Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44655 Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/wined3d/cs.c | 8 ++++++++ dlls/wined3d/glsl_shader.c | 11 +++++++---- dlls/wined3d/shader.c | 10 ++++++++++ dlls/wined3d/utils.c | 3 ++- dlls/wined3d/wined3d_private.h | 3 ++- 5 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 2aae559a6cb9..af1dbef84ce1 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -1084,9 +1084,17 @@ void wined3d_cs_emit_set_scissor_rects(struct wined3d_cs *cs, unsigned int rect_ static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_rendertarget_view *op = data; + BOOL prev_alpha_swizzle, curr_alpha_swizzle; + struct wined3d_rendertarget_view *prev;
+ prev = cs->state.fb->render_targets[op->view_idx]; cs->fb.render_targets[op->view_idx] = op->view; device_invalidate_state(cs->device, STATE_FRAMEBUFFER); + + prev_alpha_swizzle = prev && prev->format->id == WINED3DFMT_A8_UNORM; + curr_alpha_swizzle = op->view && op->view->format->id == WINED3DFMT_A8_UNORM; + if (prev_alpha_swizzle != curr_alpha_swizzle) + device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); }
void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx, diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 0db7fdc038b0..32f82d6c3d0a 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -7694,11 +7694,12 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer,
static void shader_glsl_generate_color_output(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info, const struct wined3d_shader *shader, - struct wined3d_string_buffer_list *string_buffers) + const struct ps_compile_args *args, struct wined3d_string_buffer_list *string_buffers) { const struct wined3d_shader_signature *output_signature = &shader->output_signature; struct wined3d_string_buffer *src, *assignment; enum wined3d_data_type dst_data_type; + const char *swizzle; unsigned int i;
if (output_signature->element_count) @@ -7721,7 +7722,8 @@ static void shader_glsl_generate_color_output(struct wined3d_string_buffer *buff shader_addline(buffer, "color_out%u = ", output->semantic_idx); string_buffer_sprintf(src, "ps_out[%u]", output->semantic_idx); shader_glsl_sprintf_cast(assignment, src->buffer, dst_data_type, WINED3D_DATA_FLOAT); - shader_addline(buffer, "%s;\n", assignment->buffer); + swizzle = args->rt_alpha_swizzle & (1u << output->semantic_idx) ? ".argb" : ""; + shader_addline(buffer, "%s%s;\n", assignment->buffer, swizzle); } string_buffer_release(string_buffers, src); string_buffer_release(string_buffers, assignment); @@ -7733,7 +7735,8 @@ static void shader_glsl_generate_color_output(struct wined3d_string_buffer *buff while (mask) { i = wined3d_bit_scan(&mask); - shader_addline(buffer, "color_out%u = ps_out[%u];\n", i, i); + swizzle = args->rt_alpha_swizzle & (1u << i) ? ".argb" : ""; + shader_addline(buffer, "color_out%u = ps_out[%u]%s;\n", i, i, swizzle); } } } @@ -7761,7 +7764,7 @@ static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_in shader_addline(buffer, "gl_SampleMask[0] = floatBitsToInt(sample_mask);\n");
if (!needs_legacy_glsl_syntax(gl_info)) - shader_glsl_generate_color_output(buffer, gl_info, shader, string_buffers); + shader_glsl_generate_color_output(buffer, gl_info, shader, args, string_buffers); }
/* Context activation is done by the caller. */ diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 62ec97154141..09681725b5a7 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -4124,6 +4124,16 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
args->render_offscreen = shader->reg_maps.vpos && gl_info->supported[ARB_FRAGMENT_COORD_CONVENTIONS] ? context->render_offscreen : 0; + + if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) + { + for (i = 0; i < ARRAY_SIZE(state->fb->render_targets); ++i) + { + struct wined3d_rendertarget_view *rtv = state->fb->render_targets[i]; + if (rtv && rtv->format->id == WINED3DFMT_A8_UNORM) + args->rt_alpha_swizzle |= 1u << i; + } + } }
static HRESULT pixel_shader_init(struct wined3d_shader *shader, struct wined3d_device *device, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 05579db5b2b4..e3df24ade40d 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -1519,7 +1519,8 @@ static const struct wined3d_format_texture_info format_texture_info[] = ARB_TEXTURE_RG, NULL}, {WINED3DFMT_A8_UNORM, GL_R8, GL_R8, 0, GL_RED, GL_UNSIGNED_BYTE, 0, - WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_RENDERTARGET, ARB_TEXTURE_RG, NULL}, {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9135189d026c..5f7f6fd39795 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1345,7 +1345,8 @@ struct ps_compile_args DWORD flatshading : 1; DWORD alpha_test_func : 3; DWORD render_offscreen : 1; - DWORD padding : 26; + DWORD rt_alpha_swizzle : 8; /* MAX_RENDER_TARGET_VIEWS, 8 */ + DWORD padding : 18; };
enum fog_src_type
On Mon, 1 Oct 2018 at 19:32, Józef Kucia jkucia@codeweavers.com wrote:
- prev_alpha_swizzle = prev && prev->format->id == WINED3DFMT_A8_UNORM;
- curr_alpha_swizzle = op->view && op->view->format->id == WINED3DFMT_A8_UNORM;
- if (prev_alpha_swizzle != curr_alpha_swizzle)
device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL));
But you can avoid this entire block if you have WINED3D_GL_LEGACY_CONTEXT, or perhaps some d3d_info equivalent.