And you forgot your Signed-off-by line! greets -- Christian Gmeiner, MSc
https://www.youtube.com/user/AloryOFFICIAL https://soundcloud.com/christian-gmeiner 2017-04-13 16:25 GMT+02:00 Christian Gmeiner <christian.gmei...@gmail.com>: > Hi > > 2017-04-13 16:05 GMT+02:00 Wladimir J. van der Laan <laa...@gmail.com>: >> This patch adds support for the SINGLE_BUFFER feature on GC3000 >> GPUs, which allows rendering to a single buffer using multiple pixel >> pipes. >> >> This feature is always used when it is available, which means that >> multi-tiled formats are no longer being used in that case, and all >> buffers will be normal (super)tiled. This mimics the behavior of the >> blob on GC3000. >> >> - Because the same format can be used to render to and texture from, >> this avoids an extra resolve pass when rendering to texture. >> >> - i.MX6qp includes a PRE which can scan-out directly from tiled formats, >> avoiding untiling overhead. > > Just some small nitpicks else > > Series is: > Reviewed-by: Christian Gmeiner <christian.gmei...@gmail.com> > > Btw.. we could land this for 17.0.1 if this lands before 00:00 GMT tomorrow. > >> --- >> src/gallium/drivers/etnaviv/etnaviv_context.c | 3 +++ >> src/gallium/drivers/etnaviv/etnaviv_emit.c | 6 ++++-- >> src/gallium/drivers/etnaviv/etnaviv_internal.h | 3 +++ >> src/gallium/drivers/etnaviv/etnaviv_resource.c | 9 +++++++- >> src/gallium/drivers/etnaviv/etnaviv_rs.c | 29 >> ++++++++++++++++++-------- >> src/gallium/drivers/etnaviv/etnaviv_screen.c | 5 +++++ >> src/gallium/drivers/etnaviv/etnaviv_state.c | 10 +++++++-- >> src/gallium/drivers/etnaviv/etnaviv_surface.c | 21 +++++++++++++------ >> 8 files changed, 66 insertions(+), 20 deletions(-) >> >> diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c >> b/src/gallium/drivers/etnaviv/etnaviv_context.c >> index 555aa12..f2f709c 100644 >> --- a/src/gallium/drivers/etnaviv/etnaviv_context.c >> +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c >> @@ -293,6 +293,9 @@ etna_cmd_stream_reset_notify(struct etna_cmd_stream >> *stream, void *priv) >> etna_set_state(stream, VIVS_RA_EARLY_DEPTH, 0x00000031); >> etna_set_state(stream, VIVS_PA_W_CLIP_LIMIT, 0x34000001); >> >> + /* Enable SINGLE_BUFFER for resolve, if supported */ >> + etna_set_state(stream, VIVS_RS_SINGLE_BUFFER, >> COND(ctx->specs.single_buffer, VIVS_RS_SINGLE_BUFFER_ENABLE)); >> + >> ctx->dirty = ~0L; >> >> /* go through all the used resources and clear their status flag */ >> diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.c >> b/src/gallium/drivers/etnaviv/etnaviv_emit.c >> index af74cbb..7ced5fc 100644 >> --- a/src/gallium/drivers/etnaviv/etnaviv_emit.c >> +++ b/src/gallium/drivers/etnaviv/etnaviv_emit.c >> @@ -603,10 +603,12 @@ etna_emit_state(struct etna_context *ctx) >> if (unlikely(dirty & (ETNA_DIRTY_STENCIL_REF))) { >> /*014A0*/ EMIT_STATE(PE_STENCIL_CONFIG_EXT, >> ctx->stencil_ref.PE_STENCIL_CONFIG_EXT); >> } >> + if (unlikely(dirty & (ETNA_DIRTY_BLEND | ETNA_DIRTY_FRAMEBUFFER))) { >> + struct etna_blend_state *blend = etna_blend_state(ctx->blend); >> + /*014A4*/ EMIT_STATE(PE_LOGIC_OP, blend->PE_LOGIC_OP | >> ctx->framebuffer.PE_LOGIC_OP); >> + } >> if (unlikely(dirty & (ETNA_DIRTY_BLEND))) { >> struct etna_blend_state *blend = etna_blend_state(ctx->blend); >> - >> - /*014A4*/ EMIT_STATE(PE_LOGIC_OP, blend->PE_LOGIC_OP); >> for (int x = 0; x < 2; ++x) { >> /*014A8*/ EMIT_STATE(PE_DITHER(x), blend->PE_DITHER[x]); >> } >> diff --git a/src/gallium/drivers/etnaviv/etnaviv_internal.h >> b/src/gallium/drivers/etnaviv/etnaviv_internal.h >> index 2f09d55..2f8dacb 100644 >> --- a/src/gallium/drivers/etnaviv/etnaviv_internal.h >> +++ b/src/gallium/drivers/etnaviv/etnaviv_internal.h >> @@ -72,6 +72,8 @@ struct etna_specs { >> unsigned has_shader_range_registers : 1; >> /* has the new sin/cos functions */ >> unsigned has_new_sin_cos : 1; >> + /* supports single-buffer rendering with multiple pixel pipes */ >> + unsigned single_buffer : 1; >> /* can use any kind of wrapping mode on npot textures */ >> unsigned npot_tex_any_wrap; >> /* number of bits per TS tile */ >> @@ -191,6 +193,7 @@ struct compiled_framebuffer_state { >> uint32_t TS_COLOR_CLEAR_VALUE; >> struct etna_reloc TS_COLOR_STATUS_BASE; >> struct etna_reloc TS_COLOR_SURFACE_BASE; >> + uint32_t PE_LOGIC_OP; >> bool msaa_mode; /* adds input (and possible temp) to PS */ >> }; >> >> diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c >> b/src/gallium/drivers/etnaviv/etnaviv_resource.c >> index 1f0582c..b4e853f 100644 >> --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c >> +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c >> @@ -248,9 +248,16 @@ etna_resource_create(struct pipe_screen *pscreen, >> if (util_format_is_compressed(templat->format)) >> layout = ETNA_LAYOUT_LINEAR; >> } else if (templat->target != PIPE_BUFFER) { >> - bool want_multitiled = screen->specs.pixel_pipes > 1; >> + bool want_multitiled = false; >> bool want_supertiled = screen->specs.can_supertile && >> !DBG_ENABLED(ETNA_DBG_NO_SUPERTILE); >> >> + /* When this GPU supports single-buffer rendering, don't ever enable >> + * multi-tiling. This replicates the blob behavior on GC3000. >> + */ >> + if (!screen->specs.single_buffer) { >> + want_multitiled = screen->specs.pixel_pipes > 1; >> + } >> + > > Kick not needed { } > >> /* Keep single byte blocksized resources as tiled, since we >> * are unable to use the RS blit to de-tile them. However, >> * if they're used as a render target or depth/stencil, they >> diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c >> b/src/gallium/drivers/etnaviv/etnaviv_rs.c >> index 295ca10..e133ac6 100644 >> --- a/src/gallium/drivers/etnaviv/etnaviv_rs.c >> +++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c >> @@ -70,19 +70,27 @@ etna_compile_rs_state(struct etna_context *ctx, struct >> compiled_rs_state *cs, >> COND(rs->source_tiling & 2, >> VIVS_RS_SOURCE_STRIDE_TILING) | >> COND(source_multi, VIVS_RS_SOURCE_STRIDE_MULTI); >> >> - cs->source[0].bo = rs->source; >> - cs->source[0].offset = rs->source_offset; >> - cs->source[0].flags = ETNA_RELOC_READ; >> + /* Initially all pipes to the source and destination buffer >> + * This will be overridden below as necessary for the multi-pipe, >> + * multi-tiled case. >> + */ >> + for (unsigned pipe = 0; pipe < ctx->specs.pixel_pipes; ++pipe) { >> + cs->source[pipe].bo = rs->source; >> + cs->source[pipe].offset = rs->source_offset; >> + cs->source[pipe].flags = ETNA_RELOC_READ; >> + >> + cs->dest[pipe].bo = rs->dest; >> + cs->dest[pipe].offset = rs->dest_offset; >> + cs->dest[pipe].flags = ETNA_RELOC_WRITE; >> >> - cs->dest[0].bo = rs->dest; >> - cs->dest[0].offset = rs->dest_offset; >> - cs->dest[0].flags = ETNA_RELOC_WRITE; >> + cs->RS_PIPE_OFFSET[pipe] = VIVS_RS_PIPE_OFFSET_X(0) | >> VIVS_RS_PIPE_OFFSET_Y(0); >> + } >> >> cs->RS_DEST_STRIDE = (rs->dest_stride << dest_stride_shift) | >> COND(rs->dest_tiling & 2, >> VIVS_RS_DEST_STRIDE_TILING) | >> COND(dest_multi, VIVS_RS_DEST_STRIDE_MULTI); >> >> - if (ctx->specs.pixel_pipes == 1) { >> + if (ctx->specs.pixel_pipes == 1 || ctx->specs.single_buffer) { >> cs->RS_WINDOW_SIZE = VIVS_RS_WINDOW_SIZE_WIDTH(rs->width) | >> VIVS_RS_WINDOW_SIZE_HEIGHT(rs->height); >> } else if (ctx->specs.pixel_pipes == 2) { >> @@ -102,12 +110,11 @@ etna_compile_rs_state(struct etna_context *ctx, struct >> compiled_rs_state *cs, >> >> cs->RS_WINDOW_SIZE = VIVS_RS_WINDOW_SIZE_WIDTH(rs->width) | >> VIVS_RS_WINDOW_SIZE_HEIGHT(rs->height / 2); >> + cs->RS_PIPE_OFFSET[1] = VIVS_RS_PIPE_OFFSET_X(0) | >> VIVS_RS_PIPE_OFFSET_Y(rs->height / 2); >> } else { >> abort(); >> } >> >> - cs->RS_PIPE_OFFSET[0] = VIVS_RS_PIPE_OFFSET_X(0) | >> VIVS_RS_PIPE_OFFSET_Y(0); >> - cs->RS_PIPE_OFFSET[1] = VIVS_RS_PIPE_OFFSET_X(0) | >> VIVS_RS_PIPE_OFFSET_Y(rs->height / 2); >> cs->RS_DITHER[0] = rs->dither[0]; >> cs->RS_DITHER[1] = rs->dither[1]; >> cs->RS_CLEAR_CONTROL = VIVS_RS_CLEAR_CONTROL_BITS(rs->clear_bits) | >> rs->clear_mode; >> @@ -117,6 +124,10 @@ etna_compile_rs_state(struct etna_context *ctx, struct >> compiled_rs_state *cs, >> cs->RS_FILL_VALUE[3] = rs->clear_value[3]; >> cs->RS_EXTRA_CONFIG = VIVS_RS_EXTRA_CONFIG_AA(rs->aa) | >> VIVS_RS_EXTRA_CONFIG_ENDIAN(rs->endian_mode); >> + /* TODO: cs->RS_UNK016B0 = s->size / 64 ? >> + * The blob does this consistently but there seems to be no currently >> supported >> + * model that needs it. >> + */ >> } >> >> void >> diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c >> b/src/gallium/drivers/etnaviv/etnaviv_screen.c >> index 41bacbc..9f3104f 100644 >> --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c >> +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c >> @@ -675,6 +675,11 @@ etna_get_specs(struct etna_screen *screen) >> screen->specs.max_rendertarget_size = >> VIV_FEATURE(screen, chipMinorFeatures0, RENDERTARGET_8K) ? 8192 : >> 2048; >> >> + screen->specs.single_buffer = VIV_FEATURE(screen, chipMinorFeatures4, >> SINGLE_BUFFER); >> + if (screen->specs.single_buffer) { >> + DBG("etnaviv: Single buffer mode enabled with %i pixel pipes\n", >> screen->specs.pixel_pipes); >> + } >> + > > Kick not needed { } > >> return true; >> >> fail: >> diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c >> b/src/gallium/drivers/etnaviv/etnaviv_state.c >> index dbb6c54..d96b445 100644 >> --- a/src/gallium/drivers/etnaviv/etnaviv_state.c >> +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c >> @@ -168,8 +168,8 @@ etna_set_framebuffer_state(struct pipe_context *pctx, >> cs->PE_COLOR_ADDR = cbuf->reloc[0]; >> cs->PE_COLOR_ADDR.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE; >> } else { >> - /* Rendered textures must always be multi-tiled */ >> - assert(res->layout & ETNA_LAYOUT_BIT_MULTI); >> + /* Rendered textures must always be multi-tiled, or single-buffer >> mode must be supported */ >> + assert((res->layout & ETNA_LAYOUT_BIT_MULTI) || >> ctx->specs.single_buffer); >> for (int i = 0; i < ctx->specs.pixel_pipes; i++) { >> cs->PE_PIPE_COLOR_ADDR[i] = cbuf->reloc[i]; >> cs->PE_PIPE_COLOR_ADDR[i].flags = ETNA_RELOC_READ | >> ETNA_RELOC_WRITE; >> @@ -331,6 +331,12 @@ etna_set_framebuffer_state(struct pipe_context *pctx, >> >> cs->TS_MEM_CONFIG = ts_mem_config; >> >> + /* Single buffer setup. There is only one switch for this, not a separate >> + * one per color buffer / depth buffer. To keep the logic simple always >> use >> + * single buffer when this feature is available. >> + */ >> + cs->PE_LOGIC_OP = >> VIVS_PE_LOGIC_OP_SINGLE_BUFFER(ctx->specs.single_buffer ? 2 : 0); >> + >> ctx->framebuffer_s = *sv; /* keep copy of original structure */ >> ctx->dirty |= ETNA_DIRTY_FRAMEBUFFER; >> } >> diff --git a/src/gallium/drivers/etnaviv/etnaviv_surface.c >> b/src/gallium/drivers/etnaviv/etnaviv_surface.c >> index a0013a4..d19f493 100644 >> --- a/src/gallium/drivers/etnaviv/etnaviv_surface.c >> +++ b/src/gallium/drivers/etnaviv/etnaviv_surface.c >> @@ -94,12 +94,21 @@ etna_create_surface(struct pipe_context *pctx, struct >> pipe_resource *prsc, >> struct etna_resource_level *lev = &rsc->levels[level]; >> >> /* Setup template relocations for this surface */ >> - surf->reloc[0].bo = rsc->bo; >> - surf->reloc[0].offset = surf->surf.offset; >> - surf->reloc[0].flags = 0; >> - surf->reloc[1].bo = rsc->bo; >> - surf->reloc[1].offset = surf->surf.offset + lev->stride * >> lev->padded_height / 2; >> - surf->reloc[1].flags = 0; >> + for (unsigned pipe = 0; pipe < ctx->specs.pixel_pipes; ++pipe) { >> + surf->reloc[pipe].bo = rsc->bo; >> + surf->reloc[pipe].offset = surf->surf.offset; >> + surf->reloc[pipe].flags = 0; >> + } >> + >> + /* In single buffer mode, both pixel pipes must point to the same >> address, >> + * for multi-tiled surfaces on the other hand the second pipe is >> expected to >> + * point halfway the image vertically. >> + */ >> + if (rsc->layout & ETNA_LAYOUT_BIT_MULTI) { >> + surf->reloc[1].bo = rsc->bo; >> + surf->reloc[1].offset = surf->surf.offset + lev->stride * >> lev->padded_height / 2; >> + surf->reloc[1].flags = 0; >> + } >> >> if (surf->surf.ts_size) { >> unsigned int layer_offset = layer * surf->surf.ts_layer_stride; >> -- >> 2.7.4 >> _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev