blob: e76832515fe68cc9ac63690b7ffd38b6086424f4 [file] [log] [blame]
Eric Anholt9f344b32006-08-09 19:14:05 +00001/*
2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) 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 <keith@tungstengraphics.com>
30 */
31
Eric Anholt9f344b32006-08-09 19:14:05 +000032#include "brw_context.h"
Eric Anholt9f344b32006-08-09 19:14:05 +000033#include "brw_wm.h"
34#include "brw_state.h"
Eric Anholtc3744872010-08-10 22:21:59 -070035#include "main/formats.h"
Eric Anholt1f32c662011-04-20 11:48:31 -070036#include "main/samplerobj.h"
Eric Anholt87527642011-05-16 15:10:26 -070037#include "program/prog_parameter.h"
Eric Anholt9f344b32006-08-09 19:14:05 +000038
Kenneth Graunke774fb902011-05-16 11:49:57 -070039#include "../glsl/ralloc.h"
40
Brian Paul32e03c42008-12-31 17:16:44 -070041/** Return number of src args for given instruction */
Eric Anholt9f344b32006-08-09 19:14:05 +000042GLuint brw_wm_nr_args( GLuint opcode )
43{
44 switch (opcode) {
Eric Anholt699db6d2009-03-23 16:29:31 -070045 case WM_FRONTFACING:
Eric Anholt9f344b32006-08-09 19:14:05 +000046 case WM_PIXELXY:
Eric Anholt08687c82009-08-12 12:54:43 -070047 return 0;
Eric Anholt046e88f2009-01-08 19:00:10 -080048 case WM_CINTERP:
49 case WM_WPOSXY:
Eric Anholt08687c82009-08-12 12:54:43 -070050 case WM_DELTAXY:
Eric Anholt9f344b32006-08-09 19:14:05 +000051 return 1;
Eric Anholt046e88f2009-01-08 19:00:10 -080052 case WM_LINTERP:
Eric Anholt9f344b32006-08-09 19:14:05 +000053 case WM_PIXELW:
54 return 2;
Eric Anholt9f344b32006-08-09 19:14:05 +000055 case WM_FB_WRITE:
Eric Anholt046e88f2009-01-08 19:00:10 -080056 case WM_PINTERP:
Eric Anholt9f344b32006-08-09 19:14:05 +000057 return 3;
Eric Anholt9f344b32006-08-09 19:14:05 +000058 default:
Eric Anholt046e88f2009-01-08 19:00:10 -080059 assert(opcode < MAX_OPCODE);
60 return _mesa_num_inst_src_regs(opcode);
Eric Anholt9f344b32006-08-09 19:14:05 +000061 }
62}
63
64
65GLuint brw_wm_is_scalar_result( GLuint opcode )
66{
67 switch (opcode) {
68 case OPCODE_COS:
69 case OPCODE_EX2:
70 case OPCODE_LG2:
71 case OPCODE_POW:
72 case OPCODE_RCP:
73 case OPCODE_RSQ:
74 case OPCODE_SIN:
Eric Anholtdd5ef332010-09-01 10:41:36 -070075 case OPCODE_DP2:
Eric Anholt9f344b32006-08-09 19:14:05 +000076 case OPCODE_DP3:
77 case OPCODE_DP4:
78 case OPCODE_DPH:
79 case OPCODE_DST:
80 return 1;
81
82 default:
83 return 0;
84 }
85}
86
87
Brian Paul2f78d4a2009-02-12 15:35:41 -070088/**
89 * Do GPU code generation for non-GLSL shader. non-GLSL shaders have
90 * no flow control instructions so we can more readily do SSA-style
91 * optimizations.
92 */
93static void
94brw_wm_non_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c)
95{
96 /* Augment fragment program. Add instructions for pre- and
97 * post-fragment-program tasks such as interpolation and fogging.
98 */
99 brw_wm_pass_fp(c);
100
101 /* Translate to intermediate representation. Build register usage
102 * chains.
103 */
104 brw_wm_pass0(c);
105
106 /* Dead code removal.
107 */
108 brw_wm_pass1(c);
109
110 /* Register allocation.
Brian Paul5f1ce6b2009-03-31 10:53:56 -0600111 * Divide by two because we operate on 16 pixels at a time and require
112 * two GRF entries for each logical shader register.
Brian Paul2f78d4a2009-02-12 15:35:41 -0700113 */
114 c->grf_limit = BRW_WM_MAX_GRF / 2;
115
116 brw_wm_pass2(c);
117
Brian Paul5f1ce6b2009-03-31 10:53:56 -0600118 /* how many general-purpose registers are used */
Eric Anholt17918572011-05-17 08:55:11 -0700119 c->prog_data.reg_blocks = brw_register_blocks(c->max_wm_grf);
Brian Paul5f1ce6b2009-03-31 10:53:56 -0600120
Brian Paul2f78d4a2009-02-12 15:35:41 -0700121 /* Emit GEN4 code.
122 */
123 brw_wm_emit(c);
124}
125
Eric Anholt662f1b42011-03-11 19:19:01 -0800126void
Eric Anholt16f8c822010-11-11 09:30:16 -0800127brw_wm_payload_setup(struct brw_context *brw,
128 struct brw_wm_compile *c)
129{
130 struct intel_context *intel = &brw->intel;
131 bool uses_depth = (c->fp->program.Base.InputsRead &
132 (1 << FRAG_ATTRIB_WPOS)) != 0;
133
134 if (intel->gen >= 6) {
135 /* R0-1: masks, pixel X/Y coordinates. */
136 c->nr_payload_regs = 2;
137 /* R2: only for 32-pixel dispatch.*/
138 /* R3-4: perspective pixel location barycentric */
139 c->nr_payload_regs += 2;
140 /* R5-6: perspective pixel location bary for dispatch width != 8 */
Eric Anholt5ba517b2010-11-11 09:09:38 -0800141 if (c->dispatch_width == 16) {
Eric Anholt16f8c822010-11-11 09:30:16 -0800142 c->nr_payload_regs += 2;
143 }
144 /* R7-10: perspective centroid barycentric */
145 /* R11-14: perspective sample barycentric */
146 /* R15-18: linear pixel location barycentric */
147 /* R19-22: linear centroid barycentric */
148 /* R23-26: linear sample barycentric */
149
150 /* R27: interpolated depth if uses source depth */
151 if (uses_depth) {
152 c->source_depth_reg = c->nr_payload_regs;
153 c->nr_payload_regs++;
Eric Anholt5ba517b2010-11-11 09:09:38 -0800154 if (c->dispatch_width == 16) {
Eric Anholt16f8c822010-11-11 09:30:16 -0800155 /* R28: interpolated depth if not 8-wide. */
156 c->nr_payload_regs++;
157 }
158 }
159 /* R29: interpolated W set if GEN6_WM_USES_SOURCE_W.
160 */
161 if (uses_depth) {
162 c->source_w_reg = c->nr_payload_regs;
163 c->nr_payload_regs++;
Eric Anholt5ba517b2010-11-11 09:09:38 -0800164 if (c->dispatch_width == 16) {
Eric Anholt16f8c822010-11-11 09:30:16 -0800165 /* R30: interpolated W if not 8-wide. */
166 c->nr_payload_regs++;
167 }
168 }
169 /* R31: MSAA position offsets. */
170 /* R32-: bary for 32-pixel. */
171 /* R58-59: interp W for 32-pixel. */
172
173 if (c->fp->program.Base.OutputsWritten &
174 BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
175 c->source_depth_to_render_target = GL_TRUE;
176 c->computes_depth = GL_TRUE;
177 }
178 } else {
179 brw_wm_lookup_iz(intel, c);
180 }
181}
Brian Paul2f78d4a2009-02-12 15:35:41 -0700182
183/**
184 * All Mesa program -> GPU code generation goes through this function.
185 * Depending on the instructions used (i.e. flow control instructions)
186 * we'll use one of two code generators.
187 */
Eric Anholt87527642011-05-16 15:10:26 -0700188bool do_wm_prog(struct brw_context *brw,
189 struct gl_shader_program *prog,
190 struct brw_fragment_program *fp,
191 struct brw_wm_prog_key *key)
Eric Anholt9f344b32006-08-09 19:14:05 +0000192{
Eric Anholt59c6b772011-04-14 19:36:28 -0700193 struct intel_context *intel = &brw->intel;
Eric Anholtd7b24fe2006-12-09 22:35:07 -0800194 struct brw_wm_compile *c;
Eric Anholt9f344b32006-08-09 19:14:05 +0000195 const GLuint *program;
196 GLuint program_size;
197
Eric Anholtd7b24fe2006-12-09 22:35:07 -0800198 c = brw->wm.compile_data;
199 if (c == NULL) {
Kenneth Graunke774fb902011-05-16 11:49:57 -0700200 brw->wm.compile_data = rzalloc(NULL, struct brw_wm_compile);
Brian Paul14dc4932009-02-12 14:47:56 -0700201 c = brw->wm.compile_data;
Robert Ellison44a4abf2009-05-08 14:40:38 -0600202 if (c == NULL) {
203 /* Ouch - big out of memory problem. Can't continue
204 * without triggering a segfault, no way to signal,
205 * so just return.
206 */
Eric Anholt87527642011-05-16 15:10:26 -0700207 return false;
Robert Ellison44a4abf2009-05-08 14:40:38 -0600208 }
Eric Anholtd7b24fe2006-12-09 22:35:07 -0800209 } else {
Eric Anholtc5413832009-11-10 15:51:29 -0800210 void *instruction = c->instruction;
211 void *prog_instructions = c->prog_instructions;
212 void *vreg = c->vreg;
213 void *refs = c->refs;
Brian Paul14dc4932009-02-12 14:47:56 -0700214 memset(c, 0, sizeof(*brw->wm.compile_data));
Eric Anholtc5413832009-11-10 15:51:29 -0800215 c->instruction = instruction;
216 c->prog_instructions = prog_instructions;
217 c->vreg = vreg;
218 c->refs = refs;
Eric Anholtd7b24fe2006-12-09 22:35:07 -0800219 }
220 memcpy(&c->key, key, sizeof(*key));
Eric Anholt9f344b32006-08-09 19:14:05 +0000221
Eric Anholtd7b24fe2006-12-09 22:35:07 -0800222 c->fp = fp;
223 c->env_param = brw->intel.ctx.FragmentProgram.Parameters;
Eric Anholt9f344b32006-08-09 19:14:05 +0000224
Kenneth Graunke774fb902011-05-16 11:49:57 -0700225 brw_init_compile(brw, &c->func, c);
Brian Paul14dc4932009-02-12 14:47:56 -0700226
Eric Anholt87527642011-05-16 15:10:26 -0700227 if (prog && prog->FragmentProgram) {
228 if (!brw_wm_fs_emit(brw, c, prog))
229 return false;
230 } else {
Eric Anholt0722edc2011-07-28 09:57:19 -0700231 if (!c->instruction) {
232 c->instruction = rzalloc_array(c, struct brw_wm_instruction, BRW_WM_MAX_INSN);
233 c->prog_instructions = rzalloc_array(c, struct prog_instruction, BRW_WM_MAX_INSN);
234 c->vreg = rzalloc_array(c, struct brw_wm_value, BRW_WM_MAX_VREG);
235 c->refs = rzalloc_array(c, struct brw_wm_ref, BRW_WM_MAX_REF);
236 }
237
Eric Anholt662f1b42011-03-11 19:19:01 -0800238 /* Fallback for fixed function and ARB_fp shaders. */
Eric Anholt5ba517b2010-11-11 09:09:38 -0800239 c->dispatch_width = 16;
240 brw_wm_payload_setup(brw, c);
241 brw_wm_non_glsl_emit(brw, c);
Eric Anholt662f1b42011-03-11 19:19:01 -0800242 c->prog_data.dispatch_width = 16;
Eric Anholtd7b24fe2006-12-09 22:35:07 -0800243 }
Brian Paul2f78d4a2009-02-12 15:35:41 -0700244
Eric Anholt4e725252010-10-21 15:07:45 -0700245 /* Scratch space is used for register spilling */
246 if (c->last_scratch) {
Eric Anholt2b224d62011-08-07 10:44:15 -0700247 c->prog_data.total_scratch = brw_get_scratch_size(c->last_scratch);
Eric Anholt59c6b772011-04-14 19:36:28 -0700248
Eric Anholtabbb8fc2011-08-23 10:51:16 -0700249 brw_get_scratch_bo(intel, &brw->wm.scratch_bo,
Eric Anholt2b224d62011-08-07 10:44:15 -0700250 c->prog_data.total_scratch * brw->wm_max_threads);
Eric Anholt4e725252010-10-21 15:07:45 -0700251 }
252
Eric Anholtbb154082010-11-02 19:55:07 -0700253 if (unlikely(INTEL_DEBUG & DEBUG_WM))
Eric Anholtfc3971d2009-01-08 19:15:04 -0800254 fprintf(stderr, "\n");
255
Eric Anholt9f344b32006-08-09 19:14:05 +0000256 /* get the program
257 */
Eric Anholtd7b24fe2006-12-09 22:35:07 -0800258 program = brw_get_program(&c->func, &program_size);
Eric Anholt9f344b32006-08-09 19:14:05 +0000259
Eric Anholtc1735412011-04-27 13:33:10 -0700260 brw_upload_cache(&brw->cache, BRW_WM_PROG,
261 &c->key, sizeof(c->key),
262 program, program_size,
263 &c->prog_data, sizeof(c->prog_data),
264 &brw->wm.prog_offset, &brw->wm.prog_data);
Eric Anholt87527642011-05-16 15:10:26 -0700265
266 return true;
Eric Anholt9f344b32006-08-09 19:14:05 +0000267}
268
269
270
271static void brw_wm_populate_key( struct brw_context *brw,
272 struct brw_wm_prog_key *key )
273{
Kristian Høgsbergf9995b32010-10-12 12:26:10 -0400274 struct gl_context *ctx = &brw->intel.ctx;
Eric Anholt9f344b32006-08-09 19:14:05 +0000275 /* BRW_NEW_FRAGMENT_PROGRAM */
Brian Paul55d33e12009-02-20 10:49:30 -0700276 const struct brw_fragment_program *fp =
Eric Anholt9f344b32006-08-09 19:14:05 +0000277 (struct brw_fragment_program *)brw->fragment_program;
278 GLuint lookup = 0;
279 GLuint line_aa;
280 GLuint i;
281
282 memset(key, 0, sizeof(*key));
283
284 /* Build the index for table lookup
285 */
286 /* _NEW_COLOR */
Eric Anholta9944732011-03-11 17:39:49 -0800287 key->alpha_test = ctx->Color.AlphaEnabled;
Eric Anholt9f344b32006-08-09 19:14:05 +0000288 if (fp->program.UsesKill ||
Eric Anholt052c1d62009-01-30 14:32:23 -0800289 ctx->Color.AlphaEnabled)
Eric Anholt9f344b32006-08-09 19:14:05 +0000290 lookup |= IZ_PS_KILL_ALPHATEST_BIT;
291
Ian Romanick5606dfb2009-11-17 16:10:24 -0800292 if (fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
Eric Anholt9f344b32006-08-09 19:14:05 +0000293 lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
294
295 /* _NEW_DEPTH */
Eric Anholt052c1d62009-01-30 14:32:23 -0800296 if (ctx->Depth.Test)
Eric Anholt9f344b32006-08-09 19:14:05 +0000297 lookup |= IZ_DEPTH_TEST_ENABLE_BIT;
298
Eric Anholt052c1d62009-01-30 14:32:23 -0800299 if (ctx->Depth.Test &&
300 ctx->Depth.Mask) /* ?? */
Eric Anholt9f344b32006-08-09 19:14:05 +0000301 lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
302
303 /* _NEW_STENCIL */
Brian Paul91e61f42009-03-02 11:47:52 -0700304 if (ctx->Stencil._Enabled) {
Eric Anholt9f344b32006-08-09 19:14:05 +0000305 lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
306
Eric Anholt052c1d62009-01-30 14:32:23 -0800307 if (ctx->Stencil.WriteMask[0] ||
308 ctx->Stencil.WriteMask[ctx->Stencil._BackFace])
Eric Anholt9f344b32006-08-09 19:14:05 +0000309 lookup |= IZ_STENCIL_WRITE_ENABLE_BIT;
310 }
311
Eric Anholt9f344b32006-08-09 19:14:05 +0000312 line_aa = AA_NEVER;
313
314 /* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */
Eric Anholt052c1d62009-01-30 14:32:23 -0800315 if (ctx->Line.SmoothFlag) {
Eric Anholt9f344b32006-08-09 19:14:05 +0000316 if (brw->intel.reduced_primitive == GL_LINES) {
317 line_aa = AA_ALWAYS;
318 }
319 else if (brw->intel.reduced_primitive == GL_TRIANGLES) {
Eric Anholt052c1d62009-01-30 14:32:23 -0800320 if (ctx->Polygon.FrontMode == GL_LINE) {
Eric Anholt9f344b32006-08-09 19:14:05 +0000321 line_aa = AA_SOMETIMES;
322
Eric Anholt052c1d62009-01-30 14:32:23 -0800323 if (ctx->Polygon.BackMode == GL_LINE ||
324 (ctx->Polygon.CullFlag &&
325 ctx->Polygon.CullFaceMode == GL_BACK))
Eric Anholt9f344b32006-08-09 19:14:05 +0000326 line_aa = AA_ALWAYS;
327 }
Eric Anholt052c1d62009-01-30 14:32:23 -0800328 else if (ctx->Polygon.BackMode == GL_LINE) {
Eric Anholt9f344b32006-08-09 19:14:05 +0000329 line_aa = AA_SOMETIMES;
330
Eric Anholt052c1d62009-01-30 14:32:23 -0800331 if ((ctx->Polygon.CullFlag &&
332 ctx->Polygon.CullFaceMode == GL_FRONT))
Eric Anholt9f344b32006-08-09 19:14:05 +0000333 line_aa = AA_ALWAYS;
334 }
335 }
336 }
Eric Anholt9f344b32006-08-09 19:14:05 +0000337
Eric Anholt16f8c822010-11-11 09:30:16 -0800338 key->iz_lookup = lookup;
339 key->line_aa = line_aa;
340 key->stats_wm = brw->intel.stats_wm;
Eric Anholt9f344b32006-08-09 19:14:05 +0000341
342 /* BRW_NEW_WM_INPUT_DIMENSIONS */
Brian Paul6b917d02009-06-16 18:19:45 -0600343 key->proj_attrib_mask = brw->wm.input_size_masks[4-1];
Eric Anholt9f344b32006-08-09 19:14:05 +0000344
345 /* _NEW_LIGHT */
Eric Anholt052c1d62009-01-30 14:32:23 -0800346 key->flat_shade = (ctx->Light.ShadeModel == GL_FLAT);
Eric Anholt9f344b32006-08-09 19:14:05 +0000347
Eric Anholtd22e2eb2011-04-15 14:40:09 -0700348 /* _NEW_FRAG_CLAMP | _NEW_BUFFERS */
349 key->clamp_fragment_color = ctx->Color._ClampFragmentColor;
350
Eric Anholt9f344b32006-08-09 19:14:05 +0000351 /* _NEW_TEXTURE */
352 for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
Eric Anholt052c1d62009-01-30 14:32:23 -0800353 const struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
Eric Anholt9f344b32006-08-09 19:14:05 +0000354
355 if (unit->_ReallyEnabled) {
Brian Paul89fddf92009-01-28 11:42:42 -0700356 const struct gl_texture_object *t = unit->_Current;
357 const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
Eric Anholt1f32c662011-04-20 11:48:31 -0700358 struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, i);
Eric Anholt14bf92b2010-10-03 00:24:09 -0700359 int swizzles[SWIZZLE_NIL + 1] = {
360 SWIZZLE_X,
361 SWIZZLE_Y,
362 SWIZZLE_Z,
363 SWIZZLE_W,
364 SWIZZLE_ZERO,
365 SWIZZLE_ONE,
366 SWIZZLE_NIL
367 };
Eric Anholta7fa00d2010-10-02 23:27:31 -0700368
Eric Anholta7fa00d2010-10-02 23:27:31 -0700369 /* GL_DEPTH_TEXTURE_MODE is normally handled through
370 * brw_wm_surface_state, but it applies to shadow compares as
371 * well and our shadow compares always return the result in
372 * all 4 channels.
373 */
Eric Anholt1f32c662011-04-20 11:48:31 -0700374 if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
Kenneth Graunke6430df32011-06-10 14:48:46 -0700375 key->compare_funcs[i] = sampler->CompareFunc;
376
Eric Anholt1f32c662011-04-20 11:48:31 -0700377 if (sampler->DepthMode == GL_ALPHA) {
Eric Anholt14bf92b2010-10-03 00:24:09 -0700378 swizzles[0] = SWIZZLE_ZERO;
379 swizzles[1] = SWIZZLE_ZERO;
380 swizzles[2] = SWIZZLE_ZERO;
Eric Anholt1f32c662011-04-20 11:48:31 -0700381 } else if (sampler->DepthMode == GL_LUMINANCE) {
Eric Anholt14bf92b2010-10-03 00:24:09 -0700382 swizzles[3] = SWIZZLE_ONE;
Eric Anholt1f32c662011-04-20 11:48:31 -0700383 } else if (sampler->DepthMode == GL_RED) {
Chad Versace1842b892011-03-12 17:49:41 -0800384 /* See table 3.23 of the GL 3.0 spec. */
Eric Anholt3fb18d62010-12-09 13:51:21 -0800385 swizzles[1] = SWIZZLE_ZERO;
386 swizzles[2] = SWIZZLE_ZERO;
Chad Versace1842b892011-03-12 17:49:41 -0800387 swizzles[3] = SWIZZLE_ONE;
Eric Anholta7fa00d2010-10-02 23:27:31 -0700388 }
389 }
390
Brian Paul89fddf92009-01-28 11:42:42 -0700391 if (img->InternalFormat == GL_YCBCR_MESA) {
392 key->yuvtex_mask |= 1 << i;
Brian Paul1f7c9142009-09-30 20:28:45 -0600393 if (img->TexFormat == MESA_FORMAT_YCBCR)
Brian Paul89fddf92009-01-28 11:42:42 -0700394 key->yuvtex_swap_mask |= 1 << i;
Zou Nan hai76769802008-03-07 15:11:28 +0800395 }
Brian Paulc0d3b762009-01-28 14:50:03 -0700396
Eric Anholt14bf92b2010-10-03 00:24:09 -0700397 key->tex_swizzles[i] =
398 MAKE_SWIZZLE4(swizzles[GET_SWZ(t->_Swizzle, 0)],
399 swizzles[GET_SWZ(t->_Swizzle, 1)],
400 swizzles[GET_SWZ(t->_Swizzle, 2)],
401 swizzles[GET_SWZ(t->_Swizzle, 3)]);
Eric Anholtb126a0c2010-11-02 09:11:17 -0700402
403 if (sampler->MinFilter != GL_NEAREST &&
404 sampler->MagFilter != GL_NEAREST) {
405 if (sampler->WrapS == GL_CLAMP)
406 key->gl_clamp_mask[0] |= 1 << i;
407 if (sampler->WrapT == GL_CLAMP)
408 key->gl_clamp_mask[1] |= 1 << i;
409 if (sampler->WrapR == GL_CLAMP)
410 key->gl_clamp_mask[2] |= 1 << i;
411 }
Brian Paulc0d3b762009-01-28 14:50:03 -0700412 }
413 else {
414 key->tex_swizzles[i] = SWIZZLE_NOOP;
Eric Anholt9f344b32006-08-09 19:14:05 +0000415 }
416 }
Eric Anholt9c8f27b2008-02-28 13:18:12 -0800417
418 /* _NEW_BUFFERS */
419 /*
420 * Include the draw buffer origin and height so that we can calculate
421 * fragment position values relative to the bottom left of the drawable,
422 * from the incoming screen origin relative position we get as part of our
423 * payload.
424 *
Brian Paul861fec12009-10-29 15:29:41 -0600425 * This is only needed for the WM_WPOSXY opcode when the fragment program
426 * uses the gl_FragCoord input.
427 *
Eric Anholt9c8f27b2008-02-28 13:18:12 -0800428 * We could avoid recompiling by including this as a constant referenced by
429 * our program, but if we were to do that it would also be nice to handle
430 * getting that constant updated at batchbuffer submit time (when we
431 * hold the lock and know where the buffer really is) rather than at emit
432 * time when we don't hold the lock and are just guessing. We could also
433 * just avoid using this as key data if the program doesn't use
434 * fragment.position.
435 *
Brian Paul861fec12009-10-29 15:29:41 -0600436 * For DRI2 the origin_x/y will always be (0,0) but we still need the
437 * drawable height in order to invert the Y axis.
Eric Anholt9c8f27b2008-02-28 13:18:12 -0800438 */
Brian Paul861fec12009-10-29 15:29:41 -0600439 if (fp->program.Base.InputsRead & FRAG_BIT_WPOS) {
Eric Anholtf62c2a02010-01-26 13:08:42 -0800440 key->drawable_height = ctx->DrawBuffer->Height;
Eric Anholt3b337f52010-11-13 14:00:58 -0800441 key->render_to_fbo = ctx->DrawBuffer->Name != 0;
Eric Anholt9c8f27b2008-02-28 13:18:12 -0800442 }
Eric Anholt9f344b32006-08-09 19:14:05 +0000443
Eric Anholt1b806222011-01-30 21:13:17 -0800444 /* _NEW_BUFFERS */
445 key->nr_color_regions = ctx->DrawBuffer->_NumColorDrawBuffers;
Brian Paul9ef33b82009-10-29 14:53:53 -0600446
Eric Anholt0f5113d2009-05-14 09:49:45 -0700447 /* CACHE_NEW_VS_PROG */
Ian Romanick5606dfb2009-11-17 16:10:24 -0800448 key->vp_outputs_written = brw->vs.prog_data->outputs_written;
Eric Anholt0f5113d2009-05-14 09:49:45 -0700449
Brian Paul55d33e12009-02-20 10:49:30 -0700450 /* The unique fragment program ID */
Eric Anholt9f344b32006-08-09 19:14:05 +0000451 key->program_string_id = fp->id;
Eric Anholt9f344b32006-08-09 19:14:05 +0000452}
453
454
Dave Airlief75843a2008-08-24 17:59:10 +1000455static void brw_prepare_wm_prog(struct brw_context *brw)
Eric Anholt9f344b32006-08-09 19:14:05 +0000456{
Eric Anholt87527642011-05-16 15:10:26 -0700457 struct intel_context *intel = &brw->intel;
458 struct gl_context *ctx = &intel->ctx;
Eric Anholt9f344b32006-08-09 19:14:05 +0000459 struct brw_wm_prog_key key;
460 struct brw_fragment_program *fp = (struct brw_fragment_program *)
461 brw->fragment_program;
Eric Anholt662f1b42011-03-11 19:19:01 -0800462
Eric Anholt9f344b32006-08-09 19:14:05 +0000463 brw_wm_populate_key(brw, &key);
464
Eric Anholtc1735412011-04-27 13:33:10 -0700465 if (!brw_search_cache(&brw->cache, BRW_WM_PROG,
466 &key, sizeof(key),
467 &brw->wm.prog_offset, &brw->wm.prog_data)) {
Eric Anholt87527642011-05-16 15:10:26 -0700468 bool success = do_wm_prog(brw, ctx->Shader.CurrentFragmentProgram, fp,
469 &key);
470 assert(success);
471 }
Eric Anholt9f344b32006-08-09 19:14:05 +0000472}
473
474
Eric Anholt9f344b32006-08-09 19:14:05 +0000475const struct brw_tracked_state brw_wm_prog = {
476 .dirty = {
477 .mesa = (_NEW_COLOR |
478 _NEW_DEPTH |
479 _NEW_STENCIL |
480 _NEW_POLYGON |
481 _NEW_LINE |
482 _NEW_LIGHT |
Eric Anholtd22e2eb2011-04-15 14:40:09 -0700483 _NEW_FRAG_CLAMP |
Eric Anholt9c8f27b2008-02-28 13:18:12 -0800484 _NEW_BUFFERS |
Eric Anholt9f344b32006-08-09 19:14:05 +0000485 _NEW_TEXTURE),
486 .brw = (BRW_NEW_FRAGMENT_PROGRAM |
487 BRW_NEW_WM_INPUT_DIMENSIONS |
488 BRW_NEW_REDUCED_PRIMITIVE),
Eric Anholt0f5113d2009-05-14 09:49:45 -0700489 .cache = CACHE_NEW_VS_PROG,
Eric Anholt9f344b32006-08-09 19:14:05 +0000490 },
Dave Airlie008653a2008-04-17 17:17:23 +1000491 .prepare = brw_prepare_wm_prog
Eric Anholt9f344b32006-08-09 19:14:05 +0000492};
493