cmd_buf_queue(cmd_buffer, cmd);
}
+
+void lvp_CmdPushDescriptorSetKHR(
+ VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipelineLayout _layout,
+ uint32_t set,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet* pDescriptorWrites)
+{
+ LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
+ LVP_FROM_HANDLE(lvp_pipeline_layout, layout, _layout);
+ struct lvp_cmd_buffer_entry *cmd;
+ int cmd_size = 0;
+
+ cmd_size += descriptorWriteCount * sizeof(struct lvp_write_descriptor);
+
+ int count_descriptors = 0;
+
+ for (unsigned i = 0; i < descriptorWriteCount; i++) {
+ count_descriptors += pDescriptorWrites[i].descriptorCount;
+ }
+ cmd_size += count_descriptors * sizeof(union lvp_descriptor_info);
+ cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_PUSH_DESCRIPTOR_SET);
+ if (!cmd)
+ return;
+
+ cmd->u.push_descriptor_set.bind_point = pipelineBindPoint;
+ cmd->u.push_descriptor_set.layout = layout;
+ cmd->u.push_descriptor_set.set = set;
+ cmd->u.push_descriptor_set.descriptor_write_count = descriptorWriteCount;
+ cmd->u.push_descriptor_set.descriptors = (struct lvp_write_descriptor *)(cmd + 1);
+ cmd->u.push_descriptor_set.infos = (union lvp_descriptor_info *)(cmd->u.push_descriptor_set.descriptors + descriptorWriteCount);
+
+ unsigned descriptor_index = 0;
+
+ for (unsigned i = 0; i < descriptorWriteCount; i++) {
+ struct lvp_write_descriptor *desc = &cmd->u.push_descriptor_set.descriptors[i];
+
+ /* dstSet is ignored */
+ desc->dst_binding = pDescriptorWrites[i].dstBinding;
+ desc->dst_array_element = pDescriptorWrites[i].dstArrayElement;
+ desc->descriptor_count = pDescriptorWrites[i].descriptorCount;
+ desc->descriptor_type = pDescriptorWrites[i].descriptorType;
+
+ for (unsigned j = 0; j < desc->descriptor_count; j++) {
+ union lvp_descriptor_info *info = &cmd->u.push_descriptor_set.infos[descriptor_index + j];
+ switch (desc->descriptor_type) {
+ case VK_DESCRIPTOR_TYPE_SAMPLER:
+ info->sampler = lvp_sampler_from_handle(pDescriptorWrites[i].pImageInfo[j].sampler);
+ break;
+ case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+ info->sampler = lvp_sampler_from_handle(pDescriptorWrites[i].pImageInfo[j].sampler);
+ info->iview = lvp_image_view_from_handle(pDescriptorWrites[i].pImageInfo[j].imageView);
+ info->image_layout = pDescriptorWrites[i].pImageInfo[j].imageLayout;
+ break;
+ case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+ case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+ case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+ info->iview = lvp_image_view_from_handle(pDescriptorWrites[i].pImageInfo[j].imageView);
+ info->image_layout = pDescriptorWrites[i].pImageInfo[j].imageLayout;
+ break;
+ case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+ case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+ info->buffer_view = lvp_buffer_view_from_handle(pDescriptorWrites[i].pTexelBufferView[j]);
+ break;
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+ default:
+ info->buffer = lvp_buffer_from_handle(pDescriptorWrites[i].pBufferInfo[j].buffer);
+ info->offset = pDescriptorWrites[i].pBufferInfo[j].offset;
+ info->range = pDescriptorWrites[i].pBufferInfo[j].range;
+ break;
+ }
+ }
+ descriptor_index += desc->descriptor_count;
+ }
+ cmd_buf_queue(cmd_buffer, cmd);
+}
vk_foreach_struct(ext, pProperties->pNext) {
switch (ext->sType) {
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
+ VkPhysicalDevicePushDescriptorPropertiesKHR *properties =
+ (VkPhysicalDevicePushDescriptorPropertiesKHR *) ext;
+ properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS;
+ break;
+ }
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: {
VkPhysicalDeviceMaintenance3Properties *properties =
(VkPhysicalDeviceMaintenance3Properties*)ext;
return;
ss_idx += array_idx;
ss_idx += dyn_info->stage[stage].sampler_count;
- fill_sampler(&state->ss[p_stage][ss_idx], descriptor->sampler);
+ fill_sampler(&state->ss[p_stage][ss_idx], binding->immutable_samplers ? binding->immutable_samplers[array_idx] : descriptor->sampler);
if (state->num_sampler_states[p_stage] <= ss_idx)
state->num_sampler_states[p_stage] = ss_idx + 1;
state->ss_dirty[p_stage] = true;
state->pctx->draw_vbo(state->pctx, &state->info, &state->indirect_info, &state->draw, 1);
}
+static void handle_compute_push_descriptor_set(struct lvp_cmd_buffer_entry *cmd,
+ struct dyn_info *dyn_info,
+ struct rendering_state *state)
+{
+ struct lvp_cmd_push_descriptor_set *pds = &cmd->u.push_descriptor_set;
+ struct lvp_descriptor_set_layout *layout = pds->layout->set[pds->set].layout;
+
+ if (!(layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT))
+ return;
+
+ unsigned info_idx = 0;
+ for (unsigned i = 0; i < pds->descriptor_write_count; i++) {
+ struct lvp_write_descriptor *desc = &pds->descriptors[i];
+ struct lvp_descriptor_set_binding_layout *binding = &layout->binding[desc->dst_binding];
+
+ if (!binding->valid)
+ continue;
+
+ for (unsigned j = 0; j < desc->descriptor_count; j++) {
+ union lvp_descriptor_info *info = &pds->infos[info_idx + j];
+
+ handle_descriptor(state, dyn_info, binding,
+ MESA_SHADER_COMPUTE, PIPE_SHADER_COMPUTE,
+ j, desc->descriptor_type,
+ info);
+ }
+ info_idx += desc->descriptor_count;
+ }
+}
+
+static void handle_push_descriptor_set(struct lvp_cmd_buffer_entry *cmd,
+ struct rendering_state *state)
+{
+ struct lvp_cmd_push_descriptor_set *pds = &cmd->u.push_descriptor_set;
+ struct lvp_descriptor_set_layout *layout = pds->layout->set[pds->set].layout;
+ struct dyn_info dyn_info;
+
+ memset(&dyn_info.stage, 0, sizeof(dyn_info.stage));
+ dyn_info.dyn_index = 0;
+ if (pds->bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
+ handle_compute_push_descriptor_set(cmd, &dyn_info, state);
+ }
+
+ unsigned info_idx = 0;
+ for (unsigned i = 0; i < pds->descriptor_write_count; i++) {
+ struct lvp_write_descriptor *desc = &pds->descriptors[i];
+ struct lvp_descriptor_set_binding_layout *binding = &layout->binding[desc->dst_binding];
+
+ if (!binding->valid)
+ continue;
+
+ for (unsigned j = 0; j < desc->descriptor_count; j++) {
+ union lvp_descriptor_info *info = &pds->infos[info_idx + j];
+
+ if (layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)
+ handle_descriptor(state, &dyn_info, binding,
+ MESA_SHADER_VERTEX, PIPE_SHADER_VERTEX,
+ j, desc->descriptor_type,
+ info);
+ if (layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT)
+ handle_descriptor(state, &dyn_info, binding,
+ MESA_SHADER_FRAGMENT, PIPE_SHADER_FRAGMENT,
+ j, desc->descriptor_type,
+ info);
+ if (layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT)
+ handle_descriptor(state, &dyn_info, binding,
+ MESA_SHADER_GEOMETRY, PIPE_SHADER_GEOMETRY,
+ j, desc->descriptor_type,
+ info);
+ if (layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
+ handle_descriptor(state, &dyn_info, binding,
+ MESA_SHADER_TESS_CTRL, PIPE_SHADER_TESS_CTRL,
+ j, desc->descriptor_type,
+ info);
+ if (layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
+ handle_descriptor(state, &dyn_info, binding,
+ MESA_SHADER_TESS_EVAL, PIPE_SHADER_TESS_EVAL,
+ j, desc->descriptor_type,
+ info);
+ }
+ info_idx += desc->descriptor_count;
+ }
+}
+
static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
struct rendering_state *state)
{
emit_state(state);
handle_draw_indirect_count(cmd, state, true);
break;
+ case LVP_CMD_PUSH_DESCRIPTOR_SET:
+ handle_push_descriptor_set(cmd, state);
+ break;
}
}
}
Extension('VK_KHR_maintenance2', 1, False),
Extension('VK_KHR_maintenance3', 1, False),
Extension('VK_KHR_pipeline_executable_properties', 1, False),
- Extension('VK_KHR_push_descriptor', 1, False),
+ Extension('VK_KHR_push_descriptor', 1, True),
Extension('VK_KHR_relaxed_block_layout', 1, True),
Extension('VK_KHR_sampler_mirror_clamp_to_edge', 1, True),
Extension('VK_KHR_sampler_ycbcr_conversion', 1, False),
#define MAX_SETS 8
#define MAX_PUSH_CONSTANTS_SIZE 128
+#define MAX_PUSH_DESCRIPTORS 32
#define lvp_printflike(a, b) __attribute__((__format__(__printf__, a, b)))
LVP_CMD_EXECUTE_COMMANDS,
LVP_CMD_DRAW_INDIRECT_COUNT,
LVP_CMD_DRAW_INDEXED_INDIRECT_COUNT,
+ LVP_CMD_PUSH_DESCRIPTOR_SET,
};
struct lvp_cmd_bind_pipeline {
uint32_t stride;
};
+struct lvp_write_descriptor {
+ uint32_t dst_binding;
+ uint32_t dst_array_element;
+ uint32_t descriptor_count;
+ VkDescriptorType descriptor_type;
+};
+
+struct lvp_cmd_push_descriptor_set {
+ VkPipelineBindPoint bind_point;
+ struct lvp_pipeline_layout *layout;
+ uint32_t set;
+ uint32_t descriptor_write_count;
+ struct lvp_write_descriptor *descriptors;
+ union lvp_descriptor_info *infos;
+};
+
struct lvp_cmd_buffer_entry {
struct list_head cmd_link;
uint32_t cmd_type;
struct lvp_cmd_next_subpass next_subpass;
struct lvp_cmd_execute_commands execute_commands;
struct lvp_cmd_draw_indirect_count draw_indirect_count;
+ struct lvp_cmd_push_descriptor_set push_descriptor_set;
} u;
};