i965: Refactor SIMD16-to-2xSIMD8 checks.
[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
48 /**
49 * Emit a 3DSTATE_SAMPLER_STATE_POINTERS_{VS,HS,GS,DS,PS} packet.
50 */
51 static void
52 gen7_emit_sampler_state_pointers_xs(struct brw_context *brw,
53 struct brw_stage_state *stage_state)
54 {
55 static const uint16_t packet_headers[] = {
56 [MESA_SHADER_VERTEX] = _3DSTATE_SAMPLER_STATE_POINTERS_VS,
57 [MESA_SHADER_GEOMETRY] = _3DSTATE_SAMPLER_STATE_POINTERS_GS,
58 [MESA_SHADER_FRAGMENT] = _3DSTATE_SAMPLER_STATE_POINTERS_PS,
59 };
60
61 /* Ivybridge requires a workaround flush before VS packets. */
62 if (brw->gen == 7 && !brw->is_haswell && !brw->is_baytrail &&
63 stage_state->stage == MESA_SHADER_VERTEX) {
64 gen7_emit_vs_workaround_flush(brw);
65 }
66
67 BEGIN_BATCH(2);
68 OUT_BATCH(packet_headers[stage_state->stage] << 16 | (2 - 2));
69 OUT_BATCH(stage_state->sampler_offset);
70 ADVANCE_BATCH();
71 }
72
73 /**
74 * Emit a SAMPLER_STATE structure, given all the fields.
75 */
76 void
77 brw_emit_sampler_state(struct brw_context *brw,
78 uint32_t *ss,
79 uint32_t batch_offset_for_sampler_state,
80 unsigned min_filter,
81 unsigned mag_filter,
82 unsigned mip_filter,
83 unsigned max_anisotropy,
84 unsigned address_rounding,
85 unsigned wrap_s,
86 unsigned wrap_t,
87 unsigned wrap_r,
88 unsigned min_lod,
89 unsigned max_lod,
90 int lod_bias,
91 unsigned base_level,
92 unsigned shadow_function,
93 bool non_normalized_coordinates,
94 uint32_t border_color_offset)
95 {
96 ss[0] = BRW_SAMPLER_LOD_PRECLAMP_ENABLE |
97 SET_FIELD(base_level, BRW_SAMPLER_BASE_MIPLEVEL) |
98 SET_FIELD(mip_filter, BRW_SAMPLER_MIP_FILTER) |
99 SET_FIELD(mag_filter, BRW_SAMPLER_MAG_FILTER) |
100 SET_FIELD(min_filter, BRW_SAMPLER_MIN_FILTER);
101
102 ss[2] = border_color_offset;
103 if (brw->gen < 6) {
104 ss[2] += brw->batch.bo->offset64; /* reloc */
105 drm_intel_bo_emit_reloc(brw->batch.bo,
106 batch_offset_for_sampler_state + 8,
107 brw->batch.bo, border_color_offset,
108 I915_GEM_DOMAIN_SAMPLER, 0);
109 }
110
111 ss[3] = SET_FIELD(max_anisotropy, BRW_SAMPLER_MAX_ANISOTROPY) |
112 SET_FIELD(address_rounding, BRW_SAMPLER_ADDRESS_ROUNDING);
113
114 if (brw->gen >= 7) {
115 ss[0] |= SET_FIELD(lod_bias & 0x1fff, GEN7_SAMPLER_LOD_BIAS);
116
117 if (min_filter == BRW_MAPFILTER_ANISOTROPIC)
118 ss[0] |= GEN7_SAMPLER_EWA_ANISOTROPIC_ALGORITHM;
119
120 ss[1] = SET_FIELD(min_lod, GEN7_SAMPLER_MIN_LOD) |
121 SET_FIELD(max_lod, GEN7_SAMPLER_MAX_LOD) |
122 SET_FIELD(shadow_function, GEN7_SAMPLER_SHADOW_FUNCTION);
123
124 ss[3] |= SET_FIELD(wrap_s, BRW_SAMPLER_TCX_WRAP_MODE) |
125 SET_FIELD(wrap_t, BRW_SAMPLER_TCY_WRAP_MODE) |
126 SET_FIELD(wrap_r, BRW_SAMPLER_TCZ_WRAP_MODE);
127
128 if (non_normalized_coordinates)
129 ss[3] |= GEN7_SAMPLER_NON_NORMALIZED_COORDINATES;
130 } else {
131 ss[0] |= SET_FIELD(lod_bias & 0x7ff, GEN4_SAMPLER_LOD_BIAS) |
132 SET_FIELD(shadow_function, GEN4_SAMPLER_SHADOW_FUNCTION);
133
134 if (brw->gen == 6 && min_filter != mag_filter)
135 ss[0] |= GEN6_SAMPLER_MIN_MAG_NOT_EQUAL;
136
137 ss[1] = SET_FIELD(min_lod, GEN4_SAMPLER_MIN_LOD) |
138 SET_FIELD(max_lod, GEN4_SAMPLER_MAX_LOD) |
139 SET_FIELD(wrap_s, BRW_SAMPLER_TCX_WRAP_MODE) |
140 SET_FIELD(wrap_t, BRW_SAMPLER_TCY_WRAP_MODE) |
141 SET_FIELD(wrap_r, BRW_SAMPLER_TCZ_WRAP_MODE);
142
143 if (brw->gen >= 6 && non_normalized_coordinates)
144 ss[3] |= GEN6_SAMPLER_NON_NORMALIZED_COORDINATES;
145 }
146 }
147
148 static uint32_t
149 translate_wrap_mode(struct brw_context *brw, GLenum wrap, bool using_nearest)
150 {
151 switch( wrap ) {
152 case GL_REPEAT:
153 return BRW_TEXCOORDMODE_WRAP;
154 case GL_CLAMP:
155 /* GL_CLAMP is the weird mode where coordinates are clamped to
156 * [0.0, 1.0], so linear filtering of coordinates outside of
157 * [0.0, 1.0] give you half edge texel value and half border
158 * color.
159 *
160 * Gen8+ supports this natively.
161 */
162 if (brw->gen >= 8)
163 return GEN8_TEXCOORDMODE_HALF_BORDER;
164
165 /* On Gen4-7.5, we clamp the coordinates in the fragment shader
166 * and set clamp_border here, which gets the result desired.
167 * We just use clamp(_to_edge) for nearest, because for nearest
168 * clamping to 1.0 gives border color instead of the desired
169 * edge texels.
170 */
171 if (using_nearest)
172 return BRW_TEXCOORDMODE_CLAMP;
173 else
174 return BRW_TEXCOORDMODE_CLAMP_BORDER;
175 case GL_CLAMP_TO_EDGE:
176 return BRW_TEXCOORDMODE_CLAMP;
177 case GL_CLAMP_TO_BORDER:
178 return BRW_TEXCOORDMODE_CLAMP_BORDER;
179 case GL_MIRRORED_REPEAT:
180 return BRW_TEXCOORDMODE_MIRROR;
181 case GL_MIRROR_CLAMP_TO_EDGE:
182 return BRW_TEXCOORDMODE_MIRROR_ONCE;
183 default:
184 return BRW_TEXCOORDMODE_WRAP;
185 }
186 }
187
188 /**
189 * Return true if the given wrap mode requires the border color to exist.
190 */
191 static bool
192 wrap_mode_needs_border_color(unsigned wrap_mode)
193 {
194 return wrap_mode == BRW_TEXCOORDMODE_CLAMP_BORDER ||
195 wrap_mode == GEN8_TEXCOORDMODE_HALF_BORDER;
196 }
197
198 /**
199 * Upload SAMPLER_BORDER_COLOR_STATE.
200 */
201 static void
202 upload_default_color(struct brw_context *brw,
203 const struct gl_sampler_object *sampler,
204 int unit,
205 uint32_t *sdc_offset)
206 {
207 struct gl_context *ctx = &brw->ctx;
208 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
209 struct gl_texture_object *texObj = texUnit->_Current;
210 struct gl_texture_image *firstImage = texObj->Image[0][texObj->BaseLevel];
211 union gl_color_union color;
212
213 switch (firstImage->_BaseFormat) {
214 case GL_DEPTH_COMPONENT:
215 /* GL specs that border color for depth textures is taken from the
216 * R channel, while the hardware uses A. Spam R into all the
217 * channels for safety.
218 */
219 color.ui[0] = sampler->BorderColor.ui[0];
220 color.ui[1] = sampler->BorderColor.ui[0];
221 color.ui[2] = sampler->BorderColor.ui[0];
222 color.ui[3] = sampler->BorderColor.ui[0];
223 break;
224 case GL_ALPHA:
225 color.ui[0] = 0u;
226 color.ui[1] = 0u;
227 color.ui[2] = 0u;
228 color.ui[3] = sampler->BorderColor.ui[3];
229 break;
230 case GL_INTENSITY:
231 color.ui[0] = sampler->BorderColor.ui[0];
232 color.ui[1] = sampler->BorderColor.ui[0];
233 color.ui[2] = sampler->BorderColor.ui[0];
234 color.ui[3] = sampler->BorderColor.ui[0];
235 break;
236 case GL_LUMINANCE:
237 color.ui[0] = sampler->BorderColor.ui[0];
238 color.ui[1] = sampler->BorderColor.ui[0];
239 color.ui[2] = sampler->BorderColor.ui[0];
240 color.ui[3] = float_as_int(1.0);
241 break;
242 case GL_LUMINANCE_ALPHA:
243 color.ui[0] = sampler->BorderColor.ui[0];
244 color.ui[1] = sampler->BorderColor.ui[0];
245 color.ui[2] = sampler->BorderColor.ui[0];
246 color.ui[3] = sampler->BorderColor.ui[3];
247 break;
248 default:
249 color.ui[0] = sampler->BorderColor.ui[0];
250 color.ui[1] = sampler->BorderColor.ui[1];
251 color.ui[2] = sampler->BorderColor.ui[2];
252 color.ui[3] = sampler->BorderColor.ui[3];
253 break;
254 }
255
256 /* In some cases we use an RGBA surface format for GL RGB textures,
257 * where we've initialized the A channel to 1.0. We also have to set
258 * the border color alpha to 1.0 in that case.
259 */
260 if (firstImage->_BaseFormat == GL_RGB)
261 color.ui[3] = float_as_int(1.0);
262
263 if (brw->gen >= 8) {
264 /* On Broadwell, the border color is represented as four 32-bit floats,
265 * integers, or unsigned values, interpreted according to the surface
266 * format. This matches the sampler->BorderColor union exactly; just
267 * memcpy the values.
268 */
269 uint32_t *sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
270 4 * 4, 64, sdc_offset);
271 memcpy(sdc, color.ui, 4 * 4);
272 } else if (brw->is_haswell && texObj->_IsIntegerFormat) {
273 /* Haswell's integer border color support is completely insane:
274 * SAMPLER_BORDER_COLOR_STATE is 20 DWords. The first four are
275 * for float colors. The next 12 DWords are MBZ and only exist to
276 * pad it out to a 64 byte cacheline boundary. DWords 16-19 then
277 * contain integer colors; these are only used if SURFACE_STATE
278 * has the "Integer Surface Format" bit set. Even then, the
279 * arrangement of the RGBA data devolves into madness.
280 */
281 uint32_t *sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
282 20 * 4, 512, sdc_offset);
283 memset(sdc, 0, 20 * 4);
284 sdc = &sdc[16];
285
286 mesa_format format = firstImage->TexFormat;
287 int bits_per_channel = _mesa_get_format_bits(format, GL_RED_BITS);
288
289 /* From the Haswell PRM, "Command Reference: Structures", Page 36:
290 * "If any color channel is missing from the surface format,
291 * corresponding border color should be programmed as zero and if
292 * alpha channel is missing, corresponding Alpha border color should
293 * be programmed as 1."
294 */
295 unsigned c[4] = { 0, 0, 0, 1 };
296 for (int i = 0; i < 4; i++) {
297 if (_mesa_format_has_color_component(format, i))
298 c[i] = color.ui[i];
299 }
300
301 switch (bits_per_channel) {
302 case 8:
303 /* Copy RGBA in order. */
304 for (int i = 0; i < 4; i++)
305 ((uint8_t *) sdc)[i] = c[i];
306 break;
307 case 10:
308 /* R10G10B10A2_UINT is treated like a 16-bit format. */
309 case 16:
310 ((uint16_t *) sdc)[0] = c[0]; /* R -> DWord 0, bits 15:0 */
311 ((uint16_t *) sdc)[1] = c[1]; /* G -> DWord 0, bits 31:16 */
312 /* DWord 1 is Reserved/MBZ! */
313 ((uint16_t *) sdc)[4] = c[2]; /* B -> DWord 2, bits 15:0 */
314 ((uint16_t *) sdc)[5] = c[3]; /* A -> DWord 3, bits 31:16 */
315 break;
316 case 32:
317 if (firstImage->_BaseFormat == GL_RG) {
318 /* Careful inspection of the tables reveals that for RG32 formats,
319 * the green channel needs to go where blue normally belongs.
320 */
321 sdc[0] = c[0];
322 sdc[2] = c[1];
323 sdc[3] = 1;
324 } else {
325 /* Copy RGBA in order. */
326 for (int i = 0; i < 4; i++)
327 sdc[i] = c[i];
328 }
329 break;
330 default:
331 assert(!"Invalid number of bits per channel in integer format.");
332 break;
333 }
334 } else if (brw->gen == 5 || brw->gen == 6) {
335 struct gen5_sampler_default_color *sdc;
336
337 sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
338 sizeof(*sdc), 32, sdc_offset);
339
340 memset(sdc, 0, sizeof(*sdc));
341
342 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[0], color.f[0]);
343 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[1], color.f[1]);
344 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[2], color.f[2]);
345 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[3], color.f[3]);
346
347 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[0], color.f[0]);
348 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[1], color.f[1]);
349 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[2], color.f[2]);
350 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[3], color.f[3]);
351
352 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[0], color.f[0]);
353 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[1], color.f[1]);
354 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[2], color.f[2]);
355 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[3], color.f[3]);
356
357 sdc->hf[0] = _mesa_float_to_half(color.f[0]);
358 sdc->hf[1] = _mesa_float_to_half(color.f[1]);
359 sdc->hf[2] = _mesa_float_to_half(color.f[2]);
360 sdc->hf[3] = _mesa_float_to_half(color.f[3]);
361
362 sdc->b[0] = sdc->s[0] >> 8;
363 sdc->b[1] = sdc->s[1] >> 8;
364 sdc->b[2] = sdc->s[2] >> 8;
365 sdc->b[3] = sdc->s[3] >> 8;
366
367 sdc->f[0] = color.f[0];
368 sdc->f[1] = color.f[1];
369 sdc->f[2] = color.f[2];
370 sdc->f[3] = color.f[3];
371 } else {
372 float *sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
373 4 * 4, 32, sdc_offset);
374 memcpy(sdc, color.f, 4 * 4);
375 }
376 }
377
378 /**
379 * Sets the sampler state for a single unit based off of the sampler key
380 * entry.
381 */
382 static void
383 brw_update_sampler_state(struct brw_context *brw,
384 int unit,
385 uint32_t *sampler_state,
386 uint32_t batch_offset_for_sampler_state)
387 {
388 struct gl_context *ctx = &brw->ctx;
389 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
390 const struct gl_texture_object *texObj = texUnit->_Current;
391 const struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
392
393 /* These don't use samplers at all. */
394 if (texObj->Target == GL_TEXTURE_BUFFER)
395 return;
396
397 unsigned min_filter, mag_filter, mip_filter;
398
399 /* Select min and mip filters. */
400 switch (sampler->MinFilter) {
401 case GL_NEAREST:
402 min_filter = BRW_MAPFILTER_NEAREST;
403 mip_filter = BRW_MIPFILTER_NONE;
404 break;
405 case GL_LINEAR:
406 min_filter = BRW_MAPFILTER_LINEAR;
407 mip_filter = BRW_MIPFILTER_NONE;
408 break;
409 case GL_NEAREST_MIPMAP_NEAREST:
410 min_filter = BRW_MAPFILTER_NEAREST;
411 mip_filter = BRW_MIPFILTER_NEAREST;
412 break;
413 case GL_LINEAR_MIPMAP_NEAREST:
414 min_filter = BRW_MAPFILTER_LINEAR;
415 mip_filter = BRW_MIPFILTER_NEAREST;
416 break;
417 case GL_NEAREST_MIPMAP_LINEAR:
418 min_filter = BRW_MAPFILTER_NEAREST;
419 mip_filter = BRW_MIPFILTER_LINEAR;
420 break;
421 case GL_LINEAR_MIPMAP_LINEAR:
422 min_filter = BRW_MAPFILTER_LINEAR;
423 mip_filter = BRW_MIPFILTER_LINEAR;
424 break;
425 default:
426 unreachable("not reached");
427 }
428
429 /* Select mag filter. */
430 if (sampler->MagFilter == GL_LINEAR)
431 mag_filter = BRW_MAPFILTER_LINEAR;
432 else
433 mag_filter = BRW_MAPFILTER_NEAREST;
434
435 /* Enable anisotropic filtering if desired. */
436 unsigned max_anisotropy = BRW_ANISORATIO_2;
437 if (sampler->MaxAnisotropy > 1.0) {
438 min_filter = BRW_MAPFILTER_ANISOTROPIC;
439 mag_filter = BRW_MAPFILTER_ANISOTROPIC;
440
441 if (sampler->MaxAnisotropy > 2.0) {
442 max_anisotropy =
443 MIN2((sampler->MaxAnisotropy - 2) / 2, BRW_ANISORATIO_16);
444 }
445 }
446
447 /* Set address rounding bits if not using nearest filtering. */
448 unsigned address_rounding = 0;
449 if (min_filter != BRW_MAPFILTER_NEAREST) {
450 address_rounding |= BRW_ADDRESS_ROUNDING_ENABLE_U_MIN |
451 BRW_ADDRESS_ROUNDING_ENABLE_V_MIN |
452 BRW_ADDRESS_ROUNDING_ENABLE_R_MIN;
453 }
454 if (mag_filter != BRW_MAPFILTER_NEAREST) {
455 address_rounding |= BRW_ADDRESS_ROUNDING_ENABLE_U_MAG |
456 BRW_ADDRESS_ROUNDING_ENABLE_V_MAG |
457 BRW_ADDRESS_ROUNDING_ENABLE_R_MAG;
458 }
459
460 bool either_nearest =
461 sampler->MinFilter == GL_NEAREST || sampler->MagFilter == GL_NEAREST;
462 unsigned wrap_s = translate_wrap_mode(brw, sampler->WrapS, either_nearest);
463 unsigned wrap_t = translate_wrap_mode(brw, sampler->WrapT, either_nearest);
464 unsigned wrap_r = translate_wrap_mode(brw, sampler->WrapR, either_nearest);
465
466 if (texObj->Target == GL_TEXTURE_CUBE_MAP ||
467 texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) {
468 /* Cube maps must use the same wrap mode for all three coordinate
469 * dimensions. Prior to Haswell, only CUBE and CLAMP are valid.
470 */
471 if ((ctx->Texture.CubeMapSeamless || sampler->CubeMapSeamless) &&
472 (sampler->MinFilter != GL_NEAREST ||
473 sampler->MagFilter != GL_NEAREST)) {
474 wrap_s = BRW_TEXCOORDMODE_CUBE;
475 wrap_t = BRW_TEXCOORDMODE_CUBE;
476 wrap_r = BRW_TEXCOORDMODE_CUBE;
477 } else {
478 wrap_s = BRW_TEXCOORDMODE_CLAMP;
479 wrap_t = BRW_TEXCOORDMODE_CLAMP;
480 wrap_r = BRW_TEXCOORDMODE_CLAMP;
481 }
482 } else if (texObj->Target == GL_TEXTURE_1D) {
483 /* There's a bug in 1D texture sampling - it actually pays
484 * attention to the wrap_t value, though it should not.
485 * Override the wrap_t value here to GL_REPEAT to keep
486 * any nonexistent border pixels from floating in.
487 */
488 wrap_t = BRW_TEXCOORDMODE_WRAP;
489 }
490
491 /* Set shadow function. */
492 unsigned shadow_function = 0;
493 if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
494 shadow_function =
495 intel_translate_shadow_compare_func(sampler->CompareFunc);
496 }
497
498 const int lod_bits = brw->gen >= 7 ? 8 : 6;
499 const unsigned min_lod = U_FIXED(CLAMP(sampler->MinLod, 0, 13), lod_bits);
500 const unsigned max_lod = U_FIXED(CLAMP(sampler->MaxLod, 0, 13), lod_bits);
501 const int lod_bias =
502 S_FIXED(CLAMP(texUnit->LodBias + sampler->LodBias, -16, 15), lod_bits);
503 const unsigned base_level = U_FIXED(0, 1);
504
505 /* Upload the border color if necessary. If not, just point it at
506 * offset 0 (the start of the batch) - the color should be ignored,
507 * but that address won't fault in case something reads it anyway.
508 */
509 uint32_t border_color_offset = 0;
510 if (wrap_mode_needs_border_color(wrap_s) ||
511 wrap_mode_needs_border_color(wrap_t) ||
512 wrap_mode_needs_border_color(wrap_r)) {
513 upload_default_color(brw, sampler, unit, &border_color_offset);
514 }
515
516 const bool non_normalized_coords = texObj->Target == GL_TEXTURE_RECTANGLE;
517
518 brw_emit_sampler_state(brw,
519 sampler_state,
520 batch_offset_for_sampler_state,
521 min_filter, mag_filter, mip_filter,
522 max_anisotropy,
523 address_rounding,
524 wrap_s, wrap_t, wrap_r,
525 min_lod, max_lod, lod_bias, base_level,
526 shadow_function,
527 non_normalized_coords,
528 border_color_offset);
529 }
530
531
532 static void
533 brw_upload_sampler_state_table(struct brw_context *brw,
534 struct gl_program *prog,
535 struct brw_stage_state *stage_state)
536 {
537 struct gl_context *ctx = &brw->ctx;
538 uint32_t sampler_count = stage_state->sampler_count;
539
540 GLbitfield SamplersUsed = prog->SamplersUsed;
541
542 if (sampler_count == 0)
543 return;
544
545 /* SAMPLER_STATE is 4 DWords on all platforms. */
546 const int dwords = 4;
547 const int size_in_bytes = dwords * sizeof(uint32_t);
548
549 uint32_t *sampler_state = brw_state_batch(brw, AUB_TRACE_SAMPLER_STATE,
550 sampler_count * size_in_bytes,
551 32, &stage_state->sampler_offset);
552 memset(sampler_state, 0, sampler_count * size_in_bytes);
553
554 uint32_t batch_offset_for_sampler_state = stage_state->sampler_offset;
555
556 for (unsigned s = 0; s < sampler_count; s++) {
557 if (SamplersUsed & (1 << s)) {
558 const unsigned unit = prog->SamplerUnits[s];
559 if (ctx->Texture.Unit[unit]._Current) {
560 brw_update_sampler_state(brw, unit, sampler_state,
561 batch_offset_for_sampler_state);
562 }
563 }
564
565 sampler_state += dwords;
566 batch_offset_for_sampler_state += size_in_bytes;
567 }
568
569 if (brw->gen >= 7) {
570 /* Emit a 3DSTATE_SAMPLER_STATE_POINTERS_XS packet. */
571 gen7_emit_sampler_state_pointers_xs(brw, stage_state);
572 } else {
573 /* Flag that the sampler state table pointer has changed; later atoms
574 * will handle it.
575 */
576 brw->state.dirty.brw |= BRW_NEW_SAMPLER_STATE_TABLE;
577 }
578 }
579
580 static void
581 brw_upload_fs_samplers(struct brw_context *brw)
582 {
583 /* BRW_NEW_FRAGMENT_PROGRAM */
584 struct gl_program *fs = (struct gl_program *) brw->fragment_program;
585 brw_upload_sampler_state_table(brw, fs, &brw->wm.base);
586 }
587
588 const struct brw_tracked_state brw_fs_samplers = {
589 .dirty = {
590 .mesa = _NEW_TEXTURE,
591 .brw = BRW_NEW_BATCH |
592 BRW_NEW_FRAGMENT_PROGRAM,
593 },
594 .emit = brw_upload_fs_samplers,
595 };
596
597 static void
598 brw_upload_vs_samplers(struct brw_context *brw)
599 {
600 /* BRW_NEW_VERTEX_PROGRAM */
601 struct gl_program *vs = (struct gl_program *) brw->vertex_program;
602 brw_upload_sampler_state_table(brw, vs, &brw->vs.base);
603 }
604
605
606 const struct brw_tracked_state brw_vs_samplers = {
607 .dirty = {
608 .mesa = _NEW_TEXTURE,
609 .brw = BRW_NEW_BATCH |
610 BRW_NEW_VERTEX_PROGRAM,
611 },
612 .emit = brw_upload_vs_samplers,
613 };
614
615
616 static void
617 brw_upload_gs_samplers(struct brw_context *brw)
618 {
619 /* BRW_NEW_GEOMETRY_PROGRAM */
620 struct gl_program *gs = (struct gl_program *) brw->geometry_program;
621 if (!gs)
622 return;
623
624 brw_upload_sampler_state_table(brw, gs, &brw->gs.base);
625 }
626
627
628 const struct brw_tracked_state brw_gs_samplers = {
629 .dirty = {
630 .mesa = _NEW_TEXTURE,
631 .brw = BRW_NEW_BATCH |
632 BRW_NEW_GEOMETRY_PROGRAM,
633 },
634 .emit = brw_upload_gs_samplers,
635 };