gallium: fix some compiler warnings
[mesa.git] / src / gallium / drivers / softpipe / sp_state_derived.c
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 #include "pipe/p_util.h"
29 #include "pipe/p_shader_tokens.h"
30 #include "draw/draw_context.h"
31 #include "draw/draw_vertex.h"
32 #include "draw/draw_private.h"
33 #include "sp_context.h"
34 #include "sp_state.h"
35
36
37 /**
38 * Mark the current vertex layout as "invalid".
39 * We'll validate the vertex layout later, when we start to actually
40 * render a point or line or tri.
41 */
42 static void
43 invalidate_vertex_layout(struct softpipe_context *softpipe)
44 {
45 softpipe->vertex_info.num_attribs = 0;
46 }
47
48
49 /**
50 * The vertex info describes how to convert the post-transformed vertices
51 * (simple float[][4]) used by the 'draw' module into vertices for
52 * rasterization.
53 *
54 * This function validates the vertex layout and returns a pointer to a
55 * vertex_info object.
56 */
57 struct vertex_info *
58 softpipe_get_vertex_info(struct softpipe_context *softpipe)
59 {
60 struct vertex_info *vinfo = &softpipe->vertex_info;
61
62 if (vinfo->num_attribs == 0) {
63 /* compute vertex layout now */
64 const struct sp_fragment_shader *spfs = softpipe->fs;
65 const enum interp_mode colorInterp
66 = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
67 uint i;
68
69 if (softpipe->vbuf) {
70 /* if using the post-transform vertex buffer, tell draw_vbuf to
71 * simply emit the whole post-xform vertex as-is:
72 */
73 struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
74 #if 0
75 vinfo_vbuf->num_attribs = 0;
76 /* special-case to allow memcpy of whole vertex */
77 draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0);
78 /* size in dwords or floats */
79 vinfo_vbuf->size = 4 * draw_num_vs_outputs(softpipe->draw)
80 + sizeof(struct vertex_header) / 4;
81 #else
82 /* for pass-through mode, we need a more explicit list of attribs */
83 const uint num = draw_num_vs_outputs(softpipe->draw);
84 uint i;
85
86 vinfo_vbuf->num_attribs = 0;
87 draw_emit_vertex_attr(vinfo_vbuf, EMIT_HEADER, INTERP_NONE, 0);
88 for (i = 0; i < num; i++) {
89 draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i);
90 }
91 draw_compute_vertex_size(vinfo_vbuf);
92 #endif
93 }
94
95 /*
96 * Loop over fragment shader inputs, searching for the matching output
97 * from the vertex shader.
98 */
99 vinfo->num_attribs = 0;
100 for (i = 0; i < spfs->info.num_inputs; i++) {
101 int src;
102 switch (spfs->info.input_semantic_name[i]) {
103 case TGSI_SEMANTIC_POSITION:
104 src = draw_find_vs_output(softpipe->draw,
105 TGSI_SEMANTIC_POSITION, 0);
106 draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
107 break;
108
109 case TGSI_SEMANTIC_COLOR:
110 src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_COLOR,
111 spfs->info.input_semantic_index[i]);
112 draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
113 break;
114
115 case TGSI_SEMANTIC_FOG:
116 src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_FOG, 0);
117 draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
118 break;
119
120 case TGSI_SEMANTIC_GENERIC:
121 /* this includes texcoords and varying vars */
122 src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_GENERIC,
123 spfs->info.input_semantic_index[i]);
124 draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
125 break;
126
127 default:
128 assert(0);
129 }
130 }
131
132 softpipe->psize_slot = draw_find_vs_output(softpipe->draw,
133 TGSI_SEMANTIC_PSIZE, 0);
134 if (softpipe->psize_slot > 0) {
135 draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
136 softpipe->psize_slot);
137 }
138
139 draw_compute_vertex_size(vinfo);
140 }
141
142 return vinfo;
143 }
144
145
146 /**
147 * Called from vbuf module.
148 *
149 * Note that there's actually two different vertex layouts in softpipe.
150 *
151 * The normal one is computed in softpipe_get_vertex_info() above and is
152 * used by the point/line/tri "setup" code.
153 *
154 * The other one (this one) is only used by the vbuf module (which is
155 * not normally used by default but used in testing). For the vbuf module,
156 * we basically want to pass-through the draw module's vertex layout as-is.
157 * When the softpipe vbuf code begins drawing, the normal vertex layout
158 * will come into play again.
159 */
160 struct vertex_info *
161 softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe)
162 {
163 (void) softpipe_get_vertex_info(softpipe);
164 return &softpipe->vertex_info_vbuf;
165 }
166
167
168 /**
169 * Recompute cliprect from scissor bounds, scissor enable and surface size.
170 */
171 static void
172 compute_cliprect(struct softpipe_context *sp)
173 {
174 unsigned surfWidth, surfHeight;
175
176 if (sp->framebuffer.num_cbufs > 0) {
177 surfWidth = sp->framebuffer.cbufs[0]->width;
178 surfHeight = sp->framebuffer.cbufs[0]->height;
179 }
180 else {
181 /* no surface? */
182 surfWidth = sp->scissor.maxx;
183 surfHeight = sp->scissor.maxy;
184 }
185
186 if (sp->rasterizer->scissor) {
187 /* clip to scissor rect */
188 sp->cliprect.minx = MAX2(sp->scissor.minx, 0);
189 sp->cliprect.miny = MAX2(sp->scissor.miny, 0);
190 sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth);
191 sp->cliprect.maxy = MIN2(sp->scissor.maxy, surfHeight);
192 }
193 else {
194 /* clip to surface bounds */
195 sp->cliprect.minx = 0;
196 sp->cliprect.miny = 0;
197 sp->cliprect.maxx = surfWidth;
198 sp->cliprect.maxy = surfHeight;
199 }
200 }
201
202
203 /* Hopefully this will remain quite simple, otherwise need to pull in
204 * something like the state tracker mechanism.
205 */
206 void softpipe_update_derived( struct softpipe_context *softpipe )
207 {
208 if (softpipe->dirty & (SP_NEW_RASTERIZER |
209 SP_NEW_FS |
210 SP_NEW_VS))
211 invalidate_vertex_layout( softpipe );
212
213 if (softpipe->dirty & (SP_NEW_SCISSOR |
214 SP_NEW_DEPTH_STENCIL_ALPHA |
215 SP_NEW_FRAMEBUFFER))
216 compute_cliprect(softpipe);
217
218 if (softpipe->dirty & (SP_NEW_BLEND |
219 SP_NEW_DEPTH_STENCIL_ALPHA |
220 SP_NEW_FRAMEBUFFER |
221 SP_NEW_RASTERIZER |
222 SP_NEW_FS |
223 SP_NEW_QUERY))
224 sp_build_quad_pipeline(softpipe);
225
226 softpipe->dirty = 0;
227 }