[Mesa-dev] [PATCH 2/2] r600, compute: setup RATs for write-only images
Marek Olšák
maraeo at gmail.com
Fri Aug 14 02:24:34 PDT 2015
On Fri, Aug 14, 2015 at 11:16 AM, Zoltan Gilian <zoltan.gilian at gmail.com> wrote:
> v2: Set CB_TARGET_MASK to zero for compute resources (Marek).
> Remove unnecessary use of cb_target_mask (Marek).
> Fix crash on non-contiguous RAT setup.
>
> Non-contiguous RAT setup can occur when the kernel signature contains
> no global buffer arguments, but there are write-only image args.
> In this case RAT0 is not set, but RAT1 is.
> ---
> src/gallium/drivers/r600/evergreen_compute.c | 106 +++++++++++++++++----------
> src/gallium/drivers/r600/evergreen_state.c | 43 ++++++++++-
> src/gallium/drivers/r600/r600_pipe.h | 4 +-
> src/gallium/drivers/radeon/r600_texture.c | 1 +
> 4 files changed, 113 insertions(+), 41 deletions(-)
>
> diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
> index b191e0d..16816cf 100644
> --- a/src/gallium/drivers/r600/evergreen_compute.c
> +++ b/src/gallium/drivers/r600/evergreen_compute.c
> @@ -99,8 +99,40 @@ struct r600_resource* r600_compute_buffer_alloc_vram(
> return (struct r600_resource *)buffer;
> }
>
> +static void evergreen_set_cbuf(
> + struct r600_context *ctx,
> + unsigned id,
> + struct pipe_surface *surf)
> +{
> + struct pipe_framebuffer_state *state = &ctx->framebuffer.state;
> +
> + /* Add the RAT to the list of color buffers */
> + state->cbufs[id] = surf;
> +
> + /* Update the number of color buffers */
> + state->nr_cbufs = MAX2(id + 1, state->nr_cbufs);
> +
> + /* cb_target_mask should be 0 for compute resources. */
> + ctx->compute_cb_target_mask &= ~(0xf << (id << 2));
> +}
>
> -static void evergreen_set_rat(
> +static void evergreen_unset_cbuf(
> + struct r600_context *ctx,
> + unsigned id)
> +{
> + unsigned i;
> + struct pipe_framebuffer_state *state = &ctx->framebuffer.state;
> +
> + state->cbufs[id] = NULL;
> + for (i = state->nr_cbufs; i > 0; --i) {
> + if (state->cbufs[i - 1]) {
> + break;
> + }
> + }
> + state->nr_cbufs = i;
> +}
> +
> +static void evergreen_set_rat_buf(
> struct r600_context *ctx,
> unsigned id,
> struct r600_resource* bo,
> @@ -123,23 +155,11 @@ static void evergreen_set_rat(
> rat_templ.u.tex.first_layer = 0;
> rat_templ.u.tex.last_layer = 0;
>
> - /* Add the RAT the list of color buffers */
> - ctx->framebuffer.state.cbufs[id] = ctx->b.b.create_surface(
> - (struct pipe_context *)ctx,
> - (struct pipe_resource *)bo, &rat_templ);
> -
> - /* Update the number of color buffers */
> - ctx->framebuffer.state.nr_cbufs =
> - MAX2(id + 1, ctx->framebuffer.state.nr_cbufs);
> -
> - /* Update the cb_target_mask
> - * XXX: I think this is a potential spot for bugs once we start doing
> - * GL interop. cb_target_mask may be modified in the 3D sections
> - * of this driver. */
> - ctx->compute_cb_target_mask |= (0xf << (id * 4));
> + evergreen_set_cbuf(ctx, id, ctx->b.b.create_surface(
> + (struct pipe_context *)ctx, (struct pipe_resource *)bo, &rat_templ));
>
> surf = (struct r600_surface*)ctx->framebuffer.state.cbufs[id];
> - evergreen_init_color_surface_rat(rctx, surf);
> + evergreen_init_color_surface_rat_buf(ctx, surf);
> }
>
> static void evergreen_cs_set_vertex_buffer(
> @@ -436,6 +456,8 @@ static void compute_emit_cs(struct r600_context *ctx, const uint *block_layout,
> /* XXX support more than 8 colorbuffers (the offsets are not a multiple of 0x3C for CB8-11) */
> for (i = 0; i < 8 && i < ctx->framebuffer.state.nr_cbufs; i++) {
> struct r600_surface *cb = (struct r600_surface*)ctx->framebuffer.state.cbufs[i];
> + if (!cb)
> + continue;
> unsigned reloc = r600_context_bo_reloc(&ctx->b, &ctx->b.rings.gfx,
> (struct r600_resource*)cb->base.texture,
> RADEON_USAGE_READWRITE,
> @@ -623,32 +645,34 @@ static void evergreen_set_compute_resources(struct pipe_context * ctx_,
> struct pipe_surface ** surfaces)
> {
> struct r600_context *ctx = (struct r600_context *)ctx_;
> - struct r600_surface **resources = (struct r600_surface **)surfaces;
> + struct pipe_surface *surf = NULL;
>
> COMPUTE_DBG(ctx->screen, "*** evergreen_set_compute_resources: start = %u count = %u\n",
> start, count);
>
> + if (!surfaces) {
> + for (unsigned i = 0; i < count; ++i)
> + evergreen_unset_cbuf(ctx, 1 + i);
> + return;
> + }
> +
> for (unsigned i = 0; i < count; i++) {
> - /* The First two vertex buffers are reserved for parameters and
> - * global buffers. */
> - unsigned vtx_id = 2 + i;
> - if (resources[i]) {
> - struct r600_resource_global *buffer =
> - (struct r600_resource_global*)
> - resources[i]->base.texture;
> - if (resources[i]->base.writable) {
> - assert(i+1 < 12);
> -
> - evergreen_set_rat(ctx->cs_shader_state.shader, i+1,
> - (struct r600_resource *)resources[i]->base.texture,
> - buffer->chunk->start_in_dw*4,
> - resources[i]->base.texture->width0);
> - }
> -
> - evergreen_cs_set_vertex_buffer(ctx, vtx_id,
> - buffer->chunk->start_in_dw * 4,
> - resources[i]->base.texture);
> - }
> + surf = surfaces[i];
> + if (!surf)
> + continue;
> +
> + /* XXX: Implement constant buffers. */
> + assert(surf->writable &&
> + "Constant buffer compute resources are not supported yet.");
> +
> + /* It is assumed, that surface[i]->texture contains an r600_texture. */
> +
> + /* The first RAT is reserved for global buffers. */
> + unsigned rat_id = 1 + i;
> + assert(rat_id < 12);
> +
> + evergreen_set_cbuf(ctx, rat_id, surf);
> + evergreen_init_color_surface_rat_tex(ctx, (struct r600_surface *)surf);
> }
> }
>
> @@ -686,7 +710,11 @@ static void evergreen_set_global_binding(
> first, n);
>
> if (!resources) {
> - /* XXX: Unset */
> + if (n) {
> + /* evergreen_set_rat_buf creates a new surface. */
> + ctx_->surface_destroy(ctx_, ctx->framebuffer.state.cbufs[0]);
surface_destroy is never called directly. It should be:
pipe_surface_reference(&ctx->framebuffer.state.cbufs[0], NULL);
Marek
More information about the mesa-dev
mailing list