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