Exemplo n.º 1
0
static void
radv_make_buffer_descriptor(struct radv_device *device,
			    struct radv_buffer *buffer,
			    VkFormat vk_format,
			    unsigned offset,
			    unsigned range,
			    uint32_t *state)
{
	const struct vk_format_description *desc;
	unsigned stride;
	uint64_t gpu_address = device->ws->buffer_get_va(buffer->bo);
	uint64_t va = gpu_address + buffer->offset;
	unsigned num_format, data_format;
	int first_non_void;
	desc = vk_format_description(vk_format);
	first_non_void = vk_format_get_first_non_void_channel(vk_format);
	stride = desc->block.bits / 8;

	num_format = radv_translate_buffer_numformat(desc, first_non_void);
	data_format = radv_translate_buffer_dataformat(desc, first_non_void);

	va += offset;
	state[0] = va;
	state[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) |
		S_008F04_STRIDE(stride);
	state[2] = range;
	state[3] = S_008F0C_DST_SEL_X(radv_map_swizzle(desc->swizzle[0])) |
		   S_008F0C_DST_SEL_Y(radv_map_swizzle(desc->swizzle[1])) |
		   S_008F0C_DST_SEL_Z(radv_map_swizzle(desc->swizzle[2])) |
		   S_008F0C_DST_SEL_W(radv_map_swizzle(desc->swizzle[3])) |
		   S_008F0C_NUM_FORMAT(num_format) |
		   S_008F0C_DATA_FORMAT(data_format);
}
Exemplo n.º 2
0
static void si_set_constant_buffer(struct pipe_context *ctx, uint shader, uint slot,
                                   struct pipe_constant_buffer *input)
{
    struct si_context *sctx = (struct si_context *)ctx;
    struct si_buffer_resources *buffers = &sctx->const_buffers[shader];

    if (shader >= SI_NUM_SHADERS)
        return;

    assert(slot < buffers->desc.num_elements);
    pipe_resource_reference(&buffers->buffers[slot], NULL);

    /* CIK cannot unbind a constant buffer (S_BUFFER_LOAD is buggy
     * with a NULL buffer). We need to use a dummy buffer instead. */
    if (sctx->b.chip_class == CIK &&
            (!input || (!input->buffer && !input->user_buffer)))
        input = &sctx->null_const_buf;

    if (input && (input->buffer || input->user_buffer)) {
        struct pipe_resource *buffer = NULL;
        uint64_t va;

        /* Upload the user buffer if needed. */
        if (input->user_buffer) {
            unsigned buffer_offset;

            si_upload_const_buffer(sctx,
                                   (struct r600_resource**)&buffer, input->user_buffer,
                                   input->buffer_size, &buffer_offset);
            if (!buffer) {
                /* Just unbind on failure. */
                si_set_constant_buffer(ctx, shader, slot, NULL);
                return;
            }
            va = r600_resource(buffer)->gpu_address + buffer_offset;
        } else {
            pipe_resource_reference(&buffer, input->buffer);
            va = r600_resource(buffer)->gpu_address + input->buffer_offset;
        }

        /* Set the descriptor. */
        uint32_t *desc = buffers->desc.list + slot*4;
        desc[0] = va;
        desc[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) |
                  S_008F04_STRIDE(0);
        desc[2] = input->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) |
                  S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
                  S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);

        buffers->buffers[slot] = buffer;
        r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx,
                              (struct r600_resource*)buffer,
                              buffers->shader_usage, buffers->priority);
        buffers->desc.enabled_mask |= 1llu << slot;
    } else {
Exemplo n.º 3
0
static bool si_upload_vertex_buffer_descriptors(struct si_context *sctx)
{
    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 (!sctx->vertex_buffers_dirty)
        return true;
    if (!count || !sctx->vertex_elements)
        return true;

    /* 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);
    if (!desc->buffer)
        return false;

    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);

    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 >= Elements(sctx->vertex_buffer)) {
            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 = rbuffer->gpu_address + 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 (sctx->b.chip_class <= CIK && 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;
        }
    }

    /* 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. */
    desc->pointer_dirty = true;
    si_mark_atom_dirty(sctx, &sctx->shader_userdata.atom);
    sctx->vertex_buffers_dirty = false;
    return true;
}