From 6f4c1976f4e5ecdebfe5b9ac16b6d13a5e60eed1 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Wed, 1 Apr 2015 01:14:39 -0400 Subject: [PATCH] freedreno: convert blit program to array for each number of rts Signed-off-by: Ilia Mirkin --- src/gallium/drivers/freedreno/a2xx/fd2_gmem.c | 2 +- .../drivers/freedreno/a2xx/fd2_program.c | 4 +- .../drivers/freedreno/a2xx/fd2_screen.c | 1 + src/gallium/drivers/freedreno/a3xx/fd3_gmem.c | 2 +- .../drivers/freedreno/a3xx/fd3_screen.c | 1 + src/gallium/drivers/freedreno/a4xx/fd4_gmem.c | 2 +- .../drivers/freedreno/a4xx/fd4_program.c | 2 +- .../drivers/freedreno/a4xx/fd4_screen.c | 1 + .../drivers/freedreno/freedreno_context.h | 2 +- .../drivers/freedreno/freedreno_program.c | 46 +++++++++++++------ .../drivers/freedreno/freedreno_screen.c | 2 +- .../drivers/freedreno/freedreno_screen.h | 1 + 12 files changed, 45 insertions(+), 21 deletions(-) diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c index 8593c4afc0e..982c9c2b097 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c @@ -255,7 +255,7 @@ fd2_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile) OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL)); OUT_RING(ring, 0x0000003b); - fd2_program_emit(ring, &ctx->blit_prog); + fd2_program_emit(ring, &ctx->blit_prog[0]); OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1); OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE); diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_program.c b/src/gallium/drivers/freedreno/a2xx/fd2_program.c index cb6281bd5db..5ccfd58bfe1 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_program.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_program.c @@ -474,6 +474,6 @@ fd2_prog_init(struct pipe_context *pctx) ctx->solid_prog.fp = create_solid_fp(); ctx->solid_prog.vp = create_solid_vp(); - ctx->blit_prog.fp = create_blit_fp(); - ctx->blit_prog.vp = create_blit_vp(); + ctx->blit_prog[0].fp = create_blit_fp(); + ctx->blit_prog[0].vp = create_blit_vp(); } diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_screen.c b/src/gallium/drivers/freedreno/a2xx/fd2_screen.c index 1801d957b15..c2baa6f4cb4 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_screen.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_screen.c @@ -104,6 +104,7 @@ fd2_screen_is_format_supported(struct pipe_screen *pscreen, void fd2_screen_init(struct pipe_screen *pscreen) { + fd_screen(pscreen)->max_rts = 1; pscreen->context_create = fd2_context_create; pscreen->is_format_supported = fd2_screen_is_format_supported; } diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c index 8ec28d92c34..304fc846af8 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c @@ -467,7 +467,7 @@ fd3_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile) enum pipe_format format = pipe_surface_format(pfb->cbufs[0]); struct fd3_emit emit = { .vtx = &fd3_ctx->blit_vbuf_state, - .prog = &ctx->blit_prog, + .prog = &ctx->blit_prog[0], .sprite_coord_enable = 1, .key = { .half_precision = fd3_half_precision(format), diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_screen.c b/src/gallium/drivers/freedreno/a3xx/fd3_screen.c index 5fc63e8febe..182db849902 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_screen.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_screen.c @@ -103,6 +103,7 @@ fd3_screen_is_format_supported(struct pipe_screen *pscreen, void fd3_screen_init(struct pipe_screen *pscreen) { + fd_screen(pscreen)->max_rts = 1; pscreen->context_create = fd3_context_create; pscreen->is_format_supported = fd3_screen_is_format_supported; } diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_gmem.c b/src/gallium/drivers/freedreno/a4xx/fd4_gmem.c index 2c579955712..9a905062071 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_gmem.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_gmem.c @@ -282,7 +282,7 @@ fd4_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile) struct pipe_framebuffer_state *pfb = &ctx->framebuffer; struct fd4_emit emit = { .vtx = &fd4_ctx->blit_vbuf_state, - .prog = &ctx->blit_prog, + .prog = &ctx->blit_prog[0], .key = key, .format = fd4_emit_format(pfb->cbufs[0]), }; diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_program.c b/src/gallium/drivers/freedreno/a4xx/fd4_program.c index 9ee47fbdb66..015f6c85225 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_program.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_program.c @@ -497,7 +497,7 @@ static void fix_blit_fp(struct pipe_context *pctx) { struct fd_context *ctx = fd_context(pctx); - struct fd4_shader_stateobj *so = ctx->blit_prog.fp; + struct fd4_shader_stateobj *so = ctx->blit_prog[0].fp; so->shader->vpsrepl[0] = 0x99999999; so->shader->vpsrepl[1] = 0x99999999; diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_screen.c b/src/gallium/drivers/freedreno/a4xx/fd4_screen.c index cf697d4b741..f5b46685bdf 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_screen.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_screen.c @@ -100,6 +100,7 @@ fd4_screen_is_format_supported(struct pipe_screen *pscreen, void fd4_screen_init(struct pipe_screen *pscreen) { + fd_screen(pscreen)->max_rts = 1; pscreen->context_create = fd4_context_create; pscreen->is_format_supported = fd4_screen_is_format_supported; } diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index 244d527ad20..7b0424e65da 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -176,7 +176,7 @@ struct fd_context { struct fd_program_stateobj solid_prog; // TODO move to screen? /* shaders used by mem->gmem blits: */ - struct fd_program_stateobj blit_prog; // TODO move to screen? + struct fd_program_stateobj blit_prog[8]; // TODO move to screen? /* do we need to mem2gmem before rendering. We don't, if for example, * there was a glClear() that invalidated the entire previous buffer diff --git a/src/gallium/drivers/freedreno/freedreno_program.c b/src/gallium/drivers/freedreno/freedreno_program.c index 167ed02f85d..52a165b64af 100644 --- a/src/gallium/drivers/freedreno/freedreno_program.c +++ b/src/gallium/drivers/freedreno/freedreno_program.c @@ -27,6 +27,7 @@ */ #include "tgsi/tgsi_text.h" +#include "tgsi/tgsi_ureg.h" #include "freedreno_program.h" #include "freedreno_context.h" @@ -64,15 +65,6 @@ static const char *solid_vp = " 0: MOV OUT[0], IN[0] \n" " 1: END \n"; -static const char *blit_fp = - "FRAG \n" - "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1 \n" - "DCL IN[0], TEXCOORD[0], PERSPECTIVE \n" - "DCL OUT[0], COLOR \n" - "DCL SAMP[0] \n" - " 0: TEX OUT[0], IN[0], SAMP[0], 2D \n" - " 1: END \n"; - static const char *blit_vp = "VERT \n" "DCL IN[0] \n" @@ -99,9 +91,31 @@ static void * assemble_tgsi(struct pipe_context *pctx, return pctx->create_vs_state(pctx, &cso); } +static void * +fd_prog_blit(struct pipe_context *pctx, int rts) +{ + int i; + struct ureg_src tc; + struct ureg_program *ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); + if (!ureg) + return NULL; + + tc = ureg_DECL_fs_input( + ureg, TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_PERSPECTIVE); + for (i = 0; i < rts; i++) + ureg_TEX(ureg, ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, i), + TGSI_TEXTURE_2D, tc, ureg_DECL_sampler(ureg, i)); + + ureg_END(ureg); + + return ureg_create_shader_and_destroy(ureg, pctx); +} + + void fd_prog_init(struct pipe_context *pctx) { struct fd_context *ctx = fd_context(pctx); + int i; pctx->bind_fs_state = fd_fp_state_bind; pctx->bind_vs_state = fd_vp_state_bind; @@ -113,16 +127,22 @@ void fd_prog_init(struct pipe_context *pctx) ctx->solid_prog.fp = assemble_tgsi(pctx, solid_fp, true); ctx->solid_prog.vp = assemble_tgsi(pctx, solid_vp, false); - ctx->blit_prog.fp = assemble_tgsi(pctx, blit_fp, true); - ctx->blit_prog.vp = assemble_tgsi(pctx, blit_vp, false); + ctx->blit_prog[0].vp = assemble_tgsi(pctx, blit_vp, false); + ctx->blit_prog[0].fp = fd_prog_blit(pctx, 1); + for (i = 1; i < ctx->screen->max_rts; i++) { + ctx->blit_prog[i].vp = ctx->blit_prog[0].vp; + ctx->blit_prog[i].fp = fd_prog_blit(pctx, i + 1); + } } void fd_prog_fini(struct pipe_context *pctx) { struct fd_context *ctx = fd_context(pctx); + int i; pctx->delete_vs_state(pctx, ctx->solid_prog.vp); pctx->delete_fs_state(pctx, ctx->solid_prog.fp); - pctx->delete_vs_state(pctx, ctx->blit_prog.vp); - pctx->delete_fs_state(pctx, ctx->blit_prog.fp); + pctx->delete_vs_state(pctx, ctx->blit_prog[0].vp); + for (i = 0; i < ctx->screen->max_rts; i++) + pctx->delete_fs_state(pctx, ctx->blit_prog[i].fp); } diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index bb488025ece..fe724442c07 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -252,7 +252,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) /* Render targets. */ case PIPE_CAP_MAX_RENDER_TARGETS: - return 1; + return screen->max_rts; /* Queries. */ case PIPE_CAP_QUERY_TIME_ELAPSED: diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h index e1c554c0538..3b470d1d8a6 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.h +++ b/src/gallium/drivers/freedreno/freedreno_screen.h @@ -46,6 +46,7 @@ struct fd_screen { uint32_t device_id; uint32_t gpu_id; /* 220, 305, etc */ uint32_t chip_id; /* coreid:8 majorrev:8 minorrev:8 patch:8 */ + uint32_t max_rts; struct fd_device *dev; struct fd_pipe *pipe; -- 2.30.2