1 /**********************************************************
2 * Copyright 2008-2009 VMware, Inc. All rights reserved.
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:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
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
24 **********************************************************/
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"
32 #include "svga_context.h"
33 #include "svga_screen.h"
35 #include "svga_hw_reg.h"
37 /* Hardware frontwinding is always set up as SVGA3D_FRONTWINDING_CW.
39 static SVGA3dFace
svga_translate_cullmode( unsigned mode
,
42 const int hw_front_ccw
= 0; /* hardware is always CW */
45 return SVGA3D_FACE_NONE
;
47 return front_ccw
== hw_front_ccw
? SVGA3D_FACE_FRONT
: SVGA3D_FACE_BACK
;
49 return front_ccw
== hw_front_ccw
? SVGA3D_FACE_BACK
: SVGA3D_FACE_FRONT
;
50 case PIPE_FACE_FRONT_AND_BACK
:
51 return SVGA3D_FACE_FRONT_BACK
;
54 return SVGA3D_FACE_NONE
;
58 static SVGA3dShadeMode
svga_translate_flatshade( unsigned mode
)
60 return mode
? SVGA3D_SHADEMODE_FLAT
: SVGA3D_SHADEMODE_SMOOTH
;
65 svga_create_rasterizer_state(struct pipe_context
*pipe
,
66 const struct pipe_rasterizer_state
*templ
)
68 struct svga_context
*svga
= svga_context(pipe
);
69 struct svga_rasterizer_state
*rast
= CALLOC_STRUCT( svga_rasterizer_state
);
70 struct svga_screen
*screen
= svga_screen(pipe
->screen
);
72 /* need this for draw module. */
75 /* light_twoside - XXX: need fragment shader variant */
76 /* poly_smooth - XXX: no fallback available */
77 /* poly_stipple_enable - draw module */
78 /* sprite_coord_enable - ? */
79 /* point_quad_rasterization - ? */
80 /* point_size_per_vertex - ? */
81 /* sprite_coord_mode - ??? */
82 /* flatshade_first - handled by index translation */
83 /* half_pixel_center - XXX - viewport code */
84 /* line_width - draw module */
85 /* fill_cw, fill_ccw - draw module or index translation */
87 rast
->shademode
= svga_translate_flatshade( templ
->flatshade
);
88 rast
->cullmode
= svga_translate_cullmode( templ
->cull_face
,
90 rast
->scissortestenable
= templ
->scissor
;
91 rast
->multisampleantialias
= templ
->multisample
;
92 rast
->antialiasedlineenable
= templ
->line_smooth
;
93 rast
->lastpixel
= templ
->line_last_pixel
;
94 rast
->pointsprite
= templ
->sprite_coord_enable
!= 0x0;
95 rast
->pointsize
= templ
->point_size
;
96 rast
->hw_unfilled
= PIPE_POLYGON_MODE_FILL
;
98 /* Use swtnl + decomposition implement these:
100 if (templ
->poly_stipple_enable
) {
101 rast
->need_pipeline
|= SVGA_PIPELINE_FLAG_TRIS
;
102 rast
->need_pipeline_tris_str
= "poly stipple";
105 if (screen
->maxLineWidth
> 1.0F
) {
106 /* pass line width to device */
107 rast
->linewidth
= MAX2(1.0F
, templ
->line_width
);
109 else if (svga
->debug
.no_line_width
) {
113 /* use 'draw' pipeline for wide line */
114 rast
->need_pipeline
|= SVGA_PIPELINE_FLAG_LINES
;
115 rast
->need_pipeline_lines_str
= "line width";
118 if (templ
->line_stipple_enable
) {
119 if (screen
->haveLineStipple
|| svga
->debug
.force_hw_line_stipple
) {
120 SVGA3dLinePattern lp
;
121 lp
.repeat
= templ
->line_stipple_factor
+ 1;
122 lp
.pattern
= templ
->line_stipple_pattern
;
123 rast
->linepattern
= lp
.uintValue
;
126 /* use 'draw' module to decompose into short line segments */
127 rast
->need_pipeline
|= SVGA_PIPELINE_FLAG_LINES
;
128 rast
->need_pipeline_lines_str
= "line stipple";
132 if (templ
->point_smooth
) {
133 rast
->need_pipeline
|= SVGA_PIPELINE_FLAG_POINTS
;
134 rast
->need_pipeline_points_str
= "smooth points";
137 if (templ
->line_smooth
&& !screen
->haveLineSmooth
) {
139 * XXX: Enabling the pipeline slows down performance immensely, so ignore
140 * line smooth state, where there is very little visual improvement.
141 * Smooth lines will still be drawn for wide lines.
144 rast
->need_pipeline
|= SVGA_PIPELINE_FLAG_LINES
;
145 rast
->need_pipeline_lines_str
= "smooth lines";
150 int fill_front
= templ
->fill_front
;
151 int fill_back
= templ
->fill_back
;
152 int fill
= PIPE_POLYGON_MODE_FILL
;
153 boolean offset_front
= util_get_offset(templ
, fill_front
);
154 boolean offset_back
= util_get_offset(templ
, fill_back
);
155 boolean offset
= FALSE
;
157 switch (templ
->cull_face
) {
158 case PIPE_FACE_FRONT_AND_BACK
:
160 fill
= PIPE_POLYGON_MODE_FILL
;
163 case PIPE_FACE_FRONT
:
164 offset
= offset_front
;
169 offset
= offset_back
;
174 if (fill_front
!= fill_back
|| offset_front
!= offset_back
)
176 /* Always need the draw module to work out different
177 * front/back fill modes:
179 rast
->need_pipeline
|= SVGA_PIPELINE_FLAG_TRIS
;
180 rast
->need_pipeline_tris_str
= "different front/back fillmodes";
183 offset
= offset_front
;
193 /* Unfilled primitive modes aren't implemented on all virtual
194 * hardware. We can do some unfilled processing with index
195 * translation, but otherwise need the draw module:
197 if (fill
!= PIPE_POLYGON_MODE_FILL
&&
199 templ
->light_twoside
||
201 templ
->cull_face
!= PIPE_FACE_NONE
))
203 fill
= PIPE_POLYGON_MODE_FILL
;
204 rast
->need_pipeline
|= SVGA_PIPELINE_FLAG_TRIS
;
205 rast
->need_pipeline_tris_str
= "unfilled primitives with no index manipulation";
208 /* If we are decomposing to lines, and lines need the pipeline,
209 * then we also need the pipeline for tris.
211 if (fill
== PIPE_POLYGON_MODE_LINE
&&
212 (rast
->need_pipeline
& SVGA_PIPELINE_FLAG_LINES
))
214 fill
= PIPE_POLYGON_MODE_FILL
;
215 rast
->need_pipeline
|= SVGA_PIPELINE_FLAG_TRIS
;
216 rast
->need_pipeline_tris_str
= "decomposing lines";
219 /* Similarly for points:
221 if (fill
== PIPE_POLYGON_MODE_POINT
&&
222 (rast
->need_pipeline
& SVGA_PIPELINE_FLAG_POINTS
))
224 fill
= PIPE_POLYGON_MODE_FILL
;
225 rast
->need_pipeline
|= SVGA_PIPELINE_FLAG_TRIS
;
226 rast
->need_pipeline_tris_str
= "decomposing points";
230 rast
->slopescaledepthbias
= templ
->offset_scale
;
231 rast
->depthbias
= templ
->offset_units
;
234 rast
->hw_unfilled
= fill
;
237 if (rast
->need_pipeline
& SVGA_PIPELINE_FLAG_TRIS
) {
238 /* Turn off stuff which will get done in the draw module:
240 rast
->hw_unfilled
= PIPE_POLYGON_MODE_FILL
;
241 rast
->slopescaledepthbias
= 0;
245 if (0 && rast
->need_pipeline
) {
246 debug_printf("svga: rast need_pipeline = 0x%x\n", rast
->need_pipeline
);
247 debug_printf(" pnts: %s \n", rast
->need_pipeline_points_str
);
248 debug_printf(" lins: %s \n", rast
->need_pipeline_lines_str
);
249 debug_printf(" tris: %s \n", rast
->need_pipeline_tris_str
);
255 static void svga_bind_rasterizer_state( struct pipe_context
*pipe
,
258 struct svga_context
*svga
= svga_context(pipe
);
259 struct svga_rasterizer_state
*raster
= (struct svga_rasterizer_state
*)state
;
262 draw_set_rasterizer_state(svga
->swtnl
.draw
, raster
? &raster
->templ
: NULL
,
264 svga
->curr
.rast
= raster
;
266 svga
->dirty
|= SVGA_NEW_RAST
;
269 static void svga_delete_rasterizer_state(struct pipe_context
*pipe
,
276 void svga_init_rasterizer_functions( struct svga_context
*svga
)
278 svga
->pipe
.create_rasterizer_state
= svga_create_rasterizer_state
;
279 svga
->pipe
.bind_rasterizer_state
= svga_bind_rasterizer_state
;
280 svga
->pipe
.delete_rasterizer_state
= svga_delete_rasterizer_state
;
284 /***********************************************************************
285 * Hardware state update