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