i965: Move CACHE_NEW_SAMPLER to BRW_NEW_SAMPLER_STATE_TABLE.
[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_ALGORITHM;
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 static 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 * Return true if the given wrap mode requires the border color to exist.
190 */
191 static bool
192 wrap_mode_needs_border_color(unsigned wrap_mode)
193 {
194 return wrap_mode == BRW_TEXCOORDMODE_CLAMP_BORDER ||
195 wrap_mode == GEN8_TEXCOORDMODE_HALF_BORDER;
196 }
197
198 /**
199 * Upload SAMPLER_BORDER_COLOR_STATE.
200 */
201 static void
202 upload_default_color(struct brw_context *brw,
203 const struct gl_sampler_object *sampler,
204 int unit,
205 uint32_t *sdc_offset)
206 {
207 struct gl_context *ctx = &brw->ctx;
208 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
209 struct gl_texture_object *texObj = texUnit->_Current;
210 struct gl_texture_image *firstImage = texObj->Image[0][texObj->BaseLevel];
211 float color[4];
212
213 switch (firstImage->_BaseFormat) {
214 case GL_DEPTH_COMPONENT:
215 /* GL specs that border color for depth textures is taken from the
216 * R channel, while the hardware uses A. Spam R into all the
217 * channels for safety.
218 */
219 color[0] = sampler->BorderColor.f[0];
220 color[1] = sampler->BorderColor.f[0];
221 color[2] = sampler->BorderColor.f[0];
222 color[3] = sampler->BorderColor.f[0];
223 break;
224 case GL_ALPHA:
225 color[0] = 0.0;
226 color[1] = 0.0;
227 color[2] = 0.0;
228 color[3] = sampler->BorderColor.f[3];
229 break;
230 case GL_INTENSITY:
231 color[0] = sampler->BorderColor.f[0];
232 color[1] = sampler->BorderColor.f[0];
233 color[2] = sampler->BorderColor.f[0];
234 color[3] = sampler->BorderColor.f[0];
235 break;
236 case GL_LUMINANCE:
237 color[0] = sampler->BorderColor.f[0];
238 color[1] = sampler->BorderColor.f[0];
239 color[2] = sampler->BorderColor.f[0];
240 color[3] = 1.0;
241 break;
242 case GL_LUMINANCE_ALPHA:
243 color[0] = sampler->BorderColor.f[0];
244 color[1] = sampler->BorderColor.f[0];
245 color[2] = sampler->BorderColor.f[0];
246 color[3] = sampler->BorderColor.f[3];
247 break;
248 default:
249 color[0] = sampler->BorderColor.f[0];
250 color[1] = sampler->BorderColor.f[1];
251 color[2] = sampler->BorderColor.f[2];
252 color[3] = sampler->BorderColor.f[3];
253 break;
254 }
255
256 /* In some cases we use an RGBA surface format for GL RGB textures,
257 * where we've initialized the A channel to 1.0. We also have to set
258 * the border color alpha to 1.0 in that case.
259 */
260 if (firstImage->_BaseFormat == GL_RGB)
261 color[3] = 1.0;
262
263 if (brw->gen >= 8) {
264 /* On Broadwell, the border color is represented as four 32-bit floats,
265 * integers, or unsigned values, interpreted according to the surface
266 * format. This matches the sampler->BorderColor union exactly. Since
267 * we use floats both here and in the above reswizzling code, we preserve
268 * the original bit pattern. So we actually handle all three formats.
269 */
270 float *sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
271 4 * 4, 64, sdc_offset);
272 COPY_4FV(sdc, color);
273 } else if (brw->gen == 5 || brw->gen == 6) {
274 struct gen5_sampler_default_color *sdc;
275
276 sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
277 sizeof(*sdc), 32, sdc_offset);
278
279 memset(sdc, 0, sizeof(*sdc));
280
281 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[0], color[0]);
282 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[1], color[1]);
283 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[2], color[2]);
284 UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[3], color[3]);
285
286 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[0], color[0]);
287 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[1], color[1]);
288 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[2], color[2]);
289 UNCLAMPED_FLOAT_TO_USHORT(sdc->us[3], color[3]);
290
291 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[0], color[0]);
292 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[1], color[1]);
293 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[2], color[2]);
294 UNCLAMPED_FLOAT_TO_SHORT(sdc->s[3], color[3]);
295
296 sdc->hf[0] = _mesa_float_to_half(color[0]);
297 sdc->hf[1] = _mesa_float_to_half(color[1]);
298 sdc->hf[2] = _mesa_float_to_half(color[2]);
299 sdc->hf[3] = _mesa_float_to_half(color[3]);
300
301 sdc->b[0] = sdc->s[0] >> 8;
302 sdc->b[1] = sdc->s[1] >> 8;
303 sdc->b[2] = sdc->s[2] >> 8;
304 sdc->b[3] = sdc->s[3] >> 8;
305
306 sdc->f[0] = color[0];
307 sdc->f[1] = color[1];
308 sdc->f[2] = color[2];
309 sdc->f[3] = color[3];
310 } else {
311 float *sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR,
312 4 * 4, 32, sdc_offset);
313 memcpy(sdc, color, 4 * 4);
314 }
315 }
316
317 /**
318 * Sets the sampler state for a single unit based off of the sampler key
319 * entry.
320 */
321 static void
322 brw_update_sampler_state(struct brw_context *brw,
323 int unit,
324 uint32_t *sampler_state,
325 uint32_t batch_offset_for_sampler_state)
326 {
327 struct gl_context *ctx = &brw->ctx;
328 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
329 const struct gl_texture_object *texObj = texUnit->_Current;
330 const struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
331
332 /* These don't use samplers at all. */
333 if (texObj->Target == GL_TEXTURE_BUFFER)
334 return;
335
336 unsigned min_filter, mag_filter, mip_filter;
337
338 /* Select min and mip filters. */
339 switch (sampler->MinFilter) {
340 case GL_NEAREST:
341 min_filter = BRW_MAPFILTER_NEAREST;
342 mip_filter = BRW_MIPFILTER_NONE;
343 break;
344 case GL_LINEAR:
345 min_filter = BRW_MAPFILTER_LINEAR;
346 mip_filter = BRW_MIPFILTER_NONE;
347 break;
348 case GL_NEAREST_MIPMAP_NEAREST:
349 min_filter = BRW_MAPFILTER_NEAREST;
350 mip_filter = BRW_MIPFILTER_NEAREST;
351 break;
352 case GL_LINEAR_MIPMAP_NEAREST:
353 min_filter = BRW_MAPFILTER_LINEAR;
354 mip_filter = BRW_MIPFILTER_NEAREST;
355 break;
356 case GL_NEAREST_MIPMAP_LINEAR:
357 min_filter = BRW_MAPFILTER_NEAREST;
358 mip_filter = BRW_MIPFILTER_LINEAR;
359 break;
360 case GL_LINEAR_MIPMAP_LINEAR:
361 min_filter = BRW_MAPFILTER_LINEAR;
362 mip_filter = BRW_MIPFILTER_LINEAR;
363 break;
364 default:
365 unreachable("not reached");
366 }
367
368 /* Select mag filter. */
369 if (sampler->MagFilter == GL_LINEAR)
370 mag_filter = BRW_MAPFILTER_LINEAR;
371 else
372 mag_filter = BRW_MAPFILTER_NEAREST;
373
374 /* Enable anisotropic filtering if desired. */
375 unsigned max_anisotropy = BRW_ANISORATIO_2;
376 if (sampler->MaxAnisotropy > 1.0) {
377 min_filter = BRW_MAPFILTER_ANISOTROPIC;
378 mag_filter = BRW_MAPFILTER_ANISOTROPIC;
379
380 if (sampler->MaxAnisotropy > 2.0) {
381 max_anisotropy =
382 MIN2((sampler->MaxAnisotropy - 2) / 2, BRW_ANISORATIO_16);
383 }
384 }
385
386 /* Set address rounding bits if not using nearest filtering. */
387 unsigned address_rounding = 0;
388 if (min_filter != BRW_MAPFILTER_NEAREST) {
389 address_rounding |= BRW_ADDRESS_ROUNDING_ENABLE_U_MIN |
390 BRW_ADDRESS_ROUNDING_ENABLE_V_MIN |
391 BRW_ADDRESS_ROUNDING_ENABLE_R_MIN;
392 }
393 if (mag_filter != BRW_MAPFILTER_NEAREST) {
394 address_rounding |= BRW_ADDRESS_ROUNDING_ENABLE_U_MAG |
395 BRW_ADDRESS_ROUNDING_ENABLE_V_MAG |
396 BRW_ADDRESS_ROUNDING_ENABLE_R_MAG;
397 }
398
399 bool either_nearest =
400 sampler->MinFilter == GL_NEAREST || sampler->MagFilter == GL_NEAREST;
401 unsigned wrap_s = translate_wrap_mode(brw, sampler->WrapS, either_nearest);
402 unsigned wrap_t = translate_wrap_mode(brw, sampler->WrapT, either_nearest);
403 unsigned wrap_r = translate_wrap_mode(brw, sampler->WrapR, either_nearest);
404
405 if (texObj->Target == GL_TEXTURE_CUBE_MAP ||
406 texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) {
407 /* Cube maps must use the same wrap mode for all three coordinate
408 * dimensions. Prior to Haswell, only CUBE and CLAMP are valid.
409 */
410 if ((ctx->Texture.CubeMapSeamless || sampler->CubeMapSeamless) &&
411 (sampler->MinFilter != GL_NEAREST ||
412 sampler->MagFilter != GL_NEAREST)) {
413 wrap_s = BRW_TEXCOORDMODE_CUBE;
414 wrap_t = BRW_TEXCOORDMODE_CUBE;
415 wrap_r = BRW_TEXCOORDMODE_CUBE;
416 } else {
417 wrap_s = BRW_TEXCOORDMODE_CLAMP;
418 wrap_t = BRW_TEXCOORDMODE_CLAMP;
419 wrap_r = BRW_TEXCOORDMODE_CLAMP;
420 }
421 } else if (texObj->Target == GL_TEXTURE_1D) {
422 /* There's a bug in 1D texture sampling - it actually pays
423 * attention to the wrap_t value, though it should not.
424 * Override the wrap_t value here to GL_REPEAT to keep
425 * any nonexistent border pixels from floating in.
426 */
427 wrap_t = BRW_TEXCOORDMODE_WRAP;
428 }
429
430 /* Set shadow function. */
431 unsigned shadow_function = 0;
432 if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
433 shadow_function =
434 intel_translate_shadow_compare_func(sampler->CompareFunc);
435 }
436
437 const int lod_bits = brw->gen >= 7 ? 8 : 6;
438 const unsigned min_lod = U_FIXED(CLAMP(sampler->MinLod, 0, 13), lod_bits);
439 const unsigned max_lod = U_FIXED(CLAMP(sampler->MaxLod, 0, 13), lod_bits);
440 const int lod_bias =
441 S_FIXED(CLAMP(texUnit->LodBias + sampler->LodBias, -16, 15), lod_bits);
442 const unsigned base_level = U_FIXED(0, 1);
443
444 /* Upload the border color if necessary. If not, just point it at
445 * offset 0 (the start of the batch) - the color should be ignored,
446 * but that address won't fault in case something reads it anyway.
447 */
448 uint32_t border_color_offset = 0;
449 if (wrap_mode_needs_border_color(wrap_s) ||
450 wrap_mode_needs_border_color(wrap_t) ||
451 wrap_mode_needs_border_color(wrap_r)) {
452 upload_default_color(brw, sampler, unit, &border_color_offset);
453 }
454
455 const bool non_normalized_coords = texObj->Target == GL_TEXTURE_RECTANGLE;
456
457 brw_emit_sampler_state(brw,
458 sampler_state,
459 batch_offset_for_sampler_state,
460 min_filter, mag_filter, mip_filter,
461 max_anisotropy,
462 address_rounding,
463 wrap_s, wrap_t, wrap_r,
464 min_lod, max_lod, lod_bias, base_level,
465 shadow_function,
466 non_normalized_coords,
467 border_color_offset);
468 }
469
470
471 static void
472 brw_upload_sampler_state_table(struct brw_context *brw,
473 struct gl_program *prog,
474 struct brw_stage_state *stage_state)
475 {
476 struct gl_context *ctx = &brw->ctx;
477 uint32_t sampler_count = stage_state->sampler_count;
478
479 GLbitfield SamplersUsed = prog->SamplersUsed;
480
481 if (sampler_count == 0)
482 return;
483
484 /* SAMPLER_STATE is 4 DWords on all platforms. */
485 const int dwords = 4;
486 const int size_in_bytes = dwords * sizeof(uint32_t);
487
488 uint32_t *sampler_state = brw_state_batch(brw, AUB_TRACE_SAMPLER_STATE,
489 sampler_count * size_in_bytes,
490 32, &stage_state->sampler_offset);
491 memset(sampler_state, 0, sampler_count * size_in_bytes);
492
493 uint32_t batch_offset_for_sampler_state = stage_state->sampler_offset;
494
495 for (unsigned s = 0; s < sampler_count; s++) {
496 if (SamplersUsed & (1 << s)) {
497 const unsigned unit = prog->SamplerUnits[s];
498 if (ctx->Texture.Unit[unit]._Current) {
499 brw_update_sampler_state(brw, unit, sampler_state,
500 batch_offset_for_sampler_state);
501 }
502 }
503
504 sampler_state += dwords;
505 batch_offset_for_sampler_state += size_in_bytes;
506 }
507
508 if (brw->gen >= 7) {
509 /* Emit a 3DSTATE_SAMPLER_STATE_POINTERS_XS packet. */
510 gen7_emit_sampler_state_pointers_xs(brw, stage_state);
511 } else {
512 /* Flag that the sampler state table pointer has changed; later atoms
513 * will handle it.
514 */
515 brw->state.dirty.brw |= BRW_NEW_SAMPLER_STATE_TABLE;
516 }
517 }
518
519 static void
520 brw_upload_fs_samplers(struct brw_context *brw)
521 {
522 /* BRW_NEW_FRAGMENT_PROGRAM */
523 struct gl_program *fs = (struct gl_program *) brw->fragment_program;
524 brw_upload_sampler_state_table(brw, fs, &brw->wm.base);
525 }
526
527 const struct brw_tracked_state brw_fs_samplers = {
528 .dirty = {
529 .mesa = _NEW_TEXTURE,
530 .brw = BRW_NEW_BATCH |
531 BRW_NEW_FRAGMENT_PROGRAM,
532 .cache = 0
533 },
534 .emit = brw_upload_fs_samplers,
535 };
536
537 static void
538 brw_upload_vs_samplers(struct brw_context *brw)
539 {
540 /* BRW_NEW_VERTEX_PROGRAM */
541 struct gl_program *vs = (struct gl_program *) brw->vertex_program;
542 brw_upload_sampler_state_table(brw, vs, &brw->vs.base);
543 }
544
545
546 const struct brw_tracked_state brw_vs_samplers = {
547 .dirty = {
548 .mesa = _NEW_TEXTURE,
549 .brw = BRW_NEW_BATCH |
550 BRW_NEW_VERTEX_PROGRAM,
551 .cache = 0
552 },
553 .emit = brw_upload_vs_samplers,
554 };
555
556
557 static void
558 brw_upload_gs_samplers(struct brw_context *brw)
559 {
560 /* BRW_NEW_GEOMETRY_PROGRAM */
561 struct gl_program *gs = (struct gl_program *) brw->geometry_program;
562 if (!gs)
563 return;
564
565 brw_upload_sampler_state_table(brw, gs, &brw->gs.base);
566 }
567
568
569 const struct brw_tracked_state brw_gs_samplers = {
570 .dirty = {
571 .mesa = _NEW_TEXTURE,
572 .brw = BRW_NEW_BATCH |
573 BRW_NEW_GEOMETRY_PROGRAM,
574 .cache = 0
575 },
576 .emit = brw_upload_gs_samplers,
577 };