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
,
95 unsigned shadow_function
,
96 bool non_normalized_coordinates
,
97 uint32_t border_color_offset
)
99 ss
[0] = BRW_SAMPLER_LOD_PRECLAMP_ENABLE
|
100 SET_FIELD(mip_filter
, BRW_SAMPLER_MIP_FILTER
) |
101 SET_FIELD(mag_filter
, BRW_SAMPLER_MAG_FILTER
) |
102 SET_FIELD(min_filter
, BRW_SAMPLER_MIN_FILTER
);
104 ss
[2] = border_color_offset
;
106 ss
[2] += brw
->batch
.bo
->offset64
; /* reloc */
107 brw_emit_reloc(&brw
->batch
, 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 /* This field has existed since the original i965, but is declared MBZ
136 * until Sandy Bridge. According to the PRM:
138 * "This was added to match OpenGL semantics"
140 * In particular, OpenGL allowed you to offset by 0.5 in certain cases
141 * to get slightly better filtering. On Ivy Bridge and above, it
142 * appears that this is added to RENDER_SURFACE_STATE::SurfaceMinLOD so
143 * the right value is 0.0 or 0.5 (if you want the wacky behavior). On
144 * Sandy Bridge, however, this sum does not seem to occur and you have
145 * to set it to the actual base level of the texture.
148 ss
[0] |= SET_FIELD(base_level
, BRW_SAMPLER_BASE_MIPLEVEL
);
150 if (brw
->gen
== 6 && min_filter
!= mag_filter
)
151 ss
[0] |= GEN6_SAMPLER_MIN_MAG_NOT_EQUAL
;
153 ss
[1] = SET_FIELD(min_lod
, GEN4_SAMPLER_MIN_LOD
) |
154 SET_FIELD(max_lod
, GEN4_SAMPLER_MAX_LOD
) |
155 SET_FIELD(wrap_s
, BRW_SAMPLER_TCX_WRAP_MODE
) |
156 SET_FIELD(wrap_t
, BRW_SAMPLER_TCY_WRAP_MODE
) |
157 SET_FIELD(wrap_r
, BRW_SAMPLER_TCZ_WRAP_MODE
);
159 if (brw
->gen
>= 6 && non_normalized_coordinates
)
160 ss
[3] |= GEN6_SAMPLER_NON_NORMALIZED_COORDINATES
;
165 translate_wrap_mode(struct brw_context
*brw
, GLenum wrap
, bool using_nearest
)
169 return BRW_TEXCOORDMODE_WRAP
;
171 /* GL_CLAMP is the weird mode where coordinates are clamped to
172 * [0.0, 1.0], so linear filtering of coordinates outside of
173 * [0.0, 1.0] give you half edge texel value and half border
176 * Gen8+ supports this natively.
179 return GEN8_TEXCOORDMODE_HALF_BORDER
;
181 /* On Gen4-7.5, we clamp the coordinates in the fragment shader
182 * and set clamp_border here, which gets the result desired.
183 * We just use clamp(_to_edge) for nearest, because for nearest
184 * clamping to 1.0 gives border color instead of the desired
188 return BRW_TEXCOORDMODE_CLAMP
;
190 return BRW_TEXCOORDMODE_CLAMP_BORDER
;
191 case GL_CLAMP_TO_EDGE
:
192 return BRW_TEXCOORDMODE_CLAMP
;
193 case GL_CLAMP_TO_BORDER
:
194 return BRW_TEXCOORDMODE_CLAMP_BORDER
;
195 case GL_MIRRORED_REPEAT
:
196 return BRW_TEXCOORDMODE_MIRROR
;
197 case GL_MIRROR_CLAMP_TO_EDGE
:
198 return BRW_TEXCOORDMODE_MIRROR_ONCE
;
200 return BRW_TEXCOORDMODE_WRAP
;
205 * Return true if the given wrap mode requires the border color to exist.
208 wrap_mode_needs_border_color(unsigned wrap_mode
)
210 return wrap_mode
== BRW_TEXCOORDMODE_CLAMP_BORDER
||
211 wrap_mode
== GEN8_TEXCOORDMODE_HALF_BORDER
;
215 has_component(mesa_format format
, int i
)
217 if (_mesa_is_format_color_format(format
))
218 return _mesa_format_has_color_component(format
, i
);
220 /* depth and stencil have only one component */
225 * Upload SAMPLER_BORDER_COLOR_STATE.
228 upload_default_color(struct brw_context
*brw
,
229 const struct gl_sampler_object
*sampler
,
230 mesa_format format
, GLenum base_format
,
231 bool is_integer_format
, bool is_stencil_sampling
,
232 uint32_t *sdc_offset
)
234 union gl_color_union color
;
236 switch (base_format
) {
237 case GL_DEPTH_COMPONENT
:
238 /* GL specs that border color for depth textures is taken from the
239 * R channel, while the hardware uses A. Spam R into all the
240 * channels for safety.
242 color
.ui
[0] = sampler
->BorderColor
.ui
[0];
243 color
.ui
[1] = sampler
->BorderColor
.ui
[0];
244 color
.ui
[2] = sampler
->BorderColor
.ui
[0];
245 color
.ui
[3] = sampler
->BorderColor
.ui
[0];
251 color
.ui
[3] = sampler
->BorderColor
.ui
[3];
254 color
.ui
[0] = sampler
->BorderColor
.ui
[0];
255 color
.ui
[1] = sampler
->BorderColor
.ui
[0];
256 color
.ui
[2] = sampler
->BorderColor
.ui
[0];
257 color
.ui
[3] = sampler
->BorderColor
.ui
[0];
260 color
.ui
[0] = sampler
->BorderColor
.ui
[0];
261 color
.ui
[1] = sampler
->BorderColor
.ui
[0];
262 color
.ui
[2] = sampler
->BorderColor
.ui
[0];
263 color
.ui
[3] = float_as_int(1.0);
265 case GL_LUMINANCE_ALPHA
:
266 color
.ui
[0] = sampler
->BorderColor
.ui
[0];
267 color
.ui
[1] = sampler
->BorderColor
.ui
[0];
268 color
.ui
[2] = sampler
->BorderColor
.ui
[0];
269 color
.ui
[3] = sampler
->BorderColor
.ui
[3];
272 color
.ui
[0] = sampler
->BorderColor
.ui
[0];
273 color
.ui
[1] = sampler
->BorderColor
.ui
[1];
274 color
.ui
[2] = sampler
->BorderColor
.ui
[2];
275 color
.ui
[3] = sampler
->BorderColor
.ui
[3];
279 /* In some cases we use an RGBA surface format for GL RGB textures,
280 * where we've initialized the A channel to 1.0. We also have to set
281 * the border color alpha to 1.0 in that case.
283 if (base_format
== GL_RGB
)
284 color
.ui
[3] = float_as_int(1.0);
287 /* On Broadwell, the border color is represented as four 32-bit floats,
288 * integers, or unsigned values, interpreted according to the surface
289 * format. This matches the sampler->BorderColor union exactly; just
292 uint32_t *sdc
= brw_state_batch(brw
, 4 * 4, 64, sdc_offset
);
293 memcpy(sdc
, color
.ui
, 4 * 4);
294 } else if (brw
->is_haswell
&& (is_integer_format
|| is_stencil_sampling
)) {
295 /* Haswell's integer border color support is completely insane:
296 * SAMPLER_BORDER_COLOR_STATE is 20 DWords. The first four are
297 * for float colors. The next 12 DWords are MBZ and only exist to
298 * pad it out to a 64 byte cacheline boundary. DWords 16-19 then
299 * contain integer colors; these are only used if SURFACE_STATE
300 * has the "Integer Surface Format" bit set. Even then, the
301 * arrangement of the RGBA data devolves into madness.
303 uint32_t *sdc
= brw_state_batch(brw
, 20 * 4, 512, sdc_offset
);
304 memset(sdc
, 0, 20 * 4);
307 bool stencil
= format
== MESA_FORMAT_S_UINT8
|| is_stencil_sampling
;
308 const int bits_per_channel
=
309 _mesa_get_format_bits(format
, stencil
? GL_STENCIL_BITS
: GL_RED_BITS
);
311 /* From the Haswell PRM, "Command Reference: Structures", Page 36:
312 * "If any color channel is missing from the surface format,
313 * corresponding border color should be programmed as zero and if
314 * alpha channel is missing, corresponding Alpha border color should
315 * be programmed as 1."
317 unsigned c
[4] = { 0, 0, 0, 1 };
318 for (int i
= 0; i
< 4; i
++) {
319 if (has_component(format
, i
))
323 switch (bits_per_channel
) {
325 /* Copy RGBA in order. */
326 for (int i
= 0; i
< 4; i
++)
327 ((uint8_t *) sdc
)[i
] = c
[i
];
330 /* R10G10B10A2_UINT is treated like a 16-bit format. */
332 ((uint16_t *) sdc
)[0] = c
[0]; /* R -> DWord 0, bits 15:0 */
333 ((uint16_t *) sdc
)[1] = c
[1]; /* G -> DWord 0, bits 31:16 */
334 /* DWord 1 is Reserved/MBZ! */
335 ((uint16_t *) sdc
)[4] = c
[2]; /* B -> DWord 2, bits 15:0 */
336 ((uint16_t *) sdc
)[5] = c
[3]; /* A -> DWord 3, bits 31:16 */
339 if (base_format
== GL_RG
) {
340 /* Careful inspection of the tables reveals that for RG32 formats,
341 * the green channel needs to go where blue normally belongs.
347 /* Copy RGBA in order. */
348 for (int i
= 0; i
< 4; i
++)
353 assert(!"Invalid number of bits per channel in integer format.");
356 } else if (brw
->gen
== 5 || brw
->gen
== 6) {
357 struct gen5_sampler_default_color
*sdc
;
359 sdc
= brw_state_batch(brw
, sizeof(*sdc
), 32, sdc_offset
);
361 memset(sdc
, 0, sizeof(*sdc
));
363 UNCLAMPED_FLOAT_TO_UBYTE(sdc
->ub
[0], color
.f
[0]);
364 UNCLAMPED_FLOAT_TO_UBYTE(sdc
->ub
[1], color
.f
[1]);
365 UNCLAMPED_FLOAT_TO_UBYTE(sdc
->ub
[2], color
.f
[2]);
366 UNCLAMPED_FLOAT_TO_UBYTE(sdc
->ub
[3], color
.f
[3]);
368 UNCLAMPED_FLOAT_TO_USHORT(sdc
->us
[0], color
.f
[0]);
369 UNCLAMPED_FLOAT_TO_USHORT(sdc
->us
[1], color
.f
[1]);
370 UNCLAMPED_FLOAT_TO_USHORT(sdc
->us
[2], color
.f
[2]);
371 UNCLAMPED_FLOAT_TO_USHORT(sdc
->us
[3], color
.f
[3]);
373 UNCLAMPED_FLOAT_TO_SHORT(sdc
->s
[0], color
.f
[0]);
374 UNCLAMPED_FLOAT_TO_SHORT(sdc
->s
[1], color
.f
[1]);
375 UNCLAMPED_FLOAT_TO_SHORT(sdc
->s
[2], color
.f
[2]);
376 UNCLAMPED_FLOAT_TO_SHORT(sdc
->s
[3], color
.f
[3]);
378 sdc
->hf
[0] = _mesa_float_to_half(color
.f
[0]);
379 sdc
->hf
[1] = _mesa_float_to_half(color
.f
[1]);
380 sdc
->hf
[2] = _mesa_float_to_half(color
.f
[2]);
381 sdc
->hf
[3] = _mesa_float_to_half(color
.f
[3]);
383 sdc
->b
[0] = sdc
->s
[0] >> 8;
384 sdc
->b
[1] = sdc
->s
[1] >> 8;
385 sdc
->b
[2] = sdc
->s
[2] >> 8;
386 sdc
->b
[3] = sdc
->s
[3] >> 8;
388 sdc
->f
[0] = color
.f
[0];
389 sdc
->f
[1] = color
.f
[1];
390 sdc
->f
[2] = color
.f
[2];
391 sdc
->f
[3] = color
.f
[3];
393 float *sdc
= brw_state_batch(brw
, 4 * 4, 32, sdc_offset
);
394 memcpy(sdc
, color
.f
, 4 * 4);
399 * Sets the sampler state for a single unit based off of the sampler key
403 brw_update_sampler_state(struct brw_context
*brw
,
404 GLenum target
, bool tex_cube_map_seamless
,
405 GLfloat tex_unit_lod_bias
,
406 mesa_format format
, GLenum base_format
,
407 const struct gl_texture_object
*texObj
,
408 const struct gl_sampler_object
*sampler
,
409 uint32_t *sampler_state
,
410 uint32_t batch_offset_for_sampler_state
)
412 unsigned min_filter
, mag_filter
, mip_filter
;
414 /* Select min and mip filters. */
415 switch (sampler
->MinFilter
) {
417 min_filter
= BRW_MAPFILTER_NEAREST
;
418 mip_filter
= BRW_MIPFILTER_NONE
;
421 min_filter
= BRW_MAPFILTER_LINEAR
;
422 mip_filter
= BRW_MIPFILTER_NONE
;
424 case GL_NEAREST_MIPMAP_NEAREST
:
425 min_filter
= BRW_MAPFILTER_NEAREST
;
426 mip_filter
= BRW_MIPFILTER_NEAREST
;
428 case GL_LINEAR_MIPMAP_NEAREST
:
429 min_filter
= BRW_MAPFILTER_LINEAR
;
430 mip_filter
= BRW_MIPFILTER_NEAREST
;
432 case GL_NEAREST_MIPMAP_LINEAR
:
433 min_filter
= BRW_MAPFILTER_NEAREST
;
434 mip_filter
= BRW_MIPFILTER_LINEAR
;
436 case GL_LINEAR_MIPMAP_LINEAR
:
437 min_filter
= BRW_MAPFILTER_LINEAR
;
438 mip_filter
= BRW_MIPFILTER_LINEAR
;
441 unreachable("not reached");
444 /* Select mag filter. */
445 if (sampler
->MagFilter
== GL_LINEAR
)
446 mag_filter
= BRW_MAPFILTER_LINEAR
;
448 mag_filter
= BRW_MAPFILTER_NEAREST
;
450 /* Enable anisotropic filtering if desired. */
451 unsigned max_anisotropy
= BRW_ANISORATIO_2
;
452 if (sampler
->MaxAnisotropy
> 1.0f
) {
453 min_filter
= BRW_MAPFILTER_ANISOTROPIC
;
454 mag_filter
= BRW_MAPFILTER_ANISOTROPIC
;
456 if (sampler
->MaxAnisotropy
> 2.0f
) {
458 MIN2((sampler
->MaxAnisotropy
- 2) / 2, BRW_ANISORATIO_16
);
462 /* Set address rounding bits if not using nearest filtering. */
463 unsigned address_rounding
= 0;
464 if (min_filter
!= BRW_MAPFILTER_NEAREST
) {
465 address_rounding
|= BRW_ADDRESS_ROUNDING_ENABLE_U_MIN
|
466 BRW_ADDRESS_ROUNDING_ENABLE_V_MIN
|
467 BRW_ADDRESS_ROUNDING_ENABLE_R_MIN
;
469 if (mag_filter
!= BRW_MAPFILTER_NEAREST
) {
470 address_rounding
|= BRW_ADDRESS_ROUNDING_ENABLE_U_MAG
|
471 BRW_ADDRESS_ROUNDING_ENABLE_V_MAG
|
472 BRW_ADDRESS_ROUNDING_ENABLE_R_MAG
;
475 bool either_nearest
=
476 sampler
->MinFilter
== GL_NEAREST
|| sampler
->MagFilter
== GL_NEAREST
;
477 unsigned wrap_s
= translate_wrap_mode(brw
, sampler
->WrapS
, either_nearest
);
478 unsigned wrap_t
= translate_wrap_mode(brw
, sampler
->WrapT
, either_nearest
);
479 unsigned wrap_r
= translate_wrap_mode(brw
, sampler
->WrapR
, either_nearest
);
481 if (target
== GL_TEXTURE_CUBE_MAP
||
482 target
== GL_TEXTURE_CUBE_MAP_ARRAY
) {
483 /* Cube maps must use the same wrap mode for all three coordinate
484 * dimensions. Prior to Haswell, only CUBE and CLAMP are valid.
486 * Ivybridge and Baytrail seem to have problems with CUBE mode and
487 * integer formats. Fall back to CLAMP for now.
489 if ((tex_cube_map_seamless
|| sampler
->CubeMapSeamless
) &&
490 !(brw
->gen
== 7 && !brw
->is_haswell
&& texObj
->_IsIntegerFormat
)) {
491 wrap_s
= BRW_TEXCOORDMODE_CUBE
;
492 wrap_t
= BRW_TEXCOORDMODE_CUBE
;
493 wrap_r
= BRW_TEXCOORDMODE_CUBE
;
495 wrap_s
= BRW_TEXCOORDMODE_CLAMP
;
496 wrap_t
= BRW_TEXCOORDMODE_CLAMP
;
497 wrap_r
= BRW_TEXCOORDMODE_CLAMP
;
499 } else if (target
== GL_TEXTURE_1D
) {
500 /* There's a bug in 1D texture sampling - it actually pays
501 * attention to the wrap_t value, though it should not.
502 * Override the wrap_t value here to GL_REPEAT to keep
503 * any nonexistent border pixels from floating in.
505 wrap_t
= BRW_TEXCOORDMODE_WRAP
;
508 /* Set shadow function. */
509 unsigned shadow_function
= 0;
510 if (sampler
->CompareMode
== GL_COMPARE_R_TO_TEXTURE_ARB
) {
512 intel_translate_shadow_compare_func(sampler
->CompareFunc
);
515 const int lod_bits
= brw
->gen
>= 7 ? 8 : 6;
516 const float hw_max_lod
= brw
->gen
>= 7 ? 14 : 13;
517 const unsigned base_level
=
518 U_FIXED(CLAMP(texObj
->MinLevel
+ texObj
->BaseLevel
, 0, hw_max_lod
), 1);
519 const unsigned min_lod
=
520 U_FIXED(CLAMP(sampler
->MinLod
, 0, hw_max_lod
), lod_bits
);
521 const unsigned max_lod
=
522 U_FIXED(CLAMP(sampler
->MaxLod
, 0, hw_max_lod
), lod_bits
);
524 S_FIXED(CLAMP(tex_unit_lod_bias
+ sampler
->LodBias
, -16, 15), lod_bits
);
526 /* Upload the border color if necessary. If not, just point it at
527 * offset 0 (the start of the batch) - the color should be ignored,
528 * but that address won't fault in case something reads it anyway.
530 uint32_t border_color_offset
= 0;
531 if (wrap_mode_needs_border_color(wrap_s
) ||
532 wrap_mode_needs_border_color(wrap_t
) ||
533 wrap_mode_needs_border_color(wrap_r
)) {
534 upload_default_color(brw
, sampler
, format
, base_format
,
535 texObj
->_IsIntegerFormat
, texObj
->StencilSampling
,
536 &border_color_offset
);
539 const bool non_normalized_coords
= target
== GL_TEXTURE_RECTANGLE
;
541 brw_emit_sampler_state(brw
,
543 batch_offset_for_sampler_state
,
544 min_filter
, mag_filter
, mip_filter
,
547 wrap_s
, wrap_t
, wrap_r
,
548 base_level
, min_lod
, max_lod
, lod_bias
,
550 non_normalized_coords
,
551 border_color_offset
);
555 update_sampler_state(struct brw_context
*brw
,
557 uint32_t *sampler_state
,
558 uint32_t batch_offset_for_sampler_state
)
560 struct gl_context
*ctx
= &brw
->ctx
;
561 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
562 const struct gl_texture_object
*texObj
= texUnit
->_Current
;
563 const struct gl_sampler_object
*sampler
= _mesa_get_samplerobj(ctx
, unit
);
565 /* These don't use samplers at all. */
566 if (texObj
->Target
== GL_TEXTURE_BUFFER
)
569 struct gl_texture_image
*firstImage
= texObj
->Image
[0][texObj
->BaseLevel
];
570 brw_update_sampler_state(brw
, texObj
->Target
, ctx
->Texture
.CubeMapSeamless
,
572 firstImage
->TexFormat
, firstImage
->_BaseFormat
,
574 sampler_state
, batch_offset_for_sampler_state
);
578 brw_upload_sampler_state_table(struct brw_context
*brw
,
579 struct gl_program
*prog
,
580 struct brw_stage_state
*stage_state
)
582 struct gl_context
*ctx
= &brw
->ctx
;
583 uint32_t sampler_count
= stage_state
->sampler_count
;
585 GLbitfield SamplersUsed
= prog
->SamplersUsed
;
587 if (sampler_count
== 0)
590 /* SAMPLER_STATE is 4 DWords on all platforms. */
591 const int dwords
= 4;
592 const int size_in_bytes
= dwords
* sizeof(uint32_t);
594 uint32_t *sampler_state
= brw_state_batch(brw
,
595 sampler_count
* size_in_bytes
,
596 32, &stage_state
->sampler_offset
);
597 memset(sampler_state
, 0, sampler_count
* size_in_bytes
);
599 uint32_t batch_offset_for_sampler_state
= stage_state
->sampler_offset
;
601 for (unsigned s
= 0; s
< sampler_count
; s
++) {
602 if (SamplersUsed
& (1 << s
)) {
603 const unsigned unit
= prog
->SamplerUnits
[s
];
604 if (ctx
->Texture
.Unit
[unit
]._Current
) {
605 update_sampler_state(brw
, unit
, sampler_state
,
606 batch_offset_for_sampler_state
);
610 sampler_state
+= dwords
;
611 batch_offset_for_sampler_state
+= size_in_bytes
;
614 if (brw
->gen
>= 7 && stage_state
->stage
!= MESA_SHADER_COMPUTE
) {
615 /* Emit a 3DSTATE_SAMPLER_STATE_POINTERS_XS packet. */
616 gen7_emit_sampler_state_pointers_xs(brw
, stage_state
);
618 /* Flag that the sampler state table pointer has changed; later atoms
621 brw
->ctx
.NewDriverState
|= BRW_NEW_SAMPLER_STATE_TABLE
;
626 brw_upload_fs_samplers(struct brw_context
*brw
)
628 /* BRW_NEW_FRAGMENT_PROGRAM */
629 struct gl_program
*fs
= (struct gl_program
*) brw
->fragment_program
;
630 brw_upload_sampler_state_table(brw
, fs
, &brw
->wm
.base
);
633 const struct brw_tracked_state brw_fs_samplers
= {
635 .mesa
= _NEW_TEXTURE
,
636 .brw
= BRW_NEW_BATCH
|
638 BRW_NEW_FRAGMENT_PROGRAM
,
640 .emit
= brw_upload_fs_samplers
,
644 brw_upload_vs_samplers(struct brw_context
*brw
)
646 /* BRW_NEW_VERTEX_PROGRAM */
647 struct gl_program
*vs
= (struct gl_program
*) brw
->vertex_program
;
648 brw_upload_sampler_state_table(brw
, vs
, &brw
->vs
.base
);
652 const struct brw_tracked_state brw_vs_samplers
= {
654 .mesa
= _NEW_TEXTURE
,
655 .brw
= BRW_NEW_BATCH
|
657 BRW_NEW_VERTEX_PROGRAM
,
659 .emit
= brw_upload_vs_samplers
,
664 brw_upload_gs_samplers(struct brw_context
*brw
)
666 /* BRW_NEW_GEOMETRY_PROGRAM */
667 struct gl_program
*gs
= (struct gl_program
*) brw
->geometry_program
;
671 brw_upload_sampler_state_table(brw
, gs
, &brw
->gs
.base
);
675 const struct brw_tracked_state brw_gs_samplers
= {
677 .mesa
= _NEW_TEXTURE
,
678 .brw
= BRW_NEW_BATCH
|
680 BRW_NEW_GEOMETRY_PROGRAM
,
682 .emit
= brw_upload_gs_samplers
,
687 brw_upload_tcs_samplers(struct brw_context
*brw
)
689 /* BRW_NEW_TESS_PROGRAMS */
690 struct gl_program
*tcs
= (struct gl_program
*) brw
->tess_ctrl_program
;
694 brw_upload_sampler_state_table(brw
, tcs
, &brw
->tcs
.base
);
698 const struct brw_tracked_state brw_tcs_samplers
= {
700 .mesa
= _NEW_TEXTURE
,
701 .brw
= BRW_NEW_BATCH
|
703 BRW_NEW_TESS_PROGRAMS
,
705 .emit
= brw_upload_tcs_samplers
,
710 brw_upload_tes_samplers(struct brw_context
*brw
)
712 /* BRW_NEW_TESS_PROGRAMS */
713 struct gl_program
*tes
= (struct gl_program
*) brw
->tess_eval_program
;
717 brw_upload_sampler_state_table(brw
, tes
, &brw
->tes
.base
);
721 const struct brw_tracked_state brw_tes_samplers
= {
723 .mesa
= _NEW_TEXTURE
,
724 .brw
= BRW_NEW_BATCH
|
726 BRW_NEW_TESS_PROGRAMS
,
728 .emit
= brw_upload_tes_samplers
,
732 brw_upload_cs_samplers(struct brw_context
*brw
)
734 /* BRW_NEW_COMPUTE_PROGRAM */
735 struct gl_program
*cs
= (struct gl_program
*) brw
->compute_program
;
739 brw_upload_sampler_state_table(brw
, cs
, &brw
->cs
.base
);
742 const struct brw_tracked_state brw_cs_samplers
= {
744 .mesa
= _NEW_TEXTURE
,
745 .brw
= BRW_NEW_BATCH
|
747 BRW_NEW_COMPUTE_PROGRAM
,
749 .emit
= brw_upload_cs_samplers
,