From 7c3140db22a1cde7535061e6f3e96f96790fa564 Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Fri, 4 Dec 2020 16:44:41 +0200 Subject: [PATCH] freedreno/a6xx: support layered framebuffers in blitter_clear Clear is done with one instanced draw call, where the layer to clear is controlled by gl_Layer. Same as how util_blitter_clear does this. Fixes test: gl-3.2-layered-rendering-clear-color-all-types 2d_multisample_array single_level Signed-off-by: Danylo Piliaiev Part-of: --- src/gallium/drivers/freedreno/freedreno_blitter.c | 9 +++++++-- src/gallium/drivers/freedreno/freedreno_context.h | 1 + src/gallium/drivers/freedreno/freedreno_program.c | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/freedreno/freedreno_blitter.c b/src/gallium/drivers/freedreno/freedreno_blitter.c index e8e2972..e4cc041 100644 --- a/src/gallium/drivers/freedreno/freedreno_blitter.c +++ b/src/gallium/drivers/freedreno/freedreno_blitter.c @@ -222,7 +222,12 @@ fd_blitter_clear(struct pipe_context *pctx, unsigned buffers, pctx->set_vertex_buffers(pctx, blitter->vb_slot, 1, &ctx->solid_vbuf_state.vertexbuf.vb[0]); pctx->set_stream_output_targets(pctx, 0, NULL, NULL); - pctx->bind_vs_state(pctx, ctx->solid_prog.vs); + + if (pfb->layers > 1) + pctx->bind_vs_state(pctx, ctx->solid_layered_prog.vs); + else + pctx->bind_vs_state(pctx, ctx->solid_prog.vs); + pctx->bind_fs_state(pctx, ctx->solid_prog.fs); /* Clear geom/tess shaders, lest the draw emit code think we are @@ -235,7 +240,7 @@ fd_blitter_clear(struct pipe_context *pctx, unsigned buffers, struct pipe_draw_info info = { .mode = PIPE_PRIM_MAX, /* maps to DI_PT_RECTLIST */ .max_index = 1, - .instance_count = 1, + .instance_count = MAX2(1, pfb->layers), }; struct pipe_draw_start_count draw = { .count = 2, diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index 785345f..7aed573 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -253,6 +253,7 @@ struct fd_context { /* shaders used by clear, and gmem->mem blits: */ struct fd_program_stateobj solid_prog; // TODO move to screen? + struct fd_program_stateobj solid_layered_prog; /* shaders used by mem->gmem blits: */ struct fd_program_stateobj blit_prog[MAX_RENDER_TARGETS]; // TODO move to screen? diff --git a/src/gallium/drivers/freedreno/freedreno_program.c b/src/gallium/drivers/freedreno/freedreno_program.c index 057d3a2..c09923a 100644 --- a/src/gallium/drivers/freedreno/freedreno_program.c +++ b/src/gallium/drivers/freedreno/freedreno_program.c @@ -27,6 +27,8 @@ #include "tgsi/tgsi_text.h" #include "tgsi/tgsi_ureg.h" +#include "util/u_simple_shaders.h" + #include "freedreno_program.h" #include "freedreno_context.h" @@ -188,6 +190,12 @@ void fd_prog_init(struct pipe_context *pctx) ctx->solid_prog.fs = assemble_tgsi(pctx, solid_fs, true); ctx->solid_prog.vs = assemble_tgsi(pctx, solid_vs, false); + if (ctx->screen->gpu_id >= 600) { + ctx->solid_layered_prog.fs = assemble_tgsi(pctx, solid_fs, true); + ctx->solid_layered_prog.vs = + util_make_layered_clear_vertex_shader(pctx); + } + if (ctx->screen->gpu_id >= 500) return; @@ -215,6 +223,12 @@ void fd_prog_fini(struct pipe_context *pctx) pctx->delete_vs_state(pctx, ctx->solid_prog.vs); pctx->delete_fs_state(pctx, ctx->solid_prog.fs); + + if (ctx->screen->gpu_id >= 600) { + pctx->delete_vs_state(pctx, ctx->solid_layered_prog.vs); + pctx->delete_fs_state(pctx, ctx->solid_layered_prog.fs); + } + if (ctx->screen->gpu_id >= 500) return; -- 2.7.4