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