i915_state_derived.c revision d2f05283d2226f3285dccfc373ee9e314a8c95c8
1/**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * 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, sub license, 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 portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29#include "util/u_memory.h"
30#include "pipe/p_shader_tokens.h"
31#include "draw/draw_context.h"
32#include "draw/draw_vertex.h"
33#include "i915_context.h"
34#include "i915_state.h"
35#include "i915_debug.h"
36#include "i915_fpc.h"
37#include "i915_reg.h"
38
39static uint find_mapping(const struct i915_fragment_shader* fs, int unit)
40{
41   int i;
42   for (i = 0; i < I915_TEX_UNITS ; i++)
43   {
44      if (fs->generic_mapping[i] == unit)
45         return i;
46   }
47   debug_printf("Mapping not found\n");
48   return 0;
49}
50
51
52
53/***********************************************************************
54 * Determine the hardware vertex layout.
55 * Depends on vertex/fragment shader state.
56 */
57static void calculate_vertex_layout(struct i915_context *i915)
58{
59   const struct i915_fragment_shader *fs = i915->fs;
60   const enum interp_mode colorInterp = i915->rasterizer->color_interp;
61   struct vertex_info vinfo;
62   boolean texCoords[I915_TEX_UNITS], colors[2], fog, needW;
63   uint i;
64   int src;
65
66   memset(texCoords, 0, sizeof(texCoords));
67   colors[0] = colors[1] = fog = needW = FALSE;
68   memset(&vinfo, 0, sizeof(vinfo));
69
70   /* Determine which fragment program inputs are needed.  Setup HW vertex
71    * layout below, in the HW-specific attribute order.
72    */
73   for (i = 0; i < fs->info.num_inputs; i++) {
74      switch (fs->info.input_semantic_name[i]) {
75      case TGSI_SEMANTIC_POSITION:
76         {
77            uint unit = I915_SEMANTIC_POS;
78            texCoords[find_mapping(fs, unit)] = TRUE;
79         }
80         break;
81      case TGSI_SEMANTIC_COLOR:
82         assert(fs->info.input_semantic_index[i] < 2);
83         colors[fs->info.input_semantic_index[i]] = TRUE;
84         break;
85      case TGSI_SEMANTIC_GENERIC:
86         {
87            /* texcoords/varyings/other generic */
88            /* XXX handle back/front face and point size */
89            uint unit = fs->info.input_semantic_index[i];
90
91            texCoords[find_mapping(fs, unit)] = TRUE;
92            needW = TRUE;
93         }
94         break;
95      case TGSI_SEMANTIC_FOG:
96         fog = TRUE;
97         break;
98      default:
99         assert(0);
100      }
101   }
102
103
104   /* pos */
105   src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);
106   if (needW) {
107      draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src);
108      vinfo.hwfmt[0] |= S4_VFMT_XYZW;
109      vinfo.attrib[0].emit = EMIT_4F;
110   }
111   else {
112      draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src);
113      vinfo.hwfmt[0] |= S4_VFMT_XYZ;
114      vinfo.attrib[0].emit = EMIT_3F;
115   }
116
117   /* hardware point size */
118   /* XXX todo */
119
120   /* primary color */
121   if (colors[0]) {
122      src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
123      draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src);
124      vinfo.hwfmt[0] |= S4_VFMT_COLOR;
125   }
126
127   /* secondary color */
128   if (colors[1]) {
129      src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
130      draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src);
131      vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
132   }
133
134   /* fog coord, not fog blend factor */
135   if (fog) {
136      src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FOG, 0);
137      draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
138      vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM;
139   }
140
141   /* texcoords/varyings */
142   for (i = 0; i < I915_TEX_UNITS; i++) {
143      uint hwtc;
144      if (texCoords[i]) {
145         hwtc = TEXCOORDFMT_4D;
146         src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_GENERIC, fs->generic_mapping[i]);
147         draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
148      }
149      else {
150         hwtc = TEXCOORDFMT_NOT_PRESENT;
151      }
152      vinfo.hwfmt[1] |= hwtc << (i * 4);
153   }
154
155   draw_compute_vertex_size(&vinfo);
156
157   if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) {
158      /* Need to set this flag so that the LIS2/4 registers get set.
159       * It also means the i915_update_immediate() function must be called
160       * after this one, in i915_update_derived().
161       */
162      i915->dirty |= I915_NEW_VERTEX_FORMAT;
163
164      memcpy(&i915->current.vertex_info, &vinfo, sizeof(vinfo));
165   }
166}
167
168struct i915_tracked_state i915_update_vertex_layout = {
169   "vertex_layout",
170   calculate_vertex_layout,
171   I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS
172};
173
174
175
176/***********************************************************************
177 */
178static struct i915_tracked_state *atoms[] = {
179   &i915_update_vertex_layout,
180   &i915_hw_samplers,
181   &i915_hw_sampler_views,
182   &i915_hw_immediate,
183   &i915_hw_dynamic,
184   &i915_hw_fs,
185   &i915_hw_framebuffer,
186   &i915_hw_dst_buf_vars,
187   &i915_hw_constants,
188   NULL,
189};
190
191void i915_update_derived(struct i915_context *i915)
192{
193   int i;
194
195   if (I915_DBG_ON(DBG_ATOMS))
196      i915_dump_dirty(i915, __FUNCTION__);
197
198   for (i = 0; atoms[i]; i++)
199      if (atoms[i]->dirty & i915->dirty)
200         atoms[i]->update(i915);
201
202   i915->dirty = 0;
203}
204