vk: Add support for sampler descriptors

This commit is contained in:
Kristian Høgsberg
2015-05-13 14:43:08 -07:00
parent 4f9eaf77a5
commit 83c7e1f1db
4 changed files with 153 additions and 50 deletions

View File

@@ -70,8 +70,8 @@ set_binding_table_layout(struct brw_stage_prog_data *prog_data,
else else
bias = 0; bias = 0;
count = pipeline->layout->stage[stage].count; count = pipeline->layout->stage[stage].surface_count;
entries = pipeline->layout->stage[stage].entries; entries = pipeline->layout->stage[stage].surface_entries;
prog_data->map_entries = prog_data->map_entries =
(uint32_t *) malloc(count * sizeof(prog_data->map_entries[0])); (uint32_t *) malloc(count * sizeof(prog_data->map_entries[0]));

View File

@@ -1415,8 +1415,8 @@ VkResult VKAPI vkCreateDescriptorSetLayout(
{ {
struct anv_device *device = (struct anv_device *) _device; struct anv_device *device = (struct anv_device *) _device;
struct anv_descriptor_set_layout *set_layout; struct anv_descriptor_set_layout *set_layout;
uint32_t count, k; uint32_t count, k, num_entries;
size_t size, total; size_t size, sampler_total, surface_total;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
@@ -1432,7 +1432,8 @@ VkResult VKAPI vkCreateDescriptorSetLayout(
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
k = 0; k = 0;
total = 0; sampler_total = 0;
surface_total = 0;
for (uint32_t i = 0; i < pCreateInfo->count; i++) { for (uint32_t i = 0; i < pCreateInfo->count; i++) {
for (uint32_t j = 0; j < pCreateInfo->pBinding[i].count; j++) { for (uint32_t j = 0; j < pCreateInfo->pBinding[i].count; j++) {
set_layout->bindings[k].mask = pCreateInfo->pBinding[i].stageFlags; set_layout->bindings[k].mask = pCreateInfo->pBinding[i].stageFlags;
@@ -1440,11 +1441,36 @@ VkResult VKAPI vkCreateDescriptorSetLayout(
k++; k++;
} }
total += pCreateInfo->pBinding[i].count * num_entries = pCreateInfo->pBinding[i].count *
__builtin_popcount(pCreateInfo->pBinding[i].stageFlags); __builtin_popcount(pCreateInfo->pBinding[i].stageFlags);
switch (pCreateInfo->pBinding[i].descriptorType) {
case VK_DESCRIPTOR_TYPE_SAMPLER:
sampler_total += num_entries;
break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
sampler_total += num_entries;
surface_total += num_entries;
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
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:
surface_total += num_entries;
break;
default:
unreachable("invalid descriptor type");
}
} }
set_layout->total = total; set_layout->sampler_total = sampler_total;
set_layout->surface_total = surface_total;
set_layout->count = count; set_layout->count = count;
*pSetLayout = (VkDescriptorSetLayout) set_layout; *pSetLayout = (VkDescriptorSetLayout) set_layout;
@@ -2136,36 +2162,25 @@ void VKAPI vkCmdBindVertexBuffers(
static void static void
flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer) flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
{ {
static const uint32_t opcodes[] = {
[VK_SHADER_STAGE_VERTEX] = 38,
[VK_SHADER_STAGE_TESS_CONTROL] = 39,
[VK_SHADER_STAGE_TESS_EVALUATION] = 40,
[VK_SHADER_STAGE_GEOMETRY] = 41,
[VK_SHADER_STAGE_FRAGMENT] = 42,
[VK_SHADER_STAGE_COMPUTE] = 0,
};
struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout; struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout;
struct anv_framebuffer *framebuffer = cmd_buffer->framebuffer; struct anv_framebuffer *framebuffer = cmd_buffer->framebuffer;
for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) { for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) {
uint32_t bias = s == VK_SHADER_STAGE_FRAGMENT ? MAX_RTS : 0; uint32_t bias = s == VK_SHADER_STAGE_FRAGMENT ? MAX_RTS : 0;
uint32_t count, *table; uint32_t binding_table_length, *table;
struct anv_state table_state; struct anv_state table_state;
if (layout) if (layout)
count = layout->stage[s].count + bias; binding_table_length = layout->stage[s].surface_count + bias;
else if (s == VK_SHADER_STAGE_FRAGMENT) else if (s == VK_SHADER_STAGE_FRAGMENT)
count = framebuffer->color_attachment_count; binding_table_length = framebuffer->color_attachment_count;
else else
count = 0; binding_table_length = 0;
if (count == 0) if (binding_table_length > 0)
continue; table_state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
binding_table_length * 4, 32);
table_state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
count * 4, 32);
table = table_state.map; table = table_state.map;
if (s == VK_SHADER_STAGE_FRAGMENT) { if (s == VK_SHADER_STAGE_FRAGMENT) {
@@ -2182,8 +2197,8 @@ flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
} }
if (layout) { if (layout) {
for (uint32_t i = 0; i < layout->stage[s].count; i++) { for (uint32_t i = 0; i < layout->stage[s].surface_count; i++) {
struct anv_pipeline_layout_entry *e = &layout->stage[s].entries[i]; struct anv_pipeline_layout_entry *e = &layout->stage[s].surface_entries[i];
struct anv_descriptor *d = struct anv_descriptor *d =
&cmd_buffer->descriptor_sets[e->set]->descriptors[e->index]; &cmd_buffer->descriptor_sets[e->set]->descriptors[e->index];
struct anv_image_view *image_view; struct anv_image_view *image_view;
@@ -2227,15 +2242,62 @@ flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
} }
} }
/* FIXME: Samplers */
/* The binding table pointer commands all have the same structure, only /* The binding table pointer commands all have the same structure, only
* the opcode differs. * the opcode differs.
*/ */
anv_batch_emit(&cmd_buffer->batch, static const uint32_t binding_table_opcodes[] = {
GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS, [VK_SHADER_STAGE_VERTEX] = 38,
._3DCommandSubOpcode = opcodes[s], [VK_SHADER_STAGE_TESS_CONTROL] = 39,
.PointertoVSBindingTable = table_state.offset); [VK_SHADER_STAGE_TESS_EVALUATION] = 40,
[VK_SHADER_STAGE_GEOMETRY] = 41,
[VK_SHADER_STAGE_FRAGMENT] = 42,
[VK_SHADER_STAGE_COMPUTE] = 0,
};
if (binding_table_length > 0)
anv_batch_emit(&cmd_buffer->batch,
GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS,
._3DCommandSubOpcode = binding_table_opcodes[s],
.PointertoVSBindingTable = table_state.offset);
if (layout && layout->stage[s].sampler_count > 0) {
struct anv_state sampler_state;
sampler_state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
layout->stage[s].sampler_count * 16, 32);
for (uint32_t i = 0; i < layout->stage[s].sampler_count; i++) {
struct anv_pipeline_layout_entry *e = &layout->stage[s].sampler_entries[i];
struct anv_sampler *sampler;
switch (e->type) {
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
sampler =
cmd_buffer->descriptor_sets[e->set]->descriptors[e->index].sampler;
break;
default:
unreachable("non-sampler descriptor in sampler entries");
break;
}
memcpy(sampler_state.map + i * 16, sampler->state, sizeof(sampler->state));
}
static const uint32_t sampler_state_opcodes[] = {
[VK_SHADER_STAGE_VERTEX] = 43,
[VK_SHADER_STAGE_TESS_CONTROL] = 44, /* HS */
[VK_SHADER_STAGE_TESS_EVALUATION] = 45, /* DS */
[VK_SHADER_STAGE_GEOMETRY] = 46,
[VK_SHADER_STAGE_FRAGMENT] = 47,
[VK_SHADER_STAGE_COMPUTE] = 0,
};
anv_batch_emit(&cmd_buffer->batch,
GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS,
._3DCommandSubOpcode = sampler_state_opcodes[s],
.PointertoVSSamplerState = sampler_state.offset);
}
} }
} }

View File

@@ -560,43 +560,81 @@ VkResult VKAPI vkCreatePipelineLayout(
{ {
struct anv_device *device = (struct anv_device *) _device; struct anv_device *device = (struct anv_device *) _device;
struct anv_pipeline_layout *layout; struct anv_pipeline_layout *layout;
struct anv_pipeline_layout_entry *entry; struct anv_pipeline_layout_entry *sampler_entry, *surface_entry;
uint32_t total; uint32_t sampler_total, surface_total;
size_t size; size_t size;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO); assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
total = 0; sampler_total = 0;
surface_total = 0;
for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) { for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) {
struct anv_descriptor_set_layout *set_layout = struct anv_descriptor_set_layout *set_layout =
(struct anv_descriptor_set_layout *) pCreateInfo->pSetLayouts[i]; (struct anv_descriptor_set_layout *) pCreateInfo->pSetLayouts[i];
for (uint32_t j = 0; j < set_layout->count; j++) for (uint32_t j = 0; j < set_layout->count; j++) {
total += set_layout->total; sampler_total += set_layout->sampler_total;
surface_total += set_layout->surface_total;
}
} }
size = sizeof(*layout) + total * sizeof(layout->entries[0]); size = sizeof(*layout) +
(sampler_total + surface_total) * sizeof(layout->entries[0]);
layout = anv_device_alloc(device, size, 8, layout = anv_device_alloc(device, size, 8,
VK_SYSTEM_ALLOC_TYPE_API_OBJECT); VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
if (layout == NULL) if (layout == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
entry = layout->entries; sampler_entry = layout->entries;
surface_entry = layout->entries + sampler_total;
for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) { for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) {
layout->stage[s].entries = entry; layout->stage[s].sampler_entries = sampler_entry;
layout->stage[s].surface_entries = surface_entry;
for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) { for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) {
struct anv_descriptor_set_layout *set_layout = struct anv_descriptor_set_layout *set_layout =
(struct anv_descriptor_set_layout *) pCreateInfo->pSetLayouts[i]; (struct anv_descriptor_set_layout *) pCreateInfo->pSetLayouts[i];
for (uint32_t j = 0; j < set_layout->count; j++) for (uint32_t j = 0; j < set_layout->count; j++) {
if (set_layout->bindings[j].mask & (1 << s)) { if (set_layout->bindings[j].mask & (1 << s)) {
entry->type = set_layout->bindings[j].type; switch (set_layout->bindings[j].type) {
entry->set = i; case VK_DESCRIPTOR_TYPE_SAMPLER:
entry->index = j; sampler_entry->type = set_layout->bindings[j].type;
entry++; sampler_entry->set = i;
sampler_entry->index = j;
sampler_entry++;
break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
sampler_entry->type = set_layout->bindings[j].type;
sampler_entry->set = i;
sampler_entry->index = j;
sampler_entry++;
/* fall through */
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
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:
surface_entry->type = set_layout->bindings[j].type;
surface_entry->set = i;
surface_entry->index = j;
surface_entry++;
break;
default:
break;
}
} }
}
} }
layout->stage[s].count = entry - layout->stage[s].entries; layout->stage[s].sampler_count =
sampler_entry - layout->stage[s].sampler_entries;
layout->stage[s].surface_count =
surface_entry - layout->stage[s].surface_entries;
} }
*pPipelineLayout = (VkPipelineLayout) layout; *pPipelineLayout = (VkPipelineLayout) layout;

View File

@@ -446,7 +446,8 @@ struct anv_dynamic_cb_state {
}; };
struct anv_descriptor_set_layout { struct anv_descriptor_set_layout {
uint32_t total; /* total number of entries in all stages */ uint32_t sampler_total; /* total number of samplers in all stages */
uint32_t surface_total; /* total number of surfaces in all stages */
uint32_t count; uint32_t count;
struct { struct {
VkDescriptorType type; VkDescriptorType type;
@@ -476,8 +477,10 @@ struct anv_pipeline_layout_entry {
struct anv_pipeline_layout { struct anv_pipeline_layout {
struct { struct {
uint32_t count; uint32_t sampler_count;
struct anv_pipeline_layout_entry *entries; struct anv_pipeline_layout_entry *sampler_entries;
uint32_t surface_count;
struct anv_pipeline_layout_entry *surface_entries;
} stage[VK_NUM_SHADER_STAGE]; } stage[VK_NUM_SHADER_STAGE];
struct anv_pipeline_layout_entry entries[0]; struct anv_pipeline_layout_entry entries[0];