Created
September 5, 2015 13:03
-
-
Save esiqveland/086167c9803f64b6e128 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From ee32bf843b1c50bfcb5563a8c87b1d7f440e6c45 Mon Sep 17 00:00:00 2001 | |
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com> | |
Date: Fri, 27 Feb 2015 12:25:39 +0100 | |
Subject: [PATCH 7/7] wined3d: Reorder shader constants. | |
Reply-To: wine-devel <wine-devel@winehq.org> | |
This attempts to fix bug 34052 without requiring a range check for every | |
indirect constant read. GL_ARB_robust_buffer_access_behavior would be an | |
OpenGL extension to reliably give us what we need, but I haven't tested | |
its performance impact yet. | |
--- | |
dlls/wined3d/arb_program_shader.c | 7 +++---- | |
dlls/wined3d/glsl_shader.c | 36 ++++++++++++++++++++++++++---------- | |
2 files changed, 29 insertions(+), 14 deletions(-) | |
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c | |
index 688bdb7..130293f 100644 | |
--- a/dlls/wined3d/arb_program_shader.c | |
+++ b/dlls/wined3d/arb_program_shader.c | |
@@ -4209,10 +4209,6 @@ static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader, | |
shader_addline(buffer, "TEMP TA;\n"); | |
shader_addline(buffer, "TEMP TB;\n"); | |
- /* Base Declarations */ | |
- shader_generate_arb_declarations(shader, reg_maps, buffer, gl_info, | |
- &priv_ctx.vs_clipplanes, &priv_ctx); | |
- | |
for(i = 0; i < MAX_CONST_I; i++) | |
{ | |
compiled->int_consts[i] = WINED3D_CONST_NUM_UNUSED; | |
@@ -4238,6 +4234,9 @@ static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader, | |
shader_addline(buffer, "PARAM posFixup = program.local[%u];\n", next_local); | |
compiled->pos_fixup = next_local++; | |
+ shader_generate_arb_declarations(shader, reg_maps, buffer, gl_info, | |
+ &priv_ctx.vs_clipplanes, &priv_ctx); | |
+ | |
/* Initialize output parameters. GL_ARB_vertex_program does not require special initialization values | |
* for output parameters. D3D in theory does not do that either, but some applications depend on a | |
* proper initialization of the secondary color, and programs using the fixed function pipeline without | |
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c | |
index 0804997..b51a9a2 100644 | |
--- a/dlls/wined3d/glsl_shader.c | |
+++ b/dlls/wined3d/glsl_shader.c | |
@@ -967,7 +967,32 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont | |
if (map & 1) shader_addline(buffer, "void subroutine%u();\n", i); | |
} | |
- /* Declare the constants (aka uniforms) */ | |
+ /* Always declare the full set of constants, the compiler can remove the | |
+ * unused ones because d3d doesn't (yet) support indirect int and bool | |
+ * constant addressing. This avoids problems if the app uses e.g. i0 and i9. */ | |
+ if (shader->limits->constant_int > 0 && reg_maps->integer_constants) | |
+ shader_addline(buffer, "uniform ivec4 %s_i[%u];\n", prefix, shader->limits->constant_int); | |
+ | |
+ if (shader->limits->constant_bool > 0 && reg_maps->boolean_constants) | |
+ shader_addline(buffer, "uniform bool %s_b[%u];\n", prefix, shader->limits->constant_bool); | |
+ | |
+ /* The game The Witcher reads beyond the 256 constants supported in | |
+ * d3d9 and expects vec4(0.0) to be returned. | |
+ * | |
+ * Declare the float constants last to get an on-GPU memory layout | |
+ * similar to what Windows drivers create. Reading outside the valid | |
+ * constant range is supposed to return vec4(0.0) on Windows. On dx10 | |
+ * cards the drivers load int and bool constants into the same memory, | |
+ * but they happen to be placed in front of the float array. E.g. | |
+ * on Nvidia GPUs the int consts are at c[-40] to c[-25]. Reading | |
+ * indices > 255 reliably returns 0.0 on Windows, except dx9 Radeon | |
+ * cards, which return c[255]. | |
+ * | |
+ * If the read location is outside the memory area defined by the | |
+ * driver, the hardware will return 0.0 in GL, presumably because | |
+ * it is built to conform to the d3d requirement. Problems happen | |
+ * if the read location is valid from the GPU's point of view but | |
+ * outside the declared float uniform array. */ | |
if (shader->limits->constant_float > 0) | |
{ | |
unsigned max_constantsF; | |
@@ -1042,15 +1067,6 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont | |
shader_addline(buffer, "uniform vec4 %s_c[%u];\n", prefix, max_constantsF); | |
} | |
- /* Always declare the full set of constants, the compiler can remove the | |
- * unused ones because d3d doesn't (yet) support indirect int and bool | |
- * constant addressing. This avoids problems if the app uses e.g. i0 and i9. */ | |
- if (shader->limits->constant_int > 0 && reg_maps->integer_constants) | |
- shader_addline(buffer, "uniform ivec4 %s_i[%u];\n", prefix, shader->limits->constant_int); | |
- | |
- if (shader->limits->constant_bool > 0 && reg_maps->boolean_constants) | |
- shader_addline(buffer, "uniform bool %s_b[%u];\n", prefix, shader->limits->constant_bool); | |
- | |
for (i = 0; i < WINED3D_MAX_CBS; ++i) | |
{ | |
if (reg_maps->cb_sizes[i]) | |
-- | |
2.3.0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment