blob: 6eb4a1dd10564ce7797672b6faba948234e9516a [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"
Brian Paul4433b032012-04-20 07:58:59 -060036#include "main/fbobject.h"
Eric Anholt1f32c662011-04-20 11:48:31 -070037#include "main/samplerobj.h"
Eric Anholt87527642011-05-16 15:10:26 -070038#include "program/prog_parameter.h"
Eric Anholt9f344b32006-08-09 19:14:05 +000039
Chad Versace2f0edc62011-08-26 13:58:41 -070040#include "glsl/ralloc.h"
Kenneth Graunke774fb902011-05-16 11:49:57 -070041
Paul Berrye04bdea2011-10-21 17:20:32 -070042/**
43 * Return a bitfield where bit n is set if barycentric interpolation mode n
44 * (see enum brw_wm_barycentric_interp_mode) is needed by the fragment shader.
45 */
Eric Anholt71d71d52012-02-14 21:48:43 -080046static unsigned
Paul Berry8313f442012-06-21 11:21:22 -070047brw_compute_barycentric_interp_modes(struct brw_context *brw,
48 bool shade_model_flat,
Paul Berry5aa96282011-10-22 09:33:16 -070049 const struct gl_fragment_program *fprog)
Paul Berrye04bdea2011-10-21 17:20:32 -070050{
Paul Berry5aa96282011-10-22 09:33:16 -070051 unsigned barycentric_interp_modes = 0;
52 int attr;
53
54 /* Loop through all fragment shader inputs to figure out what interpolation
55 * modes are in use, and set the appropriate bits in
56 * barycentric_interp_modes.
57 */
Paul Berryeed6baf2013-02-23 09:00:58 -080058 for (attr = 0; attr < VARYING_SLOT_MAX; ++attr) {
Paul Berry5aa96282011-10-22 09:33:16 -070059 enum glsl_interp_qualifier interp_qualifier =
60 fprog->InterpQualifier[attr];
Paul Berryd1056542012-06-18 13:52:02 -070061 bool is_centroid = fprog->IsCentroid & BITFIELD64_BIT(attr);
Paul Berryeed6baf2013-02-23 09:00:58 -080062 bool is_gl_Color = attr == VARYING_SLOT_COL0 || attr == VARYING_SLOT_COL1;
Paul Berry5aa96282011-10-22 09:33:16 -070063
64 /* Ignore unused inputs. */
65 if (!(fprog->Base.InputsRead & BITFIELD64_BIT(attr)))
66 continue;
67
68 /* Ignore WPOS and FACE, because they don't require interpolation. */
Paul Berryeed6baf2013-02-23 09:00:58 -080069 if (attr == VARYING_SLOT_POS || attr == VARYING_SLOT_FACE)
Paul Berry5aa96282011-10-22 09:33:16 -070070 continue;
71
Paul Berry8313f442012-06-21 11:21:22 -070072 /* Determine the set (or sets) of barycentric coordinates needed to
73 * interpolate this variable. Note that when
74 * brw->needs_unlit_centroid_workaround is set, centroid interpolation
75 * uses PIXEL interpolation for unlit pixels and CENTROID interpolation
76 * for lit pixels, so we need both sets of barycentric coordinates.
77 */
Paul Berry5aa96282011-10-22 09:33:16 -070078 if (interp_qualifier == INTERP_QUALIFIER_NOPERSPECTIVE) {
Paul Berryd1056542012-06-18 13:52:02 -070079 if (is_centroid) {
80 barycentric_interp_modes |=
81 1 << BRW_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC;
Paul Berry8313f442012-06-21 11:21:22 -070082 }
83 if (!is_centroid || brw->needs_unlit_centroid_workaround) {
Paul Berryd1056542012-06-18 13:52:02 -070084 barycentric_interp_modes |=
85 1 << BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
86 }
Paul Berry5aa96282011-10-22 09:33:16 -070087 } else if (interp_qualifier == INTERP_QUALIFIER_SMOOTH ||
88 (!(shade_model_flat && is_gl_Color) &&
89 interp_qualifier == INTERP_QUALIFIER_NONE)) {
Paul Berryd1056542012-06-18 13:52:02 -070090 if (is_centroid) {
91 barycentric_interp_modes |=
92 1 << BRW_WM_PERSPECTIVE_CENTROID_BARYCENTRIC;
Paul Berry8313f442012-06-21 11:21:22 -070093 }
94 if (!is_centroid || brw->needs_unlit_centroid_workaround) {
Paul Berryd1056542012-06-18 13:52:02 -070095 barycentric_interp_modes |=
96 1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
97 }
Paul Berry5aa96282011-10-22 09:33:16 -070098 }
99 }
100
101 return barycentric_interp_modes;
Paul Berrye04bdea2011-10-21 17:20:32 -0700102}
103
Eric Anholt99596cb2012-08-26 21:19:05 -0700104bool
105brw_wm_prog_data_compare(const void *in_a, const void *in_b,
106 int aux_size, const void *in_key)
107{
108 const struct brw_wm_prog_data *a = in_a;
109 const struct brw_wm_prog_data *b = in_b;
110
111 /* Compare all the struct up to the pointers. */
112 if (memcmp(a, b, offsetof(struct brw_wm_prog_data, param)))
113 return false;
114
115 if (memcmp(a->param, b->param, a->nr_params * sizeof(void *)))
116 return false;
117
118 if (memcmp(a->pull_param, b->pull_param, a->nr_pull_params * sizeof(void *)))
119 return false;
120
121 return true;
122}
123
Eric Anholtf144b782012-08-26 21:19:05 -0700124void
125brw_wm_prog_data_free(const void *in_prog_data)
126{
127 const struct brw_wm_prog_data *prog_data = in_prog_data;
128
129 ralloc_free((void *)prog_data->param);
130 ralloc_free((void *)prog_data->pull_param);
131}
132
Brian Paul2f78d4a2009-02-12 15:35:41 -0700133/**
134 * All Mesa program -> GPU code generation goes through this function.
135 * Depending on the instructions used (i.e. flow control instructions)
136 * we'll use one of two code generators.
137 */
Eric Anholt87527642011-05-16 15:10:26 -0700138bool do_wm_prog(struct brw_context *brw,
139 struct gl_shader_program *prog,
140 struct brw_fragment_program *fp,
141 struct brw_wm_prog_key *key)
Eric Anholt9f344b32006-08-09 19:14:05 +0000142{
Eric Anholt59c6b772011-04-14 19:36:28 -0700143 struct intel_context *intel = &brw->intel;
Eric Anholtd7b24fe2006-12-09 22:35:07 -0800144 struct brw_wm_compile *c;
Eric Anholt9f344b32006-08-09 19:14:05 +0000145 const GLuint *program;
Eric Anholtf144b782012-08-26 21:19:05 -0700146 struct gl_shader *fs = NULL;
Eric Anholt9f344b32006-08-09 19:14:05 +0000147 GLuint program_size;
148
Eric Anholtf144b782012-08-26 21:19:05 -0700149 if (prog)
150 fs = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
151
Eric Anholt2fcaf4e2012-11-06 09:48:51 -0800152 c = rzalloc(NULL, struct brw_wm_compile);
Eric Anholtf144b782012-08-26 21:19:05 -0700153
154 /* Allocate the references to the uniforms that will end up in the
155 * prog_data associated with the compiled program, and which will be freed
156 * by the state cache.
157 */
Eric Anholta43b1072012-11-08 14:02:22 -0800158 int param_count;
Eric Anholtf144b782012-08-26 21:19:05 -0700159 if (fs) {
Eric Anholta43b1072012-11-08 14:02:22 -0800160 param_count = fs->num_uniform_components;
Eric Anholtf144b782012-08-26 21:19:05 -0700161 } else {
Eric Anholta43b1072012-11-08 14:02:22 -0800162 param_count = fp->program.Base.Parameters->NumParameters * 4;
Eric Anholtf144b782012-08-26 21:19:05 -0700163 }
Eric Anholta43b1072012-11-08 14:02:22 -0800164 /* The backend also sometimes adds params for texture size. */
165 param_count += 2 * BRW_MAX_TEX_UNIT;
166 c->prog_data.param = rzalloc_array(NULL, const float *, param_count);
167 c->prog_data.pull_param = rzalloc_array(NULL, const float *, param_count);
Eric Anholtf144b782012-08-26 21:19:05 -0700168
Eric Anholtd7b24fe2006-12-09 22:35:07 -0800169 memcpy(&c->key, key, sizeof(*key));
Eric Anholt9f344b32006-08-09 19:14:05 +0000170
Eric Anholt71d71d52012-02-14 21:48:43 -0800171 c->prog_data.barycentric_interp_modes =
Paul Berry8313f442012-06-21 11:21:22 -0700172 brw_compute_barycentric_interp_modes(brw, c->key.flat_shade,
173 &fp->program);
Eric Anholt71d71d52012-02-14 21:48:43 -0800174
Kenneth Graunke4d09fe92012-11-20 16:21:27 -0800175 program = brw_wm_fs_emit(brw, c, &fp->program, prog, &program_size);
176 if (program == NULL)
177 return false;
Brian Paul2f78d4a2009-02-12 15:35:41 -0700178
Eric Anholt4e725252010-10-21 15:07:45 -0700179 /* Scratch space is used for register spilling */
180 if (c->last_scratch) {
Eric Anholt4cfb9e32012-07-12 13:08:20 -0700181 perf_debug("Fragment shader triggered register spilling. "
182 "Try reducing the number of live scalar values to "
183 "improve performance.\n");
184
Eric Anholt2b224d62011-08-07 10:44:15 -0700185 c->prog_data.total_scratch = brw_get_scratch_size(c->last_scratch);
Eric Anholt59c6b772011-04-14 19:36:28 -0700186
Eric Anholtabbb8fc2011-08-23 10:51:16 -0700187 brw_get_scratch_bo(intel, &brw->wm.scratch_bo,
Kenneth Graunkedb6dd6d2011-10-23 22:10:03 -0700188 c->prog_data.total_scratch * brw->max_wm_threads);
Eric Anholt4e725252010-10-21 15:07:45 -0700189 }
190
Eric Anholtbb154082010-11-02 19:55:07 -0700191 if (unlikely(INTEL_DEBUG & DEBUG_WM))
Eric Anholtfc3971d2009-01-08 19:15:04 -0800192 fprintf(stderr, "\n");
193
Eric Anholtc1735412011-04-27 13:33:10 -0700194 brw_upload_cache(&brw->cache, BRW_WM_PROG,
195 &c->key, sizeof(c->key),
196 program, program_size,
197 &c->prog_data, sizeof(c->prog_data),
198 &brw->wm.prog_offset, &brw->wm.prog_data);
Eric Anholt87527642011-05-16 15:10:26 -0700199
Eric Anholt2fcaf4e2012-11-06 09:48:51 -0800200 ralloc_free(c);
201
Eric Anholt87527642011-05-16 15:10:26 -0700202 return true;
Eric Anholt9f344b32006-08-09 19:14:05 +0000203}
204
Eric Anholtfc3b7c92012-07-12 13:19:53 -0700205static bool
Eric Anholt14cec072013-02-22 13:15:20 -0800206key_debug(struct intel_context *intel, const char *name, int a, int b)
Eric Anholtfc3b7c92012-07-12 13:19:53 -0700207{
208 if (a != b) {
209 perf_debug(" %s %d->%d\n", name, a, b);
210 return true;
211 } else {
212 return false;
213 }
214}
215
216bool
Eric Anholt14cec072013-02-22 13:15:20 -0800217brw_debug_recompile_sampler_key(struct intel_context *intel,
218 const struct brw_sampler_prog_key_data *old_key,
Eric Anholtfc3b7c92012-07-12 13:19:53 -0700219 const struct brw_sampler_prog_key_data *key)
220{
221 bool found = false;
222
Kenneth Graunkef3d0daf2012-08-26 00:28:38 -0700223 for (unsigned int i = 0; i < MAX_SAMPLERS; i++) {
Eric Anholt14cec072013-02-22 13:15:20 -0800224 found |= key_debug(intel, "EXT_texture_swizzle or DEPTH_TEXTURE_MODE",
Kenneth Graunke98211d52012-08-15 16:35:35 -0700225 old_key->swizzles[i], key->swizzles[i]);
Eric Anholtfc3b7c92012-07-12 13:19:53 -0700226 }
Eric Anholt14cec072013-02-22 13:15:20 -0800227 found |= key_debug(intel, "GL_CLAMP enabled on any texture unit's 1st coordinate",
Kenneth Graunke98211d52012-08-15 16:35:35 -0700228 old_key->gl_clamp_mask[0], key->gl_clamp_mask[0]);
Eric Anholt14cec072013-02-22 13:15:20 -0800229 found |= key_debug(intel, "GL_CLAMP enabled on any texture unit's 2nd coordinate",
Kenneth Graunke98211d52012-08-15 16:35:35 -0700230 old_key->gl_clamp_mask[1], key->gl_clamp_mask[1]);
Eric Anholt14cec072013-02-22 13:15:20 -0800231 found |= key_debug(intel, "GL_CLAMP enabled on any texture unit's 3rd coordinate",
Kenneth Graunke98211d52012-08-15 16:35:35 -0700232 old_key->gl_clamp_mask[2], key->gl_clamp_mask[2]);
Eric Anholt14cec072013-02-22 13:15:20 -0800233 found |= key_debug(intel, "GL_MESA_ycbcr texturing\n",
Kenneth Graunke98211d52012-08-15 16:35:35 -0700234 old_key->yuvtex_mask, key->yuvtex_mask);
Eric Anholt14cec072013-02-22 13:15:20 -0800235 found |= key_debug(intel, "GL_MESA_ycbcr UV swapping\n",
Kenneth Graunke98211d52012-08-15 16:35:35 -0700236 old_key->yuvtex_swap_mask, key->yuvtex_swap_mask);
Eric Anholtfc3b7c92012-07-12 13:19:53 -0700237
238 return found;
239}
240
241void
242brw_wm_debug_recompile(struct brw_context *brw,
243 struct gl_shader_program *prog,
244 const struct brw_wm_prog_key *key)
245{
Eric Anholt14cec072013-02-22 13:15:20 -0800246 struct intel_context *intel = &brw->intel;
Eric Anholtfc3b7c92012-07-12 13:19:53 -0700247 struct brw_cache_item *c = NULL;
248 const struct brw_wm_prog_key *old_key = NULL;
249 bool found = false;
250
251 perf_debug("Recompiling fragment shader for program %d\n", prog->Name);
252
253 for (unsigned int i = 0; i < brw->cache.size; i++) {
254 for (c = brw->cache.items[i]; c; c = c->next) {
255 if (c->cache_id == BRW_WM_PROG) {
256 old_key = c->key;
257
258 if (old_key->program_string_id == key->program_string_id)
259 break;
260 }
261 }
262 if (c)
263 break;
264 }
265
266 if (!c) {
Eric Anholt14cec072013-02-22 13:15:20 -0800267 perf_debug(" Didn't find previous compile in the shader cache for debug\n");
Eric Anholtfc3b7c92012-07-12 13:19:53 -0700268 return;
269 }
270
Eric Anholt14cec072013-02-22 13:15:20 -0800271 found |= key_debug(intel, "alphatest, computed depth, depth test, or "
272 "depth write",
Kenneth Graunke98211d52012-08-15 16:35:35 -0700273 old_key->iz_lookup, key->iz_lookup);
Eric Anholt14cec072013-02-22 13:15:20 -0800274 found |= key_debug(intel, "depth statistics",
275 old_key->stats_wm, key->stats_wm);
276 found |= key_debug(intel, "flat shading",
277 old_key->flat_shade, key->flat_shade);
278 found |= key_debug(intel, "number of color buffers",
279 old_key->nr_color_regions, key->nr_color_regions);
280 found |= key_debug(intel, "sample alpha to coverage",
281 old_key->sample_alpha_to_coverage, key->sample_alpha_to_coverage);
282 found |= key_debug(intel, "rendering to FBO",
283 old_key->render_to_fbo, key->render_to_fbo);
284 found |= key_debug(intel, "fragment color clamping",
285 old_key->clamp_fragment_color, key->clamp_fragment_color);
286 found |= key_debug(intel, "line smoothing",
287 old_key->line_aa, key->line_aa);
Eric Anholt14cec072013-02-22 13:15:20 -0800288 found |= key_debug(intel, "renderbuffer height",
289 old_key->drawable_height, key->drawable_height);
Paul Berry0a0deb92013-03-20 10:15:52 -0700290 found |= key_debug(intel, "input slots valid",
291 old_key->input_slots_valid, key->input_slots_valid);
Eric Anholtfc3b7c92012-07-12 13:19:53 -0700292
Eric Anholt14cec072013-02-22 13:15:20 -0800293 found |= brw_debug_recompile_sampler_key(intel, &old_key->tex, &key->tex);
Eric Anholtfc3b7c92012-07-12 13:19:53 -0700294
295 if (!found) {
296 perf_debug(" Something else\n");
297 }
298}
299
Kenneth Graunke1b05fc72011-12-06 15:36:21 -0800300void
301brw_populate_sampler_prog_key_data(struct gl_context *ctx,
Kenneth Graunkefe911c12012-06-16 13:50:03 -0700302 const struct gl_program *prog,
303 struct brw_sampler_prog_key_data *key)
Kenneth Graunke1b05fc72011-12-06 15:36:21 -0800304{
Kenneth Graunke6d6aef72012-09-21 03:13:36 -0700305 struct intel_context *intel = intel_context(ctx);
306
Kenneth Graunkef3d0daf2012-08-26 00:28:38 -0700307 for (int s = 0; s < MAX_SAMPLERS; s++) {
308 key->swizzles[s] = SWIZZLE_NOOP;
Kenneth Graunke76d13012012-08-14 11:05:55 -0700309
Kenneth Graunkef3d0daf2012-08-26 00:28:38 -0700310 if (!(prog->SamplersUsed & (1 << s)))
Kenneth Graunkefe911c12012-06-16 13:50:03 -0700311 continue;
Eric Anholt9f344b32006-08-09 19:14:05 +0000312
Kenneth Graunkef3d0daf2012-08-26 00:28:38 -0700313 int unit_id = prog->SamplerUnits[s];
314 const struct gl_texture_unit *unit = &ctx->Texture.Unit[unit_id];
Kenneth Graunke1b05fc72011-12-06 15:36:21 -0800315
Kenneth Graunkefe911c12012-06-16 13:50:03 -0700316 if (unit->_ReallyEnabled && unit->_Current->Target != GL_TEXTURE_BUFFER) {
317 const struct gl_texture_object *t = unit->_Current;
318 const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
Kenneth Graunkef3d0daf2012-08-26 00:28:38 -0700319 struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit_id);
Kenneth Graunkefe911c12012-06-16 13:50:03 -0700320
Kenneth Graunke6d6aef72012-09-21 03:13:36 -0700321 const bool alpha_depth = t->DepthMode == GL_ALPHA &&
322 (img->_BaseFormat == GL_DEPTH_COMPONENT ||
323 img->_BaseFormat == GL_DEPTH_STENCIL);
324
325 /* Haswell handles texture swizzling as surface format overrides
326 * (except for GL_ALPHA); all other platforms need MOVs in the shader.
327 */
328 if (!intel->is_haswell || alpha_depth)
Kenneth Graunke9db20982013-01-23 15:27:39 -0800329 key->swizzles[s] = brw_get_texture_swizzle(ctx, t);
Kenneth Graunkefe911c12012-06-16 13:50:03 -0700330
331 if (img->InternalFormat == GL_YCBCR_MESA) {
Kenneth Graunkef3d0daf2012-08-26 00:28:38 -0700332 key->yuvtex_mask |= 1 << s;
Kenneth Graunkefe911c12012-06-16 13:50:03 -0700333 if (img->TexFormat == MESA_FORMAT_YCBCR)
Kenneth Graunkef3d0daf2012-08-26 00:28:38 -0700334 key->yuvtex_swap_mask |= 1 << s;
Kenneth Graunkefe911c12012-06-16 13:50:03 -0700335 }
336
Kenneth Graunkefe911c12012-06-16 13:50:03 -0700337 if (sampler->MinFilter != GL_NEAREST &&
338 sampler->MagFilter != GL_NEAREST) {
339 if (sampler->WrapS == GL_CLAMP)
Kenneth Graunkef3d0daf2012-08-26 00:28:38 -0700340 key->gl_clamp_mask[0] |= 1 << s;
Kenneth Graunkefe911c12012-06-16 13:50:03 -0700341 if (sampler->WrapT == GL_CLAMP)
Kenneth Graunkef3d0daf2012-08-26 00:28:38 -0700342 key->gl_clamp_mask[1] |= 1 << s;
Kenneth Graunkefe911c12012-06-16 13:50:03 -0700343 if (sampler->WrapR == GL_CLAMP)
Kenneth Graunkef3d0daf2012-08-26 00:28:38 -0700344 key->gl_clamp_mask[2] |= 1 << s;
Kenneth Graunke1b05fc72011-12-06 15:36:21 -0800345 }
346 }
Kenneth Graunke1b05fc72011-12-06 15:36:21 -0800347 }
348}
Eric Anholt9f344b32006-08-09 19:14:05 +0000349
350static void brw_wm_populate_key( struct brw_context *brw,
351 struct brw_wm_prog_key *key )
352{
Kristian Høgsbergf9995b32010-10-12 12:26:10 -0400353 struct gl_context *ctx = &brw->intel.ctx;
Kenneth Graunke2f8351a2012-06-16 16:34:50 -0700354 struct intel_context *intel = &brw->intel;
Eric Anholt9f344b32006-08-09 19:14:05 +0000355 /* BRW_NEW_FRAGMENT_PROGRAM */
Brian Paul55d33e12009-02-20 10:49:30 -0700356 const struct brw_fragment_program *fp =
Eric Anholt9f344b32006-08-09 19:14:05 +0000357 (struct brw_fragment_program *)brw->fragment_program;
Kenneth Graunke387a3d42011-12-08 12:15:59 -0800358 const struct gl_program *prog = (struct gl_program *) brw->fragment_program;
Eric Anholt9f344b32006-08-09 19:14:05 +0000359 GLuint lookup = 0;
360 GLuint line_aa;
Paul Berryd08fdac2012-06-20 13:40:45 -0700361 bool program_uses_dfdy = fp->program.UsesDFdy;
Paul Berry82d25962012-06-20 13:40:45 -0700362
Eric Anholt9f344b32006-08-09 19:14:05 +0000363 memset(key, 0, sizeof(*key));
364
365 /* Build the index for table lookup
366 */
Kenneth Graunke2f8351a2012-06-16 16:34:50 -0700367 if (intel->gen < 6) {
Kenneth Graunke86e401b2012-07-12 11:25:58 -0700368 /* _NEW_COLOR */
Kenneth Graunke2f8351a2012-06-16 16:34:50 -0700369 if (fp->program.UsesKill || ctx->Color.AlphaEnabled)
370 lookup |= IZ_PS_KILL_ALPHATEST_BIT;
Eric Anholt9f344b32006-08-09 19:14:05 +0000371
Kenneth Graunke2f8351a2012-06-16 16:34:50 -0700372 if (fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
373 lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
Eric Anholt9f344b32006-08-09 19:14:05 +0000374
Kenneth Graunke2f8351a2012-06-16 16:34:50 -0700375 /* _NEW_DEPTH */
376 if (ctx->Depth.Test)
377 lookup |= IZ_DEPTH_TEST_ENABLE_BIT;
Eric Anholt9f344b32006-08-09 19:14:05 +0000378
Kenneth Graunke2f8351a2012-06-16 16:34:50 -0700379 if (ctx->Depth.Test && ctx->Depth.Mask) /* ?? */
380 lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
Eric Anholt9f344b32006-08-09 19:14:05 +0000381
Eric Anholt94ecf912013-06-20 09:08:30 -0700382 /* _NEW_STENCIL | _NEW_BUFFERS */
Kenneth Graunke2f8351a2012-06-16 16:34:50 -0700383 if (ctx->Stencil._Enabled) {
384 lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
385
386 if (ctx->Stencil.WriteMask[0] ||
387 ctx->Stencil.WriteMask[ctx->Stencil._BackFace])
388 lookup |= IZ_STENCIL_WRITE_ENABLE_BIT;
389 }
390 key->iz_lookup = lookup;
Eric Anholt9f344b32006-08-09 19:14:05 +0000391 }
392
Eric Anholt9f344b32006-08-09 19:14:05 +0000393 line_aa = AA_NEVER;
394
395 /* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */
Eric Anholt052c1d62009-01-30 14:32:23 -0800396 if (ctx->Line.SmoothFlag) {
Eric Anholt9f344b32006-08-09 19:14:05 +0000397 if (brw->intel.reduced_primitive == GL_LINES) {
398 line_aa = AA_ALWAYS;
399 }
400 else if (brw->intel.reduced_primitive == GL_TRIANGLES) {
Eric Anholt052c1d62009-01-30 14:32:23 -0800401 if (ctx->Polygon.FrontMode == GL_LINE) {
Eric Anholt9f344b32006-08-09 19:14:05 +0000402 line_aa = AA_SOMETIMES;
403
Eric Anholt052c1d62009-01-30 14:32:23 -0800404 if (ctx->Polygon.BackMode == GL_LINE ||
405 (ctx->Polygon.CullFlag &&
406 ctx->Polygon.CullFaceMode == GL_BACK))
Eric Anholt9f344b32006-08-09 19:14:05 +0000407 line_aa = AA_ALWAYS;
408 }
Eric Anholt052c1d62009-01-30 14:32:23 -0800409 else if (ctx->Polygon.BackMode == GL_LINE) {
Eric Anholt9f344b32006-08-09 19:14:05 +0000410 line_aa = AA_SOMETIMES;
411
Eric Anholt052c1d62009-01-30 14:32:23 -0800412 if ((ctx->Polygon.CullFlag &&
413 ctx->Polygon.CullFaceMode == GL_FRONT))
Eric Anholt9f344b32006-08-09 19:14:05 +0000414 line_aa = AA_ALWAYS;
415 }
416 }
417 }
Eric Anholt9f344b32006-08-09 19:14:05 +0000418
Eric Anholt16f8c822010-11-11 09:30:16 -0800419 key->line_aa = line_aa;
Kenneth Graunke6cc14c22012-08-26 00:47:44 -0700420
421 if (intel->gen < 6)
422 key->stats_wm = brw->intel.stats_wm;
Eric Anholt9f344b32006-08-09 19:14:05 +0000423
Eric Anholt9f344b32006-08-09 19:14:05 +0000424 /* _NEW_LIGHT */
Eric Anholt052c1d62009-01-30 14:32:23 -0800425 key->flat_shade = (ctx->Light.ShadeModel == GL_FLAT);
Eric Anholt9f344b32006-08-09 19:14:05 +0000426
Eric Anholtd22e2eb2011-04-15 14:40:09 -0700427 /* _NEW_FRAG_CLAMP | _NEW_BUFFERS */
428 key->clamp_fragment_color = ctx->Color._ClampFragmentColor;
429
Eric Anholt9f344b32006-08-09 19:14:05 +0000430 /* _NEW_TEXTURE */
Kenneth Graunkefe911c12012-06-16 13:50:03 -0700431 brw_populate_sampler_prog_key_data(ctx, prog, &key->tex);
Eric Anholt9c8f27b2008-02-28 13:18:12 -0800432
433 /* _NEW_BUFFERS */
434 /*
435 * Include the draw buffer origin and height so that we can calculate
436 * fragment position values relative to the bottom left of the drawable,
437 * from the incoming screen origin relative position we get as part of our
438 * payload.
439 *
Brian Paul861fec12009-10-29 15:29:41 -0600440 * This is only needed for the WM_WPOSXY opcode when the fragment program
441 * uses the gl_FragCoord input.
442 *
Eric Anholt9c8f27b2008-02-28 13:18:12 -0800443 * We could avoid recompiling by including this as a constant referenced by
444 * our program, but if we were to do that it would also be nice to handle
445 * getting that constant updated at batchbuffer submit time (when we
446 * hold the lock and know where the buffer really is) rather than at emit
447 * time when we don't hold the lock and are just guessing. We could also
448 * just avoid using this as key data if the program doesn't use
449 * fragment.position.
450 *
Brian Paul861fec12009-10-29 15:29:41 -0600451 * For DRI2 the origin_x/y will always be (0,0) but we still need the
452 * drawable height in order to invert the Y axis.
Eric Anholt9c8f27b2008-02-28 13:18:12 -0800453 */
Paul Berryeed6baf2013-02-23 09:00:58 -0800454 if (fp->program.Base.InputsRead & VARYING_BIT_POS) {
Eric Anholtf62c2a02010-01-26 13:08:42 -0800455 key->drawable_height = ctx->DrawBuffer->Height;
Paul Berry82d25962012-06-20 13:40:45 -0700456 }
457
Paul Berryeed6baf2013-02-23 09:00:58 -0800458 if ((fp->program.Base.InputsRead & VARYING_BIT_POS) || program_uses_dfdy) {
Brian Paul4433b032012-04-20 07:58:59 -0600459 key->render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
Eric Anholt9c8f27b2008-02-28 13:18:12 -0800460 }
Eric Anholt9f344b32006-08-09 19:14:05 +0000461
Eric Anholt1b806222011-01-30 21:13:17 -0800462 /* _NEW_BUFFERS */
463 key->nr_color_regions = ctx->DrawBuffer->_NumColorDrawBuffers;
Anuj Phogate592f7d2012-08-01 16:32:06 -0700464 /* _NEW_MULTISAMPLE */
465 key->sample_alpha_to_coverage = ctx->Multisample.SampleAlphaToCoverage;
Brian Paul9ef33b82009-10-29 14:53:53 -0600466
Paul Berrybf9bfe82013-03-17 11:29:28 -0700467 /* BRW_NEW_VUE_MAP_GEOM_OUT */
Kenneth Graunkeb6b1fc12012-08-13 23:59:09 -0700468 if (intel->gen < 6)
Paul Berry0a0deb92013-03-20 10:15:52 -0700469 key->input_slots_valid = brw->vue_map_geom_out.slots_valid;
Eric Anholt0f5113d2009-05-14 09:49:45 -0700470
Brian Paul55d33e12009-02-20 10:49:30 -0700471 /* The unique fragment program ID */
Eric Anholt9f344b32006-08-09 19:14:05 +0000472 key->program_string_id = fp->id;
Eric Anholt9f344b32006-08-09 19:14:05 +0000473}
474
475
Eric Anholtdc9a7532011-10-22 11:33:54 -0700476static void
477brw_upload_wm_prog(struct brw_context *brw)
Eric Anholt9f344b32006-08-09 19:14:05 +0000478{
Eric Anholt87527642011-05-16 15:10:26 -0700479 struct intel_context *intel = &brw->intel;
480 struct gl_context *ctx = &intel->ctx;
Eric Anholt9f344b32006-08-09 19:14:05 +0000481 struct brw_wm_prog_key key;
482 struct brw_fragment_program *fp = (struct brw_fragment_program *)
483 brw->fragment_program;
Eric Anholt662f1b42011-03-11 19:19:01 -0800484
Eric Anholt9f344b32006-08-09 19:14:05 +0000485 brw_wm_populate_key(brw, &key);
486
Eric Anholtc1735412011-04-27 13:33:10 -0700487 if (!brw_search_cache(&brw->cache, BRW_WM_PROG,
488 &key, sizeof(key),
489 &brw->wm.prog_offset, &brw->wm.prog_data)) {
Ian Romanickb527dd62011-11-15 12:01:18 -0800490 bool success = do_wm_prog(brw, ctx->Shader._CurrentFragmentProgram, fp,
Eric Anholt87527642011-05-16 15:10:26 -0700491 &key);
Brian Paul41702272011-10-07 10:38:30 -0600492 (void) success;
Eric Anholt87527642011-05-16 15:10:26 -0700493 assert(success);
494 }
Eric Anholt9f344b32006-08-09 19:14:05 +0000495}
496
497
Eric Anholt9f344b32006-08-09 19:14:05 +0000498const struct brw_tracked_state brw_wm_prog = {
499 .dirty = {
500 .mesa = (_NEW_COLOR |
501 _NEW_DEPTH |
502 _NEW_STENCIL |
503 _NEW_POLYGON |
504 _NEW_LINE |
505 _NEW_LIGHT |
Eric Anholtd22e2eb2011-04-15 14:40:09 -0700506 _NEW_FRAG_CLAMP |
Eric Anholt9c8f27b2008-02-28 13:18:12 -0800507 _NEW_BUFFERS |
Anuj Phogatf8a8f062012-08-29 12:22:11 -0700508 _NEW_TEXTURE |
509 _NEW_MULTISAMPLE),
Eric Anholt9f344b32006-08-09 19:14:05 +0000510 .brw = (BRW_NEW_FRAGMENT_PROGRAM |
Paul Berrybf9bfe82013-03-17 11:29:28 -0700511 BRW_NEW_REDUCED_PRIMITIVE |
Marek Olšák43dac272013-04-15 03:41:43 +0200512 BRW_NEW_VUE_MAP_GEOM_OUT |
513 BRW_NEW_STATS_WM)
Eric Anholt9f344b32006-08-09 19:14:05 +0000514 },
Eric Anholtdc9a7532011-10-22 11:33:54 -0700515 .emit = brw_upload_wm_prog
Eric Anholt9f344b32006-08-09 19:14:05 +0000516};
517