1 /**************************************************************************
2 *
3 * Copyright 2012-2021 VMware, Inc.
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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 **************************************************************************/
27
28 /*
29 * Rasterizer.cpp --
30 * Functions that manipulate rasterizer state.
31 */
32
33
34 #include "Rasterizer.h"
35 #include "State.h"
36
37 #include "Debug.h"
38
39
40 /*
41 * ----------------------------------------------------------------------
42 *
43 * SetViewports --
44 *
45 * The SetViewports function sets viewports.
46 *
47 * ----------------------------------------------------------------------
48 */
49
50 void APIENTRY
SetViewports(D3D10DDI_HDEVICE hDevice,UINT NumViewports,UINT ClearViewports,__in_ecount (NumViewports)const D3D10_DDI_VIEWPORT * pViewports)51 SetViewports(D3D10DDI_HDEVICE hDevice, // IN
52 UINT NumViewports, // IN
53 UINT ClearViewports, // IN
54 __in_ecount (NumViewports) const D3D10_DDI_VIEWPORT *pViewports) // IN
55 {
56 LOG_ENTRYPOINT();
57
58 struct pipe_context *pipe = CastPipeContext(hDevice);
59 struct pipe_viewport_state states[PIPE_MAX_VIEWPORTS];
60
61 ASSERT(NumViewports + ClearViewports <=
62 D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE);
63
64 for (UINT i = 0; i < NumViewports; ++i) {
65 const D3D10_DDI_VIEWPORT *pViewport = &pViewports[i];
66 float width = pViewport->Width;
67 float height = pViewport->Height;
68 float x = pViewport->TopLeftX;
69 float y = pViewport->TopLeftY;
70 float z = pViewport->MinDepth;
71 float half_width = width / 2.0f;
72 float half_height = height / 2.0f;
73 float depth = pViewport->MaxDepth - z;
74
75 states[i].scale[0] = half_width;
76 states[i].scale[1] = -half_height;
77 states[i].scale[2] = depth;
78
79 states[i].translate[0] = half_width + x;
80 states[i].translate[1] = half_height + y;
81 states[i].translate[2] = z;
82 }
83 if (ClearViewports) {
84 memset(states + NumViewports, 0,
85 sizeof(struct pipe_viewport_state) * ClearViewports);
86 }
87 pipe->set_viewport_states(pipe, 0, NumViewports + ClearViewports,
88 states);
89 }
90
91
92 /*
93 * ----------------------------------------------------------------------
94 *
95 * SetScissorRects --
96 *
97 * The SetScissorRects function marks portions of render targets
98 * that rendering is confined to.
99 *
100 * ----------------------------------------------------------------------
101 */
102
103 void APIENTRY
SetScissorRects(D3D10DDI_HDEVICE hDevice,UINT NumScissorRects,UINT ClearScissorRects,__in_ecount (NumRects)const D3D10_DDI_RECT * pRects)104 SetScissorRects(D3D10DDI_HDEVICE hDevice, // IN
105 UINT NumScissorRects, // IN
106 UINT ClearScissorRects, // IN
107 __in_ecount (NumRects) const D3D10_DDI_RECT *pRects) // IN
108 {
109 LOG_ENTRYPOINT();
110
111 struct pipe_context *pipe = CastPipeContext(hDevice);
112 struct pipe_scissor_state states[PIPE_MAX_VIEWPORTS];
113
114 ASSERT(NumScissorRects + ClearScissorRects <=
115 D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE);
116
117 for (UINT i = 0; i < NumScissorRects; ++i) {
118 const D3D10_DDI_RECT *pRect = &pRects[i];
119 /* gallium scissor values are unsigned so lets make
120 * sure that we don't overflow */
121 states[i].minx = pRect->left < 0 ? 0 : pRect->left;
122 states[i].miny = pRect->top < 0 ? 0 : pRect->top;
123 states[i].maxx = pRect->right < 0 ? 0 : pRect->right;
124 states[i].maxy = pRect->bottom < 0 ? 0 : pRect->bottom;
125 }
126 if (ClearScissorRects) {
127 memset(states + NumScissorRects, 0,
128 sizeof(struct pipe_scissor_state) * ClearScissorRects);
129 }
130 pipe->set_scissor_states(pipe, 0, NumScissorRects + ClearScissorRects,
131 states);
132 }
133
134
135 /*
136 * ----------------------------------------------------------------------
137 *
138 * CalcPrivateRasterizerStateSize --
139 *
140 * The CalcPrivateRasterizerStateSize function determines the size
141 * of the user-mode display driver's private region of memory
142 * (that is, the size of internal driver structures, not the size
143 * of the resource video memory) for a rasterizer state.
144 *
145 * ----------------------------------------------------------------------
146 */
147
148 SIZE_T APIENTRY
CalcPrivateRasterizerStateSize(D3D10DDI_HDEVICE hDevice,__in const D3D10_DDI_RASTERIZER_DESC * pRasterizerDesc)149 CalcPrivateRasterizerStateSize(
150 D3D10DDI_HDEVICE hDevice, // IN
151 __in const D3D10_DDI_RASTERIZER_DESC *pRasterizerDesc) // IN
152 {
153 return sizeof(RasterizerState);
154 }
155
156
157 static uint
translate_cull_mode(D3D10_DDI_CULL_MODE CullMode)158 translate_cull_mode(D3D10_DDI_CULL_MODE CullMode)
159 {
160 switch (CullMode) {
161 case D3D10_DDI_CULL_NONE:
162 return PIPE_FACE_NONE;
163 case D3D10_DDI_CULL_FRONT:
164 return PIPE_FACE_FRONT;
165 case D3D10_DDI_CULL_BACK:
166 return PIPE_FACE_BACK;
167 default:
168 assert(0);
169 return PIPE_FACE_NONE;
170 }
171 }
172
173 static uint
translate_fill_mode(D3D10_DDI_FILL_MODE FillMode)174 translate_fill_mode(D3D10_DDI_FILL_MODE FillMode)
175 {
176 switch (FillMode) {
177 case D3D10_DDI_FILL_WIREFRAME:
178 return PIPE_POLYGON_MODE_LINE;
179 case D3D10_DDI_FILL_SOLID:
180 return PIPE_POLYGON_MODE_FILL;
181 default:
182 assert(0);
183 return PIPE_POLYGON_MODE_FILL;
184 }
185 }
186
187
188 /*
189 * ----------------------------------------------------------------------
190 *
191 * CreateRasterizerState --
192 *
193 * The CreateRasterizerState function creates a rasterizer state.
194 *
195 * ----------------------------------------------------------------------
196 */
197
198 void APIENTRY
CreateRasterizerState(D3D10DDI_HDEVICE hDevice,__in const D3D10_DDI_RASTERIZER_DESC * pRasterizerDesc,D3D10DDI_HRASTERIZERSTATE hRasterizerState,D3D10DDI_HRTRASTERIZERSTATE hRTRasterizerState)199 CreateRasterizerState(
200 D3D10DDI_HDEVICE hDevice, // IN
201 __in const D3D10_DDI_RASTERIZER_DESC *pRasterizerDesc, // IN
202 D3D10DDI_HRASTERIZERSTATE hRasterizerState, // IN
203 D3D10DDI_HRTRASTERIZERSTATE hRTRasterizerState) // IN
204 {
205 LOG_ENTRYPOINT();
206
207 struct pipe_context *pipe = CastPipeContext(hDevice);
208 RasterizerState *pRasterizerState = CastRasterizerState(hRasterizerState);
209
210 struct pipe_rasterizer_state state;
211 memset(&state, 0, sizeof state);
212
213 state.flatshade_first = 1;
214 state.front_ccw = (pRasterizerDesc->FrontCounterClockwise ? 1 : 0);
215 state.cull_face = translate_cull_mode(pRasterizerDesc->CullMode);
216 state.fill_front = translate_fill_mode(pRasterizerDesc->FillMode);
217 state.fill_back = state.fill_front;
218 state.scissor = (pRasterizerDesc->ScissorEnable ? 1 : 0);
219 state.line_smooth = (pRasterizerDesc->AntialiasedLineEnable ? 1 : 0);
220 state.offset_units = (float)pRasterizerDesc->DepthBias;
221 state.offset_scale = pRasterizerDesc->SlopeScaledDepthBias;
222 state.offset_clamp = pRasterizerDesc->DepthBiasClamp;
223 state.multisample = /* pRasterizerDesc->MultisampleEnable */ 0;
224 state.half_pixel_center = 1;
225 state.bottom_edge_rule = 0;
226 state.clip_halfz = 1;
227 state.depth_clip_near = pRasterizerDesc->DepthClipEnable ? 1 : 0;
228 state.depth_clip_far = pRasterizerDesc->DepthClipEnable ? 1 : 0;
229 state.depth_clamp = 1;
230
231 state.point_quad_rasterization = 1;
232 state.point_size = 1.0f;
233 state.point_tri_clip = 1;
234
235 state.line_width = 1.0f;
236 state.line_rectangular = 0;
237
238 pRasterizerState->handle = pipe->create_rasterizer_state(pipe, &state);
239 }
240
241
242 /*
243 * ----------------------------------------------------------------------
244 *
245 * DestroyRasterizerState --
246 *
247 * The DestroyRasterizerState function destroys the specified
248 * rasterizer state object. The rasterizer state object can be
249 * destoyed only if it is not currently bound to a display device.
250 *
251 * ----------------------------------------------------------------------
252 */
253
254 void APIENTRY
DestroyRasterizerState(D3D10DDI_HDEVICE hDevice,D3D10DDI_HRASTERIZERSTATE hRasterizerState)255 DestroyRasterizerState(D3D10DDI_HDEVICE hDevice, // IN
256 D3D10DDI_HRASTERIZERSTATE hRasterizerState) // IN
257 {
258 LOG_ENTRYPOINT();
259
260 struct pipe_context *pipe = CastPipeContext(hDevice);
261 RasterizerState *pRasterizerState = CastRasterizerState(hRasterizerState);
262
263 pipe->delete_rasterizer_state(pipe, pRasterizerState->handle);
264 }
265
266
267 /*
268 * ----------------------------------------------------------------------
269 *
270 * SetRasterizerState --
271 *
272 * The SetRasterizerState function sets the rasterizer state.
273 *
274 * ----------------------------------------------------------------------
275 */
276
277 void APIENTRY
SetRasterizerState(D3D10DDI_HDEVICE hDevice,D3D10DDI_HRASTERIZERSTATE hRasterizerState)278 SetRasterizerState(D3D10DDI_HDEVICE hDevice, // IN
279 D3D10DDI_HRASTERIZERSTATE hRasterizerState) // IN
280 {
281 LOG_ENTRYPOINT();
282
283 struct pipe_context *pipe = CastPipeContext(hDevice);
284 void *state = CastPipeRasterizerState(hRasterizerState);
285
286 pipe->bind_rasterizer_state(pipe, state);
287 }
288