mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 04:50:11 +01:00
nil: Rewrite the TIC code in Rust
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27397>
This commit is contained in:
parent
d5b7dd6ce5
commit
5577128c83
9 changed files with 671 additions and 700 deletions
|
|
@ -51,6 +51,10 @@ _libbitview_rs = static_library(
|
|||
rust_args : nak_rust_args,
|
||||
)
|
||||
|
||||
idep_bitview_rs = declare_dependency(
|
||||
link_with : _libbitview_rs,
|
||||
)
|
||||
|
||||
libnak_deps = [
|
||||
idep_mesautil,
|
||||
idep_nir_headers,
|
||||
|
|
|
|||
|
|
@ -55,14 +55,18 @@ impl Format {
|
|||
}
|
||||
}
|
||||
|
||||
fn info(&self) -> &nil_format_info {
|
||||
pub(crate) fn info(&self) -> &nil_format_info {
|
||||
unsafe { &nil_format_table[self.p_format as usize] }
|
||||
}
|
||||
|
||||
pub fn is_integer(&self) -> bool {
|
||||
pub(crate) fn is_integer(&self) -> bool {
|
||||
unsafe { util_format_is_pure_integer((*self).into()) }
|
||||
}
|
||||
|
||||
pub(crate) fn is_srgb(&self) -> bool {
|
||||
self.description().colorspace == UTIL_FORMAT_COLORSPACE_SRGB
|
||||
}
|
||||
|
||||
pub fn supports_texturing(&self, dev: &nv_device_info) -> bool {
|
||||
if self.info().support() & NIL_FORMAT_SUPPORTS_TEXTURE_BIT == 0 {
|
||||
return false;
|
||||
|
|
@ -83,7 +87,7 @@ impl Format {
|
|||
self.supports_texturing(dev) && !self.is_integer()
|
||||
}
|
||||
|
||||
pub fn supports_buffer(&self, _dev: &nv_device_info) -> bool {
|
||||
pub fn supports_buffer(&self) -> bool {
|
||||
self.info().support() & NIL_FORMAT_SUPPORTS_BUFFER_BIT != 0
|
||||
}
|
||||
|
||||
|
|
@ -128,10 +132,10 @@ pub extern "C" fn nil_format_supports_filtering(
|
|||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn nil_format_supports_buffer(
|
||||
dev: &nv_device_info,
|
||||
_dev: &nv_device_info,
|
||||
p_format: pipe_format,
|
||||
) -> bool {
|
||||
Format::try_from(p_format).is_ok_and(|f| f.supports_buffer(dev))
|
||||
Format::try_from(p_format).is_ok_and(|f| f.supports_buffer())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ extern crate nvidia_headers;
|
|||
mod extent;
|
||||
mod format;
|
||||
mod image;
|
||||
mod tic;
|
||||
mod tiling;
|
||||
|
||||
pub trait ILog2Ceil {
|
||||
|
|
|
|||
|
|
@ -14,9 +14,14 @@ endif
|
|||
|
||||
prog_cbindgen = find_program('cbindgen', required : false, native : true)
|
||||
|
||||
dep_paste = dependency('paste',
|
||||
version : '>= 1.0.14',
|
||||
fallback : ['paste', 'dep_paste'],
|
||||
required : true,
|
||||
)
|
||||
|
||||
libnil_files = files(
|
||||
'nil.h',
|
||||
'nil_image_tic.c',
|
||||
)
|
||||
|
||||
nil_format_table = custom_target(
|
||||
|
|
@ -40,10 +45,13 @@ _libnil_rs_files = files(
|
|||
'extent.rs',
|
||||
'format.rs',
|
||||
'image.rs',
|
||||
'tic.rs',
|
||||
'tiling.rs',
|
||||
)
|
||||
|
||||
_libnil_rs_deps = [
|
||||
dep_paste,
|
||||
idep_bitview_rs,
|
||||
idep_nvidia_headers_rs,
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -14,64 +14,4 @@
|
|||
|
||||
#include "nil_rs.h"
|
||||
|
||||
struct nv_device_info;
|
||||
|
||||
enum ENUM_PACKED nil_view_type {
|
||||
NIL_VIEW_TYPE_1D,
|
||||
NIL_VIEW_TYPE_2D,
|
||||
NIL_VIEW_TYPE_3D,
|
||||
NIL_VIEW_TYPE_3D_SLICED,
|
||||
NIL_VIEW_TYPE_CUBE,
|
||||
NIL_VIEW_TYPE_1D_ARRAY,
|
||||
NIL_VIEW_TYPE_2D_ARRAY,
|
||||
NIL_VIEW_TYPE_CUBE_ARRAY,
|
||||
};
|
||||
|
||||
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];
|
||||
|
||||
/* VK_EXT_image_view_min_lod */
|
||||
float min_lod_clamp;
|
||||
};
|
||||
|
||||
void nil_image_fill_tic(struct nv_device_info *dev,
|
||||
const struct nil_image *image,
|
||||
const struct nil_view *view,
|
||||
uint64_t base_address,
|
||||
void *desc_out);
|
||||
|
||||
void nil_buffer_fill_tic(struct nv_device_info *dev,
|
||||
uint64_t base_address,
|
||||
enum pipe_format format,
|
||||
uint32_t num_elements,
|
||||
void *desc_out);
|
||||
|
||||
#endif /* NIL_H */
|
||||
|
|
|
|||
|
|
@ -1,620 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2022 Collabora Ltd.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#include "nil.h"
|
||||
|
||||
#include "nil_format_table.h"
|
||||
#include "util/bitpack_helpers.h"
|
||||
|
||||
#include "nouveau_device.h"
|
||||
|
||||
#include "cl9097.h"
|
||||
#include "cl9097tex.h"
|
||||
#include "clb097.h"
|
||||
#include "clb097tex.h"
|
||||
#include "clc097.h"
|
||||
#include "clc097tex.h"
|
||||
#include "drf.h"
|
||||
|
||||
ALWAYS_INLINE static void
|
||||
__set_u32(uint32_t *o, uint32_t v, unsigned lo, unsigned hi)
|
||||
{
|
||||
assert(lo <= hi && (lo / 32) == (hi / 32));
|
||||
o[lo / 32] |= util_bitpack_uint(v, lo % 32, hi % 32);
|
||||
}
|
||||
|
||||
#define FIXED_FRAC_BITS 8
|
||||
|
||||
ALWAYS_INLINE static void
|
||||
__set_ufixed(uint32_t *o, float v, unsigned lo, unsigned hi)
|
||||
{
|
||||
assert(lo <= hi && (lo / 32) == (hi / 32));
|
||||
o[lo / 32] |= util_bitpack_ufixed_clamp(v, lo % 32, hi % 32,
|
||||
FIXED_FRAC_BITS);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static void
|
||||
__set_i32(uint32_t *o, int32_t v, unsigned lo, unsigned hi)
|
||||
{
|
||||
assert(lo <= hi && (lo / 32) == (hi / 32));
|
||||
o[lo / 32] |= util_bitpack_sint(v, lo % 32, hi % 32);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static void
|
||||
__set_bool(uint32_t *o, bool b, unsigned lo, unsigned hi)
|
||||
{
|
||||
assert(lo == hi);
|
||||
o[lo / 32] |= util_bitpack_uint(b, lo % 32, hi % 32);
|
||||
}
|
||||
|
||||
#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))
|
||||
|
||||
#define TH_SET_UF(o, NV, VER, FIELD, val) \
|
||||
__set_ufixed((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))
|
||||
|
||||
#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))
|
||||
|
||||
#define TH_SET_E(o, NV, 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_UF(o, IDX, FIELD, val) \
|
||||
TH_SET_UF(&(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_UF(o, VER, FIELD, val) \
|
||||
TH_SET_UF((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);
|
||||
|
||||
#define TH_NVC097_SET_U(o, VER, FIELD, val) \
|
||||
TH_SET_U((o), NVC097, _##VER, FIELD, (val));
|
||||
|
||||
static const struct nil_tic_format *
|
||||
nil_tic_format_for_pipe(enum pipe_format format)
|
||||
{
|
||||
assert(format < PIPE_FORMAT_COUNT);
|
||||
const struct nil_format_info *fmt = &nil_format_table[format];
|
||||
return fmt->tic.comp_sizes == 0 ? NULL : &fmt->tic;
|
||||
}
|
||||
|
||||
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,
|
||||
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 NVB097_TEXHEAD_BL_X_SOURCE_IN_ZERO;
|
||||
case PIPE_SWIZZLE_1:
|
||||
return is_int ? NVB097_TEXHEAD_BL_X_SOURCE_IN_ONE_INT :
|
||||
NVB097_TEXHEAD_BL_X_SOURCE_IN_ONE_FLOAT;
|
||||
default:
|
||||
unreachable("Invalid component swizzle");
|
||||
}
|
||||
}
|
||||
|
||||
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])
|
||||
{
|
||||
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_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
|
||||
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; \
|
||||
STATIC_ASSERT(NVB097_TEXHEAD_BL_TEXTURE_TYPE_##NV == NV9097_TEXHEADV2_2_TEXTURE_TYPE_##NV);
|
||||
|
||||
switch (type) {
|
||||
CASE(1D, ONE_D);
|
||||
CASE(2D, TWO_D);
|
||||
CASE(3D, THREE_D);
|
||||
CASE(3D_SLICED, THREE_D);
|
||||
CASE(CUBE, CUBEMAP);
|
||||
CASE(1D_ARRAY, ONE_D_ARRAY);
|
||||
CASE(2D_ARRAY, TWO_D_ARRAY);
|
||||
CASE(CUBE_ARRAY, CUBEMAP_ARRAY);
|
||||
default: unreachable("Invalid image view type");
|
||||
}
|
||||
|
||||
#undef CASE
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
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: \
|
||||
return NVB097_TEXHEAD_BL_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 inline uint32_t
|
||||
nil_max_mip_level(const struct nil_image *image,
|
||||
const struct nil_view *view)
|
||||
{
|
||||
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
|
||||
* referenced image has more than one miplevel. Fortunately, Vulkan has
|
||||
* restrictions requiring the view to be a single-layer single-LOD view
|
||||
* in order to use nonnormalizedCoordinates = VK_TRUE in the sampler.
|
||||
* From the Vulkan 1.3.255 spec:
|
||||
*
|
||||
* "When unnormalizedCoordinates is VK_TRUE, images the sampler is
|
||||
* used with in the shader have the following requirements:
|
||||
*
|
||||
* - The viewType must be either VK_IMAGE_VIEW_TYPE_1D or
|
||||
* VK_IMAGE_VIEW_TYPE_2D.
|
||||
* - The image view must have a single layer and a single mip
|
||||
* level."
|
||||
*
|
||||
* Under these conditions, the view is simply LOD 0 of a single array
|
||||
* slice so we don't need to care about aray stride between slices so
|
||||
* it's safe to set the number of miplevels to 0 regardless of how many
|
||||
* the image actually has.
|
||||
*/
|
||||
return 0;
|
||||
} else {
|
||||
return image->num_levels - 1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct nil_extent4d
|
||||
nil_normalize_extent(const struct nil_image *image,
|
||||
const struct nil_view *view)
|
||||
{
|
||||
struct nil_extent4d extent;
|
||||
|
||||
extent.width = image->extent_px.width;
|
||||
extent.height = image->extent_px.height;
|
||||
extent.array_len = 0;
|
||||
|
||||
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;
|
||||
case NIL_VIEW_TYPE_3D_SLICED:
|
||||
assert(image->dim == NIL_IMAGE_DIM_3D);
|
||||
extent.depth = view->array_len;
|
||||
break;
|
||||
default:
|
||||
unreachable("Unsupported image view target");
|
||||
};
|
||||
|
||||
return extent;
|
||||
}
|
||||
|
||||
static void
|
||||
nv9097_nil_image_fill_tic(const struct nil_image *image,
|
||||
const struct nil_view *view,
|
||||
uint64_t base_address,
|
||||
void *desc_out)
|
||||
{
|
||||
assert(util_format_get_blocksize(image->format.p_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.array_len);
|
||||
|
||||
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;
|
||||
TH_NV9097_SET_U(th, 1, OFFSET_LOWER, layer_address & 0xffffffff);
|
||||
TH_NV9097_SET_U(th, 2, OFFSET_UPPER, layer_address >> 32);
|
||||
|
||||
const struct nil_tiling *tiling = &image->levels[0].tiling;
|
||||
if (tiling->is_tiled) {
|
||||
TH_NV9097_SET_E(th, 2, MEMORY_LAYOUT, BLOCKLINEAR);
|
||||
|
||||
assert(tiling->gob_height_is_8);
|
||||
assert(tiling->x_log2 == 0);
|
||||
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_U(th, 2, TEXTURE_TYPE, pipe_to_nv_texture_type(view->type));
|
||||
} else {
|
||||
TH_NV9097_SET_E(th, 2, MEMORY_LAYOUT, PITCH);
|
||||
|
||||
uint32_t pitch = image->levels[0].row_stride_B;
|
||||
TH_NV9097_SET_U(th, 3, PITCH, pitch);
|
||||
|
||||
assert(view->type == NIL_VIEW_TYPE_2D ||
|
||||
view->type == NIL_VIEW_TYPE_2D_ARRAY);
|
||||
assert(image->sample_layout == NIL_SAMPLE_LAYOUT_1X1);
|
||||
assert(view->num_levels == 1);
|
||||
TH_NV9097_SET_E(th, 2, TEXTURE_TYPE, TWO_D_NO_MIPMAP);
|
||||
}
|
||||
|
||||
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_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_NV9097_SET_B(th, 2, NORMALIZED_COORDS, true);
|
||||
|
||||
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_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_NV9097_SET_U(th, 7, MULTI_SAMPLE_COUNT,
|
||||
nil_to_nv9097_multi_sample_count(image->sample_layout));
|
||||
|
||||
TH_NV9097_SET_UF(th, 7, MIN_LOD_CLAMP,
|
||||
view->min_lod_clamp - view->base_level);
|
||||
|
||||
memcpy(desc_out, th, sizeof(th));
|
||||
}
|
||||
|
||||
static void
|
||||
nvb097_nil_image_fill_tic(struct nv_device_info *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.p_format) ==
|
||||
util_format_get_blocksize(view->format));
|
||||
assert(view->base_level + view->num_levels <= image->num_levels);
|
||||
|
||||
uint32_t th[8] = { };
|
||||
|
||||
th[0] = nvb097_th_bl_0(view->format, view->swizzle);
|
||||
|
||||
const struct nil_tiling *tiling = &image->levels[0].tiling;
|
||||
|
||||
/* There's no base layer field in the texture header */
|
||||
uint64_t layer_address = base_address;
|
||||
if (view->type == NIL_VIEW_TYPE_3D_SLICED) {
|
||||
assert(image->num_levels == 1);
|
||||
assert(view->base_array_layer + view->array_len <=
|
||||
image->extent_px.depth);
|
||||
layer_address += nil_image_level_z_offset_B(image, view->base_level,
|
||||
view->base_array_layer);
|
||||
} else {
|
||||
assert(view->base_array_layer + view->array_len <=
|
||||
image->extent_px.array_len);
|
||||
layer_address += view->base_array_layer * image->array_stride_B;
|
||||
}
|
||||
|
||||
if (tiling->is_tiled) {
|
||||
TH_NVB097_SET_E(th, BL, HEADER_VERSION, SELECT_BLOCKLINEAR);
|
||||
|
||||
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);
|
||||
|
||||
assert(tiling->gob_height_is_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_U(th, BL, TILE_WIDTH_IN_GOBS, tiling->x_log2);
|
||||
|
||||
TH_NVB097_SET_U(th, BL, TEXTURE_TYPE, pipe_to_nv_texture_type(view->type));
|
||||
} else {
|
||||
TH_NVB097_SET_E(th, PITCH, HEADER_VERSION, SELECT_PITCH);
|
||||
|
||||
assert((layer_address & BITFIELD_MASK(5)) == 0);
|
||||
TH_NVB097_SET_U(th, PITCH, ADDRESS_BITS31TO5,
|
||||
(uint32_t)layer_address >> 5);
|
||||
TH_NVB097_SET_U(th, PITCH, ADDRESS_BITS47TO32,
|
||||
layer_address >> 32);
|
||||
|
||||
uint32_t pitch = image->levels[0].row_stride_B;
|
||||
assert((pitch & BITFIELD_MASK(5)) == 0);
|
||||
TH_NVB097_SET_U(th, PITCH, PITCH_BITS20TO5, pitch >> 5);
|
||||
|
||||
assert(view->type == NIL_VIEW_TYPE_2D ||
|
||||
view->type == NIL_VIEW_TYPE_2D_ARRAY);
|
||||
assert(image->sample_layout == NIL_SAMPLE_LAYOUT_1X1);
|
||||
assert(view->num_levels == 1);
|
||||
TH_NVB097_SET_E(th, PITCH, TEXTURE_TYPE, TWO_D_NO_MIPMAP);
|
||||
}
|
||||
|
||||
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);
|
||||
if (dev->cls_eng3d >= PASCAL_A) {
|
||||
const uint32_t height_1 = extent.height - 1;
|
||||
const uint32_t depth_1 = extent.depth - 1;
|
||||
TH_NVC097_SET_U(th, BL, HEIGHT_MINUS_ONE, height_1 & BITFIELD_MASK(16));
|
||||
TH_NVC097_SET_U(th, BL, HEIGHT_MINUS_ONE_BIT16, height_1 >> 16);
|
||||
TH_NVC097_SET_U(th, BL, DEPTH_MINUS_ONE, depth_1 & BITFIELD_MASK(14));
|
||||
TH_NVC097_SET_U(th, BL, DEPTH_MINUS_ONE_BIT14, depth_1 >> 14);
|
||||
} else {
|
||||
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_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));
|
||||
|
||||
TH_NVB097_SET_UF(th, BL, MIN_LOD_CLAMP,
|
||||
view->min_lod_clamp - view->base_level);
|
||||
|
||||
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(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(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 nv_device_info *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(image, view, base_address, desc_out);
|
||||
} else {
|
||||
unreachable("Tesla and older not supported");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nil_buffer_fill_tic(struct nv_device_info *dev,
|
||||
uint64_t base_address,
|
||||
enum pipe_format format,
|
||||
uint32_t num_elements,
|
||||
void *desc_out)
|
||||
{
|
||||
if (dev->cls_eng3d >= MAXWELL_A) {
|
||||
nvb097_nil_buffer_fill_tic(base_address, format, num_elements, desc_out);
|
||||
} else if (dev->cls_eng3d >= FERMI_A) {
|
||||
nv9097_nil_buffer_fill_tic(base_address, format, num_elements, desc_out);
|
||||
} else {
|
||||
unreachable("Tesla and older not supported");
|
||||
}
|
||||
}
|
||||
633
src/nouveau/nil/tic.rs
Normal file
633
src/nouveau/nil/tic.rs
Normal file
|
|
@ -0,0 +1,633 @@
|
|||
// Copyright © 2024 Collabora, Ltd.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#![allow(unused_macros)]
|
||||
|
||||
extern crate bitview;
|
||||
extern crate nvidia_headers;
|
||||
|
||||
use bitview::*;
|
||||
use nil_rs_bindings::*;
|
||||
use nvidia_headers::cl9097::tex as cl9097;
|
||||
use nvidia_headers::cl9097::FERMI_A;
|
||||
use nvidia_headers::clb097::tex as clb097;
|
||||
use nvidia_headers::clb097::MAXWELL_A;
|
||||
use nvidia_headers::clc097::tex as clc097;
|
||||
use nvidia_headers::clc097::PASCAL_A;
|
||||
use paste::paste;
|
||||
use std::ops::Range;
|
||||
|
||||
use crate::extent::Extent4D;
|
||||
use crate::format::Format;
|
||||
use crate::image::Image;
|
||||
use crate::image::ImageDim;
|
||||
use crate::image::SampleLayout;
|
||||
use crate::image::View;
|
||||
use crate::image::ViewType;
|
||||
|
||||
macro_rules! set_enum {
|
||||
($th:expr, $cls:ident, $field:ident, $enum:ident) => {
|
||||
paste! {
|
||||
$th.set_field($cls::$field, $cls::[<$field _ $enum>])
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
trait SetUFixed {
|
||||
fn set_ufixed(&mut self, range: Range<usize>, val: f32);
|
||||
}
|
||||
|
||||
const FIXED_FRAC_BITS: u32 = 8;
|
||||
|
||||
impl<T: SetFieldU64> SetUFixed for T {
|
||||
fn set_ufixed(&mut self, range: Range<usize>, val: f32) {
|
||||
assert!(range.len() >= FIXED_FRAC_BITS as usize);
|
||||
let scaled = val * ((1 << FIXED_FRAC_BITS) as f32);
|
||||
let scaled_max = ((1 << range.len()) - 1) as f32;
|
||||
let u_val = scaled.clamp(0.0, scaled_max).round() as u32;
|
||||
self.set_field(range, u_val);
|
||||
}
|
||||
}
|
||||
|
||||
fn nv9097_th_v2_source(
|
||||
fmt: &nil_tic_format,
|
||||
swizzle: pipe_swizzle,
|
||||
is_int: bool,
|
||||
) -> u32 {
|
||||
match swizzle {
|
||||
PIPE_SWIZZLE_X => fmt.src_x(),
|
||||
PIPE_SWIZZLE_Y => fmt.src_y(),
|
||||
PIPE_SWIZZLE_Z => fmt.src_z(),
|
||||
PIPE_SWIZZLE_W => fmt.src_w(),
|
||||
PIPE_SWIZZLE_0 => cl9097::TEXHEADV2_X_SOURCE_IN_ZERO,
|
||||
PIPE_SWIZZLE_1 => {
|
||||
if is_int {
|
||||
cl9097::TEXHEADV2_X_SOURCE_IN_ONE_INT
|
||||
} else {
|
||||
cl9097::TEXHEADV2_X_SOURCE_IN_ONE_FLOAT
|
||||
}
|
||||
}
|
||||
other => panic!("Invalid component swizzle {}", other),
|
||||
}
|
||||
}
|
||||
|
||||
fn nvb097_th_bl_source(
|
||||
fmt: &nil_tic_format,
|
||||
swizzle: pipe_swizzle,
|
||||
is_int: bool,
|
||||
) -> u32 {
|
||||
match swizzle {
|
||||
PIPE_SWIZZLE_X => fmt.src_x(),
|
||||
PIPE_SWIZZLE_Y => fmt.src_y(),
|
||||
PIPE_SWIZZLE_Z => fmt.src_z(),
|
||||
PIPE_SWIZZLE_W => fmt.src_w(),
|
||||
PIPE_SWIZZLE_0 => clb097::TEXHEADV2_X_SOURCE_IN_ZERO,
|
||||
PIPE_SWIZZLE_1 => {
|
||||
if is_int {
|
||||
clb097::TEXHEADV2_X_SOURCE_IN_ONE_INT
|
||||
} else {
|
||||
clb097::TEXHEADV2_X_SOURCE_IN_ONE_FLOAT
|
||||
}
|
||||
}
|
||||
other => panic!("Invalid component swizzle {}", other),
|
||||
}
|
||||
}
|
||||
|
||||
type THBitView<'a> = BitMutView<'a, [u32; 8]>;
|
||||
|
||||
fn nv9097_set_th_v2_0<'a>(
|
||||
th: &mut THBitView<'a>,
|
||||
format: &Format,
|
||||
swizzle: [nil_rs_bindings::pipe_swizzle; 4],
|
||||
) {
|
||||
let fmt = &format.info().tic;
|
||||
let is_int = format.is_integer();
|
||||
let source = [
|
||||
nv9097_th_v2_source(fmt, swizzle[0], is_int),
|
||||
nv9097_th_v2_source(fmt, swizzle[1], is_int),
|
||||
nv9097_th_v2_source(fmt, swizzle[2], is_int),
|
||||
nv9097_th_v2_source(fmt, swizzle[3], is_int),
|
||||
];
|
||||
|
||||
th.set_field(cl9097::TEXHEADV2_COMPONENT_SIZES, fmt.comp_sizes());
|
||||
th.set_field(cl9097::TEXHEADV2_R_DATA_TYPE, fmt.type_r());
|
||||
th.set_field(cl9097::TEXHEADV2_G_DATA_TYPE, fmt.type_g());
|
||||
th.set_field(cl9097::TEXHEADV2_B_DATA_TYPE, fmt.type_b());
|
||||
th.set_field(cl9097::TEXHEADV2_A_DATA_TYPE, fmt.type_a());
|
||||
th.set_field(cl9097::TEXHEADV2_X_SOURCE, source[0]);
|
||||
th.set_field(cl9097::TEXHEADV2_Y_SOURCE, source[1]);
|
||||
th.set_field(cl9097::TEXHEADV2_Z_SOURCE, source[2]);
|
||||
th.set_field(cl9097::TEXHEADV2_W_SOURCE, source[3]);
|
||||
}
|
||||
|
||||
fn nvb097_set_th_bl_0<'a>(
|
||||
th: &mut THBitView<'a>,
|
||||
format: &Format,
|
||||
swizzle: [nil_rs_bindings::pipe_swizzle; 4],
|
||||
) {
|
||||
let fmt = &format.info().tic;
|
||||
let is_int = format.is_integer();
|
||||
let source = [
|
||||
nvb097_th_bl_source(fmt, swizzle[0], is_int),
|
||||
nvb097_th_bl_source(fmt, swizzle[1], is_int),
|
||||
nvb097_th_bl_source(fmt, swizzle[2], is_int),
|
||||
nvb097_th_bl_source(fmt, swizzle[3], is_int),
|
||||
];
|
||||
|
||||
th.set_field(clb097::TEXHEAD_BL_COMPONENTS, fmt.comp_sizes());
|
||||
th.set_field(clb097::TEXHEAD_BL_R_DATA_TYPE, fmt.type_r());
|
||||
th.set_field(clb097::TEXHEAD_BL_G_DATA_TYPE, fmt.type_g());
|
||||
th.set_field(clb097::TEXHEAD_BL_B_DATA_TYPE, fmt.type_b());
|
||||
th.set_field(clb097::TEXHEAD_BL_A_DATA_TYPE, fmt.type_a());
|
||||
th.set_field(clb097::TEXHEAD_BL_X_SOURCE, source[0]);
|
||||
th.set_field(clb097::TEXHEAD_BL_Y_SOURCE, source[1]);
|
||||
th.set_field(clb097::TEXHEAD_BL_Z_SOURCE, source[2]);
|
||||
th.set_field(clb097::TEXHEAD_BL_W_SOURCE, source[3]);
|
||||
}
|
||||
|
||||
fn pipe_to_nv_texture_type(ty: ViewType) -> u32 {
|
||||
match ty {
|
||||
ViewType::_1D => clb097::TEXHEAD_BL_TEXTURE_TYPE_ONE_D,
|
||||
ViewType::_2D => clb097::TEXHEAD_BL_TEXTURE_TYPE_TWO_D,
|
||||
ViewType::_3D | ViewType::_3DSliced => {
|
||||
clb097::TEXHEAD_BL_TEXTURE_TYPE_THREE_D
|
||||
}
|
||||
ViewType::Cube => clb097::TEXHEAD_BL_TEXTURE_TYPE_CUBEMAP,
|
||||
ViewType::_1DArray => clb097::TEXHEAD_BL_TEXTURE_TYPE_ONE_D_ARRAY,
|
||||
ViewType::_2DArray => clb097::TEXHEAD_BL_TEXTURE_TYPE_TWO_D_ARRAY,
|
||||
ViewType::CubeArray => clb097::TEXHEAD_BL_TEXTURE_TYPE_CUBEMAP_ARRAY,
|
||||
}
|
||||
}
|
||||
|
||||
fn nil_rs_to_nv9097_multi_sample_count(sample_layout: SampleLayout) -> u32 {
|
||||
match sample_layout {
|
||||
SampleLayout::_1x1 => cl9097::TEXHEADV2_MULTI_SAMPLE_COUNT_MODE_1X1,
|
||||
SampleLayout::_2x1 => cl9097::TEXHEADV2_MULTI_SAMPLE_COUNT_MODE_2X1,
|
||||
SampleLayout::_2x2 => cl9097::TEXHEADV2_MULTI_SAMPLE_COUNT_MODE_2X2,
|
||||
SampleLayout::_4x2 => cl9097::TEXHEADV2_MULTI_SAMPLE_COUNT_MODE_4X2,
|
||||
SampleLayout::_4x4 => cl9097::TEXHEADV2_MULTI_SAMPLE_COUNT_MODE_4X4,
|
||||
SampleLayout::Invalid => panic!("Invalid sample layout"),
|
||||
}
|
||||
}
|
||||
|
||||
fn nil_rs_to_nvb097_multi_sample_count(sample_layout: SampleLayout) -> u32 {
|
||||
match sample_layout {
|
||||
SampleLayout::_1x1 => clb097::TEXHEAD_BL_MULTI_SAMPLE_COUNT_MODE_1X1,
|
||||
SampleLayout::_2x1 => clb097::TEXHEAD_BL_MULTI_SAMPLE_COUNT_MODE_2X1,
|
||||
SampleLayout::_2x2 => clb097::TEXHEAD_BL_MULTI_SAMPLE_COUNT_MODE_2X2,
|
||||
SampleLayout::_4x2 => clb097::TEXHEAD_BL_MULTI_SAMPLE_COUNT_MODE_4X2,
|
||||
SampleLayout::_4x4 => clb097::TEXHEAD_BL_MULTI_SAMPLE_COUNT_MODE_4X4,
|
||||
SampleLayout::Invalid => panic!("Invalid sample layout"),
|
||||
}
|
||||
}
|
||||
|
||||
fn nil_rs_max_mip_level(image: &Image, view: &View) -> u32 {
|
||||
if view.view_type != ViewType::_3D
|
||||
&& view.array_len == 1
|
||||
&& view.base_level == 0
|
||||
&& view.num_levels == 1
|
||||
{
|
||||
// The Unnormalized coordinates bit in the sampler gets ignored if the
|
||||
// referenced image has more than one miplevel. Fortunately, Vulkan has
|
||||
// restrictions requiring the view to be a single-layer single-LOD view
|
||||
// in order to use nonnormalizedCoordinates = VK_TRUE in the sampler.
|
||||
// From the Vulkan 1.3.255 spec:
|
||||
//
|
||||
// "When unnormalizedCoordinates is VK_TRUE, images the sampler is
|
||||
// used with in the shader have the following requirements:
|
||||
//
|
||||
// - The viewType must be either VK_IMAGE_VIEW_TYPE_1D or
|
||||
// VK_IMAGE_VIEW_TYPE_2D.
|
||||
// - The image view must have a single layer and a single mip
|
||||
// level."
|
||||
//
|
||||
// Under these conditions, the view is simply LOD 0 of a single array
|
||||
// slice so we don't need to care about aray stride between slices so
|
||||
// it's safe to set the number of miplevels to 0 regardless of how many
|
||||
// the image actually has.
|
||||
0
|
||||
} else {
|
||||
image.num_levels - 1
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_extent(image: &Image, view: &View) -> Extent4D {
|
||||
let mut extent = Extent4D {
|
||||
width: image.extent_px.width,
|
||||
height: image.extent_px.height,
|
||||
depth: 0,
|
||||
array_len: 0,
|
||||
};
|
||||
|
||||
match view.view_type {
|
||||
ViewType::_1D
|
||||
| ViewType::_2D
|
||||
| ViewType::_1DArray
|
||||
| ViewType::_2DArray => {
|
||||
assert!(image.extent_px.depth == 1);
|
||||
extent.depth = view.array_len;
|
||||
}
|
||||
ViewType::_3D => {
|
||||
assert!(image.dim == ImageDim::_3D);
|
||||
extent.depth = image.extent_px.depth;
|
||||
}
|
||||
ViewType::Cube | ViewType::CubeArray => {
|
||||
assert!(image.dim == ImageDim::_2D);
|
||||
assert!(view.array_len % 6 == 0);
|
||||
extent.depth = view.array_len / 6;
|
||||
}
|
||||
ViewType::_3DSliced => {
|
||||
assert!(image.dim == ImageDim::_3D);
|
||||
extent.depth = view.array_len;
|
||||
}
|
||||
}
|
||||
|
||||
extent
|
||||
}
|
||||
|
||||
fn nv9097_fill_tic(
|
||||
image: &Image,
|
||||
view: &View,
|
||||
base_address: u64,
|
||||
desc_out: &mut [u32; 8],
|
||||
) {
|
||||
assert!(image.format.el_size_B() == view.format.el_size_B());
|
||||
assert!(view.base_level + view.num_levels <= image.num_levels);
|
||||
assert!(
|
||||
view.base_array_layer + view.array_len <= image.extent_px.array_len
|
||||
);
|
||||
|
||||
*desc_out = [0u32; 8];
|
||||
let mut th = BitMutView::new(desc_out);
|
||||
|
||||
th.set_field(cl9097::TEXHEADV2_USE_TEXTURE_HEADER_VERSION2, true);
|
||||
nv9097_set_th_v2_0(&mut th, &view.format, view.swizzle);
|
||||
|
||||
// There's no base layer field in the texture header
|
||||
let layer_address = base_address
|
||||
+ u64::from(view.base_array_layer)
|
||||
+ u64::from(image.array_stride_B);
|
||||
|
||||
th.set_field(cl9097::TEXHEADV2_OFFSET_LOWER, layer_address as u32);
|
||||
th.set_field(cl9097::TEXHEADV2_OFFSET_UPPER, (layer_address >> 32) as u32);
|
||||
|
||||
let tiling = &image.levels[0].tiling;
|
||||
|
||||
if tiling.is_tiled {
|
||||
set_enum!(th, cl9097, TEXHEADV2_MEMORY_LAYOUT, BLOCKLINEAR);
|
||||
|
||||
assert!(tiling.gob_height_is_8);
|
||||
assert!(tiling.x_log2 == 0);
|
||||
set_enum!(th, cl9097, TEXHEADV2_GOBS_PER_BLOCK_WIDTH, ONE_GOB);
|
||||
th.set_field(cl9097::TEXHEADV2_GOBS_PER_BLOCK_HEIGHT, tiling.y_log2);
|
||||
th.set_field(cl9097::TEXHEADV2_GOBS_PER_BLOCK_DEPTH, tiling.z_log2);
|
||||
|
||||
let nv_tex_type = pipe_to_nv_texture_type(view.view_type);
|
||||
th.set_field(cl9097::TEXHEADV2_TEXTURE_TYPE, nv_tex_type);
|
||||
} else {
|
||||
set_enum!(th, cl9097, TEXHEADV2_MEMORY_LAYOUT, PITCH);
|
||||
|
||||
let pitch = image.levels[0].row_stride_B;
|
||||
th.set_field(cl9097::TEXHEADV2_PITCH, pitch);
|
||||
|
||||
assert!(
|
||||
view.view_type == ViewType::_2D
|
||||
|| view.view_type == ViewType::_2DArray
|
||||
);
|
||||
assert!(image.sample_layout == SampleLayout::_1x1);
|
||||
assert!(view.num_levels == 1);
|
||||
set_enum!(th, cl9097, TEXHEADV2_TEXTURE_TYPE, TWO_D_NO_MIPMAP);
|
||||
}
|
||||
|
||||
set_enum!(th, cl9097, TEXHEADV2_LOD_ANISO_QUALITY, LOD_QUALITY_HIGH);
|
||||
set_enum!(th, cl9097, TEXHEADV2_LOD_ISO_QUALITY, LOD_QUALITY_HIGH);
|
||||
set_enum!(
|
||||
th,
|
||||
cl9097,
|
||||
TEXHEADV2_ANISO_COARSE_SPREAD_MODIFIER,
|
||||
SPREAD_MODIFIER_NONE
|
||||
);
|
||||
|
||||
let extent = normalize_extent(image, view);
|
||||
th.set_field(cl9097::TEXHEADV2_WIDTH, extent.width);
|
||||
th.set_field(cl9097::TEXHEADV2_HEIGHT, extent.height);
|
||||
th.set_field(cl9097::TEXHEADV2_DEPTH, extent.depth);
|
||||
|
||||
let max_mip_level = nil_rs_max_mip_level(image, view);
|
||||
th.set_field(cl9097::TEXHEADV2_MAX_MIP_LEVEL, max_mip_level);
|
||||
|
||||
th.set_field(cl9097::TEXHEADV2_S_R_G_B_CONVERSION, view.format.is_srgb());
|
||||
|
||||
set_enum!(th, cl9097, TEXHEADV2_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_field(cl9097::TEXHEADV2_NORMALIZED_COORDS, true);
|
||||
|
||||
set_enum!(
|
||||
th,
|
||||
cl9097,
|
||||
TEXHEADV2_ANISO_FINE_SPREAD_FUNC,
|
||||
SPREAD_FUNC_TWO
|
||||
);
|
||||
set_enum!(
|
||||
th,
|
||||
cl9097,
|
||||
TEXHEADV2_ANISO_COARSE_SPREAD_FUNC,
|
||||
SPREAD_FUNC_ONE
|
||||
);
|
||||
|
||||
th.set_field(cl9097::TEXHEADV2_RES_VIEW_MIN_MIP_LEVEL, view.base_level);
|
||||
th.set_field(
|
||||
cl9097::TEXHEADV2_RES_VIEW_MAX_MIP_LEVEL,
|
||||
view.num_levels + view.base_level - 1,
|
||||
);
|
||||
|
||||
let msc = nil_rs_to_nv9097_multi_sample_count(image.sample_layout);
|
||||
th.set_field(cl9097::TEXHEADV2_MULTI_SAMPLE_COUNT, msc);
|
||||
|
||||
let min_lod_clamp = view.min_lod_clamp - (view.base_level as f32);
|
||||
th.set_ufixed(cl9097::TEXHEADV2_MIN_LOD_CLAMP, min_lod_clamp);
|
||||
}
|
||||
|
||||
fn nvb097_fill_tic(
|
||||
dev: &nil_rs_bindings::nv_device_info,
|
||||
image: &Image,
|
||||
view: &View,
|
||||
base_address: u64,
|
||||
desc_out: &mut [u32; 8],
|
||||
) {
|
||||
assert!(image.format.el_size_B() == view.format.el_size_B());
|
||||
assert!(view.base_level + view.num_levels <= image.num_levels);
|
||||
|
||||
*desc_out = [0u32; 8];
|
||||
let mut th = BitMutView::new(desc_out);
|
||||
|
||||
nvb097_set_th_bl_0(&mut th, &view.format, view.swizzle);
|
||||
|
||||
let tiling = &image.levels[0].tiling;
|
||||
|
||||
// There's no base layer field in the texture header
|
||||
let mut layer_address = base_address;
|
||||
if view.view_type == ViewType::_3DSliced {
|
||||
assert!(view.num_levels == 1);
|
||||
assert!(
|
||||
view.base_array_layer + view.array_len <= image.extent_px.depth
|
||||
);
|
||||
|
||||
layer_address +=
|
||||
image.level_z_offset_B(view.base_level, view.base_array_layer);
|
||||
} else {
|
||||
assert!(
|
||||
view.base_array_layer + view.array_len <= image.extent_px.array_len
|
||||
);
|
||||
layer_address +=
|
||||
u64::from(view.base_array_layer) * u64::from(image.array_stride_B);
|
||||
}
|
||||
|
||||
if tiling.is_tiled {
|
||||
set_enum!(th, clb097, TEXHEAD_BL_HEADER_VERSION, SELECT_BLOCKLINEAR);
|
||||
|
||||
let addr = BitView::new(&layer_address);
|
||||
assert!(addr.get_bit_range_u64(0..9) == 0);
|
||||
th.set_field(
|
||||
clb097::TEXHEAD_BL_ADDRESS_BITS31TO9,
|
||||
addr.get_bit_range_u64(9..32),
|
||||
);
|
||||
th.set_field(
|
||||
clb097::TEXHEAD_BL_ADDRESS_BITS47TO32,
|
||||
addr.get_bit_range_u64(32..48),
|
||||
);
|
||||
assert!(addr.get_bit_range_u64(48..64) == 0);
|
||||
|
||||
assert!(tiling.gob_height_is_8);
|
||||
|
||||
set_enum!(th, clb097, TEXHEAD_BL_GOBS_PER_BLOCK_WIDTH, ONE_GOB);
|
||||
th.set_field(clb097::TEXHEAD_BL_GOBS_PER_BLOCK_HEIGHT, tiling.y_log2);
|
||||
th.set_field(clb097::TEXHEAD_BL_GOBS_PER_BLOCK_DEPTH, tiling.z_log2);
|
||||
th.set_field(clb097::TEXHEAD_BL_TILE_WIDTH_IN_GOBS, tiling.x_log2);
|
||||
|
||||
let nv_text_type = pipe_to_nv_texture_type(view.view_type);
|
||||
th.set_field(clb097::TEXHEAD_BL_TEXTURE_TYPE, nv_text_type);
|
||||
} else {
|
||||
set_enum!(th, clb097, TEXHEAD_BL_HEADER_VERSION, SELECT_PITCH);
|
||||
|
||||
let addr = BitView::new(&layer_address);
|
||||
assert!(addr.get_bit_range_u64(0..5) == 0);
|
||||
th.set_field(
|
||||
clb097::TEXHEAD_PITCH_ADDRESS_BITS31TO5,
|
||||
addr.get_bit_range_u64(5..32),
|
||||
);
|
||||
th.set_field(
|
||||
clb097::TEXHEAD_PITCH_ADDRESS_BITS47TO32,
|
||||
addr.get_bit_range_u64(32..48),
|
||||
);
|
||||
assert!(addr.get_bit_range_u64(48..64) == 0);
|
||||
|
||||
let pitch = image.levels[0].row_stride_B;
|
||||
let pitch = BitView::new(&pitch);
|
||||
assert!(pitch.get_bit_range_u64(0..5) == 0);
|
||||
assert!(pitch.get_bit_range_u64(21..32) == 0);
|
||||
th.set_field(
|
||||
clb097::TEXHEAD_PITCH_PITCH_BITS20TO5,
|
||||
pitch.get_bit_range_u64(5..21),
|
||||
);
|
||||
|
||||
assert!(
|
||||
view.view_type == ViewType::_2D
|
||||
|| view.view_type == ViewType::_2DArray
|
||||
);
|
||||
assert!(image.sample_layout == SampleLayout::_1x1);
|
||||
assert!(view.num_levels == 1);
|
||||
set_enum!(th, clb097, TEXHEAD_PITCH_TEXTURE_TYPE, TWO_D_NO_MIPMAP);
|
||||
}
|
||||
|
||||
th.set_field(clb097::TEXHEAD_BL_LOD_ANISO_QUALITY2, true);
|
||||
set_enum!(th, clb097, TEXHEAD_BL_LOD_ANISO_QUALITY, LOD_QUALITY_HIGH);
|
||||
set_enum!(th, clb097, TEXHEAD_BL_LOD_ISO_QUALITY, LOD_QUALITY_HIGH);
|
||||
set_enum!(
|
||||
th,
|
||||
clb097,
|
||||
TEXHEAD_BL_ANISO_COARSE_SPREAD_MODIFIER,
|
||||
SPREAD_MODIFIER_NONE
|
||||
);
|
||||
|
||||
let extent = normalize_extent(image, view);
|
||||
th.set_field(clb097::TEXHEAD_BL_WIDTH_MINUS_ONE, extent.width - 1);
|
||||
|
||||
if dev.cls_eng3d >= PASCAL_A {
|
||||
let height_1 = extent.height - 1;
|
||||
let depth_1 = extent.depth - 1;
|
||||
th.set_field(clc097::TEXHEAD_BL_HEIGHT_MINUS_ONE, height_1 & 0xffff);
|
||||
th.set_field(clc097::TEXHEAD_BL_HEIGHT_MINUS_ONE_BIT16, height_1 >> 16);
|
||||
th.set_field(clc097::TEXHEAD_BL_DEPTH_MINUS_ONE, depth_1 & 0x3fff);
|
||||
th.set_field(clc097::TEXHEAD_BL_DEPTH_MINUS_ONE_BIT14, depth_1 >> 14);
|
||||
} else {
|
||||
th.set_field(clb097::TEXHEAD_BL_HEIGHT_MINUS_ONE, extent.height - 1);
|
||||
th.set_field(clb097::TEXHEAD_BL_DEPTH_MINUS_ONE, extent.depth - 1);
|
||||
}
|
||||
|
||||
let max_mip_level = nil_rs_max_mip_level(image, view);
|
||||
th.set_field(clb097::TEXHEAD_BL_MAX_MIP_LEVEL, max_mip_level);
|
||||
|
||||
th.set_field(clb097::TEXHEAD_BL_S_R_G_B_CONVERSION, view.format.is_srgb());
|
||||
|
||||
set_enum!(th, clb097, TEXHEAD_BL_SECTOR_PROMOTION, PROMOTE_TO_2_V);
|
||||
set_enum!(th, clb097, TEXHEAD_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.set_field(clb097::TEXHEAD_BL_NORMALIZED_COORDS, true);
|
||||
set_enum!(
|
||||
th,
|
||||
clb097,
|
||||
TEXHEAD_BL_ANISO_FINE_SPREAD_FUNC,
|
||||
SPREAD_FUNC_TWO
|
||||
);
|
||||
set_enum!(
|
||||
th,
|
||||
clb097,
|
||||
TEXHEAD_BL_ANISO_COARSE_SPREAD_FUNC,
|
||||
SPREAD_FUNC_ONE
|
||||
);
|
||||
|
||||
th.set_field(clb097::TEXHEAD_BL_RES_VIEW_MIN_MIP_LEVEL, view.base_level);
|
||||
|
||||
let max_mip_level = view.num_levels + view.base_level - 1;
|
||||
th.set_field(clb097::TEXHEAD_BL_RES_VIEW_MAX_MIP_LEVEL, max_mip_level);
|
||||
|
||||
let msc = nil_rs_to_nvb097_multi_sample_count(image.sample_layout);
|
||||
th.set_field(clb097::TEXHEAD_BL_MULTI_SAMPLE_COUNT, msc);
|
||||
|
||||
let min_lod_clamp = view.min_lod_clamp - (view.base_level as f32);
|
||||
th.set_ufixed(clb097::TEXHEAD_BL_MIN_LOD_CLAMP, min_lod_clamp);
|
||||
}
|
||||
|
||||
pub const IDENTITY_SWIZZLE: [nil_rs_bindings::pipe_swizzle; 4] = [
|
||||
nil_rs_bindings::PIPE_SWIZZLE_X,
|
||||
nil_rs_bindings::PIPE_SWIZZLE_Y,
|
||||
nil_rs_bindings::PIPE_SWIZZLE_Z,
|
||||
nil_rs_bindings::PIPE_SWIZZLE_W,
|
||||
];
|
||||
|
||||
fn nv9097_nil_fill_buffer_tic(
|
||||
base_address: u64,
|
||||
format: Format,
|
||||
num_elements: u32,
|
||||
desc_out: &mut [u32; 8],
|
||||
) {
|
||||
*desc_out = [0u32; 8];
|
||||
let mut th = BitMutView::new(desc_out);
|
||||
th.set_field(cl9097::TEXHEADV2_USE_TEXTURE_HEADER_VERSION2, true);
|
||||
|
||||
assert!(format.supports_buffer());
|
||||
nv9097_set_th_v2_0(&mut th, &format, IDENTITY_SWIZZLE);
|
||||
|
||||
th.set_field(cl9097::TEXHEADV2_OFFSET_LOWER, base_address as u32);
|
||||
th.set_field(cl9097::TEXHEADV2_OFFSET_UPPER, (base_address >> 32) as u32);
|
||||
|
||||
set_enum!(th, cl9097, TEXHEADV2_MEMORY_LAYOUT, PITCH);
|
||||
|
||||
th.set_field(cl9097::TEXHEADV2_WIDTH, num_elements);
|
||||
|
||||
set_enum!(th, cl9097, TEXHEADV2_TEXTURE_TYPE, ONE_D_BUFFER);
|
||||
}
|
||||
|
||||
fn nvb097_nil_fill_buffer_tic(
|
||||
base_address: u64,
|
||||
format: Format,
|
||||
num_elements: u32,
|
||||
desc_out: &mut [u32; 8],
|
||||
) {
|
||||
*desc_out = [0u32; 8];
|
||||
let mut th = BitMutView::new(desc_out);
|
||||
|
||||
assert!(format.supports_buffer());
|
||||
nvb097_set_th_bl_0(&mut th, &format, IDENTITY_SWIZZLE);
|
||||
|
||||
th.set_field(clb097::TEXHEAD_1D_ADDRESS_BITS31TO0, base_address as u32);
|
||||
th.set_field(clb097::TEXHEAD_1D_ADDRESS_BITS47TO32, base_address >> 32);
|
||||
|
||||
set_enum!(th, clb097, TEXHEAD_1D_HEADER_VERSION, SELECT_ONE_D_BUFFER);
|
||||
|
||||
th.set_field(
|
||||
clb097::TEXHEAD_1D_WIDTH_MINUS_ONE_BITS15TO0,
|
||||
(num_elements - 1) & 0xffff,
|
||||
);
|
||||
th.set_field(
|
||||
clb097::TEXHEAD_1D_WIDTH_MINUS_ONE_BITS31TO16,
|
||||
(num_elements - 1) >> 16,
|
||||
);
|
||||
|
||||
set_enum!(th, clb097, TEXHEAD_1D_TEXTURE_TYPE, ONE_D_BUFFER);
|
||||
|
||||
// TODO: Do we need this?
|
||||
set_enum!(th, clb097, TEXHEAD_1D_SECTOR_PROMOTION, PROMOTE_TO_2_V);
|
||||
}
|
||||
|
||||
impl Image {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn nil_image_fill_tic(
|
||||
&self,
|
||||
dev: &nil_rs_bindings::nv_device_info,
|
||||
view: &View,
|
||||
base_address: u64,
|
||||
desc_out: &mut [u32; 8],
|
||||
) {
|
||||
self.fill_tic(dev, view, base_address, desc_out);
|
||||
}
|
||||
|
||||
pub fn fill_tic(
|
||||
&self,
|
||||
dev: &nil_rs_bindings::nv_device_info,
|
||||
view: &View,
|
||||
base_address: u64,
|
||||
desc_out: &mut [u32; 8],
|
||||
) {
|
||||
if dev.cls_eng3d >= MAXWELL_A {
|
||||
nvb097_fill_tic(dev, self, view, base_address, desc_out);
|
||||
} else if dev.cls_eng3d >= FERMI_A {
|
||||
nv9097_fill_tic(self, view, base_address, desc_out);
|
||||
} else {
|
||||
panic!("Tesla and older not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn nil_buffer_fill_tic(
|
||||
dev: &nil_rs_bindings::nv_device_info,
|
||||
base_address: u64,
|
||||
format: Format,
|
||||
num_elements: u32,
|
||||
desc_out: &mut [u32; 8],
|
||||
) {
|
||||
fill_buffer_tic(dev, base_address, format, num_elements, desc_out);
|
||||
}
|
||||
|
||||
pub fn fill_buffer_tic(
|
||||
dev: &nil_rs_bindings::nv_device_info,
|
||||
base_address: u64,
|
||||
format: Format,
|
||||
num_elements: u32,
|
||||
desc_out: &mut [u32; 8],
|
||||
) {
|
||||
if dev.cls_eng3d >= MAXWELL_A {
|
||||
nvb097_nil_fill_buffer_tic(base_address, format, num_elements, desc_out)
|
||||
} else if dev.cls_eng3d >= FERMI_A {
|
||||
nv9097_nil_fill_buffer_tic(base_address, format, num_elements, desc_out)
|
||||
} else {
|
||||
panic!("Tesla and older not supported");
|
||||
}
|
||||
}
|
||||
|
|
@ -57,8 +57,8 @@ nvk_CreateBufferView(VkDevice _device,
|
|||
uint32_t desc[8];
|
||||
nil_buffer_fill_tic(&nvk_device_physical(device)->info,
|
||||
nvk_buffer_address(buffer, view->vk.offset),
|
||||
vk_format_to_pipe_format(view->vk.format),
|
||||
view->vk.elements, desc);
|
||||
nil_format(vk_format_to_pipe_format(view->vk.format)),
|
||||
view->vk.elements, &desc);
|
||||
|
||||
result = nvk_descriptor_table_add(device, &device->images,
|
||||
desc, sizeof(desc), &view->desc_index);
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ image_3d_view_as_2d_array(struct nil_image *image,
|
|||
struct nil_view *view,
|
||||
uint64_t *base_addr)
|
||||
{
|
||||
assert(view->type == NIL_VIEW_TYPE_2D ||
|
||||
view->type == NIL_VIEW_TYPE_2D_ARRAY);
|
||||
assert(view->view_type == NIL_VIEW_TYPE_2D ||
|
||||
view->view_type == NIL_VIEW_TYPE_2D_ARRAY);
|
||||
assert(view->num_levels == 1);
|
||||
|
||||
uint64_t offset_B;
|
||||
|
|
@ -102,6 +102,7 @@ nvk_image_view_init(struct nvk_device *dev,
|
|||
bool driver_internal,
|
||||
const VkImageViewCreateInfo *pCreateInfo)
|
||||
{
|
||||
struct nvk_physical_device *pdev = nvk_device_physical(dev);
|
||||
VK_FROM_HANDLE(nvk_image, image, pCreateInfo->image);
|
||||
VkResult result;
|
||||
|
||||
|
|
@ -149,8 +150,8 @@ nvk_image_view_init(struct nvk_device *dev,
|
|||
p_format = get_stencil_format(p_format);
|
||||
|
||||
struct nil_view nil_view = {
|
||||
.type = vk_image_view_type_to_nil_view_type(view->vk.view_type),
|
||||
.format = p_format,
|
||||
.view_type = vk_image_view_type_to_nil_view_type(view->vk.view_type),
|
||||
.format = nil_format(p_format),
|
||||
.base_level = view->vk.base_mip_level,
|
||||
.num_levels = view->vk.level_count,
|
||||
.base_array_layer = view->vk.base_array_layer,
|
||||
|
|
@ -165,11 +166,11 @@ nvk_image_view_init(struct nvk_device *dev,
|
|||
};
|
||||
|
||||
if (util_format_is_compressed(nil_image.format.p_format) &&
|
||||
!util_format_is_compressed(nil_view.format))
|
||||
!util_format_is_compressed(nil_view.format.p_format))
|
||||
image_uncompressed_view(&nil_image, &nil_view, &base_addr);
|
||||
|
||||
if (nil_image.dim == NIL_IMAGE_DIM_3D &&
|
||||
nil_view.type != NIL_VIEW_TYPE_3D)
|
||||
nil_view.view_type != NIL_VIEW_TYPE_3D)
|
||||
image_3d_view_as_2d_array(&nil_image, &nil_view, &base_addr);
|
||||
|
||||
view->planes[view_plane].sample_layout = nil_image.sample_layout;
|
||||
|
|
@ -177,8 +178,8 @@ nvk_image_view_init(struct nvk_device *dev,
|
|||
if (view->vk.usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
|
||||
uint32_t tic[8];
|
||||
nil_image_fill_tic(&nvk_device_physical(dev)->info,
|
||||
&nil_image, &nil_view, base_addr, tic);
|
||||
nil_image_fill_tic(&nil_image, &pdev->info,
|
||||
&nil_view, base_addr, &tic);
|
||||
|
||||
result = nvk_descriptor_table_add(dev, &dev->images, tic, sizeof(tic),
|
||||
&view->planes[view_plane].sampled_desc_index);
|
||||
|
|
@ -192,7 +193,7 @@ nvk_image_view_init(struct nvk_device *dev,
|
|||
/* For storage images, we can't have any cubes */
|
||||
if (view->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE ||
|
||||
view->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
|
||||
nil_view.type = NIL_VIEW_TYPE_2D_ARRAY;
|
||||
nil_view.view_type = NIL_VIEW_TYPE_2D_ARRAY;
|
||||
|
||||
if (view->vk.view_type == VK_IMAGE_VIEW_TYPE_3D) {
|
||||
/* Without VK_AMD_shader_image_load_store_lod, the client can only
|
||||
|
|
@ -205,7 +206,7 @@ nvk_image_view_init(struct nvk_device *dev,
|
|||
|
||||
if (view->vk.storage.z_slice_offset > 0 ||
|
||||
view->vk.storage.z_slice_count < nil_image.extent_px.depth) {
|
||||
nil_view.type = NIL_VIEW_TYPE_3D_SLICED;
|
||||
nil_view.view_type = NIL_VIEW_TYPE_3D_SLICED;
|
||||
nil_view.base_array_layer = view->vk.storage.z_slice_offset;
|
||||
nil_view.array_len = view->vk.storage.z_slice_count;
|
||||
}
|
||||
|
|
@ -215,8 +216,8 @@ nvk_image_view_init(struct nvk_device *dev,
|
|||
nil_image = nil_msaa_image_as_sa(&nil_image);
|
||||
|
||||
uint32_t tic[8];
|
||||
nil_image_fill_tic(&nvk_device_physical(dev)->info,
|
||||
&nil_image, &nil_view, base_addr, tic);
|
||||
nil_image_fill_tic(&nil_image, &pdev->info, &nil_view,
|
||||
base_addr, &tic);
|
||||
|
||||
result = nvk_descriptor_table_add(dev, &dev->images, tic, sizeof(tic),
|
||||
&view->planes[view_plane].storage_desc_index);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue