Skip to content

Commit

Permalink
r600,compute: setup RATs for write-only images
Browse files Browse the repository at this point in the history
v2: Set CB_TARGET_MASK to zero for compute resources (Marek).
    Remove unnecessary use of util_range_add (Marek).
    Fix crash on non-contiguous RAT setup.
v3: Unreference surface instead of calling destroy directly (Marek).

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.
  • Loading branch information
zogi committed Aug 14, 2015
1 parent f96ee65 commit 872c096
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 41 deletions.
106 changes: 67 additions & 39 deletions src/gallium/drivers/r600/evergreen_compute.c
Expand Up @@ -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,
Expand All @@ -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(
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -629,32 +651,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);
}
}

Expand All @@ -673,7 +697,11 @@ static void evergreen_set_global_binding(
first, n);

if (!resources) {
/* XXX: Unset */
if (n) {
/* evergreen_set_rat_buf creates a new surface. */
pipe_surface_reference(&ctx->framebuffer.state.cbufs[0], NULL);
evergreen_unset_cbuf(ctx, 0);
}
return;
}

Expand Down Expand Up @@ -704,7 +732,7 @@ static void evergreen_set_global_binding(
*(handles[i]) = util_cpu_to_le32(handle);
}

evergreen_set_rat(ctx, 0, pool->bo, 0, pool->size_in_dw * 4);
evergreen_set_rat_buf(ctx, 0, pool->bo, 0, pool->size_in_dw * 4);
evergreen_cs_set_vertex_buffer(ctx, 1, 0,
(struct pipe_resource*)pool->bo);
}
Expand Down
43 changes: 42 additions & 1 deletion src/gallium/drivers/r600/evergreen_state.c
Expand Up @@ -45,6 +45,31 @@ static inline unsigned evergreen_array_mode(unsigned mode)
}
}

static inline unsigned evergreen_resource_type(enum pipe_texture_target target)
{
switch (target) {
case PIPE_BUFFER:
return V_028C70_BUFFER;
case PIPE_TEXTURE_1D:
return V_028C70_TEXTURE1D;
case PIPE_TEXTURE_RECT:
case PIPE_TEXTURE_2D:
return V_028C70_TEXTURE2D;
case PIPE_TEXTURE_3D:
return V_028C70_TEXTURE3D;
case PIPE_TEXTURE_1D_ARRAY:
return V_028C70_TEXTURE1DARRAY;
case PIPE_TEXTURE_2D_ARRAY:
return V_028C70_TEXTURE2DARRAY;
case PIPE_TEXTURE_CUBE:
case PIPE_TEXTURE_CUBE_ARRAY:
assert(0 && "Can't assign CB_COLOR_INFO resource type to "
"PIPE_TEXTURE_CUBE or PIPE_TEXTURE_CUBE_ARRAY.");
default:
assert(0 && "Unknown pipe texture target.");
}
}

static uint32_t eg_num_banks(uint32_t nbanks)
{
switch (nbanks) {
Expand Down Expand Up @@ -923,7 +948,7 @@ static void evergreen_emit_scissor_state(struct r600_context *rctx, struct r600_
* to be used for 1D aligned buffers that do not have an associated
* radeon_surf.
*/
void evergreen_init_color_surface_rat(struct r600_context *rctx,
void evergreen_init_color_surface_rat_buf(struct r600_context *rctx,
struct r600_surface *surf)
{
struct pipe_resource *pipe_buffer = surf->base.texture;
Expand Down Expand Up @@ -961,6 +986,7 @@ void evergreen_init_color_surface_rat(struct r600_context *rctx,
| S_028C70_BLEND_BYPASS(1) /* We must set this bit because we
* are using NUMBER_UINT */
| S_028C70_RAT(1)
| S_028C70_RESOURCE_TYPE(V_028C70_BUFFER)
;

surf->cb_color_attrib = S_028C74_NON_DISP_TILING_ORDER(1);
Expand All @@ -977,6 +1003,18 @@ void evergreen_init_color_surface_rat(struct r600_context *rctx,
surf->cb_color_fmask_slice = 0;
}

void evergreen_init_color_surface_rat_tex(struct r600_context *rctx,
struct r600_surface *surf)
{
struct r600_texture *tex = (struct r600_texture *)surf->base.texture;

evergreen_init_color_surface(rctx, surf);

surf->cb_color_info |= S_028C70_RAT(1) |
S_028C70_RESOURCE_TYPE(evergreen_resource_type(
tex->resource.b.b.target));
}

void evergreen_init_color_surface(struct r600_context *rctx,
struct r600_surface *surf)
{
Expand Down Expand Up @@ -1145,6 +1183,9 @@ void evergreen_init_color_surface(struct r600_context *rctx,

base_offset = rtex->resource.gpu_address;

color_dim = S_028C78_WIDTH_MAX(rtex->resource.b.b.width0 - 1) |
S_028C78_HEIGHT_MAX(rtex->resource.b.b.height0 - 1);

/* XXX handle enabling of CB beyond BASE8 which has different offset */
surf->cb_color_base = (base_offset + offset) >> 8;
surf->cb_color_dim = color_dim;
Expand Down
4 changes: 3 additions & 1 deletion src/gallium/drivers/r600/r600_pipe.h
Expand Up @@ -622,7 +622,9 @@ boolean evergreen_is_format_supported(struct pipe_screen *screen,
unsigned usage);
void evergreen_init_color_surface(struct r600_context *rctx,
struct r600_surface *surf);
void evergreen_init_color_surface_rat(struct r600_context *rctx,
void evergreen_init_color_surface_rat_buf(struct r600_context *rctx,
struct r600_surface *surf);
void evergreen_init_color_surface_rat_tex(struct r600_context *rctx,
struct r600_surface *surf);
void evergreen_update_db_shader_control(struct r600_context * rctx);

Expand Down
1 change: 1 addition & 0 deletions src/gallium/drivers/radeon/r600_texture.c
Expand Up @@ -1116,6 +1116,7 @@ struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe,
surface->base.width = width;
surface->base.height = height;
surface->base.u = templ->u;
surface->base.writable = templ->writable;
return &surface->base;
}

Expand Down

0 comments on commit 872c096

Please sign in to comment.