vk: Make cmd_buffer->bindings a pointer

This lets us save and restore efficiently by just moving the pointer to
a temporary bindings struct for meta.
This commit is contained in:
Kristian Høgsberg
2015-05-15 17:03:18 -07:00
parent 9540130c41
commit 3b9f32e893
3 changed files with 65 additions and 40 deletions

View File

@@ -1860,7 +1860,8 @@ VkResult VKAPI vkCreateCommandBuffer(
cmd_buffer->device = device; cmd_buffer->device = device;
cmd_buffer->rs_state = NULL; cmd_buffer->rs_state = NULL;
cmd_buffer->vp_state = NULL; cmd_buffer->vp_state = NULL;
memset(&cmd_buffer->bindings, 0, sizeof(cmd_buffer->bindings)); memset(&cmd_buffer->default_bindings, 0, sizeof(cmd_buffer->default_bindings));
cmd_buffer->bindings = &cmd_buffer->default_bindings;
result = anv_batch_init(&cmd_buffer->batch, device); result = anv_batch_init(&cmd_buffer->batch, device);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
@@ -2165,6 +2166,7 @@ void VKAPI vkCmdBindDescriptorSets(
{ {
struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer; struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout; struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout;
struct anv_bindings *bindings = cmd_buffer->bindings;
uint32_t offset = 0; uint32_t offset = 0;
for (uint32_t i = 0; i < setCount; i++) { for (uint32_t i = 0; i < setCount; i++) {
@@ -2181,7 +2183,6 @@ void VKAPI vkCmdBindDescriptorSets(
start = bias + layout->set[firstSet + i].surface_start[s]; start = bias + layout->set[firstSet + i].surface_start[s];
for (uint32_t b = 0; b < set_layout->stage[s].surface_count; b++) { for (uint32_t b = 0; b < set_layout->stage[s].surface_count; b++) {
struct anv_surface_view *view = set->descriptors[surface_to_desc[b]].view; struct anv_surface_view *view = set->descriptors[surface_to_desc[b]].view;
struct anv_bindings *bindings = &cmd_buffer->bindings;
bindings->descriptors[s].surfaces[start + b] = bindings->descriptors[s].surfaces[start + b] =
view->surface_state.offset; view->surface_state.offset;
@@ -2193,7 +2194,7 @@ void VKAPI vkCmdBindDescriptorSets(
for (uint32_t b = 0; b < set_layout->stage[s].sampler_count; b++) { for (uint32_t b = 0; b < set_layout->stage[s].sampler_count; b++) {
struct anv_sampler *sampler = set->descriptors[sampler_to_desc[b]].sampler; struct anv_sampler *sampler = set->descriptors[sampler_to_desc[b]].sampler;
memcpy(&cmd_buffer->bindings.descriptors[s].samplers[start + b], memcpy(&bindings->descriptors[s].samplers[start + b],
sampler->state, sizeof(sampler->state)); sampler->state, sizeof(sampler->state));
} }
} }
@@ -2234,13 +2235,14 @@ void VKAPI vkCmdBindVertexBuffers(
const VkDeviceSize* pOffsets) const VkDeviceSize* pOffsets)
{ {
struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer; struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
struct anv_bindings *bindings = cmd_buffer->bindings;
/* We have to defer setting up vertex buffer since we need the buffer /* We have to defer setting up vertex buffer since we need the buffer
* stride from the pipeline. */ * stride from the pipeline. */
for (uint32_t i = 0; i < bindingCount; i++) { for (uint32_t i = 0; i < bindingCount; i++) {
cmd_buffer->bindings.vb[startBinding + i].buffer = (struct anv_buffer *) pBuffers[i]; bindings->vb[startBinding + i].buffer = (struct anv_buffer *) pBuffers[i];
cmd_buffer->bindings.vb[startBinding + i].offset = pOffsets[i]; bindings->vb[startBinding + i].offset = pOffsets[i];
cmd_buffer->vb_dirty |= 1 << (startBinding + i); cmd_buffer->vb_dirty |= 1 << (startBinding + i);
} }
} }
@@ -2249,38 +2251,48 @@ static void
flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer) flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
{ {
struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout; struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout;
struct anv_bindings *bindings = cmd_buffer->bindings;
uint32_t layers = cmd_buffer->framebuffer->layers;
uint32_t surface_count;
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;
uint32_t binding_table_length;
if (s == VK_SHADER_STAGE_FRAGMENT) {
bias = MAX_RTS;
layers = cmd_buffer->framebuffer->layers;
} else {
bias = 0;
layers = 0;
}
/* This is a little awkward: layout can be NULL but we still have to /* This is a little awkward: layout can be NULL but we still have to
* allocate and set a binding table for the PS stage for render * allocate and set a binding table for the PS stage for render
* targets. */ * targets. */
if (layout) if (layout)
binding_table_length = layout->stage[s].surface_count + bias; surface_count = layout->stage[s].surface_count;
else else
binding_table_length = bias; surface_count = 0;
if (binding_table_length > 0) { if (layers + surface_count > 0) {
struct anv_state state; struct anv_state state;
uint32_t size; uint32_t size;
size = binding_table_length * sizeof(uint32_t); size = (layers + surface_count) * sizeof(uint32_t);
state = state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream, size, 32);
anv_state_stream_alloc(&cmd_buffer->surface_state_stream, size, 32); memcpy(state.map, bindings->descriptors[s].surfaces, size);
memcpy(state.map, cmd_buffer->bindings.descriptors[s].surfaces, size);
for (uint32_t i = 0; i < binding_table_length; i++) {
uint32_t offset = cmd_buffer->bindings.descriptors[s].surfaces[i];
if (offset == 0)
continue;
for (uint32_t i = 0; i < layers; i++)
anv_reloc_list_add(&cmd_buffer->batch.surf_relocs, anv_reloc_list_add(&cmd_buffer->batch.surf_relocs,
offset + 8 * sizeof(int32_t), bindings->descriptors[s].surfaces[i] + 8 * sizeof(int32_t),
cmd_buffer->bindings.descriptors[s].relocs[i].bo, bindings->descriptors[s].relocs[i].bo,
cmd_buffer->bindings.descriptors[s].relocs[i].offset); bindings->descriptors[s].relocs[i].offset);
}
for (uint32_t i = 0; i < surface_count; i++)
anv_reloc_list_add(&cmd_buffer->batch.surf_relocs,
bindings->descriptors[s].surfaces[bias + i] + 8 * sizeof(int32_t),
bindings->descriptors[s].relocs[bias + i].bo,
bindings->descriptors[s].relocs[bias + i].offset);
static const uint32_t binding_table_opcodes[] = { static const uint32_t binding_table_opcodes[] = {
[VK_SHADER_STAGE_VERTEX] = 38, [VK_SHADER_STAGE_VERTEX] = 38,
@@ -2303,7 +2315,7 @@ flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
size = layout->stage[s].sampler_count * 16; size = layout->stage[s].sampler_count * 16;
state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream, size, 32); state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream, size, 32);
memcpy(state.map, cmd_buffer->bindings.descriptors[s].samplers, size); memcpy(state.map, bindings->descriptors[s].samplers, size);
static const uint32_t sampler_state_opcodes[] = { static const uint32_t sampler_state_opcodes[] = {
[VK_SHADER_STAGE_VERTEX] = 43, [VK_SHADER_STAGE_VERTEX] = 43,
@@ -2326,6 +2338,7 @@ static void
anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer) anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
{ {
struct anv_pipeline *pipeline = cmd_buffer->pipeline; struct anv_pipeline *pipeline = cmd_buffer->pipeline;
struct anv_bindings *bindings = cmd_buffer->bindings;
const uint32_t num_buffers = __builtin_popcount(cmd_buffer->vb_dirty); const uint32_t num_buffers = __builtin_popcount(cmd_buffer->vb_dirty);
const uint32_t num_dwords = 1 + num_buffers * 4; const uint32_t num_dwords = 1 + num_buffers * 4;
uint32_t *p; uint32_t *p;
@@ -2335,8 +2348,8 @@ anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
GEN8_3DSTATE_VERTEX_BUFFERS); GEN8_3DSTATE_VERTEX_BUFFERS);
uint32_t vb, i = 0; uint32_t vb, i = 0;
for_each_bit(vb, cmd_buffer->vb_dirty) { for_each_bit(vb, cmd_buffer->vb_dirty) {
struct anv_buffer *buffer = cmd_buffer->bindings.vb[vb].buffer; struct anv_buffer *buffer = bindings->vb[vb].buffer;
uint32_t offset = cmd_buffer->bindings.vb[vb].offset; uint32_t offset = bindings->vb[vb].offset;
struct GEN8_VERTEX_BUFFER_STATE state = { struct GEN8_VERTEX_BUFFER_STATE state = {
.VertexBufferIndex = vb, .VertexBufferIndex = vb,
@@ -2768,6 +2781,22 @@ VkResult VKAPI vkCreateRenderPass(
return VK_SUCCESS; return VK_SUCCESS;
} }
void
anv_cmd_buffer_fill_render_targets(struct anv_cmd_buffer *cmd_buffer)
{
struct anv_framebuffer *framebuffer = cmd_buffer->framebuffer;
struct anv_bindings *bindings = cmd_buffer->bindings;
for (uint32_t i = 0; i < framebuffer->color_attachment_count; i++) {
struct anv_surface_view *view = framebuffer->color_attachments[i];
bindings->descriptors[VK_SHADER_STAGE_FRAGMENT].surfaces[i] = view->surface_state.offset;
bindings->descriptors[VK_SHADER_STAGE_FRAGMENT].relocs[i].bo = view->bo;
bindings->descriptors[VK_SHADER_STAGE_FRAGMENT].relocs[i].offset = view->offset;
}
cmd_buffer->dirty |= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY;
}
void VKAPI vkCmdBeginRenderPass( void VKAPI vkCmdBeginRenderPass(
VkCmdBuffer cmdBuffer, VkCmdBuffer cmdBuffer,
const VkRenderPassBegin* pRenderPassBegin) const VkRenderPassBegin* pRenderPassBegin)
@@ -2789,17 +2818,7 @@ void VKAPI vkCmdBeginRenderPass(
.DrawingRectangleOriginY = 0, .DrawingRectangleOriginY = 0,
.DrawingRectangleOriginX = 0); .DrawingRectangleOriginX = 0);
for (uint32_t i = 0; i < framebuffer->color_attachment_count; i++) { anv_cmd_buffer_fill_render_targets(cmd_buffer);
struct anv_surface_view *view = framebuffer->color_attachments[i];
cmd_buffer->bindings.descriptors[VK_SHADER_STAGE_FRAGMENT].surfaces[i] =
view->surface_state.offset;
cmd_buffer->bindings.descriptors[VK_SHADER_STAGE_FRAGMENT].relocs[i].bo =
view->bo;
cmd_buffer->bindings.descriptors[VK_SHADER_STAGE_FRAGMENT].relocs[i].offset =
view->offset;
}
cmd_buffer->dirty |= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY;
anv_cmd_buffer_clear(cmd_buffer, pass); anv_cmd_buffer_clear(cmd_buffer, pass);
} }

View File

@@ -156,15 +156,18 @@ static void
anv_cmd_buffer_save(struct anv_cmd_buffer *cmd_buffer, anv_cmd_buffer_save(struct anv_cmd_buffer *cmd_buffer,
struct anv_saved_state *state) struct anv_saved_state *state)
{ {
memcpy(&state->bindings, &cmd_buffer->bindings, sizeof(state->bindings)); cmd_buffer->bindings = &state->bindings;
state->pipeline = cmd_buffer->pipeline; state->pipeline = cmd_buffer->pipeline;
/* Initialize render targets for the meta bindings. */
anv_cmd_buffer_fill_render_targets(cmd_buffer);
} }
static void static void
anv_cmd_buffer_restore(struct anv_cmd_buffer *cmd_buffer, anv_cmd_buffer_restore(struct anv_cmd_buffer *cmd_buffer,
const struct anv_saved_state *state) const struct anv_saved_state *state)
{ {
memcpy(&cmd_buffer->bindings, &state->bindings, sizeof(state->bindings)); cmd_buffer->bindings = &cmd_buffer->default_bindings;
cmd_buffer->pipeline = state->pipeline; cmd_buffer->pipeline = state->pipeline;
cmd_buffer->vb_dirty |= (1 << NUM_VB_USED) - 1; cmd_buffer->vb_dirty |= (1 << NUM_VB_USED) - 1;

View File

@@ -543,7 +543,8 @@ struct anv_cmd_buffer {
struct anv_framebuffer * framebuffer; struct anv_framebuffer * framebuffer;
struct anv_dynamic_rs_state * rs_state; struct anv_dynamic_rs_state * rs_state;
struct anv_dynamic_vp_state * vp_state; struct anv_dynamic_vp_state * vp_state;
struct anv_bindings bindings; struct anv_bindings * bindings;
struct anv_bindings default_bindings;
}; };
void anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer); void anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer);
@@ -685,6 +686,8 @@ void
anv_cmd_buffer_clear(struct anv_cmd_buffer *cmd_buffer, anv_cmd_buffer_clear(struct anv_cmd_buffer *cmd_buffer,
struct anv_render_pass *pass); struct anv_render_pass *pass);
void
anv_cmd_buffer_fill_render_targets(struct anv_cmd_buffer *cmd_buffer);
#ifdef __cplusplus #ifdef __cplusplus
} }