brw_wm.c revision c5413839b3e99c7b162f1260142f3c175502b0ce
19f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt/*
29f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Copyright (C) Intel Corp.  2006.  All Rights Reserved.
39f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
49f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt develop this 3D driver.
59f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
69f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt Permission is hereby granted, free of charge, to any person obtaining
79f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt a copy of this software and associated documentation files (the
89f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt "Software"), to deal in the Software without restriction, including
99f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt without limitation the rights to use, copy, modify, merge, publish,
109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt distribute, sublicense, and/or sell copies of the Software, and to
119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt permit persons to whom the Software is furnished to do so, subject to
129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt the following conditions:
139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt The above copyright notice and this permission notice (including the
159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt next paragraph) shall be included in all copies or substantial
169f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt portions of the Software.
179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
189f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
209f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt **********************************************************************/
279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt /*
289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  * Authors:
299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  *   Keith Whitwell <keith@tungstengraphics.com>
309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt  */
319f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_context.h"
339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_util.h"
349f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_wm.h"
359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt#include "brw_state.h"
369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3832e03c4a2ff5ef07de892dcd26f6be3b82ab3ba1Brian Paul/** Return number of src args for given instruction */
399f344b3e7d6e23674dd4747faec253f103563b36Eric AnholtGLuint brw_wm_nr_args( GLuint opcode )
409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   switch (opcode) {
42699db6d842c52d0b3b98b320f8ef1104a65fa783Eric Anholt   case WM_FRONTFACING:
439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case WM_PIXELXY:
4408687c8b402f42eda5e0061112382528836b0fe9Eric Anholt      return 0;
45046e88fc0be37d5a3dfbfa9fb8033b549604c74cEric Anholt   case WM_CINTERP:
46046e88fc0be37d5a3dfbfa9fb8033b549604c74cEric Anholt   case WM_WPOSXY:
4708687c8b402f42eda5e0061112382528836b0fe9Eric Anholt   case WM_DELTAXY:
489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      return 1;
49046e88fc0be37d5a3dfbfa9fb8033b549604c74cEric Anholt   case WM_LINTERP:
509f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case WM_PIXELW:
519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      return 2;
529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case WM_FB_WRITE:
53046e88fc0be37d5a3dfbfa9fb8033b549604c74cEric Anholt   case WM_PINTERP:
549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      return 3;
559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   default:
56046e88fc0be37d5a3dfbfa9fb8033b549604c74cEric Anholt      assert(opcode < MAX_OPCODE);
57046e88fc0be37d5a3dfbfa9fb8033b549604c74cEric Anholt      return _mesa_num_inst_src_regs(opcode);
589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
629f344b3e7d6e23674dd4747faec253f103563b36Eric AnholtGLuint brw_wm_is_scalar_result( GLuint opcode )
639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   switch (opcode) {
659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case OPCODE_COS:
669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case OPCODE_EX2:
679f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case OPCODE_LG2:
689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case OPCODE_POW:
699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case OPCODE_RCP:
709f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case OPCODE_RSQ:
719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case OPCODE_SIN:
729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case OPCODE_DP3:
739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case OPCODE_DP4:
749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case OPCODE_DPH:
759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   case OPCODE_DST:
769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      return 1;
779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   default:
799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      return 0;
809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
842f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul/**
852f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * Do GPU code generation for non-GLSL shader.  non-GLSL shaders have
862f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * no flow control instructions so we can more readily do SSA-style
872f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * optimizations.
882f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul */
892f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paulstatic void
902f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paulbrw_wm_non_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c)
912f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul{
922f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Augment fragment program.  Add instructions for pre- and
932f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * post-fragment-program tasks such as interpolation and fogging.
942f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    */
952f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   brw_wm_pass_fp(c);
962f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
972f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Translate to intermediate representation.  Build register usage
982f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * chains.
992f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    */
1002f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   brw_wm_pass0(c);
1012f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
1022f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Dead code removal.
1032f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    */
1042f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   brw_wm_pass1(c);
1052f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
1062f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Register allocation.
1075f1ce6b87e837b9f6bc2a4f3e81cf8feea4af2dfBrian Paul    * Divide by two because we operate on 16 pixels at a time and require
1085f1ce6b87e837b9f6bc2a4f3e81cf8feea4af2dfBrian Paul    * two GRF entries for each logical shader register.
1092f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    */
1102f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   c->grf_limit = BRW_WM_MAX_GRF / 2;
1112f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
1122f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   brw_wm_pass2(c);
1132f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
1145f1ce6b87e837b9f6bc2a4f3e81cf8feea4af2dfBrian Paul   /* how many general-purpose registers are used */
1152f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   c->prog_data.total_grf = c->max_wm_grf;
1165f1ce6b87e837b9f6bc2a4f3e81cf8feea4af2dfBrian Paul
1175f1ce6b87e837b9f6bc2a4f3e81cf8feea4af2dfBrian Paul   /* Scratch space is used for register spilling */
1182f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   if (c->last_scratch) {
1192f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul      c->prog_data.total_scratch = c->last_scratch + 0x40;
1202f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   }
1212f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   else {
1222f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul      c->prog_data.total_scratch = 0;
1232f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   }
1242f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
1252f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /* Emit GEN4 code.
1262f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    */
1272f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   brw_wm_emit(c);
1282f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul}
1292f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
1302f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
1312f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul/**
1322f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * All Mesa program -> GPU code generation goes through this function.
1332f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * Depending on the instructions used (i.e. flow control instructions)
1342f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul * we'll use one of two code generators.
1352f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul */
1369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void do_wm_prog( struct brw_context *brw,
1379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			struct brw_fragment_program *fp,
1389f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt			struct brw_wm_prog_key *key)
1399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
140d7b24fec245f90db4b8c66f4f7c167b8f20a9b9eEric Anholt   struct brw_wm_compile *c;
1419f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   const GLuint *program;
1429f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint program_size;
1439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
144d7b24fec245f90db4b8c66f4f7c167b8f20a9b9eEric Anholt   c = brw->wm.compile_data;
145d7b24fec245f90db4b8c66f4f7c167b8f20a9b9eEric Anholt   if (c == NULL) {
14614dc4937336061c4c8d51c75d96fa216d9edcf2aBrian Paul      brw->wm.compile_data = calloc(1, sizeof(*brw->wm.compile_data));
14714dc4937336061c4c8d51c75d96fa216d9edcf2aBrian Paul      c = brw->wm.compile_data;
14844a4abfd4f8695809eaec07df8eeb191d6e017d7Robert Ellison      if (c == NULL) {
14944a4abfd4f8695809eaec07df8eeb191d6e017d7Robert Ellison         /* Ouch - big out of memory problem.  Can't continue
15044a4abfd4f8695809eaec07df8eeb191d6e017d7Robert Ellison          * without triggering a segfault, no way to signal,
15144a4abfd4f8695809eaec07df8eeb191d6e017d7Robert Ellison          * so just return.
15244a4abfd4f8695809eaec07df8eeb191d6e017d7Robert Ellison          */
15344a4abfd4f8695809eaec07df8eeb191d6e017d7Robert Ellison         return;
15444a4abfd4f8695809eaec07df8eeb191d6e017d7Robert Ellison      }
155c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      c->instruction = _mesa_calloc(BRW_WM_MAX_INSN * sizeof(*c->instruction));
156c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      c->prog_instructions = _mesa_calloc(BRW_WM_MAX_INSN *
157c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt					  sizeof(*c->prog_instructions));
158c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      c->vreg = _mesa_calloc(BRW_WM_MAX_VREG * sizeof(*c->vreg));
159c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      c->refs = _mesa_calloc(BRW_WM_MAX_REF * sizeof(*c->refs));
160c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      c->vreg = _mesa_calloc(BRW_WM_MAX_VREG * sizeof(*c->vreg));
161d7b24fec245f90db4b8c66f4f7c167b8f20a9b9eEric Anholt   } else {
162c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      void *instruction = c->instruction;
163c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      void *prog_instructions = c->prog_instructions;
164c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      void *vreg = c->vreg;
165c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      void *refs = c->refs;
16614dc4937336061c4c8d51c75d96fa216d9edcf2aBrian Paul      memset(c, 0, sizeof(*brw->wm.compile_data));
167c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      c->instruction = instruction;
168c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      c->prog_instructions = prog_instructions;
169c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      c->vreg = vreg;
170c5413839b3e99c7b162f1260142f3c175502b0ceEric Anholt      c->refs = refs;
171d7b24fec245f90db4b8c66f4f7c167b8f20a9b9eEric Anholt   }
172d7b24fec245f90db4b8c66f4f7c167b8f20a9b9eEric Anholt   memcpy(&c->key, key, sizeof(*key));
1739f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
174d7b24fec245f90db4b8c66f4f7c167b8f20a9b9eEric Anholt   c->fp = fp;
175d7b24fec245f90db4b8c66f4f7c167b8f20a9b9eEric Anholt   c->env_param = brw->intel.ctx.FragmentProgram.Parameters;
1769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
17714dc4937336061c4c8d51c75d96fa216d9edcf2aBrian Paul   brw_init_compile(brw, &c->func);
17814dc4937336061c4c8d51c75d96fa216d9edcf2aBrian Paul
1795cbd1170da0a902fdc9c460584bc503b0c4085a6Brian Paul   /* temporary sanity check assertion */
1805cbd1170da0a902fdc9c460584bc503b0c4085a6Brian Paul   ASSERT(fp->isGLSL == brw_wm_is_glsl(&c->fp->program));
1815cbd1170da0a902fdc9c460584bc503b0c4085a6Brian Paul
1822f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul   /*
1832f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * Shader which use GLSL features such as flow control are handled
1842f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    * differently from "simple" shaders.
1852f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul    */
1865cbd1170da0a902fdc9c460584bc503b0c4085a6Brian Paul   if (fp->isGLSL) {
1870eb819a2d175cab139f8c672b6d44148b2c99a4eEric Anholt      c->dispatch_width = 8;
18814dc4937336061c4c8d51c75d96fa216d9edcf2aBrian Paul      brw_wm_glsl_emit(brw, c);
18914dc4937336061c4c8d51c75d96fa216d9edcf2aBrian Paul   }
19014dc4937336061c4c8d51c75d96fa216d9edcf2aBrian Paul   else {
1910eb819a2d175cab139f8c672b6d44148b2c99a4eEric Anholt      c->dispatch_width = 16;
1922f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul      brw_wm_non_glsl_emit(brw, c);
193d7b24fec245f90db4b8c66f4f7c167b8f20a9b9eEric Anholt   }
1942f78d4a2cd009d8d6a5f470d5738586b7f89f3d9Brian Paul
195fc3971d80051b34836716579fd060dbb122d036bEric Anholt   if (INTEL_DEBUG & DEBUG_WM)
196fc3971d80051b34836716579fd060dbb122d036bEric Anholt      fprintf(stderr, "\n");
197fc3971d80051b34836716579fd060dbb122d036bEric Anholt
1989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* get the program
1999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
200d7b24fec245f90db4b8c66f4f7c167b8f20a9b9eEric Anholt   program = brw_get_program(&c->func, &program_size);
2019f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
20238bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt   dri_bo_unreference(brw->wm.prog_bo);
20338bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt   brw->wm.prog_bo = brw_upload_cache( &brw->cache, BRW_WM_PROG,
20438bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt				       &c->key, sizeof(c->key),
20538bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt				       NULL, 0,
20638bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt				       program, program_size,
20738bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt				       &c->prog_data,
20838bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt				       &brw->wm.prog_data );
2099f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
2109f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2119f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtstatic void brw_wm_populate_key( struct brw_context *brw,
2149f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt				 struct brw_wm_prog_key *key )
2159f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
216052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt   GLcontext *ctx = &brw->intel.ctx;
2179f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* BRW_NEW_FRAGMENT_PROGRAM */
21855d33e1fa7d231a0cdfce9b9650ae9e136e6c63cBrian Paul   const struct brw_fragment_program *fp =
2199f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      (struct brw_fragment_program *)brw->fragment_program;
220f44916414ecd2b888c8a680d56b7467ccdff6886Eric Anholt   GLboolean uses_depth = (fp->program.Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) != 0;
2219f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint lookup = 0;
2229f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint line_aa;
2239f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   GLuint i;
2249f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2259f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   memset(key, 0, sizeof(*key));
2269f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2279f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Build the index for table lookup
2289f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
2299f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* _NEW_COLOR */
2309f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   if (fp->program.UsesKill ||
231052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt       ctx->Color.AlphaEnabled)
2329f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      lookup |= IZ_PS_KILL_ALPHATEST_BIT;
2339f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2348d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul   if (fp->program.Base.OutputsWritten & (1<<FRAG_RESULT_DEPTH))
2359f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
2369f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2379f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* _NEW_DEPTH */
238052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt   if (ctx->Depth.Test)
2399f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      lookup |= IZ_DEPTH_TEST_ENABLE_BIT;
2409f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
241052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt   if (ctx->Depth.Test &&
242052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt       ctx->Depth.Mask) /* ?? */
2439f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
2449f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2459f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* _NEW_STENCIL */
24691e61f435a71436c209934a0ece165b540aba3e0Brian Paul   if (ctx->Stencil._Enabled) {
2479f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
2489f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
249052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt      if (ctx->Stencil.WriteMask[0] ||
250052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt	  ctx->Stencil.WriteMask[ctx->Stencil._BackFace])
2519f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 lookup |= IZ_STENCIL_WRITE_ENABLE_BIT;
2529f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
2539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   line_aa = AA_NEVER;
2559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */
257052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt   if (ctx->Line.SmoothFlag) {
2589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (brw->intel.reduced_primitive == GL_LINES) {
2599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 line_aa = AA_ALWAYS;
2609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
2619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      else if (brw->intel.reduced_primitive == GL_TRIANGLES) {
262052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt	 if (ctx->Polygon.FrontMode == GL_LINE) {
2639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	    line_aa = AA_SOMETIMES;
2649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
265052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt	    if (ctx->Polygon.BackMode == GL_LINE ||
266052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt		(ctx->Polygon.CullFlag &&
267052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt		 ctx->Polygon.CullFaceMode == GL_BACK))
2689f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	       line_aa = AA_ALWAYS;
2699f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 }
270052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt	 else if (ctx->Polygon.BackMode == GL_LINE) {
2719f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	    line_aa = AA_SOMETIMES;
2729f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
273052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt	    if ((ctx->Polygon.CullFlag &&
274052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt		 ctx->Polygon.CullFaceMode == GL_FRONT))
2759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	       line_aa = AA_ALWAYS;
2769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt	 }
2779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
2789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
2799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   brw_wm_lookup_iz(line_aa,
2819f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		    lookup,
282f44916414ecd2b888c8a680d56b7467ccdff6886Eric Anholt		    uses_depth,
2839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		    key);
2849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2869f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* BRW_NEW_WM_INPUT_DIMENSIONS */
2876b917d0b1787280f976c2f0d1ead0e5d7587a3e9Brian Paul   key->proj_attrib_mask = brw->wm.input_size_masks[4-1];
2889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* _NEW_LIGHT */
290052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt   key->flat_shade = (ctx->Light.ShadeModel == GL_FLAT);
2919f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
29218af7c384cf663533f210d95d074c244d4214f29Brian Paul   /* _NEW_HINT */
29318af7c384cf663533f210d95d074c244d4214f29Brian Paul   key->linear_color = (ctx->Hint.PerspectiveCorrection == GL_FASTEST);
29418af7c384cf663533f210d95d074c244d4214f29Brian Paul
2959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* _NEW_TEXTURE */
2969f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
297052c1d66a1ab1f2665870dc77dab28d20416cdf1Eric Anholt      const struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
2989f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
2999f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      if (unit->_ReallyEnabled) {
30089fddf978c9d2ab5042f89110015234e979c2686Brian Paul         const struct gl_texture_object *t = unit->_Current;
30189fddf978c9d2ab5042f89110015234e979c2686Brian Paul         const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
30289fddf978c9d2ab5042f89110015234e979c2686Brian Paul	 if (img->InternalFormat == GL_YCBCR_MESA) {
30389fddf978c9d2ab5042f89110015234e979c2686Brian Paul	    key->yuvtex_mask |= 1 << i;
3041f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul	    if (img->TexFormat == MESA_FORMAT_YCBCR)
30589fddf978c9d2ab5042f89110015234e979c2686Brian Paul		key->yuvtex_swap_mask |= 1 << i;
3067676980d38cff417015bca8d23549d567d74228bZou Nan hai	 }
307c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul
308c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul         key->tex_swizzles[i] = t->_Swizzle;
309c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul      }
310c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul      else {
311c0d3b7679aa90e1a0dca2db152205efaec088b90Brian Paul         key->tex_swizzles[i] = SWIZZLE_NOOP;
3129f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      }
3139f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   }
3149c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt
315b17b110716936c32d20910cb9589038062b4f527Xiang, Haihao   /* Shadow */
316b17b110716936c32d20910cb9589038062b4f527Xiang, Haihao   key->shadowtex_mask = fp->program.Base.ShadowSamplers;
317b17b110716936c32d20910cb9589038062b4f527Xiang, Haihao
3189c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt   /* _NEW_BUFFERS */
3199c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt   /*
3209c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    * Include the draw buffer origin and height so that we can calculate
3219c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    * fragment position values relative to the bottom left of the drawable,
3229c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    * from the incoming screen origin relative position we get as part of our
3239c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    * payload.
3249c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    *
325861fec163c1ae7e431956db0a08989d841e2b74eBrian Paul    * This is only needed for the WM_WPOSXY opcode when the fragment program
326861fec163c1ae7e431956db0a08989d841e2b74eBrian Paul    * uses the gl_FragCoord input.
327861fec163c1ae7e431956db0a08989d841e2b74eBrian Paul    *
3289c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    * We could avoid recompiling by including this as a constant referenced by
3299c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    * our program, but if we were to do that it would also be nice to handle
3309c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    * getting that constant updated at batchbuffer submit time (when we
3319c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    * hold the lock and know where the buffer really is) rather than at emit
3329c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    * time when we don't hold the lock and are just guessing.  We could also
3339c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    * just avoid using this as key data if the program doesn't use
3349c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    * fragment.position.
3359c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    *
336861fec163c1ae7e431956db0a08989d841e2b74eBrian Paul    * For DRI2 the origin_x/y will always be (0,0) but we still need the
337861fec163c1ae7e431956db0a08989d841e2b74eBrian Paul    * drawable height in order to invert the Y axis.
3389c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt    */
339861fec163c1ae7e431956db0a08989d841e2b74eBrian Paul   if (fp->program.Base.InputsRead & FRAG_BIT_WPOS) {
340861fec163c1ae7e431956db0a08989d841e2b74eBrian Paul      if (brw->intel.driDrawable != NULL) {
341861fec163c1ae7e431956db0a08989d841e2b74eBrian Paul         key->origin_x = brw->intel.driDrawable->x;
342861fec163c1ae7e431956db0a08989d841e2b74eBrian Paul         key->origin_y = brw->intel.driDrawable->y;
343861fec163c1ae7e431956db0a08989d841e2b74eBrian Paul         key->drawable_height = brw->intel.driDrawable->h;
344861fec163c1ae7e431956db0a08989d841e2b74eBrian Paul      }
3459c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt   }
3469f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3479ef33b86855c4d000271774030bd1b19b6d79687Brian Paul   key->nr_color_regions = brw->state.nr_color_regions;
3489ef33b86855c4d000271774030bd1b19b6d79687Brian Paul
3490f5113deed91611ecdda6596542530b1849bb161Eric Anholt   /* CACHE_NEW_VS_PROG */
3500f5113deed91611ecdda6596542530b1849bb161Eric Anholt   key->vp_outputs_written = brw->vs.prog_data->outputs_written & DO_SETUP_BITS;
3510f5113deed91611ecdda6596542530b1849bb161Eric Anholt
35255d33e1fa7d231a0cdfce9b9650ae9e136e6c63cBrian Paul   /* The unique fragment program ID */
3539f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   key->program_string_id = fp->id;
3549f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3559f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3569f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
357f75843a517bd188639e6866db2a7b04de3524e16Dave Airliestatic void brw_prepare_wm_prog(struct brw_context *brw)
3589f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt{
3599f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct brw_wm_prog_key key;
3609f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   struct brw_fragment_program *fp = (struct brw_fragment_program *)
3619f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      brw->fragment_program;
362125bd4cae51c6deaacd2e90f14931c2052f146abEric Anholt
3639f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   brw_wm_populate_key(brw, &key);
3649f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3659f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   /* Make an early check for the key.
3669f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt    */
36738bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt   dri_bo_unreference(brw->wm.prog_bo);
36838bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt   brw->wm.prog_bo = brw_search_cache(&brw->cache, BRW_WM_PROG,
36938bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt				      &key, sizeof(key),
37038bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt				      NULL, 0,
37138bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt				      &brw->wm.prog_data);
37238bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt   if (brw->wm.prog_bo == NULL)
37338bad7677e57d629eeffd4ef39a7fc254db12735Eric Anholt      do_wm_prog(brw, fp, &key);
3749f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt}
3759f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3769f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
3779f344b3e7d6e23674dd4747faec253f103563b36Eric Anholtconst struct brw_tracked_state brw_wm_prog = {
3789f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   .dirty = {
3799f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      .mesa  = (_NEW_COLOR |
3809f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		_NEW_DEPTH |
38118af7c384cf663533f210d95d074c244d4214f29Brian Paul                _NEW_HINT |
3829f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		_NEW_STENCIL |
3839f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		_NEW_POLYGON |
3849f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		_NEW_LINE |
3859f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		_NEW_LIGHT |
3869c8f27ba1366da07e20e86a0d48341ea97f5cda4Eric Anholt		_NEW_BUFFERS |
3879f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		_NEW_TEXTURE),
3889f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt      .brw   = (BRW_NEW_FRAGMENT_PROGRAM |
3899f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		BRW_NEW_WM_INPUT_DIMENSIONS |
3909f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt		BRW_NEW_REDUCED_PRIMITIVE),
3910f5113deed91611ecdda6596542530b1849bb161Eric Anholt      .cache = CACHE_NEW_VS_PROG,
3929f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt   },
393008653ac55776d6b1c6d1627ad20937aa1c4dbdaDave Airlie   .prepare = brw_prepare_wm_prog
3949f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt};
3959f344b3e7d6e23674dd4747faec253f103563b36Eric Anholt
396