1 /*
2 * Copyright © 2022 Collabora Ltd.
3 * SPDX-License-Identifier: MIT
4 */
5 #include "nil_image.h"
6
7 #include "nil_format.h"
8 #include "util/bitpack_helpers.h"
9
10 #include "nouveau_device.h"
11
12 #include "cl9097.h"
13 #include "cl9097tex.h"
14 #include "clb097.h"
15 #include "clb097tex.h"
16 #include "drf.h"
17
18 ALWAYS_INLINE static void
__set_u32(uint32_t * o,uint32_t v,unsigned lo,unsigned hi)19 __set_u32(uint32_t *o, uint32_t v, unsigned lo, unsigned hi)
20 {
21 assert(lo <= hi && (lo / 32) == (hi / 32));
22 o[lo / 32] |= util_bitpack_uint(v, lo % 32, hi % 32);
23 }
24
25 #define FIXED_FRAC_BITS 8
26
27 ALWAYS_INLINE static void
__set_ufixed(uint32_t * o,float v,unsigned lo,unsigned hi)28 __set_ufixed(uint32_t *o, float v, unsigned lo, unsigned hi)
29 {
30 assert(lo <= hi && (lo / 32) == (hi / 32));
31 o[lo / 32] |= util_bitpack_ufixed_clamp(v, lo % 32, hi % 32,
32 FIXED_FRAC_BITS);
33 }
34
35 ALWAYS_INLINE static void
__set_i32(uint32_t * o,int32_t v,unsigned lo,unsigned hi)36 __set_i32(uint32_t *o, int32_t v, unsigned lo, unsigned hi)
37 {
38 assert(lo <= hi && (lo / 32) == (hi / 32));
39 o[lo / 32] |= util_bitpack_sint(v, lo % 32, hi % 32);
40 }
41
42 ALWAYS_INLINE static void
__set_bool(uint32_t * o,bool b,unsigned lo,unsigned hi)43 __set_bool(uint32_t *o, bool b, unsigned lo, unsigned hi)
44 {
45 assert(lo == hi);
46 o[lo / 32] |= util_bitpack_uint(b, lo % 32, hi % 32);
47 }
48
49 #define MW(x) x
50
51 #define TH_SET_U(o, NV, VER, FIELD, val) \
52 __set_u32((o), (val), DRF_LO(NV##_TEXHEAD##VER##_##FIELD),\
53 DRF_HI(NV##_TEXHEAD##VER##_##FIELD))
54
55 #define TH_SET_UF(o, NV, VER, FIELD, val) \
56 __set_ufixed((o), (val), DRF_LO(NV##_TEXHEAD##VER##_##FIELD),\
57 DRF_HI(NV##_TEXHEAD##VER##_##FIELD))
58
59 #define TH_SET_I(o, NV, VER, FIELD, val) \
60 __set_i32((o), (val), DRF_LO(NV##_TEXHEAD##VER##_##FIELD),\
61 DRF_HI(NV##_TEXHEAD##VER##_##FIELD))
62
63 #define TH_SET_B(o, NV, VER, FIELD, b) \
64 __set_bool((o), (b), DRF_LO(NV##_TEXHEAD##VER##_##FIELD),\
65 DRF_HI(NV##_TEXHEAD##VER##_##FIELD))
66
67 #define TH_SET_E(o, NV, VER, FIELD, E) \
68 TH_SET_U((o), NV, VER, FIELD, NV##_TEXHEAD##VER##_##FIELD##_##E)
69
70 #define TH_NV9097_SET_U(o, IDX, FIELD, val) \
71 TH_SET_U(&(o)[IDX], NV9097, V2_##IDX, FIELD, (val));
72 #define TH_NV9097_SET_UF(o, IDX, FIELD, val) \
73 TH_SET_UF(&(o)[IDX], NV9097, V2_##IDX, FIELD, (val));
74 #define TH_NV9097_SET_I(o, IDX, FIELD, val) \
75 TH_SET_I(&(o)[IDX], NV9097, V2_##IDX, FIELD, (val));
76 #define TH_NV9097_SET_B(o, IDX, FIELD, b) \
77 TH_SET_B(&(o)[IDX], NV9097, V2_##IDX, FIELD, (b));
78 #define TH_NV9097_SET_E(o, IDX, FIELD, E) \
79 TH_SET_E(&(o)[IDX], NV9097, V2_##IDX, FIELD, E);
80
81 #define TH_NVB097_SET_U(o, VER, FIELD, val) \
82 TH_SET_U((o), NVB097, _##VER, FIELD, (val));
83 #define TH_NVB097_SET_UF(o, VER, FIELD, val) \
84 TH_SET_UF((o), NVB097, _##VER, FIELD, (val));
85 #define TH_NVB097_SET_I(o, VER, FIELD, val) \
86 TH_SET_I((o), NVB097, _##VER, FIELD, (val));
87 #define TH_NVB097_SET_B(o, VER, FIELD, b) \
88 TH_SET_B((o), NVB097, _##VER, FIELD, (b));
89 #define TH_NVB097_SET_E(o, VER, FIELD, E) \
90 TH_SET_E((o), NVB097, _##VER, FIELD, E);
91
92 static inline uint32_t
nv9097_th_bl_source(const struct nil_tic_format * fmt,enum pipe_swizzle swz,bool is_int)93 nv9097_th_bl_source(const struct nil_tic_format *fmt,
94 enum pipe_swizzle swz, bool is_int)
95 {
96 switch (swz) {
97 case PIPE_SWIZZLE_X: return fmt->src_x;
98 case PIPE_SWIZZLE_Y: return fmt->src_y;
99 case PIPE_SWIZZLE_Z: return fmt->src_z;
100 case PIPE_SWIZZLE_W: return fmt->src_w;
101 case PIPE_SWIZZLE_0:
102 return NV9097_TEXHEADV2_0_X_SOURCE_IN_ZERO;
103 case PIPE_SWIZZLE_1:
104 return is_int ? NV9097_TEXHEADV2_0_X_SOURCE_IN_ONE_INT :
105 NV9097_TEXHEADV2_0_X_SOURCE_IN_ONE_FLOAT;
106 default:
107 unreachable("Invalid component swizzle");
108 }
109 }
110
111 static inline uint32_t
nvb097_th_bl_source(const struct nil_tic_format * fmt,enum pipe_swizzle swz,bool is_int)112 nvb097_th_bl_source(const struct nil_tic_format *fmt,
113 enum pipe_swizzle swz, bool is_int)
114 {
115 switch (swz) {
116 case PIPE_SWIZZLE_X: return fmt->src_x;
117 case PIPE_SWIZZLE_Y: return fmt->src_y;
118 case PIPE_SWIZZLE_Z: return fmt->src_z;
119 case PIPE_SWIZZLE_W: return fmt->src_w;
120 case PIPE_SWIZZLE_0:
121 return NVB097_TEXHEAD_BL_X_SOURCE_IN_ZERO;
122 case PIPE_SWIZZLE_1:
123 return is_int ? NVB097_TEXHEAD_BL_X_SOURCE_IN_ONE_INT :
124 NVB097_TEXHEAD_BL_X_SOURCE_IN_ONE_FLOAT;
125 default:
126 unreachable("Invalid component swizzle");
127 }
128 }
129
130 static uint32_t
nv9097_th_bl_0(enum pipe_format format,const enum pipe_swizzle swizzle[4])131 nv9097_th_bl_0(enum pipe_format format, const enum pipe_swizzle swizzle[4])
132 {
133 const struct nil_tic_format *fmt = nil_tic_format_for_pipe(format);
134 const bool is_int = util_format_is_pure_integer(format);
135
136 uint32_t source[4];
137 for (unsigned i = 0; i < 4; i++)
138 source[i] = nvb097_th_bl_source(fmt, swizzle[i], is_int);
139
140 uint32_t th_0 = 0;
141 TH_NV9097_SET_U(&th_0, 0, COMPONENT_SIZES, fmt->comp_sizes);
142 TH_NV9097_SET_U(&th_0, 0, R_DATA_TYPE, fmt->type_r);
143 TH_NV9097_SET_U(&th_0, 0, G_DATA_TYPE, fmt->type_g);
144 TH_NV9097_SET_U(&th_0, 0, B_DATA_TYPE, fmt->type_b);
145 TH_NV9097_SET_U(&th_0, 0, A_DATA_TYPE, fmt->type_a);
146 TH_NV9097_SET_U(&th_0, 0, X_SOURCE, source[0]);
147 TH_NV9097_SET_U(&th_0, 0, Y_SOURCE, source[1]);
148 TH_NV9097_SET_U(&th_0, 0, Z_SOURCE, source[2]);
149 TH_NV9097_SET_U(&th_0, 0, W_SOURCE, source[3]);
150
151 return th_0;
152 }
153
154 static uint32_t
nvb097_th_bl_0(enum pipe_format format,const enum pipe_swizzle swizzle[4])155 nvb097_th_bl_0(enum pipe_format format, const enum pipe_swizzle swizzle[4])
156 {
157 const struct nil_tic_format *fmt = nil_tic_format_for_pipe(format);
158 const bool is_int = util_format_is_pure_integer(format);
159
160 uint32_t source[4];
161 for (unsigned i = 0; i < 4; i++)
162 source[i] = nvb097_th_bl_source(fmt, swizzle[i], is_int);
163
164 uint32_t th_0 = 0;
165 TH_NVB097_SET_U(&th_0, BL, COMPONENTS, fmt->comp_sizes);
166 TH_NVB097_SET_U(&th_0, BL, R_DATA_TYPE, fmt->type_r);
167 TH_NVB097_SET_U(&th_0, BL, G_DATA_TYPE, fmt->type_g);
168 TH_NVB097_SET_U(&th_0, BL, B_DATA_TYPE, fmt->type_b);
169 TH_NVB097_SET_U(&th_0, BL, A_DATA_TYPE, fmt->type_a);
170 TH_NVB097_SET_U(&th_0, BL, X_SOURCE, source[0]);
171 TH_NVB097_SET_U(&th_0, BL, Y_SOURCE, source[1]);
172 TH_NVB097_SET_U(&th_0, BL, Z_SOURCE, source[2]);
173 TH_NVB097_SET_U(&th_0, BL, W_SOURCE, source[3]);
174
175 return th_0;
176 }
177
178 static uint32_t
pipe_to_nv_texture_type(enum nil_view_type type)179 pipe_to_nv_texture_type(enum nil_view_type type)
180 {
181 #define CASE(NIL, NV) \
182 case NIL_VIEW_TYPE_##NIL: return NVB097_TEXHEAD_BL_TEXTURE_TYPE_##NV; \
183 STATIC_ASSERT(NVB097_TEXHEAD_BL_TEXTURE_TYPE_##NV == NV9097_TEXHEADV2_2_TEXTURE_TYPE_##NV);
184
185 switch (type) {
186 CASE(1D, ONE_D);
187 CASE(2D, TWO_D);
188 CASE(3D, THREE_D);
189 CASE(CUBE, CUBEMAP);
190 CASE(1D_ARRAY, ONE_D_ARRAY);
191 CASE(2D_ARRAY, TWO_D_ARRAY);
192 CASE(CUBE_ARRAY, CUBEMAP_ARRAY);
193 default: unreachable("Invalid image view type");
194 }
195
196 #undef CASE
197 }
198
199 static uint32_t
nil_to_nv9097_multi_sample_count(enum nil_sample_layout sample_layout)200 nil_to_nv9097_multi_sample_count(enum nil_sample_layout sample_layout)
201 {
202 #define CASE(SIZE) \
203 case NIL_SAMPLE_LAYOUT_##SIZE: \
204 return NV9097_TEXHEADV2_7_MULTI_SAMPLE_COUNT_MODE_##SIZE
205
206 switch (sample_layout) {
207 CASE(1X1);
208 CASE(2X1);
209 CASE(2X2);
210 CASE(4X2);
211 CASE(4X4);
212 default:
213 unreachable("Invalid sample layout");
214 }
215
216 #undef CASE
217 }
218
219 static uint32_t
nil_to_nvb097_multi_sample_count(enum nil_sample_layout sample_layout)220 nil_to_nvb097_multi_sample_count(enum nil_sample_layout sample_layout)
221 {
222 #define CASE(SIZE) \
223 case NIL_SAMPLE_LAYOUT_##SIZE: \
224 return NVB097_TEXHEAD_BL_MULTI_SAMPLE_COUNT_MODE_##SIZE
225
226 switch (sample_layout) {
227 CASE(1X1);
228 CASE(2X1);
229 CASE(2X2);
230 CASE(4X2);
231 CASE(4X4);
232 default:
233 unreachable("Invalid sample layout");
234 }
235
236 #undef CASE
237 }
238
239 static inline uint32_t
nil_max_mip_level(const struct nil_image * image,const struct nil_view * view)240 nil_max_mip_level(const struct nil_image *image,
241 const struct nil_view *view)
242 {
243 if (view->type != NIL_VIEW_TYPE_3D && view->array_len == 1 &&
244 view->base_level == 0 && view->num_levels == 1) {
245 /* The Unnormalized coordinates bit in the sampler gets ignored if the
246 * referenced image has more than one miplevel. Fortunately, Vulkan has
247 * restrictions requiring the view to be a single-layer single-LOD view
248 * in order to use nonnormalizedCoordinates = VK_TRUE in the sampler.
249 * From the Vulkan 1.3.255 spec:
250 *
251 * "When unnormalizedCoordinates is VK_TRUE, images the sampler is
252 * used with in the shader have the following requirements:
253 *
254 * - The viewType must be either VK_IMAGE_VIEW_TYPE_1D or
255 * VK_IMAGE_VIEW_TYPE_2D.
256 * - The image view must have a single layer and a single mip
257 * level."
258 *
259 * Under these conditions, the view is simply LOD 0 of a single array
260 * slice so we don't need to care about aray stride between slices so
261 * it's safe to set the number of miplevels to 0 regardless of how many
262 * the image actually has.
263 */
264 return 0;
265 } else {
266 return image->num_levels - 1;
267 }
268 }
269
270 static struct nil_extent4d
nil_normalize_extent(const struct nil_image * image,const struct nil_view * view)271 nil_normalize_extent(const struct nil_image *image,
272 const struct nil_view *view)
273 {
274 struct nil_extent4d extent;
275
276 extent.width = image->extent_px.width;
277 extent.height = image->extent_px.height;
278 extent.array_len = 0;
279
280 switch (view->type) {
281 case NIL_VIEW_TYPE_1D:
282 case NIL_VIEW_TYPE_1D_ARRAY:
283 case NIL_VIEW_TYPE_2D:
284 case NIL_VIEW_TYPE_2D_ARRAY:
285 assert(image->extent_px.depth == 1);
286 extent.depth = view->array_len;
287 break;
288 case NIL_VIEW_TYPE_CUBE:
289 case NIL_VIEW_TYPE_CUBE_ARRAY:
290 assert(image->dim == NIL_IMAGE_DIM_2D);
291 assert(view->array_len % 6 == 0);
292 extent.depth = view->array_len / 6;
293 break;
294 case NIL_VIEW_TYPE_3D:
295 assert(image->dim == NIL_IMAGE_DIM_3D);
296 extent.depth = image->extent_px.depth;
297 break;
298 default:
299 unreachable("Unsupported image view target");
300 };
301
302 return extent;
303 }
304
305 static void
nv9097_nil_image_fill_tic(const struct nil_image * image,const struct nil_view * view,uint64_t base_address,void * desc_out)306 nv9097_nil_image_fill_tic(const struct nil_image *image,
307 const struct nil_view *view,
308 uint64_t base_address,
309 void *desc_out)
310 {
311 assert(util_format_get_blocksize(image->format) ==
312 util_format_get_blocksize(view->format));
313 assert(view->base_level + view->num_levels <= image->num_levels);
314 assert(view->base_array_layer + view->array_len <= image->extent_px.a);
315
316 uint32_t th[8] = { };
317
318 TH_NV9097_SET_B(th, 4, USE_TEXTURE_HEADER_VERSION2, true);
319
320 th[0] = nv9097_th_bl_0(view->format, view->swizzle);
321
322 /* There's no base layer field in the texture header */
323 const uint64_t layer_address =
324 base_address + view->base_array_layer * image->array_stride_B;
325 TH_NV9097_SET_U(th, 1, OFFSET_LOWER, layer_address & 0xffffffff);
326 TH_NV9097_SET_U(th, 2, OFFSET_UPPER, layer_address >> 32);
327
328 const struct nil_tiling *tiling = &image->levels[0].tiling;
329 if (tiling->is_tiled) {
330 TH_NV9097_SET_E(th, 2, MEMORY_LAYOUT, BLOCKLINEAR);
331
332 assert(tiling->gob_height_8);
333 TH_NV9097_SET_E(th, 2, GOBS_PER_BLOCK_WIDTH, ONE_GOB);
334 TH_NV9097_SET_U(th, 2, GOBS_PER_BLOCK_HEIGHT, tiling->y_log2);
335 TH_NV9097_SET_U(th, 2, GOBS_PER_BLOCK_DEPTH, tiling->z_log2);
336
337 TH_NV9097_SET_U(th, 2, TEXTURE_TYPE, pipe_to_nv_texture_type(view->type));
338 } else {
339 TH_NV9097_SET_E(th, 2, MEMORY_LAYOUT, PITCH);
340
341 uint32_t pitch = image->levels[0].row_stride_B;
342 TH_NV9097_SET_U(th, 3, PITCH, pitch);
343
344 assert(view->type == NIL_VIEW_TYPE_2D ||
345 view->type == NIL_VIEW_TYPE_2D_ARRAY);
346 assert(image->sample_layout == NIL_SAMPLE_LAYOUT_1X1);
347 assert(view->num_levels == 1);
348 TH_NV9097_SET_E(th, 2, TEXTURE_TYPE, TWO_D_NO_MIPMAP);
349 }
350
351 TH_NV9097_SET_E(th, 3, LOD_ANISO_QUALITY, LOD_QUALITY_HIGH);
352 TH_NV9097_SET_E(th, 3, LOD_ISO_QUALITY, LOD_QUALITY_HIGH);
353 TH_NV9097_SET_E(th, 3, ANISO_COARSE_SPREAD_MODIFIER, SPREAD_MODIFIER_NONE);
354
355 const struct nil_extent4d extent = nil_normalize_extent(image, view);
356 TH_NV9097_SET_U(th, 4, WIDTH, extent.width);
357 TH_NV9097_SET_U(th, 5, HEIGHT, extent.height);
358 TH_NV9097_SET_U(th, 5, DEPTH, extent.depth);
359
360 TH_NV9097_SET_U(th, 5, MAX_MIP_LEVEL, nil_max_mip_level(image, view));
361
362 TH_NV9097_SET_B(th, 2, S_R_G_B_CONVERSION,
363 util_format_is_srgb(view->format));
364
365 TH_NV9097_SET_E(th, 2, BORDER_SOURCE, BORDER_COLOR);
366
367 /* In the sampler, the two options for FLOAT_COORD_NORMALIZATION are:
368 *
369 * - FORCE_UNNORMALIZED_COORDS
370 * - USE_HEADER_SETTING
371 *
372 * So we set it to normalized in the header and let the sampler select
373 * that or force non-normalized.
374 */
375 TH_NV9097_SET_B(th, 2, NORMALIZED_COORDS, true);
376
377 TH_NV9097_SET_E(th, 6, ANISO_FINE_SPREAD_FUNC, SPREAD_FUNC_TWO);
378 TH_NV9097_SET_E(th, 6, ANISO_COARSE_SPREAD_FUNC, SPREAD_FUNC_ONE);
379
380 TH_NV9097_SET_U(th, 7, RES_VIEW_MIN_MIP_LEVEL, view->base_level);
381 TH_NV9097_SET_U(th, 7, RES_VIEW_MAX_MIP_LEVEL,
382 view->num_levels + view->base_level - 1);
383
384 TH_NV9097_SET_U(th, 7, MULTI_SAMPLE_COUNT,
385 nil_to_nv9097_multi_sample_count(image->sample_layout));
386
387 TH_NV9097_SET_UF(th, 7, MIN_LOD_CLAMP,
388 view->min_lod_clamp - view->base_level);
389
390 memcpy(desc_out, th, sizeof(th));
391 }
392
393 static void
nvb097_nil_image_fill_tic(const struct nil_image * image,const struct nil_view * view,uint64_t base_address,void * desc_out)394 nvb097_nil_image_fill_tic(const struct nil_image *image,
395 const struct nil_view *view,
396 uint64_t base_address,
397 void *desc_out)
398 {
399 assert(util_format_get_blocksize(image->format) ==
400 util_format_get_blocksize(view->format));
401 assert(view->base_level + view->num_levels <= image->num_levels);
402 assert(view->base_array_layer + view->array_len <= image->extent_px.a);
403
404 uint32_t th[8] = { };
405
406 th[0] = nvb097_th_bl_0(view->format, view->swizzle);
407
408 /* There's no base layer field in the texture header */
409 const uint64_t layer_address =
410 base_address + view->base_array_layer * image->array_stride_B;
411 const struct nil_tiling *tiling = &image->levels[0].tiling;
412
413 if (tiling->is_tiled) {
414 TH_NVB097_SET_E(th, BL, HEADER_VERSION, SELECT_BLOCKLINEAR);
415
416 assert((layer_address & BITFIELD_MASK(9)) == 0);
417 TH_NVB097_SET_U(th, BL, ADDRESS_BITS31TO9, (uint32_t)layer_address >> 9);
418 TH_NVB097_SET_U(th, BL, ADDRESS_BITS47TO32, layer_address >> 32);
419
420 assert(tiling->gob_height_8);
421 TH_NVB097_SET_E(th, BL, GOBS_PER_BLOCK_WIDTH, ONE_GOB);
422 TH_NVB097_SET_U(th, BL, GOBS_PER_BLOCK_HEIGHT, tiling->y_log2);
423 TH_NVB097_SET_U(th, BL, GOBS_PER_BLOCK_DEPTH, tiling->z_log2);
424
425 TH_NVB097_SET_U(th, BL, TEXTURE_TYPE, pipe_to_nv_texture_type(view->type));
426 } else {
427 TH_NVB097_SET_E(th, PITCH, HEADER_VERSION, SELECT_PITCH);
428
429 assert((layer_address & BITFIELD_MASK(5)) == 0);
430 TH_NVB097_SET_U(th, PITCH, ADDRESS_BITS31TO5,
431 (uint32_t)layer_address >> 5);
432 TH_NVB097_SET_U(th, PITCH, ADDRESS_BITS47TO32,
433 layer_address >> 32);
434
435 uint32_t pitch = image->levels[0].row_stride_B;
436 assert((pitch & BITFIELD_MASK(5)) == 0);
437 TH_NVB097_SET_U(th, PITCH, PITCH_BITS20TO5, pitch >> 5);
438
439 assert(view->type == NIL_VIEW_TYPE_2D ||
440 view->type == NIL_VIEW_TYPE_2D_ARRAY);
441 assert(image->sample_layout == NIL_SAMPLE_LAYOUT_1X1);
442 assert(view->num_levels == 1);
443 TH_NVB097_SET_E(th, PITCH, TEXTURE_TYPE, TWO_D_NO_MIPMAP);
444 }
445
446 TH_NVB097_SET_B(th, BL, LOD_ANISO_QUALITY2, true);
447 TH_NVB097_SET_E(th, BL, LOD_ANISO_QUALITY, LOD_QUALITY_HIGH);
448 TH_NVB097_SET_E(th, BL, LOD_ISO_QUALITY, LOD_QUALITY_HIGH);
449 TH_NVB097_SET_E(th, BL, ANISO_COARSE_SPREAD_MODIFIER, SPREAD_MODIFIER_NONE);
450
451 const struct nil_extent4d extent = nil_normalize_extent(image, view);
452 TH_NVB097_SET_U(th, BL, WIDTH_MINUS_ONE, extent.width - 1);
453 TH_NVB097_SET_U(th, BL, HEIGHT_MINUS_ONE, extent.height - 1);
454 TH_NVB097_SET_U(th, BL, DEPTH_MINUS_ONE, extent.depth - 1);
455
456 TH_NVB097_SET_U(th, BL, MAX_MIP_LEVEL, nil_max_mip_level(image, view));
457
458 TH_NVB097_SET_B(th, BL, S_R_G_B_CONVERSION,
459 util_format_is_srgb(view->format));
460
461 TH_NVB097_SET_E(th, BL, SECTOR_PROMOTION, PROMOTE_TO_2_V);
462 TH_NVB097_SET_E(th, BL, BORDER_SIZE, BORDER_SAMPLER_COLOR);
463
464 /* In the sampler, the two options for FLOAT_COORD_NORMALIZATION are:
465 *
466 * - FORCE_UNNORMALIZED_COORDS
467 * - USE_HEADER_SETTING
468 *
469 * So we set it to normalized in the header and let the sampler select
470 * that or force non-normalized.
471 */
472 TH_NVB097_SET_B(th, BL, NORMALIZED_COORDS, true);
473
474 TH_NVB097_SET_E(th, BL, ANISO_FINE_SPREAD_FUNC, SPREAD_FUNC_TWO);
475 TH_NVB097_SET_E(th, BL, ANISO_COARSE_SPREAD_FUNC, SPREAD_FUNC_ONE);
476
477 TH_NVB097_SET_U(th, BL, RES_VIEW_MIN_MIP_LEVEL, view->base_level);
478 TH_NVB097_SET_U(th, BL, RES_VIEW_MAX_MIP_LEVEL,
479 view->num_levels + view->base_level - 1);
480
481 TH_NVB097_SET_U(th, BL, MULTI_SAMPLE_COUNT,
482 nil_to_nvb097_multi_sample_count(image->sample_layout));
483
484 TH_NVB097_SET_UF(th, BL, MIN_LOD_CLAMP,
485 view->min_lod_clamp - view->base_level);
486
487 memcpy(desc_out, th, sizeof(th));
488 }
489
490 static const enum pipe_swizzle IDENTITY_SWIZZLE[4] = {
491 PIPE_SWIZZLE_X,
492 PIPE_SWIZZLE_Y,
493 PIPE_SWIZZLE_Z,
494 PIPE_SWIZZLE_W,
495 };
496
497 static void
nv9097_nil_buffer_fill_tic(uint64_t base_address,enum pipe_format format,uint32_t num_elements,void * desc_out)498 nv9097_nil_buffer_fill_tic(uint64_t base_address,
499 enum pipe_format format,
500 uint32_t num_elements,
501 void *desc_out)
502 {
503 uint32_t th[8] = { };
504
505 TH_NV9097_SET_B(th, 4, USE_TEXTURE_HEADER_VERSION2, true);
506
507 assert(!util_format_is_compressed(format));
508 th[0] = nv9097_th_bl_0(format, IDENTITY_SWIZZLE);
509
510 TH_NV9097_SET_U(th, 1, OFFSET_LOWER, base_address);
511 TH_NV9097_SET_U(th, 2, OFFSET_UPPER, base_address >> 32);
512 TH_NV9097_SET_E(th, 2, MEMORY_LAYOUT, PITCH);
513
514 TH_NV9097_SET_U(th, 4, WIDTH, num_elements);
515 TH_NV9097_SET_E(th, 2, TEXTURE_TYPE, ONE_D_BUFFER);
516
517
518 memcpy(desc_out, th, sizeof(th));
519 }
520
521 static void
nvb097_nil_buffer_fill_tic(uint64_t base_address,enum pipe_format format,uint32_t num_elements,void * desc_out)522 nvb097_nil_buffer_fill_tic(uint64_t base_address,
523 enum pipe_format format,
524 uint32_t num_elements,
525 void *desc_out)
526 {
527 uint32_t th[8] = { };
528
529 assert(!util_format_is_compressed(format));
530 th[0] = nvb097_th_bl_0(format, IDENTITY_SWIZZLE);
531
532 TH_NVB097_SET_U(th, 1D, ADDRESS_BITS31TO0, base_address);
533 TH_NVB097_SET_U(th, 1D, ADDRESS_BITS47TO32, base_address >> 32);
534 TH_NVB097_SET_E(th, 1D, HEADER_VERSION, SELECT_ONE_D_BUFFER);
535
536 TH_NVB097_SET_U(th, 1D, WIDTH_MINUS_ONE_BITS15TO0,
537 (num_elements - 1) & 0xffff);
538 TH_NVB097_SET_U(th, 1D, WIDTH_MINUS_ONE_BITS31TO16,
539 (num_elements - 1) >> 16);
540
541 TH_NVB097_SET_E(th, 1D, TEXTURE_TYPE, ONE_D_BUFFER);
542
543 /* TODO: Do we need this? */
544 TH_NVB097_SET_E(th, 1D, SECTOR_PROMOTION, PROMOTE_TO_2_V);
545
546 memcpy(desc_out, th, sizeof(th));
547 }
548
549 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)550 nil_image_fill_tic(struct nv_device_info *dev,
551 const struct nil_image *image,
552 const struct nil_view *view,
553 uint64_t base_address,
554 void *desc_out)
555 {
556 if (dev->cls_eng3d >= MAXWELL_A) {
557 nvb097_nil_image_fill_tic(image, view, base_address, desc_out);
558 } else if (dev->cls_eng3d >= FERMI_A) {
559 nv9097_nil_image_fill_tic(image, view, base_address, desc_out);
560 } else {
561 unreachable("Tesla and older not supported");
562 }
563 }
564
565 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)566 nil_buffer_fill_tic(struct nv_device_info *dev,
567 uint64_t base_address,
568 enum pipe_format format,
569 uint32_t num_elements,
570 void *desc_out)
571 {
572 if (dev->cls_eng3d >= MAXWELL_A) {
573 nvb097_nil_buffer_fill_tic(base_address, format, num_elements, desc_out);
574 } else if (dev->cls_eng3d >= FERMI_A) {
575 nv9097_nil_buffer_fill_tic(base_address, format, num_elements, desc_out);
576 } else {
577 unreachable("Tesla and older not supported");
578 }
579 }
580