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 "svga_cmd.h"
27
28#include "util/u_inlines.h"
29
30#include "svga_context.h"
31#include "svga_surface.h"
32
33
34static void svga_set_scissor_state( struct pipe_context *pipe,
35                                 const struct pipe_scissor_state *scissor )
36{
37   struct svga_context *svga = svga_context(pipe);
38
39   memcpy( &svga->curr.scissor, scissor, sizeof(*scissor) );
40   svga->dirty |= SVGA_NEW_SCISSOR;
41}
42
43
44static void svga_set_polygon_stipple( struct pipe_context *pipe,
45                                      const struct pipe_poly_stipple *stipple )
46{
47   /* overridden by the draw module */
48}
49
50
51void svga_cleanup_framebuffer(struct svga_context *svga)
52{
53   struct pipe_framebuffer_state *curr = &svga->curr.framebuffer;
54   struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
55   int i;
56
57   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
58      pipe_surface_reference(&curr->cbufs[i], NULL);
59      pipe_surface_reference(&hw->cbufs[i], NULL);
60   }
61
62   pipe_surface_reference(&curr->zsbuf, NULL);
63   pipe_surface_reference(&hw->zsbuf, NULL);
64}
65
66
67#define DEPTH_BIAS_SCALE_FACTOR_D16    ((float)(1<<15))
68#define DEPTH_BIAS_SCALE_FACTOR_D24S8  ((float)(1<<23))
69#define DEPTH_BIAS_SCALE_FACTOR_D32    ((float)(1<<31))
70
71
72static void svga_set_framebuffer_state(struct pipe_context *pipe,
73				       const struct pipe_framebuffer_state *fb)
74{
75   struct svga_context *svga = svga_context(pipe);
76   struct pipe_framebuffer_state *dst = &svga->curr.framebuffer;
77   boolean propagate = FALSE;
78   int i;
79
80   dst->width = fb->width;
81   dst->height = fb->height;
82   dst->nr_cbufs = fb->nr_cbufs;
83
84   /* check if we need to propagate any of the target surfaces */
85   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
86      if (dst->cbufs[i] && dst->cbufs[i] != fb->cbufs[i])
87         if (svga_surface_needs_propagation(dst->cbufs[i]))
88            propagate = TRUE;
89   }
90
91   if (propagate) {
92      /* make sure that drawing calls comes before propagation calls */
93      svga_hwtnl_flush_retry( svga );
94
95      for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
96         if (dst->cbufs[i] && dst->cbufs[i] != fb->cbufs[i])
97            svga_propagate_surface(svga, dst->cbufs[i]);
98   }
99
100   /* XXX: Actually the virtual hardware may support rendertargets with
101    * different size, depending on the host API and driver, but since we cannot
102    * know that make no such assumption here. */
103   for(i = 0; i < fb->nr_cbufs; ++i) {
104      if (fb->zsbuf && fb->cbufs[i]) {
105         assert(fb->zsbuf->width == fb->cbufs[i]->width);
106         assert(fb->zsbuf->height == fb->cbufs[i]->height);
107      }
108   }
109
110   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
111      pipe_surface_reference(&dst->cbufs[i],
112                             (i < fb->nr_cbufs) ? fb->cbufs[i] : NULL);
113   }
114   pipe_surface_reference(&dst->zsbuf, fb->zsbuf);
115
116
117   if (svga->curr.framebuffer.zsbuf)
118   {
119      switch (svga->curr.framebuffer.zsbuf->format) {
120      case PIPE_FORMAT_Z16_UNORM:
121         svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D16;
122         break;
123      case PIPE_FORMAT_Z24_UNORM_S8_UINT:
124      case PIPE_FORMAT_Z24X8_UNORM:
125      case PIPE_FORMAT_S8_UINT_Z24_UNORM:
126      case PIPE_FORMAT_X8Z24_UNORM:
127         svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D24S8;
128         break;
129      case PIPE_FORMAT_Z32_UNORM:
130         svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D32;
131         break;
132      case PIPE_FORMAT_Z32_FLOAT:
133         svga->curr.depthscale = 1.0f / ((float)(1<<23));
134         break;
135      default:
136         svga->curr.depthscale = 0.0f;
137         break;
138      }
139   }
140   else {
141      svga->curr.depthscale = 0.0f;
142   }
143
144   svga->dirty |= SVGA_NEW_FRAME_BUFFER;
145}
146
147
148
149static void svga_set_clip_state( struct pipe_context *pipe,
150                                 const struct pipe_clip_state *clip )
151{
152   struct svga_context *svga = svga_context(pipe);
153
154   svga->curr.clip = *clip; /* struct copy */
155
156   svga->dirty |= SVGA_NEW_CLIP;
157}
158
159
160
161/* Called when driver state tracker notices changes to the viewport
162 * matrix:
163 */
164static void svga_set_viewport_state( struct pipe_context *pipe,
165				     const struct pipe_viewport_state *viewport )
166{
167   struct svga_context *svga = svga_context(pipe);
168
169   svga->curr.viewport = *viewport; /* struct copy */
170
171   svga->dirty |= SVGA_NEW_VIEWPORT;
172}
173
174
175
176void svga_init_misc_functions( struct svga_context *svga )
177{
178   svga->pipe.set_scissor_state = svga_set_scissor_state;
179   svga->pipe.set_polygon_stipple = svga_set_polygon_stipple;
180   svga->pipe.set_framebuffer_state = svga_set_framebuffer_state;
181   svga->pipe.set_clip_state = svga_set_clip_state;
182   svga->pipe.set_viewport_state = svga_set_viewport_state;
183}
184
185
186