aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeonsi/si_descriptors.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/radeonsi/si_descriptors.c')
-rw-r--r--src/gallium/drivers/radeonsi/si_descriptors.c131
1 files changed, 125 insertions, 6 deletions
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 0b0704c7e28..c3236375e4b 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -166,11 +166,13 @@ static void si_update_descriptors(struct si_context *sctx,
}
static void si_emit_shader_pointer(struct si_context *sctx,
- struct si_descriptors *desc)
+ struct r600_atom *atom)
{
+ struct si_descriptors *desc = (struct si_descriptors*)atom;
struct radeon_winsys_cs *cs = sctx->b.rings.gfx.cs;
uint64_t va = r600_resource_va(sctx->b.b.screen, &desc->buffer->b.b) +
- desc->current_context_id * desc->context_size;
+ desc->current_context_id * desc->context_size +
+ desc->buffer_offset;
radeon_emit(cs, PKT3(PKT3_SET_SH_REG, 2, 0));
radeon_emit(cs, (desc->shader_userdata_reg - SI_SH_REG_OFFSET) >> 2);
@@ -253,7 +255,7 @@ static void si_emit_descriptors(struct si_context *sctx,
desc->current_context_id = new_context_id;
/* Now update the shader userdata pointer. */
- si_emit_shader_pointer(sctx, desc);
+ si_emit_shader_pointer(sctx, &desc->atom);
}
static unsigned si_get_shader_user_data_base(unsigned shader)
@@ -330,7 +332,7 @@ static void si_sampler_views_begin_new_cs(struct si_context *sctx,
r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, views->desc.buffer,
RADEON_USAGE_READWRITE, RADEON_PRIO_SHADER_DATA);
- si_emit_shader_pointer(sctx, &views->desc);
+ si_emit_shader_pointer(sctx, &views->desc.atom);
}
static void si_set_sampler_view(struct si_context *sctx, unsigned shader,
@@ -432,7 +434,7 @@ static void si_sampler_states_begin_new_cs(struct si_context *sctx,
{
r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, states->desc.buffer,
RADEON_USAGE_READWRITE, RADEON_PRIO_SHADER_DATA);
- si_emit_shader_pointer(sctx, &states->desc);
+ si_emit_shader_pointer(sctx, &states->desc.atom);
}
void si_set_sampler_descriptors(struct si_context *sctx, unsigned shader,
@@ -533,9 +535,119 @@ static void si_buffer_resources_begin_new_cs(struct si_context *sctx,
buffers->desc.buffer, RADEON_USAGE_READWRITE,
RADEON_PRIO_SHADER_DATA);
- si_emit_shader_pointer(sctx, &buffers->desc);
+ si_emit_shader_pointer(sctx, &buffers->desc.atom);
}
+/* VERTEX BUFFERS */
+
+static void si_vertex_buffers_begin_new_cs(struct si_context *sctx)
+{
+ struct si_descriptors *desc = &sctx->vertex_buffers;
+ int count = sctx->vertex_elements ? sctx->vertex_elements->count : 0;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ int vb = sctx->vertex_elements->elements[i].vertex_buffer_index;
+
+ if (vb >= sctx->nr_vertex_buffers)
+ continue;
+ if (!sctx->vertex_buffer[vb].buffer)
+ continue;
+
+ r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
+ (struct r600_resource*)sctx->vertex_buffer[vb].buffer,
+ RADEON_USAGE_READ, RADEON_PRIO_SHADER_BUFFER_RO);
+ }
+ r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
+ desc->buffer, RADEON_USAGE_READ,
+ RADEON_PRIO_SHADER_DATA);
+
+ si_emit_shader_pointer(sctx, &desc->atom);
+}
+
+void si_update_vertex_buffers(struct si_context *sctx)
+{
+ struct pipe_context *ctx = &sctx->b.b;
+ struct si_descriptors *desc = &sctx->vertex_buffers;
+ bool bound[SI_NUM_VERTEX_BUFFERS] = {};
+ unsigned i, count = sctx->vertex_elements->count;
+ uint64_t va;
+ uint32_t *ptr;
+
+ if (!count || !sctx->vertex_elements)
+ return;
+
+ /* Vertex buffer descriptors are the only ones which are uploaded
+ * directly through a staging buffer and don't go through
+ * the fine-grained upload path.
+ */
+ u_upload_alloc(sctx->b.uploader, 0, count * 16, &desc->buffer_offset,
+ (struct pipe_resource**)&desc->buffer, (void**)&ptr);
+
+ r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
+ desc->buffer, RADEON_USAGE_READ,
+ RADEON_PRIO_SHADER_DATA);
+
+ assert(count <= SI_NUM_VERTEX_BUFFERS);
+ assert(desc->current_context_id == 0);
+
+ for (i = 0; i < count; i++) {
+ struct pipe_vertex_element *ve = &sctx->vertex_elements->elements[i];
+ struct pipe_vertex_buffer *vb;
+ struct r600_resource *rbuffer;
+ unsigned offset;
+ uint32_t *desc = &ptr[i*4];
+
+ if (ve->vertex_buffer_index >= sctx->nr_vertex_buffers) {
+ memset(desc, 0, 16);
+ continue;
+ }
+
+ vb = &sctx->vertex_buffer[ve->vertex_buffer_index];
+ rbuffer = (struct r600_resource*)vb->buffer;
+ if (rbuffer == NULL) {
+ memset(desc, 0, 16);
+ continue;
+ }
+
+ offset = vb->buffer_offset + ve->src_offset;
+
+ va = r600_resource_va(ctx->screen, (void*)rbuffer);
+ va += offset;
+
+ /* Fill in T# buffer resource description */
+ desc[0] = va & 0xFFFFFFFF;
+ desc[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) |
+ S_008F04_STRIDE(vb->stride);
+ if (vb->stride)
+ /* Round up by rounding down and adding 1 */
+ desc[2] = (vb->buffer->width0 - offset -
+ sctx->vertex_elements->format_size[i]) /
+ vb->stride + 1;
+ else
+ desc[2] = vb->buffer->width0 - offset;
+
+ desc[3] = sctx->vertex_elements->rsrc_word3[i];
+
+ if (!bound[ve->vertex_buffer_index]) {
+ r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
+ (struct r600_resource*)vb->buffer,
+ RADEON_USAGE_READ, RADEON_PRIO_SHADER_BUFFER_RO);
+ bound[ve->vertex_buffer_index] = true;
+ }
+ }
+
+ desc->atom.num_dw = 8; /* update 2 shader pointers (VS+ES) */
+ desc->atom.dirty = true;
+
+ /* Don't flush the const cache. It would have a very negative effect
+ * on performance (confirmed by testing). New descriptors are always
+ * uploaded to a fresh new buffer, so I don't think flushing the const
+ * cache is needed. */
+ sctx->b.flags |= R600_CONTEXT_INV_TEX_CACHE;
+}
+
+
/* CONSTANT BUFFERS */
void si_upload_const_buffer(struct si_context *sctx, struct r600_resource **rbuffer,
@@ -1096,6 +1208,11 @@ void si_init_all_descriptors(struct si_context *sctx)
sctx->atoms.s.sampler_states[i] = &sctx->samplers[i].states.desc.atom;
}
+ si_init_descriptors(sctx, &sctx->vertex_buffers,
+ si_get_shader_user_data_base(PIPE_SHADER_VERTEX) +
+ SI_SGPR_VERTEX_BUFFER*4, 4, SI_NUM_VERTEX_BUFFERS,
+ si_emit_shader_pointer);
+ sctx->atoms.s.vertex_buffers = &sctx->vertex_buffers.atom;
/* Set pipe_context functions. */
sctx->b.b.set_constant_buffer = si_set_constant_buffer;
@@ -1115,6 +1232,7 @@ void si_release_all_descriptors(struct si_context *sctx)
si_release_sampler_views(&sctx->samplers[i].views);
si_release_descriptors(&sctx->samplers[i].states.desc);
}
+ si_release_descriptors(&sctx->vertex_buffers);
}
void si_all_descriptors_begin_new_cs(struct si_context *sctx)
@@ -1127,4 +1245,5 @@ void si_all_descriptors_begin_new_cs(struct si_context *sctx)
si_sampler_views_begin_new_cs(sctx, &sctx->samplers[i].views);
si_sampler_states_begin_new_cs(sctx, &sctx->samplers[i].states);
}
+ si_vertex_buffers_begin_new_cs(sctx);
}