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+.