From ec6d56d4ce4d4ce9de3e1e3d30b84eb648061616 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Thu, 3 Aug 2023 15:47:20 -0500 Subject: [PATCH] nil: Add a nil_view and code to fill out TIC entries Part-of: --- src/nouveau/nil/meson.build | 1 + src/nouveau/nil/nil_image.h | 48 ++++++++++++ src/nouveau/nil/nil_image_tic.c | 164 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+) create mode 100644 src/nouveau/nil/nil_image_tic.c diff --git a/src/nouveau/nil/meson.build b/src/nouveau/nil/meson.build index 04eb7af..2426e23 100644 --- a/src/nouveau/nil/meson.build +++ b/src/nouveau/nil/meson.build @@ -23,6 +23,7 @@ libnil_files = files( 'nil_format.h', 'nil_image.c', 'nil_image.h', + 'nil_image_tic.c', ) _libnil = static_library( diff --git a/src/nouveau/nil/nil_image.h b/src/nouveau/nil/nil_image.h index e1d79df..86ba16d 100644 --- a/src/nouveau/nil/nil_image.h +++ b/src/nouveau/nil/nil_image.h @@ -26,6 +26,16 @@ enum nil_image_usage_flags { NIL_IMAGE_USAGE_2D_VIEW_BIT = BITFIELD_BIT(6), }; +enum PACKED nil_view_type { + NIL_VIEW_TYPE_1D, + NIL_VIEW_TYPE_2D, + NIL_VIEW_TYPE_3D, + NIL_VIEW_TYPE_CUBE, + NIL_VIEW_TYPE_1D_ARRAY, + NIL_VIEW_TYPE_2D_ARRAY, + NIL_VIEW_TYPE_CUBE_ARRAY, +}; + struct nil_extent4d { union { uint32_t w, width; }; union { uint32_t h, height; }; @@ -95,6 +105,38 @@ struct nil_image { uint64_t size_B; }; +struct nil_view { + enum nil_view_type type; + + /** + * The format to use in the view + * + * This may differ from the format of the actual isl_surf but must have + * the same block size. + */ + enum pipe_format format; + + uint32_t base_level; + uint32_t num_levels; + + /** + * Base array layer + * + * For cube maps, both base_array_layer and array_len should be + * specified in terms of 2-D layers and must be a multiple of 6. + */ + uint32_t base_array_layer; + + /** + * Array Length + * + * Indicates the number of array elements starting at Base Array Layer. + */ + uint32_t array_len; + + enum pipe_swizzle swizzle[4]; +}; + bool nil_image_init(struct nouveau_ws_device *dev, struct nil_image *image, const struct nil_image_init_info *restrict info); @@ -109,4 +151,10 @@ nil_image_level_layer_offset_B(const struct nil_image *image, } +void nil_image_fill_tic(struct nouveau_ws_device *dev, + const struct nil_image *image, + const struct nil_view *view, + uint64_t base_address, + void *desc_out); + #endif /* NIL_H */ diff --git a/src/nouveau/nil/nil_image_tic.c b/src/nouveau/nil/nil_image_tic.c new file mode 100644 index 0000000..973a02a --- /dev/null +++ b/src/nouveau/nil/nil_image_tic.c @@ -0,0 +1,164 @@ +#include "nil_image.h" + +#include "nil_format.h" +#include "util/u_math.h" + +#include "gallium/drivers/nouveau/nv50/g80_defs.xml.h" +#include "gallium/drivers/nouveau/nv50/g80_texture.xml.h" +#include "gallium/drivers/nouveau/nvc0/gm107_texture.xml.h" + +static inline uint32_t +tic_source(const struct nil_tic_format *fmt, + enum pipe_swizzle swz, bool is_int) +{ + switch (swz) { + case PIPE_SWIZZLE_X: return fmt->src_x; + case PIPE_SWIZZLE_Y: return fmt->src_y; + case PIPE_SWIZZLE_Z: return fmt->src_z; + case PIPE_SWIZZLE_W: return fmt->src_w; + case PIPE_SWIZZLE_0: + return G80_TIC_SOURCE_ZERO; + case PIPE_SWIZZLE_1: + return is_int ? G80_TIC_SOURCE_ONE_INT : G80_TIC_SOURCE_ONE_FLOAT; + default: + unreachable("Invalid component swizzle"); + } +} + +static uint32_t +gm107_tic2_0_format(enum pipe_format format, + const enum pipe_swizzle swizzle[4]) +{ + const struct nil_tic_format *fmt = nil_tic_format_for_pipe(format); + const bool is_int = util_format_is_pure_integer(format); + + uint32_t source[4]; + for (unsigned i = 0; i < 4; i++) + source[i] = tic_source(fmt, swizzle[i], is_int); + + uint32_t tic; + tic = fmt->comp_sizes << GM107_TIC2_0_COMPONENTS_SIZES__SHIFT; + tic |= fmt->type_r << GM107_TIC2_0_R_DATA_TYPE__SHIFT; + tic |= fmt->type_g << GM107_TIC2_0_G_DATA_TYPE__SHIFT; + tic |= fmt->type_b << GM107_TIC2_0_B_DATA_TYPE__SHIFT; + tic |= fmt->type_a << GM107_TIC2_0_A_DATA_TYPE__SHIFT; + tic |= source[0] << GM107_TIC2_0_X_SOURCE__SHIFT; + tic |= source[1] << GM107_TIC2_0_Y_SOURCE__SHIFT; + tic |= source[2] << GM107_TIC2_0_Z_SOURCE__SHIFT; + tic |= source[3] << GM107_TIC2_0_W_SOURCE__SHIFT; + + return tic; +} + +static uint32_t +gm107_tic2_4_view_type(enum nil_view_type type) +{ + switch (type) { + case NIL_VIEW_TYPE_1D: + return GM107_TIC2_4_TEXTURE_TYPE_ONE_D; + case NIL_VIEW_TYPE_2D: + return GM107_TIC2_4_TEXTURE_TYPE_TWO_D; + case NIL_VIEW_TYPE_3D: + return GM107_TIC2_4_TEXTURE_TYPE_THREE_D; + case NIL_VIEW_TYPE_CUBE: + return GM107_TIC2_4_TEXTURE_TYPE_CUBEMAP; + case NIL_VIEW_TYPE_1D_ARRAY: + return GM107_TIC2_4_TEXTURE_TYPE_ONE_D_ARRAY; + case NIL_VIEW_TYPE_2D_ARRAY: + return GM107_TIC2_4_TEXTURE_TYPE_TWO_D_ARRAY; + case NIL_VIEW_TYPE_CUBE_ARRAY: + return GM107_TIC2_4_TEXTURE_TYPE_CUBE_ARRAY; + default: + unreachable("Invalid image view type"); + } +} + +static uint32_t +gm107_tic7_4_multi_sample_count(uint32_t samples) +{ + switch (samples) { + case 1: return GM107_TIC2_7_MULTI_SAMPLE_COUNT_1X1; + case 2: return GM107_TIC2_7_MULTI_SAMPLE_COUNT_2X1; + case 4: return GM107_TIC2_7_MULTI_SAMPLE_COUNT_2X2; + case 8: return GM107_TIC2_7_MULTI_SAMPLE_COUNT_4X2; + case 16: return GM107_TIC2_7_MULTI_SAMPLE_COUNT_4X4; + default: + unreachable("Unsupported sample count"); + } +} + +void +nil_image_fill_tic(struct nouveau_ws_device *dev, + const struct nil_image *image, + const struct nil_view *view, + uint64_t base_address, + void *desc_out) +{ + assert(util_format_get_blocksize(image->format) == + util_format_get_blocksize(view->format)); + assert(view->base_level + view->num_levels <= image->num_levels); + assert(view->base_array_layer + view->array_len <= image->extent_px.a); + + uint32_t tic[8] = { }; + + tic[0] = gm107_tic2_0_format(view->format, view->swizzle); + + tic[3] |= GM107_TIC2_3_LOD_ANISO_QUALITY_2; + tic[4] |= GM107_TIC2_4_SECTOR_PROMOTION_PROMOTE_TO_2_V; + tic[4] |= GM107_TIC2_4_BORDER_SIZE_SAMPLER_COLOR; + + if (util_format_is_srgb(view->format)) + tic[4] |= GM107_TIC2_4_SRGB_CONVERSION; + + /* TODO: Unnormalized? */ + tic[5] |= GM107_TIC2_5_NORMALIZED_COORDS; + + tic[2] |= GM107_TIC2_2_HEADER_VERSION_BLOCKLINEAR; + assert(image->levels[0].tiling.gob_height_8); + tic[3] |= (uint32_t)image->levels[0].tiling.y_log2 << + GM107_TIC2_3_GOBS_PER_BLOCK_HEIGHT__SHIFT; + tic[3] |= (uint32_t)image->levels[0].tiling.z_log2 << + GM107_TIC2_3_GOBS_PER_BLOCK_DEPTH__SHIFT; + + /* There doesn't seem to be a base layer field in TIC */ + const uint64_t layer_address = + base_address + view->base_array_layer * image->array_stride_B; + tic[1] = layer_address; + tic[2] |= layer_address >> 32; + + tic[4] |= gm107_tic2_4_view_type(view->type); + + /* TODO: NV50_TEXVIEW_FILTER_MSAA8 */ + tic[3] |= GM107_TIC2_3_LOD_ANISO_QUALITY_HIGH | + GM107_TIC2_3_LOD_ISO_QUALITY_HIGH; + + const uint32_t width = u_minify(image->extent_px.width, view->base_level); + const uint32_t height = u_minify(image->extent_px.height, view->base_level); + uint32_t depth; + if (view->type == NIL_VIEW_TYPE_3D) { + assert(image->dim == NIL_IMAGE_DIM_3D); + depth = u_minify(image->extent_px.depth, view->base_level); + } else if (view->type == NIL_VIEW_TYPE_CUBE || + view->type == NIL_VIEW_TYPE_CUBE_ARRAY) { + assert(image->dim == NIL_IMAGE_DIM_2D); + assert(view->array_len % 6 == 0); + depth = view->array_len / 6; + } else { + depth = view->array_len; + } + + tic[4] |= width - 1; + tic[5] |= height - 1; + tic[5] |= (depth - 1) << 16; + + tic[3] |= image->mip_tail_start << GM107_TIC2_3_MAX_MIP_LEVEL__SHIFT; + + tic[6] |= GM107_TIC2_6_ANISO_FINE_SPREAD_FUNC_TWO; + tic[6] |= GM107_TIC2_6_ANISO_COARSE_SPREAD_FUNC_ONE; + + const uint32_t last_level = view->num_levels + view->base_level - 1; + tic[7] |= (last_level << 4) | view->base_level; + tic[7] |= gm107_tic7_4_multi_sample_count(image->num_samples); + + memcpy(desc_out, tic, sizeof(tic)); +} -- 2.7.4