i965: Make brw_update_sampler_state() use brw_emit_sampler_state().
[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 base_level,
92 unsigned shadow_function,
93 bool non_normalized_coordinates,
94 uint32_t border_color_offset)
95 {
96 ss[0] = BRW_SAMPLER_LOD_PRECLAMP_ENABLE |
97 SET_FIELD(base_level, BRW_SAMPLER_BASE_MIPLEVEL) |
98 SET_FIELD(mip_filter, BRW_SAMPLER_MIP_FILTER) |
99 SET_FIELD(mag_filter, BRW_SAMPLER_MAG_FILTER) |
100 SET_FIELD(min_filter, BRW_SAMPLER_MIN_FILTER);
101
102 ss[2] = border_color_offset;
103 if (brw->gen < 6) {
104 ss[2] += brw->batch.bo->offset64; /* reloc */
105 drm_intel_bo_emit_reloc(brw->batch.bo,
106 batch_offset_for_sampler_state + 8,
107 brw->batch.bo, border_color_offset,
108 I915_GEM_DOMAIN_SAMPLER, 0);
109 }
110
111 ss[3] = SET_FIELD(max_anisotropy, BRW_SAMPLER_MAX_ANISOTROPY) |
112 SET_FIELD(address_rounding, BRW_SAMPLER_ADDRESS_ROUNDING);
113
114 if (brw->gen >= 7) {
115 ss[0] |= SET_FIELD(lod_bias & 0x1fff, GEN7_SAMPLER_LOD_BIAS);
116
117 if (min_filter == BRW_MAPFILTER_ANISOTROPIC)
118 ss[0] |= GEN7_SAMPLER_EWA_ANISOTROPIC_ALGORIHTM;
119
120 ss[1] = SET_FIELD(min_lod, GEN7_SAMPLER_MIN_LOD) |
121 SET_FIELD(max_lod, GEN7_SAMPLER_MAX_LOD) |
122 SET_FIELD(shadow_function, GEN7_SAMPLER_SHADOW_FUNCTION);
123
124 ss[3] |= SET_FIELD(wrap_s, BRW_SAMPLER_TCX_WRAP_MODE) |
125 SET_FIELD(wrap_t, BRW_SAMPLER_TCY_WRAP_MODE) |
126 SET_FIELD(wrap_r, BRW_SAMPLER_TCZ_WRAP_MODE);
127
128 if (non_normalized_coordinates)
129 ss[3] |= GEN7_SAMPLER_NON_NORMALIZED_COORDINATES;
130 } else {
131 ss[0] |= SET_FIELD(lod_bias & 0x7ff, GEN4_SAMPLER_LOD_BIAS) |
132 SET_FIELD(shadow_function, GEN4_SAMPLER_SHADOW_FUNCTION);
133
134 if (brw->gen == 6 && min_filter != mag_filter)
135 ss[0] |= GEN6_SAMPLER_MIN_MAG_NOT_EQUAL;
136
137 ss[1] = SET_FIELD(min_lod, GEN4_SAMPLER_MIN_LOD) |
138 SET_FIELD(max_lod, GEN4_SAMPLER_MAX_LOD) |
139 SET_FIELD(wrap_s, BRW_SAMPLER_TCX_WRAP_MODE) |
140 SET_FIELD(wrap_t, BRW_SAMPLER_TCY_WRAP_MODE) |
141 SET_FIELD(wrap_r, BRW_SAMPLER_TCZ_WRAP_MODE);
142
143 if (brw->gen >= 6 && non_normalized_coordinates)
144 ss[3] |= GEN6_SAMPLER_NON_NORMALIZED_COORDINATES;
145 }
146 }
147
148 uint32_t
149 translate_wrap_mode(struct brw_context *brw, GLenum wrap, bool using_nearest)
150 {
151 switch( wrap ) {
152 case GL_REPEAT:
153 return BRW_TEXCOORDMODE_WRAP;
154 case GL_CLAMP:
155 /* GL_CLAMP is the weird mode where coordinates are clamped to
156 * [0.0, 1.0], so linear filtering of coordinates outside of
157 * [0.0, 1.0] give you half edge texel value and half border
158 * color.
159 *
160 * Gen8+ supports this natively.
161 */
162 if (brw->gen >= 8)
163 return GEN8_TEXCOORDMODE_HALF_BORDER;
164
165 /* On Gen4-7.5, we clamp the coordinates in the fragment shader
166 * and set clamp_border here, which gets the result desired.
167 * We just use clamp(_to_edge) for nearest, because for nearest
168 * clamping to 1.0 gives border color instead of the desired
169 * edge texels.
170 */
171 if (using_nearest)
172 return BRW_TEXCOORDMODE_CLAMP;
173 else
174 return BRW_TEXCOORDMODE_CLAMP_BORDER;
175 case GL_CLAMP_TO_EDGE:
176 return BRW_TEXCOORDMODE_CLAMP;
177 case GL_CLAMP_TO_BORDER:
178 return BRW_TEXCOORDMODE_CLAMP_BORDER;
179 case GL_MIRRORED_REPEAT:
180 return BRW_TEXCOORDMODE_MIRROR;
181 case GL_MIRROR_CLAMP_TO_EDGE:
182 return BRW_TEXCOORDMODE_MIRROR_ONCE;
183 default:
184 return BRW_TEXCOORDMODE_WRAP;
185 }
186 }
187
188 /**
189 * Upload SAMPLER_BORDER_COLOR_STATE.
190 */
191 void
192 upload_default_color(struct brw_context *brw,
193 const struct gl_sampler_object *sampler,
194 int unit,
195 uint32_t *sdc_offset)
196 {
197 struct gl_context *ctx = &brw->ctx;
198 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
199 struct gl_texture_object *texObj = texUnit->_Current;
200 struct gl_texture_image *firstImage = texObj->Image[0][texObj->BaseLevel];
201 float color[4];
202
203 switch (firstImage->_BaseFormat) {
204 case GL_DEPTH_COMPONENT:
205 /* GL specs that border color for depth textures is taken from the
206 * R channel, while the hardware uses A. Spam R into all the
207 * channels for safety.
208 */
209 color[0] = sampler->BorderColor.f[0];
210 color[1] = sampler->BorderColor.f[0];
211 color[2] = sampler->BorderColor.f[0];
212 color[3] = sampler->BorderColor.f[0];
213 break;
214 case GL_ALPHA:
215 color[0] = 0.0;
216 color[1] = 0.0;
217 color[2] = 0.0;
218 color[3] = sampler->BorderColor.f[3];
219 break;
220 case GL_INTENSITY:
221 color[0] = sampler->BorderColor.f[0];
222 color[1] = sampler->BorderColor.f[0];
223 color[2] = sampler->BorderColor.f[0];
224 color[3] = sampler->BorderColor.f[0];
225 break;
226 case GL_LUMINANCE:
227 color[0] = sampler->BorderColor.f[0];
228 color[1] = sampler->BorderColor.f[0];
229 color[2] = sampler->BorderColor.f[0];
230 color[3] = 1.0;
231 break;
232 case GL_LUMINANCE_ALPHA:
233 color[0] = sampler->BorderColor.f[0];
234 color[1] = sampler->BorderColor.f[0];
235 color[2] = sampler->BorderColor.f[0];
236 color[3] = sampler->BorderColor.f[3];
237 break;
238 default:
239 color[0] = sampler->BorderColor.f[0];
240 color[1] = sampler->BorderColor.f[1];
241 color[2] = sampler->BorderColor.f[2];
242 color[3] = sampler->BorderColor.f[3];
243 break;
244 }
245
246 /* In some cases we use an RGBA surface format for GL RGB textures,
247 * where we've initialized the A channel to 1.0. We also have to set
248 * the border color alpha to 1.0 in that case.
249 */
250 if (firstImage->_BaseFormat == GL_RGB)
251 color[3] = 1.0;
252
253 if (brw->gen >= 8) {
254 /* On Broadwell, the border color is represented as four 32-bit floats,
255 * integers, or unsigned values, interpreted according to the surface
256 * format. This matches the sampler->BorderColor union exactly. Since
257 * we use floats both here and in the above reswizzling code, we preserve
258 * the original bit pattern. So we actually handle all three formats.
259 */
260 float *sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
261 4 * 4, 64, sdc_offset);
262 COPY_4FV(sdc, color);
263 } else if (brw->gen == 5 || brw->gen == 6) {
264 struct gen5_sampler_default_color *sdc;
265
266 sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
267 sizeof(*sdc), 32, sdc_offset);
268
269 memset(sdc, 0, sizeof(*sdc));
270
271 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[0], color[0]);
272 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[1], color[1]);
273 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[2], color[2]);
274 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[3], color[3]);
275
276 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[0], color[0]);
277 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[1], color[1]);
278 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[2], color[2]);
279 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[3], color[3]);
280
281 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[0], color[0]);
282 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[1], color[1]);
283 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[2], color[2]);
284 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[3], color[3]);
285
286 sdc->hf[0] = _mesa_float_to_half(color[0]);
287 sdc->hf[1] = _mesa_float_to_half(color[1]);
288 sdc->hf[2] = _mesa_float_to_half(color[2]);
289 sdc->hf[3] = _mesa_float_to_half(color[3]);
290
291 sdc->b[0] = sdc->s[0] >> 8;
292 sdc->b[1] = sdc->s[1] >> 8;
293 sdc->b[2] = sdc->s[2] >> 8;
294 sdc->b[3] = sdc->s[3] >> 8;
295
296 sdc->f[0] = color[0];
297 sdc->f[1] = color[1];
298 sdc->f[2] = color[2];
299 sdc->f[3] = color[3];
300 } else {
301 float *sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
302 4 * 4, 32, sdc_offset);
303 memcpy(sdc, color, 4 * 4);
304 }
305 }
306
307 /**
308 * Sets the sampler state for a single unit based off of the sampler key
309 * entry.
310 */
311 static void
312 brw_update_sampler_state(struct brw_context *brw,
313 int unit,
314 uint32_t *sampler_state,
315 uint32_t batch_offset_for_sampler_state)
316 {
317 struct gl_context *ctx = &brw->ctx;
318 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
319 const struct gl_texture_object *texObj = texUnit->_Current;
320 const struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
321
322 /* These don't use samplers at all. */
323 if (texObj->Target == GL_TEXTURE_BUFFER)
324 return;
325
326 unsigned min_filter, mag_filter, mip_filter;
327
328 /* Select min and mip filters. */
329 switch (sampler->MinFilter) {
330 case GL_NEAREST:
331 min_filter = BRW_MAPFILTER_NEAREST;
332 mip_filter = BRW_MIPFILTER_NONE;
333 break;
334 case GL_LINEAR:
335 min_filter = BRW_MAPFILTER_LINEAR;
336 mip_filter = BRW_MIPFILTER_NONE;
337 break;
338 case GL_NEAREST_MIPMAP_NEAREST:
339 min_filter = BRW_MAPFILTER_NEAREST;
340 mip_filter = BRW_MIPFILTER_NEAREST;
341 break;
342 case GL_LINEAR_MIPMAP_NEAREST:
343 min_filter = BRW_MAPFILTER_LINEAR;
344 mip_filter = BRW_MIPFILTER_NEAREST;
345 break;
346 case GL_NEAREST_MIPMAP_LINEAR:
347 min_filter = BRW_MAPFILTER_NEAREST;
348 mip_filter = BRW_MIPFILTER_LINEAR;
349 break;
350 case GL_LINEAR_MIPMAP_LINEAR:
351 min_filter = BRW_MAPFILTER_LINEAR;
352 mip_filter = BRW_MIPFILTER_LINEAR;
353 break;
354 default:
355 break;
356 }
357
358 /* Select mag filter. */
359 if (sampler->MagFilter == GL_LINEAR)
360 mag_filter = BRW_MAPFILTER_LINEAR;
361 else
362 mag_filter = BRW_MAPFILTER_NEAREST;
363
364 /* Enable anisotropic filtering if desired. */
365 unsigned max_anisotropy = BRW_ANISORATIO_2;
366 if (sampler->MaxAnisotropy > 1.0) {
367 min_filter = BRW_MAPFILTER_ANISOTROPIC;
368 mag_filter = BRW_MAPFILTER_ANISOTROPIC;
369
370 if (sampler->MaxAnisotropy > 2.0) {
371 max_anisotropy =
372 MIN2((sampler->MaxAnisotropy - 2) / 2, BRW_ANISORATIO_16);
373 }
374 }
375
376 /* Set address rounding bits if not using nearest filtering. */
377 unsigned address_rounding = 0;
378 if (min_filter != BRW_MAPFILTER_NEAREST) {
379 address_rounding |= BRW_ADDRESS_ROUNDING_ENABLE_U_MIN |
380 BRW_ADDRESS_ROUNDING_ENABLE_V_MIN |
381 BRW_ADDRESS_ROUNDING_ENABLE_R_MIN;
382 }
383 if (mag_filter != BRW_MAPFILTER_NEAREST) {
384 address_rounding |= BRW_ADDRESS_ROUNDING_ENABLE_U_MAG |
385 BRW_ADDRESS_ROUNDING_ENABLE_V_MAG |
386 BRW_ADDRESS_ROUNDING_ENABLE_R_MAG;
387 }
388
389 bool either_nearest =
390 sampler->MinFilter == GL_NEAREST || sampler->MagFilter == GL_NEAREST;
391 unsigned wrap_s = translate_wrap_mode(brw, sampler->WrapS, either_nearest);
392 unsigned wrap_t = translate_wrap_mode(brw, sampler->WrapT, either_nearest);
393 unsigned wrap_r = translate_wrap_mode(brw, sampler->WrapR, either_nearest);
394
395 if (texObj->Target == GL_TEXTURE_CUBE_MAP ||
396 texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) {
397 /* Cube maps must use the same wrap mode for all three coordinate
398 * dimensions. Prior to Haswell, only CUBE and CLAMP are valid.
399 */
400 if ((ctx->Texture.CubeMapSeamless || sampler->CubeMapSeamless) &&
401 (sampler->MinFilter != GL_NEAREST ||
402 sampler->MagFilter != GL_NEAREST)) {
403 wrap_s = BRW_TEXCOORDMODE_CUBE;
404 wrap_t = BRW_TEXCOORDMODE_CUBE;
405 wrap_r = BRW_TEXCOORDMODE_CUBE;
406 } else {
407 wrap_s = BRW_TEXCOORDMODE_CLAMP;
408 wrap_t = BRW_TEXCOORDMODE_CLAMP;
409 wrap_r = BRW_TEXCOORDMODE_CLAMP;
410 }
411 } else if (texObj->Target == GL_TEXTURE_1D) {
412 /* There's a bug in 1D texture sampling - it actually pays
413 * attention to the wrap_t value, though it should not.
414 * Override the wrap_t value here to GL_REPEAT to keep
415 * any nonexistent border pixels from floating in.
416 */
417 wrap_t = BRW_TEXCOORDMODE_WRAP;
418 }
419
420 /* Set shadow function. */
421 unsigned shadow_function = 0;
422 if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
423 shadow_function =
424 intel_translate_shadow_compare_func(sampler->CompareFunc);
425 }
426
427 const unsigned min_lod = U_FIXED(CLAMP(sampler->MinLod, 0, 13), 6);
428 const unsigned max_lod = U_FIXED(CLAMP(sampler->MaxLod, 0, 13), 6);
429 const int lod_bias =
430 S_FIXED(CLAMP(texUnit->LodBias + sampler->LodBias, -16, 15), 6);
431 const unsigned base_level = U_FIXED(0, 1);
432
433 uint32_t border_color_offset;
434 upload_default_color(brw, sampler, unit, &border_color_offset);
435
436 const bool non_normalized_coords = texObj->Target == GL_TEXTURE_RECTANGLE;
437
438 brw_emit_sampler_state(brw,
439 sampler_state,
440 batch_offset_for_sampler_state,
441 min_filter, mag_filter, mip_filter,
442 max_anisotropy,
443 address_rounding,
444 wrap_s, wrap_t, wrap_r,
445 min_lod, max_lod, lod_bias, base_level,
446 shadow_function,
447 non_normalized_coords,
448 border_color_offset);
449 }
450
451
452 static void
453 brw_upload_sampler_state_table(struct brw_context *brw,
454 struct gl_program *prog,
455 struct brw_stage_state *stage_state)
456 {
457 struct gl_context *ctx = &brw->ctx;
458 uint32_t sampler_count = stage_state->sampler_count;
459
460 GLbitfield SamplersUsed = prog->SamplersUsed;
461
462 if (sampler_count == 0)
463 return;
464
465 /* SAMPLER_STATE is 4 DWords on all platforms. */
466 const int dwords = 4;
467 const int size_in_bytes = dwords * sizeof(uint32_t);
468
469 uint32_t *sampler_state = brw_state_batch(brw, AUB_TRACE_SAMPLER_STATE,
470 sampler_count * size_in_bytes,
471 32, &stage_state->sampler_offset);
472 memset(sampler_state, 0, sampler_count * size_in_bytes);
473
474 uint32_t batch_offset_for_sampler_state = stage_state->sampler_offset;
475
476 for (unsigned s = 0; s < sampler_count; s++) {
477 if (SamplersUsed & (1 << s)) {
478 const unsigned unit = prog->SamplerUnits[s];
479 if (ctx->Texture.Unit[unit]._Current) {
480 if (brw->gen >= 7) {
481 gen7_update_sampler_state(brw, unit,
482 (struct gen7_sampler_state *)
483 sampler_state);
484 } else {
485 brw_update_sampler_state(brw, unit,
486 sampler_state,
487 batch_offset_for_sampler_state);
488 }
489 }
490 }
491
492 sampler_state += dwords;
493 batch_offset_for_sampler_state += size_in_bytes;
494 }
495
496 if (brw->gen >= 7) {
497 /* Emit a 3DSTATE_SAMPLER_STATE_POINTERS_XS packet. */
498 gen7_emit_sampler_state_pointers_xs(brw, stage_state);
499 } else {
500 /* Flag that the sampler state table pointer has changed; later atoms
501 * will handle it.
502 */
503 brw->state.dirty.cache |= CACHE_NEW_SAMPLER;
504 }
505 }
506
507 static void
508 brw_upload_fs_samplers(struct brw_context *brw)
509 {
510 /* BRW_NEW_FRAGMENT_PROGRAM */
511 struct gl_program *fs = (struct gl_program *) brw->fragment_program;
512 brw_upload_sampler_state_table(brw, fs, &brw->wm.base);
513 }
514
515 const struct brw_tracked_state brw_fs_samplers = {
516 .dirty = {
517 .mesa = _NEW_TEXTURE,
518 .brw = BRW_NEW_BATCH |
519 BRW_NEW_FRAGMENT_PROGRAM,
520 .cache = 0
521 },
522 .emit = brw_upload_fs_samplers,
523 };
524
525 static void
526 brw_upload_vs_samplers(struct brw_context *brw)
527 {
528 /* BRW_NEW_VERTEX_PROGRAM */
529 struct gl_program *vs = (struct gl_program *) brw->vertex_program;
530 brw_upload_sampler_state_table(brw, vs, &brw->vs.base);
531 }
532
533
534 const struct brw_tracked_state brw_vs_samplers = {
535 .dirty = {
536 .mesa = _NEW_TEXTURE,
537 .brw = BRW_NEW_BATCH |
538 BRW_NEW_VERTEX_PROGRAM,
539 .cache = 0
540 },
541 .emit = brw_upload_vs_samplers,
542 };
543
544
545 static void
546 brw_upload_gs_samplers(struct brw_context *brw)
547 {
548 /* BRW_NEW_GEOMETRY_PROGRAM */
549 struct gl_program *gs = (struct gl_program *) brw->geometry_program;
550 if (!gs)
551 return;
552
553 brw_upload_sampler_state_table(brw, gs, &brw->gs.base);
554 }
555
556
557 const struct brw_tracked_state brw_gs_samplers = {
558 .dirty = {
559 .mesa = _NEW_TEXTURE,
560 .brw = BRW_NEW_BATCH |
561 BRW_NEW_GEOMETRY_PROGRAM,
562 .cache = 0
563 },
564 .emit = brw_upload_gs_samplers,
565 };