Henri Verbeet : wined3d: Abort on invalid instructions in shader_generate_main().

Alexandre Julliard julliard at winehq.org
Wed Mar 8 16:01:38 CST 2017


Module: wine
Branch: master
Commit: df6540edf0266225489fffcc5afec4752efcd9f8
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=df6540edf0266225489fffcc5afec4752efcd9f8

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Wed Mar  8 10:53:05 2017 +0100

wined3d: Abort on invalid instructions in shader_generate_main().

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/arb_program_shader.c |  6 ++++--
 dlls/wined3d/glsl_shader.c        | 25 ++++++++++++-------------
 dlls/wined3d/shader.c             |  8 +++++---
 dlls/wined3d/wined3d_private.h    |  2 +-
 4 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index ff868f9..150342b 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -3809,7 +3809,8 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader,
     }
 
     /* Base Shader Body */
-    shader_generate_main(shader, buffer, reg_maps, &priv_ctx);
+    if (FAILED(shader_generate_main(shader, buffer, reg_maps, &priv_ctx)))
+        return 0;
 
     if(args->super.srgb_correction) {
         arbfp_add_sRGB_correction(buffer, fragcolor, srgbtmp[0], srgbtmp[1], srgbtmp[2], srgbtmp[3],
@@ -4222,7 +4223,8 @@ static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader,
     /* The shader starts with the main function */
     priv_ctx.in_main_func = TRUE;
     /* Base Shader Body */
-    shader_generate_main(shader, buffer, reg_maps, &priv_ctx);
+    if (FAILED(shader_generate_main(shader, buffer, reg_maps, &priv_ctx)))
+        return -1;
 
     if (!priv_ctx.footer_written) vshader_add_footer(&priv_ctx,
             shader_data, args, reg_maps, gl_info, buffer);
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index d021f01..e43a78b 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -6757,9 +6757,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct shader_glsl_ctx_priv priv_ctx;
     BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
-
-    /* Create the hw GLSL shader object and assign it as the shader->prgId */
-    GLuint shader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
+    GLuint shader_id;
 
     memset(&priv_ctx, 0, sizeof(priv_ctx));
     priv_ctx.cur_ps_args = args;
@@ -6850,7 +6848,8 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
         shader_glsl_input_pack(shader, buffer, &shader->input_signature, reg_maps, args, gl_info);
 
     /* Base Shader Body */
-    shader_generate_main(shader, buffer, reg_maps, &priv_ctx);
+    if (FAILED(shader_generate_main(shader, buffer, reg_maps, &priv_ctx)))
+        return 0;
 
     /* In SM4+ the shader epilogue is generated by the "ret" instruction. */
     if (reg_maps->shader_version.major < 4)
@@ -6858,6 +6857,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
 
     shader_addline(buffer, "}\n");
 
+    shader_id = GL_EXTCALL(glCreateShader(GL_FRAGMENT_SHADER));
     TRACE("Compiling shader object %u.\n", shader_id);
     shader_glsl_compile(gl_info, shader_id, buffer->buffer);
 
@@ -6916,9 +6916,7 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
     struct wined3d_string_buffer *buffer = &priv->shader_buffer;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct shader_glsl_ctx_priv priv_ctx;
-
-    /* Create the hw GLSL shader program and assign it as the shader->prgId */
-    GLuint shader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
+    GLuint shader_id;
 
     shader_glsl_add_version_declaration(buffer, gl_info, &reg_maps->shader_version);
 
@@ -6949,7 +6947,8 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
     shader_addline(buffer, "void main()\n{\n");
 
     /* Base Shader Body */
-    shader_generate_main(shader, buffer, reg_maps, &priv_ctx);
+    if (FAILED(shader_generate_main(shader, buffer, reg_maps, &priv_ctx)))
+        return 0;
 
     /* In SM4+ the shader epilogue is generated by the "ret" instruction. */
     if (reg_maps->shader_version.major < 4)
@@ -6957,6 +6956,7 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
 
     shader_addline(buffer, "}\n");
 
+    shader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
     TRACE("Compiling shader object %u.\n", shader_id);
     shader_glsl_compile(gl_info, shader_id, buffer->buffer);
 
@@ -6974,8 +6974,6 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
     struct shader_glsl_ctx_priv priv_ctx;
     GLuint shader_id;
 
-    shader_id = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER));
-
     shader_glsl_add_version_declaration(buffer, gl_info, &reg_maps->shader_version);
 
     shader_glsl_enable_extensions(buffer, gl_info);
@@ -6989,9 +6987,11 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
         shader_addline(buffer, "uniform vec4 pos_fixup;\n");
     shader_glsl_generate_sm4_rasterizer_input_setup(priv, shader, args->ps_input_count, gl_info);
     shader_addline(buffer, "void main()\n{\n");
-    shader_generate_main(shader, buffer, reg_maps, &priv_ctx);
+    if (FAILED(shader_generate_main(shader, buffer, reg_maps, &priv_ctx)))
+        return 0;
     shader_addline(buffer, "}\n");
 
+    shader_id = GL_EXTCALL(glCreateShader(GL_GEOMETRY_SHADER));
     TRACE("Compiling shader object %u.\n", shader_id);
     shader_glsl_compile(gl_info, shader_id, buffer->buffer);
 
@@ -7033,8 +7033,6 @@ static GLuint shader_glsl_generate_compute_shader(const struct wined3d_context *
     GLuint shader_id;
     unsigned int i;
 
-    shader_id = GL_EXTCALL(glCreateShader(GL_COMPUTE_SHADER));
-
     shader_glsl_add_version_declaration(buffer, gl_info, &reg_maps->shader_version);
 
     shader_glsl_enable_extensions(buffer, gl_info);
@@ -7058,6 +7056,7 @@ static GLuint shader_glsl_generate_compute_shader(const struct wined3d_context *
     shader_generate_main(shader, buffer, reg_maps, &priv_ctx);
     shader_addline(buffer, "}\n");
 
+    shader_id = GL_EXTCALL(glCreateShader(GL_COMPUTE_SHADER));
     TRACE("Compiling shader object %u.\n", shader_id);
     shader_glsl_compile(gl_info, shader_id, buffer->buffer);
 
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 7186fdf..0c617c4 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -2282,7 +2282,7 @@ static void shader_dump_src_param(struct wined3d_string_buffer *buffer,
 
 /* Shared code in order to generate the bulk of the shader string.
  * NOTE: A description of how to parse tokens can be found on MSDN. */
-void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer,
+HRESULT shader_generate_main(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer,
         const struct wined3d_shader_reg_maps *reg_maps, void *backend_ctx)
 {
     struct wined3d_device *device = shader->device;
@@ -2320,8 +2320,8 @@ void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_st
         /* Unknown opcode and its parameters. */
         if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
         {
-            TRACE("Skipping unrecognized instruction.\n");
-            continue;
+            WARN("Encountered unrecognised or invalid instruction.\n");
+            return WINED3DERR_INVALIDCALL;
         }
 
         if (ins.predicate)
@@ -2330,6 +2330,8 @@ void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_st
         /* Call appropriate function for output target */
         device->shader_backend->shader_handle_instruction(&ins);
     }
+
+    return WINED3D_OK;
 }
 
 static void shader_dump_ins_modifiers(struct wined3d_string_buffer *buffer,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e8c858e..8d5eee5 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3679,7 +3679,7 @@ BOOL string_buffer_init(struct wined3d_string_buffer *buffer) DECLSPEC_HIDDEN;
 void string_buffer_free(struct wined3d_string_buffer *buffer) DECLSPEC_HIDDEN;
 unsigned int shader_find_free_input_register(const struct wined3d_shader_reg_maps *reg_maps,
         unsigned int max) DECLSPEC_HIDDEN;
-void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer,
+HRESULT shader_generate_main(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer,
         const struct wined3d_shader_reg_maps *reg_maps, void *backend_ctx) DECLSPEC_HIDDEN;
 BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage usage) DECLSPEC_HIDDEN;
 




More information about the wine-cvs mailing list