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