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