mirror of
https://github.com/reactos/wine.git
synced 2024-12-14 23:29:44 +00:00
wined3d: Implement return instruction.
Based on a patch by Andrew Wesie. Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b621973c47
commit
b9b8e775ea
@ -7643,7 +7643,7 @@ static void test_swapchain_flip(void)
|
||||
|
||||
ID3D10Device_Draw(device, 4, 0);
|
||||
color = get_texture_color(offscreen, 120, 240);
|
||||
todo_wine ok(compare_color(color, 0x7f0000ff, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
ok(compare_color(color, 0x7f0000ff, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
|
||||
/* DXGI moves buffers in the same direction as earlier versions. Buffer 2 becomes buffer 1,
|
||||
* buffer 1 becomes the new buffer 0, and buffer 0 becomes buffer n - 1. However, only buffer
|
||||
@ -7660,7 +7660,7 @@ static void test_swapchain_flip(void)
|
||||
|
||||
ID3D10Device_Draw(device, 4, 0);
|
||||
color = get_texture_color(offscreen, 120, 240); /* green, buf 0 */
|
||||
todo_wine ok(compare_color(color, 0x7f00ff00, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
ok(compare_color(color, 0x7f00ff00, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
/* Buffer 1 is still untouched. */
|
||||
|
||||
color = get_texture_color(backbuffer_0, 320, 240); /* green */
|
||||
@ -7674,7 +7674,7 @@ static void test_swapchain_flip(void)
|
||||
|
||||
ID3D10Device_Draw(device, 4, 0);
|
||||
color = get_texture_color(offscreen, 120, 240); /* blue, buf 0 */
|
||||
todo_wine ok(compare_color(color, 0x7fff0000, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
ok(compare_color(color, 0x7fff0000, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
color = get_texture_color(offscreen, 360, 240); /* red, buf 1 */
|
||||
ok(compare_color(color, 0x7f0000ff, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
|
||||
|
@ -7962,7 +7962,7 @@ static void test_swapchain_flip(void)
|
||||
|
||||
ID3D11DeviceContext_Draw(context, 4, 0);
|
||||
color = get_texture_color(offscreen, 120, 240);
|
||||
todo_wine ok(compare_color(color, 0x7f0000ff, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
ok(compare_color(color, 0x7f0000ff, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
|
||||
/* DXGI moves buffers in the same direction as earlier versions. Buffer 2
|
||||
* becomes buffer 1, buffer 1 becomes the new buffer 0, and buffer 0
|
||||
@ -7980,7 +7980,7 @@ static void test_swapchain_flip(void)
|
||||
|
||||
ID3D11DeviceContext_Draw(context, 4, 0);
|
||||
color = get_texture_color(offscreen, 120, 240); /* green, buf 0 */
|
||||
todo_wine ok(compare_color(color, 0x7f00ff00, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
ok(compare_color(color, 0x7f00ff00, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
/* Buffer 1 is still untouched. */
|
||||
|
||||
color = get_texture_color(backbuffer_0, 320, 240); /* green */
|
||||
@ -7994,7 +7994,7 @@ static void test_swapchain_flip(void)
|
||||
|
||||
ID3D11DeviceContext_Draw(context, 4, 0);
|
||||
color = get_texture_color(offscreen, 120, 240); /* blue, buf 0 */
|
||||
todo_wine ok(compare_color(color, 0x7fff0000, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
ok(compare_color(color, 0x7fff0000, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
color = get_texture_color(offscreen, 360, 240); /* red, buf 1 */
|
||||
ok(compare_color(color, 0x7f0000ff, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
|
||||
|
@ -290,6 +290,8 @@ struct glsl_ffp_destroy_ctx
|
||||
const struct wined3d_gl_info *gl_info;
|
||||
};
|
||||
|
||||
static void shader_glsl_generate_shader_epilogue(const struct wined3d_shader_context *ctx);
|
||||
|
||||
static const char *debug_gl_shader_type(GLenum type)
|
||||
{
|
||||
switch (type)
|
||||
@ -4553,9 +4555,13 @@ static void shader_glsl_callnz(const struct wined3d_shader_instruction *ins)
|
||||
|
||||
static void shader_glsl_ret(const struct wined3d_shader_instruction *ins)
|
||||
{
|
||||
/* No-op. The closing } is written when a new function is started, and at the end of the shader. This
|
||||
* function only suppresses the unhandled instruction warning
|
||||
*/
|
||||
const struct wined3d_shader_version *version = &ins->ctx->shader->reg_maps.shader_version;
|
||||
|
||||
if (version->major >= 4)
|
||||
{
|
||||
shader_glsl_generate_shader_epilogue(ins->ctx);
|
||||
shader_addline(ins->ctx->buffer, "return;\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
@ -6065,6 +6071,26 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer,
|
||||
shader_addline(buffer, "#extension GL_EXT_texture_array : enable\n");
|
||||
}
|
||||
|
||||
static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_info,
|
||||
struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader,
|
||||
const struct ps_compile_args *args)
|
||||
{
|
||||
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
|
||||
|
||||
/* Pixel shaders < 2.0 place the resulting color in R0 implicitly. */
|
||||
if (reg_maps->shader_version.major < 2)
|
||||
shader_addline(buffer, "%s[0] = R0;\n", get_fragment_output(gl_info));
|
||||
|
||||
if (args->srgb_correction)
|
||||
shader_glsl_generate_srgb_write_correction(buffer, gl_info);
|
||||
|
||||
/* SM < 3 does not replace the fog stage. */
|
||||
if (reg_maps->shader_version.major < 3)
|
||||
shader_glsl_generate_fog_code(buffer, gl_info, args->fog);
|
||||
|
||||
shader_glsl_generate_alpha_test(buffer, gl_info, args->alpha_test_func + 1);
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context,
|
||||
struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers,
|
||||
@ -6171,18 +6197,9 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
|
||||
/* Base Shader Body */
|
||||
shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
|
||||
|
||||
/* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
|
||||
if (reg_maps->shader_version.major < 2)
|
||||
shader_addline(buffer, "%s[0] = R0;\n", get_fragment_output(gl_info));
|
||||
|
||||
if (args->srgb_correction)
|
||||
shader_glsl_generate_srgb_write_correction(buffer, gl_info);
|
||||
|
||||
/* SM < 3 does not replace the fog stage. */
|
||||
if (reg_maps->shader_version.major < 3)
|
||||
shader_glsl_generate_fog_code(buffer, gl_info, args->fog);
|
||||
|
||||
shader_glsl_generate_alpha_test(buffer, gl_info, args->alpha_test_func + 1);
|
||||
/* In SM4+ the shader epilogue is generated by the "ret" instruction. */
|
||||
if (reg_maps->shader_version.major < 4)
|
||||
shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, args);
|
||||
|
||||
shader_addline(buffer, "}\n");
|
||||
|
||||
@ -6192,6 +6209,49 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
|
||||
return shader_id;
|
||||
}
|
||||
|
||||
static void shader_glsl_generate_vs_epilogue(const struct wined3d_gl_info *gl_info,
|
||||
struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader,
|
||||
const struct vs_compile_args *args)
|
||||
{
|
||||
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
|
||||
BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
|
||||
unsigned int i;
|
||||
|
||||
/* Unpack outputs. */
|
||||
shader_addline(buffer, "setup_vs_output(vs_out);\n");
|
||||
|
||||
/* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
|
||||
* or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE),
|
||||
* the fog frag coord is thrown away. If the fog frag coord is used, but not written by
|
||||
* the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0).
|
||||
*/
|
||||
if (reg_maps->shader_version.major < 3)
|
||||
{
|
||||
if (args->fog_src == VS_FOG_Z)
|
||||
shader_addline(buffer, "%s = gl_Position.z;\n",
|
||||
legacy_context ? "gl_FogFragCoord" : "ffp_varying_fogcoord");
|
||||
else if (!reg_maps->fog)
|
||||
shader_addline(buffer, "%s = 0.0;\n",
|
||||
legacy_context ? "gl_FogFragCoord" : "ffp_varying_fogcoord");
|
||||
}
|
||||
|
||||
/* We always store the clipplanes without y inversion. */
|
||||
if (args->clip_enabled)
|
||||
{
|
||||
if (legacy_context)
|
||||
shader_addline(buffer, "gl_ClipVertex = gl_Position;\n");
|
||||
else
|
||||
for (i = 0; i < gl_info->limits.user_clip_distances; ++i)
|
||||
shader_addline(buffer, "gl_ClipDistance[%u] = dot(gl_Position, clip_planes[%u]);\n", i, i);
|
||||
}
|
||||
|
||||
if (args->point_size && !args->per_vertex_point_size)
|
||||
shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n");
|
||||
|
||||
if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
|
||||
shader_glsl_fixup_position(buffer);
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context,
|
||||
struct shader_glsl_priv *priv, const struct wined3d_shader *shader, const struct vs_compile_args *args)
|
||||
@ -6200,10 +6260,8 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
|
||||
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
|
||||
struct wined3d_string_buffer *buffer = &priv->shader_buffer;
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
BOOL legacy_context = gl_info->supported[WINED3D_GL_LEGACY_CONTEXT];
|
||||
const DWORD *function = shader->function;
|
||||
struct shader_glsl_ctx_priv priv_ctx;
|
||||
unsigned int i;
|
||||
|
||||
/* Create the hw GLSL shader program and assign it as the shader->prgId */
|
||||
GLuint shader_id = GL_EXTCALL(glCreateShader(GL_VERTEX_SHADER));
|
||||
@ -6239,39 +6297,9 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
|
||||
/* Base Shader Body */
|
||||
shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
|
||||
|
||||
/* Unpack outputs */
|
||||
shader_addline(buffer, "setup_vs_output(vs_out);\n");
|
||||
|
||||
/* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
|
||||
* or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE),
|
||||
* the fog frag coord is thrown away. If the fog frag coord is used, but not written by
|
||||
* the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0)
|
||||
*/
|
||||
if (reg_maps->shader_version.major < 3)
|
||||
{
|
||||
if (args->fog_src == VS_FOG_Z)
|
||||
shader_addline(buffer, "%s = gl_Position.z;\n",
|
||||
legacy_context ? "gl_FogFragCoord" : "ffp_varying_fogcoord");
|
||||
else if (!reg_maps->fog)
|
||||
shader_addline(buffer, "%s = 0.0;\n",
|
||||
legacy_context ? "gl_FogFragCoord" : "ffp_varying_fogcoord");
|
||||
}
|
||||
|
||||
/* We always store the clipplanes without y inversion */
|
||||
if (args->clip_enabled)
|
||||
{
|
||||
if (legacy_context)
|
||||
shader_addline(buffer, "gl_ClipVertex = gl_Position;\n");
|
||||
else
|
||||
for (i = 0; i < gl_info->limits.user_clip_distances; ++i)
|
||||
shader_addline(buffer, "gl_ClipDistance[%u] = dot(gl_Position, clip_planes[%u]);\n", i, i);
|
||||
}
|
||||
|
||||
if (args->point_size && !args->per_vertex_point_size)
|
||||
shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n");
|
||||
|
||||
if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
|
||||
shader_glsl_fixup_position(buffer);
|
||||
/* In SM4+ the shader epilogue is generated by the "ret" instruction. */
|
||||
if (reg_maps->shader_version.major < 4)
|
||||
shader_glsl_generate_vs_epilogue(gl_info, buffer, shader, args);
|
||||
|
||||
shader_addline(buffer, "}\n");
|
||||
|
||||
@ -6317,6 +6345,28 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
|
||||
return shader_id;
|
||||
}
|
||||
|
||||
static void shader_glsl_generate_shader_epilogue(const struct wined3d_shader_context *ctx)
|
||||
{
|
||||
const struct shader_glsl_ctx_priv *priv = ctx->backend_data;
|
||||
const struct wined3d_gl_info *gl_info = ctx->gl_info;
|
||||
const struct wined3d_shader *shader = ctx->shader;
|
||||
|
||||
switch (shader->reg_maps.shader_version.type)
|
||||
{
|
||||
case WINED3D_SHADER_TYPE_PIXEL:
|
||||
shader_glsl_generate_ps_epilogue(gl_info, ctx->buffer, shader, priv->cur_ps_args);
|
||||
break;
|
||||
case WINED3D_SHADER_TYPE_VERTEX:
|
||||
shader_glsl_generate_vs_epilogue(gl_info, ctx->buffer, shader, priv->cur_vs_args);
|
||||
break;
|
||||
case WINED3D_SHADER_TYPE_GEOMETRY:
|
||||
break;
|
||||
default:
|
||||
FIXME("Unhandled shader type %#x.\n", shader->reg_maps.shader_version.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint find_glsl_pshader(const struct wined3d_context *context,
|
||||
struct wined3d_string_buffer *buffer, struct wined3d_string_buffer_list *string_buffers,
|
||||
struct wined3d_shader *shader,
|
||||
|
Loading…
Reference in New Issue
Block a user