radv: implement VK_EXT_vertex_input_dynamic_state
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com> Acked-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11717>
This commit is contained in:
@@ -4414,6 +4414,8 @@ radv_CmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer, uint32_t firstBindi
|
||||
vb[idx].buffer = buffer;
|
||||
vb[idx].offset = pOffsets[i];
|
||||
vb[idx].size = size;
|
||||
/* if pStrides=NULL, it shouldn't overwrite the strides specified by CmdSetVertexInputEXT */
|
||||
if (pStrides)
|
||||
vb[idx].stride = stride;
|
||||
|
||||
if (buffer) {
|
||||
@@ -5371,6 +5373,64 @@ radv_CmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer, uint32_t attachmen
|
||||
state->dirty |= RADV_CMD_DIRTY_DYNAMIC_COLOR_WRITE_ENABLE;
|
||||
}
|
||||
|
||||
void
|
||||
radv_CmdSetVertexInputEXT(VkCommandBuffer commandBuffer, uint32_t vertexBindingDescriptionCount,
|
||||
const VkVertexInputBindingDescription2EXT *pVertexBindingDescriptions,
|
||||
uint32_t vertexAttributeDescriptionCount,
|
||||
const VkVertexInputAttributeDescription2EXT *pVertexAttributeDescriptions)
|
||||
{
|
||||
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
struct radv_vs_input_state *state = &cmd_buffer->state.dynamic_vs_input;
|
||||
|
||||
const VkVertexInputBindingDescription2EXT *bindings[MAX_VBS];
|
||||
for (unsigned i = 0; i < vertexBindingDescriptionCount; i++)
|
||||
bindings[pVertexBindingDescriptions[i].binding] = &pVertexBindingDescriptions[i];
|
||||
|
||||
state->attribute_mask = 0;
|
||||
state->instance_rate_inputs = 0;
|
||||
state->nontrivial_divisors = 0;
|
||||
state->post_shuffle = 0;
|
||||
state->alpha_adjust_lo = 0;
|
||||
state->alpha_adjust_hi = 0;
|
||||
|
||||
for (unsigned i = 0; i < vertexAttributeDescriptionCount; i++) {
|
||||
const VkVertexInputAttributeDescription2EXT *attrib = &pVertexAttributeDescriptions[i];
|
||||
const VkVertexInputBindingDescription2EXT *binding = bindings[attrib->binding];
|
||||
unsigned loc = attrib->location;
|
||||
const struct util_format_description *format_desc = vk_format_description(attrib->format);
|
||||
unsigned nfmt, dfmt;
|
||||
bool post_shuffle;
|
||||
enum radv_vs_input_alpha_adjust alpha_adjust;
|
||||
|
||||
state->attribute_mask |= 1u << loc;
|
||||
state->bindings[loc] = attrib->binding;
|
||||
if (binding->inputRate == VK_VERTEX_INPUT_RATE_INSTANCE) {
|
||||
state->instance_rate_inputs |= 1u << loc;
|
||||
state->divisors[loc] = binding->divisor;
|
||||
if (binding->divisor != 1)
|
||||
state->nontrivial_divisors |= 1u << loc;
|
||||
}
|
||||
cmd_buffer->vertex_bindings[attrib->binding].stride = binding->stride;
|
||||
state->offsets[loc] = attrib->offset;
|
||||
|
||||
radv_translate_vertex_format(cmd_buffer->device->physical_device, attrib->format, format_desc,
|
||||
&dfmt, &nfmt, &post_shuffle, &alpha_adjust);
|
||||
|
||||
state->formats[loc] = dfmt | (nfmt << 4);
|
||||
state->format_align_req_minus_1[loc] =
|
||||
format_desc->channel[0].size >= 32 ? 3 : (format_desc->block.bits / 8u - 1);
|
||||
state->format_sizes[loc] = format_desc->block.bits / 8u;
|
||||
|
||||
state->alpha_adjust_lo |= (alpha_adjust & 0x1) << loc;
|
||||
state->alpha_adjust_hi |= (alpha_adjust >> 1) << loc;
|
||||
|
||||
if (post_shuffle)
|
||||
state->post_shuffle |= 1u << loc;
|
||||
}
|
||||
|
||||
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_VERTEX_STATE;
|
||||
}
|
||||
|
||||
void
|
||||
radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
|
||||
const VkCommandBuffer *pCmdBuffers)
|
||||
|
@@ -1627,6 +1627,12 @@ radv_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
|
||||
features->maintenance4 = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT: {
|
||||
VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT *features =
|
||||
(VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT *)ext;
|
||||
features->vertexInputDynamicState = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2940,6 +2946,12 @@ radv_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCr
|
||||
image_float32_atomics = true;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT: {
|
||||
const VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT *features = (const void *)ext;
|
||||
if (features->vertexInputDynamicState)
|
||||
vs_prologs = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -1298,6 +1298,8 @@ radv_dynamic_state_mask(VkDynamicState state)
|
||||
return RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
|
||||
case VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT:
|
||||
return RADV_DYNAMIC_COLOR_WRITE_ENABLE;
|
||||
case VK_DYNAMIC_STATE_VERTEX_INPUT_EXT:
|
||||
return RADV_DYNAMIC_VERTEX_INPUT;
|
||||
default:
|
||||
unreachable("Unhandled dynamic state");
|
||||
}
|
||||
@@ -1334,7 +1336,8 @@ radv_pipeline_needed_dynamic_state(const VkGraphicsPipelineCreateInfo *pCreateIn
|
||||
if (pCreateInfo->pRasterizationState->rasterizerDiscardEnable &&
|
||||
!radv_is_state_dynamic(pCreateInfo, VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)) {
|
||||
return RADV_DYNAMIC_PRIMITIVE_TOPOLOGY | RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE |
|
||||
RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE | RADV_DYNAMIC_RASTERIZER_DISCARD_ENABLE;
|
||||
RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE | RADV_DYNAMIC_RASTERIZER_DISCARD_ENABLE |
|
||||
RADV_DYNAMIC_VERTEX_INPUT;
|
||||
}
|
||||
|
||||
if (!pCreateInfo->pRasterizationState->depthBiasEnable &&
|
||||
@@ -1681,7 +1684,8 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
|
||||
dynamic->line_stipple.pattern = rast_line_info->lineStipplePattern;
|
||||
}
|
||||
|
||||
if (!(states & RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE))
|
||||
if (!(states & RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE) ||
|
||||
!(states & RADV_DYNAMIC_VERTEX_INPUT))
|
||||
pipeline->graphics.uses_dynamic_stride = true;
|
||||
|
||||
const VkPipelineFragmentShadingRateStateCreateInfoKHR *shading_rate = vk_find_struct_const(
|
||||
@@ -2545,9 +2549,6 @@ radv_generate_graphics_pipeline_key(const struct radv_pipeline *pipeline,
|
||||
{
|
||||
RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass);
|
||||
struct radv_subpass *subpass = pass->subpasses + pCreateInfo->subpass;
|
||||
const VkPipelineVertexInputStateCreateInfo *input_state = pCreateInfo->pVertexInputState;
|
||||
const VkPipelineVertexInputDivisorStateCreateInfoEXT *divisor_state =
|
||||
vk_find_struct_const(input_state->pNext, PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT);
|
||||
bool uses_dynamic_stride = false;
|
||||
|
||||
struct radv_pipeline_key key;
|
||||
@@ -2558,6 +2559,25 @@ radv_generate_graphics_pipeline_key(const struct radv_pipeline *pipeline,
|
||||
|
||||
key.has_multiview_view_index = !!subpass->view_mask;
|
||||
|
||||
if (pCreateInfo->pDynamicState) {
|
||||
uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (pCreateInfo->pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_VERTEX_INPUT_EXT) {
|
||||
key.vs.dynamic_input_state = true;
|
||||
/* we don't care about use_dynamic_stride in this case */
|
||||
break;
|
||||
} else if (pCreateInfo->pDynamicState->pDynamicStates[i] ==
|
||||
VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT) {
|
||||
uses_dynamic_stride = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!key.vs.dynamic_input_state) {
|
||||
const VkPipelineVertexInputStateCreateInfo *input_state = pCreateInfo->pVertexInputState;
|
||||
const VkPipelineVertexInputDivisorStateCreateInfoEXT *divisor_state = vk_find_struct_const(
|
||||
input_state->pNext, PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT);
|
||||
|
||||
uint32_t binding_input_rate = 0;
|
||||
uint32_t instance_rate_divisors[MAX_VERTEX_ATTRIBS];
|
||||
for (unsigned i = 0; i < input_state->vertexBindingDescriptionCount; ++i) {
|
||||
@@ -2574,19 +2594,9 @@ radv_generate_graphics_pipeline_key(const struct radv_pipeline *pipeline,
|
||||
}
|
||||
}
|
||||
|
||||
if (pCreateInfo->pDynamicState) {
|
||||
uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (pCreateInfo->pDynamicState->pDynamicStates[i] ==
|
||||
VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT) {
|
||||
uses_dynamic_stride = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < input_state->vertexAttributeDescriptionCount; ++i) {
|
||||
const VkVertexInputAttributeDescription *desc = &input_state->pVertexAttributeDescriptions[i];
|
||||
const VkVertexInputAttributeDescription *desc =
|
||||
&input_state->pVertexAttributeDescriptions[i];
|
||||
const struct util_format_description *format_desc;
|
||||
unsigned location = desc->location;
|
||||
unsigned binding = desc->binding;
|
||||
@@ -2641,6 +2651,7 @@ radv_generate_graphics_pipeline_key(const struct radv_pipeline *pipeline,
|
||||
if (post_shuffle)
|
||||
key.vs.vertex_post_shuffle |= 1 << location;
|
||||
}
|
||||
}
|
||||
|
||||
const VkPipelineTessellationStateCreateInfo *tess =
|
||||
radv_pipeline_get_tessellation_state(pCreateInfo);
|
||||
@@ -5363,9 +5374,11 @@ radv_pipeline_generate_pm4(struct radv_pipeline *pipeline,
|
||||
|
||||
static void
|
||||
radv_pipeline_init_vertex_input_state(struct radv_pipeline *pipeline,
|
||||
const VkGraphicsPipelineCreateInfo *pCreateInfo)
|
||||
const VkGraphicsPipelineCreateInfo *pCreateInfo,
|
||||
const struct radv_pipeline_key *key)
|
||||
{
|
||||
const struct radv_shader_info *info = &radv_get_shader(pipeline, MESA_SHADER_VERTEX)->info;
|
||||
if (!key->vs.dynamic_input_state) {
|
||||
const VkPipelineVertexInputStateCreateInfo *vi_info = pCreateInfo->pVertexInputState;
|
||||
|
||||
for (uint32_t i = 0; i < vi_info->vertexBindingDescriptionCount; i++) {
|
||||
@@ -5384,6 +5397,7 @@ radv_pipeline_init_vertex_input_state(struct radv_pipeline *pipeline,
|
||||
desc->offset / pipeline->binding_stride[desc->binding];
|
||||
pipeline->attrib_bindings[desc->location] = desc->binding;
|
||||
}
|
||||
}
|
||||
|
||||
pipeline->use_per_attribute_vb_descs = info->vs.use_per_attribute_vb_descs;
|
||||
if (info->vs.dynamic_inputs)
|
||||
@@ -5541,7 +5555,7 @@ radv_pipeline_init(struct radv_pipeline *pipeline, struct radv_device *device,
|
||||
pCreateInfo->pTessellationState->patchControlPoints;
|
||||
}
|
||||
|
||||
radv_pipeline_init_vertex_input_state(pipeline, pCreateInfo);
|
||||
radv_pipeline_init_vertex_input_state(pipeline, pCreateInfo, &key);
|
||||
radv_pipeline_init_binning_state(pipeline, pCreateInfo, &blend);
|
||||
radv_pipeline_init_shader_stages_state(pipeline);
|
||||
radv_pipeline_init_scratch(device, pipeline);
|
||||
|
Reference in New Issue
Block a user