From 27d6f994baa190a2cd2da2fffa06a9a8befaece9 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Sat, 10 Sep 2022 18:00:01 +0200 Subject: [PATCH] nvk: support pre Maxwell Texture Headers GM10x seems to disable it by default, so enable them there. Signed-off-by: Karol Herbst Part-of: --- src/nouveau/nil/nil_image_tic.c | 504 ++++++++++++++++++------- src/nouveau/nvidia-headers/meson.build | 1 + src/nouveau/nvidia-headers/nv_push.h | 1 + src/nouveau/vulkan/nvk_cmd_draw.c | 7 + 4 files changed, 380 insertions(+), 133 deletions(-) diff --git a/src/nouveau/nil/nil_image_tic.c b/src/nouveau/nil/nil_image_tic.c index 517fa1e2ccb..b7c296b9747 100644 --- a/src/nouveau/nil/nil_image_tic.c +++ b/src/nouveau/nil/nil_image_tic.c @@ -3,6 +3,11 @@ #include "nil_format.h" #include "util/bitpack_helpers.h" +#include "nouveau_device.h" + +#include "cl9097.h" +#include "cl9097tex.h" +#include "clb097.h" #include "clb097tex.h" #include "drf.h" @@ -30,19 +35,56 @@ __set_bool(uint32_t *o, bool b, unsigned lo, unsigned hi) #define MW(x) x #define TH_SET_U(o, NV, VER, FIELD, val) \ - __set_u32((o), (val), DRF_LO(NV##_TEXHEAD_##VER##_##FIELD),\ - DRF_HI(NV##_TEXHEAD_##VER##_##FIELD)) + __set_u32((o), (val), DRF_LO(NV##_TEXHEAD##VER##_##FIELD),\ + DRF_HI(NV##_TEXHEAD##VER##_##FIELD)) #define TH_SET_I(o, NV, VER, FIELD, val) \ - __set_i32((o), (val), DRF_LO(NV##_TEXHEAD_##VER##_##FIELD),\ - DRF_HI(NV##_TEXHEAD_##VER##_##FIELD)) + __set_i32((o), (val), DRF_LO(NV##_TEXHEAD##VER##_##FIELD),\ + DRF_HI(NV##_TEXHEAD##VER##_##FIELD)) #define TH_SET_B(o, NV, VER, FIELD, b) \ - __set_bool((o), (b), DRF_LO(NV##_TEXHEAD_##VER##_##FIELD),\ - DRF_HI(NV##_TEXHEAD_##VER##_##FIELD)) + __set_bool((o), (b), DRF_LO(NV##_TEXHEAD##VER##_##FIELD),\ + DRF_HI(NV##_TEXHEAD##VER##_##FIELD)) #define TH_SET_E(o, NV, VER, FIELD, E) \ - TH_SET_U((o), NV, VER, FIELD, NV##_TEXHEAD_##VER##_##FIELD##_##E) + TH_SET_U((o), NV, VER, FIELD, NV##_TEXHEAD##VER##_##FIELD##_##E) + +#define TH_NV9097_SET_U(o, IDX, FIELD, val) \ + TH_SET_U(&(o)[IDX], NV9097, V2_##IDX, FIELD, (val)); +#define TH_NV9097_SET_I(o, IDX, FIELD, val) \ + TH_SET_I(&(o)[IDX], NV9097, V2_##IDX, FIELD, (val)); +#define TH_NV9097_SET_B(o, IDX, FIELD, b) \ + TH_SET_B(&(o)[IDX], NV9097, V2_##IDX, FIELD, (b)); +#define TH_NV9097_SET_E(o, IDX, FIELD, E) \ + TH_SET_E(&(o)[IDX], NV9097, V2_##IDX, FIELD, E); + +#define TH_NVB097_SET_U(o, VER, FIELD, val) \ + TH_SET_U((o), NVB097, _##VER, FIELD, (val)); +#define TH_NVB097_SET_I(o, VER, FIELD, val) \ + TH_SET_I((o), NVB097, _##VER, FIELD, (val)); +#define TH_NVB097_SET_B(o, VER, FIELD, b) \ + TH_SET_B((o), NVB097, _##VER, FIELD, (b)); +#define TH_NVB097_SET_E(o, VER, FIELD, E) \ + TH_SET_E((o), NVB097, _##VER, FIELD, E); + +static inline uint32_t +nv9097_th_bl_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 NV9097_TEXHEADV2_0_X_SOURCE_IN_ZERO; + case PIPE_SWIZZLE_1: + return is_int ? NV9097_TEXHEADV2_0_X_SOURCE_IN_ONE_INT : + NV9097_TEXHEADV2_0_X_SOURCE_IN_ONE_FLOAT; + default: + unreachable("Invalid component swizzle"); + } +} static inline uint32_t nvb097_th_bl_source(const struct nil_tic_format *fmt, @@ -63,6 +105,30 @@ nvb097_th_bl_source(const struct nil_tic_format *fmt, } } +static uint32_t +nv9097_th_bl_0(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] = nvb097_th_bl_source(fmt, swizzle[i], is_int); + + uint32_t th_0 = 0; + TH_NV9097_SET_U(&th_0, 0, COMPONENT_SIZES, fmt->comp_sizes); + TH_NV9097_SET_U(&th_0, 0, R_DATA_TYPE, fmt->type_r); + TH_NV9097_SET_U(&th_0, 0, G_DATA_TYPE, fmt->type_g); + TH_NV9097_SET_U(&th_0, 0, B_DATA_TYPE, fmt->type_b); + TH_NV9097_SET_U(&th_0, 0, A_DATA_TYPE, fmt->type_a); + TH_NV9097_SET_U(&th_0, 0, X_SOURCE, source[0]); + TH_NV9097_SET_U(&th_0, 0, Y_SOURCE, source[1]); + TH_NV9097_SET_U(&th_0, 0, Z_SOURCE, source[2]); + TH_NV9097_SET_U(&th_0, 0, W_SOURCE, source[3]); + + return th_0; +} + static uint32_t nvb097_th_bl_0(enum pipe_format format, const enum pipe_swizzle swizzle[4]) { @@ -74,24 +140,25 @@ nvb097_th_bl_0(enum pipe_format format, const enum pipe_swizzle swizzle[4]) source[i] = nvb097_th_bl_source(fmt, swizzle[i], is_int); uint32_t th_0 = 0; - TH_SET_U(&th_0, NVB097, BL, COMPONENTS, fmt->comp_sizes); - TH_SET_U(&th_0, NVB097, BL, R_DATA_TYPE, fmt->type_r); - TH_SET_U(&th_0, NVB097, BL, G_DATA_TYPE, fmt->type_g); - TH_SET_U(&th_0, NVB097, BL, B_DATA_TYPE, fmt->type_b); - TH_SET_U(&th_0, NVB097, BL, A_DATA_TYPE, fmt->type_a); - TH_SET_U(&th_0, NVB097, BL, X_SOURCE, source[0]); - TH_SET_U(&th_0, NVB097, BL, Y_SOURCE, source[1]); - TH_SET_U(&th_0, NVB097, BL, Z_SOURCE, source[2]); - TH_SET_U(&th_0, NVB097, BL, W_SOURCE, source[3]); + TH_NVB097_SET_U(&th_0, BL, COMPONENTS, fmt->comp_sizes); + TH_NVB097_SET_U(&th_0, BL, R_DATA_TYPE, fmt->type_r); + TH_NVB097_SET_U(&th_0, BL, G_DATA_TYPE, fmt->type_g); + TH_NVB097_SET_U(&th_0, BL, B_DATA_TYPE, fmt->type_b); + TH_NVB097_SET_U(&th_0, BL, A_DATA_TYPE, fmt->type_a); + TH_NVB097_SET_U(&th_0, BL, X_SOURCE, source[0]); + TH_NVB097_SET_U(&th_0, BL, Y_SOURCE, source[1]); + TH_NVB097_SET_U(&th_0, BL, Z_SOURCE, source[2]); + TH_NVB097_SET_U(&th_0, BL, W_SOURCE, source[3]); return th_0; } static uint32_t -nil_to_nvb097_texture_type(enum nil_view_type type) +pipe_to_nv_texture_type(enum nil_view_type type) { #define CASE(NIL, NV) \ - case NIL_VIEW_TYPE_##NIL: return NVB097_TEXHEAD_BL_TEXTURE_TYPE_##NV; + case NIL_VIEW_TYPE_##NIL: return NVB097_TEXHEAD_BL_TEXTURE_TYPE_##NV; \ + STATIC_ASSERT(NVB097_TEXHEAD_BL_TEXTURE_TYPE_##NV == NV9097_TEXHEADV2_2_TEXTURE_TYPE_##NV); switch (type) { CASE(1D, ONE_D); @@ -108,7 +175,27 @@ nil_to_nvb097_texture_type(enum nil_view_type type) } static uint32_t -nil_to_nvb097_multi_sample_count_mode(enum nil_sample_layout sample_layout) +nil_to_nv9097_multi_sample_count(enum nil_sample_layout sample_layout) +{ +#define CASE(SIZE) \ + case NIL_SAMPLE_LAYOUT_##SIZE: \ + return NV9097_TEXHEADV2_7_MULTI_SAMPLE_COUNT_MODE_##SIZE + + switch (sample_layout) { + CASE(1X1); + CASE(2X1); + CASE(2X2); + CASE(4X2); + CASE(4X4); + default: + unreachable("Invalid sample layout"); + } + +#undef CASE +} + +static uint32_t +nil_to_nvb097_multi_sample_count(enum nil_sample_layout sample_layout) { #define CASE(SIZE) \ case NIL_SAMPLE_LAYOUT_##SIZE: \ @@ -127,72 +214,10 @@ nil_to_nvb097_multi_sample_count_mode(enum nil_sample_layout sample_layout) #undef CASE } -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) +static inline uint32_t +nil_max_mip_level(const struct nil_image *image, + const struct nil_view *view) { - 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 th[8] = { }; - - th[0] = nvb097_th_bl_0(view->format, view->swizzle); - - /* There's no base layer field in the texture header */ - const uint64_t layer_address = - base_address + view->base_array_layer * image->array_stride_B; - assert((layer_address & BITFIELD_MASK(9)) == 0); - TH_SET_U(th, NVB097, BL, ADDRESS_BITS31TO9, (uint32_t)layer_address >> 9); - TH_SET_U(th, NVB097, BL, ADDRESS_BITS47TO32, layer_address >> 32); - - TH_SET_E(th, NVB097, BL, HEADER_VERSION, SELECT_BLOCKLINEAR); - - const struct nil_tiling *tiling = &image->levels[0].tiling; - assert(tiling->is_tiled); - assert(tiling->gob_height_8); - TH_SET_E(th, NVB097, BL, GOBS_PER_BLOCK_WIDTH, ONE_GOB); - TH_SET_U(th, NVB097, BL, GOBS_PER_BLOCK_HEIGHT, tiling->y_log2); - TH_SET_U(th, NVB097, BL, GOBS_PER_BLOCK_DEPTH, tiling->z_log2); - - TH_SET_B(th, NVB097, BL, LOD_ANISO_QUALITY2, true); - TH_SET_E(th, NVB097, BL, LOD_ANISO_QUALITY, LOD_QUALITY_HIGH); - TH_SET_E(th, NVB097, BL, LOD_ISO_QUALITY, LOD_QUALITY_HIGH); - TH_SET_E(th, NVB097, BL, ANISO_COARSE_SPREAD_MODIFIER, SPREAD_MODIFIER_NONE); - - const uint32_t width = image->extent_px.width; - const uint32_t height = image->extent_px.height; - uint32_t depth; - switch (view->type) { - case NIL_VIEW_TYPE_1D: - case NIL_VIEW_TYPE_1D_ARRAY: - case NIL_VIEW_TYPE_2D: - case NIL_VIEW_TYPE_2D_ARRAY: - assert(image->extent_px.depth == 1); - depth = view->array_len; - break; - case NIL_VIEW_TYPE_CUBE: - case NIL_VIEW_TYPE_CUBE_ARRAY: - assert(image->dim == NIL_IMAGE_DIM_2D); - assert(view->array_len % 6 == 0); - depth = view->array_len / 6; - break; - case NIL_VIEW_TYPE_3D: - assert(image->dim == NIL_IMAGE_DIM_3D); - depth = image->extent_px.depth; - break; - default: - unreachable("Unsupported image view target"); - }; - - TH_SET_U(th, NVB097, BL, WIDTH_MINUS_ONE, width - 1); - TH_SET_U(th, NVB097, BL, HEIGHT_MINUS_ONE, height - 1); - TH_SET_U(th, NVB097, BL, DEPTH_MINUS_ONE, depth - 1); - if (view->type != NIL_VIEW_TYPE_3D && view->array_len == 1 && view->base_level == 0 && view->num_levels == 1) { /* The Unnormalized coordinates bit in the sampler gets ignored if the @@ -214,43 +239,275 @@ nil_image_fill_tic(struct nouveau_ws_device *dev, * it's safe to set the number of miplevels to 0 regardless of how many * the image actually has. */ - TH_SET_U(th, NVB097, BL, MAX_MIP_LEVEL, 0); + return 0; } else { - TH_SET_U(th, NVB097, BL, MAX_MIP_LEVEL, image->num_levels - 1); + return image->num_levels - 1; } +} - TH_SET_U(th, NVB097, BL, TEXTURE_TYPE, - nil_to_nvb097_texture_type(view->type)); +static struct nil_extent4d +nil_normalize_extent(const struct nil_image *image, + const struct nil_view *view) +{ + struct nil_extent4d extent; - TH_SET_B(th, NVB097, BL, S_R_G_B_CONVERSION, - util_format_is_srgb(view->format)); + extent.width = image->extent_px.width; + extent.height = image->extent_px.height; + extent.array_len = 0; - TH_SET_E(th, NVB097, BL, SECTOR_PROMOTION, PROMOTE_TO_2_V); - TH_SET_E(th, NVB097, BL, BORDER_SIZE, BORDER_SAMPLER_COLOR); + switch (view->type) { + case NIL_VIEW_TYPE_1D: + case NIL_VIEW_TYPE_1D_ARRAY: + case NIL_VIEW_TYPE_2D: + case NIL_VIEW_TYPE_2D_ARRAY: + assert(image->extent_px.depth == 1); + extent.depth = view->array_len; + break; + case NIL_VIEW_TYPE_CUBE: + case NIL_VIEW_TYPE_CUBE_ARRAY: + assert(image->dim == NIL_IMAGE_DIM_2D); + assert(view->array_len % 6 == 0); + extent.depth = view->array_len / 6; + break; + case NIL_VIEW_TYPE_3D: + assert(image->dim == NIL_IMAGE_DIM_3D); + extent.depth = image->extent_px.depth; + break; + default: + unreachable("Unsupported image view target"); + }; + + return extent; +} + +static void +nv9097_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 th[8] = { }; + + TH_NV9097_SET_B(th, 4, USE_TEXTURE_HEADER_VERSION2, true); + + th[0] = nv9097_th_bl_0(view->format, view->swizzle); + + /* There's no base layer field in the texture header */ + const uint64_t layer_address = + base_address + view->base_array_layer * image->array_stride_B; + assert((layer_address & BITFIELD_MASK(9)) == 0); + TH_NV9097_SET_U(th, 1, OFFSET_LOWER, layer_address & 0xffffffff); + TH_NV9097_SET_U(th, 2, OFFSET_UPPER, layer_address >> 32); + + TH_NV9097_SET_E(th, 2, MEMORY_LAYOUT, BLOCKLINEAR); + + const struct nil_tiling *tiling = &image->levels[0].tiling; + assert(tiling->is_tiled); + assert(tiling->gob_height_8); + + TH_NV9097_SET_E(th, 2, GOBS_PER_BLOCK_WIDTH, ONE_GOB); + TH_NV9097_SET_U(th, 2, GOBS_PER_BLOCK_HEIGHT, tiling->y_log2); + TH_NV9097_SET_U(th, 2, GOBS_PER_BLOCK_DEPTH, tiling->z_log2); + + TH_NV9097_SET_E(th, 3, LOD_ANISO_QUALITY, LOD_QUALITY_HIGH); + TH_NV9097_SET_E(th, 3, LOD_ISO_QUALITY, LOD_QUALITY_HIGH); + TH_NV9097_SET_E(th, 3, ANISO_COARSE_SPREAD_MODIFIER, SPREAD_MODIFIER_NONE); + + const struct nil_extent4d extent = nil_normalize_extent(image, view); + TH_NV9097_SET_U(th, 4, WIDTH, extent.width); + TH_NV9097_SET_U(th, 5, HEIGHT, extent.height); + TH_NV9097_SET_U(th, 5, DEPTH, extent.depth); + + TH_NV9097_SET_U(th, 5, MAX_MIP_LEVEL, nil_max_mip_level(image, view)); + + TH_NV9097_SET_U(th, 2, TEXTURE_TYPE, pipe_to_nv_texture_type(view->type)); + + TH_NV9097_SET_B(th, 2, S_R_G_B_CONVERSION, + util_format_is_srgb(view->format)); + + TH_NV9097_SET_E(th, 2, BORDER_SOURCE, BORDER_COLOR); /* In the sampler, the two options for FLOAT_COORD_NORMALIZATION are: - * - * - FORCE_UNNORMALIZED_COORDS - * - USE_HEADER_SETTING - * - * So we set it to normalized in the header and let the sampler select - * that or force non-normalized. - */ - TH_SET_B(th, NVB097, BL, NORMALIZED_COORDS, true); + * + * - FORCE_UNNORMALIZED_COORDS + * - USE_HEADER_SETTING + * + * So we set it to normalized in the header and let the sampler select + * that or force non-normalized. + */ + TH_NV9097_SET_B(th, 2, NORMALIZED_COORDS, true); - TH_SET_E(th, NVB097, BL, ANISO_FINE_SPREAD_FUNC, SPREAD_FUNC_TWO); - TH_SET_E(th, NVB097, BL, ANISO_COARSE_SPREAD_FUNC, SPREAD_FUNC_ONE); + TH_NV9097_SET_E(th, 6, ANISO_FINE_SPREAD_FUNC, SPREAD_FUNC_TWO); + TH_NV9097_SET_E(th, 6, ANISO_COARSE_SPREAD_FUNC, SPREAD_FUNC_ONE); - TH_SET_U(th, NVB097, BL, RES_VIEW_MIN_MIP_LEVEL, view->base_level); - TH_SET_U(th, NVB097, BL, RES_VIEW_MAX_MIP_LEVEL, - view->num_levels + view->base_level - 1); + TH_NV9097_SET_U(th, 7, RES_VIEW_MIN_MIP_LEVEL, view->base_level); + TH_NV9097_SET_U(th, 7, RES_VIEW_MAX_MIP_LEVEL, + view->num_levels + view->base_level - 1); - TH_SET_U(th, NVB097, BL, MULTI_SAMPLE_COUNT, - nil_to_nvb097_multi_sample_count_mode(image->sample_layout)); + TH_NV9097_SET_U(th, 7, MULTI_SAMPLE_COUNT, + nil_to_nv9097_multi_sample_count(image->sample_layout)); memcpy(desc_out, th, sizeof(th)); } +static void +nvb097_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 th[8] = { }; + + th[0] = nvb097_th_bl_0(view->format, view->swizzle); + + /* There's no base layer field in the texture header */ + const uint64_t layer_address = + base_address + view->base_array_layer * image->array_stride_B; + assert((layer_address & BITFIELD_MASK(9)) == 0); + TH_NVB097_SET_U(th, BL, ADDRESS_BITS31TO9, (uint32_t)layer_address >> 9); + TH_NVB097_SET_U(th, BL, ADDRESS_BITS47TO32, layer_address >> 32); + + TH_NVB097_SET_E(th, BL, HEADER_VERSION, SELECT_BLOCKLINEAR); + + const struct nil_tiling *tiling = &image->levels[0].tiling; + assert(tiling->is_tiled); + assert(tiling->gob_height_8); + TH_NVB097_SET_E(th, BL, GOBS_PER_BLOCK_WIDTH, ONE_GOB); + TH_NVB097_SET_U(th, BL, GOBS_PER_BLOCK_HEIGHT, tiling->y_log2); + TH_NVB097_SET_U(th, BL, GOBS_PER_BLOCK_DEPTH, tiling->z_log2); + + TH_NVB097_SET_B(th, BL, LOD_ANISO_QUALITY2, true); + TH_NVB097_SET_E(th, BL, LOD_ANISO_QUALITY, LOD_QUALITY_HIGH); + TH_NVB097_SET_E(th, BL, LOD_ISO_QUALITY, LOD_QUALITY_HIGH); + TH_NVB097_SET_E(th, BL, ANISO_COARSE_SPREAD_MODIFIER, SPREAD_MODIFIER_NONE); + + const struct nil_extent4d extent = nil_normalize_extent(image, view); + TH_NVB097_SET_U(th, BL, WIDTH_MINUS_ONE, extent.width - 1); + TH_NVB097_SET_U(th, BL, HEIGHT_MINUS_ONE, extent.height - 1); + TH_NVB097_SET_U(th, BL, DEPTH_MINUS_ONE, extent.depth - 1); + + TH_NVB097_SET_U(th, BL, MAX_MIP_LEVEL, nil_max_mip_level(image, view)); + + TH_NVB097_SET_U(th, BL, TEXTURE_TYPE, pipe_to_nv_texture_type(view->type)); + + TH_NVB097_SET_B(th, BL, S_R_G_B_CONVERSION, + util_format_is_srgb(view->format)); + + TH_NVB097_SET_E(th, BL, SECTOR_PROMOTION, PROMOTE_TO_2_V); + TH_NVB097_SET_E(th, BL, BORDER_SIZE, BORDER_SAMPLER_COLOR); + + /* In the sampler, the two options for FLOAT_COORD_NORMALIZATION are: + * + * - FORCE_UNNORMALIZED_COORDS + * - USE_HEADER_SETTING + * + * So we set it to normalized in the header and let the sampler select + * that or force non-normalized. + */ + TH_NVB097_SET_B(th, BL, NORMALIZED_COORDS, true); + + TH_NVB097_SET_E(th, BL, ANISO_FINE_SPREAD_FUNC, SPREAD_FUNC_TWO); + TH_NVB097_SET_E(th, BL, ANISO_COARSE_SPREAD_FUNC, SPREAD_FUNC_ONE); + + TH_NVB097_SET_U(th, BL, RES_VIEW_MIN_MIP_LEVEL, view->base_level); + TH_NVB097_SET_U(th, BL, RES_VIEW_MAX_MIP_LEVEL, + view->num_levels + view->base_level - 1); + + TH_NVB097_SET_U(th, BL, MULTI_SAMPLE_COUNT, + nil_to_nvb097_multi_sample_count(image->sample_layout)); + + memcpy(desc_out, th, sizeof(th)); +} + +static const enum pipe_swizzle IDENTITY_SWIZZLE[4] = { + PIPE_SWIZZLE_X, + PIPE_SWIZZLE_Y, + PIPE_SWIZZLE_Z, + PIPE_SWIZZLE_W, +}; + +static void +nv9097_nil_buffer_fill_tic(struct nouveau_ws_device *dev, + uint64_t base_address, + enum pipe_format format, + uint32_t num_elements, + void *desc_out) +{ + uint32_t th[8] = { }; + + TH_NV9097_SET_B(th, 4, USE_TEXTURE_HEADER_VERSION2, true); + + assert(!util_format_is_compressed(format)); + th[0] = nv9097_th_bl_0(format, IDENTITY_SWIZZLE); + + TH_NV9097_SET_U(th, 1, OFFSET_LOWER, base_address); + TH_NV9097_SET_U(th, 2, OFFSET_UPPER, base_address >> 32); + TH_NV9097_SET_E(th, 2, MEMORY_LAYOUT, PITCH); + + TH_NV9097_SET_U(th, 4, WIDTH, num_elements); + TH_NV9097_SET_E(th, 2, TEXTURE_TYPE, ONE_D_BUFFER); + + + memcpy(desc_out, th, sizeof(th)); +} + +static void +nvb097_nil_buffer_fill_tic(struct nouveau_ws_device *dev, + uint64_t base_address, + enum pipe_format format, + uint32_t num_elements, + void *desc_out) +{ + uint32_t th[8] = { }; + + assert(!util_format_is_compressed(format)); + th[0] = nvb097_th_bl_0(format, IDENTITY_SWIZZLE); + + TH_NVB097_SET_U(th, 1D, ADDRESS_BITS31TO0, base_address); + TH_NVB097_SET_U(th, 1D, ADDRESS_BITS47TO32, base_address >> 32); + TH_NVB097_SET_E(th, 1D, HEADER_VERSION, SELECT_ONE_D_BUFFER); + + TH_NVB097_SET_U(th, 1D, WIDTH_MINUS_ONE_BITS15TO0, + (num_elements - 1) & 0xffff); + TH_NVB097_SET_U(th, 1D, WIDTH_MINUS_ONE_BITS31TO16, + (num_elements - 1) >> 16); + + TH_NVB097_SET_E(th, 1D, TEXTURE_TYPE, ONE_D_BUFFER); + + /* TODO: Do we need this? */ + TH_NVB097_SET_E(th, 1D, SECTOR_PROMOTION, PROMOTE_TO_2_V); + + memcpy(desc_out, th, sizeof(th)); +} + +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) +{ + if (dev->cls_eng3d >= MAXWELL_A) { + nvb097_nil_image_fill_tic(dev, image, view, base_address, desc_out); + } else if (dev->cls_eng3d >= FERMI_A) { + nv9097_nil_image_fill_tic(dev, image, view, base_address, desc_out); + } else { + unreachable("Tesla and older not supported"); + } +} + void nil_buffer_fill_tic(struct nouveau_ws_device *dev, uint64_t base_address, @@ -258,30 +515,11 @@ nil_buffer_fill_tic(struct nouveau_ws_device *dev, uint32_t num_elements, void *desc_out) { - static const enum pipe_swizzle identity_swizzle[4] = { - PIPE_SWIZZLE_X, - PIPE_SWIZZLE_Y, - PIPE_SWIZZLE_Z, - PIPE_SWIZZLE_W, - }; - uint32_t th[8] = { }; - - assert(!util_format_is_compressed(format)); - th[0] = nvb097_th_bl_0(format, identity_swizzle); - - TH_SET_U(th, NVB097, 1D, ADDRESS_BITS31TO0, base_address); - TH_SET_U(th, NVB097, 1D, ADDRESS_BITS47TO32, base_address >> 32); - TH_SET_E(th, NVB097, 1D, HEADER_VERSION, SELECT_ONE_D_BUFFER); - - TH_SET_U(th, NVB097, 1D, WIDTH_MINUS_ONE_BITS15TO0, - (num_elements - 1) & 0xffff); - TH_SET_U(th, NVB097, 1D, WIDTH_MINUS_ONE_BITS31TO16, - (num_elements - 1) >> 16); - - TH_SET_E(th, NVB097, 1D, TEXTURE_TYPE, ONE_D_BUFFER); - - /* TODO: Do we need this? */ - TH_SET_E(th, NVB097, 1D, SECTOR_PROMOTION, PROMOTE_TO_2_V); - - memcpy(desc_out, th, sizeof(th)); + if (dev->cls_eng3d >= MAXWELL_A) { + nvb097_nil_buffer_fill_tic(dev, base_address, format, num_elements, desc_out); + } else if (dev->cls_eng3d >= FERMI_A) { + nv9097_nil_buffer_fill_tic(dev, base_address, format, num_elements, desc_out); + } else { + unreachable("Tesla and older not supported"); + } } diff --git a/src/nouveau/nvidia-headers/meson.build b/src/nouveau/nvidia-headers/meson.build index 649df72dc82..1e71c446d1e 100644 --- a/src/nouveau/nvidia-headers/meson.build +++ b/src/nouveau/nvidia-headers/meson.build @@ -7,6 +7,7 @@ nvk_classes = [ 'cla0b5', 'cla097', 'clb097', + 'clb0c0', 'clb197', 'clc097', 'clc1b5', diff --git a/src/nouveau/nvidia-headers/nv_push.h b/src/nouveau/nvidia-headers/nv_push.h index bfb4185cfc1..698cff67962 100644 --- a/src/nouveau/nvidia-headers/nv_push.h +++ b/src/nouveau/nvidia-headers/nv_push.h @@ -54,6 +54,7 @@ void vk_push_print(FILE *fp, const struct nv_push *push, #define SUBC_NV90C0 1 #define SUBC_NVA0C0 1 +#define SUBC_NVB0C0 1 #define SUBC_NVC0C0 1 #define SUBC_NVC3C0 1 diff --git a/src/nouveau/vulkan/nvk_cmd_draw.c b/src/nouveau/vulkan/nvk_cmd_draw.c index a65a8fe7785..fcaec5cff16 100644 --- a/src/nouveau/vulkan/nvk_cmd_draw.c +++ b/src/nouveau/vulkan/nvk_cmd_draw.c @@ -17,6 +17,7 @@ #include "nvk_cl902d.h" #include "nvk_cl90c0.h" +#include "nvk_clb0c0.h" #include "nvk_cl9097.h" #include "nvk_cla097.h" @@ -307,6 +308,9 @@ nvk_queue_init_context_draw_state(struct nvk_queue *queue) P_NV9097_SET_VERTEX_STREAM_SUBSTITUTE_A(p, zero_addr >> 32); P_NV9097_SET_VERTEX_STREAM_SUBSTITUTE_B(p, zero_addr); + if (dev->ctx->eng3d.cls == MAXWELL_A) + P_IMMD(p, NVB097, SET_SELECT_MAXWELL_TEXTURE_HEADERS, V_TRUE); + /* Compute state */ P_MTHD(p, NV90C0, SET_OBJECT); P_NV90C0_SET_OBJECT(p, { @@ -314,6 +318,9 @@ nvk_queue_init_context_draw_state(struct nvk_queue *queue) .engine_id = 0, }); + if (dev->ctx->compute.cls == MAXWELL_COMPUTE_A) + P_IMMD(p, NVB0C0, SET_SELECT_MAXWELL_TEXTURE_HEADERS, V_TRUE); + return nvk_queue_submit_simple(queue, nv_push_dw_count(&push), push_data, 0, NULL, false /* sync */); }