17ec681f3Smrg/**************************************************************************
27ec681f3Smrg *
37ec681f3Smrg * Copyright 2012-2021 VMware, Inc.
47ec681f3Smrg * All Rights Reserved.
57ec681f3Smrg *
67ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
77ec681f3Smrg * copy of this software and associated documentation files (the
87ec681f3Smrg * "Software"), to deal in the Software without restriction, including
97ec681f3Smrg * without limitation the rights to use, copy, modify, merge, publish,
107ec681f3Smrg * distribute, sub license, and/or sell copies of the Software, and to
117ec681f3Smrg * permit persons to whom the Software is furnished to do so, subject to
127ec681f3Smrg * the following conditions:
137ec681f3Smrg *
147ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
157ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
167ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
177ec681f3Smrg * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
187ec681f3Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
197ec681f3Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
207ec681f3Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
217ec681f3Smrg *
227ec681f3Smrg * The above copyright notice and this permission notice (including the
237ec681f3Smrg * next paragraph) shall be included in all copies or substantial portions
247ec681f3Smrg * of the Software.
257ec681f3Smrg *
267ec681f3Smrg **************************************************************************/
277ec681f3Smrg
287ec681f3Smrg/*
297ec681f3Smrg * Rasterizer.cpp --
307ec681f3Smrg *    Functions that manipulate rasterizer state.
317ec681f3Smrg */
327ec681f3Smrg
337ec681f3Smrg
347ec681f3Smrg#include "Rasterizer.h"
357ec681f3Smrg#include "State.h"
367ec681f3Smrg
377ec681f3Smrg#include "Debug.h"
387ec681f3Smrg
397ec681f3Smrg
407ec681f3Smrg/*
417ec681f3Smrg * ----------------------------------------------------------------------
427ec681f3Smrg *
437ec681f3Smrg * SetViewports --
447ec681f3Smrg *
457ec681f3Smrg *    The SetViewports function sets viewports.
467ec681f3Smrg *
477ec681f3Smrg * ----------------------------------------------------------------------
487ec681f3Smrg */
497ec681f3Smrg
507ec681f3Smrgvoid APIENTRY
517ec681f3SmrgSetViewports(D3D10DDI_HDEVICE hDevice,                                        // IN
527ec681f3Smrg             UINT NumViewports,                                               // IN
537ec681f3Smrg             UINT ClearViewports,                                             // IN
547ec681f3Smrg             __in_ecount (NumViewports) const D3D10_DDI_VIEWPORT *pViewports) // IN
557ec681f3Smrg{
567ec681f3Smrg   LOG_ENTRYPOINT();
577ec681f3Smrg
587ec681f3Smrg   struct pipe_context *pipe = CastPipeContext(hDevice);
597ec681f3Smrg   struct pipe_viewport_state states[PIPE_MAX_VIEWPORTS];
607ec681f3Smrg
617ec681f3Smrg   ASSERT(NumViewports + ClearViewports <=
627ec681f3Smrg          D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE);
637ec681f3Smrg
647ec681f3Smrg   for (UINT i = 0; i < NumViewports; ++i) {
657ec681f3Smrg      const D3D10_DDI_VIEWPORT *pViewport = &pViewports[i];
667ec681f3Smrg      float width = pViewport->Width;
677ec681f3Smrg      float height = pViewport->Height;
687ec681f3Smrg      float x = pViewport->TopLeftX;
697ec681f3Smrg      float y = pViewport->TopLeftY;
707ec681f3Smrg      float z = pViewport->MinDepth;
717ec681f3Smrg      float half_width = width / 2.0f;
727ec681f3Smrg      float half_height = height / 2.0f;
737ec681f3Smrg      float depth = pViewport->MaxDepth - z;
747ec681f3Smrg
757ec681f3Smrg      states[i].scale[0] = half_width;
767ec681f3Smrg      states[i].scale[1] = -half_height;
777ec681f3Smrg      states[i].scale[2] = depth;
787ec681f3Smrg
797ec681f3Smrg      states[i].translate[0] = half_width + x;
807ec681f3Smrg      states[i].translate[1] = half_height + y;
817ec681f3Smrg      states[i].translate[2] = z;
827ec681f3Smrg   }
837ec681f3Smrg   if (ClearViewports) {
847ec681f3Smrg      memset(states + NumViewports, 0,
857ec681f3Smrg             sizeof(struct pipe_viewport_state) * ClearViewports);
867ec681f3Smrg   }
877ec681f3Smrg   pipe->set_viewport_states(pipe, 0, NumViewports + ClearViewports,
887ec681f3Smrg                             states);
897ec681f3Smrg}
907ec681f3Smrg
917ec681f3Smrg
927ec681f3Smrg/*
937ec681f3Smrg * ----------------------------------------------------------------------
947ec681f3Smrg *
957ec681f3Smrg * SetScissorRects --
967ec681f3Smrg *
977ec681f3Smrg *    The SetScissorRects function marks portions of render targets
987ec681f3Smrg *    that rendering is confined to.
997ec681f3Smrg *
1007ec681f3Smrg * ----------------------------------------------------------------------
1017ec681f3Smrg */
1027ec681f3Smrg
1037ec681f3Smrgvoid APIENTRY
1047ec681f3SmrgSetScissorRects(D3D10DDI_HDEVICE hDevice,                            // IN
1057ec681f3Smrg                UINT NumScissorRects,                                // IN
1067ec681f3Smrg                UINT ClearScissorRects,                              // IN
1077ec681f3Smrg                __in_ecount (NumRects) const D3D10_DDI_RECT *pRects) // IN
1087ec681f3Smrg{
1097ec681f3Smrg   LOG_ENTRYPOINT();
1107ec681f3Smrg
1117ec681f3Smrg   struct pipe_context *pipe = CastPipeContext(hDevice);
1127ec681f3Smrg   struct pipe_scissor_state states[PIPE_MAX_VIEWPORTS];
1137ec681f3Smrg
1147ec681f3Smrg   ASSERT(NumScissorRects + ClearScissorRects <=
1157ec681f3Smrg          D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE);
1167ec681f3Smrg
1177ec681f3Smrg   for (UINT i = 0; i < NumScissorRects; ++i) {
1187ec681f3Smrg      const D3D10_DDI_RECT *pRect = &pRects[i];
1197ec681f3Smrg      /* gallium scissor values are unsigned so lets make
1207ec681f3Smrg      * sure that we don't overflow */
1217ec681f3Smrg      states[i].minx = pRect->left   < 0 ? 0 : pRect->left;
1227ec681f3Smrg      states[i].miny = pRect->top    < 0 ? 0 : pRect->top;
1237ec681f3Smrg      states[i].maxx = pRect->right  < 0 ? 0 : pRect->right;
1247ec681f3Smrg      states[i].maxy = pRect->bottom < 0 ? 0 : pRect->bottom;
1257ec681f3Smrg   }
1267ec681f3Smrg   if (ClearScissorRects) {
1277ec681f3Smrg      memset(states + NumScissorRects, 0,
1287ec681f3Smrg             sizeof(struct pipe_scissor_state) * ClearScissorRects);
1297ec681f3Smrg   }
1307ec681f3Smrg   pipe->set_scissor_states(pipe, 0, NumScissorRects + ClearScissorRects,
1317ec681f3Smrg                            states);
1327ec681f3Smrg}
1337ec681f3Smrg
1347ec681f3Smrg
1357ec681f3Smrg/*
1367ec681f3Smrg * ----------------------------------------------------------------------
1377ec681f3Smrg *
1387ec681f3Smrg * CalcPrivateRasterizerStateSize --
1397ec681f3Smrg *
1407ec681f3Smrg *    The CalcPrivateRasterizerStateSize function determines the size
1417ec681f3Smrg *    of the user-mode display driver's private region of memory
1427ec681f3Smrg *    (that is, the size of internal driver structures, not the size
1437ec681f3Smrg *    of the resource video memory) for a rasterizer state.
1447ec681f3Smrg *
1457ec681f3Smrg * ----------------------------------------------------------------------
1467ec681f3Smrg */
1477ec681f3Smrg
1487ec681f3SmrgSIZE_T APIENTRY
1497ec681f3SmrgCalcPrivateRasterizerStateSize(
1507ec681f3Smrg   D3D10DDI_HDEVICE hDevice,                                // IN
1517ec681f3Smrg   __in const D3D10_DDI_RASTERIZER_DESC *pRasterizerDesc)   // IN
1527ec681f3Smrg{
1537ec681f3Smrg   return sizeof(RasterizerState);
1547ec681f3Smrg}
1557ec681f3Smrg
1567ec681f3Smrg
1577ec681f3Smrgstatic uint
1587ec681f3Smrgtranslate_cull_mode(D3D10_DDI_CULL_MODE CullMode)
1597ec681f3Smrg{
1607ec681f3Smrg   switch (CullMode) {
1617ec681f3Smrg   case D3D10_DDI_CULL_NONE:
1627ec681f3Smrg      return PIPE_FACE_NONE;
1637ec681f3Smrg   case D3D10_DDI_CULL_FRONT:
1647ec681f3Smrg      return PIPE_FACE_FRONT;
1657ec681f3Smrg   case D3D10_DDI_CULL_BACK:
1667ec681f3Smrg      return PIPE_FACE_BACK;
1677ec681f3Smrg   default:
1687ec681f3Smrg      assert(0);
1697ec681f3Smrg      return PIPE_FACE_NONE;
1707ec681f3Smrg   }
1717ec681f3Smrg}
1727ec681f3Smrg
1737ec681f3Smrgstatic uint
1747ec681f3Smrgtranslate_fill_mode(D3D10_DDI_FILL_MODE FillMode)
1757ec681f3Smrg{
1767ec681f3Smrg   switch (FillMode) {
1777ec681f3Smrg   case D3D10_DDI_FILL_WIREFRAME:
1787ec681f3Smrg      return PIPE_POLYGON_MODE_LINE;
1797ec681f3Smrg   case D3D10_DDI_FILL_SOLID:
1807ec681f3Smrg      return PIPE_POLYGON_MODE_FILL;
1817ec681f3Smrg   default:
1827ec681f3Smrg      assert(0);
1837ec681f3Smrg      return PIPE_POLYGON_MODE_FILL;
1847ec681f3Smrg   }
1857ec681f3Smrg}
1867ec681f3Smrg
1877ec681f3Smrg
1887ec681f3Smrg/*
1897ec681f3Smrg * ----------------------------------------------------------------------
1907ec681f3Smrg *
1917ec681f3Smrg * CreateRasterizerState --
1927ec681f3Smrg *
1937ec681f3Smrg *    The CreateRasterizerState function creates a rasterizer state.
1947ec681f3Smrg *
1957ec681f3Smrg * ----------------------------------------------------------------------
1967ec681f3Smrg */
1977ec681f3Smrg
1987ec681f3Smrgvoid APIENTRY
1997ec681f3SmrgCreateRasterizerState(
2007ec681f3Smrg    D3D10DDI_HDEVICE hDevice,                               // IN
2017ec681f3Smrg    __in const D3D10_DDI_RASTERIZER_DESC *pRasterizerDesc,  // IN
2027ec681f3Smrg    D3D10DDI_HRASTERIZERSTATE hRasterizerState,             // IN
2037ec681f3Smrg    D3D10DDI_HRTRASTERIZERSTATE hRTRasterizerState)         // IN
2047ec681f3Smrg{
2057ec681f3Smrg   LOG_ENTRYPOINT();
2067ec681f3Smrg
2077ec681f3Smrg   struct pipe_context *pipe = CastPipeContext(hDevice);
2087ec681f3Smrg   RasterizerState *pRasterizerState = CastRasterizerState(hRasterizerState);
2097ec681f3Smrg
2107ec681f3Smrg   struct pipe_rasterizer_state state;
2117ec681f3Smrg   memset(&state, 0, sizeof state);
2127ec681f3Smrg
2137ec681f3Smrg   state.flatshade_first = 1;
2147ec681f3Smrg   state.front_ccw = (pRasterizerDesc->FrontCounterClockwise ? 1 : 0);
2157ec681f3Smrg   state.cull_face = translate_cull_mode(pRasterizerDesc->CullMode);
2167ec681f3Smrg   state.fill_front = translate_fill_mode(pRasterizerDesc->FillMode);
2177ec681f3Smrg   state.fill_back = state.fill_front;
2187ec681f3Smrg   state.scissor = (pRasterizerDesc->ScissorEnable ? 1 : 0);
2197ec681f3Smrg   state.line_smooth = (pRasterizerDesc->AntialiasedLineEnable ? 1 : 0);
2207ec681f3Smrg   state.offset_units = (float)pRasterizerDesc->DepthBias;
2217ec681f3Smrg   state.offset_scale = pRasterizerDesc->SlopeScaledDepthBias;
2227ec681f3Smrg   state.offset_clamp = pRasterizerDesc->DepthBiasClamp;
2237ec681f3Smrg   state.multisample = /* pRasterizerDesc->MultisampleEnable */ 0;
2247ec681f3Smrg   state.half_pixel_center = 1;
2257ec681f3Smrg   state.bottom_edge_rule = 0;
2267ec681f3Smrg   state.clip_halfz = 1;
2277ec681f3Smrg   state.depth_clip_near = pRasterizerDesc->DepthClipEnable ? 1 : 0;
2287ec681f3Smrg   state.depth_clip_far = pRasterizerDesc->DepthClipEnable ? 1 : 0;
2297ec681f3Smrg   state.depth_clamp = 1;
2307ec681f3Smrg
2317ec681f3Smrg   state.point_quad_rasterization = 1;
2327ec681f3Smrg   state.point_size = 1.0f;
2337ec681f3Smrg   state.point_tri_clip = 1;
2347ec681f3Smrg
2357ec681f3Smrg   state.line_width = 1.0f;
2367ec681f3Smrg   state.line_rectangular = 0;
2377ec681f3Smrg
2387ec681f3Smrg   pRasterizerState->handle = pipe->create_rasterizer_state(pipe, &state);
2397ec681f3Smrg}
2407ec681f3Smrg
2417ec681f3Smrg
2427ec681f3Smrg/*
2437ec681f3Smrg * ----------------------------------------------------------------------
2447ec681f3Smrg *
2457ec681f3Smrg * DestroyRasterizerState --
2467ec681f3Smrg *
2477ec681f3Smrg *    The DestroyRasterizerState function destroys the specified
2487ec681f3Smrg *    rasterizer state object. The rasterizer state object can be
2497ec681f3Smrg *    destoyed only if it is not currently bound to a display device.
2507ec681f3Smrg *
2517ec681f3Smrg * ----------------------------------------------------------------------
2527ec681f3Smrg */
2537ec681f3Smrg
2547ec681f3Smrgvoid APIENTRY
2557ec681f3SmrgDestroyRasterizerState(D3D10DDI_HDEVICE hDevice,                     // IN
2567ec681f3Smrg                       D3D10DDI_HRASTERIZERSTATE hRasterizerState)   // IN
2577ec681f3Smrg{
2587ec681f3Smrg   LOG_ENTRYPOINT();
2597ec681f3Smrg
2607ec681f3Smrg   struct pipe_context *pipe = CastPipeContext(hDevice);
2617ec681f3Smrg   RasterizerState *pRasterizerState = CastRasterizerState(hRasterizerState);
2627ec681f3Smrg
2637ec681f3Smrg   pipe->delete_rasterizer_state(pipe, pRasterizerState->handle);
2647ec681f3Smrg}
2657ec681f3Smrg
2667ec681f3Smrg
2677ec681f3Smrg/*
2687ec681f3Smrg * ----------------------------------------------------------------------
2697ec681f3Smrg *
2707ec681f3Smrg * SetRasterizerState --
2717ec681f3Smrg *
2727ec681f3Smrg *    The SetRasterizerState function sets the rasterizer state.
2737ec681f3Smrg *
2747ec681f3Smrg * ----------------------------------------------------------------------
2757ec681f3Smrg */
2767ec681f3Smrg
2777ec681f3Smrgvoid APIENTRY
2787ec681f3SmrgSetRasterizerState(D3D10DDI_HDEVICE hDevice,                   // IN
2797ec681f3Smrg                   D3D10DDI_HRASTERIZERSTATE hRasterizerState) // IN
2807ec681f3Smrg{
2817ec681f3Smrg   LOG_ENTRYPOINT();
2827ec681f3Smrg
2837ec681f3Smrg   struct pipe_context *pipe = CastPipeContext(hDevice);
2847ec681f3Smrg   void *state = CastPipeRasterizerState(hRasterizerState);
2857ec681f3Smrg
2867ec681f3Smrg   pipe->bind_rasterizer_state(pipe, state);
2877ec681f3Smrg}
288