[Mesa-dev] [PATCH 2/2] r600, compute: setup RATs for write-only images
Zoltan Gilian
zoltan.gilian at gmail.com
Mon Aug 10 11:32:44 PDT 2015
---
src/gallium/drivers/r600/evergreen_compute.c | 101 ++++++++++++++++-----------
src/gallium/drivers/r600/evergreen_state.c | 44 +++++++++++-
src/gallium/drivers/r600/r600_pipe.h | 4 +-
src/gallium/drivers/radeon/r600_texture.c | 1 +
4 files changed, 109 insertions(+), 41 deletions(-)
diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
index 8b27a66..6f39507 100644
--- a/src/gallium/drivers/r600/evergreen_compute.c
+++ b/src/gallium/drivers/r600/evergreen_compute.c
@@ -99,8 +99,39 @@ 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);
+
+ /* 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 << 2));
+}
+
+static void evergreen_unset_cbuf(
+ struct r600_context *ctx,
+ unsigned id)
+{
+ struct pipe_framebuffer_state *state = &ctx->framebuffer.state;
+
+ state->cbufs[id] = NULL;
+ ctx->compute_cb_target_mask &= ~(0xf << (id << 2));
+ /* nr_cbufs = ceil(last_bit / 4) */
+ state->nr_cbufs = (util_last_bit(ctx->compute_cb_target_mask) + 3) >> 2;
+}
-static void evergreen_set_rat(
+static void evergreen_set_rat_buf(
struct r600_context *ctx,
unsigned id,
struct r600_resource* bo,
@@ -123,23 +154,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(
@@ -623,32 +642,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 +707,9 @@ static void evergreen_set_global_binding(
first, n);
if (!resources) {
- /* XXX: Unset */
+ /* evergreen_set_rat_buf creates a new surface. */
+ ctx_->surface_destroy(ctx_, ctx->framebuffer.state.cbufs[0]);
+ evergreen_unset_cbuf(ctx, 0);
return;
}
@@ -717,7 +740,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);
}
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index f479698..688a092 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -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) {
@@ -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;
@@ -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);
@@ -977,6 +1003,19 @@ 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));
+ util_range_add(&tex->resource.valid_buffer_range, 0, tex->size);
+}
+
void evergreen_init_color_surface(struct r600_context *rctx,
struct r600_surface *surf)
{
@@ -1145,6 +1184,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;
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index bcb9390..84c921a 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -567,7 +567,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);
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index d05b0a1..b9fa78e 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -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;
}
--
2.4.6
More information about the mesa-dev
mailing list