desc->buffer = (struct r600_resource*)
pipe_buffer_create(sctx->b.b.screen, PIPE_BIND_CUSTOM,
- PIPE_USAGE_STATIC,
+ PIPE_USAGE_DEFAULT,
SI_NUM_CONTEXTS * desc->context_size);
- r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, desc->buffer, RADEON_USAGE_READWRITE);
+ r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, desc->buffer,
+ RADEON_USAGE_READWRITE, RADEON_PRIO_SHADER_DATA);
va = r600_resource_va(sctx->b.b.screen, &desc->buffer->b.b);
/* We don't check for CS space here, because this should be called
7 + /* copy */
(4 + desc->element_dw_size) * util_bitcount(desc->dirty_mask) + /* update */
4; /* pointer update */
+#if HAVE_LLVM >= 0x0305
+ if (desc->shader_userdata_reg >= R_00B130_SPI_SHADER_USER_DATA_VS_0 &&
+ desc->shader_userdata_reg < R_00B230_SPI_SHADER_USER_DATA_GS_0)
+ desc->atom.num_dw += 4; /* second pointer update */
+#endif
desc->atom.dirty = true;
/* The descriptors are read with the K cache. */
sctx->b.flags |= R600_CONTEXT_INV_CONST_CACHE;
radeon_emit(cs, (desc->shader_userdata_reg - SI_SH_REG_OFFSET) >> 2);
radeon_emit(cs, va);
radeon_emit(cs, va >> 32);
+
+#if HAVE_LLVM >= 0x0305
+ if (desc->shader_userdata_reg >= R_00B130_SPI_SHADER_USER_DATA_VS_0 &&
+ desc->shader_userdata_reg < R_00B230_SPI_SHADER_USER_DATA_GS_0) {
+ radeon_emit(cs, PKT3(PKT3_SET_SH_REG, 2, 0));
+ radeon_emit(cs, (desc->shader_userdata_reg +
+ (R_00B330_SPI_SHADER_USER_DATA_ES_0 -
+ R_00B130_SPI_SHADER_USER_DATA_VS_0) -
+ SI_SH_REG_OFFSET) >> 2);
+ radeon_emit(cs, va);
+ radeon_emit(cs, va >> 32);
+ }
+#endif
}
static void si_emit_descriptors(struct si_context *sctx,
si_release_descriptors(&views->desc);
}
+static enum radeon_bo_priority si_get_resource_ro_priority(struct r600_resource *res)
+{
+ if (res->b.b.target == PIPE_BUFFER)
+ return RADEON_PRIO_SHADER_BUFFER_RO;
+
+ if (res->b.b.nr_samples > 1)
+ return RADEON_PRIO_SHADER_TEXTURE_MSAA;
+
+ return RADEON_PRIO_SHADER_TEXTURE_RO;
+}
+
static void si_sampler_views_begin_new_cs(struct si_context *sctx,
struct si_sampler_views *views)
{
struct si_pipe_sampler_view *rview =
(struct si_pipe_sampler_view*)views->views[i];
- r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, rview->resource, RADEON_USAGE_READ);
+ r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
+ rview->resource, RADEON_USAGE_READ,
+ si_get_resource_ro_priority(rview->resource));
}
- r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, views->desc.buffer, RADEON_USAGE_READWRITE);
+ 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);
}
struct si_pipe_sampler_view *rview =
(struct si_pipe_sampler_view*)view;
- r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, rview->resource, RADEON_USAGE_READ);
+ r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
+ rview->resource, RADEON_USAGE_READ,
+ si_get_resource_ro_priority(rview->resource));
pipe_sampler_view_reference(&views->views[slot], view);
views->desc_data[slot] = view_desc;
struct si_buffer_resources *buffers,
unsigned num_buffers, unsigned shader,
unsigned shader_userdata_index,
- enum radeon_bo_usage shader_usage)
+ enum radeon_bo_usage shader_usage,
+ enum radeon_bo_priority priority)
{
int i;
buffers->num_buffers = num_buffers;
buffers->shader_usage = shader_usage;
+ buffers->priority = priority;
buffers->buffers = CALLOC(num_buffers, sizeof(struct pipe_resource*));
buffers->desc_storage = CALLOC(num_buffers, sizeof(uint32_t) * 4);
{
int i;
- for (i = 0; i < Elements(buffers->buffers); i++) {
+ for (i = 0; i < buffers->num_buffers; i++) {
pipe_resource_reference(&buffers->buffers[i], NULL);
}
r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
(struct r600_resource*)buffers->buffers[i],
- buffers->shader_usage);
+ buffers->shader_usage, buffers->priority);
}
r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
- buffers->desc.buffer, RADEON_USAGE_READWRITE);
+ buffers->desc.buffer, RADEON_USAGE_READWRITE,
+ RADEON_PRIO_SHADER_DATA);
si_emit_shader_pointer(sctx, &buffers->desc);
}
}
for (i = 0; i < size / 4; ++i) {
- tmpPtr[i] = util_bswap32(((uint32_t *)ptr)[i]);
+ tmpPtr[i] = util_cpu_to_le32(((uint32_t *)ptr)[i]);
}
u_upload_data(sctx->b.uploader, 0, size, tmpPtr, const_offset,
buffers->buffers[slot] = buffer;
r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
- (struct r600_resource*)buffer, buffers->shader_usage);
+ (struct r600_resource*)buffer,
+ buffers->shader_usage, buffers->priority);
+ buffers->desc.enabled_mask |= 1 << slot;
+ } else {
+ /* Clear the descriptor. */
+ memset(buffers->desc_data[slot], 0, sizeof(uint32_t) * 4);
+ buffers->desc.enabled_mask &= ~(1 << slot);
+ }
+
+ buffers->desc.dirty_mask |= 1 << slot;
+ si_update_descriptors(sctx, &buffers->desc);
+}
+
+/* RING BUFFERS */
+
+void si_set_ring_buffer(struct pipe_context *ctx, uint shader, uint slot,
+ struct pipe_constant_buffer *input,
+ unsigned stride, unsigned num_records,
+ bool add_tid, bool swizzle,
+ unsigned element_size, unsigned index_stride)
+{
+ struct si_context *sctx = (struct si_context *)ctx;
+ struct si_buffer_resources *buffers = &sctx->rw_buffers[shader];
+
+ if (shader >= SI_NUM_SHADERS)
+ return;
+
+ /* The stride field in the resource descriptor has 14 bits */
+ assert(stride < (1 << 14));
+
+ assert(slot < buffers->num_buffers);
+ pipe_resource_reference(&buffers->buffers[slot], NULL);
+
+ if (input && input->buffer) {
+ uint64_t va;
+
+ va = r600_resource_va(ctx->screen, input->buffer);
+
+ switch (element_size) {
+ default:
+ assert(!"Unsupported ring buffer element size");
+ case 0:
+ case 2:
+ element_size = 0;
+ break;
+ case 4:
+ element_size = 1;
+ break;
+ case 8:
+ element_size = 2;
+ break;
+ case 16:
+ element_size = 3;
+ break;
+ }
+
+ switch (index_stride) {
+ default:
+ assert(!"Unsupported ring buffer index stride");
+ case 0:
+ case 8:
+ index_stride = 0;
+ break;
+ case 16:
+ index_stride = 1;
+ break;
+ case 32:
+ index_stride = 2;
+ break;
+ case 64:
+ index_stride = 3;
+ break;
+ }
+
+ /* Set the descriptor. */
+ uint32_t *desc = buffers->desc_data[slot];
+ desc[0] = va;
+ desc[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) |
+ S_008F04_STRIDE(stride) |
+ S_008F04_SWIZZLE_ENABLE(swizzle);
+ desc[2] = num_records;
+ desc[3] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
+ S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
+ S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
+ S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
+ S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
+ S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32) |
+ S_008F0C_ELEMENT_SIZE(element_size) |
+ S_008F0C_INDEX_STRIDE(index_stride) |
+ S_008F0C_ADD_TID_ENABLE(add_tid);
+
+ pipe_resource_reference(&buffers->buffers[slot], input->buffer);
+ r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
+ (struct r600_resource*)input->buffer,
+ buffers->shader_usage, buffers->priority);
buffers->desc.enabled_mask |= 1 << slot;
} else {
/* Clear the descriptor. */
static void si_set_streamout_targets(struct pipe_context *ctx,
unsigned num_targets,
struct pipe_stream_output_target **targets,
- unsigned append_bitmask)
+ const unsigned *offsets)
{
struct si_context *sctx = (struct si_context *)ctx;
- struct si_buffer_resources *buffers = &sctx->streamout_buffers;
+ struct si_buffer_resources *buffers = &sctx->rw_buffers[PIPE_SHADER_VERTEX];
unsigned old_num_targets = sctx->b.streamout.num_targets;
- unsigned i;
+ unsigned i, bufidx;
/* Streamout buffers must be bound in 2 places:
* 1) in VGT by setting the VGT_STRMOUT registers
*/
/* Set the VGT regs. */
- r600_set_streamout_targets(ctx, num_targets, targets, append_bitmask);
+ r600_set_streamout_targets(ctx, num_targets, targets, offsets);
/* Set the shader resources.*/
for (i = 0; i < num_targets; i++) {
+ bufidx = SI_RW_SO + i;
+
if (targets[i]) {
struct pipe_resource *buffer = targets[i]->buffer;
uint64_t va = r600_resource_va(ctx->screen, buffer);
/* Set the descriptor. */
- uint32_t *desc = buffers->desc_data[i];
+ uint32_t *desc = buffers->desc_data[bufidx];
desc[0] = va;
desc[1] = S_008F04_BASE_ADDRESS_HI(va >> 32);
desc[2] = 0xffffffff;
S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
/* Set the resource. */
- pipe_resource_reference(&buffers->buffers[i], buffer);
+ pipe_resource_reference(&buffers->buffers[bufidx],
+ buffer);
r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
(struct r600_resource*)buffer,
- buffers->shader_usage);
- buffers->desc.enabled_mask |= 1 << i;
+ buffers->shader_usage, buffers->priority);
+ buffers->desc.enabled_mask |= 1 << bufidx;
} else {
/* Clear the descriptor and unset the resource. */
- memset(buffers->desc_data[i], 0, sizeof(uint32_t) * 4);
- pipe_resource_reference(&buffers->buffers[i], NULL);
- buffers->desc.enabled_mask &= ~(1 << i);
+ memset(buffers->desc_data[bufidx], 0,
+ sizeof(uint32_t) * 4);
+ pipe_resource_reference(&buffers->buffers[bufidx],
+ NULL);
+ buffers->desc.enabled_mask &= ~(1 << bufidx);
}
- buffers->desc.dirty_mask |= 1 << i;
+ buffers->desc.dirty_mask |= 1 << bufidx;
}
for (; i < old_num_targets; i++) {
+ bufidx = SI_RW_SO + i;
/* Clear the descriptor and unset the resource. */
- memset(buffers->desc_data[i], 0, sizeof(uint32_t) * 4);
- pipe_resource_reference(&buffers->buffers[i], NULL);
- buffers->desc.enabled_mask &= ~(1 << i);
- buffers->desc.dirty_mask |= 1 << i;
+ memset(buffers->desc_data[bufidx], 0, sizeof(uint32_t) * 4);
+ pipe_resource_reference(&buffers->buffers[bufidx], NULL);
+ buffers->desc.enabled_mask &= ~(1 << bufidx);
+ buffers->desc.dirty_mask |= 1 << bufidx;
}
si_update_descriptors(sctx, &buffers->desc);
unsigned i, shader, alignment = rbuffer->buf->alignment;
uint64_t old_va = r600_resource_va(ctx->screen, buf);
- /* Discard the buffer. */
- pb_reference(&rbuffer->buf, NULL);
-
- /* Create a new one in the same pipe_resource. */
- r600_init_resource(&sctx->screen->b, rbuffer, rbuffer->b.b.width0, alignment,
- TRUE, rbuffer->b.b.usage);
+ /* Reallocate the buffer in the same pipe_resource. */
+ r600_init_resource(&sctx->screen->b, rbuffer, rbuffer->b.b.width0,
+ alignment, TRUE);
/* We changed the buffer, now we need to bind it where the old one
* was bound. This consists of 2 things:
/* Vertex buffers. */
/* Nothing to do. Vertex buffer bindings are updated before every draw call. */
- /* Streamout buffers. */
- for (i = 0; i < sctx->streamout_buffers.num_buffers; i++) {
- if (sctx->streamout_buffers.buffers[i] == buf) {
- /* Update the descriptor. */
- si_desc_reset_buffer_offset(ctx, sctx->streamout_buffers.desc_data[i],
- old_va, buf);
+ /* Read/Write buffers. */
+ for (shader = 0; shader < SI_NUM_SHADERS; shader++) {
+ struct si_buffer_resources *buffers = &sctx->rw_buffers[shader];
+ bool found = false;
+ uint32_t mask = buffers->desc.enabled_mask;
- r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
- (struct r600_resource*)buf,
- sctx->streamout_buffers.shader_usage);
- sctx->streamout_buffers.desc.dirty_mask |= 1 << i;
- si_update_descriptors(sctx, &sctx->streamout_buffers.desc);
-
- /* Update the streamout state. */
- if (sctx->b.streamout.begin_emitted) {
- r600_emit_streamout_end(&sctx->b);
+ while (mask) {
+ i = u_bit_scan(&mask);
+ if (buffers->buffers[i] == buf) {
+ si_desc_reset_buffer_offset(ctx, buffers->desc_data[i],
+ old_va, buf);
+
+ r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
+ rbuffer, buffers->shader_usage,
+ buffers->priority);
+
+ buffers->desc.dirty_mask |= 1 << i;
+ found = true;
+
+ if (i >= SI_RW_SO && shader == PIPE_SHADER_VERTEX) {
+ /* Update the streamout state. */
+ if (sctx->b.streamout.begin_emitted) {
+ r600_emit_streamout_end(&sctx->b);
+ }
+ sctx->b.streamout.append_bitmask =
+ sctx->b.streamout.enabled_mask;
+ r600_streamout_buffers_dirty(&sctx->b);
+ }
}
- sctx->b.streamout.append_bitmask = sctx->b.streamout.enabled_mask;
- r600_streamout_buffers_dirty(&sctx->b);
+ }
+ if (found) {
+ si_update_descriptors(sctx, &buffers->desc);
}
}
old_va, buf);
r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
- rbuffer, buffers->shader_usage);
+ rbuffer, buffers->shader_usage,
+ buffers->priority);
buffers->desc.dirty_mask |= 1 << i;
found = true;
old_va, buf);
r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
- rbuffer, RADEON_USAGE_READ);
+ rbuffer, RADEON_USAGE_READ,
+ RADEON_PRIO_SHADER_BUFFER_RO);
views->desc.dirty_mask |= 1 << i;
found = true;
/* This must be done after need_cs_space. */
r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
- (struct r600_resource*)dst, RADEON_USAGE_WRITE);
+ (struct r600_resource*)dst, RADEON_USAGE_WRITE,
+ RADEON_PRIO_MIN);
/* Flush the caches for the first copy only.
* Also wait for the previous CP DMA operations. */
}
/* This must be done after r600_need_cs_space. */
- r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, (struct r600_resource*)src, RADEON_USAGE_READ);
- r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, (struct r600_resource*)dst, RADEON_USAGE_WRITE);
+ r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, (struct r600_resource*)src,
+ RADEON_USAGE_READ, RADEON_PRIO_MIN);
+ r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, (struct r600_resource*)dst,
+ RADEON_USAGE_WRITE, RADEON_PRIO_MIN);
si_emit_cp_dma_copy_buffer(sctx, dst_offset, src_offset, byte_count, sync_flags);
for (i = 0; i < SI_NUM_SHADERS; i++) {
si_init_buffer_resources(sctx, &sctx->const_buffers[i],
NUM_CONST_BUFFERS, i, SI_SGPR_CONST,
- RADEON_USAGE_READ);
+ RADEON_USAGE_READ, RADEON_PRIO_SHADER_BUFFER_RO);
+ si_init_buffer_resources(sctx, &sctx->rw_buffers[i],
+ i == PIPE_SHADER_VERTEX ?
+ SI_RW_SO + 4 : SI_RW_SO,
+ i, SI_SGPR_RW_BUFFERS,
+ RADEON_USAGE_READWRITE, RADEON_PRIO_SHADER_RESOURCE_RW);
si_init_sampler_views(sctx, &sctx->samplers[i].views, i);
sctx->atoms.const_buffers[i] = &sctx->const_buffers[i].desc.atom;
+ sctx->atoms.rw_buffers[i] = &sctx->rw_buffers[i].desc.atom;
sctx->atoms.sampler_views[i] = &sctx->samplers[i].views.desc.atom;
}
- si_init_buffer_resources(sctx, &sctx->streamout_buffers, 4, PIPE_SHADER_VERTEX,
- SI_SGPR_SO_BUFFER, RADEON_USAGE_WRITE);
- sctx->atoms.streamout_buffers = &sctx->streamout_buffers.desc.atom;
/* Set pipe_context functions. */
sctx->b.b.set_constant_buffer = si_set_constant_buffer;
for (i = 0; i < SI_NUM_SHADERS; i++) {
si_release_buffer_resources(&sctx->const_buffers[i]);
+ si_release_buffer_resources(&sctx->rw_buffers[i]);
si_release_sampler_views(&sctx->samplers[i].views);
}
- si_release_buffer_resources(&sctx->streamout_buffers);
}
void si_all_descriptors_begin_new_cs(struct si_context *sctx)
for (i = 0; i < SI_NUM_SHADERS; i++) {
si_buffer_resources_begin_new_cs(sctx, &sctx->const_buffers[i]);
+ si_buffer_resources_begin_new_cs(sctx, &sctx->rw_buffers[i]);
si_sampler_views_begin_new_cs(sctx, &sctx->samplers[i].views);
}
- si_buffer_resources_begin_new_cs(sctx, &sctx->streamout_buffers);
}