v3dv: implement VK_EXT_color_write_enable

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11784>
This commit is contained in:
Ella-0 2021-07-10 20:02:47 +00:00 committed by Marge Bot
parent aa8179e33f
commit f623072328
7 changed files with 80 additions and 10 deletions

View File

@ -508,7 +508,7 @@ Khronos extensions that are not part of any Vulkan version:
VK_KHR_zero_initialize_workgroup_memory DONE (anv, radv)
VK_EXT_4444_formats DONE (anv, radv, tu)
VK_EXT_calibrated_timestamps DONE (anv, lvp, radv)
VK_EXT_color_write_enable DONE (anv, lvp)
VK_EXT_color_write_enable DONE (anv, lvp, v3dv)
VK_EXT_conditional_rendering DONE (anv, lvp, radv, tu)
VK_EXT_conservative_rasterization DONE (anv/gen9+, radv)
VK_EXT_custom_border_color DONE (anv, lvp, radv, tu, v3dv)

View File

@ -55,6 +55,7 @@ const struct v3dv_dynamic_state default_dynamic_state = {
.slope_factor = 0.0f,
},
.line_width = 1.0f,
.color_write_enable = (1ull << (4 * V3D_MAX_DRAW_BUFFERS)) - 1,
};
void
@ -1870,6 +1871,13 @@ cmd_buffer_bind_pipeline_static_state(struct v3dv_cmd_buffer *cmd_buffer,
}
}
if (!(dynamic_mask & V3DV_DYNAMIC_COLOR_WRITE_ENABLE)) {
if (dest->color_write_enable != src->color_write_enable) {
dest->color_write_enable = src->color_write_enable;
dirty |= V3DV_CMD_DIRTY_COLOR_WRITE_ENABLE;
}
}
cmd_buffer->state.dynamic.mask = dynamic_mask;
cmd_buffer->state.dirty |= dirty;
}
@ -2541,6 +2549,9 @@ v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer)
if (*dirty & V3DV_CMD_DIRTY_PIPELINE)
v3dv_X(device, cmd_buffer_emit_sample_state)(cmd_buffer);
if (*dirty & (V3DV_CMD_DIRTY_PIPELINE | V3DV_CMD_DIRTY_COLOR_WRITE_ENABLE))
v3dv_X(device, cmd_buffer_emit_color_write_mask)(cmd_buffer);
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_PIPELINE;
}
@ -2965,6 +2976,26 @@ v3dv_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_BLEND_CONSTANTS;
}
VKAPI_ATTR void VKAPI_CALL
v3dv_CmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer,
uint32_t attachmentCount,
const VkBool32 *pColorWriteEnables)
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
uint32_t color_write_enable = 0;
for (uint32_t i = 0; i < attachmentCount; i++)
color_write_enable |= pColorWriteEnables[i] ? (0xfu << (i * 4)) : 0;
if (state->dynamic.color_write_enable == color_write_enable)
return;
state->dynamic.color_write_enable = color_write_enable;
state->dirty |= V3DV_CMD_DIRTY_COLOR_WRITE_ENABLE;
}
void
v3dv_cmd_buffer_reset_queries(struct v3dv_cmd_buffer *cmd_buffer,
struct v3dv_query_pool *pool,

View File

@ -139,6 +139,7 @@ get_device_extensions(const struct v3dv_physical_device *device,
.KHR_incremental_present = true,
#endif
.KHR_variable_pointers = true,
.EXT_color_write_enable = true,
.EXT_custom_border_color = true,
.EXT_external_memory_dma_buf = true,
.EXT_index_type_uint8 = true,
@ -1101,6 +1102,12 @@ v3dv_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT: {
VkPhysicalDeviceColorWriteEnableFeaturesEXT *features = (void *) ext;
features->colorWriteEnable = true;
break;
}
/* Vulkan 1.1 */
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: {
VkPhysicalDeviceVulkan11Features *features =

View File

@ -2548,6 +2548,8 @@ v3dv_dynamic_state_mask(VkDynamicState state)
return V3DV_DYNAMIC_DEPTH_BIAS;
case VK_DYNAMIC_STATE_LINE_WIDTH:
return V3DV_DYNAMIC_LINE_WIDTH;
case VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT:
return V3DV_DYNAMIC_COLOR_WRITE_ENABLE;
/* Depth bounds testing is not available in in V3D 4.2 so here we are just
* ignoring this dynamic state. We are already asserting at pipeline creation
@ -2568,7 +2570,8 @@ pipeline_init_dynamic_state(
const VkPipelineViewportStateCreateInfo *pViewportState,
const VkPipelineDepthStencilStateCreateInfo *pDepthStencilState,
const VkPipelineColorBlendStateCreateInfo *pColorBlendState,
const VkPipelineRasterizationStateCreateInfo *pRasterizationState)
const VkPipelineRasterizationStateCreateInfo *pRasterizationState,
const VkPipelineColorWriteCreateInfoEXT *pColorWriteState)
{
pipeline->dynamic_state = default_dynamic_state;
struct v3dv_dynamic_state *dynamic = &pipeline->dynamic_state;
@ -2644,6 +2647,12 @@ pipeline_init_dynamic_state(
dynamic->line_width = pRasterizationState->lineWidth;
}
if (pColorWriteState && !(dynamic_states & V3DV_DYNAMIC_COLOR_WRITE_ENABLE)) {
dynamic->color_write_enable = 0;
for (uint32_t i = 0; i < pColorWriteState->attachmentCount; i++)
dynamic->color_write_enable |= pColorWriteState->pColorWriteEnables[i] ? (0xfu << (i * 4)) : 0;
}
pipeline->dynamic_state.mask = dynamic_states;
}
@ -2843,9 +2852,14 @@ pipeline_init(struct v3dv_pipeline *pipeline,
const VkPipelineMultisampleStateCreateInfo *ms_info =
raster_enabled ? pCreateInfo->pMultisampleState : NULL;
const VkPipelineColorWriteCreateInfoEXT *cw_info =
cb_info ? vk_find_struct_const(cb_info->pNext,
PIPELINE_COLOR_WRITE_CREATE_INFO_EXT) :
NULL;
pipeline_init_dynamic_state(pipeline,
pCreateInfo->pDynamicState,
vp_info, ds_info, cb_info, rs_info);
vp_info, ds_info, cb_info, rs_info, cw_info);
/* V3D 4.2 doesn't support depth bounds testing so we don't advertise that
* feature and it shouldn't be used by any pipeline.

View File

@ -797,7 +797,8 @@ enum v3dv_dynamic_state_bits {
V3DV_DYNAMIC_BLEND_CONSTANTS = 1 << 5,
V3DV_DYNAMIC_DEPTH_BIAS = 1 << 6,
V3DV_DYNAMIC_LINE_WIDTH = 1 << 7,
V3DV_DYNAMIC_ALL = (1 << 8) - 1,
V3DV_DYNAMIC_COLOR_WRITE_ENABLE = 1 << 8,
V3DV_DYNAMIC_ALL = (1 << 9) - 1,
};
/* Flags for dirty pipeline state.
@ -820,6 +821,7 @@ enum v3dv_cmd_dirty_bits {
V3DV_CMD_DIRTY_DEPTH_BIAS = 1 << 14,
V3DV_CMD_DIRTY_LINE_WIDTH = 1 << 15,
V3DV_CMD_DIRTY_VIEW_INDEX = 1 << 16,
V3DV_CMD_DIRTY_COLOR_WRITE_ENABLE = 1 << 17,
};
struct v3dv_dynamic_state {
@ -857,6 +859,8 @@ struct v3dv_dynamic_state {
} depth_bias;
float line_width;
uint32_t color_write_enable;
};
extern const struct v3dv_dynamic_state default_dynamic_state;

View File

@ -1161,8 +1161,7 @@ v3dX(cmd_buffer_emit_blend)(struct v3dv_cmd_buffer *cmd_buffer)
const uint32_t blend_packets_size =
cl_packet_length(BLEND_ENABLES) +
cl_packet_length(BLEND_CONSTANT_COLOR) +
cl_packet_length(BLEND_CFG) * V3D_MAX_DRAW_BUFFERS +
cl_packet_length(COLOR_WRITE_MASKS);
cl_packet_length(BLEND_CFG) * V3D_MAX_DRAW_BUFFERS;
v3dv_cl_ensure_space_with_branch(&job->bcl, blend_packets_size);
v3dv_return_if_oom(cmd_buffer, NULL);
@ -1178,10 +1177,6 @@ v3dX(cmd_buffer_emit_blend)(struct v3dv_cmd_buffer *cmd_buffer)
if (pipeline->blend.enables & (1 << i))
cl_emit_prepacked(&job->bcl, &pipeline->blend.cfg[i]);
}
cl_emit(&job->bcl, COLOR_WRITE_MASKS, mask) {
mask.mask = pipeline->blend.color_write_masks;
}
}
if (pipeline->blend.needs_color_constants &&
@ -1197,6 +1192,22 @@ v3dX(cmd_buffer_emit_blend)(struct v3dv_cmd_buffer *cmd_buffer)
}
}
void
v3dX(cmd_buffer_emit_color_write_mask)(struct v3dv_cmd_buffer *cmd_buffer)
{
struct v3dv_job *job = cmd_buffer->state.job;
v3dv_cl_ensure_space_with_branch(&job->bcl, cl_packet_length(COLOR_WRITE_MASKS));
struct v3dv_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
struct v3dv_dynamic_state *dynamic = &cmd_buffer->state.dynamic;
cl_emit(&job->bcl, COLOR_WRITE_MASKS, mask) {
mask.mask = (~dynamic->color_write_enable |
pipeline->blend.color_write_masks) & 0xffff;
}
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_COLOR_WRITE_ENABLE;
}
static void
emit_flat_shade_flags(struct v3dv_job *job,
int varying_offset,

View File

@ -33,6 +33,9 @@
void
v3dX(job_emit_binning_flush)(struct v3dv_job *job);
void
v3dX(cmd_buffer_emit_color_write_mask)(struct v3dv_cmd_buffer *cmd_buffer);
void
v3dX(cmd_buffer_end_render_pass_secondary)(struct v3dv_cmd_buffer *cmd_buffer);