Subversion Repositories Kolibri OS

Rev

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