summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/freedreno/a5xx
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2019-02-05 15:33:57 -0500
committerRob Clark <robdclark@gmail.com>2019-02-16 16:27:59 -0500
commit2e0ea3f09c79c657116cbc9cbc68377e364dfe28 (patch)
tree5d6f4a3793b79332d6de26140fd1b3d21703b131 /src/gallium/drivers/freedreno/a5xx
parent75f3a5245e54d1be5b75db66ba50d7c2f5dee4fc (diff)
freedreno/ir3: add image/ssbo <-> ibo/tex mapping
Images and SSBOs don't map directly to the hw. They end up being part texture and part something else. Starting with a6xx, the hack used for a5xx to smash the image tex state into hw texture state starting from MAX counting down won't work, because we start using tex state also for SSBO read. Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'src/gallium/drivers/freedreno/a5xx')
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_emit.c67
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_image.c29
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_image.h3
3 files changed, 32 insertions, 67 deletions
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
index ad942fd7f5a..515d120bb1c 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
@@ -396,37 +396,24 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
static void
emit_ssbos(struct fd_context *ctx, struct fd_ringbuffer *ring,
- enum a4xx_state_block sb, struct fd_shaderbuf_stateobj *so)
+ enum a4xx_state_block sb, struct fd_shaderbuf_stateobj *so,
+ const struct ir3_shader_variant *v)
{
unsigned count = util_last_bit(so->enabled_mask);
+ const struct ir3_ibo_mapping *m = &v->image_mapping;
- if (count == 0)
- return;
-
- OUT_PKT7(ring, CP_LOAD_STATE4, 3 + (4 * count));
- OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(0) |
- CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |
- CP_LOAD_STATE4_0_STATE_BLOCK(sb) |
- CP_LOAD_STATE4_0_NUM_UNIT(count));
- OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(0) |
- CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));
- OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
for (unsigned i = 0; i < count; i++) {
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
- OUT_RING(ring, 0x00000000);
- }
+ unsigned slot = m->ssbo_to_ibo[i];
+
+ OUT_PKT7(ring, CP_LOAD_STATE4, 5);
+ OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(slot) |
+ CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |
+ CP_LOAD_STATE4_0_STATE_BLOCK(sb) |
+ CP_LOAD_STATE4_0_NUM_UNIT(1));
+ OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(1) |
+ CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));
+ OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
- OUT_PKT7(ring, CP_LOAD_STATE4, 3 + (2 * count));
- OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(0) |
- CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |
- CP_LOAD_STATE4_0_STATE_BLOCK(sb) |
- CP_LOAD_STATE4_0_NUM_UNIT(count));
- OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(1) |
- CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));
- OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
- for (unsigned i = 0; i < count; i++) {
struct pipe_shader_buffer *buf = &so->sb[i];
unsigned sz = buf->buffer_size;
@@ -435,18 +422,16 @@ emit_ssbos(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RING(ring, A5XX_SSBO_1_0_WIDTH(sz));
OUT_RING(ring, A5XX_SSBO_1_1_HEIGHT(sz >> 16));
- }
- OUT_PKT7(ring, CP_LOAD_STATE4, 3 + (2 * count));
- OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(0) |
- CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |
- CP_LOAD_STATE4_0_STATE_BLOCK(sb) |
- CP_LOAD_STATE4_0_NUM_UNIT(count));
- OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(2) |
- CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));
- OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
- for (unsigned i = 0; i < count; i++) {
- struct pipe_shader_buffer *buf = &so->sb[i];
+ OUT_PKT7(ring, CP_LOAD_STATE4, 5);
+ OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(slot) |
+ CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |
+ CP_LOAD_STATE4_0_STATE_BLOCK(sb) |
+ CP_LOAD_STATE4_0_NUM_UNIT(1));
+ OUT_RING(ring, CP_LOAD_STATE4_1_STATE_TYPE(2) |
+ CP_LOAD_STATE4_1_EXT_SRC_ADDR(0));
+ OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
+
if (buf->buffer) {
struct fd_resource *rsc = fd_resource(buf->buffer);
OUT_RELOCW(ring, rsc->bo, buf->buffer_offset, 0, 0);
@@ -821,10 +806,10 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
emit_border_color(ctx, ring);
if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_SSBO)
- emit_ssbos(ctx, ring, SB4_SSBO, &ctx->shaderbuf[PIPE_SHADER_FRAGMENT]);
+ emit_ssbos(ctx, ring, SB4_SSBO, &ctx->shaderbuf[PIPE_SHADER_FRAGMENT], fp);
if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_IMAGE)
- fd5_emit_images(ctx, ring, PIPE_SHADER_FRAGMENT);
+ fd5_emit_images(ctx, ring, PIPE_SHADER_FRAGMENT, fp);
}
void
@@ -862,10 +847,10 @@ fd5_emit_cs_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
~0 : ctx->tex[PIPE_SHADER_COMPUTE].num_textures);
if (dirty & FD_DIRTY_SHADER_SSBO)
- emit_ssbos(ctx, ring, SB4_CS_SSBO, &ctx->shaderbuf[PIPE_SHADER_COMPUTE]);
+ emit_ssbos(ctx, ring, SB4_CS_SSBO, &ctx->shaderbuf[PIPE_SHADER_COMPUTE], cp);
if (dirty & FD_DIRTY_SHADER_IMAGE)
- fd5_emit_images(ctx, ring, PIPE_SHADER_COMPUTE);
+ fd5_emit_images(ctx, ring, PIPE_SHADER_COMPUTE, cp);
}
/* emit setup at begin of new cmdstream buffer (don't rely on previous
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_image.c b/src/gallium/drivers/freedreno/a5xx/fd5_image.c
index 028497f3a10..c53b2e92245 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_image.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_image.c
@@ -189,46 +189,25 @@ static void emit_image_ssbo(struct fd_ringbuffer *ring, unsigned slot,
}
}
-/* Note that to avoid conflicts with textures and non-image "SSBO"s, images
- * are placedd, in reverse order, at the end of the state block, so for
- * example the sampler state:
- *
- * 0: first texture
- * 1: second texture
- * ....
- * N-1: second image
- * N: first image
- */
-static unsigned
-get_image_slot(unsigned index)
-{
- /* TODO figure out real limit per generation, and don't hardcode.
- * This needs to match get_image_slot() in ir3_compiler_nir.
- * Possibly should be factored out into shared helper?
- */
- const unsigned max_samplers = 16;
- return max_samplers - index - 1;
-}
-
/* Emit required "SSBO" and sampler state. The sampler state is used by the
* hw for imageLoad(), and "SSBO" state for imageStore(). Returns max sampler
* used.
*/
void
fd5_emit_images(struct fd_context *ctx, struct fd_ringbuffer *ring,
- enum pipe_shader_type shader)
+ enum pipe_shader_type shader, const struct ir3_shader_variant *v)
{
struct fd_shaderimg_stateobj *so = &ctx->shaderimg[shader];
unsigned enabled_mask = so->enabled_mask;
+ const struct ir3_ibo_mapping *m = &v->image_mapping;
while (enabled_mask) {
unsigned index = u_bit_scan(&enabled_mask);
- unsigned slot = get_image_slot(index);
struct fd5_image img;
translate_image(&img, &so->si[index]);
- emit_image_tex(ring, slot, &img, shader);
- emit_image_ssbo(ring, slot, &img, shader);
+ emit_image_tex(ring, m->image_to_tex[index] + m->tex_base, &img, shader);
+ emit_image_ssbo(ring, m->image_to_ibo[index], &img, shader);
}
}
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_image.h b/src/gallium/drivers/freedreno/a5xx/fd5_image.h
index 98c7faf6154..f7567826ba6 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_image.h
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_image.h
@@ -29,7 +29,8 @@
#include "freedreno_context.h"
+struct ir3_shader_variant;
void fd5_emit_images(struct fd_context *ctx, struct fd_ringbuffer *ring,
- enum pipe_shader_type shader);
+ enum pipe_shader_type shader, const struct ir3_shader_variant *v);
#endif /* FD5_IMAGE_H_ */