Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 1 | /* |
| 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 Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 32 | #include "brw_context.h" |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 33 | #include "brw_wm.h" |
| 34 | #include "brw_state.h" |
Eric Anholt | c374487 | 2010-08-10 22:21:59 -0700 | [diff] [blame] | 35 | #include "main/formats.h" |
Brian Paul | 4433b03 | 2012-04-20 07:58:59 -0600 | [diff] [blame] | 36 | #include "main/fbobject.h" |
Eric Anholt | 1f32c66 | 2011-04-20 11:48:31 -0700 | [diff] [blame] | 37 | #include "main/samplerobj.h" |
Eric Anholt | 8752764 | 2011-05-16 15:10:26 -0700 | [diff] [blame] | 38 | #include "program/prog_parameter.h" |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 39 | |
Chad Versace | 2f0edc6 | 2011-08-26 13:58:41 -0700 | [diff] [blame] | 40 | #include "glsl/ralloc.h" |
Kenneth Graunke | 774fb90 | 2011-05-16 11:49:57 -0700 | [diff] [blame] | 41 | |
Paul Berry | e04bdea | 2011-10-21 17:20:32 -0700 | [diff] [blame] | 42 | /** |
| 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 Anholt | 71d71d5 | 2012-02-14 21:48:43 -0800 | [diff] [blame] | 46 | static unsigned |
Paul Berry | 8313f44 | 2012-06-21 11:21:22 -0700 | [diff] [blame] | 47 | brw_compute_barycentric_interp_modes(struct brw_context *brw, |
| 48 | bool shade_model_flat, |
Paul Berry | 5aa9628 | 2011-10-22 09:33:16 -0700 | [diff] [blame] | 49 | const struct gl_fragment_program *fprog) |
Paul Berry | e04bdea | 2011-10-21 17:20:32 -0700 | [diff] [blame] | 50 | { |
Paul Berry | 5aa9628 | 2011-10-22 09:33:16 -0700 | [diff] [blame] | 51 | 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 Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 58 | for (attr = 0; attr < VARYING_SLOT_MAX; ++attr) { |
Paul Berry | 5aa9628 | 2011-10-22 09:33:16 -0700 | [diff] [blame] | 59 | enum glsl_interp_qualifier interp_qualifier = |
| 60 | fprog->InterpQualifier[attr]; |
Paul Berry | d105654 | 2012-06-18 13:52:02 -0700 | [diff] [blame] | 61 | bool is_centroid = fprog->IsCentroid & BITFIELD64_BIT(attr); |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 62 | bool is_gl_Color = attr == VARYING_SLOT_COL0 || attr == VARYING_SLOT_COL1; |
Paul Berry | 5aa9628 | 2011-10-22 09:33:16 -0700 | [diff] [blame] | 63 | |
| 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 Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 69 | if (attr == VARYING_SLOT_POS || attr == VARYING_SLOT_FACE) |
Paul Berry | 5aa9628 | 2011-10-22 09:33:16 -0700 | [diff] [blame] | 70 | continue; |
| 71 | |
Paul Berry | 8313f44 | 2012-06-21 11:21:22 -0700 | [diff] [blame] | 72 | /* 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 Berry | 5aa9628 | 2011-10-22 09:33:16 -0700 | [diff] [blame] | 78 | if (interp_qualifier == INTERP_QUALIFIER_NOPERSPECTIVE) { |
Paul Berry | d105654 | 2012-06-18 13:52:02 -0700 | [diff] [blame] | 79 | if (is_centroid) { |
| 80 | barycentric_interp_modes |= |
| 81 | 1 << BRW_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC; |
Paul Berry | 8313f44 | 2012-06-21 11:21:22 -0700 | [diff] [blame] | 82 | } |
| 83 | if (!is_centroid || brw->needs_unlit_centroid_workaround) { |
Paul Berry | d105654 | 2012-06-18 13:52:02 -0700 | [diff] [blame] | 84 | barycentric_interp_modes |= |
| 85 | 1 << BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC; |
| 86 | } |
Paul Berry | 5aa9628 | 2011-10-22 09:33:16 -0700 | [diff] [blame] | 87 | } else if (interp_qualifier == INTERP_QUALIFIER_SMOOTH || |
| 88 | (!(shade_model_flat && is_gl_Color) && |
| 89 | interp_qualifier == INTERP_QUALIFIER_NONE)) { |
Paul Berry | d105654 | 2012-06-18 13:52:02 -0700 | [diff] [blame] | 90 | if (is_centroid) { |
| 91 | barycentric_interp_modes |= |
| 92 | 1 << BRW_WM_PERSPECTIVE_CENTROID_BARYCENTRIC; |
Paul Berry | 8313f44 | 2012-06-21 11:21:22 -0700 | [diff] [blame] | 93 | } |
| 94 | if (!is_centroid || brw->needs_unlit_centroid_workaround) { |
Paul Berry | d105654 | 2012-06-18 13:52:02 -0700 | [diff] [blame] | 95 | barycentric_interp_modes |= |
| 96 | 1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC; |
| 97 | } |
Paul Berry | 5aa9628 | 2011-10-22 09:33:16 -0700 | [diff] [blame] | 98 | } |
| 99 | } |
| 100 | |
| 101 | return barycentric_interp_modes; |
Paul Berry | e04bdea | 2011-10-21 17:20:32 -0700 | [diff] [blame] | 102 | } |
| 103 | |
Eric Anholt | 99596cb | 2012-08-26 21:19:05 -0700 | [diff] [blame] | 104 | bool |
| 105 | brw_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 Anholt | f144b78 | 2012-08-26 21:19:05 -0700 | [diff] [blame] | 124 | void |
| 125 | brw_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 Paul | 2f78d4a | 2009-02-12 15:35:41 -0700 | [diff] [blame] | 133 | /** |
| 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 Anholt | 8752764 | 2011-05-16 15:10:26 -0700 | [diff] [blame] | 138 | bool 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 Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 142 | { |
Eric Anholt | 59c6b77 | 2011-04-14 19:36:28 -0700 | [diff] [blame] | 143 | struct intel_context *intel = &brw->intel; |
Eric Anholt | d7b24fe | 2006-12-09 22:35:07 -0800 | [diff] [blame] | 144 | struct brw_wm_compile *c; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 145 | const GLuint *program; |
Eric Anholt | f144b78 | 2012-08-26 21:19:05 -0700 | [diff] [blame] | 146 | struct gl_shader *fs = NULL; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 147 | GLuint program_size; |
| 148 | |
Eric Anholt | f144b78 | 2012-08-26 21:19:05 -0700 | [diff] [blame] | 149 | if (prog) |
| 150 | fs = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; |
| 151 | |
Eric Anholt | 2fcaf4e | 2012-11-06 09:48:51 -0800 | [diff] [blame] | 152 | c = rzalloc(NULL, struct brw_wm_compile); |
Eric Anholt | f144b78 | 2012-08-26 21:19:05 -0700 | [diff] [blame] | 153 | |
| 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 Anholt | a43b107 | 2012-11-08 14:02:22 -0800 | [diff] [blame] | 158 | int param_count; |
Eric Anholt | f144b78 | 2012-08-26 21:19:05 -0700 | [diff] [blame] | 159 | if (fs) { |
Eric Anholt | a43b107 | 2012-11-08 14:02:22 -0800 | [diff] [blame] | 160 | param_count = fs->num_uniform_components; |
Eric Anholt | f144b78 | 2012-08-26 21:19:05 -0700 | [diff] [blame] | 161 | } else { |
Eric Anholt | a43b107 | 2012-11-08 14:02:22 -0800 | [diff] [blame] | 162 | param_count = fp->program.Base.Parameters->NumParameters * 4; |
Eric Anholt | f144b78 | 2012-08-26 21:19:05 -0700 | [diff] [blame] | 163 | } |
Eric Anholt | a43b107 | 2012-11-08 14:02:22 -0800 | [diff] [blame] | 164 | /* 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 Anholt | f144b78 | 2012-08-26 21:19:05 -0700 | [diff] [blame] | 168 | |
Eric Anholt | d7b24fe | 2006-12-09 22:35:07 -0800 | [diff] [blame] | 169 | memcpy(&c->key, key, sizeof(*key)); |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 170 | |
Eric Anholt | 71d71d5 | 2012-02-14 21:48:43 -0800 | [diff] [blame] | 171 | c->prog_data.barycentric_interp_modes = |
Paul Berry | 8313f44 | 2012-06-21 11:21:22 -0700 | [diff] [blame] | 172 | brw_compute_barycentric_interp_modes(brw, c->key.flat_shade, |
| 173 | &fp->program); |
Eric Anholt | 71d71d5 | 2012-02-14 21:48:43 -0800 | [diff] [blame] | 174 | |
Kenneth Graunke | 4d09fe9 | 2012-11-20 16:21:27 -0800 | [diff] [blame] | 175 | program = brw_wm_fs_emit(brw, c, &fp->program, prog, &program_size); |
| 176 | if (program == NULL) |
| 177 | return false; |
Brian Paul | 2f78d4a | 2009-02-12 15:35:41 -0700 | [diff] [blame] | 178 | |
Eric Anholt | 4e72525 | 2010-10-21 15:07:45 -0700 | [diff] [blame] | 179 | /* Scratch space is used for register spilling */ |
| 180 | if (c->last_scratch) { |
Eric Anholt | 4cfb9e3 | 2012-07-12 13:08:20 -0700 | [diff] [blame] | 181 | perf_debug("Fragment shader triggered register spilling. " |
| 182 | "Try reducing the number of live scalar values to " |
| 183 | "improve performance.\n"); |
| 184 | |
Eric Anholt | 2b224d6 | 2011-08-07 10:44:15 -0700 | [diff] [blame] | 185 | c->prog_data.total_scratch = brw_get_scratch_size(c->last_scratch); |
Eric Anholt | 59c6b77 | 2011-04-14 19:36:28 -0700 | [diff] [blame] | 186 | |
Eric Anholt | abbb8fc | 2011-08-23 10:51:16 -0700 | [diff] [blame] | 187 | brw_get_scratch_bo(intel, &brw->wm.scratch_bo, |
Kenneth Graunke | db6dd6d | 2011-10-23 22:10:03 -0700 | [diff] [blame] | 188 | c->prog_data.total_scratch * brw->max_wm_threads); |
Eric Anholt | 4e72525 | 2010-10-21 15:07:45 -0700 | [diff] [blame] | 189 | } |
| 190 | |
Eric Anholt | bb15408 | 2010-11-02 19:55:07 -0700 | [diff] [blame] | 191 | if (unlikely(INTEL_DEBUG & DEBUG_WM)) |
Eric Anholt | fc3971d | 2009-01-08 19:15:04 -0800 | [diff] [blame] | 192 | fprintf(stderr, "\n"); |
| 193 | |
Eric Anholt | c173541 | 2011-04-27 13:33:10 -0700 | [diff] [blame] | 194 | 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 Anholt | 8752764 | 2011-05-16 15:10:26 -0700 | [diff] [blame] | 199 | |
Eric Anholt | 2fcaf4e | 2012-11-06 09:48:51 -0800 | [diff] [blame] | 200 | ralloc_free(c); |
| 201 | |
Eric Anholt | 8752764 | 2011-05-16 15:10:26 -0700 | [diff] [blame] | 202 | return true; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 203 | } |
| 204 | |
Eric Anholt | fc3b7c9 | 2012-07-12 13:19:53 -0700 | [diff] [blame] | 205 | static bool |
Eric Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 206 | key_debug(struct intel_context *intel, const char *name, int a, int b) |
Eric Anholt | fc3b7c9 | 2012-07-12 13:19:53 -0700 | [diff] [blame] | 207 | { |
| 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 | |
| 216 | bool |
Eric Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 217 | brw_debug_recompile_sampler_key(struct intel_context *intel, |
| 218 | const struct brw_sampler_prog_key_data *old_key, |
Eric Anholt | fc3b7c9 | 2012-07-12 13:19:53 -0700 | [diff] [blame] | 219 | const struct brw_sampler_prog_key_data *key) |
| 220 | { |
| 221 | bool found = false; |
| 222 | |
Kenneth Graunke | f3d0daf | 2012-08-26 00:28:38 -0700 | [diff] [blame] | 223 | for (unsigned int i = 0; i < MAX_SAMPLERS; i++) { |
Eric Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 224 | found |= key_debug(intel, "EXT_texture_swizzle or DEPTH_TEXTURE_MODE", |
Kenneth Graunke | 98211d5 | 2012-08-15 16:35:35 -0700 | [diff] [blame] | 225 | old_key->swizzles[i], key->swizzles[i]); |
Eric Anholt | fc3b7c9 | 2012-07-12 13:19:53 -0700 | [diff] [blame] | 226 | } |
Eric Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 227 | found |= key_debug(intel, "GL_CLAMP enabled on any texture unit's 1st coordinate", |
Kenneth Graunke | 98211d5 | 2012-08-15 16:35:35 -0700 | [diff] [blame] | 228 | old_key->gl_clamp_mask[0], key->gl_clamp_mask[0]); |
Eric Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 229 | found |= key_debug(intel, "GL_CLAMP enabled on any texture unit's 2nd coordinate", |
Kenneth Graunke | 98211d5 | 2012-08-15 16:35:35 -0700 | [diff] [blame] | 230 | old_key->gl_clamp_mask[1], key->gl_clamp_mask[1]); |
Eric Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 231 | found |= key_debug(intel, "GL_CLAMP enabled on any texture unit's 3rd coordinate", |
Kenneth Graunke | 98211d5 | 2012-08-15 16:35:35 -0700 | [diff] [blame] | 232 | old_key->gl_clamp_mask[2], key->gl_clamp_mask[2]); |
Eric Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 233 | found |= key_debug(intel, "GL_MESA_ycbcr texturing\n", |
Kenneth Graunke | 98211d5 | 2012-08-15 16:35:35 -0700 | [diff] [blame] | 234 | old_key->yuvtex_mask, key->yuvtex_mask); |
Eric Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 235 | found |= key_debug(intel, "GL_MESA_ycbcr UV swapping\n", |
Kenneth Graunke | 98211d5 | 2012-08-15 16:35:35 -0700 | [diff] [blame] | 236 | old_key->yuvtex_swap_mask, key->yuvtex_swap_mask); |
Eric Anholt | fc3b7c9 | 2012-07-12 13:19:53 -0700 | [diff] [blame] | 237 | |
| 238 | return found; |
| 239 | } |
| 240 | |
| 241 | void |
| 242 | brw_wm_debug_recompile(struct brw_context *brw, |
| 243 | struct gl_shader_program *prog, |
| 244 | const struct brw_wm_prog_key *key) |
| 245 | { |
Eric Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 246 | struct intel_context *intel = &brw->intel; |
Eric Anholt | fc3b7c9 | 2012-07-12 13:19:53 -0700 | [diff] [blame] | 247 | 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 Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 267 | perf_debug(" Didn't find previous compile in the shader cache for debug\n"); |
Eric Anholt | fc3b7c9 | 2012-07-12 13:19:53 -0700 | [diff] [blame] | 268 | return; |
| 269 | } |
| 270 | |
Eric Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 271 | found |= key_debug(intel, "alphatest, computed depth, depth test, or " |
| 272 | "depth write", |
Kenneth Graunke | 98211d5 | 2012-08-15 16:35:35 -0700 | [diff] [blame] | 273 | old_key->iz_lookup, key->iz_lookup); |
Eric Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 274 | 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 Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 288 | found |= key_debug(intel, "renderbuffer height", |
| 289 | old_key->drawable_height, key->drawable_height); |
Paul Berry | 0a0deb9 | 2013-03-20 10:15:52 -0700 | [diff] [blame] | 290 | found |= key_debug(intel, "input slots valid", |
| 291 | old_key->input_slots_valid, key->input_slots_valid); |
Eric Anholt | fc3b7c9 | 2012-07-12 13:19:53 -0700 | [diff] [blame] | 292 | |
Eric Anholt | 14cec07 | 2013-02-22 13:15:20 -0800 | [diff] [blame] | 293 | found |= brw_debug_recompile_sampler_key(intel, &old_key->tex, &key->tex); |
Eric Anholt | fc3b7c9 | 2012-07-12 13:19:53 -0700 | [diff] [blame] | 294 | |
| 295 | if (!found) { |
| 296 | perf_debug(" Something else\n"); |
| 297 | } |
| 298 | } |
| 299 | |
Kenneth Graunke | 1b05fc7 | 2011-12-06 15:36:21 -0800 | [diff] [blame] | 300 | void |
| 301 | brw_populate_sampler_prog_key_data(struct gl_context *ctx, |
Kenneth Graunke | fe911c1 | 2012-06-16 13:50:03 -0700 | [diff] [blame] | 302 | const struct gl_program *prog, |
| 303 | struct brw_sampler_prog_key_data *key) |
Kenneth Graunke | 1b05fc7 | 2011-12-06 15:36:21 -0800 | [diff] [blame] | 304 | { |
Kenneth Graunke | 6d6aef7 | 2012-09-21 03:13:36 -0700 | [diff] [blame] | 305 | struct intel_context *intel = intel_context(ctx); |
| 306 | |
Kenneth Graunke | f3d0daf | 2012-08-26 00:28:38 -0700 | [diff] [blame] | 307 | for (int s = 0; s < MAX_SAMPLERS; s++) { |
| 308 | key->swizzles[s] = SWIZZLE_NOOP; |
Kenneth Graunke | 76d1301 | 2012-08-14 11:05:55 -0700 | [diff] [blame] | 309 | |
Kenneth Graunke | f3d0daf | 2012-08-26 00:28:38 -0700 | [diff] [blame] | 310 | if (!(prog->SamplersUsed & (1 << s))) |
Kenneth Graunke | fe911c1 | 2012-06-16 13:50:03 -0700 | [diff] [blame] | 311 | continue; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 312 | |
Kenneth Graunke | f3d0daf | 2012-08-26 00:28:38 -0700 | [diff] [blame] | 313 | int unit_id = prog->SamplerUnits[s]; |
| 314 | const struct gl_texture_unit *unit = &ctx->Texture.Unit[unit_id]; |
Kenneth Graunke | 1b05fc7 | 2011-12-06 15:36:21 -0800 | [diff] [blame] | 315 | |
Kenneth Graunke | fe911c1 | 2012-06-16 13:50:03 -0700 | [diff] [blame] | 316 | 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 Graunke | f3d0daf | 2012-08-26 00:28:38 -0700 | [diff] [blame] | 319 | struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit_id); |
Kenneth Graunke | fe911c1 | 2012-06-16 13:50:03 -0700 | [diff] [blame] | 320 | |
Kenneth Graunke | 6d6aef7 | 2012-09-21 03:13:36 -0700 | [diff] [blame] | 321 | 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 Graunke | 9db2098 | 2013-01-23 15:27:39 -0800 | [diff] [blame] | 329 | key->swizzles[s] = brw_get_texture_swizzle(ctx, t); |
Kenneth Graunke | fe911c1 | 2012-06-16 13:50:03 -0700 | [diff] [blame] | 330 | |
| 331 | if (img->InternalFormat == GL_YCBCR_MESA) { |
Kenneth Graunke | f3d0daf | 2012-08-26 00:28:38 -0700 | [diff] [blame] | 332 | key->yuvtex_mask |= 1 << s; |
Kenneth Graunke | fe911c1 | 2012-06-16 13:50:03 -0700 | [diff] [blame] | 333 | if (img->TexFormat == MESA_FORMAT_YCBCR) |
Kenneth Graunke | f3d0daf | 2012-08-26 00:28:38 -0700 | [diff] [blame] | 334 | key->yuvtex_swap_mask |= 1 << s; |
Kenneth Graunke | fe911c1 | 2012-06-16 13:50:03 -0700 | [diff] [blame] | 335 | } |
| 336 | |
Kenneth Graunke | fe911c1 | 2012-06-16 13:50:03 -0700 | [diff] [blame] | 337 | if (sampler->MinFilter != GL_NEAREST && |
| 338 | sampler->MagFilter != GL_NEAREST) { |
| 339 | if (sampler->WrapS == GL_CLAMP) |
Kenneth Graunke | f3d0daf | 2012-08-26 00:28:38 -0700 | [diff] [blame] | 340 | key->gl_clamp_mask[0] |= 1 << s; |
Kenneth Graunke | fe911c1 | 2012-06-16 13:50:03 -0700 | [diff] [blame] | 341 | if (sampler->WrapT == GL_CLAMP) |
Kenneth Graunke | f3d0daf | 2012-08-26 00:28:38 -0700 | [diff] [blame] | 342 | key->gl_clamp_mask[1] |= 1 << s; |
Kenneth Graunke | fe911c1 | 2012-06-16 13:50:03 -0700 | [diff] [blame] | 343 | if (sampler->WrapR == GL_CLAMP) |
Kenneth Graunke | f3d0daf | 2012-08-26 00:28:38 -0700 | [diff] [blame] | 344 | key->gl_clamp_mask[2] |= 1 << s; |
Kenneth Graunke | 1b05fc7 | 2011-12-06 15:36:21 -0800 | [diff] [blame] | 345 | } |
| 346 | } |
Kenneth Graunke | 1b05fc7 | 2011-12-06 15:36:21 -0800 | [diff] [blame] | 347 | } |
| 348 | } |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 349 | |
| 350 | static void brw_wm_populate_key( struct brw_context *brw, |
| 351 | struct brw_wm_prog_key *key ) |
| 352 | { |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 353 | struct gl_context *ctx = &brw->intel.ctx; |
Kenneth Graunke | 2f8351a | 2012-06-16 16:34:50 -0700 | [diff] [blame] | 354 | struct intel_context *intel = &brw->intel; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 355 | /* BRW_NEW_FRAGMENT_PROGRAM */ |
Brian Paul | 55d33e1 | 2009-02-20 10:49:30 -0700 | [diff] [blame] | 356 | const struct brw_fragment_program *fp = |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 357 | (struct brw_fragment_program *)brw->fragment_program; |
Kenneth Graunke | 387a3d4 | 2011-12-08 12:15:59 -0800 | [diff] [blame] | 358 | const struct gl_program *prog = (struct gl_program *) brw->fragment_program; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 359 | GLuint lookup = 0; |
| 360 | GLuint line_aa; |
Paul Berry | d08fdac | 2012-06-20 13:40:45 -0700 | [diff] [blame] | 361 | bool program_uses_dfdy = fp->program.UsesDFdy; |
Paul Berry | 82d2596 | 2012-06-20 13:40:45 -0700 | [diff] [blame] | 362 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 363 | memset(key, 0, sizeof(*key)); |
| 364 | |
| 365 | /* Build the index for table lookup |
| 366 | */ |
Kenneth Graunke | 2f8351a | 2012-06-16 16:34:50 -0700 | [diff] [blame] | 367 | if (intel->gen < 6) { |
Kenneth Graunke | 86e401b | 2012-07-12 11:25:58 -0700 | [diff] [blame] | 368 | /* _NEW_COLOR */ |
Kenneth Graunke | 2f8351a | 2012-06-16 16:34:50 -0700 | [diff] [blame] | 369 | if (fp->program.UsesKill || ctx->Color.AlphaEnabled) |
| 370 | lookup |= IZ_PS_KILL_ALPHATEST_BIT; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 371 | |
Kenneth Graunke | 2f8351a | 2012-06-16 16:34:50 -0700 | [diff] [blame] | 372 | if (fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) |
| 373 | lookup |= IZ_PS_COMPUTES_DEPTH_BIT; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 374 | |
Kenneth Graunke | 2f8351a | 2012-06-16 16:34:50 -0700 | [diff] [blame] | 375 | /* _NEW_DEPTH */ |
| 376 | if (ctx->Depth.Test) |
| 377 | lookup |= IZ_DEPTH_TEST_ENABLE_BIT; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 378 | |
Kenneth Graunke | 2f8351a | 2012-06-16 16:34:50 -0700 | [diff] [blame] | 379 | if (ctx->Depth.Test && ctx->Depth.Mask) /* ?? */ |
| 380 | lookup |= IZ_DEPTH_WRITE_ENABLE_BIT; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 381 | |
Eric Anholt | 94ecf91 | 2013-06-20 09:08:30 -0700 | [diff] [blame^] | 382 | /* _NEW_STENCIL | _NEW_BUFFERS */ |
Kenneth Graunke | 2f8351a | 2012-06-16 16:34:50 -0700 | [diff] [blame] | 383 | 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 Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 391 | } |
| 392 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 393 | line_aa = AA_NEVER; |
| 394 | |
| 395 | /* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */ |
Eric Anholt | 052c1d6 | 2009-01-30 14:32:23 -0800 | [diff] [blame] | 396 | if (ctx->Line.SmoothFlag) { |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 397 | if (brw->intel.reduced_primitive == GL_LINES) { |
| 398 | line_aa = AA_ALWAYS; |
| 399 | } |
| 400 | else if (brw->intel.reduced_primitive == GL_TRIANGLES) { |
Eric Anholt | 052c1d6 | 2009-01-30 14:32:23 -0800 | [diff] [blame] | 401 | if (ctx->Polygon.FrontMode == GL_LINE) { |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 402 | line_aa = AA_SOMETIMES; |
| 403 | |
Eric Anholt | 052c1d6 | 2009-01-30 14:32:23 -0800 | [diff] [blame] | 404 | if (ctx->Polygon.BackMode == GL_LINE || |
| 405 | (ctx->Polygon.CullFlag && |
| 406 | ctx->Polygon.CullFaceMode == GL_BACK)) |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 407 | line_aa = AA_ALWAYS; |
| 408 | } |
Eric Anholt | 052c1d6 | 2009-01-30 14:32:23 -0800 | [diff] [blame] | 409 | else if (ctx->Polygon.BackMode == GL_LINE) { |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 410 | line_aa = AA_SOMETIMES; |
| 411 | |
Eric Anholt | 052c1d6 | 2009-01-30 14:32:23 -0800 | [diff] [blame] | 412 | if ((ctx->Polygon.CullFlag && |
| 413 | ctx->Polygon.CullFaceMode == GL_FRONT)) |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 414 | line_aa = AA_ALWAYS; |
| 415 | } |
| 416 | } |
| 417 | } |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 418 | |
Eric Anholt | 16f8c82 | 2010-11-11 09:30:16 -0800 | [diff] [blame] | 419 | key->line_aa = line_aa; |
Kenneth Graunke | 6cc14c2 | 2012-08-26 00:47:44 -0700 | [diff] [blame] | 420 | |
| 421 | if (intel->gen < 6) |
| 422 | key->stats_wm = brw->intel.stats_wm; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 423 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 424 | /* _NEW_LIGHT */ |
Eric Anholt | 052c1d6 | 2009-01-30 14:32:23 -0800 | [diff] [blame] | 425 | key->flat_shade = (ctx->Light.ShadeModel == GL_FLAT); |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 426 | |
Eric Anholt | d22e2eb | 2011-04-15 14:40:09 -0700 | [diff] [blame] | 427 | /* _NEW_FRAG_CLAMP | _NEW_BUFFERS */ |
| 428 | key->clamp_fragment_color = ctx->Color._ClampFragmentColor; |
| 429 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 430 | /* _NEW_TEXTURE */ |
Kenneth Graunke | fe911c1 | 2012-06-16 13:50:03 -0700 | [diff] [blame] | 431 | brw_populate_sampler_prog_key_data(ctx, prog, &key->tex); |
Eric Anholt | 9c8f27b | 2008-02-28 13:18:12 -0800 | [diff] [blame] | 432 | |
| 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 Paul | 861fec1 | 2009-10-29 15:29:41 -0600 | [diff] [blame] | 440 | * This is only needed for the WM_WPOSXY opcode when the fragment program |
| 441 | * uses the gl_FragCoord input. |
| 442 | * |
Eric Anholt | 9c8f27b | 2008-02-28 13:18:12 -0800 | [diff] [blame] | 443 | * 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 Paul | 861fec1 | 2009-10-29 15:29:41 -0600 | [diff] [blame] | 451 | * 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 Anholt | 9c8f27b | 2008-02-28 13:18:12 -0800 | [diff] [blame] | 453 | */ |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 454 | if (fp->program.Base.InputsRead & VARYING_BIT_POS) { |
Eric Anholt | f62c2a0 | 2010-01-26 13:08:42 -0800 | [diff] [blame] | 455 | key->drawable_height = ctx->DrawBuffer->Height; |
Paul Berry | 82d2596 | 2012-06-20 13:40:45 -0700 | [diff] [blame] | 456 | } |
| 457 | |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 458 | if ((fp->program.Base.InputsRead & VARYING_BIT_POS) || program_uses_dfdy) { |
Brian Paul | 4433b03 | 2012-04-20 07:58:59 -0600 | [diff] [blame] | 459 | key->render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer); |
Eric Anholt | 9c8f27b | 2008-02-28 13:18:12 -0800 | [diff] [blame] | 460 | } |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 461 | |
Eric Anholt | 1b80622 | 2011-01-30 21:13:17 -0800 | [diff] [blame] | 462 | /* _NEW_BUFFERS */ |
| 463 | key->nr_color_regions = ctx->DrawBuffer->_NumColorDrawBuffers; |
Anuj Phogat | e592f7d | 2012-08-01 16:32:06 -0700 | [diff] [blame] | 464 | /* _NEW_MULTISAMPLE */ |
| 465 | key->sample_alpha_to_coverage = ctx->Multisample.SampleAlphaToCoverage; |
Brian Paul | 9ef33b8 | 2009-10-29 14:53:53 -0600 | [diff] [blame] | 466 | |
Paul Berry | bf9bfe8 | 2013-03-17 11:29:28 -0700 | [diff] [blame] | 467 | /* BRW_NEW_VUE_MAP_GEOM_OUT */ |
Kenneth Graunke | b6b1fc1 | 2012-08-13 23:59:09 -0700 | [diff] [blame] | 468 | if (intel->gen < 6) |
Paul Berry | 0a0deb9 | 2013-03-20 10:15:52 -0700 | [diff] [blame] | 469 | key->input_slots_valid = brw->vue_map_geom_out.slots_valid; |
Eric Anholt | 0f5113d | 2009-05-14 09:49:45 -0700 | [diff] [blame] | 470 | |
Brian Paul | 55d33e1 | 2009-02-20 10:49:30 -0700 | [diff] [blame] | 471 | /* The unique fragment program ID */ |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 472 | key->program_string_id = fp->id; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 473 | } |
| 474 | |
| 475 | |
Eric Anholt | dc9a753 | 2011-10-22 11:33:54 -0700 | [diff] [blame] | 476 | static void |
| 477 | brw_upload_wm_prog(struct brw_context *brw) |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 478 | { |
Eric Anholt | 8752764 | 2011-05-16 15:10:26 -0700 | [diff] [blame] | 479 | struct intel_context *intel = &brw->intel; |
| 480 | struct gl_context *ctx = &intel->ctx; |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 481 | struct brw_wm_prog_key key; |
| 482 | struct brw_fragment_program *fp = (struct brw_fragment_program *) |
| 483 | brw->fragment_program; |
Eric Anholt | 662f1b4 | 2011-03-11 19:19:01 -0800 | [diff] [blame] | 484 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 485 | brw_wm_populate_key(brw, &key); |
| 486 | |
Eric Anholt | c173541 | 2011-04-27 13:33:10 -0700 | [diff] [blame] | 487 | if (!brw_search_cache(&brw->cache, BRW_WM_PROG, |
| 488 | &key, sizeof(key), |
| 489 | &brw->wm.prog_offset, &brw->wm.prog_data)) { |
Ian Romanick | b527dd6 | 2011-11-15 12:01:18 -0800 | [diff] [blame] | 490 | bool success = do_wm_prog(brw, ctx->Shader._CurrentFragmentProgram, fp, |
Eric Anholt | 8752764 | 2011-05-16 15:10:26 -0700 | [diff] [blame] | 491 | &key); |
Brian Paul | 4170227 | 2011-10-07 10:38:30 -0600 | [diff] [blame] | 492 | (void) success; |
Eric Anholt | 8752764 | 2011-05-16 15:10:26 -0700 | [diff] [blame] | 493 | assert(success); |
| 494 | } |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 495 | } |
| 496 | |
| 497 | |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 498 | const 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 Anholt | d22e2eb | 2011-04-15 14:40:09 -0700 | [diff] [blame] | 506 | _NEW_FRAG_CLAMP | |
Eric Anholt | 9c8f27b | 2008-02-28 13:18:12 -0800 | [diff] [blame] | 507 | _NEW_BUFFERS | |
Anuj Phogat | f8a8f06 | 2012-08-29 12:22:11 -0700 | [diff] [blame] | 508 | _NEW_TEXTURE | |
| 509 | _NEW_MULTISAMPLE), |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 510 | .brw = (BRW_NEW_FRAGMENT_PROGRAM | |
Paul Berry | bf9bfe8 | 2013-03-17 11:29:28 -0700 | [diff] [blame] | 511 | BRW_NEW_REDUCED_PRIMITIVE | |
Marek Olšák | 43dac27 | 2013-04-15 03:41:43 +0200 | [diff] [blame] | 512 | BRW_NEW_VUE_MAP_GEOM_OUT | |
| 513 | BRW_NEW_STATS_WM) |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 514 | }, |
Eric Anholt | dc9a753 | 2011-10-22 11:33:54 -0700 | [diff] [blame] | 515 | .emit = brw_upload_wm_prog |
Eric Anholt | 9f344b3 | 2006-08-09 19:14:05 +0000 | [diff] [blame] | 516 | }; |
| 517 | |