From 954a704da3052028da4129cc7757f5f224ee1ffc Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 28 Dec 2017 14:00:15 -0800 Subject: [PATCH] broadcom/vc5: Port the RCL setup to V3D4.1. The TLB load/store path is rebuilt in this version. There is no longer a single-byte resolved store or the 3-byte extended store. Instead, you get to always use general loads/stores (which, honestly, was tempting even in previous versions). --- src/gallium/drivers/vc5/Makefile.am | 16 +- src/gallium/drivers/vc5/Makefile.sources | 5 +- src/gallium/drivers/vc5/meson.build | 24 +- src/gallium/drivers/vc5/v3dx_context.h | 29 ++ src/gallium/drivers/vc5/vc5_context.h | 16 +- src/gallium/drivers/vc5/vc5_job.c | 5 +- src/gallium/drivers/vc5/vc5_rcl.c | 323 +++++++++++++++++++---- 7 files changed, 360 insertions(+), 58 deletions(-) create mode 100644 src/gallium/drivers/vc5/v3dx_context.h diff --git a/src/gallium/drivers/vc5/Makefile.am b/src/gallium/drivers/vc5/Makefile.am index 42d4be73d26..b8f7e484b34 100644 --- a/src/gallium/drivers/vc5/Makefile.am +++ b/src/gallium/drivers/vc5/Makefile.am @@ -31,10 +31,24 @@ AM_CFLAGS = \ $(VALGRIND_CFLAGS) \ $() -noinst_LTLIBRARIES = libvc5.la +noinst_LTLIBRARIES = \ + libvc5.la \ + libvc5_v33.la \ + libvc5_v41.la \ + $() + +libvc5_v33_la_SOURCES = $(VC5_PER_VERSION_SOURCES) +libvc5_v33_la_CFLAGS = -DV3D_VERSION=33 + +libvc5_v41_la_SOURCES = $(VC5_PER_VERSION_SOURCES) +libvc5_v41_la_CFLAGS = -DV3D_VERSION=41 libvc5_la_SOURCES = $(C_SOURCES) libvc5_la_LDFLAGS = \ $(VC5_SIMULATOR_LIBS) \ $(NULL) +libvc5_la_LIBADD = \ + libvc5_v33.la \ + libvc5_v41.la \ + $() diff --git a/src/gallium/drivers/vc5/Makefile.sources b/src/gallium/drivers/vc5/Makefile.sources index 3fb6a0d0911..f942c74ca30 100644 --- a/src/gallium/drivers/vc5/Makefile.sources +++ b/src/gallium/drivers/vc5/Makefile.sources @@ -14,7 +14,6 @@ C_SOURCES := \ vc5_job.c \ vc5_program.c \ vc5_query.c \ - vc5_rcl.c \ vc5_resource.c \ vc5_resource.h \ vc5_screen.c \ @@ -25,3 +24,7 @@ C_SOURCES := \ vc5_tiling.h \ vc5_uniforms.c \ $() + +VC5_PER_VERSION_SOURCES = \ + vc5_rcl.c \ + $() diff --git a/src/gallium/drivers/vc5/meson.build b/src/gallium/drivers/vc5/meson.build index deaa81fdb9d..ad4395212b2 100644 --- a/src/gallium/drivers/vc5/meson.build +++ b/src/gallium/drivers/vc5/meson.build @@ -33,7 +33,6 @@ files_libvc5 = files( 'vc5_job.c', 'vc5_program.c', 'vc5_query.c', - 'vc5_rcl.c', 'vc5_resource.c', 'vc5_resource.h', 'vc5_screen.c', @@ -46,12 +45,34 @@ files_libvc5 = files( 'vc5_uniforms.c', ) +files_per_version = files( + 'vc5_rcl.c', +) + v3dv3_c_args = [] dep_v3dv3 = dependency('v3dv3') if dep_v3dv3.found() v3dv3_c_args = '-DUSE_VC5_SIMULATOR' endif +vc5_versions = ['33', '41'] + +per_version_libs = [] +foreach ver : vc5_versions + per_version_libs += static_library( + 'vc5-v' + ver, + [files_per_version, v3d_xml_pack, nir_opcodes_h, nir_builder_opcodes_h], + include_directories : [ + inc_src, inc_include, inc_gallium, inc_gallium_aux, inc_broadcom, + inc_gallium_drivers, inc_drm_uapi, + ], + c_args : [c_vis_args, v3dv3_c_args, '-DV3D_VERSION=' + ver], + cpp_args : [cpp_vis_args], + dependencies : [dep_v3dv3, dep_libdrm, dep_valgrind], +) + +endforeach + libvc5 = static_library( 'vc5', [files_libvc5, v3d_xml_pack], @@ -62,6 +83,7 @@ libvc5 = static_library( c_args : [c_vis_args, v3dv3_c_args], cpp_args : [cpp_vis_args, v3dv3_c_args], dependencies : [dep_v3dv3, dep_libdrm, dep_valgrind, idep_nir_headers], + link_with: per_version_libs, ) driver_vc5 = declare_dependency( diff --git a/src/gallium/drivers/vc5/v3dx_context.h b/src/gallium/drivers/vc5/v3dx_context.h new file mode 100644 index 00000000000..19ca956922c --- /dev/null +++ b/src/gallium/drivers/vc5/v3dx_context.h @@ -0,0 +1,29 @@ +/* + * Copyright © 2014-2017 Broadcom + * Copyright (C) 2012 Rob Clark + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* This file generates the per-v3d-version function prototypes. It must only + * be included from vc5_context.h. + */ + +void v3dX(emit_rcl)(struct vc5_job *job); diff --git a/src/gallium/drivers/vc5/vc5_context.h b/src/gallium/drivers/vc5/vc5_context.h index 04ab506f035..0e7cff7482b 100644 --- a/src/gallium/drivers/vc5/vc5_context.h +++ b/src/gallium/drivers/vc5/vc5_context.h @@ -25,6 +25,10 @@ #ifndef VC5_CONTEXT_H #define VC5_CONTEXT_H +#ifdef V3D_VERSION +#include "broadcom/common/v3d_macros.h" +#endif + #include #include "pipe/p_context.h" @@ -504,7 +508,17 @@ void vc5_get_internal_type_bpp_for_output_format(uint32_t format, void vc5_init_query_functions(struct vc5_context *vc5); void vc5_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info); void vc5_blitter_save(struct vc5_context *vc5); -void vc5_emit_rcl(struct vc5_job *job); +#ifdef v3dX +# include "v3dx_context.h" +#else +# define v3dX(x) v3d33_##x +# include "v3dx_context.h" +# undef v3dX + +# define v3dX(x) v3d41_##x +# include "v3dx_context.h" +# undef v3dX +#endif #endif /* VC5_CONTEXT_H */ diff --git a/src/gallium/drivers/vc5/vc5_job.c b/src/gallium/drivers/vc5/vc5_job.c index 07d39f3b229..02a7d53a99e 100644 --- a/src/gallium/drivers/vc5/vc5_job.c +++ b/src/gallium/drivers/vc5/vc5_job.c @@ -382,7 +382,10 @@ vc5_job_submit(struct vc5_context *vc5, struct vc5_job *job) goto done; } - vc5_emit_rcl(job); + if (vc5->screen->devinfo.ver >= 41) + v3d41_emit_rcl(job); + else + v3d33_emit_rcl(job); if (cl_offset(&job->bcl) > 0) { vc5_cl_ensure_space_with_branch(&job->bcl, diff --git a/src/gallium/drivers/vc5/vc5_rcl.c b/src/gallium/drivers/vc5/vc5_rcl.c index 56c6a16cc51..8018bfdcba1 100644 --- a/src/gallium/drivers/vc5/vc5_rcl.c +++ b/src/gallium/drivers/vc5/vc5_rcl.c @@ -24,7 +24,6 @@ #include "util/u_format.h" #include "vc5_context.h" #include "vc5_tiling.h" -#define V3D_VERSION 33 #include "broadcom/common/v3d_macros.h" #include "broadcom/cle/v3dx_pack.h" @@ -36,36 +35,129 @@ #define PIPE_FIRST_COLOR_BUFFER_BIT (ffs(PIPE_CLEAR_COLOR0) - 1) static void -load_raw(struct vc5_cl *cl, struct pipe_surface *psurf, int buffer) +load_general(struct vc5_cl *cl, struct pipe_surface *psurf, int buffer) { struct vc5_surface *surf = vc5_surface(psurf); struct vc5_resource *rsc = vc5_resource(psurf->texture); + struct vc5_resource *separate_stencil = NULL; + if (rsc->separate_stencil && buffer == STENCIL) + separate_stencil = rsc->separate_stencil; + cl_emit(cl, LOAD_TILE_BUFFER_GENERAL, load) { - load.raw_mode = true; load.buffer_to_load = buffer; - load.address = cl_address(rsc->bo, surf->offset); + if (separate_stencil) { + load.address = cl_address(separate_stencil->bo, + surf->separate_stencil_offset); + } else { + load.address = cl_address(rsc->bo, surf->offset); + } + +#if V3D_VERSION >= 40 + if (separate_stencil) { + load.input_image_format = V3D_OUTPUT_IMAGE_FORMAT_S8; + load.memory_format = surf->separate_stencil_tiling; + } else { + load.input_image_format = surf->format; + load.memory_format = surf->tiling; + } + + if (surf->tiling == VC5_TILING_UIF_NO_XOR || + surf->tiling == VC5_TILING_UIF_XOR) { + if (separate_stencil) { + load.height_in_ub_or_stride = + surf->separate_stencil_padded_height_of_output_image_in_uif_blocks; + } else { + load.height_in_ub_or_stride = + surf->padded_height_of_output_image_in_uif_blocks; + } + } else if (surf->tiling == VC5_TILING_RASTER) { + struct vc5_resource_slice *slice = + &rsc->slices[psurf->u.tex.level]; + load.height_in_ub_or_stride = slice->stride; + } + + /* XXX: MSAA */ +#else /* V3D_VERSION < 40 */ + load.raw_mode = true; load.padded_height_of_output_image_in_uif_blocks = surf->padded_height_of_output_image_in_uif_blocks; +#endif /* V3D_VERSION < 40 */ } } static void -store_raw(struct vc5_cl *cl, struct pipe_surface *psurf, int buffer, - bool color_clear, bool z_clear, bool s_clear) +store_general(struct vc5_job *job, + struct vc5_cl *cl, struct pipe_surface *psurf, int buffer, + int pipe_bit, bool last_store, bool general_color_clear) { struct vc5_surface *surf = vc5_surface(psurf); struct vc5_resource *rsc = vc5_resource(psurf->texture); + struct vc5_resource *separate_stencil = NULL; + if (rsc->separate_stencil && buffer == STENCIL) { + separate_stencil = rsc->separate_stencil; + separate_stencil->writes++; + } else { + rsc->writes++; + } + cl_emit(cl, STORE_TILE_BUFFER_GENERAL, store) { - store.raw_mode = true; store.buffer_to_store = buffer; - store.address = cl_address(rsc->bo, surf->offset); - store.disable_colour_buffers_clear_on_write = !color_clear; - store.disable_z_buffer_clear_on_write = !z_clear; - store.disable_stencil_buffer_clear_on_write = !s_clear; + if (separate_stencil) { + store.address = cl_address(separate_stencil->bo, + surf->separate_stencil_offset); + } else { + store.address = cl_address(rsc->bo, surf->offset); + } + +#if V3D_VERSION >= 40 + store.clear_buffer_being_stored = + ((job->cleared & pipe_bit) && + (general_color_clear || + !(pipe_bit & PIPE_CLEAR_COLOR_BUFFERS))); + + if (separate_stencil) { + store.output_image_format = V3D_OUTPUT_IMAGE_FORMAT_S8; + store.memory_format = surf->separate_stencil_tiling; + } else { + store.output_image_format = surf->format; + store.memory_format = surf->tiling; + } + + if (surf->tiling == VC5_TILING_UIF_NO_XOR || + surf->tiling == VC5_TILING_UIF_XOR) { + if (separate_stencil) { + store.height_in_ub_or_stride = + surf->separate_stencil_padded_height_of_output_image_in_uif_blocks; + } else { + store.height_in_ub_or_stride = + surf->padded_height_of_output_image_in_uif_blocks; + } + } else if (surf->tiling == VC5_TILING_RASTER) { + struct vc5_resource_slice *slice = + &rsc->slices[psurf->u.tex.level]; + store.height_in_ub_or_stride = slice->stride; + } +#else /* V3D_VERSION < 40 */ + store.raw_mode = true; + if (!last_store) { + store.disable_colour_buffers_clear_on_write = true; + store.disable_z_buffer_clear_on_write = true; + store.disable_stencil_buffer_clear_on_write = true; + } else { + store.disable_colour_buffers_clear_on_write = + !(((pipe_bit & PIPE_CLEAR_COLOR_BUFFERS) && + general_color_clear && + (job->cleared & pipe_bit))); + store.disable_z_buffer_clear_on_write = + !(job->cleared & PIPE_CLEAR_DEPTH); + store.disable_stencil_buffer_clear_on_write = + !(job->cleared & PIPE_CLEAR_STENCIL); + } store.padded_height_of_output_image_in_uif_blocks = surf->padded_height_of_output_image_in_uif_blocks; +#endif /* V3D_VERSION < 40 */ } } @@ -92,6 +184,9 @@ zs_buffer_from_pipe_bits(int pipe_clear_bits) static void flush_last_load(struct vc5_cl *cl) { + if (V3D_VERSION >= 40) + return; + cl_emit(cl, TILE_COORDINATES_IMPLICIT, coords); cl_emit(cl, STORE_TILE_BUFFER_GENERAL, store) { store.buffer_to_store = NONE; @@ -109,25 +204,29 @@ vc5_rcl_emit_loads(struct vc5_job *job, struct vc5_cl *cl) continue; struct pipe_surface *psurf = job->cbufs[i]; - if (!psurf || psurf->texture->nr_samples <= 1) + if (!psurf || (V3D_VERSION < 40 && + psurf->texture->nr_samples <= 1)) { continue; + } - load_raw(cl, psurf, RENDER_TARGET_0 + i); + load_general(cl, psurf, RENDER_TARGET_0 + i); read_but_not_cleared &= ~bit; if (read_but_not_cleared) flush_last_load(cl); } - if (job->zsbuf && job->zsbuf->texture->nr_samples > 1 && - read_but_not_cleared & PIPE_CLEAR_DEPTHSTENCIL) { - load_raw(cl, job->zsbuf, - zs_buffer_from_pipe_bits(read_but_not_cleared)); + if (read_but_not_cleared & PIPE_CLEAR_DEPTHSTENCIL && + (V3D_VERSION >= 40 || + (job->zsbuf && job->zsbuf->texture->nr_samples > 1))) { + load_general(cl, job->zsbuf, + zs_buffer_from_pipe_bits(read_but_not_cleared)); read_but_not_cleared &= ~PIPE_CLEAR_DEPTHSTENCIL; if (read_but_not_cleared) cl_emit(cl, TILE_COORDINATES_IMPLICIT, coords); } +#if V3D_VERSION < 40 /* The initial reload will be queued until we get the * tile coordinates. */ @@ -143,27 +242,47 @@ vc5_rcl_emit_loads(struct vc5_job *job, struct vc5_cl *cl) read_but_not_cleared & PIPE_CLEAR_STENCIL; } } +#else /* V3D_VERSION >= 40 */ + assert(!read_but_not_cleared); + cl_emit(cl, END_OF_LOADS, end); +#endif } static void vc5_rcl_emit_stores(struct vc5_job *job, struct vc5_cl *cl) { - bool needs_color_clear = job->cleared & PIPE_CLEAR_COLOR_BUFFERS; - bool needs_z_clear = job->cleared & PIPE_CLEAR_DEPTH; - bool needs_s_clear = job->cleared & PIPE_CLEAR_STENCIL; - /* Note that only the color RT being stored will be cleared by a - * STORE_GENERAL, or all of them if the buffer is NONE. + MAYBE_UNUSED bool needs_color_clear = job->cleared & PIPE_CLEAR_COLOR_BUFFERS; + MAYBE_UNUSED bool needs_z_clear = job->cleared & PIPE_CLEAR_DEPTH; + MAYBE_UNUSED bool needs_s_clear = job->cleared & PIPE_CLEAR_STENCIL; + + /* For clearing color in a TLB general on V3D 3.3: + * + * - NONE buffer store clears all TLB color buffers. + * - color buffer store clears just the TLB color buffer being stored. + * - Z/S buffers store may not clear the TLB color buffer. + * + * And on V3D 4.1, we only have one flag for "clear the buffer being + * stored" in the general packet, and a separate packet to clear all + * color TLB buffers. + * + * As a result, we only bother flagging TLB color clears in a general + * packet when we don't have to emit a separate packet to clear all + * TLB color buffers. */ - bool msaa_color_clear = (needs_color_clear && - (job->cleared & PIPE_CLEAR_COLOR_BUFFERS) == - (job->resolve & PIPE_CLEAR_COLOR_BUFFERS)); + bool general_color_clear = (needs_color_clear && + (job->cleared & PIPE_CLEAR_COLOR_BUFFERS) == + (job->resolve & PIPE_CLEAR_COLOR_BUFFERS)); uint32_t stores_pending = job->resolve; - /* Use raw stores for any MSAA surfaces. These output UIF tiled - * images where each 4x MSAA pixel is a 2x2 quad, and the format will - * be that of the internal_type/internal_bpp, rather than the format - * from GL's perspective. + /* For V3D 4.1, use general stores for all TLB stores. + * + * For V3D 3.3, we only use general stores to do raw stores for any + * MSAA surfaces. These output UIF tiled images where each 4x MSAA + * pixel is a 2x2 quad, and the format will be that of the + * internal_type/internal_bpp, rather than the format from GL's + * perspective. Non-MSAA surfaces will use + * STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED. */ for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++) { uint32_t bit = PIPE_CLEAR_COLOR0 << i; @@ -171,33 +290,49 @@ vc5_rcl_emit_stores(struct vc5_job *job, struct vc5_cl *cl) continue; struct pipe_surface *psurf = job->cbufs[i]; - if (!psurf || psurf->texture->nr_samples <= 1) + if (!psurf || + (V3D_VERSION < 40 && psurf->texture->nr_samples <= 1)) { continue; + } stores_pending &= ~bit; - store_raw(cl, psurf, RENDER_TARGET_0 + i, - !stores_pending && msaa_color_clear, - !stores_pending && needs_z_clear, - !stores_pending && needs_s_clear); - - if (stores_pending) + store_general(job, cl, psurf, RENDER_TARGET_0 + i, bit, + !stores_pending, general_color_clear); + if (V3D_VERSION < 40 && stores_pending) cl_emit(cl, TILE_COORDINATES_IMPLICIT, coords); } if (job->resolve & PIPE_CLEAR_DEPTHSTENCIL && job->zsbuf && - job->zsbuf->texture->nr_samples > 1) { + !(V3D_VERSION < 40 && job->zsbuf->texture->nr_samples <= 1)) { stores_pending &= ~PIPE_CLEAR_DEPTHSTENCIL; - store_raw(cl, job->zsbuf, - zs_buffer_from_pipe_bits(job->resolve), - false, - !stores_pending && needs_z_clear, - !stores_pending && needs_s_clear); - if (stores_pending) + struct vc5_resource *rsc = vc5_resource(job->zsbuf->texture); + if (rsc->separate_stencil) { + if (job->resolve & PIPE_CLEAR_DEPTH) { + store_general(job, cl, job->zsbuf, Z, + PIPE_CLEAR_DEPTH, + !stores_pending, + general_color_clear); + } + if (job->resolve & PIPE_CLEAR_STENCIL) { + store_general(job, cl, job->zsbuf, STENCIL, + PIPE_CLEAR_STENCIL, + !stores_pending, + general_color_clear); + } + } else { + store_general(job, cl, job->zsbuf, + zs_buffer_from_pipe_bits(job->resolve), + job->resolve & PIPE_CLEAR_DEPTHSTENCIL, + !stores_pending, general_color_clear); + } + + if (V3D_VERSION < 40 && stores_pending) cl_emit(cl, TILE_COORDINATES_IMPLICIT, coords); } if (stores_pending) { +#if V3D_VERSION < 40 cl_emit(cl, STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED, store) { store.disable_color_buffer_write = @@ -216,14 +351,22 @@ vc5_rcl_emit_stores(struct vc5_job *job, struct vc5_cl *cl) store.disable_stencil_buffer_clear_on_write = !needs_s_clear; }; - } else if (needs_color_clear && !msaa_color_clear) { - /* If we had MSAA color stores that didn't match the set of - * MSAA color clears, then we need to clear the color buffers - * now. +#else /* V3D_VERSION >= 40 */ + unreachable("All color buffers should have been stored."); +#endif /* V3D_VERSION >= 40 */ + } else if (needs_color_clear && !general_color_clear) { + /* If we didn't do our color clears in the general packet, + * then emit a packet to clear all the TLB color buffers now. */ +#if V3D_VERSION < 40 cl_emit(cl, STORE_TILE_BUFFER_GENERAL, store) { store.buffer_to_store = NONE; } +#else /* V3D_VERSION >= 40 */ + cl_emit(cl, CLEAR_TILE_BUFFERS, clear) { + clear.clear_all_render_targets = true; + } +#endif /* V3D_VERSION >= 40 */ } } @@ -237,12 +380,21 @@ vc5_rcl_emit_generic_per_tile_list(struct vc5_job *job, int last_cbuf) vc5_cl_ensure_space(cl, 200, 1); struct vc5_cl_reloc tile_list_start = cl_get_address(cl); + if (V3D_VERSION >= 40) { + /* V3D 4.x only requires a single tile coordinates, and + * END_OF_LOADS switches us between loading and rendering. + */ + cl_emit(cl, TILE_COORDINATES_IMPLICIT, coords); + } + vc5_rcl_emit_loads(job, cl); - /* Tile Coordinates triggers the reload and sets where the stores - * go. There must be one per store packet. - */ - cl_emit(cl, TILE_COORDINATES_IMPLICIT, coords); + if (V3D_VERSION < 40) { + /* Tile Coordinates triggers the last reload and sets where + * the stores go. There must be one per store packet. + */ + cl_emit(cl, TILE_COORDINATES_IMPLICIT, coords); + } /* The binner starts out writing tiles assuming that the initial mode * is triangles, so make sure that's the case. @@ -256,6 +408,10 @@ vc5_rcl_emit_generic_per_tile_list(struct vc5_job *job, int last_cbuf) vc5_rcl_emit_stores(job, cl); +#if V3D_VERSION >= 40 + cl_emit(cl, END_OF_TILE_MARKER, end); +#endif + cl_emit(cl, RETURN_FROM_SUB_LIST, ret); cl_emit(&job->rcl, START_ADDRESS_OF_GENERIC_TILE_LIST, branch) { @@ -264,10 +420,25 @@ vc5_rcl_emit_generic_per_tile_list(struct vc5_job *job, int last_cbuf) } } +#if V3D_VERSION >= 40 +static void +v3d_setup_render_target(struct vc5_job *job, int cbuf, + uint32_t *rt_bpp, uint32_t *rt_type, uint32_t *rt_clamp) +{ + if (!job->cbufs[cbuf]) + return; + + struct vc5_surface *surf = vc5_surface(job->cbufs[cbuf]); + *rt_bpp = surf->internal_bpp; + *rt_type = surf->internal_type; + *rt_clamp = V3D_RENDER_TARGET_CLAMP_NONE; +} +#endif /* V3D_VERSION >= 40 */ + #define div_round_up(a, b) (((a) + (b) - 1) / b) void -vc5_emit_rcl(struct vc5_job *job) +v3dX(emit_rcl)(struct vc5_job *job) { /* The RCL list should be empty. */ assert(!job->rcl.bo); @@ -289,8 +460,17 @@ vc5_emit_rcl(struct vc5_job *job) */ cl_emit(&job->rcl, TILE_RENDERING_MODE_CONFIGURATION_COMMON_CONFIGURATION, config) { +#if V3D_VERSION < 40 config.enable_z_store = job->resolve & PIPE_CLEAR_DEPTH; config.enable_stencil_store = job->resolve & PIPE_CLEAR_STENCIL; +#else /* V3D_VERSION >= 40 */ + if (job->zsbuf) { + struct vc5_surface *surf = vc5_surface(job->zsbuf); + config.internal_depth_type = surf->internal_type; + } +#endif /* V3D_VERSION >= 40 */ + + /* XXX: Early D/S clear */ config.early_z_disable = !job->uses_early_z; @@ -312,7 +492,7 @@ vc5_emit_rcl(struct vc5_job *job) struct vc5_surface *surf = vc5_surface(psurf); struct vc5_resource *rsc = vc5_resource(psurf->texture); - uint32_t config_pad = 0; + MAYBE_UNUSED uint32_t config_pad = 0; uint32_t clear_pad = 0; /* XXX: Set the pad for raster. */ @@ -331,6 +511,7 @@ vc5_emit_rcl(struct vc5_job *job) } } +#if V3D_VERSION < 40 cl_emit(&job->rcl, TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG, rt) { rt.address = cl_address(rsc->bo, surf->offset); rt.internal_type = surf->internal_type; @@ -343,6 +524,7 @@ vc5_emit_rcl(struct vc5_job *job) if (job->resolve & PIPE_CLEAR_COLOR0 << i) rsc->writes++; } +#endif /* V3D_VERSION < 40 */ cl_emit(&job->rcl, TILE_RENDERING_MODE_CONFIGURATION_CLEAR_COLORS_PART1, clear) { @@ -374,6 +556,28 @@ vc5_emit_rcl(struct vc5_job *job) } } +#if V3D_VERSION >= 40 + cl_emit(&job->rcl, TILE_RENDERING_MODE_CONFIGURATION_RENDER_TARGET_CONFIG, rt) { + v3d_setup_render_target(job, 0, + &rt.render_target_0_internal_bpp, + &rt.render_target_0_internal_type, + &rt.render_target_0_clamp); + v3d_setup_render_target(job, 1, + &rt.render_target_1_internal_bpp, + &rt.render_target_1_internal_type, + &rt.render_target_1_clamp); + v3d_setup_render_target(job, 2, + &rt.render_target_2_internal_bpp, + &rt.render_target_2_internal_type, + &rt.render_target_2_clamp); + v3d_setup_render_target(job, 3, + &rt.render_target_3_internal_bpp, + &rt.render_target_3_internal_type, + &rt.render_target_3_clamp); + } +#endif + +#if V3D_VERSION < 40 /* TODO: Don't bother emitting if we don't load/clear Z/S. */ if (job->zsbuf) { struct pipe_surface *psurf = job->zsbuf; @@ -417,6 +621,7 @@ vc5_emit_rcl(struct vc5_job *job) } } } +#endif /* V3D_VERSION < 40 */ /* Ends rendering mode config. */ cl_emit(&job->rcl, TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CLEAR_VALUES, @@ -480,9 +685,21 @@ vc5_emit_rcl(struct vc5_job *job) coords.tile_row_number = 0; } +#if V3D_VERSION < 40 cl_emit(&job->rcl, STORE_TILE_BUFFER_GENERAL, store) { store.buffer_to_store = NONE; } +#else + cl_emit(&job->rcl, END_OF_LOADS, end); + cl_emit(&job->rcl, STORE_TILE_BUFFER_GENERAL, store) { + store.buffer_to_store = NONE; + } + cl_emit(&job->rcl, CLEAR_TILE_BUFFERS, clear) { + clear.clear_z_stencil_buffer = true; + clear.clear_all_render_targets = true; + } + cl_emit(&job->rcl, END_OF_TILE_MARKER, end); +#endif cl_emit(&job->rcl, FLUSH_VCD_CACHE, flush);