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 * OutputMerger.cpp -- 307ec681f3Smrg * Functions that manipulate the output merger state. 317ec681f3Smrg */ 327ec681f3Smrg 337ec681f3Smrg 347ec681f3Smrg#include "OutputMerger.h" 357ec681f3Smrg#include "State.h" 367ec681f3Smrg 377ec681f3Smrg#include "Debug.h" 387ec681f3Smrg#include "Format.h" 397ec681f3Smrg 407ec681f3Smrg#include "util/u_framebuffer.h" 417ec681f3Smrg#include "util/format/u_format.h" 427ec681f3Smrg 437ec681f3Smrg 447ec681f3Smrg/* 457ec681f3Smrg * ---------------------------------------------------------------------- 467ec681f3Smrg * 477ec681f3Smrg * CalcPrivateRenderTargetViewSize -- 487ec681f3Smrg * 497ec681f3Smrg * The CalcPrivateRenderTargetViewSize function determines the size 507ec681f3Smrg * of the user-mode display driver's private region of memory 517ec681f3Smrg * (that is, the size of internal driver structures, not the size 527ec681f3Smrg * of the resource video memory) for a render target view. 537ec681f3Smrg * 547ec681f3Smrg * ---------------------------------------------------------------------- 557ec681f3Smrg */ 567ec681f3Smrg 577ec681f3Smrg 587ec681f3SmrgSIZE_T APIENTRY 597ec681f3SmrgCalcPrivateRenderTargetViewSize( 607ec681f3Smrg D3D10DDI_HDEVICE hDevice, // IN 617ec681f3Smrg __in const D3D10DDIARG_CREATERENDERTARGETVIEW *pCreateRenderTargetView) // IN 627ec681f3Smrg{ 637ec681f3Smrg return sizeof(RenderTargetView); 647ec681f3Smrg} 657ec681f3Smrg 667ec681f3Smrg 677ec681f3Smrg/* 687ec681f3Smrg * ---------------------------------------------------------------------- 697ec681f3Smrg * 707ec681f3Smrg * CreateRenderTargetView -- 717ec681f3Smrg * 727ec681f3Smrg * The CreateRenderTargetView function creates a render target view. 737ec681f3Smrg * 747ec681f3Smrg * ---------------------------------------------------------------------- 757ec681f3Smrg */ 767ec681f3Smrg 777ec681f3Smrgvoid APIENTRY 787ec681f3SmrgCreateRenderTargetView( 797ec681f3Smrg D3D10DDI_HDEVICE hDevice, // IN 807ec681f3Smrg __in const D3D10DDIARG_CREATERENDERTARGETVIEW *pCreateRenderTargetView, // IN 817ec681f3Smrg D3D10DDI_HRENDERTARGETVIEW hRenderTargetView, // IN 827ec681f3Smrg D3D10DDI_HRTRENDERTARGETVIEW hRTRenderTargetView) // IN 837ec681f3Smrg{ 847ec681f3Smrg LOG_ENTRYPOINT(); 857ec681f3Smrg 867ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 877ec681f3Smrg struct pipe_resource *resource = CastPipeResource(pCreateRenderTargetView->hDrvResource); 887ec681f3Smrg RenderTargetView *pRTView = CastRenderTargetView(hRenderTargetView); 897ec681f3Smrg 907ec681f3Smrg struct pipe_surface desc; 917ec681f3Smrg 927ec681f3Smrg memset(&desc, 0, sizeof desc); 937ec681f3Smrg desc.format = FormatTranslate(pCreateRenderTargetView->Format, FALSE); 947ec681f3Smrg 957ec681f3Smrg switch (pCreateRenderTargetView->ResourceDimension) { 967ec681f3Smrg case D3D10DDIRESOURCE_BUFFER: 977ec681f3Smrg desc.u.buf.first_element = pCreateRenderTargetView->Buffer.FirstElement; 987ec681f3Smrg desc.u.buf.last_element = pCreateRenderTargetView->Buffer.NumElements - 1 + 997ec681f3Smrg desc.u.buf.first_element; 1007ec681f3Smrg break; 1017ec681f3Smrg case D3D10DDIRESOURCE_TEXTURE1D: 1027ec681f3Smrg ASSERT(pCreateRenderTargetView->Tex1D.ArraySize != (UINT)-1); 1037ec681f3Smrg desc.u.tex.level = pCreateRenderTargetView->Tex1D.MipSlice; 1047ec681f3Smrg desc.u.tex.first_layer = pCreateRenderTargetView->Tex1D.FirstArraySlice; 1057ec681f3Smrg desc.u.tex.last_layer = pCreateRenderTargetView->Tex1D.ArraySize - 1 + 1067ec681f3Smrg desc.u.tex.first_layer; 1077ec681f3Smrg break; 1087ec681f3Smrg case D3D10DDIRESOURCE_TEXTURE2D: 1097ec681f3Smrg ASSERT(pCreateRenderTargetView->Tex2D.ArraySize != (UINT)-1); 1107ec681f3Smrg desc.u.tex.level = pCreateRenderTargetView->Tex2D.MipSlice; 1117ec681f3Smrg desc.u.tex.first_layer = pCreateRenderTargetView->Tex2D.FirstArraySlice; 1127ec681f3Smrg desc.u.tex.last_layer = pCreateRenderTargetView->Tex2D.ArraySize - 1 + 1137ec681f3Smrg desc.u.tex.first_layer; 1147ec681f3Smrg break; 1157ec681f3Smrg case D3D10DDIRESOURCE_TEXTURE3D: 1167ec681f3Smrg desc.u.tex.level = pCreateRenderTargetView->Tex3D.MipSlice; 1177ec681f3Smrg desc.u.tex.first_layer = pCreateRenderTargetView->Tex3D.FirstW; 1187ec681f3Smrg desc.u.tex.last_layer = pCreateRenderTargetView->Tex3D.WSize - 1 + 1197ec681f3Smrg desc.u.tex.first_layer; 1207ec681f3Smrg break; 1217ec681f3Smrg case D3D10DDIRESOURCE_TEXTURECUBE: 1227ec681f3Smrg ASSERT(pCreateRenderTargetView->TexCube.ArraySize != (UINT)-1); 1237ec681f3Smrg desc.u.tex.level = pCreateRenderTargetView->TexCube.MipSlice; 1247ec681f3Smrg desc.u.tex.first_layer = pCreateRenderTargetView->TexCube.FirstArraySlice; 1257ec681f3Smrg desc.u.tex.last_layer = pCreateRenderTargetView->TexCube.ArraySize - 1 + 1267ec681f3Smrg desc.u.tex.first_layer;; 1277ec681f3Smrg break; 1287ec681f3Smrg default: 1297ec681f3Smrg ASSERT(0); 1307ec681f3Smrg return; 1317ec681f3Smrg } 1327ec681f3Smrg 1337ec681f3Smrg pRTView->surface = pipe->create_surface(pipe, resource, &desc); 1347ec681f3Smrg assert(pRTView->surface); 1357ec681f3Smrg} 1367ec681f3Smrg 1377ec681f3Smrg 1387ec681f3Smrg/* 1397ec681f3Smrg * ---------------------------------------------------------------------- 1407ec681f3Smrg * 1417ec681f3Smrg * DestroyRenderTargetView -- 1427ec681f3Smrg * 1437ec681f3Smrg * The DestroyRenderTargetView function destroys the specified 1447ec681f3Smrg * render target view object. The render target view object can 1457ec681f3Smrg * be destoyed only if it is not currently bound to a display device. 1467ec681f3Smrg * 1477ec681f3Smrg * ---------------------------------------------------------------------- 1487ec681f3Smrg */ 1497ec681f3Smrg 1507ec681f3Smrgvoid APIENTRY 1517ec681f3SmrgDestroyRenderTargetView(D3D10DDI_HDEVICE hDevice, // IN 1527ec681f3Smrg D3D10DDI_HRENDERTARGETVIEW hRenderTargetView) // IN 1537ec681f3Smrg{ 1547ec681f3Smrg LOG_ENTRYPOINT(); 1557ec681f3Smrg 1567ec681f3Smrg RenderTargetView *pRTView = CastRenderTargetView(hRenderTargetView); 1577ec681f3Smrg 1587ec681f3Smrg pipe_surface_reference(&pRTView->surface, NULL); 1597ec681f3Smrg} 1607ec681f3Smrg 1617ec681f3Smrg 1627ec681f3Smrg/* 1637ec681f3Smrg * ---------------------------------------------------------------------- 1647ec681f3Smrg * 1657ec681f3Smrg * ClearRenderTargetView -- 1667ec681f3Smrg * 1677ec681f3Smrg * The ClearRenderTargetView function clears the specified 1687ec681f3Smrg * render target view by setting it to a constant value. 1697ec681f3Smrg * 1707ec681f3Smrg * ---------------------------------------------------------------------- 1717ec681f3Smrg */ 1727ec681f3Smrg 1737ec681f3Smrgvoid APIENTRY 1747ec681f3SmrgClearRenderTargetView(D3D10DDI_HDEVICE hDevice, // IN 1757ec681f3Smrg D3D10DDI_HRENDERTARGETVIEW hRenderTargetView, // IN 1767ec681f3Smrg FLOAT pColorRGBA[4]) // IN 1777ec681f3Smrg{ 1787ec681f3Smrg LOG_ENTRYPOINT(); 1797ec681f3Smrg 1807ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 1817ec681f3Smrg struct pipe_surface *surface = CastPipeRenderTargetView(hRenderTargetView); 1827ec681f3Smrg union pipe_color_union clear_color; 1837ec681f3Smrg 1847ec681f3Smrg /* 1857ec681f3Smrg * DX10 always uses float clear color but gallium does not. 1867ec681f3Smrg * Conversion should just be ordinary conversion. Actual clamping will 1877ec681f3Smrg * be done later but need to make sure values exceeding int/uint range 1887ec681f3Smrg * are handled correctly. 1897ec681f3Smrg */ 1907ec681f3Smrg if (util_format_is_pure_integer(surface->format)) { 1917ec681f3Smrg if (util_format_is_pure_sint(surface->format)) { 1927ec681f3Smrg unsigned i; 1937ec681f3Smrg /* If only MIN_INT/UINT32 in c++ code would work... */ 1947ec681f3Smrg int min_int32 = 0x80000000; 1957ec681f3Smrg int max_int32 = 0x7fffffff; 1967ec681f3Smrg for (i = 0; i < 4; i++) { 1977ec681f3Smrg float value = pColorRGBA[i]; 1987ec681f3Smrg /* This is an expanded clamp to handle NaN and integer conversion. */ 1997ec681f3Smrg if (util_is_nan(value)) { 2007ec681f3Smrg clear_color.i[i] = 0; 2017ec681f3Smrg } else if (value <= (float)min_int32) { 2027ec681f3Smrg clear_color.i[i] = min_int32; 2037ec681f3Smrg } else if (value >= (float)max_int32) { 2047ec681f3Smrg clear_color.i[i] = max_int32; 2057ec681f3Smrg } else { 2067ec681f3Smrg clear_color.i[i] = value; 2077ec681f3Smrg } 2087ec681f3Smrg } 2097ec681f3Smrg } 2107ec681f3Smrg else { 2117ec681f3Smrg assert(util_format_is_pure_uint(surface->format)); 2127ec681f3Smrg unsigned i; 2137ec681f3Smrg unsigned max_uint32 = 0xffffffffU; 2147ec681f3Smrg for (i = 0; i < 4; i++) { 2157ec681f3Smrg float value = pColorRGBA[i]; 2167ec681f3Smrg /* This is an expanded clamp to handle NaN and integer conversion. */ 2177ec681f3Smrg if (!(value >= 0.0f)) { 2187ec681f3Smrg /* Handles NaN. */ 2197ec681f3Smrg clear_color.ui[i] = 0; 2207ec681f3Smrg } else if (value >= (float)max_uint32) { 2217ec681f3Smrg clear_color.ui[i] = max_uint32; 2227ec681f3Smrg } else { 2237ec681f3Smrg clear_color.ui[i] = value; 2247ec681f3Smrg } 2257ec681f3Smrg } 2267ec681f3Smrg } 2277ec681f3Smrg } 2287ec681f3Smrg else { 2297ec681f3Smrg clear_color.f[0] = pColorRGBA[0]; 2307ec681f3Smrg clear_color.f[1] = pColorRGBA[1]; 2317ec681f3Smrg clear_color.f[2] = pColorRGBA[2]; 2327ec681f3Smrg clear_color.f[3] = pColorRGBA[3]; 2337ec681f3Smrg } 2347ec681f3Smrg 2357ec681f3Smrg pipe->clear_render_target(pipe, 2367ec681f3Smrg surface, 2377ec681f3Smrg &clear_color, 2387ec681f3Smrg 0, 0, 2397ec681f3Smrg surface->width, 2407ec681f3Smrg surface->height, 2417ec681f3Smrg TRUE); 2427ec681f3Smrg} 2437ec681f3Smrg 2447ec681f3Smrg 2457ec681f3Smrg/* 2467ec681f3Smrg * ---------------------------------------------------------------------- 2477ec681f3Smrg * 2487ec681f3Smrg * CalcPrivateDepthStencilViewSize -- 2497ec681f3Smrg * 2507ec681f3Smrg * The CalcPrivateDepthStencilViewSize function determines the size 2517ec681f3Smrg * of the user-mode display driver's private region of memory 2527ec681f3Smrg * (that is, the size of internal driver structures, not the size 2537ec681f3Smrg * of the resource video memory) for a depth stencil view. 2547ec681f3Smrg * 2557ec681f3Smrg * ---------------------------------------------------------------------- 2567ec681f3Smrg */ 2577ec681f3Smrg 2587ec681f3SmrgSIZE_T APIENTRY 2597ec681f3SmrgCalcPrivateDepthStencilViewSize( 2607ec681f3Smrg D3D10DDI_HDEVICE hDevice, // IN 2617ec681f3Smrg __in const D3D10DDIARG_CREATEDEPTHSTENCILVIEW *pCreateDepthStencilView) // IN 2627ec681f3Smrg{ 2637ec681f3Smrg return sizeof(DepthStencilView); 2647ec681f3Smrg} 2657ec681f3Smrg 2667ec681f3Smrg 2677ec681f3Smrg/* 2687ec681f3Smrg * ---------------------------------------------------------------------- 2697ec681f3Smrg * 2707ec681f3Smrg * CreateDepthStencilView -- 2717ec681f3Smrg * 2727ec681f3Smrg * The CreateDepthStencilView function creates a depth stencil view. 2737ec681f3Smrg * 2747ec681f3Smrg * ---------------------------------------------------------------------- 2757ec681f3Smrg */ 2767ec681f3Smrg 2777ec681f3Smrgvoid APIENTRY 2787ec681f3SmrgCreateDepthStencilView( 2797ec681f3Smrg D3D10DDI_HDEVICE hDevice, // IN 2807ec681f3Smrg __in const D3D10DDIARG_CREATEDEPTHSTENCILVIEW *pCreateDepthStencilView, // IN 2817ec681f3Smrg D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView, // IN 2827ec681f3Smrg D3D10DDI_HRTDEPTHSTENCILVIEW hRTDepthStencilView) // IN 2837ec681f3Smrg{ 2847ec681f3Smrg LOG_ENTRYPOINT(); 2857ec681f3Smrg 2867ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 2877ec681f3Smrg struct pipe_resource *resource = CastPipeResource(pCreateDepthStencilView->hDrvResource); 2887ec681f3Smrg DepthStencilView *pDSView = CastDepthStencilView(hDepthStencilView); 2897ec681f3Smrg 2907ec681f3Smrg struct pipe_surface desc; 2917ec681f3Smrg 2927ec681f3Smrg memset(&desc, 0, sizeof desc); 2937ec681f3Smrg desc.format = FormatTranslate(pCreateDepthStencilView->Format, TRUE); 2947ec681f3Smrg 2957ec681f3Smrg switch (pCreateDepthStencilView->ResourceDimension) { 2967ec681f3Smrg case D3D10DDIRESOURCE_TEXTURE1D: 2977ec681f3Smrg ASSERT(pCreateDepthStencilView->Tex1D.ArraySize != (UINT)-1); 2987ec681f3Smrg desc.u.tex.level = pCreateDepthStencilView->Tex1D.MipSlice; 2997ec681f3Smrg desc.u.tex.first_layer = pCreateDepthStencilView->Tex1D.FirstArraySlice; 3007ec681f3Smrg desc.u.tex.last_layer = pCreateDepthStencilView->Tex1D.ArraySize - 1 + 3017ec681f3Smrg desc.u.tex.first_layer; 3027ec681f3Smrg break; 3037ec681f3Smrg case D3D10DDIRESOURCE_TEXTURE2D: 3047ec681f3Smrg ASSERT(pCreateDepthStencilView->Tex2D.ArraySize != (UINT)-1); 3057ec681f3Smrg desc.u.tex.level = pCreateDepthStencilView->Tex2D.MipSlice; 3067ec681f3Smrg desc.u.tex.first_layer = pCreateDepthStencilView->Tex2D.FirstArraySlice; 3077ec681f3Smrg desc.u.tex.last_layer = pCreateDepthStencilView->Tex2D.ArraySize - 1 + 3087ec681f3Smrg desc.u.tex.first_layer; 3097ec681f3Smrg break; 3107ec681f3Smrg case D3D10DDIRESOURCE_TEXTURECUBE: 3117ec681f3Smrg ASSERT(pCreateDepthStencilView->TexCube.ArraySize != (UINT)-1); 3127ec681f3Smrg desc.u.tex.level = pCreateDepthStencilView->TexCube.MipSlice; 3137ec681f3Smrg desc.u.tex.first_layer = pCreateDepthStencilView->TexCube.FirstArraySlice; 3147ec681f3Smrg desc.u.tex.last_layer = pCreateDepthStencilView->TexCube.ArraySize - 1 + 3157ec681f3Smrg desc.u.tex.first_layer; 3167ec681f3Smrg break; 3177ec681f3Smrg default: 3187ec681f3Smrg ASSERT(0); 3197ec681f3Smrg return; 3207ec681f3Smrg } 3217ec681f3Smrg 3227ec681f3Smrg pDSView->surface = pipe->create_surface(pipe, resource, &desc); 3237ec681f3Smrg assert(pDSView->surface); 3247ec681f3Smrg} 3257ec681f3Smrg 3267ec681f3Smrg 3277ec681f3Smrg/* 3287ec681f3Smrg * ---------------------------------------------------------------------- 3297ec681f3Smrg * 3307ec681f3Smrg * DestroyDepthStencilView -- 3317ec681f3Smrg * 3327ec681f3Smrg * The DestroyDepthStencilView function destroys the specified 3337ec681f3Smrg * depth stencil view object. The depth stencil view object can 3347ec681f3Smrg * be destoyed only if it is not currently bound to a display device. 3357ec681f3Smrg * 3367ec681f3Smrg * ---------------------------------------------------------------------- 3377ec681f3Smrg */ 3387ec681f3Smrg 3397ec681f3Smrgvoid APIENTRY 3407ec681f3SmrgDestroyDepthStencilView(D3D10DDI_HDEVICE hDevice, // IN 3417ec681f3Smrg D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView) // IN 3427ec681f3Smrg{ 3437ec681f3Smrg LOG_ENTRYPOINT(); 3447ec681f3Smrg 3457ec681f3Smrg DepthStencilView *pDSView = CastDepthStencilView(hDepthStencilView); 3467ec681f3Smrg 3477ec681f3Smrg pipe_surface_reference(&pDSView->surface, NULL); 3487ec681f3Smrg} 3497ec681f3Smrg 3507ec681f3Smrg 3517ec681f3Smrg/* 3527ec681f3Smrg * ---------------------------------------------------------------------- 3537ec681f3Smrg * 3547ec681f3Smrg * ClearDepthStencilView -- 3557ec681f3Smrg * 3567ec681f3Smrg * The ClearDepthStencilView function clears the specified 3577ec681f3Smrg * currently bound depth-stencil view. 3587ec681f3Smrg * 3597ec681f3Smrg * ---------------------------------------------------------------------- 3607ec681f3Smrg */ 3617ec681f3Smrg 3627ec681f3Smrgvoid APIENTRY 3637ec681f3SmrgClearDepthStencilView(D3D10DDI_HDEVICE hDevice, // IN 3647ec681f3Smrg D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView, // IN 3657ec681f3Smrg UINT Flags, // IN 3667ec681f3Smrg FLOAT Depth, // IN 3677ec681f3Smrg UINT8 Stencil) // IN 3687ec681f3Smrg{ 3697ec681f3Smrg LOG_ENTRYPOINT(); 3707ec681f3Smrg 3717ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 3727ec681f3Smrg struct pipe_surface *surface = CastPipeDepthStencilView(hDepthStencilView); 3737ec681f3Smrg 3747ec681f3Smrg unsigned flags = 0; 3757ec681f3Smrg if (Flags & D3D10_DDI_CLEAR_DEPTH) { 3767ec681f3Smrg flags |= PIPE_CLEAR_DEPTH; 3777ec681f3Smrg } 3787ec681f3Smrg if (Flags & D3D10_DDI_CLEAR_STENCIL) { 3797ec681f3Smrg flags |= PIPE_CLEAR_STENCIL; 3807ec681f3Smrg } 3817ec681f3Smrg 3827ec681f3Smrg pipe->clear_depth_stencil(pipe, 3837ec681f3Smrg surface, 3847ec681f3Smrg flags, 3857ec681f3Smrg Depth, 3867ec681f3Smrg Stencil, 3877ec681f3Smrg 0, 0, 3887ec681f3Smrg surface->width, 3897ec681f3Smrg surface->height, 3907ec681f3Smrg TRUE); 3917ec681f3Smrg} 3927ec681f3Smrg 3937ec681f3Smrg 3947ec681f3Smrg/* 3957ec681f3Smrg * ---------------------------------------------------------------------- 3967ec681f3Smrg * 3977ec681f3Smrg * CalcPrivateBlendStateSize -- 3987ec681f3Smrg * 3997ec681f3Smrg * The CalcPrivateBlendStateSize function determines the size of 4007ec681f3Smrg * the user-mode display driver's private region of memory (that 4017ec681f3Smrg * is, the size of internal driver structures, not the size of 4027ec681f3Smrg * the resource video memory) for a blend state. 4037ec681f3Smrg * 4047ec681f3Smrg * ---------------------------------------------------------------------- 4057ec681f3Smrg */ 4067ec681f3Smrg 4077ec681f3SmrgSIZE_T APIENTRY 4087ec681f3SmrgCalcPrivateBlendStateSize(D3D10DDI_HDEVICE hDevice, // IN 4097ec681f3Smrg __in const D3D10_DDI_BLEND_DESC *pBlendDesc) // IN 4107ec681f3Smrg{ 4117ec681f3Smrg return sizeof(BlendState); 4127ec681f3Smrg} 4137ec681f3Smrg 4147ec681f3Smrg 4157ec681f3Smrg/* 4167ec681f3Smrg * ---------------------------------------------------------------------- 4177ec681f3Smrg * 4187ec681f3Smrg * CalcPrivateBlendStateSize1 -- 4197ec681f3Smrg * 4207ec681f3Smrg * The CalcPrivateBlendStateSize function determines the size of 4217ec681f3Smrg * the user-mode display driver's private region of memory (that 4227ec681f3Smrg * is, the size of internal driver structures, not the size of 4237ec681f3Smrg * the resource video memory) for a blend state. 4247ec681f3Smrg * 4257ec681f3Smrg * ---------------------------------------------------------------------- 4267ec681f3Smrg */ 4277ec681f3Smrg 4287ec681f3SmrgSIZE_T APIENTRY 4297ec681f3SmrgCalcPrivateBlendStateSize1(D3D10DDI_HDEVICE hDevice, // IN 4307ec681f3Smrg __in const D3D10_1_DDI_BLEND_DESC *pBlendDesc) // IN 4317ec681f3Smrg{ 4327ec681f3Smrg return sizeof(BlendState); 4337ec681f3Smrg} 4347ec681f3Smrg 4357ec681f3Smrg 4367ec681f3Smrg/* 4377ec681f3Smrg * ---------------------------------------------------------------------- 4387ec681f3Smrg * 4397ec681f3Smrg * translateBlend -- 4407ec681f3Smrg * 4417ec681f3Smrg * Translate blend function from svga3d to gallium representation. 4427ec681f3Smrg * 4437ec681f3Smrg * ---------------------------------------------------------------------- 4447ec681f3Smrg */ 4457ec681f3Smrgstatic uint 4467ec681f3SmrgtranslateBlendOp(D3D10_DDI_BLEND_OP op) 4477ec681f3Smrg{ 4487ec681f3Smrg switch (op) { 4497ec681f3Smrg case D3D10_DDI_BLEND_OP_ADD: 4507ec681f3Smrg return PIPE_BLEND_ADD; 4517ec681f3Smrg case D3D10_DDI_BLEND_OP_SUBTRACT: 4527ec681f3Smrg return PIPE_BLEND_SUBTRACT; 4537ec681f3Smrg case D3D10_DDI_BLEND_OP_REV_SUBTRACT: 4547ec681f3Smrg return PIPE_BLEND_REVERSE_SUBTRACT; 4557ec681f3Smrg case D3D10_DDI_BLEND_OP_MIN: 4567ec681f3Smrg return PIPE_BLEND_MIN; 4577ec681f3Smrg case D3D10_DDI_BLEND_OP_MAX: 4587ec681f3Smrg return PIPE_BLEND_MAX; 4597ec681f3Smrg default: 4607ec681f3Smrg assert(0); 4617ec681f3Smrg return PIPE_BLEND_ADD; 4627ec681f3Smrg } 4637ec681f3Smrg} 4647ec681f3Smrg 4657ec681f3Smrg 4667ec681f3Smrg/* 4677ec681f3Smrg * ---------------------------------------------------------------------- 4687ec681f3Smrg * 4697ec681f3Smrg * translateBlend -- 4707ec681f3Smrg * 4717ec681f3Smrg * Translate blend factor from svga3d to gallium representation. 4727ec681f3Smrg * 4737ec681f3Smrg * ---------------------------------------------------------------------- 4747ec681f3Smrg */ 4757ec681f3Smrgstatic uint 4767ec681f3SmrgtranslateBlend(Device *pDevice, 4777ec681f3Smrg D3D10_DDI_BLEND blend) 4787ec681f3Smrg{ 4797ec681f3Smrg if (!pDevice->max_dual_source_render_targets) { 4807ec681f3Smrg switch (blend) { 4817ec681f3Smrg case D3D10_DDI_BLEND_SRC1_COLOR: 4827ec681f3Smrg case D3D10_DDI_BLEND_SRC1_ALPHA: 4837ec681f3Smrg LOG_UNSUPPORTED(TRUE); 4847ec681f3Smrg return D3D10_DDI_BLEND_ZERO; 4857ec681f3Smrg case D3D10_DDI_BLEND_INV_SRC1_COLOR: 4867ec681f3Smrg case D3D10_DDI_BLEND_INV_SRC1_ALPHA: 4877ec681f3Smrg LOG_UNSUPPORTED(TRUE); 4887ec681f3Smrg return D3D10_DDI_BLEND_ONE; 4897ec681f3Smrg default: 4907ec681f3Smrg break; 4917ec681f3Smrg } 4927ec681f3Smrg } 4937ec681f3Smrg 4947ec681f3Smrg switch (blend) { 4957ec681f3Smrg case D3D10_DDI_BLEND_ZERO: 4967ec681f3Smrg return PIPE_BLENDFACTOR_ZERO; 4977ec681f3Smrg case D3D10_DDI_BLEND_ONE: 4987ec681f3Smrg return PIPE_BLENDFACTOR_ONE; 4997ec681f3Smrg case D3D10_DDI_BLEND_SRC_COLOR: 5007ec681f3Smrg return PIPE_BLENDFACTOR_SRC_COLOR; 5017ec681f3Smrg case D3D10_DDI_BLEND_INV_SRC_COLOR: 5027ec681f3Smrg return PIPE_BLENDFACTOR_INV_SRC_COLOR; 5037ec681f3Smrg case D3D10_DDI_BLEND_SRC_ALPHA: 5047ec681f3Smrg return PIPE_BLENDFACTOR_SRC_ALPHA; 5057ec681f3Smrg case D3D10_DDI_BLEND_INV_SRC_ALPHA: 5067ec681f3Smrg return PIPE_BLENDFACTOR_INV_SRC_ALPHA; 5077ec681f3Smrg case D3D10_DDI_BLEND_DEST_ALPHA: 5087ec681f3Smrg return PIPE_BLENDFACTOR_DST_ALPHA; 5097ec681f3Smrg case D3D10_DDI_BLEND_INV_DEST_ALPHA: 5107ec681f3Smrg return PIPE_BLENDFACTOR_INV_DST_ALPHA; 5117ec681f3Smrg case D3D10_DDI_BLEND_DEST_COLOR: 5127ec681f3Smrg return PIPE_BLENDFACTOR_DST_COLOR; 5137ec681f3Smrg case D3D10_DDI_BLEND_INV_DEST_COLOR: 5147ec681f3Smrg return PIPE_BLENDFACTOR_INV_DST_COLOR; 5157ec681f3Smrg case D3D10_DDI_BLEND_SRC_ALPHASAT: 5167ec681f3Smrg return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE; 5177ec681f3Smrg case D3D10_DDI_BLEND_BLEND_FACTOR: 5187ec681f3Smrg return PIPE_BLENDFACTOR_CONST_COLOR; 5197ec681f3Smrg case D3D10_DDI_BLEND_INVBLEND_FACTOR: 5207ec681f3Smrg return PIPE_BLENDFACTOR_INV_CONST_COLOR; 5217ec681f3Smrg case D3D10_DDI_BLEND_SRC1_COLOR: 5227ec681f3Smrg return PIPE_BLENDFACTOR_SRC1_COLOR; 5237ec681f3Smrg case D3D10_DDI_BLEND_INV_SRC1_COLOR: 5247ec681f3Smrg return PIPE_BLENDFACTOR_INV_SRC1_COLOR; 5257ec681f3Smrg case D3D10_DDI_BLEND_SRC1_ALPHA: 5267ec681f3Smrg return PIPE_BLENDFACTOR_SRC1_ALPHA; 5277ec681f3Smrg case D3D10_DDI_BLEND_INV_SRC1_ALPHA: 5287ec681f3Smrg return PIPE_BLENDFACTOR_INV_SRC1_ALPHA; 5297ec681f3Smrg default: 5307ec681f3Smrg assert(0); 5317ec681f3Smrg return PIPE_BLENDFACTOR_ONE; 5327ec681f3Smrg } 5337ec681f3Smrg} 5347ec681f3Smrg 5357ec681f3Smrg 5367ec681f3Smrg/* 5377ec681f3Smrg * ---------------------------------------------------------------------- 5387ec681f3Smrg * 5397ec681f3Smrg * CreateBlendState -- 5407ec681f3Smrg * 5417ec681f3Smrg * The CreateBlendState function creates a blend state. 5427ec681f3Smrg * 5437ec681f3Smrg * ---------------------------------------------------------------------- 5447ec681f3Smrg */ 5457ec681f3Smrg 5467ec681f3Smrgvoid APIENTRY 5477ec681f3SmrgCreateBlendState(D3D10DDI_HDEVICE hDevice, // IN 5487ec681f3Smrg __in const D3D10_DDI_BLEND_DESC *pBlendDesc, // IN 5497ec681f3Smrg D3D10DDI_HBLENDSTATE hBlendState, // IN 5507ec681f3Smrg D3D10DDI_HRTBLENDSTATE hRTBlendState) // IN 5517ec681f3Smrg{ 5527ec681f3Smrg unsigned i; 5537ec681f3Smrg 5547ec681f3Smrg LOG_ENTRYPOINT(); 5557ec681f3Smrg 5567ec681f3Smrg Device *pDevice = CastDevice(hDevice); 5577ec681f3Smrg struct pipe_context *pipe = pDevice->pipe; 5587ec681f3Smrg BlendState *pBlendState = CastBlendState(hBlendState); 5597ec681f3Smrg 5607ec681f3Smrg struct pipe_blend_state state; 5617ec681f3Smrg memset(&state, 0, sizeof state); 5627ec681f3Smrg 5637ec681f3Smrg for (i = 0; i < MIN2(PIPE_MAX_COLOR_BUFS, D3D10_DDI_SIMULTANEOUS_RENDER_TARGET_COUNT); ++i) { 5647ec681f3Smrg state.rt[i].blend_enable = pBlendDesc->BlendEnable[i]; 5657ec681f3Smrg state.rt[i].colormask = pBlendDesc->RenderTargetWriteMask[i]; 5667ec681f3Smrg 5677ec681f3Smrg if (pBlendDesc->BlendEnable[0] != pBlendDesc->BlendEnable[i] || 5687ec681f3Smrg pBlendDesc->RenderTargetWriteMask[0] != pBlendDesc->RenderTargetWriteMask[i]) { 5697ec681f3Smrg state.independent_blend_enable = 1; 5707ec681f3Smrg } 5717ec681f3Smrg } 5727ec681f3Smrg 5737ec681f3Smrg state.rt[0].rgb_func = translateBlendOp(pBlendDesc->BlendOp); 5747ec681f3Smrg if (pBlendDesc->BlendOp == D3D10_DDI_BLEND_OP_MIN || 5757ec681f3Smrg pBlendDesc->BlendOp == D3D10_DDI_BLEND_OP_MAX) { 5767ec681f3Smrg state.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; 5777ec681f3Smrg state.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; 5787ec681f3Smrg } else { 5797ec681f3Smrg state.rt[0].rgb_src_factor = translateBlend(pDevice, pBlendDesc->SrcBlend); 5807ec681f3Smrg state.rt[0].rgb_dst_factor = translateBlend(pDevice, pBlendDesc->DestBlend); 5817ec681f3Smrg } 5827ec681f3Smrg 5837ec681f3Smrg state.rt[0].alpha_func = translateBlendOp(pBlendDesc->BlendOpAlpha); 5847ec681f3Smrg if (pBlendDesc->BlendOpAlpha == D3D10_DDI_BLEND_OP_MIN || 5857ec681f3Smrg pBlendDesc->BlendOpAlpha == D3D10_DDI_BLEND_OP_MAX) { 5867ec681f3Smrg state.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; 5877ec681f3Smrg state.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; 5887ec681f3Smrg } else { 5897ec681f3Smrg state.rt[0].alpha_src_factor = translateBlend(pDevice, pBlendDesc->SrcBlendAlpha); 5907ec681f3Smrg state.rt[0].alpha_dst_factor = translateBlend(pDevice, pBlendDesc->DestBlendAlpha); 5917ec681f3Smrg } 5927ec681f3Smrg 5937ec681f3Smrg /* 5947ec681f3Smrg * Propagate to all the other rendertargets 5957ec681f3Smrg */ 5967ec681f3Smrg for (i = 1; i < MIN2(PIPE_MAX_COLOR_BUFS, D3D10_DDI_SIMULTANEOUS_RENDER_TARGET_COUNT); ++i) { 5977ec681f3Smrg state.rt[i].rgb_func = state.rt[0].rgb_func; 5987ec681f3Smrg state.rt[i].rgb_src_factor = state.rt[0].rgb_src_factor; 5997ec681f3Smrg state.rt[i].rgb_dst_factor = state.rt[0].rgb_dst_factor; 6007ec681f3Smrg state.rt[i].alpha_func = state.rt[0].alpha_func; 6017ec681f3Smrg state.rt[i].alpha_src_factor = state.rt[0].alpha_src_factor; 6027ec681f3Smrg state.rt[i].alpha_dst_factor = state.rt[0].alpha_dst_factor; 6037ec681f3Smrg } 6047ec681f3Smrg 6057ec681f3Smrg state.alpha_to_coverage = pBlendDesc->AlphaToCoverageEnable; 6067ec681f3Smrg 6077ec681f3Smrg pBlendState->handle = pipe->create_blend_state(pipe, &state); 6087ec681f3Smrg} 6097ec681f3Smrg 6107ec681f3Smrg 6117ec681f3Smrg/* 6127ec681f3Smrg * ---------------------------------------------------------------------- 6137ec681f3Smrg * 6147ec681f3Smrg * CreateBlendState1 -- 6157ec681f3Smrg * 6167ec681f3Smrg * The CreateBlendState function creates a blend state. 6177ec681f3Smrg * 6187ec681f3Smrg * ---------------------------------------------------------------------- 6197ec681f3Smrg */ 6207ec681f3Smrg 6217ec681f3Smrgvoid APIENTRY 6227ec681f3SmrgCreateBlendState1(D3D10DDI_HDEVICE hDevice, // IN 6237ec681f3Smrg __in const D3D10_1_DDI_BLEND_DESC *pBlendDesc, // IN 6247ec681f3Smrg D3D10DDI_HBLENDSTATE hBlendState, // IN 6257ec681f3Smrg D3D10DDI_HRTBLENDSTATE hRTBlendState) // IN 6267ec681f3Smrg{ 6277ec681f3Smrg unsigned i; 6287ec681f3Smrg 6297ec681f3Smrg LOG_ENTRYPOINT(); 6307ec681f3Smrg 6317ec681f3Smrg Device *pDevice = CastDevice(hDevice); 6327ec681f3Smrg struct pipe_context *pipe = pDevice->pipe; 6337ec681f3Smrg BlendState *pBlendState = CastBlendState(hBlendState); 6347ec681f3Smrg 6357ec681f3Smrg struct pipe_blend_state state; 6367ec681f3Smrg memset(&state, 0, sizeof state); 6377ec681f3Smrg 6387ec681f3Smrg state.alpha_to_coverage = pBlendDesc->AlphaToCoverageEnable; 6397ec681f3Smrg state.independent_blend_enable = pBlendDesc->IndependentBlendEnable; 6407ec681f3Smrg 6417ec681f3Smrg for (i = 0; i < MIN2(PIPE_MAX_COLOR_BUFS, D3D10_DDI_SIMULTANEOUS_RENDER_TARGET_COUNT); ++i) { 6427ec681f3Smrg state.rt[i].blend_enable = pBlendDesc->RenderTarget[i].BlendEnable; 6437ec681f3Smrg state.rt[i].colormask = pBlendDesc->RenderTarget[i].RenderTargetWriteMask; 6447ec681f3Smrg 6457ec681f3Smrg state.rt[i].rgb_func = translateBlendOp(pBlendDesc->RenderTarget[i].BlendOp); 6467ec681f3Smrg if (pBlendDesc->RenderTarget[i].BlendOp == D3D10_DDI_BLEND_OP_MIN || 6477ec681f3Smrg pBlendDesc->RenderTarget[i].BlendOp == D3D10_DDI_BLEND_OP_MAX) { 6487ec681f3Smrg state.rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE; 6497ec681f3Smrg state.rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; 6507ec681f3Smrg } else { 6517ec681f3Smrg state.rt[i].rgb_src_factor = translateBlend(pDevice, pBlendDesc->RenderTarget[i].SrcBlend); 6527ec681f3Smrg state.rt[i].rgb_dst_factor = translateBlend(pDevice, pBlendDesc->RenderTarget[i].DestBlend); 6537ec681f3Smrg } 6547ec681f3Smrg 6557ec681f3Smrg state.rt[i].alpha_func = translateBlendOp(pBlendDesc->RenderTarget[i].BlendOpAlpha); 6567ec681f3Smrg if (pBlendDesc->RenderTarget[i].BlendOpAlpha == D3D10_DDI_BLEND_OP_MIN || 6577ec681f3Smrg pBlendDesc->RenderTarget[i].BlendOpAlpha == D3D10_DDI_BLEND_OP_MAX) { 6587ec681f3Smrg state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE; 6597ec681f3Smrg state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; 6607ec681f3Smrg } else { 6617ec681f3Smrg state.rt[i].alpha_src_factor = translateBlend(pDevice, pBlendDesc->RenderTarget[i].SrcBlendAlpha); 6627ec681f3Smrg state.rt[i].alpha_dst_factor = translateBlend(pDevice, pBlendDesc->RenderTarget[i].DestBlendAlpha); 6637ec681f3Smrg } 6647ec681f3Smrg } 6657ec681f3Smrg 6667ec681f3Smrg pBlendState->handle = pipe->create_blend_state(pipe, &state); 6677ec681f3Smrg} 6687ec681f3Smrg 6697ec681f3Smrg 6707ec681f3Smrg/* 6717ec681f3Smrg * ---------------------------------------------------------------------- 6727ec681f3Smrg * 6737ec681f3Smrg * DestroyBlendState -- 6747ec681f3Smrg * 6757ec681f3Smrg * The DestroyBlendState function destroys the specified blend 6767ec681f3Smrg * state object. The blend state object can be destoyed only if 6777ec681f3Smrg * it is not currently bound to a display device. 6787ec681f3Smrg * 6797ec681f3Smrg * ---------------------------------------------------------------------- 6807ec681f3Smrg */ 6817ec681f3Smrg 6827ec681f3Smrgvoid APIENTRY 6837ec681f3SmrgDestroyBlendState(D3D10DDI_HDEVICE hDevice, // IN 6847ec681f3Smrg D3D10DDI_HBLENDSTATE hBlendState) // IN 6857ec681f3Smrg{ 6867ec681f3Smrg LOG_ENTRYPOINT(); 6877ec681f3Smrg 6887ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 6897ec681f3Smrg BlendState *pBlendState = CastBlendState(hBlendState); 6907ec681f3Smrg 6917ec681f3Smrg pipe->delete_blend_state(pipe, pBlendState->handle); 6927ec681f3Smrg} 6937ec681f3Smrg 6947ec681f3Smrg 6957ec681f3Smrg/* 6967ec681f3Smrg * ---------------------------------------------------------------------- 6977ec681f3Smrg * 6987ec681f3Smrg * SetBlendState -- 6997ec681f3Smrg * 7007ec681f3Smrg * The SetBlendState function sets a blend state. 7017ec681f3Smrg * 7027ec681f3Smrg * ---------------------------------------------------------------------- 7037ec681f3Smrg */ 7047ec681f3Smrg 7057ec681f3Smrgvoid APIENTRY 7067ec681f3SmrgSetBlendState(D3D10DDI_HDEVICE hDevice, // IN 7077ec681f3Smrg D3D10DDI_HBLENDSTATE hState, // IN 7087ec681f3Smrg const FLOAT pBlendFactor[4], // IN 7097ec681f3Smrg UINT SampleMask) // IN 7107ec681f3Smrg{ 7117ec681f3Smrg LOG_ENTRYPOINT(); 7127ec681f3Smrg 7137ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 7147ec681f3Smrg void *state = CastPipeBlendState(hState); 7157ec681f3Smrg 7167ec681f3Smrg pipe->bind_blend_state(pipe, state); 7177ec681f3Smrg 7187ec681f3Smrg struct pipe_blend_color color; 7197ec681f3Smrg color.color[0] = pBlendFactor[0]; 7207ec681f3Smrg color.color[1] = pBlendFactor[1]; 7217ec681f3Smrg color.color[2] = pBlendFactor[2]; 7227ec681f3Smrg color.color[3] = pBlendFactor[3]; 7237ec681f3Smrg 7247ec681f3Smrg pipe->set_blend_color(pipe, &color); 7257ec681f3Smrg 7267ec681f3Smrg pipe->set_sample_mask(pipe, SampleMask); 7277ec681f3Smrg} 7287ec681f3Smrg 7297ec681f3Smrg 7307ec681f3Smrg/* 7317ec681f3Smrg * ---------------------------------------------------------------------- 7327ec681f3Smrg * 7337ec681f3Smrg * SetRenderTargets -- 7347ec681f3Smrg * 7357ec681f3Smrg * Set the rendertargets. 7367ec681f3Smrg * 7377ec681f3Smrg * ---------------------------------------------------------------------- 7387ec681f3Smrg */ 7397ec681f3Smrg 7407ec681f3Smrgvoid APIENTRY 7417ec681f3SmrgSetRenderTargets(D3D10DDI_HDEVICE hDevice, // IN 7427ec681f3Smrg __in_ecount (NumViews) 7437ec681f3Smrg const D3D10DDI_HRENDERTARGETVIEW *phRenderTargetView, // IN 7447ec681f3Smrg UINT RTargets, // IN 7457ec681f3Smrg UINT ClearTargets, // IN 7467ec681f3Smrg D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView) // IN 7477ec681f3Smrg{ 7487ec681f3Smrg LOG_ENTRYPOINT(); 7497ec681f3Smrg 7507ec681f3Smrg Device *pDevice = CastDevice(hDevice); 7517ec681f3Smrg 7527ec681f3Smrg struct pipe_context *pipe = pDevice->pipe; 7537ec681f3Smrg 7547ec681f3Smrg pDevice->fb.nr_cbufs = 0; 7557ec681f3Smrg for (unsigned i = 0; i < RTargets; ++i) { 7567ec681f3Smrg pipe_surface_reference(&pDevice->fb.cbufs[i], 7577ec681f3Smrg CastPipeRenderTargetView(phRenderTargetView[i])); 7587ec681f3Smrg if (pDevice->fb.cbufs[i]) { 7597ec681f3Smrg pDevice->fb.nr_cbufs = i + 1; 7607ec681f3Smrg } 7617ec681f3Smrg } 7627ec681f3Smrg 7637ec681f3Smrg for (unsigned i = RTargets; i < PIPE_MAX_COLOR_BUFS; ++i) { 7647ec681f3Smrg pipe_surface_reference(&pDevice->fb.cbufs[i], NULL); 7657ec681f3Smrg } 7667ec681f3Smrg 7677ec681f3Smrg pipe_surface_reference(&pDevice->fb.zsbuf, 7687ec681f3Smrg CastPipeDepthStencilView(hDepthStencilView)); 7697ec681f3Smrg 7707ec681f3Smrg /* 7717ec681f3Smrg * Calculate the width/height fields for this framebuffer. D3D10 7727ec681f3Smrg * actually specifies that they be identical for all bound views. 7737ec681f3Smrg */ 7747ec681f3Smrg unsigned width, height; 7757ec681f3Smrg util_framebuffer_min_size(&pDevice->fb, &width, &height); 7767ec681f3Smrg pDevice->fb.width = width; 7777ec681f3Smrg pDevice->fb.height = height; 7787ec681f3Smrg 7797ec681f3Smrg pipe->set_framebuffer_state(pipe, &pDevice->fb); 7807ec681f3Smrg} 7817ec681f3Smrg 7827ec681f3Smrg 7837ec681f3Smrg/* 7847ec681f3Smrg * ---------------------------------------------------------------------- 7857ec681f3Smrg * 7867ec681f3Smrg * CalcPrivateDepthStencilStateSize -- 7877ec681f3Smrg * 7887ec681f3Smrg * The CalcPrivateDepthStencilStateSize function determines the size 7897ec681f3Smrg * of the user-mode display driver's private region of memory (that 7907ec681f3Smrg * is, the size of internal driver structures, not the size of the 7917ec681f3Smrg * resource video memory) for a depth stencil state. 7927ec681f3Smrg * 7937ec681f3Smrg * ---------------------------------------------------------------------- 7947ec681f3Smrg */ 7957ec681f3Smrg 7967ec681f3SmrgSIZE_T APIENTRY 7977ec681f3SmrgCalcPrivateDepthStencilStateSize( 7987ec681f3Smrg D3D10DDI_HDEVICE hDevice, // IN 7997ec681f3Smrg __in const D3D10_DDI_DEPTH_STENCIL_DESC *pDepthStencilDesc) // IN 8007ec681f3Smrg{ 8017ec681f3Smrg return sizeof(DepthStencilState); 8027ec681f3Smrg} 8037ec681f3Smrg 8047ec681f3Smrg 8057ec681f3Smrg/* 8067ec681f3Smrg * ---------------------------------------------------------------------- 8077ec681f3Smrg * 8087ec681f3Smrg * translateComparison -- 8097ec681f3Smrg * 8107ec681f3Smrg * Translate comparison function from DX10 to gallium representation. 8117ec681f3Smrg * 8127ec681f3Smrg * ---------------------------------------------------------------------- 8137ec681f3Smrg */ 8147ec681f3Smrgstatic uint 8157ec681f3SmrgtranslateComparison(D3D10_DDI_COMPARISON_FUNC Func) 8167ec681f3Smrg{ 8177ec681f3Smrg switch (Func) { 8187ec681f3Smrg case D3D10_DDI_COMPARISON_NEVER: 8197ec681f3Smrg return PIPE_FUNC_NEVER; 8207ec681f3Smrg case D3D10_DDI_COMPARISON_LESS: 8217ec681f3Smrg return PIPE_FUNC_LESS; 8227ec681f3Smrg case D3D10_DDI_COMPARISON_EQUAL: 8237ec681f3Smrg return PIPE_FUNC_EQUAL; 8247ec681f3Smrg case D3D10_DDI_COMPARISON_LESS_EQUAL: 8257ec681f3Smrg return PIPE_FUNC_LEQUAL; 8267ec681f3Smrg case D3D10_DDI_COMPARISON_GREATER: 8277ec681f3Smrg return PIPE_FUNC_GREATER; 8287ec681f3Smrg case D3D10_DDI_COMPARISON_NOT_EQUAL: 8297ec681f3Smrg return PIPE_FUNC_NOTEQUAL; 8307ec681f3Smrg case D3D10_DDI_COMPARISON_GREATER_EQUAL: 8317ec681f3Smrg return PIPE_FUNC_GEQUAL; 8327ec681f3Smrg case D3D10_DDI_COMPARISON_ALWAYS: 8337ec681f3Smrg return PIPE_FUNC_ALWAYS; 8347ec681f3Smrg default: 8357ec681f3Smrg assert(0); 8367ec681f3Smrg return PIPE_FUNC_ALWAYS; 8377ec681f3Smrg } 8387ec681f3Smrg} 8397ec681f3Smrg 8407ec681f3Smrg 8417ec681f3Smrg/* 8427ec681f3Smrg * ---------------------------------------------------------------------- 8437ec681f3Smrg * 8447ec681f3Smrg * translateStencilOp -- 8457ec681f3Smrg * 8467ec681f3Smrg * Translate stencil op from DX10 to gallium representation. 8477ec681f3Smrg * 8487ec681f3Smrg * ---------------------------------------------------------------------- 8497ec681f3Smrg */ 8507ec681f3Smrgstatic uint 8517ec681f3SmrgtranslateStencilOp(D3D10_DDI_STENCIL_OP StencilOp) 8527ec681f3Smrg{ 8537ec681f3Smrg switch (StencilOp) { 8547ec681f3Smrg case D3D10_DDI_STENCIL_OP_KEEP: 8557ec681f3Smrg return PIPE_STENCIL_OP_KEEP; 8567ec681f3Smrg case D3D10_DDI_STENCIL_OP_ZERO: 8577ec681f3Smrg return PIPE_STENCIL_OP_ZERO; 8587ec681f3Smrg case D3D10_DDI_STENCIL_OP_REPLACE: 8597ec681f3Smrg return PIPE_STENCIL_OP_REPLACE; 8607ec681f3Smrg case D3D10_DDI_STENCIL_OP_INCR_SAT: 8617ec681f3Smrg return PIPE_STENCIL_OP_INCR; 8627ec681f3Smrg case D3D10_DDI_STENCIL_OP_DECR_SAT: 8637ec681f3Smrg return PIPE_STENCIL_OP_DECR; 8647ec681f3Smrg case D3D10_DDI_STENCIL_OP_INVERT: 8657ec681f3Smrg return PIPE_STENCIL_OP_INVERT; 8667ec681f3Smrg case D3D10_DDI_STENCIL_OP_INCR: 8677ec681f3Smrg return PIPE_STENCIL_OP_INCR_WRAP; 8687ec681f3Smrg case D3D10_DDI_STENCIL_OP_DECR: 8697ec681f3Smrg return PIPE_STENCIL_OP_DECR_WRAP; 8707ec681f3Smrg default: 8717ec681f3Smrg assert(0); 8727ec681f3Smrg return PIPE_STENCIL_OP_KEEP; 8737ec681f3Smrg } 8747ec681f3Smrg} 8757ec681f3Smrg 8767ec681f3Smrg 8777ec681f3Smrg/* 8787ec681f3Smrg * ---------------------------------------------------------------------- 8797ec681f3Smrg * 8807ec681f3Smrg * CreateDepthStencilState -- 8817ec681f3Smrg * 8827ec681f3Smrg * The CreateDepthStencilState function creates a depth stencil state. 8837ec681f3Smrg * 8847ec681f3Smrg * ---------------------------------------------------------------------- 8857ec681f3Smrg */ 8867ec681f3Smrg 8877ec681f3Smrgvoid APIENTRY 8887ec681f3SmrgCreateDepthStencilState( 8897ec681f3Smrg D3D10DDI_HDEVICE hDevice, // IN 8907ec681f3Smrg __in const D3D10_DDI_DEPTH_STENCIL_DESC *pDepthStencilDesc, // IN 8917ec681f3Smrg D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState, // IN 8927ec681f3Smrg D3D10DDI_HRTDEPTHSTENCILSTATE hRTDepthStencilState) // IN 8937ec681f3Smrg{ 8947ec681f3Smrg LOG_ENTRYPOINT(); 8957ec681f3Smrg 8967ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 8977ec681f3Smrg DepthStencilState *pDepthStencilState = CastDepthStencilState(hDepthStencilState); 8987ec681f3Smrg 8997ec681f3Smrg struct pipe_depth_stencil_alpha_state state; 9007ec681f3Smrg memset(&state, 0, sizeof state); 9017ec681f3Smrg 9027ec681f3Smrg /* Depth. */ 9037ec681f3Smrg state.depth_enabled = (pDepthStencilDesc->DepthEnable ? 1 : 0); 9047ec681f3Smrg state.depth_writemask = (pDepthStencilDesc->DepthWriteMask ? 1 : 0); 9057ec681f3Smrg state.depth_func = translateComparison(pDepthStencilDesc->DepthFunc); 9067ec681f3Smrg 9077ec681f3Smrg /* Stencil. */ 9087ec681f3Smrg if (pDepthStencilDesc->StencilEnable) { 9097ec681f3Smrg struct pipe_stencil_state *face0 = &state.stencil[0]; 9107ec681f3Smrg struct pipe_stencil_state *face1 = &state.stencil[1]; 9117ec681f3Smrg 9127ec681f3Smrg face0->enabled = 1; 9137ec681f3Smrg face0->func = translateComparison(pDepthStencilDesc->FrontFace.StencilFunc); 9147ec681f3Smrg face0->fail_op = translateStencilOp(pDepthStencilDesc->FrontFace.StencilFailOp); 9157ec681f3Smrg face0->zpass_op = translateStencilOp(pDepthStencilDesc->FrontFace.StencilPassOp); 9167ec681f3Smrg face0->zfail_op = translateStencilOp(pDepthStencilDesc->FrontFace.StencilDepthFailOp); 9177ec681f3Smrg face0->valuemask = pDepthStencilDesc->StencilReadMask; 9187ec681f3Smrg face0->writemask = pDepthStencilDesc->StencilWriteMask; 9197ec681f3Smrg 9207ec681f3Smrg face1->enabled = 1; 9217ec681f3Smrg face1->func = translateComparison(pDepthStencilDesc->BackFace.StencilFunc); 9227ec681f3Smrg face1->fail_op = translateStencilOp(pDepthStencilDesc->BackFace.StencilFailOp); 9237ec681f3Smrg face1->zpass_op = translateStencilOp(pDepthStencilDesc->BackFace.StencilPassOp); 9247ec681f3Smrg face1->zfail_op = translateStencilOp(pDepthStencilDesc->BackFace.StencilDepthFailOp); 9257ec681f3Smrg face1->valuemask = pDepthStencilDesc->StencilReadMask; 9267ec681f3Smrg face1->writemask = pDepthStencilDesc->StencilWriteMask; 9277ec681f3Smrg#ifdef DEBUG 9287ec681f3Smrg if (!pDepthStencilDesc->FrontEnable) { 9297ec681f3Smrg ASSERT(face0->func == PIPE_FUNC_ALWAYS); 9307ec681f3Smrg ASSERT(face0->fail_op == PIPE_STENCIL_OP_KEEP); 9317ec681f3Smrg ASSERT(face0->zpass_op == PIPE_STENCIL_OP_KEEP); 9327ec681f3Smrg ASSERT(face0->zfail_op == PIPE_STENCIL_OP_KEEP); 9337ec681f3Smrg } 9347ec681f3Smrg 9357ec681f3Smrg if (!pDepthStencilDesc->BackEnable) { 9367ec681f3Smrg ASSERT(face1->func == PIPE_FUNC_ALWAYS); 9377ec681f3Smrg ASSERT(face1->fail_op == PIPE_STENCIL_OP_KEEP); 9387ec681f3Smrg ASSERT(face1->zpass_op == PIPE_STENCIL_OP_KEEP); 9397ec681f3Smrg ASSERT(face1->zfail_op == PIPE_STENCIL_OP_KEEP); 9407ec681f3Smrg } 9417ec681f3Smrg#endif 9427ec681f3Smrg } 9437ec681f3Smrg 9447ec681f3Smrg pDepthStencilState->handle = 9457ec681f3Smrg pipe->create_depth_stencil_alpha_state(pipe, &state); 9467ec681f3Smrg} 9477ec681f3Smrg 9487ec681f3Smrg 9497ec681f3Smrg/* 9507ec681f3Smrg * ---------------------------------------------------------------------- 9517ec681f3Smrg * 9527ec681f3Smrg * DestroyDepthStencilState -- 9537ec681f3Smrg * 9547ec681f3Smrg * The CreateDepthStencilState function creates a depth stencil state. 9557ec681f3Smrg * 9567ec681f3Smrg * ---------------------------------------------------------------------- 9577ec681f3Smrg */ 9587ec681f3Smrg 9597ec681f3Smrgvoid APIENTRY 9607ec681f3SmrgDestroyDepthStencilState(D3D10DDI_HDEVICE hDevice, // IN 9617ec681f3Smrg D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState) // IN 9627ec681f3Smrg{ 9637ec681f3Smrg LOG_ENTRYPOINT(); 9647ec681f3Smrg 9657ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 9667ec681f3Smrg DepthStencilState *pDepthStencilState = CastDepthStencilState(hDepthStencilState); 9677ec681f3Smrg 9687ec681f3Smrg pipe->delete_depth_stencil_alpha_state(pipe, pDepthStencilState->handle); 9697ec681f3Smrg} 9707ec681f3Smrg 9717ec681f3Smrg 9727ec681f3Smrg/* 9737ec681f3Smrg * ---------------------------------------------------------------------- 9747ec681f3Smrg * 9757ec681f3Smrg * SetDepthStencilState -- 9767ec681f3Smrg * 9777ec681f3Smrg * The SetDepthStencilState function sets a depth-stencil state. 9787ec681f3Smrg * 9797ec681f3Smrg * ---------------------------------------------------------------------- 9807ec681f3Smrg */ 9817ec681f3Smrg 9827ec681f3Smrgvoid APIENTRY 9837ec681f3SmrgSetDepthStencilState(D3D10DDI_HDEVICE hDevice, // IN 9847ec681f3Smrg D3D10DDI_HDEPTHSTENCILSTATE hState, // IN 9857ec681f3Smrg UINT StencilRef) // IN 9867ec681f3Smrg{ 9877ec681f3Smrg LOG_ENTRYPOINT(); 9887ec681f3Smrg 9897ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 9907ec681f3Smrg void *state = CastPipeDepthStencilState(hState); 9917ec681f3Smrg struct pipe_stencil_ref psr; 9927ec681f3Smrg 9937ec681f3Smrg psr.ref_value[0] = StencilRef; 9947ec681f3Smrg psr.ref_value[1] = StencilRef; 9957ec681f3Smrg 9967ec681f3Smrg pipe->bind_depth_stencil_alpha_state(pipe, state); 9977ec681f3Smrg pipe->set_stencil_ref(pipe, psr); 9987ec681f3Smrg} 999