+static void si_set_shader_buffer(struct si_context *sctx,
+ struct si_buffer_resources *buffers,
+ unsigned descriptors_idx,
+ uint slot, const struct pipe_shader_buffer *sbuffer,
+ bool writable, enum radeon_bo_priority priority)
+{
+ struct si_descriptors *descs = &sctx->descriptors[descriptors_idx];
+ uint32_t *desc = descs->list + slot * 4;
+
+ if (!sbuffer || !sbuffer->buffer) {
+ pipe_resource_reference(&buffers->buffers[slot], NULL);
+ memset(desc, 0, sizeof(uint32_t) * 4);
+ buffers->enabled_mask &= ~(1u << slot);
+ buffers->writable_mask &= ~(1u << slot);
+ sctx->descriptors_dirty |= 1u << descriptors_idx;
+ return;
+ }
+
+ struct si_resource *buf = si_resource(sbuffer->buffer);
+ uint64_t va = buf->gpu_address + sbuffer->buffer_offset;
+
+ desc[0] = va;
+ desc[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) |
+ S_008F04_STRIDE(0);
+ desc[2] = sbuffer->buffer_size;
+ 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);
+
+ if (sctx->chip_class >= GFX10) {
+ desc[3] |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
+ S_008F0C_OOB_SELECT(3) |
+ S_008F0C_RESOURCE_LEVEL(1);
+ } else {
+ desc[3] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
+ S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
+ }
+
+ pipe_resource_reference(&buffers->buffers[slot], &buf->b.b);
+ buffers->offsets[slot] = sbuffer->buffer_offset;
+ radeon_add_to_gfx_buffer_list_check_mem(sctx, buf,
+ writable ? RADEON_USAGE_READWRITE :
+ RADEON_USAGE_READ,
+ priority, true);
+ if (writable)
+ buffers->writable_mask |= 1u << slot;
+ else
+ buffers->writable_mask &= ~(1u << slot);
+
+ buffers->enabled_mask |= 1u << slot;
+ sctx->descriptors_dirty |= 1u << descriptors_idx;
+
+ util_range_add(&buf->valid_buffer_range, sbuffer->buffer_offset,
+ sbuffer->buffer_offset + sbuffer->buffer_size);
+}
+