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