i965/drm: Rename drm_bacon_bo to brw_bo.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_sampler_state.c
1 /*
2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics to
4 develop this 3D driver.
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **********************************************************************/
27 /*
28 * Authors:
29 * Keith Whitwell <keithw@vmware.com>
30 */
31
32 /**
33 * @file brw_sampler_state.c
34 *
35 * This file contains code for emitting SAMPLER_STATE structures, which
36 * specifies filter modes, wrap modes, border color, and so on.
37 */
38
39 #include "brw_context.h"
40 #include "brw_state.h"
41 #include "brw_defines.h"
42 #include "intel_batchbuffer.h"
43 #include "intel_mipmap_tree.h"
44
45 #include "main/macros.h"
46 #include "main/samplerobj.h"
47 #include "util/half_float.h"
48
49 /**
50 * Emit a 3DSTATE_SAMPLER_STATE_POINTERS_{VS,HS,GS,DS,PS} packet.
51 */
52 static void
53 gen7_emit_sampler_state_pointers_xs(struct brw_context *brw,
54 struct brw_stage_state *stage_state)
55 {
56 static const uint16_t packet_headers[] = {
57 [MESA_SHADER_VERTEX] = _3DSTATE_SAMPLER_STATE_POINTERS_VS,
58 [MESA_SHADER_TESS_CTRL] = _3DSTATE_SAMPLER_STATE_POINTERS_HS,
59 [MESA_SHADER_TESS_EVAL] = _3DSTATE_SAMPLER_STATE_POINTERS_DS,
60 [MESA_SHADER_GEOMETRY] = _3DSTATE_SAMPLER_STATE_POINTERS_GS,
61 [MESA_SHADER_FRAGMENT] = _3DSTATE_SAMPLER_STATE_POINTERS_PS,
62 };
63
64 /* Ivybridge requires a workaround flush before VS packets. */
65 if (brw->gen == 7 && !brw->is_haswell && !brw->is_baytrail &&
66 stage_state->stage == MESA_SHADER_VERTEX) {
67 gen7_emit_vs_workaround_flush(brw);
68 }
69
70 BEGIN_BATCH(2);
71 OUT_BATCH(packet_headers[stage_state->stage] << 16 | (2 - 2));
72 OUT_BATCH(stage_state->sampler_offset);
73 ADVANCE_BATCH();
74 }
75
76 /**
77 * Emit a SAMPLER_STATE structure, given all the fields.
78 */
79 void
80 brw_emit_sampler_state(struct brw_context *brw,
81 uint32_t *ss,
82 uint32_t batch_offset_for_sampler_state,
83 unsigned min_filter,
84 unsigned mag_filter,
85 unsigned mip_filter,
86 unsigned max_anisotropy,
87 unsigned address_rounding,
88 unsigned wrap_s,
89 unsigned wrap_t,
90 unsigned wrap_r,
91 unsigned base_level,
92 unsigned min_lod,
93 unsigned max_lod,
94 int lod_bias,
95 unsigned shadow_function,
96 bool non_normalized_coordinates,
97 uint32_t border_color_offset)
98 {
99 ss[0] = BRW_SAMPLER_LOD_PRECLAMP_ENABLE |
100 SET_FIELD(mip_filter, BRW_SAMPLER_MIP_FILTER) |
101 SET_FIELD(mag_filter, BRW_SAMPLER_MAG_FILTER) |
102 SET_FIELD(min_filter, BRW_SAMPLER_MIN_FILTER);
103
104 ss[2] = border_color_offset;
105 if (brw->gen < 6) {
106 ss[2] += brw->batch.bo->offset64; /* reloc */
107 brw_emit_reloc(&brw->batch, batch_offset_for_sampler_state + 8,
108 brw->batch.bo, border_color_offset,
109 I915_GEM_DOMAIN_SAMPLER, 0);
110 }
111
112 ss[3] = SET_FIELD(max_anisotropy, BRW_SAMPLER_MAX_ANISOTROPY) |
113 SET_FIELD(address_rounding, BRW_SAMPLER_ADDRESS_ROUNDING);
114
115 if (brw->gen >= 7) {
116 ss[0] |= SET_FIELD(lod_bias & 0x1fff, GEN7_SAMPLER_LOD_BIAS);
117
118 if (min_filter == BRW_MAPFILTER_ANISOTROPIC)
119 ss[0] |= GEN7_SAMPLER_EWA_ANISOTROPIC_ALGORITHM;
120
121 ss[1] = SET_FIELD(min_lod, GEN7_SAMPLER_MIN_LOD) |
122 SET_FIELD(max_lod, GEN7_SAMPLER_MAX_LOD) |
123 SET_FIELD(shadow_function, GEN7_SAMPLER_SHADOW_FUNCTION);
124
125 ss[3] |= SET_FIELD(wrap_s, BRW_SAMPLER_TCX_WRAP_MODE) |
126 SET_FIELD(wrap_t, BRW_SAMPLER_TCY_WRAP_MODE) |
127 SET_FIELD(wrap_r, BRW_SAMPLER_TCZ_WRAP_MODE);
128
129 if (non_normalized_coordinates)
130 ss[3] |= GEN7_SAMPLER_NON_NORMALIZED_COORDINATES;
131 } else {
132 ss[0] |= SET_FIELD(lod_bias & 0x7ff, GEN4_SAMPLER_LOD_BIAS) |
133 SET_FIELD(shadow_function, GEN4_SAMPLER_SHADOW_FUNCTION);
134
135 /* This field has existed since the original i965, but is declared MBZ
136 * until Sandy Bridge. According to the PRM:
137 *
138 * "This was added to match OpenGL semantics"
139 *
140 * In particular, OpenGL allowed you to offset by 0.5 in certain cases
141 * to get slightly better filtering. On Ivy Bridge and above, it
142 * appears that this is added to RENDER_SURFACE_STATE::SurfaceMinLOD so
143 * the right value is 0.0 or 0.5 (if you want the wacky behavior). On
144 * Sandy Bridge, however, this sum does not seem to occur and you have
145 * to set it to the actual base level of the texture.
146 */
147 if (brw->gen == 6)
148 ss[0] |= SET_FIELD(base_level, BRW_SAMPLER_BASE_MIPLEVEL);
149
150 if (brw->gen == 6 && min_filter != mag_filter)
151 ss[0] |= GEN6_SAMPLER_MIN_MAG_NOT_EQUAL;
152
153 ss[1] = SET_FIELD(min_lod, GEN4_SAMPLER_MIN_LOD) |
154 SET_FIELD(max_lod, GEN4_SAMPLER_MAX_LOD) |
155 SET_FIELD(wrap_s, BRW_SAMPLER_TCX_WRAP_MODE) |
156 SET_FIELD(wrap_t, BRW_SAMPLER_TCY_WRAP_MODE) |
157 SET_FIELD(wrap_r, BRW_SAMPLER_TCZ_WRAP_MODE);
158
159 if (brw->gen >= 6 && non_normalized_coordinates)
160 ss[3] |= GEN6_SAMPLER_NON_NORMALIZED_COORDINATES;
161 }
162 }
163
164 static uint32_t
165 translate_wrap_mode(struct brw_context *brw, GLenum wrap, bool using_nearest)
166 {
167 switch (wrap) {
168 case GL_REPEAT:
169 return BRW_TEXCOORDMODE_WRAP;
170 case GL_CLAMP:
171 /* GL_CLAMP is the weird mode where coordinates are clamped to
172 * [0.0, 1.0], so linear filtering of coordinates outside of
173 * [0.0, 1.0] give you half edge texel value and half border
174 * color.
175 *
176 * Gen8+ supports this natively.
177 */
178 if (brw->gen >= 8)
179 return GEN8_TEXCOORDMODE_HALF_BORDER;
180
181 /* On Gen4-7.5, we clamp the coordinates in the fragment shader
182 * and set clamp_border here, which gets the result desired.
183 * We just use clamp(_to_edge) for nearest, because for nearest
184 * clamping to 1.0 gives border color instead of the desired
185 * edge texels.
186 */
187 if (using_nearest)
188 return BRW_TEXCOORDMODE_CLAMP;
189 else
190 return BRW_TEXCOORDMODE_CLAMP_BORDER;
191 case GL_CLAMP_TO_EDGE:
192 return BRW_TEXCOORDMODE_CLAMP;
193 case GL_CLAMP_TO_BORDER:
194 return BRW_TEXCOORDMODE_CLAMP_BORDER;
195 case GL_MIRRORED_REPEAT:
196 return BRW_TEXCOORDMODE_MIRROR;
197 case GL_MIRROR_CLAMP_TO_EDGE:
198 return BRW_TEXCOORDMODE_MIRROR_ONCE;
199 default:
200 return BRW_TEXCOORDMODE_WRAP;
201 }
202 }
203
204 /**
205 * Return true if the given wrap mode requires the border color to exist.
206 */
207 static bool
208 wrap_mode_needs_border_color(unsigned wrap_mode)
209 {
210 return wrap_mode == BRW_TEXCOORDMODE_CLAMP_BORDER ||
211 wrap_mode == GEN8_TEXCOORDMODE_HALF_BORDER;
212 }
213
214 static bool
215 has_component(mesa_format format, int i)
216 {
217 if (_mesa_is_format_color_format(format))
218 return _mesa_format_has_color_component(format, i);
219
220 /* depth and stencil have only one component */
221 return i == 0;
222 }
223
224 /**
225 * Upload SAMPLER_BORDER_COLOR_STATE.
226 */
227 static void
228 upload_default_color(struct brw_context *brw,
229 const struct gl_sampler_object *sampler,
230 mesa_format format, GLenum base_format,
231 bool is_integer_format, bool is_stencil_sampling,
232 uint32_t *sdc_offset)
233 {
234 union gl_color_union color;
235
236 switch (base_format) {
237 case GL_DEPTH_COMPONENT:
238 /* GL specs that border color for depth textures is taken from the
239 * R channel, while the hardware uses A. Spam R into all the
240 * channels for safety.
241 */
242 color.ui[0] = sampler->BorderColor.ui[0];
243 color.ui[1] = sampler->BorderColor.ui[0];
244 color.ui[2] = sampler->BorderColor.ui[0];
245 color.ui[3] = sampler->BorderColor.ui[0];
246 break;
247 case GL_ALPHA:
248 color.ui[0] = 0u;
249 color.ui[1] = 0u;
250 color.ui[2] = 0u;
251 color.ui[3] = sampler->BorderColor.ui[3];
252 break;
253 case GL_INTENSITY:
254 color.ui[0] = sampler->BorderColor.ui[0];
255 color.ui[1] = sampler->BorderColor.ui[0];
256 color.ui[2] = sampler->BorderColor.ui[0];
257 color.ui[3] = sampler->BorderColor.ui[0];
258 break;
259 case GL_LUMINANCE:
260 color.ui[0] = sampler->BorderColor.ui[0];
261 color.ui[1] = sampler->BorderColor.ui[0];
262 color.ui[2] = sampler->BorderColor.ui[0];
263 color.ui[3] = float_as_int(1.0);
264 break;
265 case GL_LUMINANCE_ALPHA:
266 color.ui[0] = sampler->BorderColor.ui[0];
267 color.ui[1] = sampler->BorderColor.ui[0];
268 color.ui[2] = sampler->BorderColor.ui[0];
269 color.ui[3] = sampler->BorderColor.ui[3];
270 break;
271 default:
272 color.ui[0] = sampler->BorderColor.ui[0];
273 color.ui[1] = sampler->BorderColor.ui[1];
274 color.ui[2] = sampler->BorderColor.ui[2];
275 color.ui[3] = sampler->BorderColor.ui[3];
276 break;
277 }
278
279 /* In some cases we use an RGBA surface format for GL RGB textures,
280 * where we've initialized the A channel to 1.0. We also have to set
281 * the border color alpha to 1.0 in that case.
282 */
283 if (base_format == GL_RGB)
284 color.ui[3] = float_as_int(1.0);
285
286 if (brw->gen >= 8) {
287 /* On Broadwell, the border color is represented as four 32-bit floats,
288 * integers, or unsigned values, interpreted according to the surface
289 * format. This matches the sampler->BorderColor union exactly; just
290 * memcpy the values.
291 */
292 uint32_t *sdc = brw_state_batch(brw, 4 * 4, 64, sdc_offset);
293 memcpy(sdc, color.ui, 4 * 4);
294 } else if (brw->is_haswell && (is_integer_format || is_stencil_sampling)) {
295 /* Haswell's integer border color support is completely insane:
296 * SAMPLER_BORDER_COLOR_STATE is 20 DWords. The first four are
297 * for float colors. The next 12 DWords are MBZ and only exist to
298 * pad it out to a 64 byte cacheline boundary. DWords 16-19 then
299 * contain integer colors; these are only used if SURFACE_STATE
300 * has the "Integer Surface Format" bit set. Even then, the
301 * arrangement of the RGBA data devolves into madness.
302 */
303 uint32_t *sdc = brw_state_batch(brw, 20 * 4, 512, sdc_offset);
304 memset(sdc, 0, 20 * 4);
305 sdc = &sdc[16];
306
307 bool stencil = format == MESA_FORMAT_S_UINT8 || is_stencil_sampling;
308 const int bits_per_channel =
309 _mesa_get_format_bits(format, stencil ? GL_STENCIL_BITS : GL_RED_BITS);
310
311 /* From the Haswell PRM, "Command Reference: Structures", Page 36:
312 * "If any color channel is missing from the surface format,
313 * corresponding border color should be programmed as zero and if
314 * alpha channel is missing, corresponding Alpha border color should
315 * be programmed as 1."
316 */
317 unsigned c[4] = { 0, 0, 0, 1 };
318 for (int i = 0; i < 4; i++) {
319 if (has_component(format, i))
320 c[i] = color.ui[i];
321 }
322
323 switch (bits_per_channel) {
324 case 8:
325 /* Copy RGBA in order. */
326 for (int i = 0; i < 4; i++)
327 ((uint8_t *) sdc)[i] = c[i];
328 break;
329 case 10:
330 /* R10G10B10A2_UINT is treated like a 16-bit format. */
331 case 16:
332 ((uint16_t *) sdc)[0] = c[0]; /* R -> DWord 0, bits 15:0 */
333 ((uint16_t *) sdc)[1] = c[1]; /* G -> DWord 0, bits 31:16 */
334 /* DWord 1 is Reserved/MBZ! */
335 ((uint16_t *) sdc)[4] = c[2]; /* B -> DWord 2, bits 15:0 */
336 ((uint16_t *) sdc)[5] = c[3]; /* A -> DWord 3, bits 31:16 */
337 break;
338 case 32:
339 if (base_format == GL_RG) {
340 /* Careful inspection of the tables reveals that for RG32 formats,
341 * the green channel needs to go where blue normally belongs.
342 */
343 sdc[0] = c[0];
344 sdc[2] = c[1];
345 sdc[3] = 1;
346 } else {
347 /* Copy RGBA in order. */
348 for (int i = 0; i < 4; i++)
349 sdc[i] = c[i];
350 }
351 break;
352 default:
353 assert(!"Invalid number of bits per channel in integer format.");
354 break;
355 }
356 } else if (brw->gen == 5 || brw->gen == 6) {
357 struct gen5_sampler_default_color *sdc;
358
359 sdc = brw_state_batch(brw, sizeof(*sdc), 32, sdc_offset);
360
361 memset(sdc, 0, sizeof(*sdc));
362
363 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[0], color.f[0]);
364 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[1], color.f[1]);
365 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[2], color.f[2]);
366 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[3], color.f[3]);
367
368 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[0], color.f[0]);
369 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[1], color.f[1]);
370 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[2], color.f[2]);
371 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[3], color.f[3]);
372
373 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[0], color.f[0]);
374 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[1], color.f[1]);
375 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[2], color.f[2]);
376 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[3], color.f[3]);
377
378 sdc->hf[0] = _mesa_float_to_half(color.f[0]);
379 sdc->hf[1] = _mesa_float_to_half(color.f[1]);
380 sdc->hf[2] = _mesa_float_to_half(color.f[2]);
381 sdc->hf[3] = _mesa_float_to_half(color.f[3]);
382
383 sdc->b[0] = sdc->s[0] >> 8;
384 sdc->b[1] = sdc->s[1] >> 8;
385 sdc->b[2] = sdc->s[2] >> 8;
386 sdc->b[3] = sdc->s[3] >> 8;
387
388 sdc->f[0] = color.f[0];
389 sdc->f[1] = color.f[1];
390 sdc->f[2] = color.f[2];
391 sdc->f[3] = color.f[3];
392 } else {
393 float *sdc = brw_state_batch(brw, 4 * 4, 32, sdc_offset);
394 memcpy(sdc, color.f, 4 * 4);
395 }
396 }
397
398 /**
399 * Sets the sampler state for a single unit based off of the sampler key
400 * entry.
401 */
402 static void
403 brw_update_sampler_state(struct brw_context *brw,
404 GLenum target, bool tex_cube_map_seamless,
405 GLfloat tex_unit_lod_bias,
406 mesa_format format, GLenum base_format,
407 const struct gl_texture_object *texObj,
408 const struct gl_sampler_object *sampler,
409 uint32_t *sampler_state,
410 uint32_t batch_offset_for_sampler_state)
411 {
412 unsigned min_filter, mag_filter, mip_filter;
413
414 /* Select min and mip filters. */
415 switch (sampler->MinFilter) {
416 case GL_NEAREST:
417 min_filter = BRW_MAPFILTER_NEAREST;
418 mip_filter = BRW_MIPFILTER_NONE;
419 break;
420 case GL_LINEAR:
421 min_filter = BRW_MAPFILTER_LINEAR;
422 mip_filter = BRW_MIPFILTER_NONE;
423 break;
424 case GL_NEAREST_MIPMAP_NEAREST:
425 min_filter = BRW_MAPFILTER_NEAREST;
426 mip_filter = BRW_MIPFILTER_NEAREST;
427 break;
428 case GL_LINEAR_MIPMAP_NEAREST:
429 min_filter = BRW_MAPFILTER_LINEAR;
430 mip_filter = BRW_MIPFILTER_NEAREST;
431 break;
432 case GL_NEAREST_MIPMAP_LINEAR:
433 min_filter = BRW_MAPFILTER_NEAREST;
434 mip_filter = BRW_MIPFILTER_LINEAR;
435 break;
436 case GL_LINEAR_MIPMAP_LINEAR:
437 min_filter = BRW_MAPFILTER_LINEAR;
438 mip_filter = BRW_MIPFILTER_LINEAR;
439 break;
440 default:
441 unreachable("not reached");
442 }
443
444 /* Select mag filter. */
445 if (sampler->MagFilter == GL_LINEAR)
446 mag_filter = BRW_MAPFILTER_LINEAR;
447 else
448 mag_filter = BRW_MAPFILTER_NEAREST;
449
450 /* Enable anisotropic filtering if desired. */
451 unsigned max_anisotropy = BRW_ANISORATIO_2;
452 if (sampler->MaxAnisotropy > 1.0f) {
453 min_filter = BRW_MAPFILTER_ANISOTROPIC;
454 mag_filter = BRW_MAPFILTER_ANISOTROPIC;
455
456 if (sampler->MaxAnisotropy > 2.0f) {
457 max_anisotropy =
458 MIN2((sampler->MaxAnisotropy - 2) / 2, BRW_ANISORATIO_16);
459 }
460 }
461
462 /* Set address rounding bits if not using nearest filtering. */
463 unsigned address_rounding = 0;
464 if (min_filter != BRW_MAPFILTER_NEAREST) {
465 address_rounding |= BRW_ADDRESS_ROUNDING_ENABLE_U_MIN |
466 BRW_ADDRESS_ROUNDING_ENABLE_V_MIN |
467 BRW_ADDRESS_ROUNDING_ENABLE_R_MIN;
468 }
469 if (mag_filter != BRW_MAPFILTER_NEAREST) {
470 address_rounding |= BRW_ADDRESS_ROUNDING_ENABLE_U_MAG |
471 BRW_ADDRESS_ROUNDING_ENABLE_V_MAG |
472 BRW_ADDRESS_ROUNDING_ENABLE_R_MAG;
473 }
474
475 bool either_nearest =
476 sampler->MinFilter == GL_NEAREST || sampler->MagFilter == GL_NEAREST;
477 unsigned wrap_s = translate_wrap_mode(brw, sampler->WrapS, either_nearest);
478 unsigned wrap_t = translate_wrap_mode(brw, sampler->WrapT, either_nearest);
479 unsigned wrap_r = translate_wrap_mode(brw, sampler->WrapR, either_nearest);
480
481 if (target == GL_TEXTURE_CUBE_MAP ||
482 target == GL_TEXTURE_CUBE_MAP_ARRAY) {
483 /* Cube maps must use the same wrap mode for all three coordinate
484 * dimensions. Prior to Haswell, only CUBE and CLAMP are valid.
485 *
486 * Ivybridge and Baytrail seem to have problems with CUBE mode and
487 * integer formats. Fall back to CLAMP for now.
488 */
489 if ((tex_cube_map_seamless || sampler->CubeMapSeamless) &&
490 !(brw->gen == 7 && !brw->is_haswell && texObj->_IsIntegerFormat)) {
491 wrap_s = BRW_TEXCOORDMODE_CUBE;
492 wrap_t = BRW_TEXCOORDMODE_CUBE;
493 wrap_r = BRW_TEXCOORDMODE_CUBE;
494 } else {
495 wrap_s = BRW_TEXCOORDMODE_CLAMP;
496 wrap_t = BRW_TEXCOORDMODE_CLAMP;
497 wrap_r = BRW_TEXCOORDMODE_CLAMP;
498 }
499 } else if (target == GL_TEXTURE_1D) {
500 /* There's a bug in 1D texture sampling - it actually pays
501 * attention to the wrap_t value, though it should not.
502 * Override the wrap_t value here to GL_REPEAT to keep
503 * any nonexistent border pixels from floating in.
504 */
505 wrap_t = BRW_TEXCOORDMODE_WRAP;
506 }
507
508 /* Set shadow function. */
509 unsigned shadow_function = 0;
510 if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
511 shadow_function =
512 intel_translate_shadow_compare_func(sampler->CompareFunc);
513 }
514
515 const int lod_bits = brw->gen >= 7 ? 8 : 6;
516 const float hw_max_lod = brw->gen >= 7 ? 14 : 13;
517 const unsigned base_level =
518 U_FIXED(CLAMP(texObj->MinLevel + texObj->BaseLevel, 0, hw_max_lod), 1);
519 const unsigned min_lod =
520 U_FIXED(CLAMP(sampler->MinLod, 0, hw_max_lod), lod_bits);
521 const unsigned max_lod =
522 U_FIXED(CLAMP(sampler->MaxLod, 0, hw_max_lod), lod_bits);
523 const int lod_bias =
524 S_FIXED(CLAMP(tex_unit_lod_bias + sampler->LodBias, -16, 15), lod_bits);
525
526 /* Upload the border color if necessary. If not, just point it at
527 * offset 0 (the start of the batch) - the color should be ignored,
528 * but that address won't fault in case something reads it anyway.
529 */
530 uint32_t border_color_offset = 0;
531 if (wrap_mode_needs_border_color(wrap_s) ||
532 wrap_mode_needs_border_color(wrap_t) ||
533 wrap_mode_needs_border_color(wrap_r)) {
534 upload_default_color(brw, sampler, format, base_format,
535 texObj->_IsIntegerFormat, texObj->StencilSampling,
536 &border_color_offset);
537 }
538
539 const bool non_normalized_coords = target == GL_TEXTURE_RECTANGLE;
540
541 brw_emit_sampler_state(brw,
542 sampler_state,
543 batch_offset_for_sampler_state,
544 min_filter, mag_filter, mip_filter,
545 max_anisotropy,
546 address_rounding,
547 wrap_s, wrap_t, wrap_r,
548 base_level, min_lod, max_lod, lod_bias,
549 shadow_function,
550 non_normalized_coords,
551 border_color_offset);
552 }
553
554 static void
555 update_sampler_state(struct brw_context *brw,
556 int unit,
557 uint32_t *sampler_state,
558 uint32_t batch_offset_for_sampler_state)
559 {
560 struct gl_context *ctx = &brw->ctx;
561 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
562 const struct gl_texture_object *texObj = texUnit->_Current;
563 const struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
564
565 /* These don't use samplers at all. */
566 if (texObj->Target == GL_TEXTURE_BUFFER)
567 return;
568
569 struct gl_texture_image *firstImage = texObj->Image[0][texObj->BaseLevel];
570 brw_update_sampler_state(brw, texObj->Target, ctx->Texture.CubeMapSeamless,
571 texUnit->LodBias,
572 firstImage->TexFormat, firstImage->_BaseFormat,
573 texObj, sampler,
574 sampler_state, batch_offset_for_sampler_state);
575 }
576
577 static void
578 brw_upload_sampler_state_table(struct brw_context *brw,
579 struct gl_program *prog,
580 struct brw_stage_state *stage_state)
581 {
582 struct gl_context *ctx = &brw->ctx;
583 uint32_t sampler_count = stage_state->sampler_count;
584
585 GLbitfield SamplersUsed = prog->SamplersUsed;
586
587 if (sampler_count == 0)
588 return;
589
590 /* SAMPLER_STATE is 4 DWords on all platforms. */
591 const int dwords = 4;
592 const int size_in_bytes = dwords * sizeof(uint32_t);
593
594 uint32_t *sampler_state = brw_state_batch(brw,
595 sampler_count * size_in_bytes,
596 32, &stage_state->sampler_offset);
597 memset(sampler_state, 0, sampler_count * size_in_bytes);
598
599 uint32_t batch_offset_for_sampler_state = stage_state->sampler_offset;
600
601 for (unsigned s = 0; s < sampler_count; s++) {
602 if (SamplersUsed & (1 << s)) {
603 const unsigned unit = prog->SamplerUnits[s];
604 if (ctx->Texture.Unit[unit]._Current) {
605 update_sampler_state(brw, unit, sampler_state,
606 batch_offset_for_sampler_state);
607 }
608 }
609
610 sampler_state += dwords;
611 batch_offset_for_sampler_state += size_in_bytes;
612 }
613
614 if (brw->gen >= 7 && stage_state->stage != MESA_SHADER_COMPUTE) {
615 /* Emit a 3DSTATE_SAMPLER_STATE_POINTERS_XS packet. */
616 gen7_emit_sampler_state_pointers_xs(brw, stage_state);
617 } else {
618 /* Flag that the sampler state table pointer has changed; later atoms
619 * will handle it.
620 */
621 brw->ctx.NewDriverState |= BRW_NEW_SAMPLER_STATE_TABLE;
622 }
623 }
624
625 static void
626 brw_upload_fs_samplers(struct brw_context *brw)
627 {
628 /* BRW_NEW_FRAGMENT_PROGRAM */
629 struct gl_program *fs = (struct gl_program *) brw->fragment_program;
630 brw_upload_sampler_state_table(brw, fs, &brw->wm.base);
631 }
632
633 const struct brw_tracked_state brw_fs_samplers = {
634 .dirty = {
635 .mesa = _NEW_TEXTURE,
636 .brw = BRW_NEW_BATCH |
637 BRW_NEW_BLORP |
638 BRW_NEW_FRAGMENT_PROGRAM,
639 },
640 .emit = brw_upload_fs_samplers,
641 };
642
643 static void
644 brw_upload_vs_samplers(struct brw_context *brw)
645 {
646 /* BRW_NEW_VERTEX_PROGRAM */
647 struct gl_program *vs = (struct gl_program *) brw->vertex_program;
648 brw_upload_sampler_state_table(brw, vs, &brw->vs.base);
649 }
650
651
652 const struct brw_tracked_state brw_vs_samplers = {
653 .dirty = {
654 .mesa = _NEW_TEXTURE,
655 .brw = BRW_NEW_BATCH |
656 BRW_NEW_BLORP |
657 BRW_NEW_VERTEX_PROGRAM,
658 },
659 .emit = brw_upload_vs_samplers,
660 };
661
662
663 static void
664 brw_upload_gs_samplers(struct brw_context *brw)
665 {
666 /* BRW_NEW_GEOMETRY_PROGRAM */
667 struct gl_program *gs = (struct gl_program *) brw->geometry_program;
668 if (!gs)
669 return;
670
671 brw_upload_sampler_state_table(brw, gs, &brw->gs.base);
672 }
673
674
675 const struct brw_tracked_state brw_gs_samplers = {
676 .dirty = {
677 .mesa = _NEW_TEXTURE,
678 .brw = BRW_NEW_BATCH |
679 BRW_NEW_BLORP |
680 BRW_NEW_GEOMETRY_PROGRAM,
681 },
682 .emit = brw_upload_gs_samplers,
683 };
684
685
686 static void
687 brw_upload_tcs_samplers(struct brw_context *brw)
688 {
689 /* BRW_NEW_TESS_PROGRAMS */
690 struct gl_program *tcs = (struct gl_program *) brw->tess_ctrl_program;
691 if (!tcs)
692 return;
693
694 brw_upload_sampler_state_table(brw, tcs, &brw->tcs.base);
695 }
696
697
698 const struct brw_tracked_state brw_tcs_samplers = {
699 .dirty = {
700 .mesa = _NEW_TEXTURE,
701 .brw = BRW_NEW_BATCH |
702 BRW_NEW_BLORP |
703 BRW_NEW_TESS_PROGRAMS,
704 },
705 .emit = brw_upload_tcs_samplers,
706 };
707
708
709 static void
710 brw_upload_tes_samplers(struct brw_context *brw)
711 {
712 /* BRW_NEW_TESS_PROGRAMS */
713 struct gl_program *tes = (struct gl_program *) brw->tess_eval_program;
714 if (!tes)
715 return;
716
717 brw_upload_sampler_state_table(brw, tes, &brw->tes.base);
718 }
719
720
721 const struct brw_tracked_state brw_tes_samplers = {
722 .dirty = {
723 .mesa = _NEW_TEXTURE,
724 .brw = BRW_NEW_BATCH |
725 BRW_NEW_BLORP |
726 BRW_NEW_TESS_PROGRAMS,
727 },
728 .emit = brw_upload_tes_samplers,
729 };
730
731 static void
732 brw_upload_cs_samplers(struct brw_context *brw)
733 {
734 /* BRW_NEW_COMPUTE_PROGRAM */
735 struct gl_program *cs = (struct gl_program *) brw->compute_program;
736 if (!cs)
737 return;
738
739 brw_upload_sampler_state_table(brw, cs, &brw->cs.base);
740 }
741
742 const struct brw_tracked_state brw_cs_samplers = {
743 .dirty = {
744 .mesa = _NEW_TEXTURE,
745 .brw = BRW_NEW_BATCH |
746 BRW_NEW_BLORP |
747 BRW_NEW_COMPUTE_PROGRAM,
748 },
749 .emit = brw_upload_cs_samplers,
750 };