vk: Add support for sampler descriptors
This commit is contained in:
@@ -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]));
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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];
|
||||||
|
Reference in New Issue
Block a user