From 1cf36797bf9d63b33c405d85ce720dcd5e75a47c Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Thu, 15 Apr 2021 13:47:58 +0200 Subject: [PATCH] v3dv: fix sRGB blending workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This workaround needs to set a flag in the current job but it was implemented at pipeline binding time, which can happen outside a render pass. Move it to the pre-draw handler, where it belongs. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4645 Reviewed-by: Alejandro PiƱeiro Part-of: --- src/broadcom/vulkan/v3dv_cmd_buffer.c | 43 ++++++++++++++------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index b5724d2ecc1..9e38f991d24 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -3140,25 +3140,6 @@ bind_graphics_pipeline(struct v3dv_cmd_buffer *cmd_buffer, if (cmd_buffer->state.gfx.pipeline == pipeline) return; - /* Enable always flush if we are blending to sRGB render targets. This - * fixes test failures in: - * dEQP-VK.pipeline.blend.format.r8g8b8a8_srgb.* - * - * FIXME: not sure why we need this. The tile buffer is always linear, with - * conversion from/to sRGB happening on tile load/store operations. This - * means that when we enable flushing the only difference is that we convert - * to sRGB on the store after each draw call and we convert from sRGB on the - * load before each draw call, but the blend happens in linear format in the - * tile buffer anyway, which is the same scenario as if we didn't flush. - */ - assert(pipeline->subpass); - if (pipeline->subpass->has_srgb_rt && pipeline->blend.enables) { - assert(cmd_buffer->state.job); - cmd_buffer->state.job->always_flush = true; - perf_debug("flushing draw calls for subpass %d because bound pipeline " - "uses sRGB blending\n", cmd_buffer->state.subpass_idx); - } - cmd_buffer->state.gfx.pipeline = pipeline; cmd_buffer_bind_pipeline_static_state(cmd_buffer, &pipeline->dynamic_state); @@ -4347,8 +4328,9 @@ emit_index_buffer(struct v3dv_cmd_buffer *cmd_buffer) static void cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer) { - assert(cmd_buffer->state.gfx.pipeline); - assert(!(cmd_buffer->state.gfx.pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT)); + struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; + assert(pipeline); + assert(!(pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT)); /* If we emitted a pipeline barrier right before this draw we won't have * an active job. In that case, create a new job continuing the current @@ -4362,6 +4344,25 @@ cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer) /* Restart single sample job for MSAA pipeline if needed */ cmd_buffer_restart_job_for_msaa_if_needed(cmd_buffer); + /* Enable always flush if we are blending to sRGB render targets. This + * fixes test failures in: + * dEQP-VK.pipeline.blend.format.r8g8b8a8_srgb.* + * + * FIXME: not sure why we need this. The tile buffer is always linear, with + * conversion from/to sRGB happening on tile load/store operations. This + * means that when we enable flushing the only difference is that we convert + * to sRGB on the store after each draw call and we convert from sRGB on the + * load before each draw call, but the blend happens in linear format in the + * tile buffer anyway, which is the same scenario as if we didn't flush. + */ + assert(pipeline->subpass); + assert(cmd_buffer->state.job); + if (pipeline->subpass->has_srgb_rt && pipeline->blend.enables) { + cmd_buffer->state.job->always_flush = true; + perf_debug("flushing draw calls for subpass %d because bound pipeline " + "uses sRGB blending\n", cmd_buffer->state.subpass_idx); + } + /* If the job is configured to flush on every draw call we need to create * a new job now. */