{
struct anv_device *device = (struct anv_device *) _device;
struct anv_descriptor_set_layout *set_layout;
- uint32_t count, k;
- size_t size, total;
+ uint32_t count, k, num_entries;
+ size_t size, sampler_total, surface_total;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
k = 0;
- total = 0;
+ sampler_total = 0;
+ surface_total = 0;
for (uint32_t i = 0; i < pCreateInfo->count; i++) {
for (uint32_t j = 0; j < pCreateInfo->pBinding[i].count; j++) {
set_layout->bindings[k].mask = pCreateInfo->pBinding[i].stageFlags;
k++;
}
- total += pCreateInfo->pBinding[i].count *
+ num_entries = pCreateInfo->pBinding[i].count *
__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;
*pSetLayout = (VkDescriptorSetLayout) set_layout;
static void
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_framebuffer *framebuffer = cmd_buffer->framebuffer;
for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) {
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;
if (layout)
- count = layout->stage[s].count + bias;
+ binding_table_length = layout->stage[s].surface_count + bias;
else if (s == VK_SHADER_STAGE_FRAGMENT)
- count = framebuffer->color_attachment_count;
+ binding_table_length = framebuffer->color_attachment_count;
else
- count = 0;
+ binding_table_length = 0;
- if (count == 0)
- continue;
-
- table_state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
- count * 4, 32);
+ if (binding_table_length > 0)
+ table_state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
+ binding_table_length * 4, 32);
table = table_state.map;
if (s == VK_SHADER_STAGE_FRAGMENT) {
}
if (layout) {
- for (uint32_t i = 0; i < layout->stage[s].count; i++) {
- struct anv_pipeline_layout_entry *e = &layout->stage[s].entries[i];
+ for (uint32_t i = 0; i < layout->stage[s].surface_count; i++) {
+ struct anv_pipeline_layout_entry *e = &layout->stage[s].surface_entries[i];
struct anv_descriptor *d =
&cmd_buffer->descriptor_sets[e->set]->descriptors[e->index];
struct anv_image_view *image_view;
}
}
- /* FIXME: Samplers */
-
/* The binding table pointer commands all have the same structure, only
* the opcode differs.
*/
- anv_batch_emit(&cmd_buffer->batch,
- GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS,
- ._3DCommandSubOpcode = opcodes[s],
- .PointertoVSBindingTable = table_state.offset);
+ static const uint32_t binding_table_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,
+ };
+
+ 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);
+ }
}
}
{
struct anv_device *device = (struct anv_device *) _device;
struct anv_pipeline_layout *layout;
- struct anv_pipeline_layout_entry *entry;
- uint32_t total;
+ struct anv_pipeline_layout_entry *sampler_entry, *surface_entry;
+ uint32_t sampler_total, surface_total;
size_t size;
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++) {
struct anv_descriptor_set_layout *set_layout =
(struct anv_descriptor_set_layout *) pCreateInfo->pSetLayouts[i];
- for (uint32_t j = 0; j < set_layout->count; j++)
- total += set_layout->total;
+ for (uint32_t j = 0; j < set_layout->count; j++) {
+ 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,
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
if (layout == NULL)
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++) {
- 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++) {
struct anv_descriptor_set_layout *set_layout =
(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)) {
- entry->type = set_layout->bindings[j].type;
- entry->set = i;
- entry->index = j;
- entry++;
+ switch (set_layout->bindings[j].type) {
+ case VK_DESCRIPTOR_TYPE_SAMPLER:
+ sampler_entry->type = set_layout->bindings[j].type;
+ 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;