lavapipe: add support for VK_KHR_push_descriptor

Acked-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7912>
This commit is contained in:
Dave Airlie 2020-12-04 10:24:46 +10:00 committed by Marge Bot
parent e7cb57d73e
commit 6be19765cf
5 changed files with 194 additions and 2 deletions

View file

@ -1473,3 +1473,83 @@ void lvp_CmdDrawIndexedIndirectCount(
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);
}

View file

@ -554,6 +554,12 @@ void lvp_GetPhysicalDeviceProperties2(
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;

View file

@ -752,7 +752,7 @@ static void fill_sampler_stage(struct rendering_state *state,
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;
@ -2335,6 +2335,90 @@ static void handle_draw_indirect_count(struct lvp_cmd_buffer_entry *cmd,
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)
{
@ -2486,6 +2570,9 @@ static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
emit_state(state);
handle_draw_indirect_count(cmd, state, true);
break;
case LVP_CMD_PUSH_DESCRIPTOR_SET:
handle_push_descriptor_set(cmd, state);
break;
}
}
}

View file

@ -87,7 +87,7 @@ EXTENSIONS = [
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),

View file

@ -63,6 +63,7 @@ extern "C" {
#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)))
@ -646,6 +647,7 @@ enum lvp_cmds {
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 {
@ -919,6 +921,22 @@ struct lvp_cmd_draw_indirect_count {
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;
@ -960,6 +978,7 @@ struct lvp_cmd_buffer_entry {
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;
};