/************************************************************************** * * Copyright 2012-2021 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * **************************************************************************/ /* * Rasterizer.cpp -- * Functions that manipulate rasterizer state. */ #include "Rasterizer.h" #include "State.h" #include "Debug.h" /* * ---------------------------------------------------------------------- * * SetViewports -- * * The SetViewports function sets viewports. * * ---------------------------------------------------------------------- */ void APIENTRY SetViewports(D3D10DDI_HDEVICE hDevice, // IN UINT NumViewports, // IN UINT ClearViewports, // IN __in_ecount (NumViewports) const D3D10_DDI_VIEWPORT *pViewports) // IN { LOG_ENTRYPOINT(); struct pipe_context *pipe = CastPipeContext(hDevice); struct pipe_viewport_state states[PIPE_MAX_VIEWPORTS]; ASSERT(NumViewports + ClearViewports <= D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE); for (UINT i = 0; i < NumViewports; ++i) { const D3D10_DDI_VIEWPORT *pViewport = &pViewports[i]; float width = pViewport->Width; float height = pViewport->Height; float x = pViewport->TopLeftX; float y = pViewport->TopLeftY; float z = pViewport->MinDepth; float half_width = width / 2.0f; float half_height = height / 2.0f; float depth = pViewport->MaxDepth - z; states[i].scale[0] = half_width; states[i].scale[1] = -half_height; states[i].scale[2] = depth; states[i].translate[0] = half_width + x; states[i].translate[1] = half_height + y; states[i].translate[2] = z; } if (ClearViewports) { memset(states + NumViewports, 0, sizeof(struct pipe_viewport_state) * ClearViewports); } pipe->set_viewport_states(pipe, 0, NumViewports + ClearViewports, states); } /* * ---------------------------------------------------------------------- * * SetScissorRects -- * * The SetScissorRects function marks portions of render targets * that rendering is confined to. * * ---------------------------------------------------------------------- */ void APIENTRY SetScissorRects(D3D10DDI_HDEVICE hDevice, // IN UINT NumScissorRects, // IN UINT ClearScissorRects, // IN __in_ecount (NumRects) const D3D10_DDI_RECT *pRects) // IN { LOG_ENTRYPOINT(); struct pipe_context *pipe = CastPipeContext(hDevice); struct pipe_scissor_state states[PIPE_MAX_VIEWPORTS]; ASSERT(NumScissorRects + ClearScissorRects <= D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE); for (UINT i = 0; i < NumScissorRects; ++i) { const D3D10_DDI_RECT *pRect = &pRects[i]; /* gallium scissor values are unsigned so lets make * sure that we don't overflow */ states[i].minx = pRect->left < 0 ? 0 : pRect->left; states[i].miny = pRect->top < 0 ? 0 : pRect->top; states[i].maxx = pRect->right < 0 ? 0 : pRect->right; states[i].maxy = pRect->bottom < 0 ? 0 : pRect->bottom; } if (ClearScissorRects) { memset(states + NumScissorRects, 0, sizeof(struct pipe_scissor_state) * ClearScissorRects); } pipe->set_scissor_states(pipe, 0, NumScissorRects + ClearScissorRects, states); } /* * ---------------------------------------------------------------------- * * CalcPrivateRasterizerStateSize -- * * The CalcPrivateRasterizerStateSize function determines the size * of the user-mode display driver's private region of memory * (that is, the size of internal driver structures, not the size * of the resource video memory) for a rasterizer state. * * ---------------------------------------------------------------------- */ SIZE_T APIENTRY CalcPrivateRasterizerStateSize( D3D10DDI_HDEVICE hDevice, // IN __in const D3D10_DDI_RASTERIZER_DESC *pRasterizerDesc) // IN { return sizeof(RasterizerState); } static uint translate_cull_mode(D3D10_DDI_CULL_MODE CullMode) { switch (CullMode) { case D3D10_DDI_CULL_NONE: return PIPE_FACE_NONE; case D3D10_DDI_CULL_FRONT: return PIPE_FACE_FRONT; case D3D10_DDI_CULL_BACK: return PIPE_FACE_BACK; default: assert(0); return PIPE_FACE_NONE; } } static uint translate_fill_mode(D3D10_DDI_FILL_MODE FillMode) { switch (FillMode) { case D3D10_DDI_FILL_WIREFRAME: return PIPE_POLYGON_MODE_LINE; case D3D10_DDI_FILL_SOLID: return PIPE_POLYGON_MODE_FILL; default: assert(0); return PIPE_POLYGON_MODE_FILL; } } /* * ---------------------------------------------------------------------- * * CreateRasterizerState -- * * The CreateRasterizerState function creates a rasterizer state. * * ---------------------------------------------------------------------- */ void APIENTRY CreateRasterizerState( D3D10DDI_HDEVICE hDevice, // IN __in const D3D10_DDI_RASTERIZER_DESC *pRasterizerDesc, // IN D3D10DDI_HRASTERIZERSTATE hRasterizerState, // IN D3D10DDI_HRTRASTERIZERSTATE hRTRasterizerState) // IN { LOG_ENTRYPOINT(); struct pipe_context *pipe = CastPipeContext(hDevice); RasterizerState *pRasterizerState = CastRasterizerState(hRasterizerState); struct pipe_rasterizer_state state; memset(&state, 0, sizeof state); state.flatshade_first = 1; state.front_ccw = (pRasterizerDesc->FrontCounterClockwise ? 1 : 0); state.cull_face = translate_cull_mode(pRasterizerDesc->CullMode); state.fill_front = translate_fill_mode(pRasterizerDesc->FillMode); state.fill_back = state.fill_front; state.scissor = (pRasterizerDesc->ScissorEnable ? 1 : 0); state.line_smooth = (pRasterizerDesc->AntialiasedLineEnable ? 1 : 0); state.offset_units = (float)pRasterizerDesc->DepthBias; state.offset_scale = pRasterizerDesc->SlopeScaledDepthBias; state.offset_clamp = pRasterizerDesc->DepthBiasClamp; state.multisample = /* pRasterizerDesc->MultisampleEnable */ 0; state.half_pixel_center = 1; state.bottom_edge_rule = 0; state.clip_halfz = 1; state.depth_clip_near = pRasterizerDesc->DepthClipEnable ? 1 : 0; state.depth_clip_far = pRasterizerDesc->DepthClipEnable ? 1 : 0; state.depth_clamp = 1; state.point_quad_rasterization = 1; state.point_size = 1.0f; state.point_tri_clip = 1; state.line_width = 1.0f; state.line_rectangular = 0; pRasterizerState->handle = pipe->create_rasterizer_state(pipe, &state); } /* * ---------------------------------------------------------------------- * * DestroyRasterizerState -- * * The DestroyRasterizerState function destroys the specified * rasterizer state object. The rasterizer state object can be * destoyed only if it is not currently bound to a display device. * * ---------------------------------------------------------------------- */ void APIENTRY DestroyRasterizerState(D3D10DDI_HDEVICE hDevice, // IN D3D10DDI_HRASTERIZERSTATE hRasterizerState) // IN { LOG_ENTRYPOINT(); struct pipe_context *pipe = CastPipeContext(hDevice); RasterizerState *pRasterizerState = CastRasterizerState(hRasterizerState); pipe->delete_rasterizer_state(pipe, pRasterizerState->handle); } /* * ---------------------------------------------------------------------- * * SetRasterizerState -- * * The SetRasterizerState function sets the rasterizer state. * * ---------------------------------------------------------------------- */ void APIENTRY SetRasterizerState(D3D10DDI_HDEVICE hDevice, // IN D3D10DDI_HRASTERIZERSTATE hRasterizerState) // IN { LOG_ENTRYPOINT(); struct pipe_context *pipe = CastPipeContext(hDevice); void *state = CastPipeRasterizerState(hRasterizerState); pipe->bind_rasterizer_state(pipe, state); }