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 has_component(mesa_format format
, int i
)
202 if (_mesa_is_format_color_format(format
))
203 return _mesa_format_has_color_component(format
, i
);
205 /* depth and stencil have only one component */
210 * Upload SAMPLER_BORDER_COLOR_STATE.
213 upload_default_color(struct brw_context
*brw
,
214 const struct gl_sampler_object
*sampler
,
215 mesa_format format
, GLenum base_format
,
216 bool is_integer_format
,
217 uint32_t *sdc_offset
)
219 union gl_color_union color
;
221 switch (base_format
) {
222 case GL_DEPTH_COMPONENT
:
223 /* GL specs that border color for depth textures is taken from the
224 * R channel, while the hardware uses A. Spam R into all the
225 * channels for safety.
227 color
.ui
[0] = sampler
->BorderColor
.ui
[0];
228 color
.ui
[1] = sampler
->BorderColor
.ui
[0];
229 color
.ui
[2] = sampler
->BorderColor
.ui
[0];
230 color
.ui
[3] = sampler
->BorderColor
.ui
[0];
236 color
.ui
[3] = sampler
->BorderColor
.ui
[3];
239 color
.ui
[0] = sampler
->BorderColor
.ui
[0];
240 color
.ui
[1] = sampler
->BorderColor
.ui
[0];
241 color
.ui
[2] = sampler
->BorderColor
.ui
[0];
242 color
.ui
[3] = sampler
->BorderColor
.ui
[0];
245 color
.ui
[0] = sampler
->BorderColor
.ui
[0];
246 color
.ui
[1] = sampler
->BorderColor
.ui
[0];
247 color
.ui
[2] = sampler
->BorderColor
.ui
[0];
248 color
.ui
[3] = float_as_int(1.0);
250 case GL_LUMINANCE_ALPHA
:
251 color
.ui
[0] = sampler
->BorderColor
.ui
[0];
252 color
.ui
[1] = sampler
->BorderColor
.ui
[0];
253 color
.ui
[2] = sampler
->BorderColor
.ui
[0];
254 color
.ui
[3] = sampler
->BorderColor
.ui
[3];
257 color
.ui
[0] = sampler
->BorderColor
.ui
[0];
258 color
.ui
[1] = sampler
->BorderColor
.ui
[1];
259 color
.ui
[2] = sampler
->BorderColor
.ui
[2];
260 color
.ui
[3] = sampler
->BorderColor
.ui
[3];
264 /* In some cases we use an RGBA surface format for GL RGB textures,
265 * where we've initialized the A channel to 1.0. We also have to set
266 * the border color alpha to 1.0 in that case.
268 if (base_format
== GL_RGB
)
269 color
.ui
[3] = float_as_int(1.0);
272 /* On Broadwell, the border color is represented as four 32-bit floats,
273 * integers, or unsigned values, interpreted according to the surface
274 * format. This matches the sampler->BorderColor union exactly; just
277 uint32_t *sdc
= brw_state_batch(brw
, AUB_TRACE_SAMPLER_DEFAULT_COLOR
,
278 4 * 4, 64, sdc_offset
);
279 memcpy(sdc
, color
.ui
, 4 * 4);
280 } else if (brw
->is_haswell
&& is_integer_format
) {
281 /* Haswell's integer border color support is completely insane:
282 * SAMPLER_BORDER_COLOR_STATE is 20 DWords. The first four are
283 * for float colors. The next 12 DWords are MBZ and only exist to
284 * pad it out to a 64 byte cacheline boundary. DWords 16-19 then
285 * contain integer colors; these are only used if SURFACE_STATE
286 * has the "Integer Surface Format" bit set. Even then, the
287 * arrangement of the RGBA data devolves into madness.
289 uint32_t *sdc
= brw_state_batch(brw
, AUB_TRACE_SAMPLER_DEFAULT_COLOR
,
290 20 * 4, 512, sdc_offset
);
291 memset(sdc
, 0, 20 * 4);
294 const int bits_per_channel
=
295 _mesa_get_format_bits(format
,
296 format
== MESA_FORMAT_S_UINT8
?
297 GL_STENCIL_BITS
: GL_RED_BITS
);
299 /* From the Haswell PRM, "Command Reference: Structures", Page 36:
300 * "If any color channel is missing from the surface format,
301 * corresponding border color should be programmed as zero and if
302 * alpha channel is missing, corresponding Alpha border color should
303 * be programmed as 1."
305 unsigned c
[4] = { 0, 0, 0, 1 };
306 for (int i
= 0; i
< 4; i
++) {
307 if (has_component(format
, i
))
311 switch (bits_per_channel
) {
313 /* Copy RGBA in order. */
314 for (int i
= 0; i
< 4; i
++)
315 ((uint8_t *) sdc
)[i
] = c
[i
];
318 /* R10G10B10A2_UINT is treated like a 16-bit format. */
320 ((uint16_t *) sdc
)[0] = c
[0]; /* R -> DWord 0, bits 15:0 */
321 ((uint16_t *) sdc
)[1] = c
[1]; /* G -> DWord 0, bits 31:16 */
322 /* DWord 1 is Reserved/MBZ! */
323 ((uint16_t *) sdc
)[4] = c
[2]; /* B -> DWord 2, bits 15:0 */
324 ((uint16_t *) sdc
)[5] = c
[3]; /* A -> DWord 3, bits 31:16 */
327 if (base_format
== GL_RG
) {
328 /* Careful inspection of the tables reveals that for RG32 formats,
329 * the green channel needs to go where blue normally belongs.
335 /* Copy RGBA in order. */
336 for (int i
= 0; i
< 4; i
++)
341 assert(!"Invalid number of bits per channel in integer format.");
344 } else if (brw
->gen
== 5 || brw
->gen
== 6) {
345 struct gen5_sampler_default_color
*sdc
;
347 sdc
= brw_state_batch(brw
, AUB_TRACE_SAMPLER_DEFAULT_COLOR
,
348 sizeof(*sdc
), 32, sdc_offset
);
350 memset(sdc
, 0, sizeof(*sdc
));
352 UNCLAMPED_FLOAT_TO_UBYTE(sdc
->ub
[0], color
.f
[0]);
353 UNCLAMPED_FLOAT_TO_UBYTE(sdc
->ub
[1], color
.f
[1]);
354 UNCLAMPED_FLOAT_TO_UBYTE(sdc
->ub
[2], color
.f
[2]);
355 UNCLAMPED_FLOAT_TO_UBYTE(sdc
->ub
[3], color
.f
[3]);
357 UNCLAMPED_FLOAT_TO_USHORT(sdc
->us
[0], color
.f
[0]);
358 UNCLAMPED_FLOAT_TO_USHORT(sdc
->us
[1], color
.f
[1]);
359 UNCLAMPED_FLOAT_TO_USHORT(sdc
->us
[2], color
.f
[2]);
360 UNCLAMPED_FLOAT_TO_USHORT(sdc
->us
[3], color
.f
[3]);
362 UNCLAMPED_FLOAT_TO_SHORT(sdc
->s
[0], color
.f
[0]);
363 UNCLAMPED_FLOAT_TO_SHORT(sdc
->s
[1], color
.f
[1]);
364 UNCLAMPED_FLOAT_TO_SHORT(sdc
->s
[2], color
.f
[2]);
365 UNCLAMPED_FLOAT_TO_SHORT(sdc
->s
[3], color
.f
[3]);
367 sdc
->hf
[0] = _mesa_float_to_half(color
.f
[0]);
368 sdc
->hf
[1] = _mesa_float_to_half(color
.f
[1]);
369 sdc
->hf
[2] = _mesa_float_to_half(color
.f
[2]);
370 sdc
->hf
[3] = _mesa_float_to_half(color
.f
[3]);
372 sdc
->b
[0] = sdc
->s
[0] >> 8;
373 sdc
->b
[1] = sdc
->s
[1] >> 8;
374 sdc
->b
[2] = sdc
->s
[2] >> 8;
375 sdc
->b
[3] = sdc
->s
[3] >> 8;
377 sdc
->f
[0] = color
.f
[0];
378 sdc
->f
[1] = color
.f
[1];
379 sdc
->f
[2] = color
.f
[2];
380 sdc
->f
[3] = color
.f
[3];
382 float *sdc
= brw_state_batch(brw
, AUB_TRACE_SAMPLER_DEFAULT_COLOR
,
383 4 * 4, 32, sdc_offset
);
384 memcpy(sdc
, color
.f
, 4 * 4);
389 * Sets the sampler state for a single unit based off of the sampler key
393 brw_update_sampler_state(struct brw_context
*brw
,
394 GLenum target
, bool tex_cube_map_seamless
,
395 GLfloat tex_unit_lod_bias
,
396 mesa_format format
, GLenum base_format
,
397 bool is_integer_format
,
398 const struct gl_sampler_object
*sampler
,
399 uint32_t *sampler_state
,
400 uint32_t batch_offset_for_sampler_state
)
402 unsigned min_filter
, mag_filter
, mip_filter
;
404 /* Select min and mip filters. */
405 switch (sampler
->MinFilter
) {
407 min_filter
= BRW_MAPFILTER_NEAREST
;
408 mip_filter
= BRW_MIPFILTER_NONE
;
411 min_filter
= BRW_MAPFILTER_LINEAR
;
412 mip_filter
= BRW_MIPFILTER_NONE
;
414 case GL_NEAREST_MIPMAP_NEAREST
:
415 min_filter
= BRW_MAPFILTER_NEAREST
;
416 mip_filter
= BRW_MIPFILTER_NEAREST
;
418 case GL_LINEAR_MIPMAP_NEAREST
:
419 min_filter
= BRW_MAPFILTER_LINEAR
;
420 mip_filter
= BRW_MIPFILTER_NEAREST
;
422 case GL_NEAREST_MIPMAP_LINEAR
:
423 min_filter
= BRW_MAPFILTER_NEAREST
;
424 mip_filter
= BRW_MIPFILTER_LINEAR
;
426 case GL_LINEAR_MIPMAP_LINEAR
:
427 min_filter
= BRW_MAPFILTER_LINEAR
;
428 mip_filter
= BRW_MIPFILTER_LINEAR
;
431 unreachable("not reached");
434 /* Select mag filter. */
435 if (sampler
->MagFilter
== GL_LINEAR
)
436 mag_filter
= BRW_MAPFILTER_LINEAR
;
438 mag_filter
= BRW_MAPFILTER_NEAREST
;
440 /* Enable anisotropic filtering if desired. */
441 unsigned max_anisotropy
= BRW_ANISORATIO_2
;
442 if (sampler
->MaxAnisotropy
> 1.0f
) {
443 min_filter
= BRW_MAPFILTER_ANISOTROPIC
;
444 mag_filter
= BRW_MAPFILTER_ANISOTROPIC
;
446 if (sampler
->MaxAnisotropy
> 2.0f
) {
448 MIN2((sampler
->MaxAnisotropy
- 2) / 2, BRW_ANISORATIO_16
);
452 /* Set address rounding bits if not using nearest filtering. */
453 unsigned address_rounding
= 0;
454 if (min_filter
!= BRW_MAPFILTER_NEAREST
) {
455 address_rounding
|= BRW_ADDRESS_ROUNDING_ENABLE_U_MIN
|
456 BRW_ADDRESS_ROUNDING_ENABLE_V_MIN
|
457 BRW_ADDRESS_ROUNDING_ENABLE_R_MIN
;
459 if (mag_filter
!= BRW_MAPFILTER_NEAREST
) {
460 address_rounding
|= BRW_ADDRESS_ROUNDING_ENABLE_U_MAG
|
461 BRW_ADDRESS_ROUNDING_ENABLE_V_MAG
|
462 BRW_ADDRESS_ROUNDING_ENABLE_R_MAG
;
465 bool either_nearest
=
466 sampler
->MinFilter
== GL_NEAREST
|| sampler
->MagFilter
== GL_NEAREST
;
467 unsigned wrap_s
= translate_wrap_mode(brw
, sampler
->WrapS
, either_nearest
);
468 unsigned wrap_t
= translate_wrap_mode(brw
, sampler
->WrapT
, either_nearest
);
469 unsigned wrap_r
= translate_wrap_mode(brw
, sampler
->WrapR
, either_nearest
);
471 if (target
== GL_TEXTURE_CUBE_MAP
||
472 target
== GL_TEXTURE_CUBE_MAP_ARRAY
) {
473 /* Cube maps must use the same wrap mode for all three coordinate
474 * dimensions. Prior to Haswell, only CUBE and CLAMP are valid.
476 * Ivybridge and Baytrail seem to have problems with CUBE mode and
477 * integer formats. Fall back to CLAMP for now.
479 if ((tex_cube_map_seamless
|| sampler
->CubeMapSeamless
) &&
480 !(brw
->gen
== 7 && !brw
->is_haswell
&& is_integer_format
)) {
481 wrap_s
= BRW_TEXCOORDMODE_CUBE
;
482 wrap_t
= BRW_TEXCOORDMODE_CUBE
;
483 wrap_r
= BRW_TEXCOORDMODE_CUBE
;
485 wrap_s
= BRW_TEXCOORDMODE_CLAMP
;
486 wrap_t
= BRW_TEXCOORDMODE_CLAMP
;
487 wrap_r
= BRW_TEXCOORDMODE_CLAMP
;
489 } else if (target
== GL_TEXTURE_1D
) {
490 /* There's a bug in 1D texture sampling - it actually pays
491 * attention to the wrap_t value, though it should not.
492 * Override the wrap_t value here to GL_REPEAT to keep
493 * any nonexistent border pixels from floating in.
495 wrap_t
= BRW_TEXCOORDMODE_WRAP
;
498 /* Set shadow function. */
499 unsigned shadow_function
= 0;
500 if (sampler
->CompareMode
== GL_COMPARE_R_TO_TEXTURE_ARB
) {
502 intel_translate_shadow_compare_func(sampler
->CompareFunc
);
505 const int lod_bits
= brw
->gen
>= 7 ? 8 : 6;
506 const unsigned min_lod
= U_FIXED(CLAMP(sampler
->MinLod
, 0, 13), lod_bits
);
507 const unsigned max_lod
= U_FIXED(CLAMP(sampler
->MaxLod
, 0, 13), lod_bits
);
509 S_FIXED(CLAMP(tex_unit_lod_bias
+ sampler
->LodBias
, -16, 15), lod_bits
);
511 /* Upload the border color if necessary. If not, just point it at
512 * offset 0 (the start of the batch) - the color should be ignored,
513 * but that address won't fault in case something reads it anyway.
515 uint32_t border_color_offset
= 0;
516 if (wrap_mode_needs_border_color(wrap_s
) ||
517 wrap_mode_needs_border_color(wrap_t
) ||
518 wrap_mode_needs_border_color(wrap_r
)) {
519 upload_default_color(brw
, sampler
,
520 format
, base_format
, is_integer_format
,
521 &border_color_offset
);
524 const bool non_normalized_coords
= target
== GL_TEXTURE_RECTANGLE
;
526 brw_emit_sampler_state(brw
,
528 batch_offset_for_sampler_state
,
529 min_filter
, mag_filter
, mip_filter
,
532 wrap_s
, wrap_t
, wrap_r
,
533 min_lod
, max_lod
, lod_bias
,
535 non_normalized_coords
,
536 border_color_offset
);
540 update_sampler_state(struct brw_context
*brw
,
542 uint32_t *sampler_state
,
543 uint32_t batch_offset_for_sampler_state
)
545 struct gl_context
*ctx
= &brw
->ctx
;
546 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
547 const struct gl_texture_object
*texObj
= texUnit
->_Current
;
548 const struct gl_sampler_object
*sampler
= _mesa_get_samplerobj(ctx
, unit
);
550 /* These don't use samplers at all. */
551 if (texObj
->Target
== GL_TEXTURE_BUFFER
)
554 struct gl_texture_image
*firstImage
= texObj
->Image
[0][texObj
->BaseLevel
];
555 brw_update_sampler_state(brw
, texObj
->Target
, ctx
->Texture
.CubeMapSeamless
,
557 firstImage
->TexFormat
, firstImage
->_BaseFormat
,
558 texObj
->_IsIntegerFormat
,
560 sampler_state
, batch_offset_for_sampler_state
);
564 brw_upload_sampler_state_table(struct brw_context
*brw
,
565 struct gl_program
*prog
,
566 struct brw_stage_state
*stage_state
)
568 struct gl_context
*ctx
= &brw
->ctx
;
569 uint32_t sampler_count
= stage_state
->sampler_count
;
571 GLbitfield SamplersUsed
= prog
->SamplersUsed
;
573 if (sampler_count
== 0)
576 /* SAMPLER_STATE is 4 DWords on all platforms. */
577 const int dwords
= 4;
578 const int size_in_bytes
= dwords
* sizeof(uint32_t);
580 uint32_t *sampler_state
= brw_state_batch(brw
, AUB_TRACE_SAMPLER_STATE
,
581 sampler_count
* size_in_bytes
,
582 32, &stage_state
->sampler_offset
);
583 memset(sampler_state
, 0, sampler_count
* size_in_bytes
);
585 uint32_t batch_offset_for_sampler_state
= stage_state
->sampler_offset
;
587 for (unsigned s
= 0; s
< sampler_count
; s
++) {
588 if (SamplersUsed
& (1 << s
)) {
589 const unsigned unit
= prog
->SamplerUnits
[s
];
590 if (ctx
->Texture
.Unit
[unit
]._Current
) {
591 update_sampler_state(brw
, unit
, sampler_state
,
592 batch_offset_for_sampler_state
);
596 sampler_state
+= dwords
;
597 batch_offset_for_sampler_state
+= size_in_bytes
;
600 if (brw
->gen
>= 7 && stage_state
->stage
!= MESA_SHADER_COMPUTE
) {
601 /* Emit a 3DSTATE_SAMPLER_STATE_POINTERS_XS packet. */
602 gen7_emit_sampler_state_pointers_xs(brw
, stage_state
);
604 /* Flag that the sampler state table pointer has changed; later atoms
607 brw
->ctx
.NewDriverState
|= BRW_NEW_SAMPLER_STATE_TABLE
;
612 brw_upload_fs_samplers(struct brw_context
*brw
)
614 /* BRW_NEW_FRAGMENT_PROGRAM */
615 struct gl_program
*fs
= (struct gl_program
*) brw
->fragment_program
;
616 brw_upload_sampler_state_table(brw
, fs
, &brw
->wm
.base
);
619 const struct brw_tracked_state brw_fs_samplers
= {
621 .mesa
= _NEW_TEXTURE
,
622 .brw
= BRW_NEW_BATCH
|
624 BRW_NEW_FRAGMENT_PROGRAM
,
626 .emit
= brw_upload_fs_samplers
,
630 brw_upload_vs_samplers(struct brw_context
*brw
)
632 /* BRW_NEW_VERTEX_PROGRAM */
633 struct gl_program
*vs
= (struct gl_program
*) brw
->vertex_program
;
634 brw_upload_sampler_state_table(brw
, vs
, &brw
->vs
.base
);
638 const struct brw_tracked_state brw_vs_samplers
= {
640 .mesa
= _NEW_TEXTURE
,
641 .brw
= BRW_NEW_BATCH
|
643 BRW_NEW_VERTEX_PROGRAM
,
645 .emit
= brw_upload_vs_samplers
,
650 brw_upload_gs_samplers(struct brw_context
*brw
)
652 /* BRW_NEW_GEOMETRY_PROGRAM */
653 struct gl_program
*gs
= (struct gl_program
*) brw
->geometry_program
;
657 brw_upload_sampler_state_table(brw
, gs
, &brw
->gs
.base
);
661 const struct brw_tracked_state brw_gs_samplers
= {
663 .mesa
= _NEW_TEXTURE
,
664 .brw
= BRW_NEW_BATCH
|
666 BRW_NEW_GEOMETRY_PROGRAM
,
668 .emit
= brw_upload_gs_samplers
,
673 brw_upload_tcs_samplers(struct brw_context
*brw
)
675 /* BRW_NEW_TESS_PROGRAMS */
676 struct gl_program
*tcs
= (struct gl_program
*) brw
->tess_ctrl_program
;
680 brw_upload_sampler_state_table(brw
, tcs
, &brw
->tcs
.base
);
684 const struct brw_tracked_state brw_tcs_samplers
= {
686 .mesa
= _NEW_TEXTURE
,
687 .brw
= BRW_NEW_BATCH
|
689 BRW_NEW_TESS_PROGRAMS
,
691 .emit
= brw_upload_tcs_samplers
,
696 brw_upload_tes_samplers(struct brw_context
*brw
)
698 /* BRW_NEW_TESS_PROGRAMS */
699 struct gl_program
*tes
= (struct gl_program
*) brw
->tess_eval_program
;
703 brw_upload_sampler_state_table(brw
, tes
, &brw
->tes
.base
);
707 const struct brw_tracked_state brw_tes_samplers
= {
709 .mesa
= _NEW_TEXTURE
,
710 .brw
= BRW_NEW_BATCH
|
712 BRW_NEW_TESS_PROGRAMS
,
714 .emit
= brw_upload_tes_samplers
,
718 brw_upload_cs_samplers(struct brw_context
*brw
)
720 /* BRW_NEW_COMPUTE_PROGRAM */
721 struct gl_program
*cs
= (struct gl_program
*) brw
->compute_program
;
725 brw_upload_sampler_state_table(brw
, cs
, &brw
->cs
.base
);
728 const struct brw_tracked_state brw_cs_samplers
= {
730 .mesa
= _NEW_TEXTURE
,
731 .brw
= BRW_NEW_BATCH
|
733 BRW_NEW_COMPUTE_PROGRAM
,
735 .emit
= brw_upload_cs_samplers
,