Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /********************************************************** |
2 | * Copyright 2008-2009 VMware, Inc. All rights reserved. |
||
3 | * |
||
4 | * Permission is hereby granted, free of charge, to any person |
||
5 | * obtaining a copy of this software and associated documentation |
||
6 | * files (the "Software"), to deal in the Software without |
||
7 | * restriction, including without limitation the rights to use, copy, |
||
8 | * modify, merge, publish, distribute, sublicense, and/or sell copies |
||
9 | * of the Software, and to permit persons to whom the Software is |
||
10 | * furnished to do so, subject to the following conditions: |
||
11 | * |
||
12 | * The above copyright notice and this permission notice shall be |
||
13 | * included in all copies or substantial portions of the Software. |
||
14 | * |
||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
||
19 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
||
20 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
||
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||
22 | * SOFTWARE. |
||
23 | * |
||
24 | **********************************************************/ |
||
25 | |||
26 | #include "draw/draw_context.h" |
||
27 | #include "util/u_inlines.h" |
||
28 | #include "pipe/p_defines.h" |
||
29 | #include "util/u_math.h" |
||
30 | #include "util/u_memory.h" |
||
31 | |||
32 | #include "svga_context.h" |
||
33 | |||
34 | #include "svga_hw_reg.h" |
||
35 | |||
36 | /* Hardware frontwinding is always set up as SVGA3D_FRONTWINDING_CW. |
||
37 | */ |
||
38 | static SVGA3dFace svga_translate_cullmode( unsigned mode, |
||
39 | unsigned front_ccw ) |
||
40 | { |
||
41 | const int hw_front_ccw = 0; /* hardware is always CW */ |
||
42 | switch (mode) { |
||
43 | case PIPE_FACE_NONE: |
||
44 | return SVGA3D_FACE_NONE; |
||
45 | case PIPE_FACE_FRONT: |
||
46 | return front_ccw == hw_front_ccw ? SVGA3D_FACE_FRONT : SVGA3D_FACE_BACK; |
||
47 | case PIPE_FACE_BACK: |
||
48 | return front_ccw == hw_front_ccw ? SVGA3D_FACE_BACK : SVGA3D_FACE_FRONT; |
||
49 | case PIPE_FACE_FRONT_AND_BACK: |
||
50 | return SVGA3D_FACE_FRONT_BACK; |
||
51 | default: |
||
52 | assert(0); |
||
53 | return SVGA3D_FACE_NONE; |
||
54 | } |
||
55 | } |
||
56 | |||
57 | static SVGA3dShadeMode svga_translate_flatshade( unsigned mode ) |
||
58 | { |
||
59 | return mode ? SVGA3D_SHADEMODE_FLAT : SVGA3D_SHADEMODE_SMOOTH; |
||
60 | } |
||
61 | |||
62 | |||
63 | static void * |
||
64 | svga_create_rasterizer_state(struct pipe_context *pipe, |
||
65 | const struct pipe_rasterizer_state *templ) |
||
66 | { |
||
67 | struct svga_context *svga = svga_context(pipe); |
||
68 | struct svga_rasterizer_state *rast = CALLOC_STRUCT( svga_rasterizer_state ); |
||
69 | |||
70 | /* need this for draw module. */ |
||
71 | rast->templ = *templ; |
||
72 | |||
73 | /* light_twoside - XXX: need fragment shader variant */ |
||
74 | /* poly_smooth - XXX: no fallback available */ |
||
75 | /* poly_stipple_enable - draw module */ |
||
76 | /* sprite_coord_enable - ? */ |
||
77 | /* point_quad_rasterization - ? */ |
||
78 | /* point_size_per_vertex - ? */ |
||
79 | /* sprite_coord_mode - ??? */ |
||
80 | /* flatshade_first - handled by index translation */ |
||
81 | /* half_pixel_center - XXX - viewport code */ |
||
82 | /* line_width - draw module */ |
||
83 | /* fill_cw, fill_ccw - draw module or index translation */ |
||
84 | |||
85 | rast->shademode = svga_translate_flatshade( templ->flatshade ); |
||
86 | rast->cullmode = svga_translate_cullmode( templ->cull_face, |
||
87 | templ->front_ccw ); |
||
88 | rast->scissortestenable = templ->scissor; |
||
89 | rast->multisampleantialias = templ->multisample; |
||
90 | rast->antialiasedlineenable = templ->line_smooth; |
||
91 | rast->lastpixel = templ->line_last_pixel; |
||
92 | rast->pointsprite = templ->sprite_coord_enable != 0x0; |
||
93 | rast->pointsize = templ->point_size; |
||
94 | rast->hw_unfilled = PIPE_POLYGON_MODE_FILL; |
||
95 | |||
96 | /* Use swtnl + decomposition implement these: |
||
97 | */ |
||
98 | if (templ->poly_stipple_enable) { |
||
99 | rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; |
||
100 | rast->need_pipeline_tris_str = "poly stipple"; |
||
101 | } |
||
102 | |||
103 | if (templ->line_width >= 1.5f && |
||
104 | !svga->debug.no_line_width) { |
||
105 | rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES; |
||
106 | rast->need_pipeline_lines_str = "line width"; |
||
107 | } |
||
108 | |||
109 | if (templ->line_stipple_enable) { |
||
110 | /* XXX: LinePattern not implemented on all backends, and there is no |
||
111 | * mechanism to query it. |
||
112 | */ |
||
113 | if (!svga->debug.force_hw_line_stipple) { |
||
114 | SVGA3dLinePattern lp; |
||
115 | lp.repeat = templ->line_stipple_factor + 1; |
||
116 | lp.pattern = templ->line_stipple_pattern; |
||
117 | rast->linepattern = lp.uintValue; |
||
118 | } |
||
119 | else { |
||
120 | rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES; |
||
121 | rast->need_pipeline_lines_str = "line stipple"; |
||
122 | } |
||
123 | } |
||
124 | |||
125 | if (templ->point_smooth) { |
||
126 | rast->need_pipeline |= SVGA_PIPELINE_FLAG_POINTS; |
||
127 | rast->need_pipeline_points_str = "smooth points"; |
||
128 | } |
||
129 | |||
130 | if (templ->line_smooth) { |
||
131 | rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES; |
||
132 | rast->need_pipeline_lines_str = "smooth lines"; |
||
133 | } |
||
134 | |||
135 | { |
||
136 | int fill_front = templ->fill_front; |
||
137 | int fill_back = templ->fill_back; |
||
138 | int fill = PIPE_POLYGON_MODE_FILL; |
||
139 | boolean offset_front = util_get_offset(templ, fill_front); |
||
140 | boolean offset_back = util_get_offset(templ, fill_back); |
||
141 | boolean offset = 0; |
||
142 | |||
143 | switch (templ->cull_face) { |
||
144 | case PIPE_FACE_FRONT_AND_BACK: |
||
145 | offset = 0; |
||
146 | fill = PIPE_POLYGON_MODE_FILL; |
||
147 | break; |
||
148 | |||
149 | case PIPE_FACE_FRONT: |
||
150 | offset = offset_front; |
||
151 | fill = fill_front; |
||
152 | break; |
||
153 | |||
154 | case PIPE_FACE_BACK: |
||
155 | offset = offset_back; |
||
156 | fill = fill_back; |
||
157 | break; |
||
158 | |||
159 | case PIPE_FACE_NONE: |
||
160 | if (fill_front != fill_back || offset_front != offset_back) |
||
161 | { |
||
162 | /* Always need the draw module to work out different |
||
163 | * front/back fill modes: |
||
164 | */ |
||
165 | rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; |
||
166 | rast->need_pipeline_tris_str = "different front/back fillmodes"; |
||
167 | } |
||
168 | else { |
||
169 | offset = offset_front; |
||
170 | fill = fill_front; |
||
171 | } |
||
172 | break; |
||
173 | |||
174 | default: |
||
175 | assert(0); |
||
176 | break; |
||
177 | } |
||
178 | |||
179 | /* Unfilled primitive modes aren't implemented on all virtual |
||
180 | * hardware. We can do some unfilled processing with index |
||
181 | * translation, but otherwise need the draw module: |
||
182 | */ |
||
183 | if (fill != PIPE_POLYGON_MODE_FILL && |
||
184 | (templ->flatshade || |
||
185 | templ->light_twoside || |
||
186 | offset || |
||
187 | templ->cull_face != PIPE_FACE_NONE)) |
||
188 | { |
||
189 | fill = PIPE_POLYGON_MODE_FILL; |
||
190 | rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; |
||
191 | rast->need_pipeline_tris_str = "unfilled primitives with no index manipulation"; |
||
192 | } |
||
193 | |||
194 | /* If we are decomposing to lines, and lines need the pipeline, |
||
195 | * then we also need the pipeline for tris. |
||
196 | */ |
||
197 | if (fill == PIPE_POLYGON_MODE_LINE && |
||
198 | (rast->need_pipeline & SVGA_PIPELINE_FLAG_LINES)) |
||
199 | { |
||
200 | fill = PIPE_POLYGON_MODE_FILL; |
||
201 | rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; |
||
202 | rast->need_pipeline_tris_str = "decomposing lines"; |
||
203 | } |
||
204 | |||
205 | /* Similarly for points: |
||
206 | */ |
||
207 | if (fill == PIPE_POLYGON_MODE_POINT && |
||
208 | (rast->need_pipeline & SVGA_PIPELINE_FLAG_POINTS)) |
||
209 | { |
||
210 | fill = PIPE_POLYGON_MODE_FILL; |
||
211 | rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; |
||
212 | rast->need_pipeline_tris_str = "decomposing points"; |
||
213 | } |
||
214 | |||
215 | if (offset) { |
||
216 | rast->slopescaledepthbias = templ->offset_scale; |
||
217 | rast->depthbias = templ->offset_units; |
||
218 | } |
||
219 | |||
220 | rast->hw_unfilled = fill; |
||
221 | } |
||
222 | |||
223 | if (rast->need_pipeline & SVGA_PIPELINE_FLAG_TRIS) { |
||
224 | /* Turn off stuff which will get done in the draw module: |
||
225 | */ |
||
226 | rast->hw_unfilled = PIPE_POLYGON_MODE_FILL; |
||
227 | rast->slopescaledepthbias = 0; |
||
228 | rast->depthbias = 0; |
||
229 | } |
||
230 | |||
231 | return rast; |
||
232 | } |
||
233 | |||
234 | static void svga_bind_rasterizer_state( struct pipe_context *pipe, |
||
235 | void *state ) |
||
236 | { |
||
237 | struct svga_context *svga = svga_context(pipe); |
||
238 | struct svga_rasterizer_state *raster = (struct svga_rasterizer_state *)state; |
||
239 | |||
240 | |||
241 | draw_set_rasterizer_state(svga->swtnl.draw, raster ? &raster->templ : NULL, |
||
242 | state); |
||
243 | svga->curr.rast = raster; |
||
244 | |||
245 | svga->dirty |= SVGA_NEW_RAST; |
||
246 | } |
||
247 | |||
248 | static void svga_delete_rasterizer_state(struct pipe_context *pipe, |
||
249 | void *raster) |
||
250 | { |
||
251 | FREE(raster); |
||
252 | } |
||
253 | |||
254 | |||
255 | void svga_init_rasterizer_functions( struct svga_context *svga ) |
||
256 | { |
||
257 | svga->pipe.create_rasterizer_state = svga_create_rasterizer_state; |
||
258 | svga->pipe.bind_rasterizer_state = svga_bind_rasterizer_state; |
||
259 | svga->pipe.delete_rasterizer_state = svga_delete_rasterizer_state; |
||
260 | } |
||
261 | |||
262 | |||
263 | /*********************************************************************** |
||
264 | * Hardware state update |
||
265 | */ |
||
266 |