On Fri, Nov 18, 2016 at 6:46 AM, Andrew Wesie awesie@gmail.com wrote:
--- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -2028,6 +2028,7 @@ void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_st struct wined3d_shader_tex_mx tex_mx; struct wined3d_shader_context ctx; const DWORD *ptr = byte_code;
enum WINED3D_SHADER_INSTRUCTION_HANDLER last_opcode = WINED3DSIH_TABLE_SIZE;
/* Initialize current parsing state. */ tex_mx.current_row = 0;
@@ -2062,6 +2063,16 @@ 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);
last_opcode = ins.handler_idx;
- }
- if (last_opcode != WINED3DSIH_RET)
- {
/* Force a return instruction at the end of function body. */
memset(&ins, 0, sizeof(ins));
ins.ctx = &ctx;
ins.handler_idx = WINED3DSIH_RET;
}device->shader_backend->shader_handle_instruction(&ins);
}
Would it make sense to always generate a shader epilogue for shader model <= 3, and handle the RET instruction in a special way for shader model >= 4?
2016-11-21 1:46 GMT+01:00 Józef Kucia joseph.kucia@gmail.com:
On Fri, Nov 18, 2016 at 6:46 AM, Andrew Wesie awesie@gmail.com wrote:
--- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -2028,6 +2028,7 @@ void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_st struct wined3d_shader_tex_mx tex_mx; struct wined3d_shader_context ctx; const DWORD *ptr = byte_code;
enum WINED3D_SHADER_INSTRUCTION_HANDLER last_opcode = WINED3DSIH_TABLE_SIZE;
/* Initialize current parsing state. */ tex_mx.current_row = 0;
@@ -2062,6 +2063,16 @@ 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);
last_opcode = ins.handler_idx;
- }
- if (last_opcode != WINED3DSIH_RET)
- {
/* Force a return instruction at the end of function body. */
memset(&ins, 0, sizeof(ins));
ins.ctx = &ctx;
ins.handler_idx = WINED3DSIH_RET;
}device->shader_backend->shader_handle_instruction(&ins);
}
Would it make sense to always generate a shader epilogue for shader model <= 3, and handle the RET instruction in a special way for shader model >= 4?
Notice that the RET instruction is also used for returning from subroutines. Now, I don't know that anyone has ever used subroutines in d3d shaders (especially for SM <= 3) but probably the correct thing to do is to only generate an additional shader epilogue for RETs called from the main function. That means keeping track of whether we are in the main shader or in a subroutine (maybe by extending / renaming struct wined3d_shader_loop_state) and only generating the epilogue for RETs called from the main shader.
FWIW, this only came up now because RET appearing before the end of the main shader, i.e. as an early return is new to SM4+.
On Tue, Nov 22, 2016 at 2:00 AM, Matteo Bruni matteo.mystral@gmail.com wrote:
Would it make sense to always generate a shader epilogue for shader model <= 3, and handle the RET instruction in a special way for shader model >= 4?
Notice that the RET instruction is also used for returning from subroutines. Now, I don't know that anyone has ever used subroutines in d3d shaders (especially for SM <= 3) but probably the correct thing to do is to only generate an additional shader epilogue for RETs called from the main function. That means keeping track of whether we are in the main shader or in a subroutine (maybe by extending / renaming struct wined3d_shader_loop_state) and only generating the epilogue for RETs called from the main shader.
Yeah, but generating a shader epilogue always in shader_glsl_generate_pshader() and shader_glsl_generate_vshader(), i.e. the current behavior should work fine for shader model <= 3. We will probably need to revisit this code when implementing tessellation shaders or SM4 subroutines.
2016-11-22 11:56 GMT+01:00 Józef Kucia joseph.kucia@gmail.com:
On Tue, Nov 22, 2016 at 2:00 AM, Matteo Bruni matteo.mystral@gmail.com wrote:
Would it make sense to always generate a shader epilogue for shader model <= 3, and handle the RET instruction in a special way for shader model >= 4?
Notice that the RET instruction is also used for returning from subroutines. Now, I don't know that anyone has ever used subroutines in d3d shaders (especially for SM <= 3) but probably the correct thing to do is to only generate an additional shader epilogue for RETs called from the main function. That means keeping track of whether we are in the main shader or in a subroutine (maybe by extending / renaming struct wined3d_shader_loop_state) and only generating the epilogue for RETs called from the main shader.
Yeah, but generating a shader epilogue always in shader_glsl_generate_pshader() and shader_glsl_generate_vshader(), i.e. the current behavior should work fine for shader model <= 3. We will probably need to revisit this code when implementing tessellation shaders or SM4 subroutines.
Sure, generating the epilogue in the generation functions for SM <= 3 is fine with me. Still it seems sensible to implement the SM4 RET correctly right away. Unless I'm missing something, you can set an "in_subroutine" flag in the LABEL callback (you never need to unset it afterwards actually, since the main shader is always at the start and before any subroutine) and that should mostly do the trick.