cmd_buffer->state.descriptors_dirty |=
set_layout->shader_stages & VK_SHADER_STAGE_ALL_GRAPHICS;
}
-
- /* Pipeline layout objects are required to live at least while any command
- * buffers that use them are in recording state. We need to grab a reference
- * to the pipeline layout being bound here so we can compute correct dynamic
- * offsets for VK_DESCRIPTOR_TYPE_*_DYNAMIC in dynamic_offset_for_binding()
- * when we record draw commands that come after this.
- */
- pipe_state->layout = layout;
}
void anv_CmdBindDescriptorSets(
map->surface_to_descriptor[map->surface_count] =
(struct anv_pipeline_binding) {
.set = ANV_DESCRIPTOR_SET_DESCRIPTORS,
- .binding = s,
+ .index = s,
};
state.set[s].desc_offset = map->surface_count;
map->surface_count++;
state.set[set].surface_offsets[b] = BINDLESS_OFFSET;
} else {
state.set[set].surface_offsets[b] = map->surface_count;
- struct anv_sampler **samplers = binding->immutable_samplers;
- for (unsigned i = 0; i < binding->array_size; i++) {
- uint8_t planes = samplers ? samplers[i]->n_planes : 1;
- for (uint8_t p = 0; p < planes; p++) {
+ if (binding->dynamic_offset_index < 0) {
+ struct anv_sampler **samplers = binding->immutable_samplers;
+ for (unsigned i = 0; i < binding->array_size; i++) {
+ uint8_t planes = samplers ? samplers[i]->n_planes : 1;
+ for (uint8_t p = 0; p < planes; p++) {
+ map->surface_to_descriptor[map->surface_count++] =
+ (struct anv_pipeline_binding) {
+ .set = set,
+ .index = binding->descriptor_index + i,
+ .plane = p,
+ };
+ }
+ }
+ } else {
+ for (unsigned i = 0; i < binding->array_size; i++) {
map->surface_to_descriptor[map->surface_count++] =
(struct anv_pipeline_binding) {
.set = set,
- .binding = b,
- .index = i,
- .plane = p,
+ .index = binding->descriptor_index + i,
+ .dynamic_offset_index =
+ layout->set[set].dynamic_offset_start +
+ binding->dynamic_offset_index + i,
};
}
}
map->sampler_to_descriptor[map->sampler_count++] =
(struct anv_pipeline_binding) {
.set = set,
- .binding = b,
- .index = i,
+ .index = binding->descriptor_index + i,
.plane = p,
};
}
const uint32_t set = var->data.descriptor_set;
const uint32_t binding = var->data.binding;
- const uint32_t array_size =
- layout->set[set].layout->binding[binding].array_size;
+ struct anv_descriptor_set_binding_layout *bind_layout =
+ &layout->set[set].layout->binding[binding];
+ const uint32_t array_size = bind_layout->array_size;
if (state.set[set].use_count[binding] == 0)
continue;
&map->surface_to_descriptor[state.set[set].surface_offsets[binding]];
for (unsigned i = 0; i < array_size; i++) {
assert(pipe_binding[i].set == set);
- assert(pipe_binding[i].binding == binding);
- assert(pipe_binding[i].index == i);
+ assert(pipe_binding[i].index == bind_layout->descriptor_index + i);
if (dim == GLSL_SAMPLER_DIM_SUBPASS ||
dim == GLSL_SAMPLER_DIM_SUBPASS_MS)
if (stage->key.wm.color_outputs_valid & BITFIELD_BIT(rt)) {
rt_bindings[rt] = (struct anv_pipeline_binding) {
.set = ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS,
- .binding = 0,
.index = rt,
};
} else {
/* Setup a null render target */
rt_bindings[rt] = (struct anv_pipeline_binding) {
.set = ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS,
- .binding = 0,
.index = UINT32_MAX,
};
}
/* Setup a null render target */
rt_bindings[0] = (struct anv_pipeline_binding) {
.set = ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS,
- .binding = 0,
.index = UINT32_MAX,
};
num_rt_bindings = 1;
#define ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS UINT8_MAX
struct anv_pipeline_binding {
- /* The descriptor set this surface corresponds to. The special value of
- * ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS indicates that the offset refers
- * to a color attachment and not a regular descriptor.
+ /** Index in the descriptor set
+ *
+ * This is a flattened index; the descriptor set layout is already taken
+ * into account.
*/
- uint8_t set;
+ uint32_t index;
- /* Binding in the descriptor set */
- uint32_t binding;
+ /** The descriptor set this surface corresponds to.
+ *
+ * The special ANV_DESCRIPTOR_SET_* values above indicates that this
+ * binding is not a normal descriptor set but something else.
+ */
+ uint8_t set;
- /* Index in the binding */
- uint32_t index;
+ union {
+ /** Plane in the binding index for images */
+ uint8_t plane;
- /* Plane in the binding index */
- uint8_t plane;
+ /** Input attachment index (relative to the subpass) */
+ uint8_t input_attachment_index;
- /* Input attachment index (relative to the subpass) */
- uint8_t input_attachment_index;
+ /** Dynamic offset index (for dynamic UBOs and SSBOs) */
+ uint8_t dynamic_offset_index;
+ };
- /* For a storage image, whether it is write-only */
+ /** For a storage image, whether it is write-only */
bool write_only;
};
*/
struct anv_cmd_pipeline_state {
struct anv_pipeline *pipeline;
- struct anv_pipeline_layout *layout;
struct anv_descriptor_set *descriptors[MAX_SETS];
uint32_t dynamic_offsets[MAX_DYNAMIC_BUFFERS];
cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_ALL_GRAPHICS;
}
-static const struct anv_descriptor *
-anv_descriptor_for_binding(const struct anv_cmd_pipeline_state *pipe_state,
- const struct anv_pipeline_binding *binding)
-{
- assert(binding->set < MAX_SETS);
- const struct anv_descriptor_set *set =
- pipe_state->descriptors[binding->set];
- const uint32_t offset =
- set->layout->binding[binding->binding].descriptor_index;
- return &set->descriptors[offset + binding->index];
-}
-
-static uint32_t
-dynamic_offset_for_binding(const struct anv_cmd_pipeline_state *pipe_state,
- const struct anv_pipeline_binding *binding)
-{
- assert(binding->set < MAX_SETS);
- const struct anv_descriptor_set *set =
- pipe_state->descriptors[binding->set];
-
- uint32_t dynamic_offset_idx =
- pipe_state->layout->set[binding->set].dynamic_offset_start +
- set->layout->binding[binding->binding].dynamic_offset_index +
- binding->index;
-
- return pipe_state->dynamic_offsets[dynamic_offset_idx];
-}
-
static struct anv_address
anv_descriptor_set_address(struct anv_cmd_buffer *cmd_buffer,
struct anv_descriptor_set *set)
if (binding->set == ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS) {
/* Color attachment binding */
assert(stage == MESA_SHADER_FRAGMENT);
- assert(binding->binding == 0);
if (binding->index < subpass->color_count) {
const unsigned att =
subpass->color_attachments[binding->index].attachment;
* given by binding->binding. (Yes, that's confusing.)
*/
struct anv_descriptor_set *set =
- pipe_state->descriptors[binding->binding];
+ pipe_state->descriptors[binding->index];
assert(set->desc_mem.alloc_size);
assert(set->desc_surface_state.alloc_size);
bt_map[s] = set->desc_surface_state.offset + state_offset;
}
const struct anv_descriptor *desc =
- anv_descriptor_for_binding(pipe_state, binding);
+ &pipe_state->descriptors[binding->set]->descriptors[binding->index];
switch (desc->type) {
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
/* Compute the offset within the buffer */
uint32_t dynamic_offset =
- dynamic_offset_for_binding(pipe_state, binding);
+ pipe_state->dynamic_offsets[binding->dynamic_offset_index];
uint64_t offset = desc->offset + dynamic_offset;
/* Clamp to the buffer size */
offset = MIN2(offset, desc->buffer->size);
for (uint32_t s = 0; s < map->sampler_count; s++) {
struct anv_pipeline_binding *binding = &map->sampler_to_descriptor[s];
const struct anv_descriptor *desc =
- anv_descriptor_for_binding(pipe_state, binding);
+ &pipe_state->descriptors[binding->set]->descriptors[binding->index];
if (desc->type != VK_DESCRIPTOR_TYPE_SAMPLER &&
desc->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
* confusing.)
*/
struct anv_descriptor_set *set =
- gfx_state->base.descriptors[binding->binding];
+ gfx_state->base.descriptors[binding->index];
struct anv_address desc_buffer_addr =
anv_descriptor_set_address(cmd_buffer, set);
const unsigned desc_buffer_size = set->desc_mem.alloc_size;
read_addr = anv_address_add(desc_buffer_addr,
range->start * 32);
} else {
+ struct anv_descriptor_set *set =
+ gfx_state->base.descriptors[binding->set];
const struct anv_descriptor *desc =
- anv_descriptor_for_binding(&gfx_state->base, binding);
+ &set->descriptors[binding->index];
if (desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
read_len = MIN2(range->length,
assert(desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
uint32_t dynamic_offset =
- dynamic_offset_for_binding(&gfx_state->base, binding);
+ gfx_state->base.dynamic_offsets[binding->dynamic_offset_index];
uint32_t buf_offset =
MIN2(desc->offset + dynamic_offset, desc->buffer->size);
uint32_t buf_range =
continue;
}
- assert(binding->binding == 0);
const VkPipelineColorBlendAttachmentState *a =
&info->pAttachments[binding->index];