Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/microsoft/compiler/dxil_nir_lower_int_samplers.c
4564 views
1
/*
2
* Copyright © Microsoft Corporation
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* on the rights to use, copy, modify, merge, publish, distribute, sub
8
* license, and/or sell copies of the Software, and to permit persons to whom
9
* the Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21
* USE OR OTHER DEALINGS IN THE SOFTWARE.
22
*/
23
24
#include "dxil_nir_lower_int_samplers.h"
25
#include "nir_builder.h"
26
#include "nir_builtin_builder.h"
27
28
static bool
29
lower_sample_to_txf_for_integer_tex_filter(const nir_instr *instr,
30
UNUSED const void *_options)
31
{
32
if (instr->type != nir_instr_type_tex)
33
return false;
34
35
nir_tex_instr *tex = nir_instr_as_tex(instr);
36
if (tex->op != nir_texop_tex &&
37
tex->op != nir_texop_txb &&
38
tex->op != nir_texop_txl &&
39
tex->op != nir_texop_txd)
40
return false;
41
42
return (tex->dest_type & (nir_type_int | nir_type_uint));
43
}
44
45
static nir_ssa_def *
46
dx_get_texture_lod(nir_builder *b, nir_tex_instr *tex)
47
{
48
nir_tex_instr *tql;
49
50
unsigned num_srcs = 0;
51
for (unsigned i = 0; i < tex->num_srcs; i++) {
52
if (tex->src[i].src_type == nir_tex_src_coord ||
53
tex->src[i].src_type == nir_tex_src_texture_deref ||
54
tex->src[i].src_type == nir_tex_src_sampler_deref ||
55
tex->src[i].src_type == nir_tex_src_texture_offset ||
56
tex->src[i].src_type == nir_tex_src_sampler_offset ||
57
tex->src[i].src_type == nir_tex_src_texture_handle ||
58
tex->src[i].src_type == nir_tex_src_sampler_handle)
59
num_srcs++;
60
}
61
62
tql = nir_tex_instr_create(b->shader, num_srcs);
63
tql->op = nir_texop_lod;
64
unsigned coord_components = tex->coord_components;
65
if (tex->is_array)
66
--coord_components;
67
68
tql->coord_components = coord_components;
69
tql->sampler_dim = tex->sampler_dim;
70
tql->is_shadow = tex->is_shadow;
71
tql->is_new_style_shadow = tex->is_new_style_shadow;
72
tql->texture_index = tex->texture_index;
73
tql->sampler_index = tex->sampler_index;
74
tql->dest_type = nir_type_float32;
75
76
/* The coordinate needs special handling because we might have
77
* to strip the array index. Don't clutter the code with an additional
78
* check for is_array though, in the worst case we create an additional
79
* move the the optimization will remove later again. */
80
int coord_index = nir_tex_instr_src_index(tex, nir_tex_src_coord);
81
nir_ssa_def *ssa_src = nir_channels(b, tex->src[coord_index].src.ssa,
82
(1 << coord_components) - 1);
83
nir_src src = nir_src_for_ssa(ssa_src);
84
nir_src_copy(&tql->src[0].src, &src, tql);
85
tql->src[0].src_type = nir_tex_src_coord;
86
87
unsigned idx = 1;
88
for (unsigned i = 0; i < tex->num_srcs; i++) {
89
if (tex->src[i].src_type == nir_tex_src_texture_deref ||
90
tex->src[i].src_type == nir_tex_src_sampler_deref ||
91
tex->src[i].src_type == nir_tex_src_texture_offset ||
92
tex->src[i].src_type == nir_tex_src_sampler_offset ||
93
tex->src[i].src_type == nir_tex_src_texture_handle ||
94
tex->src[i].src_type == nir_tex_src_sampler_handle) {
95
nir_src_copy(&tql->src[idx].src, &tex->src[i].src, tql);
96
tql->src[idx].src_type = tex->src[i].src_type;
97
idx++;
98
}
99
}
100
101
nir_ssa_dest_init(&tql->instr, &tql->dest, 2, 32, NULL);
102
nir_builder_instr_insert(b, &tql->instr);
103
104
/* DirectX LOD only has a value in x channel */
105
return nir_channel(b, &tql->dest.ssa, 0);
106
}
107
108
typedef struct {
109
nir_ssa_def *coords;
110
nir_ssa_def *use_border_color;
111
} wrap_result_t;
112
113
typedef struct {
114
nir_ssa_def *lod;
115
nir_ssa_def *size;
116
int ncoord_comp;
117
wrap_result_t wrap[3];
118
} wrap_lower_param_t;
119
120
static void
121
wrap_clamp_to_edge(nir_builder *b, wrap_result_t *wrap_params, nir_ssa_def *size)
122
{
123
/* clamp(coord, 0, size - 1) */
124
wrap_params->coords = nir_fmin(b, nir_fsub(b, size, nir_imm_float(b, 1.0f)),
125
nir_fmax(b, wrap_params->coords, nir_imm_float(b, 0.0f)));
126
}
127
128
static void
129
wrap_repeat(nir_builder *b, wrap_result_t *wrap_params, nir_ssa_def *size)
130
{
131
/* mod(coord, size)
132
* This instruction must be exact, otherwise certain sizes result in
133
* incorrect sampling */
134
wrap_params->coords = nir_fmod(b, wrap_params->coords, size);
135
nir_instr_as_alu(wrap_params->coords->parent_instr)->exact = true;
136
}
137
138
static nir_ssa_def *
139
mirror(nir_builder *b, nir_ssa_def *coord)
140
{
141
/* coord if >= 0, otherwise -(1 + coord) */
142
return nir_bcsel(b, nir_fge(b, coord, nir_imm_float(b, 0.0f)), coord,
143
nir_fneg(b, nir_fadd(b, nir_imm_float(b, 1.0f), coord)));
144
}
145
146
static void
147
wrap_mirror_repeat(nir_builder *b, wrap_result_t *wrap_params, nir_ssa_def *size)
148
{
149
/* (size − 1) − mirror(mod(coord, 2 * size) − size) */
150
nir_ssa_def *coord_mod2size = nir_fmod(b, wrap_params->coords, nir_fmul(b, nir_imm_float(b, 2.0f), size));
151
nir_instr_as_alu(coord_mod2size->parent_instr)->exact = true;
152
nir_ssa_def *a = nir_fsub(b, coord_mod2size, size);
153
wrap_params->coords = nir_fsub(b, nir_fsub(b, size, nir_imm_float(b, 1.0f)), mirror(b, a));
154
}
155
156
static void
157
wrap_mirror_clamp_to_edge(nir_builder *b, wrap_result_t *wrap_params, nir_ssa_def *size)
158
{
159
/* clamp(mirror(coord), 0, size - 1) */
160
wrap_params->coords = nir_fmin(b, nir_fsub(b, size, nir_imm_float(b, 1.0f)),
161
nir_fmax(b, mirror(b, wrap_params->coords), nir_imm_float(b, 0.0f)));
162
}
163
164
static void
165
wrap_clamp(nir_builder *b, wrap_result_t *wrap_params, nir_ssa_def *size)
166
{
167
nir_ssa_def *is_low = nir_flt(b, wrap_params->coords, nir_imm_float(b, 0.0));
168
nir_ssa_def *is_high = nir_fge(b, wrap_params->coords, size);
169
wrap_params->use_border_color = nir_ior(b, is_low, is_high);
170
}
171
172
static void
173
wrap_mirror_clamp(nir_builder *b, wrap_result_t *wrap_params, nir_ssa_def *size)
174
{
175
/* We have to take care of the boundaries */
176
nir_ssa_def *is_low = nir_flt(b, wrap_params->coords, nir_fmul(b, size, nir_imm_float(b, -1.0)));
177
nir_ssa_def *is_high = nir_flt(b, nir_fmul(b, size, nir_imm_float(b, 2.0)), wrap_params->coords);
178
wrap_params->use_border_color = nir_ior(b, is_low, is_high);
179
180
/* Within the boundaries this acts like mirror_repeat */
181
wrap_mirror_repeat(b, wrap_params, size);
182
183
}
184
185
static wrap_result_t
186
wrap_coords(nir_builder *b, nir_ssa_def *coords, enum pipe_tex_wrap wrap,
187
nir_ssa_def *size)
188
{
189
wrap_result_t result = {coords, nir_imm_false(b)};
190
191
switch (wrap) {
192
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
193
wrap_clamp_to_edge(b, &result, size);
194
break;
195
case PIPE_TEX_WRAP_REPEAT:
196
wrap_repeat(b, &result, size);
197
break;
198
case PIPE_TEX_WRAP_MIRROR_REPEAT:
199
wrap_mirror_repeat(b, &result, size);
200
break;
201
case PIPE_TEX_WRAP_MIRROR_CLAMP:
202
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
203
wrap_mirror_clamp_to_edge(b, &result, size);
204
break;
205
case PIPE_TEX_WRAP_CLAMP:
206
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
207
wrap_clamp(b, &result, size);
208
break;
209
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
210
wrap_mirror_clamp(b, &result, size);
211
break;
212
}
213
return result;
214
}
215
216
static nir_ssa_def *
217
load_bordercolor(nir_builder *b, nir_tex_instr *tex, dxil_wrap_sampler_state *active_state,
218
const dxil_texture_swizzle_state *tex_swizzle)
219
{
220
nir_const_value const_value[4] = {{0}};
221
int ndest_comp = nir_dest_num_components(tex->dest);
222
223
unsigned swizzle[4] = {
224
tex_swizzle->swizzle_r,
225
tex_swizzle->swizzle_g,
226
tex_swizzle->swizzle_b,
227
tex_swizzle->swizzle_a
228
};
229
230
for (int i = 0; i < ndest_comp; ++i) {
231
switch (swizzle[i]) {
232
case PIPE_SWIZZLE_0:
233
const_value[i].f32 = 0;
234
break;
235
case PIPE_SWIZZLE_1:
236
const_value[i].i32 = 1;
237
break;
238
case PIPE_SWIZZLE_X:
239
case PIPE_SWIZZLE_Y:
240
case PIPE_SWIZZLE_Z:
241
case PIPE_SWIZZLE_W:
242
const_value[i].f32 = active_state->border_color[swizzle[i]];
243
break;
244
default:
245
unreachable("Unexpected swizzle value");
246
}
247
}
248
249
return nir_build_imm(b, ndest_comp, 32, const_value);
250
}
251
252
static nir_tex_instr *
253
create_txf_from_tex(nir_builder *b, nir_tex_instr *tex)
254
{
255
nir_tex_instr *txf;
256
257
unsigned num_srcs = 0;
258
for (unsigned i = 0; i < tex->num_srcs; i++) {
259
if (tex->src[i].src_type == nir_tex_src_texture_deref ||
260
tex->src[i].src_type == nir_tex_src_texture_offset ||
261
tex->src[i].src_type == nir_tex_src_texture_handle)
262
num_srcs++;
263
}
264
265
txf = nir_tex_instr_create(b->shader, num_srcs);
266
txf->op = nir_texop_txf;
267
txf->sampler_dim = tex->sampler_dim;
268
txf->is_array = tex->is_array;
269
txf->is_shadow = tex->is_shadow;
270
txf->is_new_style_shadow = tex->is_new_style_shadow;
271
txf->texture_index = tex->texture_index;
272
txf->sampler_index = tex->sampler_index;
273
txf->dest_type = tex->dest_type;
274
275
unsigned idx = 0;
276
for (unsigned i = 0; i < tex->num_srcs; i++) {
277
if (tex->src[i].src_type == nir_tex_src_texture_deref ||
278
tex->src[i].src_type == nir_tex_src_texture_offset ||
279
tex->src[i].src_type == nir_tex_src_texture_handle) {
280
nir_src_copy(&txf->src[idx].src, &tex->src[i].src, txf);
281
txf->src[idx].src_type = tex->src[i].src_type;
282
idx++;
283
}
284
}
285
286
nir_ssa_dest_init(&txf->instr, &txf->dest,
287
nir_tex_instr_dest_size(txf), 32, NULL);
288
nir_builder_instr_insert(b, &txf->instr);
289
290
return txf;
291
}
292
293
static nir_ssa_def *
294
load_texel(nir_builder *b, nir_tex_instr *tex, wrap_lower_param_t *params)
295
{
296
nir_ssa_def *texcoord = NULL;
297
298
/* Put coordinates back together */
299
switch (tex->coord_components) {
300
case 1:
301
texcoord = params->wrap[0].coords;
302
break;
303
case 2:
304
texcoord = nir_vec2(b, params->wrap[0].coords, params->wrap[1].coords);
305
break;
306
case 3:
307
texcoord = nir_vec3(b, params->wrap[0].coords, params->wrap[1].coords, params->wrap[2].coords);
308
break;
309
default:
310
;
311
}
312
313
texcoord = nir_f2i32(b, texcoord);
314
315
nir_tex_instr *load = create_txf_from_tex(b, tex);
316
nir_tex_instr_add_src(load, nir_tex_src_lod, nir_src_for_ssa(params->lod));
317
nir_tex_instr_add_src(load, nir_tex_src_coord, nir_src_for_ssa(texcoord));
318
b->cursor = nir_after_instr(&load->instr);
319
return &load->dest.ssa;
320
}
321
322
typedef struct {
323
dxil_wrap_sampler_state *aws;
324
float max_bias;
325
nir_ssa_def *size;
326
int ncoord_comp;
327
} lod_params;
328
329
static nir_ssa_def *
330
evalute_active_lod(nir_builder *b, nir_tex_instr *tex, lod_params *params)
331
{
332
static nir_ssa_def *lod = NULL;
333
334
/* Later we use min_lod for clamping the LOD to a legal value */
335
float min_lod = MAX2(params->aws->min_lod, 0.0f);
336
337
/* Evaluate the LOD to be used for the texel fetch */
338
if (unlikely(tex->op == nir_texop_txl)) {
339
int lod_index = nir_tex_instr_src_index(tex, nir_tex_src_lod);
340
/* if we have an explicite LOD, take it */
341
lod = tex->src[lod_index].src.ssa;
342
} else if (unlikely(tex->op == nir_texop_txd)) {
343
int ddx_index = nir_tex_instr_src_index(tex, nir_tex_src_ddx);
344
int ddy_index = nir_tex_instr_src_index(tex, nir_tex_src_ddy);
345
assert(ddx_index >= 0 && ddy_index >= 0);
346
347
nir_ssa_def *grad = nir_fmax(b,
348
tex->src[ddx_index].src.ssa,
349
tex->src[ddy_index].src.ssa);
350
351
nir_ssa_def *r = nir_fmul(b, grad, nir_i2f32(b, params->size));
352
nir_ssa_def *rho = nir_channel(b, r, 0);
353
for (int i = 1; i < params->ncoord_comp; ++i)
354
rho = nir_fmax(b, rho, nir_channel(b, r, i));
355
lod = nir_flog2(b, rho);
356
} else if (b->shader->info.stage == MESA_SHADER_FRAGMENT){
357
lod = dx_get_texture_lod(b, tex);
358
} else {
359
/* Only fragment shaders provide the gradient information to evaluate a LOD,
360
* so force 0 otherwise */
361
lod = nir_imm_float(b, 0.0);
362
}
363
364
/* Evaluate bias according to OpenGL (4.6 (Compatibility Profile) October 22, 2019),
365
* sec. 8.14.1, eq. (8.9)
366
*
367
* lod' = lambda + CLAMP(bias_texobj + bias_texunit + bias_shader)
368
*
369
* bias_texobj is the value of TEXTURE_LOD_BIAS for the bound texture object. ...
370
* bias_textunt is the value of TEXTURE_LOD_BIAS for the current texture unit, ...
371
* bias shader is the value of the optional bias parameter in the texture
372
* lookup functions available to fragment shaders. ... The sum of these values
373
* is clamped to the range [−bias_max, bias_max] where bias_max is the value
374
* of the implementation defined constant MAX_TEXTURE_LOD_BIAS.
375
* In core contexts the value bias_texunit is dropped from above equation.
376
*
377
* Gallium provides the value lod_bias as the sum of bias_texobj and bias_texunit
378
* in compatibility contexts and as bias_texobj in core contexts, hence the
379
* implementation here is the same in both cases.
380
*/
381
nir_ssa_def *lod_bias = nir_imm_float(b, params->aws->lod_bias);
382
383
if (unlikely(tex->op == nir_texop_txb)) {
384
int bias_index = nir_tex_instr_src_index(tex, nir_tex_src_bias);
385
lod_bias = nir_fadd(b, lod_bias, tex->src[bias_index].src.ssa);
386
}
387
388
lod = nir_fadd(b, lod, nir_fclamp(b, lod_bias,
389
nir_imm_float(b, -params->max_bias),
390
nir_imm_float(b, params->max_bias)));
391
392
/* Clamp lod according to ibid. eq. (8.10) */
393
lod = nir_fmax(b, lod, nir_imm_float(b, min_lod));
394
395
/* If the max lod is > max_bias = log2(max_texture_size), the lod will be clamped
396
* by the number of levels, no need to clamp it againt the max_lod first. */
397
if (params->aws->max_lod <= params->max_bias)
398
lod = nir_fmin(b, lod, nir_imm_float(b, params->aws->max_lod));
399
400
/* Pick nearest LOD */
401
lod = nir_f2i32(b, nir_fround_even(b, lod));
402
403
/* cap actual lod by number of available levels */
404
return nir_imin(b, lod, nir_imm_int(b, params->aws->last_level));
405
}
406
407
typedef struct {
408
dxil_wrap_sampler_state *wrap_states;
409
dxil_texture_swizzle_state *tex_swizzles;
410
float max_bias;
411
} sampler_states;
412
413
414
static nir_ssa_def *
415
lower_sample_to_txf_for_integer_tex_impl(nir_builder *b, nir_instr *instr,
416
void *options)
417
{
418
sampler_states *states = (sampler_states *)options;
419
wrap_lower_param_t params = {0};
420
421
nir_tex_instr *tex = nir_instr_as_tex(instr);
422
dxil_wrap_sampler_state *active_wrap_state = &states->wrap_states[tex->sampler_index];
423
424
b->cursor = nir_before_instr(instr);
425
426
int coord_index = nir_tex_instr_src_index(tex, nir_tex_src_coord);
427
nir_ssa_def *old_coord = tex->src[coord_index].src.ssa;
428
params.ncoord_comp = tex->coord_components;
429
if (tex->is_array)
430
params.ncoord_comp -= 1;
431
432
/* This helper to get the texture size always uses LOD 0, and DirectX doesn't support
433
* giving another LOD when querying the texture size */
434
nir_ssa_def *size0 = nir_get_texture_size(b, tex);
435
436
params.lod = nir_imm_int(b, 0);
437
438
if (active_wrap_state->last_level > 0) {
439
lod_params p = {
440
.aws = active_wrap_state,
441
.max_bias = states->max_bias,
442
.size = size0,
443
.ncoord_comp = params.ncoord_comp
444
};
445
params.lod = evalute_active_lod(b, tex, &p);
446
447
/* Evaluate actual level size*/
448
params.size = nir_i2f32(b, nir_imax(b, nir_ishr(b, size0, params.lod),
449
nir_imm_int(b, 1)));
450
} else {
451
params.size = nir_i2f32(b, size0);
452
}
453
454
nir_ssa_def *new_coord = old_coord;
455
if (!active_wrap_state->is_nonnormalized_coords) {
456
/* Evaluate the integer lookup coordinates for the requested LOD, don't touch the
457
* array index */
458
if (!tex->is_array) {
459
new_coord = nir_fmul(b, params.size, old_coord);
460
} else {
461
nir_ssa_def *array_index = nir_channel(b, old_coord, params.ncoord_comp);
462
int mask = (1 << params.ncoord_comp) - 1;
463
nir_ssa_def *coord = nir_fmul(b, nir_channels(b, params.size, mask),
464
nir_channels(b, old_coord, mask));
465
switch (params.ncoord_comp) {
466
case 1:
467
new_coord = nir_vec2(b, coord, array_index);
468
break;
469
case 2:
470
new_coord = nir_vec3(b, nir_channel(b, coord, 0),
471
nir_channel(b, coord, 1),
472
array_index);
473
break;
474
default:
475
unreachable("unsupported number of non-array coordinates");
476
}
477
}
478
}
479
480
nir_ssa_def *coord_help[3];
481
for (int i = 0; i < params.ncoord_comp; ++i)
482
coord_help[i] = nir_ffloor(b, nir_channel(b, new_coord, i));
483
484
// Note: array index needs to be rounded to nearest before clamp rather than floored
485
if (tex->is_array)
486
coord_help[params.ncoord_comp] = nir_fround_even(b, nir_channel(b, new_coord, params.ncoord_comp));
487
488
/* Correct the texture coordinates for the offsets. */
489
int offset_index = nir_tex_instr_src_index(tex, nir_tex_src_offset);
490
if (offset_index >= 0) {
491
nir_ssa_def *offset = tex->src[offset_index].src.ssa;
492
for (int i = 0; i < params.ncoord_comp; ++i)
493
coord_help[i] = nir_fadd(b, coord_help[i], nir_i2f32(b, nir_channel(b, offset, i)));
494
}
495
496
nir_ssa_def *use_border_color = nir_imm_false(b);
497
498
if (!active_wrap_state->skip_boundary_conditions) {
499
500
for (int i = 0; i < params.ncoord_comp; ++i) {
501
params.wrap[i] = wrap_coords(b, coord_help[i], active_wrap_state->wrap[i], nir_channel(b, params.size, i));
502
use_border_color = nir_ior(b, use_border_color, params.wrap[i].use_border_color);
503
}
504
505
if (tex->is_array)
506
params.wrap[params.ncoord_comp] =
507
wrap_coords(b, coord_help[params.ncoord_comp],
508
PIPE_TEX_WRAP_CLAMP_TO_EDGE,
509
nir_i2f32(b, nir_channel(b, size0, params.ncoord_comp)));
510
} else {
511
/* When we emulate a cube map by using a texture array, the coordinates are always
512
* in range, and we don't have to take care of boundary conditions */
513
for (unsigned i = 0; i < 3; ++i) {
514
params.wrap[i].coords = coord_help[i];
515
params.wrap[i].use_border_color = nir_imm_false(b);
516
}
517
}
518
519
const dxil_texture_swizzle_state one2one = {
520
PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W
521
};
522
523
nir_if *border_if = nir_push_if(b, use_border_color);
524
const dxil_texture_swizzle_state *swizzle = states->tex_swizzles ?
525
&states->tex_swizzles[tex->sampler_index]:
526
&one2one;
527
528
nir_ssa_def *border_color = load_bordercolor(b, tex, active_wrap_state, swizzle);
529
nir_if *border_else = nir_push_else(b, border_if);
530
nir_ssa_def *sampler_color = load_texel(b, tex, &params);
531
nir_pop_if(b, border_else);
532
533
return nir_if_phi(b, border_color, sampler_color);
534
}
535
536
/* Sampling from integer textures is not allowed in DirectX, so we have
537
* to use texel fetches. For this we have to scale the coordiantes
538
* to be integer based, and evaluate the LOD the texel fetch has to be
539
* applied on, and take care of the boundary conditions .
540
*/
541
bool
542
dxil_lower_sample_to_txf_for_integer_tex(nir_shader *s,
543
dxil_wrap_sampler_state *wrap_states,
544
dxil_texture_swizzle_state *tex_swizzles,
545
float max_bias)
546
{
547
sampler_states states = {wrap_states, tex_swizzles, max_bias};
548
549
bool result =
550
nir_shader_lower_instructions(s,
551
lower_sample_to_txf_for_integer_tex_filter,
552
lower_sample_to_txf_for_integer_tex_impl,
553
&states);
554
return result;
555
}
556
557