Skip to content

Commit b607110

Browse files
committed
Merge pull request #102792 from clayjohn/varying-crash
Validate varying count when compiling shaders
2 parents 40ff57e + 3510039 commit b607110

17 files changed

+92
-27
lines changed

drivers/d3d12/rendering_device_driver_d3d12.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6234,6 +6234,8 @@ uint64_t RenderingDeviceDriverD3D12::limit_get(Limit p_limit) {
62346234
case LIMIT_VRS_MAX_FRAGMENT_WIDTH:
62356235
case LIMIT_VRS_MAX_FRAGMENT_HEIGHT:
62366236
return vrs_capabilities.ss_max_fragment_size;
6237+
case LIMIT_MAX_SHADER_VARYINGS:
6238+
return MIN(D3D12_VS_OUTPUT_REGISTER_COUNT, D3D12_PS_INPUT_REGISTER_COUNT);
62376239
default: {
62386240
#ifdef DEV_ENABLED
62396241
WARN_PRINT("Returning maximum value for unknown limit " + itos(p_limit) + ".");

drivers/gles3/storage/config.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ Config::Config() {
110110
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
111111
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_viewport_size);
112112
glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &max_uniform_buffer_size);
113+
GLint max_vertex_output;
114+
glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, &max_vertex_output);
115+
GLint max_fragment_input;
116+
glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, &max_fragment_input);
117+
max_shader_varyings = (uint32_t)MIN(max_vertex_output, max_fragment_input) / 4;
113118

114119
// sanity clamp buffer size to 16K..1MB
115120
max_uniform_buffer_size = CLAMP(max_uniform_buffer_size, 16384, 1048576);

drivers/gles3/storage/config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class Config {
6262
GLint max_texture_size = 0;
6363
GLint max_viewport_size[2] = { 0, 0 };
6464
GLint64 max_uniform_buffer_size = 0;
65+
uint32_t max_shader_varyings = 0;
6566

6667
int64_t max_renderable_elements = 0;
6768
int64_t max_renderable_lights = 0;

drivers/gles3/storage/utilities.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,4 +465,16 @@ Size2i Utilities::get_maximum_viewport_size() const {
465465
return Size2i(config->max_viewport_size[0], config->max_viewport_size[1]);
466466
}
467467

468+
uint32_t Utilities::get_maximum_shader_varyings() const {
469+
Config *config = Config::get_singleton();
470+
ERR_FAIL_NULL_V(config, 31);
471+
return config->max_shader_varyings;
472+
}
473+
474+
uint64_t Utilities::get_maximum_uniform_buffer_size() const {
475+
Config *config = Config::get_singleton();
476+
ERR_FAIL_NULL_V(config, 65536);
477+
return uint64_t(config->max_uniform_buffer_size);
478+
}
479+
468480
#endif // GLES3_ENABLED

drivers/gles3/storage/utilities.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ class Utilities : public RendererUtilities {
226226
virtual String get_video_adapter_api_version() const override;
227227

228228
virtual Size2i get_maximum_viewport_size() const override;
229+
virtual uint32_t get_maximum_shader_varyings() const override;
230+
virtual uint64_t get_maximum_uniform_buffer_size() const override;
229231
};
230232

231233
} // namespace GLES3

drivers/metal/metal_device_properties.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ struct MetalLimits {
124124
uint32_t maxVertexInputBindings;
125125
uint32_t maxVertexInputBindingStride;
126126
uint32_t maxDrawIndexedIndexValue;
127+
uint32_t maxShaderVaryings;
127128

128129
double temporalScalerInputContentMinScale;
129130
double temporalScalerInputContentMaxScale;

drivers/metal/metal_device_properties.mm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@
303303
limits.maxVertexInputAttributes = 31;
304304
limits.maxVertexInputBindings = 31;
305305
limits.maxVertexInputBindingStride = (2 * KIBI);
306+
limits.maxShaderVaryings = 31; // Accurate on Apple4 and above. See: https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
306307

307308
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
308309
limits.minUniformBufferOffsetAlignment = 64;

drivers/metal/rendering_device_driver_metal.mm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3999,6 +3999,8 @@ bool isArrayTexture(MTLTextureType p_type) {
39993999
return (uint64_t)((1.0 / limits.temporalScalerInputContentMaxScale) * 1000'000);
40004000
case LIMIT_METALFX_TEMPORAL_SCALER_MAX_SCALE:
40014001
return (uint64_t)((1.0 / limits.temporalScalerInputContentMinScale) * 1000'000);
4002+
case LIMIT_MAX_SHADER_VARYINGS:
4003+
return limits.maxShaderVaryings;
40024004
UNKNOWN(LIMIT_VRS_TEXEL_WIDTH);
40034005
UNKNOWN(LIMIT_VRS_TEXEL_HEIGHT);
40044006
UNKNOWN(LIMIT_VRS_MAX_FRAGMENT_WIDTH);

drivers/vulkan/rendering_device_driver_vulkan.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5886,6 +5886,10 @@ uint64_t RenderingDeviceDriverVulkan::limit_get(Limit p_limit) {
58865886
return vrs_capabilities.max_fragment_size.x;
58875887
case LIMIT_VRS_MAX_FRAGMENT_HEIGHT:
58885888
return vrs_capabilities.max_fragment_size.y;
5889+
case LIMIT_MAX_SHADER_VARYINGS:
5890+
// The Vulkan spec states that built in varyings like gl_FragCoord should count against this, but in
5891+
// practice, that doesn't seem to be the case. The validation layers don't even complain.
5892+
return MIN(limits.maxVertexOutputComponents / 4, limits.maxFragmentInputComponents / 4);
58895893
default:
58905894
ERR_FAIL_V(0);
58915895
}

servers/rendering/dummy/storage/utilities.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ class Utilities : public RendererUtilities {
9494
virtual String get_video_adapter_api_version() const override { return String(); }
9595

9696
virtual Size2i get_maximum_viewport_size() const override { return Size2i(); }
97+
virtual uint32_t get_maximum_shader_varyings() const override { return 31; } // Fair assumption for everything except old OpenGL-only phones.
98+
virtual uint64_t get_maximum_uniform_buffer_size() const override { return 65536; } // Fair assumption for all devices.
9799
};
98100

99101
} // namespace RendererDummy

0 commit comments

Comments
 (0)