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