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