From 578190c0fedd6cb0e348f3512ef1fab365713214 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 19 Jul 2021 16:23:31 -0400 Subject: [PATCH] lavapipe: implement VK_EXT_color_write_enable Reviewed-by: Dave Airlie Part-of: --- .../frontends/lavapipe/lvp_cmd_buffer.c | 23 ++++++++++++ src/gallium/frontends/lavapipe/lvp_device.c | 7 ++++ src/gallium/frontends/lavapipe/lvp_execute.c | 36 ++++++++++++++++++- src/gallium/frontends/lavapipe/lvp_pipeline.c | 12 +++++++ src/gallium/frontends/lavapipe/lvp_private.h | 6 ++++ 5 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c index c62765c9d15..a04f7442fd5 100644 --- a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c +++ b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c @@ -2258,3 +2258,26 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdSetRasterizerDiscardEnableEXT( cmd->u.set_rasterizer_discard_enable.enable = rasterizerDiscardEnable == VK_TRUE; cmd_buf_queue(cmd_buffer, cmd); } + +VKAPI_ATTR void VKAPI_CALL lvp_CmdSetColorWriteEnableEXT( + VkCommandBuffer commandBuffer, + uint32_t attachmentCount, + const VkBool32* pColorWriteEnables) +{ + LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); + struct lvp_cmd_buffer_entry *cmd; + + cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_COLOR_WRITE_ENABLE); + if (!cmd) + return; + + cmd->u.set_color_write_enable.disable_mask = 0; + for (unsigned i = 0; i < attachmentCount; i++) { + /* this is inverted because cmdbufs are zero-initialized, meaning only 'true' + * can be detected with a bool, and the default is to enable color writes + */ + if (pColorWriteEnables[i] != VK_TRUE) + cmd->u.set_color_write_enable.disable_mask |= BITFIELD_BIT(i); + } + cmd_buf_queue(cmd_buffer, cmd); +} diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c index 58ea8238a5d..e3f41939cd3 100644 --- a/src/gallium/frontends/lavapipe/lvp_device.c +++ b/src/gallium/frontends/lavapipe/lvp_device.c @@ -125,6 +125,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported = .KHR_uniform_buffer_standard_layout = true, .KHR_variable_pointers = true, .EXT_calibrated_timestamps = true, + .EXT_color_write_enable = true, .EXT_conditional_rendering = true, .EXT_extended_dynamic_state = true, .EXT_extended_dynamic_state2 = true, @@ -639,6 +640,12 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2( features->customBorderColorWithoutFormat = true; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT: { + VkPhysicalDeviceColorWriteEnableFeaturesEXT *features = + (VkPhysicalDeviceColorWriteEnableFeaturesEXT *)ext; + features->colorWriteEnable = true; + break; + } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: { VkPhysicalDeviceProvokingVertexFeaturesEXT *features = (VkPhysicalDeviceProvokingVertexFeaturesEXT*)ext; diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 0a9b9f9fa54..5f309c382f7 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -126,7 +126,9 @@ struct rendering_state { bool disable_multisample; enum gs_output gs_output_lines : 2; - uint32_t pad:22; + uint32_t color_write_disables:8; + bool has_color_write_disables:1; + uint32_t pad:13; void *ss_cso[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; void *velems_cso; @@ -220,7 +222,22 @@ static void emit_state(struct rendering_state *state) { int sh; if (state->blend_dirty) { + uint32_t mask = 0; + /* zero out the colormask values for disabled attachments */ + if (state->has_color_write_disables && state->color_write_disables) { + u_foreach_bit(att, state->color_write_disables) { + mask |= state->blend_state.rt[att].colormask << (att * 4); + state->blend_state.rt[att].colormask = 0; + } + } cso_set_blend(state->cso, &state->blend_state); + /* reset colormasks using saved bitmask */ + if (state->has_color_write_disables && state->color_write_disables) { + const uint32_t att_mask = BITFIELD_MASK(4); + u_foreach_bit(att, state->color_write_disables) { + state->blend_state.rt[att].colormask = (mask >> (att * 4)) & att_mask; + } + } state->blend_dirty = false; } @@ -402,6 +419,8 @@ get_viewport_xform(const VkViewport *viewport, VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT VK_DYNAMIC_STATE_LOGIC_OP_EXT VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT + + VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT */ static int conv_dynamic_state_idx(VkDynamicState dyn_state) { @@ -420,6 +439,10 @@ static int conv_dynamic_state_idx(VkDynamicState dyn_state) return dyn_state - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT + VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1; + if (dyn_state == VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT) + return VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT + + VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT + + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1 + 1; assert(0); return -1; } @@ -443,6 +466,7 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd, dynamic_states[idx] = true; } } + state->has_color_write_disables = dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT)]; bool has_stage[PIPE_SHADER_TYPES] = { false }; @@ -3067,6 +3091,13 @@ static void handle_set_rasterizer_discard_enable(struct lvp_cmd_buffer_entry *cm state->rs_state.rasterizer_discard = cmd->u.set_rasterizer_discard_enable.enable; } +static void handle_set_color_write_enable(struct lvp_cmd_buffer_entry *cmd, + struct rendering_state *state) +{ + state->blend_dirty |= state->color_write_disables != cmd->u.set_color_write_enable.disable_mask; + state->color_write_disables = cmd->u.set_color_write_enable.disable_mask; +} + static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer, struct rendering_state *state) { @@ -3297,6 +3328,9 @@ static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer, case LVP_CMD_SET_RASTERIZER_DISCARD_ENABLE: handle_set_rasterizer_discard_enable(cmd, state); break; + case LVP_CMD_SET_COLOR_WRITE_ENABLE: + handle_set_color_write_enable(cmd, state); + break; } first = false; did_flush = false; diff --git a/src/gallium/frontends/lavapipe/lvp_pipeline.c b/src/gallium/frontends/lavapipe/lvp_pipeline.c index 0c1c30315c6..899587baec1 100644 --- a/src/gallium/frontends/lavapipe/lvp_pipeline.c +++ b/src/gallium/frontends/lavapipe/lvp_pipeline.c @@ -828,6 +828,18 @@ lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline, } else pipeline->line_rectangular = true; + if (!dynamic_state_contains(pipeline->graphics_create_info.pDynamicState, VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT)) { + const VkPipelineColorWriteCreateInfoEXT *cw_state = + vk_find_struct_const(pCreateInfo->pColorBlendState, PIPELINE_COLOR_WRITE_CREATE_INFO_EXT); + if (cw_state) { + for (unsigned i = 0; i < cw_state->attachmentCount; i++) + if (!cw_state->pColorWriteEnables[i]) { + VkPipelineColorBlendAttachmentState *att = (void*)&pipeline->graphics_create_info.pColorBlendState->pAttachments[i]; + att->colorWriteMask = 0; + } + } + } + for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) { VK_FROM_HANDLE(vk_shader_module, module, diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h index d1e6b05621c..a56ac3f2e1f 100644 --- a/src/gallium/frontends/lavapipe/lvp_private.h +++ b/src/gallium/frontends/lavapipe/lvp_private.h @@ -690,6 +690,7 @@ enum lvp_cmds { LVP_CMD_SET_PATCH_CONTROL_POINTS, LVP_CMD_SET_PRIMITIVE_RESTART_ENABLE, LVP_CMD_SET_RASTERIZER_DISCARD_ENABLE, + LVP_CMD_SET_COLOR_WRITE_ENABLE, }; struct lvp_cmd_bind_pipeline { @@ -1096,6 +1097,10 @@ struct lvp_cmd_set_rasterizer_discard_enable { bool enable; }; +struct lvp_cmd_set_color_write_enable { + uint8_t disable_mask; //PIPE_MAX_COLOR_BUFS is max attachment count +}; + struct lvp_cmd_buffer_entry { struct list_head cmd_link; uint32_t cmd_type; @@ -1159,6 +1164,7 @@ struct lvp_cmd_buffer_entry { struct lvp_cmd_set_patch_control_points set_patch_control_points; struct lvp_cmd_set_primitive_restart_enable set_primitive_restart_enable; struct lvp_cmd_set_rasterizer_discard_enable set_rasterizer_discard_enable; + struct lvp_cmd_set_color_write_enable set_color_write_enable; } u; };