2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics to
4 develop this 3D driver.
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:
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.
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.
26 **********************************************************************/
29 * Keith Whitwell <keithw@vmware.com>
33 * @file brw_sampler_state.c
35 * This file contains code for emitting SAMPLER_STATE structures, which
36 * specifies filter modes, wrap modes, border color, and so on.
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"
45 #include "main/macros.h"
46 #include "main/samplerobj.h"
47 #include "util/half_float.h"
50 * Emit a 3DSTATE_SAMPLER_STATE_POINTERS_{VS,HS,GS,DS,PS} packet.
53 gen7_emit_sampler_state_pointers_xs(struct brw_context
*brw
,
54 struct brw_stage_state
*stage_state
)
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
,
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
);
71 OUT_BATCH(packet_headers
[stage_state
->stage
] << 16 | (2 - 2));
72 OUT_BATCH(stage_state
->sampler_offset
);
77 * Emit a SAMPLER_STATE structure, given all the fields.
80 brw_emit_sampler_state(struct brw_context
*brw
,
82 uint32_t batch_offset_for_sampler_state
,
86 unsigned max_anisotropy
,
87 unsigned address_rounding
,
94 unsigned shadow_function
,
95 bool non_normalized_coordinates
,
96 uint32_t border_color_offset
)
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
);
103 ss
[2] = border_color_offset
;
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);
112 ss
[3] = SET_FIELD(max_anisotropy
, BRW_SAMPLER_MAX_ANISOTROPY
) |
113 SET_FIELD(address_rounding
, BRW_SAMPLER_ADDRESS_ROUNDING
);
116 ss
[0] |= SET_FIELD(lod_bias
& 0x1fff, GEN7_SAMPLER_LOD_BIAS
);
118 if (min_filter
== BRW_MAPFILTER_ANISOTROPIC
)
119 ss
[0] |= GEN7_SAMPLER_EWA_ANISOTROPIC_ALGORITHM
;
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
);
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
);
129 if (non_normalized_coordinates
)
130 ss
[3] |= GEN7_SAMPLER_NON_NORMALIZED_COORDINATES
;
132 ss
[0] |= SET_FIELD(lod_bias
& 0x7ff, GEN4_SAMPLER_LOD_BIAS
) |
133 SET_FIELD(shadow_function
, GEN4_SAMPLER_SHADOW_FUNCTION
);
135 if (brw
->gen
== 6 && min_filter
!= mag_filter
)
136 ss
[0] |= GEN6_SAMPLER_MIN_MAG_NOT_EQUAL
;
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
);
144 if (brw
->gen
>= 6 && non_normalized_coordinates
)
145 ss
[3] |= GEN6_SAMPLER_NON_NORMALIZED_COORDINATES
;
150 translate_wrap_mode(struct brw_context
*brw
, GLenum wrap
, bool using_nearest
)
154 return BRW_TEXCOORDMODE_WRAP
;
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
161 * Gen8+ supports this natively.
164 return GEN8_TEXCOORDMODE_HALF_BORDER
;
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
173 return BRW_TEXCOORDMODE_CLAMP
;
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
;
185 return BRW_TEXCOORDMODE_WRAP
;
190 * Return true if the given wrap mode requires the border color to exist.
193 wrap_mode_needs_border_color(unsigned wrap_mode
)
195 return wrap_mode
== BRW_TEXCOORDMODE_CLAMP_BORDER
||
196 wrap_mode
== GEN8_TEXCOORDMODE_HALF_BORDER
;
200 * Upload SAMPLER_BORDER_COLOR_STATE.
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
)
209 union gl_color_union color
;
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.
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];
226 color
.ui
[3] = sampler
->BorderColor
.ui
[3];
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];
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);
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];
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];
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.
258 if (base_format
== GL_RGB
)
259 color
.ui
[3] = float_as_int(1.0);
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
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.
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);
284 int bits_per_channel
= _mesa_get_format_bits(format
, GL_RED_BITS
);
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."
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
))
298 switch (bits_per_channel
) {
300 /* Copy RGBA in order. */
301 for (int i
= 0; i
< 4; i
++)
302 ((uint8_t *) sdc
)[i
] = c
[i
];
305 /* R10G10B10A2_UINT is treated like a 16-bit format. */
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 */
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.
322 /* Copy RGBA in order. */
323 for (int i
= 0; i
< 4; i
++)
328 assert(!"Invalid number of bits per channel in integer format.");
331 } else if (brw
->gen
== 5 || brw
->gen
== 6) {
332 struct gen5_sampler_default_color
*sdc
;
334 sdc
= brw_state_batch(brw
, AUB_TRACE_SAMPLER_DEFAULT_COLOR
,
335 sizeof(*sdc
), 32, sdc_offset
);
337 memset(sdc
, 0, sizeof(*sdc
));
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]);
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]);
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]);
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]);
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;
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];
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);
376 * Sets the sampler state for a single unit based off of the sampler key
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
)
389 unsigned min_filter
, mag_filter
, mip_filter
;
391 /* Select min and mip filters. */
392 switch (sampler
->MinFilter
) {
394 min_filter
= BRW_MAPFILTER_NEAREST
;
395 mip_filter
= BRW_MIPFILTER_NONE
;
398 min_filter
= BRW_MAPFILTER_LINEAR
;
399 mip_filter
= BRW_MIPFILTER_NONE
;
401 case GL_NEAREST_MIPMAP_NEAREST
:
402 min_filter
= BRW_MAPFILTER_NEAREST
;
403 mip_filter
= BRW_MIPFILTER_NEAREST
;
405 case GL_LINEAR_MIPMAP_NEAREST
:
406 min_filter
= BRW_MAPFILTER_LINEAR
;
407 mip_filter
= BRW_MIPFILTER_NEAREST
;
409 case GL_NEAREST_MIPMAP_LINEAR
:
410 min_filter
= BRW_MAPFILTER_NEAREST
;
411 mip_filter
= BRW_MIPFILTER_LINEAR
;
413 case GL_LINEAR_MIPMAP_LINEAR
:
414 min_filter
= BRW_MAPFILTER_LINEAR
;
415 mip_filter
= BRW_MIPFILTER_LINEAR
;
418 unreachable("not reached");
421 /* Select mag filter. */
422 if (sampler
->MagFilter
== GL_LINEAR
)
423 mag_filter
= BRW_MAPFILTER_LINEAR
;
425 mag_filter
= BRW_MAPFILTER_NEAREST
;
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
;
433 if (sampler
->MaxAnisotropy
> 2.0f
) {
435 MIN2((sampler
->MaxAnisotropy
- 2) / 2, BRW_ANISORATIO_16
);
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
;
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
;
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
);
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.
463 if (tex_cube_map_seamless
|| sampler
->CubeMapSeamless
) {
464 wrap_s
= BRW_TEXCOORDMODE_CUBE
;
465 wrap_t
= BRW_TEXCOORDMODE_CUBE
;
466 wrap_r
= BRW_TEXCOORDMODE_CUBE
;
468 wrap_s
= BRW_TEXCOORDMODE_CLAMP
;
469 wrap_t
= BRW_TEXCOORDMODE_CLAMP
;
470 wrap_r
= BRW_TEXCOORDMODE_CLAMP
;
472 } else if (target
== GL_TEXTURE_1D
) {
473 /* There's a bug in 1D texture sampling - it actually pays
474 * attention to the wrap_t value, though it should not.
475 * Override the wrap_t value here to GL_REPEAT to keep
476 * any nonexistent border pixels from floating in.
478 wrap_t
= BRW_TEXCOORDMODE_WRAP
;
481 /* Set shadow function. */
482 unsigned shadow_function
= 0;
483 if (sampler
->CompareMode
== GL_COMPARE_R_TO_TEXTURE_ARB
) {
485 intel_translate_shadow_compare_func(sampler
->CompareFunc
);
488 const int lod_bits
= brw
->gen
>= 7 ? 8 : 6;
489 const unsigned min_lod
= U_FIXED(CLAMP(sampler
->MinLod
, 0, 13), lod_bits
);
490 const unsigned max_lod
= U_FIXED(CLAMP(sampler
->MaxLod
, 0, 13), lod_bits
);
492 S_FIXED(CLAMP(tex_unit_lod_bias
+ sampler
->LodBias
, -16, 15), lod_bits
);
494 /* Upload the border color if necessary. If not, just point it at
495 * offset 0 (the start of the batch) - the color should be ignored,
496 * but that address won't fault in case something reads it anyway.
498 uint32_t border_color_offset
= 0;
499 if (wrap_mode_needs_border_color(wrap_s
) ||
500 wrap_mode_needs_border_color(wrap_t
) ||
501 wrap_mode_needs_border_color(wrap_r
)) {
502 upload_default_color(brw
, sampler
,
503 format
, base_format
, is_integer_format
,
504 &border_color_offset
);
507 const bool non_normalized_coords
= target
== GL_TEXTURE_RECTANGLE
;
509 brw_emit_sampler_state(brw
,
511 batch_offset_for_sampler_state
,
512 min_filter
, mag_filter
, mip_filter
,
515 wrap_s
, wrap_t
, wrap_r
,
516 min_lod
, max_lod
, lod_bias
,
518 non_normalized_coords
,
519 border_color_offset
);
523 update_sampler_state(struct brw_context
*brw
,
525 uint32_t *sampler_state
,
526 uint32_t batch_offset_for_sampler_state
)
528 struct gl_context
*ctx
= &brw
->ctx
;
529 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
530 const struct gl_texture_object
*texObj
= texUnit
->_Current
;
531 const struct gl_sampler_object
*sampler
= _mesa_get_samplerobj(ctx
, unit
);
533 /* These don't use samplers at all. */
534 if (texObj
->Target
== GL_TEXTURE_BUFFER
)
537 struct gl_texture_image
*firstImage
= texObj
->Image
[0][texObj
->BaseLevel
];
538 brw_update_sampler_state(brw
, texObj
->Target
, ctx
->Texture
.CubeMapSeamless
,
540 firstImage
->TexFormat
, firstImage
->_BaseFormat
,
541 texObj
->_IsIntegerFormat
,
543 sampler_state
, batch_offset_for_sampler_state
);
547 brw_upload_sampler_state_table(struct brw_context
*brw
,
548 struct gl_program
*prog
,
549 struct brw_stage_state
*stage_state
)
551 struct gl_context
*ctx
= &brw
->ctx
;
552 uint32_t sampler_count
= stage_state
->sampler_count
;
554 GLbitfield SamplersUsed
= prog
->SamplersUsed
;
556 if (sampler_count
== 0)
559 /* SAMPLER_STATE is 4 DWords on all platforms. */
560 const int dwords
= 4;
561 const int size_in_bytes
= dwords
* sizeof(uint32_t);
563 uint32_t *sampler_state
= brw_state_batch(brw
, AUB_TRACE_SAMPLER_STATE
,
564 sampler_count
* size_in_bytes
,
565 32, &stage_state
->sampler_offset
);
566 memset(sampler_state
, 0, sampler_count
* size_in_bytes
);
568 uint32_t batch_offset_for_sampler_state
= stage_state
->sampler_offset
;
570 for (unsigned s
= 0; s
< sampler_count
; s
++) {
571 if (SamplersUsed
& (1 << s
)) {
572 const unsigned unit
= prog
->SamplerUnits
[s
];
573 if (ctx
->Texture
.Unit
[unit
]._Current
) {
574 update_sampler_state(brw
, unit
, sampler_state
,
575 batch_offset_for_sampler_state
);
579 sampler_state
+= dwords
;
580 batch_offset_for_sampler_state
+= size_in_bytes
;
583 if (brw
->gen
>= 7 && stage_state
->stage
!= MESA_SHADER_COMPUTE
) {
584 /* Emit a 3DSTATE_SAMPLER_STATE_POINTERS_XS packet. */
585 gen7_emit_sampler_state_pointers_xs(brw
, stage_state
);
587 /* Flag that the sampler state table pointer has changed; later atoms
590 brw
->ctx
.NewDriverState
|= BRW_NEW_SAMPLER_STATE_TABLE
;
595 brw_upload_fs_samplers(struct brw_context
*brw
)
597 /* BRW_NEW_FRAGMENT_PROGRAM */
598 struct gl_program
*fs
= (struct gl_program
*) brw
->fragment_program
;
599 brw_upload_sampler_state_table(brw
, fs
, &brw
->wm
.base
);
602 const struct brw_tracked_state brw_fs_samplers
= {
604 .mesa
= _NEW_TEXTURE
,
605 .brw
= BRW_NEW_BATCH
|
606 BRW_NEW_FRAGMENT_PROGRAM
,
608 .emit
= brw_upload_fs_samplers
,
612 brw_upload_vs_samplers(struct brw_context
*brw
)
614 /* BRW_NEW_VERTEX_PROGRAM */
615 struct gl_program
*vs
= (struct gl_program
*) brw
->vertex_program
;
616 brw_upload_sampler_state_table(brw
, vs
, &brw
->vs
.base
);
620 const struct brw_tracked_state brw_vs_samplers
= {
622 .mesa
= _NEW_TEXTURE
,
623 .brw
= BRW_NEW_BATCH
|
624 BRW_NEW_VERTEX_PROGRAM
,
626 .emit
= brw_upload_vs_samplers
,
631 brw_upload_gs_samplers(struct brw_context
*brw
)
633 /* BRW_NEW_GEOMETRY_PROGRAM */
634 struct gl_program
*gs
= (struct gl_program
*) brw
->geometry_program
;
638 brw_upload_sampler_state_table(brw
, gs
, &brw
->gs
.base
);
642 const struct brw_tracked_state brw_gs_samplers
= {
644 .mesa
= _NEW_TEXTURE
,
645 .brw
= BRW_NEW_BATCH
|
646 BRW_NEW_GEOMETRY_PROGRAM
,
648 .emit
= brw_upload_gs_samplers
,
653 brw_upload_tcs_samplers(struct brw_context
*brw
)
655 /* BRW_NEW_TESS_PROGRAMS */
656 struct gl_program
*tcs
= (struct gl_program
*) brw
->tess_ctrl_program
;
660 brw_upload_sampler_state_table(brw
, tcs
, &brw
->tcs
.base
);
664 const struct brw_tracked_state brw_tcs_samplers
= {
666 .mesa
= _NEW_TEXTURE
,
667 .brw
= BRW_NEW_BATCH
|
668 BRW_NEW_TESS_PROGRAMS
,
670 .emit
= brw_upload_tcs_samplers
,
675 brw_upload_tes_samplers(struct brw_context
*brw
)
677 /* BRW_NEW_TESS_PROGRAMS */
678 struct gl_program
*tes
= (struct gl_program
*) brw
->tess_eval_program
;
682 brw_upload_sampler_state_table(brw
, tes
, &brw
->tes
.base
);
686 const struct brw_tracked_state brw_tes_samplers
= {
688 .mesa
= _NEW_TEXTURE
,
689 .brw
= BRW_NEW_BATCH
|
690 BRW_NEW_TESS_PROGRAMS
,
692 .emit
= brw_upload_tes_samplers
,
696 brw_upload_cs_samplers(struct brw_context
*brw
)
698 /* BRW_NEW_COMPUTE_PROGRAM */
699 struct gl_program
*cs
= (struct gl_program
*) brw
->compute_program
;
703 brw_upload_sampler_state_table(brw
, cs
, &brw
->cs
.base
);
706 const struct brw_tracked_state brw_cs_samplers
= {
708 .mesa
= _NEW_TEXTURE
,
709 .brw
= BRW_NEW_BATCH
|
710 BRW_NEW_COMPUTE_PROGRAM
,
712 .emit
= brw_upload_cs_samplers
,