d3d10umd,d3d10sw: Initial import.

This change adds a gallium D3D10 state tracker that works as a WDDM UMD
software driver, similar to Microsoft WARP, but using llvmpipe/softpipe.

The final deliverable is a d3d10sw.dll, which is similar to WARP's
d3d10warp.dll.

This has been used to run Microsoft Windows HCK wgf11* tests with
llvmpipe, and they were at one point passing 100%.

Known limitations:
- TGSI (no NIR)
- D3D10 only (no D3D11 support yet)
- no WINE integration (WINE doesn't implement WDDM DDI.)

For further details see:
- src/gallium/frontends/d3d10umd/README.md
- src/gallium/targets/d3d10sw/README.md

v2: Drop the DXBC-based disassembly.  Add missing break statements.
v3: Incorporate Jesse's feedback.

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Acked-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10687>
This commit is contained in:
Jose Fonseca 2021-05-05 11:57:43 +01:00
parent 3927a2d946
commit 54b8137141
43 changed files with 12391 additions and 0 deletions

13
include/winddk/.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
d3d10tokenizedprogramformat.hpp
d3d10umddi.h
d3d11tokenizedprogramformat.hpp
d3dkmddi.h
d3dkmdt.h
d3dkmthk.h
d3dukmdt.h
d3dumddi.h
dxgiddi.h
dxgiformat.h
dxgitype.h
dxmini.h
wmidata.h

16
include/winddk/README.txt Normal file
View File

@ -0,0 +1,16 @@
The gallium d3d10umd statetracker depends upon the follow Windows DDK headers
being placed here:
d3d10tokenizedprogramformat.hpp
d3d10umddi.h
d3d11tokenizedprogramformat.hpp
d3dkmddi.h
d3dkmdt.h
d3dkmthk.h
d3dukmdt.h
d3dumddi.h
dxgiddi.h
dxgiformat.h
dxgitype.h
dxmini.h
wmidata.h

View File

@ -0,0 +1,236 @@
/**************************************************************************
*
* Copyright 2009 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 above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* 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 VMWARE 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.
*
**************************************************************************/
/**
* @file
* SDK/DDK compatability.
*
* Different headers/defines on different Windows SDKs / DDKs, so define
* all used status here to keep the code portable.
*
* @author <jfonseca@vmware.com>
*/
#ifndef VMW_WDDM_COMPAT_H_
#define VMW_WDDM_COMPAT_H_
#ifndef __in
#define __in /**/
#endif
#ifndef __out
#define __out /**/
#endif
#ifndef __inout
#define __inout /**/
#endif
#ifndef __in_opt
#define __in_opt /**/
#endif
#ifndef __inout_opt
#define __inout_opt /**/
#endif
#ifndef __ecount
#define __ecount(x) /**/
#endif
#ifndef __in_ecount
#define __in_ecount(x) /**/
#endif
#ifndef __deref_ecount
#define __deref_ecount(x) /**/
#endif
#ifndef __in_bcount
#define __in_bcount(x) /**/
#endif
#ifndef __out_bcount
#define __out_bcount(x) /**/
#endif
#ifndef __out_ecount_opt
#define __out_ecount_opt(x) /**/
#endif
#ifndef __deref_out
#define __deref_out /**/
#endif
#ifndef __in_range
#define __in_range(x,y) /**/
#endif
#ifndef __field_bcount
#define __field_bcount(x) /**/
#endif
#ifndef __out_bcount
#define __out_bcount(x) /**/
#endif
#ifndef __out_bcount_full_opt
#define __out_bcount_full_opt(x) /**/
#endif
#ifndef __out_ecount_part_z_opt
#define __out_ecount_part_z_opt(x, y) /**/
#endif
#ifndef __out_ecount_part_opt
#define __out_ecount_part_opt(x, y) /**/
#endif
#ifndef __field_ecount
#define __field_ecount(x) /**/
#endif
#ifndef __field_ecount_full
#define __field_ecount_full(x) /**/
#endif
#ifndef __checkReturn
#define __checkReturn /**/
#endif
#ifndef __drv_requiresIRQL
#define __drv_requiresIRQL(x) /**/
#endif
#ifndef __drv_minIRQL
#define __drv_minIRQL(x) /**/
#endif
#ifndef __drv_maxIRQL
#define __drv_maxIRQL(x) /**/
#endif
#ifdef __MINGW32__
#define __inline static __inline__
#endif
#ifndef EXTERN_C
#define EXTERN_C /**/
#endif
#ifdef __MINGW32__
typedef unsigned char UINT8;
#endif
#ifndef NTSTATUS
#define NTSTATUS LONG
#endif
typedef LARGE_INTEGER PHYSICAL_ADDRESS;
#ifndef NT_SUCCESS
#define NT_SUCCESS(_status) ((_status) >= 0)
#endif
#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif
#ifndef STATUS_UNSUCCESSFUL
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
#endif
#ifndef STATUS_INVALID_PARAMETER
#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL)
#endif
#ifndef STATUS_NO_MEMORY
#define STATUS_NO_MEMORY ((NTSTATUS)0xC0000017L)
#endif
#ifndef STATUS_ILLEGAL_INSTRUCTION
#define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS)0xC000001DL)
#endif
#ifndef STATUS_BUFFER_TOO_SMALL
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
#endif
#ifndef STATUS_PRIVILEGED_INSTRUCTION
#define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS)0xC0000096L)
#endif
#ifndef STATUS_NOT_SUPPORTED
#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL)
#endif
#ifndef STATUS_DEVICE_REMOVED
#define STATUS_DEVICE_REMOVED ((NTSTATUS)0xC00002B6L)
#endif
#ifndef STATUS_INVALID_USER_BUFFER
#define STATUS_INVALID_USER_BUFFER ((NTSTATUS)0xC00000E8L)
#endif
#ifndef STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER
#define STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER ((NTSTATUS)0xC01E0000L)
#endif
#ifndef STATUS_NO_VIDEO_MEMORY
#define STATUS_NO_VIDEO_MEMORY ((NTSTATUS)0xC01E0100L)
#endif
#ifndef STATUS_GRAPHICS_ALLOCATION_BUSY
#define STATUS_GRAPHICS_ALLOCATION_BUSY ((NTSTATUS)0xC01E0102L)
#endif
#ifndef STATUS_GRAPHICS_TOO_MANY_REFERENCES
#define STATUS_GRAPHICS_TOO_MANY_REFERENCES ((NTSTATUS)0xC01E0103L)
#endif
#ifndef STATUS_GRAPHICS_ALLOCATION_INVALID
#define STATUS_GRAPHICS_ALLOCATION_INVALID ((NTSTATUS)0xC01E0106L)
#endif
#ifndef STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION
#define STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION ((NTSTATUS)0xC01E0109L)
#endif
#ifndef STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION
#define STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION ((NTSTATUS)0xC01E0111L)
#endif
#ifndef STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE
#define STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE ((NTSTATUS)0xC01E0200L)
#endif
#ifndef STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET
#define STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET ((NTSTATUS)0xC01E0333L)
#endif
#endif /* VMW_WDDM_COMPAT_H_ */

View File

@ -787,6 +787,12 @@ if with_gallium_st_nine
error('Using nine with wine requires dri3')
endif
endif
with_gallium_st_d3d10umd = get_option('gallium-d3d10umd')
if with_gallium_st_d3d10umd
if not with_gallium_softpipe
error('The d3d10umd state tracker requires gallium softpipe/llvmpipe.')
endif
endif
_power8 = get_option('power8')
if _power8 == 'true'
_power8 = 'enabled'

View File

@ -142,6 +142,12 @@ option(
value : false,
description : 'build gallium "nine" Direct3D 9.x frontend.',
)
option(
'gallium-d3d10umd',
type : 'boolean',
value : false,
description : 'build gallium D3D10 WDDM UMD frontend.',
)
option(
'gallium-opencl',
type : 'combo',

View File

@ -0,0 +1,274 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Adpater.cpp --
* Driver entry point.
*/
#include "DriverIncludes.h"
#include "Device.h"
#include "State.h"
#include "Debug.h"
#include "util/u_memory.h"
EXTERN_C struct pipe_screen *
d3d10_create_screen(void);
static HRESULT APIENTRY CloseAdapter(D3D10DDI_HADAPTER hAdapter);
static unsigned long numAdapters = 0;
#if 0
static unsigned long memdbg_no = 0;
#endif
/*
* ----------------------------------------------------------------------
*
* OpenAdapterCommon --
*
* Common code for OpenAdapter10 and OpenAdapter10_2
*
* ----------------------------------------------------------------------
*/
static HRESULT
OpenAdapterCommon(__inout D3D10DDIARG_OPENADAPTER *pOpenData) // IN
{
#if 0
if (numAdapters == 0) {
memdbg_no = debug_memory_begin();
}
#endif
++numAdapters;
Adapter *pAdaptor = (Adapter *)calloc(sizeof *pAdaptor, 1);
if (!pAdaptor) {
--numAdapters;
return E_OUTOFMEMORY;
}
pAdaptor->screen = d3d10_create_screen();
if (!pAdaptor->screen) {
free(pAdaptor);
--numAdapters;
return E_OUTOFMEMORY;
}
pOpenData->hAdapter.pDrvPrivate = pAdaptor;
pOpenData->pAdapterFuncs->pfnCalcPrivateDeviceSize = CalcPrivateDeviceSize;
pOpenData->pAdapterFuncs->pfnCreateDevice = CreateDevice;
pOpenData->pAdapterFuncs->pfnCloseAdapter = CloseAdapter;
return S_OK;
}
/*
* ----------------------------------------------------------------------
*
* OpenAdapter10 --
*
* The OpenAdapter10 function creates a graphics adapter object
* that is referenced in subsequent calls.
*
* ----------------------------------------------------------------------
*/
EXTERN_C HRESULT APIENTRY
OpenAdapter10(__inout D3D10DDIARG_OPENADAPTER *pOpenData) // IN
{
LOG_ENTRYPOINT();
/*
* This is checked here and not on the common code because MSDN docs
* state that it should be ignored on OpenAdapter10_2.
*/
switch (pOpenData->Interface) {
case D3D10_0_DDI_INTERFACE_VERSION:
case D3D10_0_x_DDI_INTERFACE_VERSION:
case D3D10_0_7_DDI_INTERFACE_VERSION:
#if SUPPORT_D3D10_1
case D3D10_1_DDI_INTERFACE_VERSION:
case D3D10_1_x_DDI_INTERFACE_VERSION:
case D3D10_1_7_DDI_INTERFACE_VERSION:
#endif
#if SUPPORT_D3D11
case D3D11_0_DDI_INTERFACE_VERSION:
case D3D11_0_7_DDI_INTERFACE_VERSION:
#endif
break;
default:
if (0) {
DebugPrintf("%s: unsupported interface version 0x%08x\n",
__FUNCTION__, pOpenData->Interface);
}
return E_FAIL;
}
return OpenAdapterCommon(pOpenData);
}
static const UINT64
SupportedDDIInterfaceVersions[] = {
D3D10_0_DDI_SUPPORTED,
D3D10_0_x_DDI_SUPPORTED,
D3D10_0_7_DDI_SUPPORTED,
#if SUPPORT_D3D10_1
D3D10_1_DDI_SUPPORTED,
D3D10_1_x_DDI_SUPPORTED,
D3D10_1_7_DDI_SUPPORTED,
#endif
#if SUPPORT_D3D11
D3D11_0_DDI_SUPPORTED,
D3D11_0_7_DDI_SUPPORTED,
#endif
};
/*
* ----------------------------------------------------------------------
*
* GetSupportedVersions --
*
* Return a list of interface versions supported by the graphics
* adapter.
*
* ----------------------------------------------------------------------
*/
static HRESULT APIENTRY
GetSupportedVersions(D3D10DDI_HADAPTER hAdapter,
UINT32 *puEntries,
UINT64 *pSupportedDDIInterfaceVersions)
{
LOG_ENTRYPOINT();
if (pSupportedDDIInterfaceVersions &&
*puEntries < ARRAYSIZE(SupportedDDIInterfaceVersions)) {
return E_OUTOFMEMORY;
}
*puEntries = ARRAYSIZE(SupportedDDIInterfaceVersions);
if (pSupportedDDIInterfaceVersions) {
memcpy(pSupportedDDIInterfaceVersions,
SupportedDDIInterfaceVersions,
sizeof SupportedDDIInterfaceVersions);
}
return S_OK;
}
/*
* ----------------------------------------------------------------------
*
* GetCaps --
*
* Return the capabilities of the graphics adapter.
*
* ----------------------------------------------------------------------
*/
static HRESULT APIENTRY
GetCaps(D3D10DDI_HADAPTER hAdapter,
const D3D10_2DDIARG_GETCAPS *pData)
{
LOG_ENTRYPOINT();
memset(pData->pData, 0, pData->DataSize);
return S_OK;
}
/*
* ----------------------------------------------------------------------
*
* OpenAdapter10 --
*
* The OpenAdapter10 function creates a graphics adapter object
* that is referenced in subsequent calls.
*
* ----------------------------------------------------------------------
*/
EXTERN_C HRESULT APIENTRY
OpenAdapter10_2(__inout D3D10DDIARG_OPENADAPTER *pOpenData) // IN
{
LOG_ENTRYPOINT();
HRESULT hr = OpenAdapterCommon(pOpenData);
if (SUCCEEDED(hr)) {
pOpenData->pAdapterFuncs_2->pfnGetSupportedVersions = GetSupportedVersions;
pOpenData->pAdapterFuncs_2->pfnGetCaps = GetCaps;
}
return hr;
}
/*
* ----------------------------------------------------------------------
*
* CloseAdapter --
*
* The CloseAdapter function releases resources for a
* graphics adapter object.
*
* ----------------------------------------------------------------------
*/
HRESULT APIENTRY
CloseAdapter(D3D10DDI_HADAPTER hAdapter) // IN
{
LOG_ENTRYPOINT();
Adapter *pAdapter = CastAdapter(hAdapter);
struct pipe_screen *screen = pAdapter->screen;
screen->destroy(screen);
free(pAdapter);
--numAdapters;
#if 0
if (numAdapters == 0) {
debug_memory_end(memdbg_no);
}
#endif
return S_OK;
}

View File

@ -0,0 +1,728 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* D3DKMT.cpp --
* Implement kernel mode thunks, so that this can be loaded as a
* software DLL (D3D_DRIVER_TYPE_SOFTWARE).
*/
#include "DriverIncludes.h"
#include "Debug.h"
#ifndef STATUS_NOT_IMPLEMENTED
#define STATUS_NOT_IMPLEMENTED 0xC0000002
#endif
EXTERN_C NTSTATUS APIENTRY
D3DKMTCreateAllocation(D3DKMT_CREATEALLOCATION *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCreateAllocation2(D3DKMT_CREATEALLOCATION *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTQueryResourceInfo(D3DKMT_QUERYRESOURCEINFO *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTOpenResource(D3DKMT_OPENRESOURCE *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTOpenResource2(D3DKMT_OPENRESOURCE *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTDestroyAllocation(CONST D3DKMT_DESTROYALLOCATION *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSetAllocationPriority(CONST D3DKMT_SETALLOCATIONPRIORITY *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTQueryAllocationResidency(CONST D3DKMT_QUERYALLOCATIONRESIDENCY *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCreateDevice(D3DKMT_CREATEDEVICE *pData)
{
LOG_ENTRYPOINT();
pData->hDevice = 1;
return STATUS_SUCCESS;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTDestroyDevice(CONST D3DKMT_DESTROYDEVICE *pData)
{
LOG_ENTRYPOINT();
return STATUS_SUCCESS;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCreateContext(D3DKMT_CREATECONTEXT *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTDestroyContext(CONST D3DKMT_DESTROYCONTEXT *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCreateSynchronizationObject(D3DKMT_CREATESYNCHRONIZATIONOBJECT *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCreateSynchronizationObject2(D3DKMT_CREATESYNCHRONIZATIONOBJECT2 *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTOpenSynchronizationObject(D3DKMT_OPENSYNCHRONIZATIONOBJECT *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTDestroySynchronizationObject(CONST D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTWaitForSynchronizationObject(CONST D3DKMT_WAITFORSYNCHRONIZATIONOBJECT *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTWaitForSynchronizationObject2(CONST D3DKMT_WAITFORSYNCHRONIZATIONOBJECT2 *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSignalSynchronizationObject(CONST D3DKMT_SIGNALSYNCHRONIZATIONOBJECT *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSignalSynchronizationObject2(CONST D3DKMT_SIGNALSYNCHRONIZATIONOBJECT2 *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTLock(D3DKMT_LOCK *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTUnlock(CONST D3DKMT_UNLOCK *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTGetDisplayModeList(D3DKMT_GETDISPLAYMODELIST *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSetDisplayMode(CONST D3DKMT_SETDISPLAYMODE *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTGetMultisampleMethodList(D3DKMT_GETMULTISAMPLEMETHODLIST *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTPresent(CONST D3DKMT_PRESENT *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTRender(D3DKMT_RENDER *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTGetRuntimeData(CONST D3DKMT_GETRUNTIMEDATA *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTQueryAdapterInfo(CONST D3DKMT_QUERYADAPTERINFO *pData)
{
LOG_ENTRYPOINT();
switch (pData->Type) {
case KMTQAITYPE_UMDRIVERNAME:
{
D3DKMT_UMDFILENAMEINFO *pResult =
(D3DKMT_UMDFILENAMEINFO *)pData->pPrivateDriverData;
if (pResult->Version != KMTUMDVERSION_DX10 &&
pResult->Version != KMTUMDVERSION_DX11) {
DebugPrintf("%s: unsupported UMD version (%u)\n",
__FUNCTION__, pResult->Version);
return STATUS_INVALID_PARAMETER;
}
HMODULE hModule = 0;
BOOL bRet;
DWORD dwRet;
bRet = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)D3DKMTQueryAdapterInfo,
&hModule);
assert(bRet);
dwRet = GetModuleFileNameW(hModule, pResult->UmdFileName, MAX_PATH);
assert(dwRet);
return STATUS_SUCCESS;
}
break;
case KMTQAITYPE_GETSEGMENTSIZE:
{
D3DKMT_SEGMENTSIZEINFO *pResult =
(D3DKMT_SEGMENTSIZEINFO *)pData->pPrivateDriverData;
pResult->DedicatedVideoMemorySize = 0;
pResult->DedicatedSystemMemorySize = 0;
pResult->SharedSystemMemorySize = 3ULL*1024ULL*1024ULL*1024ULL;
return STATUS_SUCCESS;
}
break;
case KMTQAITYPE_CHECKDRIVERUPDATESTATUS:
{
BOOL *pResult = (BOOL *)pData->pPrivateDriverData;
*pResult = FALSE;
return STATUS_SUCCESS;
}
case KMTQAITYPE_DRIVERVERSION:
{
D3DKMT_DRIVERVERSION *pResult = (D3DKMT_DRIVERVERSION *)pData->pPrivateDriverData;
*pResult = KMT_DRIVERVERSION_WDDM_1_0;
return STATUS_SUCCESS;
}
case KMTQAITYPE_XBOX:
{
BOOL *pResult = (BOOL *)pData->pPrivateDriverData;
*pResult = FALSE;
return STATUS_SUCCESS;
}
case KMTQAITYPE_PHYSICALADAPTERCOUNT:
{
UINT *pResult = (UINT *)pData->pPrivateDriverData;
*pResult = 1;
return STATUS_SUCCESS;
}
case KMTQAITYPE_PHYSICALADAPTERDEVICEIDS:
ZeroMemory(pData->pPrivateDriverData, pData->PrivateDriverDataSize);
return STATUS_SUCCESS;
default:
DebugPrintf("%s: unsupported query type (Type=%u, PrivateDriverDataSize=%u)\n",
__FUNCTION__, pData->Type, pData->PrivateDriverDataSize);
ZeroMemory(pData->pPrivateDriverData, pData->PrivateDriverDataSize);
return STATUS_NOT_IMPLEMENTED;
}
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTOpenAdapterFromHdc(D3DKMT_OPENADAPTERFROMHDC *pData)
{
LOG_ENTRYPOINT();
pData->hAdapter = 1;
pData->AdapterLuid.LowPart = 0;
pData->AdapterLuid.HighPart = 0;
pData->VidPnSourceId = 1;
return STATUS_SUCCESS;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTOpenAdapterFromGdiDisplayName(D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME *pData)
{
LOG_ENTRYPOINT();
pData->hAdapter = 1;
pData->AdapterLuid.LowPart = 0;
pData->AdapterLuid.HighPart = 0;
pData->VidPnSourceId = 1;
return STATUS_SUCCESS;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTOpenAdapterFromDeviceName(D3DKMT_OPENADAPTERFROMDEVICENAME *pData)
{
LOG_ENTRYPOINT();
pData->hAdapter = 1;
pData->AdapterLuid.LowPart = 0;
pData->AdapterLuid.HighPart = 0;
return STATUS_SUCCESS;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCloseAdapter(CONST D3DKMT_CLOSEADAPTER *pData)
{
LOG_ENTRYPOINT();
return STATUS_SUCCESS;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTGetSharedPrimaryHandle(D3DKMT_GETSHAREDPRIMARYHANDLE *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTEscape(CONST D3DKMT_ESCAPE *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSetVidPnSourceOwner(CONST D3DKMT_SETVIDPNSOURCEOWNER *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSetVidPnSourceOwner1(const void *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTGetPresentHistory(D3DKMT_GETPRESENTHISTORY *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTGetPresentQueueEvent(D3DKMT_HANDLE hAdapter, HANDLE *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCreateOverlay(D3DKMT_CREATEOVERLAY *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTUpdateOverlay(CONST D3DKMT_UPDATEOVERLAY *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTFlipOverlay(CONST D3DKMT_FLIPOVERLAY *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTDestroyOverlay(CONST D3DKMT_DESTROYOVERLAY *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTWaitForVerticalBlankEvent(CONST D3DKMT_WAITFORVERTICALBLANKEVENT *pData)
{
LOG_ENTRYPOINT();
return STATUS_SUCCESS;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSetGammaRamp(CONST D3DKMT_SETGAMMARAMP *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTGetDeviceState(D3DKMT_GETDEVICESTATE *pData)
{
LOG_ENTRYPOINT();
switch (pData->StateType) {
case D3DKMT_DEVICESTATE_EXECUTION:
pData->ExecutionState = D3DKMT_DEVICEEXECUTION_ACTIVE;
return STATUS_SUCCESS;
case D3DKMT_DEVICESTATE_PRESENT:
pData->PresentState.PresentStats.PresentCount = 0;
pData->PresentState.PresentStats.PresentRefreshCount = 0;
pData->PresentState.PresentStats.SyncRefreshCount = 0;
pData->PresentState.PresentStats.SyncQPCTime.QuadPart = 0;
pData->PresentState.PresentStats.SyncGPUTime.QuadPart = 0;
return STATUS_SUCCESS;
case D3DKMT_DEVICESTATE_RESET:
pData->ResetState.Value = 0;
return STATUS_SUCCESS;
default:
return STATUS_INVALID_PARAMETER;
}
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCreateDCFromMemory(D3DKMT_CREATEDCFROMMEMORY *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTDestroyDCFromMemory(CONST D3DKMT_DESTROYDCFROMMEMORY *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSetContextSchedulingPriority(CONST D3DKMT_SETCONTEXTSCHEDULINGPRIORITY *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTGetContextSchedulingPriority(D3DKMT_GETCONTEXTSCHEDULINGPRIORITY *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSetProcessSchedulingPriorityClass(HANDLE hProcess, D3DKMT_SCHEDULINGPRIORITYCLASS Priority)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTGetProcessSchedulingPriorityClass(HANDLE hProcess, D3DKMT_SCHEDULINGPRIORITYCLASS *pPriority)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTReleaseProcessVidPnSourceOwners(HANDLE hProcess)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTGetScanLine(D3DKMT_GETSCANLINE *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTChangeSurfacePointer(CONST D3DKMT_CHANGESURFACEPOINTER *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSetQueuedLimit(CONST D3DKMT_SETQUEUEDLIMIT *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTPollDisplayChildren(CONST D3DKMT_POLLDISPLAYCHILDREN *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTInvalidateActiveVidPn(CONST D3DKMT_INVALIDATEACTIVEVIDPN *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCheckOcclusion(CONST D3DKMT_CHECKOCCLUSION *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTWaitForIdle(CONST D3DKMT_WAITFORIDLE *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCheckMonitorPowerState(CONST D3DKMT_CHECKMONITORPOWERSTATE *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C BOOLEAN APIENTRY
D3DKMTCheckExclusiveOwnership(VOID)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return FALSE;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCheckVidPnExclusiveOwnership(CONST D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSetDisplayPrivateDriverFormat(CONST D3DKMT_SETDISPLAYPRIVATEDRIVERFORMAT *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSharedPrimaryLockNotification(CONST D3DKMT_SHAREDPRIMARYLOCKNOTIFICATION *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTSharedPrimaryUnLockNotification(CONST D3DKMT_SHAREDPRIMARYUNLOCKNOTIFICATION *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCreateKeyedMutex(D3DKMT_CREATEKEYEDMUTEX *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTOpenKeyedMutex(D3DKMT_OPENKEYEDMUTEX *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTDestroyKeyedMutex(CONST D3DKMT_DESTROYKEYEDMUTEX *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTAcquireKeyedMutex(D3DKMT_ACQUIREKEYEDMUTEX *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTReleaseKeyedMutex(D3DKMT_RELEASEKEYEDMUTEX *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTConfigureSharedResource(CONST D3DKMT_CONFIGURESHAREDRESOURCE *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTGetOverlayState(D3DKMT_GETOVERLAYSTATE *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}
EXTERN_C NTSTATUS APIENTRY
D3DKMTCheckSharedResourceAccess(CONST D3DKMT_CHECKSHAREDRESOURCEACCESS *pData)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return STATUS_NOT_IMPLEMENTED;
}

View File

@ -0,0 +1,81 @@
#include "Debug.h"
#include <stdarg.h>
#include <stdio.h>
#ifdef DEBUG
unsigned st_debug = 0;
static const
struct debug_named_value st_debug_flags[] = {
{"oldtexops", ST_DEBUG_OLD_TEX_OPS, "oldtexops"},
{"tgsi", ST_DEBUG_TGSI, "tgsi"},
{NULL, 0, NULL},
};
void
st_debug_parse(void)
{
st_debug = debug_get_flags_option("ST_DEBUG", st_debug_flags, st_debug);
}
#endif
void
DebugPrintf(const char *format, ...)
{
char buf[4096];
va_list ap;
va_start(ap, format);
vsnprintf(buf, sizeof buf, format, ap);
va_end(ap);
OutputDebugStringA(buf);
}
/**
* Produce a human readable message from HRESULT.
*
* @sa http://msdn.microsoft.com/en-us/library/ms679351(VS.85).aspx
*/
void
CheckHResult(HRESULT hr, const char *function, unsigned line)
{
if (FAILED(hr)) {
LPSTR lpMessageBuffer = NULL;
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
hr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&lpMessageBuffer,
0,
NULL);
DebugPrintf("%s: %u: 0x%08lX: %s", function, line, hr, lpMessageBuffer);
LocalFree(lpMessageBuffer);
}
}
void
AssertFail(const char *expr,
const char *file,
unsigned line,
const char *function)
{
DebugPrintf("%s:%u:%s: Assertion `%s' failed.\n", file, line, function, expr);
#if defined(__GNUC__)
__asm("int3");
#elif defined(_MSC_VER)
__debugbreak();
#else
DebugBreak();
#endif
}

View File

@ -0,0 +1,72 @@
#pragma once
#include "DriverIncludes.h"
#include "util/u_debug.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ST_DEBUG_OLD_TEX_OPS (1 << 0)
#define ST_DEBUG_TGSI (1 << 1)
#ifdef DEBUG
extern unsigned st_debug;
#else
#define st_debug 0
#endif
#ifdef DEBUG
void st_debug_parse(void);
#else
#define st_debug_parse() ((void)0)
#endif
void
DebugPrintf(const char *format, ...);
void
CheckHResult(HRESULT hr, const char *function, unsigned line);
#define CHECK_NTSTATUS(status) \
CheckNTStatus(status, __FUNCTION__, __LINE__)
#define CHECK_HRESULT(hr) \
CheckHResult(hr, __FUNCTION__, __LINE__)
void
AssertFail(const char *expr, const char *file, unsigned line, const char *function);
#ifndef NDEBUG
#define ASSERT(expr) ((expr) ? (void)0 : AssertFail(#expr, __FILE__, __LINE__, __FUNCTION__))
#else
#define ASSERT(expr) do { } while (0 && (expr))
#endif
#if 0 && !defined(NDEBUG)
#define LOG_ENTRYPOINT() DebugPrintf("%s\n", __FUNCTION__)
#else
#define LOG_ENTRYPOINT() (void)0
#endif
#define LOG_UNSUPPORTED_ENTRYPOINT() DebugPrintf("%s XXX\n", __FUNCTION__)
#define LOG_UNSUPPORTED(expr) \
do { if (expr) DebugPrintf("%s:%d XXX %s\n", __FUNCTION__, __LINE__, #expr); } while(0)
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,725 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Device.cpp --
* Functions that provide the 3D device functionality.
*/
#include "Draw.h"
#include "Dxgi.h"
#include "InputAssembly.h"
#include "OutputMerger.h"
#include "Query.h"
#include "Rasterizer.h"
#include "Resource.h"
#include "Shader.h"
#include "State.h"
#include "Format.h"
#include "Debug.h"
#include "util/u_sampler.h"
static void APIENTRY DestroyDevice(D3D10DDI_HDEVICE hDevice);
static void APIENTRY RelocateDeviceFuncs(D3D10DDI_HDEVICE hDevice,
__in struct D3D10DDI_DEVICEFUNCS *pDeviceFunctions);
static void APIENTRY RelocateDeviceFuncs1(D3D10DDI_HDEVICE hDevice,
__in struct D3D10_1DDI_DEVICEFUNCS *pDeviceFunctions);
static void APIENTRY Flush(D3D10DDI_HDEVICE hDevice);
static void APIENTRY CheckFormatSupport(D3D10DDI_HDEVICE hDevice, DXGI_FORMAT Format,
__out UINT *pFormatCaps);
static void APIENTRY CheckMultisampleQualityLevels(D3D10DDI_HDEVICE hDevice,
DXGI_FORMAT Format,
UINT SampleCount,
__out UINT *pNumQualityLevels);
static void APIENTRY SetTextFilterSize(D3D10DDI_HDEVICE hDevice, UINT Width, UINT Height);
/*
* ----------------------------------------------------------------------
*
* CalcPrivateDeviceSize --
*
* The CalcPrivateDeviceSize function determines the size of a memory
* region that the user-mode display driver requires from the Microsoft
* Direct3D runtime to store frequently-accessed data.
*
* ----------------------------------------------------------------------
*/
SIZE_T APIENTRY
CalcPrivateDeviceSize(D3D10DDI_HADAPTER hAdapter, // IN
__in const D3D10DDIARG_CALCPRIVATEDEVICESIZE *pData) // IN
{
return sizeof(Device);
}
/*
* ----------------------------------------------------------------------
*
* CreateDevice --
*
* The CreateDevice function creates a graphics context that is
* referenced in subsequent calls.
*
* ----------------------------------------------------------------------
*/
HRESULT APIENTRY
CreateDevice(D3D10DDI_HADAPTER hAdapter, // IN
__in D3D10DDIARG_CREATEDEVICE *pCreateData) // IN
{
LOG_ENTRYPOINT();
if (0) {
DebugPrintf("hAdapter = %p\n", hAdapter);
DebugPrintf("pKTCallbacks = %p\n", pCreateData->pKTCallbacks);
DebugPrintf("p10_1DeviceFuncs = %p\n", pCreateData->p10_1DeviceFuncs);
DebugPrintf("hDrvDevice = %p\n", pCreateData->hDrvDevice);
DebugPrintf("DXGIBaseDDI = %p\n", pCreateData->DXGIBaseDDI);
DebugPrintf("hRTCoreLayer = %p\n", pCreateData->hRTCoreLayer);
DebugPrintf("pUMCallbacks = %p\n", pCreateData->pUMCallbacks);
}
switch (pCreateData->Interface) {
case D3D10_0_DDI_INTERFACE_VERSION:
case D3D10_0_x_DDI_INTERFACE_VERSION:
case D3D10_0_7_DDI_INTERFACE_VERSION:
#if SUPPORT_D3D10_1
case D3D10_1_DDI_INTERFACE_VERSION:
case D3D10_1_x_DDI_INTERFACE_VERSION:
case D3D10_1_7_DDI_INTERFACE_VERSION:
#endif
break;
default:
DebugPrintf("%s: unsupported interface version 0x%08x\n",
__FUNCTION__, pCreateData->Interface);
return E_FAIL;
}
Adapter *pAdapter = CastAdapter(hAdapter);
Device *pDevice = CastDevice(pCreateData->hDrvDevice);
memset(pDevice, 0, sizeof *pDevice);
struct pipe_screen *screen = pAdapter->screen;
struct pipe_context *pipe = screen->context_create(screen, NULL, 0);
pDevice->pipe = pipe;
pDevice->empty_vs = CreateEmptyShader(pDevice, PIPE_SHADER_VERTEX);
pDevice->empty_fs = CreateEmptyShader(pDevice, PIPE_SHADER_FRAGMENT);
pipe->bind_vs_state(pipe, pDevice->empty_vs);
pipe->bind_fs_state(pipe, pDevice->empty_fs);
pDevice->max_dual_source_render_targets =
screen->get_param(screen, PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS);
pDevice->hRTCoreLayer = pCreateData->hRTCoreLayer;
pDevice->hDevice = (HANDLE)pCreateData->hRTDevice.handle;
pDevice->KTCallbacks = *pCreateData->pKTCallbacks;
pDevice->UMCallbacks = *pCreateData->pUMCallbacks;
pDevice->pDXGIBaseCallbacks = pCreateData->DXGIBaseDDI.pDXGIBaseCallbacks;
pDevice->draw_so_target = NULL;
if (0) {
DebugPrintf("pDevice = %p\n", pDevice);
}
st_debug_parse();
/*
* Fill in the D3D10 DDI functions
*/
switch (pCreateData->Interface) {
case D3D10_0_DDI_INTERFACE_VERSION:
case D3D10_0_x_DDI_INTERFACE_VERSION:
case D3D10_0_7_DDI_INTERFACE_VERSION:
pCreateData->pDeviceFuncs->pfnDefaultConstantBufferUpdateSubresourceUP =
ResourceUpdateSubResourceUP;
pCreateData->pDeviceFuncs->pfnVsSetConstantBuffers = VsSetConstantBuffers;
pCreateData->pDeviceFuncs->pfnPsSetShaderResources = PsSetShaderResources;
pCreateData->pDeviceFuncs->pfnPsSetShader = PsSetShader;
pCreateData->pDeviceFuncs->pfnPsSetSamplers = PsSetSamplers;
pCreateData->pDeviceFuncs->pfnVsSetShader = VsSetShader;
pCreateData->pDeviceFuncs->pfnDrawIndexed = DrawIndexed;
pCreateData->pDeviceFuncs->pfnDraw = Draw;
pCreateData->pDeviceFuncs->pfnDynamicIABufferMapNoOverwrite =
ResourceMap;
pCreateData->pDeviceFuncs->pfnDynamicIABufferUnmap = ResourceUnmap;
pCreateData->pDeviceFuncs->pfnDynamicConstantBufferMapDiscard =
ResourceMap;
pCreateData->pDeviceFuncs->pfnDynamicIABufferMapDiscard =
ResourceMap;
pCreateData->pDeviceFuncs->pfnDynamicConstantBufferUnmap =
ResourceUnmap;
pCreateData->pDeviceFuncs->pfnPsSetConstantBuffers = PsSetConstantBuffers;
pCreateData->pDeviceFuncs->pfnIaSetInputLayout = IaSetInputLayout;
pCreateData->pDeviceFuncs->pfnIaSetVertexBuffers = IaSetVertexBuffers;
pCreateData->pDeviceFuncs->pfnIaSetIndexBuffer = IaSetIndexBuffer;
pCreateData->pDeviceFuncs->pfnDrawIndexedInstanced = DrawIndexedInstanced;
pCreateData->pDeviceFuncs->pfnDrawInstanced = DrawInstanced;
pCreateData->pDeviceFuncs->pfnDynamicResourceMapDiscard =
ResourceMap;
pCreateData->pDeviceFuncs->pfnDynamicResourceUnmap = ResourceUnmap;
pCreateData->pDeviceFuncs->pfnGsSetConstantBuffers = GsSetConstantBuffers;
pCreateData->pDeviceFuncs->pfnGsSetShader = GsSetShader;
pCreateData->pDeviceFuncs->pfnIaSetTopology = IaSetTopology;
pCreateData->pDeviceFuncs->pfnStagingResourceMap = ResourceMap;
pCreateData->pDeviceFuncs->pfnStagingResourceUnmap = ResourceUnmap;
pCreateData->pDeviceFuncs->pfnVsSetShaderResources = VsSetShaderResources;
pCreateData->pDeviceFuncs->pfnVsSetSamplers = VsSetSamplers;
pCreateData->pDeviceFuncs->pfnGsSetShaderResources = GsSetShaderResources;
pCreateData->pDeviceFuncs->pfnGsSetSamplers = GsSetSamplers;
pCreateData->pDeviceFuncs->pfnSetRenderTargets = SetRenderTargets;
pCreateData->pDeviceFuncs->pfnShaderResourceViewReadAfterWriteHazard =
ShaderResourceViewReadAfterWriteHazard;
pCreateData->pDeviceFuncs->pfnResourceReadAfterWriteHazard =
ResourceReadAfterWriteHazard;
pCreateData->pDeviceFuncs->pfnSetBlendState = SetBlendState;
pCreateData->pDeviceFuncs->pfnSetDepthStencilState = SetDepthStencilState;
pCreateData->pDeviceFuncs->pfnSetRasterizerState = SetRasterizerState;
pCreateData->pDeviceFuncs->pfnQueryEnd = QueryEnd;
pCreateData->pDeviceFuncs->pfnQueryBegin = QueryBegin;
pCreateData->pDeviceFuncs->pfnResourceCopyRegion = ResourceCopyRegion;
pCreateData->pDeviceFuncs->pfnResourceUpdateSubresourceUP =
ResourceUpdateSubResourceUP;
pCreateData->pDeviceFuncs->pfnSoSetTargets = SoSetTargets;
pCreateData->pDeviceFuncs->pfnDrawAuto = DrawAuto;
pCreateData->pDeviceFuncs->pfnSetViewports = SetViewports;
pCreateData->pDeviceFuncs->pfnSetScissorRects = SetScissorRects;
pCreateData->pDeviceFuncs->pfnClearRenderTargetView = ClearRenderTargetView;
pCreateData->pDeviceFuncs->pfnClearDepthStencilView = ClearDepthStencilView;
pCreateData->pDeviceFuncs->pfnSetPredication = SetPredication;
pCreateData->pDeviceFuncs->pfnQueryGetData = QueryGetData;
pCreateData->pDeviceFuncs->pfnFlush = Flush;
pCreateData->pDeviceFuncs->pfnGenMips = GenMips;
pCreateData->pDeviceFuncs->pfnResourceCopy = ResourceCopy;
pCreateData->pDeviceFuncs->pfnResourceResolveSubresource =
ResourceResolveSubResource;
pCreateData->pDeviceFuncs->pfnResourceMap = ResourceMap;
pCreateData->pDeviceFuncs->pfnResourceUnmap = ResourceUnmap;
pCreateData->pDeviceFuncs->pfnResourceIsStagingBusy = ResourceIsStagingBusy;
pCreateData->pDeviceFuncs->pfnRelocateDeviceFuncs = RelocateDeviceFuncs;
pCreateData->pDeviceFuncs->pfnCalcPrivateResourceSize =
CalcPrivateResourceSize;
pCreateData->pDeviceFuncs->pfnCalcPrivateOpenedResourceSize =
CalcPrivateOpenedResourceSize;
pCreateData->pDeviceFuncs->pfnCreateResource = CreateResource;
pCreateData->pDeviceFuncs->pfnOpenResource = OpenResource;
pCreateData->pDeviceFuncs->pfnDestroyResource = DestroyResource;
pCreateData->pDeviceFuncs->pfnCalcPrivateShaderResourceViewSize =
CalcPrivateShaderResourceViewSize;
pCreateData->pDeviceFuncs->pfnCreateShaderResourceView =
CreateShaderResourceView;
pCreateData->pDeviceFuncs->pfnDestroyShaderResourceView =
DestroyShaderResourceView;
pCreateData->pDeviceFuncs->pfnCalcPrivateRenderTargetViewSize =
CalcPrivateRenderTargetViewSize;
pCreateData->pDeviceFuncs->pfnCreateRenderTargetView =
CreateRenderTargetView;
pCreateData->pDeviceFuncs->pfnDestroyRenderTargetView =
DestroyRenderTargetView;
pCreateData->pDeviceFuncs->pfnCalcPrivateDepthStencilViewSize =
CalcPrivateDepthStencilViewSize;
pCreateData->pDeviceFuncs->pfnCreateDepthStencilView =
CreateDepthStencilView;
pCreateData->pDeviceFuncs->pfnDestroyDepthStencilView =
DestroyDepthStencilView;
pCreateData->pDeviceFuncs->pfnCalcPrivateElementLayoutSize =
CalcPrivateElementLayoutSize;
pCreateData->pDeviceFuncs->pfnCreateElementLayout = CreateElementLayout;
pCreateData->pDeviceFuncs->pfnDestroyElementLayout = DestroyElementLayout;
pCreateData->pDeviceFuncs->pfnCalcPrivateBlendStateSize =
CalcPrivateBlendStateSize;
pCreateData->pDeviceFuncs->pfnCreateBlendState = CreateBlendState;
pCreateData->pDeviceFuncs->pfnDestroyBlendState = DestroyBlendState;
pCreateData->pDeviceFuncs->pfnCalcPrivateDepthStencilStateSize =
CalcPrivateDepthStencilStateSize;
pCreateData->pDeviceFuncs->pfnCreateDepthStencilState =
CreateDepthStencilState;
pCreateData->pDeviceFuncs->pfnDestroyDepthStencilState =
DestroyDepthStencilState;
pCreateData->pDeviceFuncs->pfnCalcPrivateRasterizerStateSize =
CalcPrivateRasterizerStateSize;
pCreateData->pDeviceFuncs->pfnCreateRasterizerState =
CreateRasterizerState;
pCreateData->pDeviceFuncs->pfnDestroyRasterizerState =
DestroyRasterizerState;
pCreateData->pDeviceFuncs->pfnCalcPrivateShaderSize = CalcPrivateShaderSize;
pCreateData->pDeviceFuncs->pfnCreateVertexShader = CreateVertexShader;
pCreateData->pDeviceFuncs->pfnCreateGeometryShader = CreateGeometryShader;
pCreateData->pDeviceFuncs->pfnCreatePixelShader = CreatePixelShader;
pCreateData->pDeviceFuncs->pfnCalcPrivateGeometryShaderWithStreamOutput =
CalcPrivateGeometryShaderWithStreamOutput;
pCreateData->pDeviceFuncs->pfnCreateGeometryShaderWithStreamOutput =
CreateGeometryShaderWithStreamOutput;
pCreateData->pDeviceFuncs->pfnDestroyShader = DestroyShader;
pCreateData->pDeviceFuncs->pfnCalcPrivateSamplerSize = CalcPrivateSamplerSize;
pCreateData->pDeviceFuncs->pfnCreateSampler = CreateSampler;
pCreateData->pDeviceFuncs->pfnDestroySampler = DestroySampler;
pCreateData->pDeviceFuncs->pfnCalcPrivateQuerySize = CalcPrivateQuerySize;
pCreateData->pDeviceFuncs->pfnCreateQuery = CreateQuery;
pCreateData->pDeviceFuncs->pfnDestroyQuery = DestroyQuery;
pCreateData->pDeviceFuncs->pfnCheckFormatSupport = CheckFormatSupport;
pCreateData->pDeviceFuncs->pfnCheckMultisampleQualityLevels =
CheckMultisampleQualityLevels;
pCreateData->pDeviceFuncs->pfnCheckCounterInfo = CheckCounterInfo;
pCreateData->pDeviceFuncs->pfnCheckCounter = CheckCounter;
pCreateData->pDeviceFuncs->pfnDestroyDevice = DestroyDevice;
pCreateData->pDeviceFuncs->pfnSetTextFilterSize = SetTextFilterSize;
break;
case D3D10_1_DDI_INTERFACE_VERSION:
case D3D10_1_x_DDI_INTERFACE_VERSION:
case D3D10_1_7_DDI_INTERFACE_VERSION:
pCreateData->p10_1DeviceFuncs->pfnDefaultConstantBufferUpdateSubresourceUP =
ResourceUpdateSubResourceUP;
pCreateData->p10_1DeviceFuncs->pfnVsSetConstantBuffers = VsSetConstantBuffers;
pCreateData->p10_1DeviceFuncs->pfnPsSetShaderResources = PsSetShaderResources;
pCreateData->p10_1DeviceFuncs->pfnPsSetShader = PsSetShader;
pCreateData->p10_1DeviceFuncs->pfnPsSetSamplers = PsSetSamplers;
pCreateData->p10_1DeviceFuncs->pfnVsSetShader = VsSetShader;
pCreateData->p10_1DeviceFuncs->pfnDrawIndexed = DrawIndexed;
pCreateData->p10_1DeviceFuncs->pfnDraw = Draw;
pCreateData->p10_1DeviceFuncs->pfnDynamicIABufferMapNoOverwrite =
ResourceMap;
pCreateData->p10_1DeviceFuncs->pfnDynamicIABufferUnmap = ResourceUnmap;
pCreateData->p10_1DeviceFuncs->pfnDynamicConstantBufferMapDiscard =
ResourceMap;
pCreateData->p10_1DeviceFuncs->pfnDynamicIABufferMapDiscard =
ResourceMap;
pCreateData->p10_1DeviceFuncs->pfnDynamicConstantBufferUnmap =
ResourceUnmap;
pCreateData->p10_1DeviceFuncs->pfnPsSetConstantBuffers = PsSetConstantBuffers;
pCreateData->p10_1DeviceFuncs->pfnIaSetInputLayout = IaSetInputLayout;
pCreateData->p10_1DeviceFuncs->pfnIaSetVertexBuffers = IaSetVertexBuffers;
pCreateData->p10_1DeviceFuncs->pfnIaSetIndexBuffer = IaSetIndexBuffer;
pCreateData->p10_1DeviceFuncs->pfnDrawIndexedInstanced = DrawIndexedInstanced;
pCreateData->p10_1DeviceFuncs->pfnDrawInstanced = DrawInstanced;
pCreateData->p10_1DeviceFuncs->pfnDynamicResourceMapDiscard =
ResourceMap;
pCreateData->p10_1DeviceFuncs->pfnDynamicResourceUnmap = ResourceUnmap;
pCreateData->p10_1DeviceFuncs->pfnGsSetConstantBuffers = GsSetConstantBuffers;
pCreateData->p10_1DeviceFuncs->pfnGsSetShader = GsSetShader;
pCreateData->p10_1DeviceFuncs->pfnIaSetTopology = IaSetTopology;
pCreateData->p10_1DeviceFuncs->pfnStagingResourceMap = ResourceMap;
pCreateData->p10_1DeviceFuncs->pfnStagingResourceUnmap = ResourceUnmap;
pCreateData->p10_1DeviceFuncs->pfnVsSetShaderResources = VsSetShaderResources;
pCreateData->p10_1DeviceFuncs->pfnVsSetSamplers = VsSetSamplers;
pCreateData->p10_1DeviceFuncs->pfnGsSetShaderResources = GsSetShaderResources;
pCreateData->p10_1DeviceFuncs->pfnGsSetSamplers = GsSetSamplers;
pCreateData->p10_1DeviceFuncs->pfnSetRenderTargets = SetRenderTargets;
pCreateData->p10_1DeviceFuncs->pfnShaderResourceViewReadAfterWriteHazard =
ShaderResourceViewReadAfterWriteHazard;
pCreateData->p10_1DeviceFuncs->pfnResourceReadAfterWriteHazard =
ResourceReadAfterWriteHazard;
pCreateData->p10_1DeviceFuncs->pfnSetBlendState = SetBlendState;
pCreateData->p10_1DeviceFuncs->pfnSetDepthStencilState = SetDepthStencilState;
pCreateData->p10_1DeviceFuncs->pfnSetRasterizerState = SetRasterizerState;
pCreateData->p10_1DeviceFuncs->pfnQueryEnd = QueryEnd;
pCreateData->p10_1DeviceFuncs->pfnQueryBegin = QueryBegin;
pCreateData->p10_1DeviceFuncs->pfnResourceCopyRegion = ResourceCopyRegion;
pCreateData->p10_1DeviceFuncs->pfnResourceUpdateSubresourceUP =
ResourceUpdateSubResourceUP;
pCreateData->p10_1DeviceFuncs->pfnSoSetTargets = SoSetTargets;
pCreateData->p10_1DeviceFuncs->pfnDrawAuto = DrawAuto;
pCreateData->p10_1DeviceFuncs->pfnSetViewports = SetViewports;
pCreateData->p10_1DeviceFuncs->pfnSetScissorRects = SetScissorRects;
pCreateData->p10_1DeviceFuncs->pfnClearRenderTargetView = ClearRenderTargetView;
pCreateData->p10_1DeviceFuncs->pfnClearDepthStencilView = ClearDepthStencilView;
pCreateData->p10_1DeviceFuncs->pfnSetPredication = SetPredication;
pCreateData->p10_1DeviceFuncs->pfnQueryGetData = QueryGetData;
pCreateData->p10_1DeviceFuncs->pfnFlush = Flush;
pCreateData->p10_1DeviceFuncs->pfnGenMips = GenMips;
pCreateData->p10_1DeviceFuncs->pfnResourceCopy = ResourceCopy;
pCreateData->p10_1DeviceFuncs->pfnResourceResolveSubresource =
ResourceResolveSubResource;
pCreateData->p10_1DeviceFuncs->pfnResourceMap = ResourceMap;
pCreateData->p10_1DeviceFuncs->pfnResourceUnmap = ResourceUnmap;
pCreateData->p10_1DeviceFuncs->pfnResourceIsStagingBusy = ResourceIsStagingBusy;
pCreateData->p10_1DeviceFuncs->pfnRelocateDeviceFuncs = RelocateDeviceFuncs1;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateResourceSize =
CalcPrivateResourceSize;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateOpenedResourceSize =
CalcPrivateOpenedResourceSize;
pCreateData->p10_1DeviceFuncs->pfnCreateResource = CreateResource;
pCreateData->p10_1DeviceFuncs->pfnOpenResource = OpenResource;
pCreateData->p10_1DeviceFuncs->pfnDestroyResource = DestroyResource;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateShaderResourceViewSize =
CalcPrivateShaderResourceViewSize1;
pCreateData->p10_1DeviceFuncs->pfnCreateShaderResourceView =
CreateShaderResourceView1;
pCreateData->p10_1DeviceFuncs->pfnDestroyShaderResourceView =
DestroyShaderResourceView;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateRenderTargetViewSize =
CalcPrivateRenderTargetViewSize;
pCreateData->p10_1DeviceFuncs->pfnCreateRenderTargetView =
CreateRenderTargetView;
pCreateData->p10_1DeviceFuncs->pfnDestroyRenderTargetView =
DestroyRenderTargetView;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateDepthStencilViewSize =
CalcPrivateDepthStencilViewSize;
pCreateData->p10_1DeviceFuncs->pfnCreateDepthStencilView =
CreateDepthStencilView;
pCreateData->p10_1DeviceFuncs->pfnDestroyDepthStencilView =
DestroyDepthStencilView;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateElementLayoutSize =
CalcPrivateElementLayoutSize;
pCreateData->p10_1DeviceFuncs->pfnCreateElementLayout = CreateElementLayout;
pCreateData->p10_1DeviceFuncs->pfnDestroyElementLayout = DestroyElementLayout;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateBlendStateSize =
CalcPrivateBlendStateSize1;
pCreateData->p10_1DeviceFuncs->pfnCreateBlendState = CreateBlendState1;
pCreateData->p10_1DeviceFuncs->pfnDestroyBlendState = DestroyBlendState;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateDepthStencilStateSize =
CalcPrivateDepthStencilStateSize;
pCreateData->p10_1DeviceFuncs->pfnCreateDepthStencilState =
CreateDepthStencilState;
pCreateData->p10_1DeviceFuncs->pfnDestroyDepthStencilState =
DestroyDepthStencilState;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateRasterizerStateSize =
CalcPrivateRasterizerStateSize;
pCreateData->p10_1DeviceFuncs->pfnCreateRasterizerState =
CreateRasterizerState;
pCreateData->p10_1DeviceFuncs->pfnDestroyRasterizerState =
DestroyRasterizerState;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateShaderSize = CalcPrivateShaderSize;
pCreateData->p10_1DeviceFuncs->pfnCreateVertexShader = CreateVertexShader;
pCreateData->p10_1DeviceFuncs->pfnCreateGeometryShader = CreateGeometryShader;
pCreateData->p10_1DeviceFuncs->pfnCreatePixelShader = CreatePixelShader;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateGeometryShaderWithStreamOutput =
CalcPrivateGeometryShaderWithStreamOutput;
pCreateData->p10_1DeviceFuncs->pfnCreateGeometryShaderWithStreamOutput =
CreateGeometryShaderWithStreamOutput;
pCreateData->p10_1DeviceFuncs->pfnDestroyShader = DestroyShader;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateSamplerSize = CalcPrivateSamplerSize;
pCreateData->p10_1DeviceFuncs->pfnCreateSampler = CreateSampler;
pCreateData->p10_1DeviceFuncs->pfnDestroySampler = DestroySampler;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateQuerySize = CalcPrivateQuerySize;
pCreateData->p10_1DeviceFuncs->pfnCreateQuery = CreateQuery;
pCreateData->p10_1DeviceFuncs->pfnDestroyQuery = DestroyQuery;
pCreateData->p10_1DeviceFuncs->pfnCheckFormatSupport = CheckFormatSupport;
pCreateData->p10_1DeviceFuncs->pfnCheckMultisampleQualityLevels =
CheckMultisampleQualityLevels;
pCreateData->p10_1DeviceFuncs->pfnCheckCounterInfo = CheckCounterInfo;
pCreateData->p10_1DeviceFuncs->pfnCheckCounter = CheckCounter;
pCreateData->p10_1DeviceFuncs->pfnDestroyDevice = DestroyDevice;
pCreateData->p10_1DeviceFuncs->pfnSetTextFilterSize = SetTextFilterSize;
pCreateData->p10_1DeviceFuncs->pfnRelocateDeviceFuncs = RelocateDeviceFuncs1;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateShaderResourceViewSize =
CalcPrivateShaderResourceViewSize1;
pCreateData->p10_1DeviceFuncs->pfnCreateShaderResourceView =
CreateShaderResourceView1;
pCreateData->p10_1DeviceFuncs->pfnCalcPrivateBlendStateSize =
CalcPrivateBlendStateSize1;
pCreateData->p10_1DeviceFuncs->pfnCreateBlendState = CreateBlendState1;
pCreateData->p10_1DeviceFuncs->pfnResourceConvert =
pCreateData->p10_1DeviceFuncs->pfnResourceCopy;
pCreateData->p10_1DeviceFuncs->pfnResourceConvertRegion =
pCreateData->p10_1DeviceFuncs->pfnResourceCopyRegion;
break;
default:
assert(0);
break;
}
/*
* Fill in DXGI DDI functions
*/
pCreateData->DXGIBaseDDI.pDXGIDDIBaseFunctions->pfnPresent =
_Present;
pCreateData->DXGIBaseDDI.pDXGIDDIBaseFunctions->pfnGetGammaCaps =
_GetGammaCaps;
pCreateData->DXGIBaseDDI.pDXGIDDIBaseFunctions->pfnSetDisplayMode =
_SetDisplayMode;
pCreateData->DXGIBaseDDI.pDXGIDDIBaseFunctions->pfnSetResourcePriority =
_SetResourcePriority;
pCreateData->DXGIBaseDDI.pDXGIDDIBaseFunctions->pfnQueryResourceResidency =
_QueryResourceResidency;
pCreateData->DXGIBaseDDI.pDXGIDDIBaseFunctions->pfnRotateResourceIdentities =
_RotateResourceIdentities;
pCreateData->DXGIBaseDDI.pDXGIDDIBaseFunctions->pfnBlt =
_Blt;
if (0) {
return S_OK;
} else {
// Tell DXGI to not use the shared resource presentation path when
// communicating with DWM:
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff569887(v=vs.85).aspx
return DXGI_STATUS_NO_REDIRECTION;
}
}
/*
* ----------------------------------------------------------------------
*
* DestroyDevice --
*
* The DestroyDevice function destroys a graphics context.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DestroyDevice(D3D10DDI_HDEVICE hDevice) // IN
{
unsigned i;
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_context *pipe = pDevice->pipe;
pipe->flush(pipe, NULL, 0);
for (i = 0; i < PIPE_MAX_SO_BUFFERS; ++i) {
pipe_so_target_reference(&pDevice->so_targets[i], NULL);
}
if (pDevice->draw_so_target) {
pipe_so_target_reference(&pDevice->draw_so_target, NULL);
}
pipe->bind_fs_state(pipe, NULL);
pipe->bind_vs_state(pipe, NULL);
DeleteEmptyShader(pDevice, PIPE_SHADER_FRAGMENT, pDevice->empty_fs);
DeleteEmptyShader(pDevice, PIPE_SHADER_VERTEX, pDevice->empty_vs);
pipe_surface_reference(&pDevice->fb.zsbuf, NULL);
for (i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
pipe_surface_reference(&pDevice->fb.cbufs[i], NULL);
}
for (i = 0; i < PIPE_MAX_ATTRIBS; ++i) {
if (!pDevice->vertex_buffers[i].is_user_buffer) {
pipe_resource_reference(&pDevice->vertex_buffers[i].buffer.resource, NULL);
}
}
pipe_resource_reference(&pDevice->index_buffer, NULL);
static struct pipe_sampler_view * sampler_views[PIPE_MAX_SHADER_SAMPLER_VIEWS];
memset(sampler_views, 0, sizeof sampler_views);
pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0,
PIPE_MAX_SHADER_SAMPLER_VIEWS, 0, sampler_views);
pipe->set_sampler_views(pipe, PIPE_SHADER_VERTEX, 0,
PIPE_MAX_SHADER_SAMPLER_VIEWS, 0, sampler_views);
pipe->set_sampler_views(pipe, PIPE_SHADER_GEOMETRY, 0,
PIPE_MAX_SHADER_SAMPLER_VIEWS, 0, sampler_views);
pipe->destroy(pipe);
}
/*
* ----------------------------------------------------------------------
*
* RelocateDeviceFuncs --
*
* The RelocateDeviceFuncs function notifies the user-mode
* display driver about the new location of the driver function table.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
RelocateDeviceFuncs(D3D10DDI_HDEVICE hDevice, // IN
__in struct D3D10DDI_DEVICEFUNCS *pDeviceFunctions) // IN
{
LOG_ENTRYPOINT();
/*
* Nothing to do as we don't store a pointer to this entity.
*/
}
/*
* ----------------------------------------------------------------------
*
* RelocateDeviceFuncs1 --
*
* The RelocateDeviceFuncs function notifies the user-mode
* display driver about the new location of the driver function table.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
RelocateDeviceFuncs1(D3D10DDI_HDEVICE hDevice, // IN
__in struct D3D10_1DDI_DEVICEFUNCS *pDeviceFunctions) // IN
{
LOG_ENTRYPOINT();
/*
* Nothing to do as we don't store a pointer to this entity.
*/
}
/*
* ----------------------------------------------------------------------
*
* Flush --
*
* The Flush function submits outstanding hardware commands that
* are in the hardware command buffer to the display miniport driver.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
Flush(D3D10DDI_HDEVICE hDevice) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
pipe->flush(pipe, NULL, 0);
}
/*
* ----------------------------------------------------------------------
*
* CheckFormatSupport --
*
* The CheckFormatSupport function retrieves the capabilites that
* the device has with the specified format.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CheckFormatSupport(D3D10DDI_HDEVICE hDevice, // IN
DXGI_FORMAT Format, // IN
__out UINT *pFormatCaps) // OUT
{
//LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
struct pipe_screen *screen = pipe->screen;
*pFormatCaps = 0;
enum pipe_format format = FormatTranslate(Format, FALSE);
if (format == PIPE_FORMAT_NONE) {
*pFormatCaps = D3D10_DDI_FORMAT_SUPPORT_NOT_SUPPORTED;
return;
}
if (Format == DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM) {
/*
* We only need to support creation.
* http://msdn.microsoft.com/en-us/library/windows/hardware/ff552818.aspx
*/
return;
}
if (screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, 0,
PIPE_BIND_RENDER_TARGET)) {
*pFormatCaps |= D3D10_DDI_FORMAT_SUPPORT_RENDERTARGET;
*pFormatCaps |= D3D10_DDI_FORMAT_SUPPORT_BLENDABLE;
#if SUPPORT_MSAA
if (screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 4, 4,
PIPE_BIND_RENDER_TARGET)) {
*pFormatCaps |= D3D10_DDI_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET;
}
#endif
}
if (screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, 0,
PIPE_BIND_SAMPLER_VIEW)) {
*pFormatCaps |= D3D10_DDI_FORMAT_SUPPORT_SHADER_SAMPLE;
#if SUPPORT_MSAA
if (screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 4, 4,
PIPE_BIND_RENDER_TARGET)) {
*pFormatCaps |= D3D10_DDI_FORMAT_SUPPORT_MULTISAMPLE_LOAD;
}
#endif
}
}
/*
* ----------------------------------------------------------------------
*
* CheckMultisampleQualityLevels --
*
* The CheckMultisampleQualityLevels function retrieves the number
* of quality levels that the device supports for the specified
* number of samples.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CheckMultisampleQualityLevels(D3D10DDI_HDEVICE hDevice, // IN
DXGI_FORMAT Format, // IN
UINT SampleCount, // IN
__out UINT *pNumQualityLevels) // OUT
{
//LOG_ENTRYPOINT();
/* XXX: Disable MSAA */
*pNumQualityLevels = 0;
}
/*
* ----------------------------------------------------------------------
*
* SetTextFilterSize --
*
* The SetTextFilterSize function sets the width and height
* of the monochrome convolution filter.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
SetTextFilterSize(D3D10DDI_HDEVICE hDevice, // IN
UINT Width, // IN
UINT Height) // IN
{
LOG_ENTRYPOINT();
LOG_UNSUPPORTED(Width != 1 || Height != 1);
}

View File

@ -0,0 +1,44 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Device.h --
* Functions that provide the 3D device functionality.
*/
#ifndef DEVICE_H
#define DEVICE_H
#include "DriverIncludes.h"
SIZE_T APIENTRY CalcPrivateDeviceSize(D3D10DDI_HADAPTER hAdapter,
__in const D3D10DDIARG_CALCPRIVATEDEVICESIZE *pData);
HRESULT APIENTRY CreateDevice(D3D10DDI_HADAPTER hAdapter,
__in D3D10DDIARG_CREATEDEVICE *pCreateData);
#endif /* DEVICE_H */

View File

@ -0,0 +1,343 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Draw.h --
* Functions that render 3D primitives.
*/
#include "Draw.h"
#include "State.h"
#include "Shader.h"
#include "Debug.h"
#include "util/u_draw.h"
#include "util/u_memory.h"
static unsigned
ClampedUAdd(unsigned a,
unsigned b)
{
unsigned c = a + b;
if (c < a) {
return 0xffffffff;
}
return c;
}
/*
* We have to resolve the stream output state for empty geometry shaders.
* In particular we've remapped the output indices when translating the
* shaders so now the register_index variables in the stream output
* state are incorrect and we need to remap them back to the correct
* state.
*/
static void
ResolveState(Device *pDevice)
{
if (pDevice->bound_empty_gs && pDevice->bound_vs &&
pDevice->bound_vs->state.tokens) {
Shader *gs = pDevice->bound_empty_gs;
Shader *vs = pDevice->bound_vs;
boolean remapped = FALSE;
struct pipe_context *pipe = pDevice->pipe;
if (!gs->output_resolved) {
for (unsigned i = 0; i < gs->state.stream_output.num_outputs; ++i) {
unsigned mapping =
ShaderFindOutputMapping(vs, gs->state.stream_output.output[i].register_index);
if (mapping != gs->state.stream_output.output[i].register_index) {
gs->state.stream_output.output[i].register_index = mapping;
remapped = TRUE;
}
}
if (remapped) {
pipe->delete_gs_state(pipe, gs->handle);
gs->handle = pipe->create_gs_state(pipe, &gs->state);
}
gs->output_resolved = TRUE;
}
pipe->bind_gs_state(pipe, gs->handle);
}
}
static struct pipe_resource *
create_null_index_buffer(struct pipe_context *ctx, uint num_indices,
unsigned *restart_index, unsigned *index_size,
unsigned *ib_offset)
{
unsigned buf_size = num_indices * sizeof(unsigned);
unsigned *buf = (unsigned*)MALLOC(buf_size);
struct pipe_resource *ibuf;
memset(buf, 0, buf_size);
ibuf = pipe_buffer_create_with_data(ctx,
PIPE_BIND_INDEX_BUFFER,
PIPE_USAGE_IMMUTABLE,
buf_size, buf);
*index_size = 4;
*restart_index = 0xffffffff;
*ib_offset = 0;
FREE(buf);
return ibuf;
}
/*
* ----------------------------------------------------------------------
*
* Draw --
*
* The Draw function draws nonindexed primitives.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
Draw(D3D10DDI_HDEVICE hDevice, // IN
UINT VertexCount, // IN
UINT StartVertexLocation) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
ResolveState(pDevice);
assert(pDevice->primitive < PIPE_PRIM_MAX);
util_draw_arrays(pDevice->pipe,
pDevice->primitive,
StartVertexLocation,
VertexCount);
}
/*
* ----------------------------------------------------------------------
*
* DrawIndexed --
*
* The DrawIndexed function draws indexed primitives.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DrawIndexed(D3D10DDI_HDEVICE hDevice, // IN
UINT IndexCount, // IN
UINT StartIndexLocation, // IN
INT BaseVertexLocation) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_draw_info info;
struct pipe_draw_start_count_bias draw;
struct pipe_resource *null_ib = NULL;
unsigned restart_index = pDevice->restart_index;
unsigned index_size = pDevice->index_size;
unsigned ib_offset = pDevice->ib_offset;
assert(pDevice->primitive < PIPE_PRIM_MAX);
/* XXX I don't think draw still needs this? */
if (!pDevice->index_buffer) {
null_ib =
create_null_index_buffer(pDevice->pipe,
StartIndexLocation + IndexCount,
&restart_index, &index_size, &ib_offset);
}
ResolveState(pDevice);
util_draw_init_info(&info);
info.index_size = index_size;
info.mode = pDevice->primitive;
draw.start = ClampedUAdd(StartIndexLocation, ib_offset / index_size);
draw.count = IndexCount;
info.index.resource = null_ib ? null_ib : pDevice->index_buffer;
draw.index_bias = BaseVertexLocation;
info.primitive_restart = TRUE;
info.restart_index = restart_index;
pDevice->pipe->draw_vbo(pDevice->pipe, &info, 0, NULL, &draw, 1);
if (null_ib) {
pipe_resource_reference(&null_ib, NULL);
}
}
/*
* ----------------------------------------------------------------------
*
* DrawInstanced --
*
* The DrawInstanced function draws particular instances
* of nonindexed primitives.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DrawInstanced(D3D10DDI_HDEVICE hDevice, // IN
UINT VertexCountPerInstance, // IN
UINT InstanceCount, // IN
UINT StartVertexLocation, // IN
UINT StartInstanceLocation) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
if (!InstanceCount) {
return;
}
ResolveState(pDevice);
assert(pDevice->primitive < PIPE_PRIM_MAX);
util_draw_arrays_instanced(pDevice->pipe,
pDevice->primitive,
StartVertexLocation,
VertexCountPerInstance,
StartInstanceLocation,
InstanceCount);
}
/*
* ----------------------------------------------------------------------
*
* DrawIndexedInstanced --
*
* The DrawIndexedInstanced function draws particular
* instances of indexed primitives.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DrawIndexedInstanced(D3D10DDI_HDEVICE hDevice, // IN
UINT IndexCountPerInstance, // IN
UINT InstanceCount, // IN
UINT StartIndexLocation, // IN
INT BaseVertexLocation, // IN
UINT StartInstanceLocation) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_draw_info info;
struct pipe_draw_start_count_bias draw;
struct pipe_resource *null_ib = NULL;
unsigned restart_index = pDevice->restart_index;
unsigned index_size = pDevice->index_size;
unsigned ib_offset = pDevice->ib_offset;
assert(pDevice->primitive < PIPE_PRIM_MAX);
if (!InstanceCount) {
return;
}
/* XXX I don't think draw still needs this? */
if (!pDevice->index_buffer) {
null_ib =
create_null_index_buffer(pDevice->pipe,
StartIndexLocation + IndexCountPerInstance,
&restart_index, &index_size, &ib_offset);
}
ResolveState(pDevice);
util_draw_init_info(&info);
info.index_size = index_size;
info.mode = pDevice->primitive;
draw.start = ClampedUAdd(StartIndexLocation, ib_offset / index_size);
draw.count = IndexCountPerInstance;
info.index.resource = null_ib ? null_ib : pDevice->index_buffer;
draw.index_bias = BaseVertexLocation;
info.start_instance = StartInstanceLocation;
info.instance_count = InstanceCount;
info.primitive_restart = TRUE;
info.restart_index = restart_index;
pDevice->pipe->draw_vbo(pDevice->pipe, &info, 0, NULL, &draw, 1);
if (null_ib) {
pipe_resource_reference(&null_ib, NULL);
}
}
/*
* ----------------------------------------------------------------------
*
* DrawAuto --
*
* The DrawAuto function works similarly to the Draw function,
* except DrawAuto is used for the special case where vertex
* data is written through the stream-output unit and then
* recycled as a vertex buffer. The driver determines the number
* of primitives, in part, by how much data was written to the
* buffer through stream output.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DrawAuto(D3D10DDI_HDEVICE hDevice) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_draw_info info;
struct pipe_draw_indirect_info indirect;
if (!pDevice->draw_so_target) {
LOG_UNSUPPORTED("DrawAuto without a set source buffer!");
return;
}
assert(pDevice->primitive < PIPE_PRIM_MAX);
ResolveState(pDevice);
util_draw_init_info(&info);
info.mode = pDevice->primitive;
memset(&indirect, 0, sizeof indirect);
indirect.count_from_stream_output = pDevice->draw_so_target;
pDevice->pipe->draw_vbo(pDevice->pipe, &info, 0, &indirect, NULL, 1);
}

View File

@ -0,0 +1,52 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Draw.h --
* Functions that render 3D primitives.
*/
#ifndef DRAW_H
#define DRAW_H
#include "DriverIncludes.h"
void APIENTRY Draw(D3D10DDI_HDEVICE hDevice, UINT VertexCount, UINT StartVertexLocation);
void APIENTRY DrawIndexed(D3D10DDI_HDEVICE hDevice, UINT IndexCount,
UINT StartIndexLocation, INT BaseVertexLocation);
void APIENTRY DrawInstanced(D3D10DDI_HDEVICE hDevice, UINT VertexCountPerInstance,
UINT InstanceCount, UINT StartVertexLocation,
UINT StartInstanceLocation);
void APIENTRY DrawIndexedInstanced(D3D10DDI_HDEVICE hDevice, UINT IndexCountPerInstance,
UINT InstanceCount, UINT StartIndexLocation,
INT BaseVertexLocation, UINT StartInstanceLocation);
void APIENTRY DrawAuto(D3D10DDI_HDEVICE hDevice);
#endif

View File

@ -0,0 +1,65 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* DriverIncludes.h --
* Basic DDK includes for building the client driver.
*/
#ifndef DRIVER_INCLUDES_H
#define DRIVER_INCLUDES_H
#ifdef __MINGW32__
#undef WIN32_LEAN_AND_MEAN /* for DEFINE_GUID macro */
#define _NO_OLDNAMES /* avoid defining ssize_t */
#include <stdio.h> /* for vsnprintf */
#undef fileno /* we redefine this in vm_basic_defs.h */
#endif
#include <windows.h>
#include "winddk/winddk_compat.h"
//typedef LARGE_INTEGER PHYSICAL_ADDRESS;
//typedef __success(return >= 0) LONG NTSTATUS;
#define D3D10DDI_MINOR_HEADER_VERSION 1
#include <d3d10umddi.h>
#include "Debug.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_format.h"
#include "pipe/p_defines.h"
#include "util/u_debug.h"
#include "util/u_inlines.h"
#endif /* DRIVER_INCLUDES_H */

View File

@ -0,0 +1,374 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Dxgi.cpp --
* DXGI related functions.
*/
#include <stdio.h>
#include "Dxgi.h"
#include "Format.h"
#include "State.h"
#include "Debug.h"
#include "util/format/u_format.h"
/*
* ----------------------------------------------------------------------
*
* _Present --
*
* This is turned into kernel callbacks rather than directly emitted
* as fifo packets.
*
* ----------------------------------------------------------------------
*/
HRESULT APIENTRY
_Present(DXGI_DDI_ARG_PRESENT *pPresentData)
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeDevice(pPresentData->hDevice);
Resource *pSrcResource = CastResource(pPresentData->hSurfaceToPresent);
D3DKMT_PRESENT *pPresentInfo = (D3DKMT_PRESENT *)pPresentData->pDXGIContext;
HWND hWnd = pPresentInfo->hWindow;
if (0) {
DebugPrintf(" hWindow = 0x%08lx\n", pPresentInfo->hWindow);
if (pPresentInfo->Flags.SrcRectValid) {
DebugPrintf(" SrcRect.left = %li\n", pPresentInfo->SrcRect.left);
DebugPrintf(" SrcRect.top = %li\n", pPresentInfo->SrcRect.top);
DebugPrintf(" SrcRect.right = %li\n", pPresentInfo->SrcRect.right);
DebugPrintf(" SrcRect.bottom = %li\n", pPresentInfo->SrcRect.bottom);
}
if (pPresentInfo->Flags.DstRectValid) {
DebugPrintf(" DstRect.left = %li\n", pPresentInfo->DstRect.left);
DebugPrintf(" DstRect.top = %li\n", pPresentInfo->DstRect.top);
DebugPrintf(" DstRect.right = %li\n", pPresentInfo->DstRect.right);
DebugPrintf(" DstRect.bottom = %li\n", pPresentInfo->DstRect.bottom);
}
}
RECT rect;
if (!GetClientRect(hWnd, &rect)) {
DebugPrintf("Invalid window.\n");
return S_OK;
}
int windowWidth = rect.right - rect.left;
int windowHeight = rect.bottom - rect.top;
HDC hDC = GetDC(hWnd);
unsigned w = pSrcResource->resource->width0;
unsigned h = pSrcResource->resource->height0;
void *map;
struct pipe_transfer *transfer;
map = pipe_transfer_map(pipe,
pSrcResource->resource,
0, 0, PIPE_MAP_READ,
0, 0, w, h,
&transfer);
if (map) {
BITMAPINFO bmi;
memset(&bmi, 0, sizeof bmi);
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = w;
bmi.bmiHeader.biHeight= -(long)h;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
DWORD *pixels = NULL;
// http://www.daniweb.com/software-development/cpp/code/241875/fast-animation-with-the-windows-gdi
HBITMAP hBmp = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pixels, NULL, 0);
util_format_translate(
PIPE_FORMAT_B8G8R8X8_UNORM,
(void *)pixels, w * 4,
0, 0,
pSrcResource->resource->format,
map, transfer->stride,
0, 0, w, h);
if (0) {
/*
* Save a BMP for debugging.
*/
FILE *fp = fopen("present.bmp", "wb");
if (fp) {
BITMAPFILEHEADER bmf;
bmf.bfType = 0x4d42;
bmf.bfSize = sizeof bmf + sizeof bmi + h * w * 4;
bmf.bfReserved1 = 0;
bmf.bfReserved2 = 0;
bmf.bfOffBits = sizeof bmf + sizeof bmi;
fwrite(&bmf, sizeof bmf, 1, fp);
fwrite(&bmi, sizeof bmi, 1, fp);
fwrite(pixels, h, w * 4, fp);
fclose(fp);
}
}
HDC hdcMem;
hdcMem = CreateCompatibleDC(hDC);
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hBmp);
int iStretchMode = SetStretchBltMode(hDC, HALFTONE);
StretchBlt(hDC, 0, 0, windowWidth, windowHeight,
hdcMem, 0, 0, w, h,
SRCCOPY);
if (iStretchMode) {
SetStretchBltMode(hDC, iStretchMode);
}
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
DeleteObject(hBmp);
pipe_transfer_unmap(pipe, transfer);
}
ReleaseDC(hWnd, hDC);
return S_OK;
}
/*
* ----------------------------------------------------------------------
*
* _GetGammaCaps --
*
* Return gamma capabilities.
*
* ----------------------------------------------------------------------
*/
HRESULT APIENTRY
_GetGammaCaps( DXGI_DDI_ARG_GET_GAMMA_CONTROL_CAPS *GetCaps )
{
LOG_ENTRYPOINT();
DXGI_GAMMA_CONTROL_CAPABILITIES *pCaps;
pCaps = GetCaps->pGammaCapabilities;
pCaps->ScaleAndOffsetSupported = FALSE;
pCaps->MinConvertedValue = 0.0;
pCaps->MaxConvertedValue = 1.0;
pCaps->NumGammaControlPoints = 17;
for (UINT i = 0; i < pCaps->NumGammaControlPoints; i++) {
pCaps->ControlPointPositions[i] = (float)i / (float)(pCaps->NumGammaControlPoints - 1);
}
return S_OK;
}
/*
* ----------------------------------------------------------------------
*
* _SetDisplayMode --
*
* Set the resource that is used to scan out to the display.
*
* ----------------------------------------------------------------------
*/
HRESULT APIENTRY
_SetDisplayMode( DXGI_DDI_ARG_SETDISPLAYMODE *SetDisplayMode )
{
LOG_UNSUPPORTED_ENTRYPOINT();
return S_OK;
}
/*
* ----------------------------------------------------------------------
*
* _SetResourcePriority --
*
* ----------------------------------------------------------------------
*/
HRESULT APIENTRY
_SetResourcePriority( DXGI_DDI_ARG_SETRESOURCEPRIORITY *SetResourcePriority )
{
LOG_ENTRYPOINT();
/* ignore */
return S_OK;
}
/*
* ----------------------------------------------------------------------
*
* _QueryResourceResidency --
*
* ----------------------------------------------------------------------
*/
HRESULT APIENTRY
_QueryResourceResidency( DXGI_DDI_ARG_QUERYRESOURCERESIDENCY *QueryResourceResidency )
{
LOG_ENTRYPOINT();
for (UINT i = 0; i < QueryResourceResidency->Resources; ++i) {
QueryResourceResidency->pStatus[i] = DXGI_DDI_RESIDENCY_FULLY_RESIDENT;
}
return S_OK;
}
/*
* ----------------------------------------------------------------------
*
* _RotateResourceIdentities --
*
* Rotate a list of resources by recreating their views with
* the updated rotations.
*
* ----------------------------------------------------------------------
*/
HRESULT APIENTRY
_RotateResourceIdentities( DXGI_DDI_ARG_ROTATE_RESOURCE_IDENTITIES *RotateResourceIdentities )
{
LOG_ENTRYPOINT();
if (RotateResourceIdentities->Resources <= 1) {
return S_OK;
}
struct pipe_context *pipe = CastPipeDevice(RotateResourceIdentities->hDevice);
struct pipe_screen *screen = pipe->screen;
struct pipe_resource *resource0 = CastPipeResource(RotateResourceIdentities->pResources[0]);
assert(resource0);
LOG_UNSUPPORTED(resource0->last_level);
/*
* XXX: Copying is not very efficient, but it is much simpler than the
* alternative of recreating all views.
*/
struct pipe_resource *temp_resource;
temp_resource = screen->resource_create(screen, resource0);
assert(temp_resource);
if (!temp_resource) {
return E_OUTOFMEMORY;
}
struct pipe_box src_box;
src_box.x = 0;
src_box.y = 0;
src_box.z = 0;
src_box.width = resource0->width0;
src_box.height = resource0->height0;
src_box.depth = resource0->depth0;
for (UINT i = 0; i < RotateResourceIdentities->Resources + 1; ++i) {
struct pipe_resource *src_resource;
struct pipe_resource *dst_resource;
if (i < RotateResourceIdentities->Resources) {
src_resource = CastPipeResource(RotateResourceIdentities->pResources[i]);
} else {
src_resource = temp_resource;
}
if (i > 0) {
dst_resource = CastPipeResource(RotateResourceIdentities->pResources[i - 1]);
} else {
dst_resource = temp_resource;
}
assert(dst_resource);
assert(src_resource);
pipe->resource_copy_region(pipe,
dst_resource,
0, // dst_level
0, 0, 0, // dst_x,y,z
src_resource,
0, // src_level
&src_box);
}
pipe_resource_reference(&temp_resource, NULL);
return S_OK;
}
/*
* ----------------------------------------------------------------------
*
* _Blt --
*
* Do a blt between two subresources. Apply MSAA resolve, format
* conversion and stretching.
*
* ----------------------------------------------------------------------
*/
HRESULT APIENTRY
_Blt(DXGI_DDI_ARG_BLT *Blt)
{
LOG_UNSUPPORTED_ENTRYPOINT();
return S_OK;
}

View File

@ -0,0 +1,46 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Dxgi.h --
* Functions that manipulate GPU resources.
*/
#ifndef WRAP_DXGI_H
#define WRAP_DXGI_H
#include "DriverIncludes.h"
HRESULT APIENTRY _Present( DXGI_DDI_ARG_PRESENT * );
HRESULT APIENTRY _GetGammaCaps( DXGI_DDI_ARG_GET_GAMMA_CONTROL_CAPS * );
HRESULT APIENTRY _SetDisplayMode( DXGI_DDI_ARG_SETDISPLAYMODE * );
HRESULT APIENTRY _SetResourcePriority( DXGI_DDI_ARG_SETRESOURCEPRIORITY * );
HRESULT APIENTRY _QueryResourceResidency( DXGI_DDI_ARG_QUERYRESOURCERESIDENCY * );
HRESULT APIENTRY _RotateResourceIdentities( DXGI_DDI_ARG_ROTATE_RESOURCE_IDENTITIES * );
HRESULT APIENTRY _Blt( DXGI_DDI_ARG_BLT * );
#endif

View File

@ -0,0 +1,389 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Format.h --
* Functions for format manipulation.
*/
#include <stdint.h>
#include "Format.h"
#include "State.h"
#include "Debug.h"
/* XXX: for a time llvmpipe didn't support SRGB */
#define HAVE_SRGB 1
enum pipe_format
FormatTranslate(DXGI_FORMAT Format, BOOL depth)
{
switch (Format) {
case DXGI_FORMAT_UNKNOWN:
return PIPE_FORMAT_NONE;
case DXGI_FORMAT_R32G32B32A32_FLOAT:
return PIPE_FORMAT_R32G32B32A32_FLOAT;
case DXGI_FORMAT_R32G32B32A32_UINT:
return PIPE_FORMAT_R32G32B32A32_UINT;
case DXGI_FORMAT_R32G32B32A32_SINT:
return PIPE_FORMAT_R32G32B32A32_SINT;
case DXGI_FORMAT_R32G32B32_FLOAT:
return PIPE_FORMAT_R32G32B32_FLOAT;
case DXGI_FORMAT_R32G32B32_UINT:
return PIPE_FORMAT_R32G32B32_UINT;
case DXGI_FORMAT_R32G32B32_SINT:
return PIPE_FORMAT_R32G32B32_SINT;
case DXGI_FORMAT_R16G16B16A16_UNORM:
return PIPE_FORMAT_R16G16B16A16_UNORM;
case DXGI_FORMAT_R16G16B16A16_UINT:
return PIPE_FORMAT_R16G16B16A16_UINT;
case DXGI_FORMAT_R16G16B16A16_SNORM:
return PIPE_FORMAT_R16G16B16A16_SNORM;
case DXGI_FORMAT_R16G16B16A16_SINT:
return PIPE_FORMAT_R16G16B16A16_SINT;
case DXGI_FORMAT_R32G32_FLOAT:
return PIPE_FORMAT_R32G32_FLOAT;
case DXGI_FORMAT_R32G32_UINT:
return PIPE_FORMAT_R32G32_UINT;
case DXGI_FORMAT_R32G32_SINT:
return PIPE_FORMAT_R32G32_SINT;
case DXGI_FORMAT_R8G8B8A8_UNORM:
return PIPE_FORMAT_R8G8B8A8_UNORM;
case DXGI_FORMAT_R8G8B8A8_UINT:
return PIPE_FORMAT_R8G8B8A8_UINT;
case DXGI_FORMAT_R8G8B8A8_SNORM:
return PIPE_FORMAT_R8G8B8A8_SNORM;
case DXGI_FORMAT_R8G8B8A8_SINT:
return PIPE_FORMAT_R8G8B8A8_SINT;
case DXGI_FORMAT_R16G16_UNORM:
return PIPE_FORMAT_R16G16_UNORM;
case DXGI_FORMAT_R16G16_UINT:
return PIPE_FORMAT_R16G16_UINT;
case DXGI_FORMAT_R16G16_SNORM:
return PIPE_FORMAT_R16G16_SNORM;
case DXGI_FORMAT_R16G16_SINT:
return PIPE_FORMAT_R16G16_SINT;
case DXGI_FORMAT_D32_FLOAT:
return PIPE_FORMAT_Z32_FLOAT;
case DXGI_FORMAT_R32_FLOAT:
return PIPE_FORMAT_R32_FLOAT;
case DXGI_FORMAT_R32_UINT:
return PIPE_FORMAT_R32_UINT;
case DXGI_FORMAT_R32_SINT:
return PIPE_FORMAT_R32_SINT;
case DXGI_FORMAT_D24_UNORM_S8_UINT:
return PIPE_FORMAT_Z24_UNORM_S8_UINT;
case DXGI_FORMAT_R8G8_UNORM:
return PIPE_FORMAT_R8G8_UNORM;
case DXGI_FORMAT_R8G8_UINT:
return PIPE_FORMAT_R8G8_UINT;
case DXGI_FORMAT_R8G8_SNORM:
return PIPE_FORMAT_R8G8_SNORM;
case DXGI_FORMAT_R8G8_SINT:
return PIPE_FORMAT_R8G8_SINT;
case DXGI_FORMAT_D16_UNORM:
return PIPE_FORMAT_Z16_UNORM;
case DXGI_FORMAT_R16_UNORM:
return PIPE_FORMAT_R16_UNORM;
case DXGI_FORMAT_R16_UINT:
return PIPE_FORMAT_R16_UINT;
case DXGI_FORMAT_R16_SNORM:
return PIPE_FORMAT_R16_SNORM;
case DXGI_FORMAT_R16_SINT:
return PIPE_FORMAT_R16_SINT;
case DXGI_FORMAT_R8_UNORM:
return PIPE_FORMAT_R8_UNORM;
case DXGI_FORMAT_R8_UINT:
return PIPE_FORMAT_R8_UINT;
case DXGI_FORMAT_R8_SNORM:
return PIPE_FORMAT_R8_SNORM;
case DXGI_FORMAT_R8_SINT:
return PIPE_FORMAT_R8_SINT;
case DXGI_FORMAT_A8_UNORM:
return PIPE_FORMAT_A8_UNORM;
case DXGI_FORMAT_BC1_UNORM:
return PIPE_FORMAT_DXT1_RGBA;
case DXGI_FORMAT_BC1_UNORM_SRGB:
#if HAVE_SRGB
return PIPE_FORMAT_DXT1_SRGBA;
#else
return PIPE_FORMAT_DXT1_RGBA;
#endif
case DXGI_FORMAT_BC2_UNORM:
return PIPE_FORMAT_DXT3_RGBA;
case DXGI_FORMAT_BC2_UNORM_SRGB:
#if HAVE_SRGB
return PIPE_FORMAT_DXT3_SRGBA;
#else
return PIPE_FORMAT_DXT3_RGBA;
#endif
case DXGI_FORMAT_BC3_UNORM:
return PIPE_FORMAT_DXT5_RGBA;
case DXGI_FORMAT_BC3_UNORM_SRGB:
#if HAVE_SRGB
return PIPE_FORMAT_DXT5_SRGBA;
#else
return PIPE_FORMAT_DXT5_RGBA;
#endif
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
#if HAVE_SRGB
return PIPE_FORMAT_R8G8B8A8_SRGB;
#else
return PIPE_FORMAT_R8G8B8A8_UNORM;
#endif
/* Gallium has no typeless formats. We simply use an equivalent
* typed format.
*/
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
return PIPE_FORMAT_R8G8B8A8_UNORM;
case DXGI_FORMAT_BC1_TYPELESS:
return PIPE_FORMAT_DXT1_RGBA;
case DXGI_FORMAT_BC2_TYPELESS:
return PIPE_FORMAT_DXT3_RGBA;
case DXGI_FORMAT_BC3_TYPELESS:
return PIPE_FORMAT_DXT5_RGBA;
case DXGI_FORMAT_R8_TYPELESS:
return PIPE_FORMAT_R8_UNORM;
case DXGI_FORMAT_R32G32B32A32_TYPELESS:
return PIPE_FORMAT_R32G32B32A32_UNORM;
case DXGI_FORMAT_R32G32B32_TYPELESS:
return PIPE_FORMAT_R32G32B32_UNORM;
case DXGI_FORMAT_R16G16B16A16_TYPELESS:
return PIPE_FORMAT_R16G16B16A16_UNORM;
case DXGI_FORMAT_R32G32_TYPELESS:
return PIPE_FORMAT_R32G32_UNORM;
case DXGI_FORMAT_R8G8_TYPELESS:
return PIPE_FORMAT_R8G8_UNORM;
case DXGI_FORMAT_R16_TYPELESS:
return depth ? PIPE_FORMAT_Z16_UNORM : PIPE_FORMAT_R16_UNORM;
case DXGI_FORMAT_R16G16_TYPELESS:
return PIPE_FORMAT_R16G16_UNORM;
case DXGI_FORMAT_R32_TYPELESS:
return depth ? PIPE_FORMAT_Z32_FLOAT : PIPE_FORMAT_R32_FLOAT;
case DXGI_FORMAT_R24G8_TYPELESS:
return PIPE_FORMAT_Z24_UNORM_S8_UINT;
case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
return PIPE_FORMAT_Z24X8_UNORM;
case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
return PIPE_FORMAT_Z24_UNORM_S8_UINT;
case DXGI_FORMAT_R8G8_B8G8_UNORM:
return PIPE_FORMAT_R8G8_B8G8_UNORM;
case DXGI_FORMAT_G8R8_G8B8_UNORM:
return PIPE_FORMAT_G8R8_G8B8_UNORM;
case DXGI_FORMAT_R16G16B16A16_FLOAT:
return PIPE_FORMAT_R16G16B16A16_FLOAT;
case DXGI_FORMAT_R16G16_FLOAT:
return PIPE_FORMAT_R16G16_FLOAT;
case DXGI_FORMAT_R16_FLOAT:
return PIPE_FORMAT_R16_FLOAT;
case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
return PIPE_FORMAT_R9G9B9E5_FLOAT;
case DXGI_FORMAT_R1_UNORM:
return PIPE_FORMAT_R1_UNORM;
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
case DXGI_FORMAT_R32G8X24_TYPELESS:
case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
return PIPE_FORMAT_Z32_FLOAT_S8X24_UINT;
case DXGI_FORMAT_R10G10B10A2_TYPELESS:
case DXGI_FORMAT_R10G10B10A2_UNORM:
return PIPE_FORMAT_R10G10B10A2_UNORM;
case DXGI_FORMAT_R10G10B10A2_UINT:
return PIPE_FORMAT_R10G10B10A2_UINT;
case DXGI_FORMAT_R11G11B10_FLOAT:
return PIPE_FORMAT_R11G11B10_FLOAT;
case DXGI_FORMAT_BC4_TYPELESS:
case DXGI_FORMAT_BC4_UNORM:
return PIPE_FORMAT_RGTC1_UNORM;
case DXGI_FORMAT_BC4_SNORM:
return PIPE_FORMAT_RGTC1_SNORM;
case DXGI_FORMAT_BC5_TYPELESS:
case DXGI_FORMAT_BC5_UNORM:
return PIPE_FORMAT_RGTC2_UNORM;
case DXGI_FORMAT_BC5_SNORM:
return PIPE_FORMAT_RGTC2_SNORM;
case DXGI_FORMAT_B5G6R5_UNORM:
return PIPE_FORMAT_B5G6R5_UNORM;
case DXGI_FORMAT_B5G5R5A1_UNORM:
return PIPE_FORMAT_B5G5R5A1_UNORM;
case DXGI_FORMAT_B8G8R8A8_UNORM:
return PIPE_FORMAT_B8G8R8A8_UNORM;
case DXGI_FORMAT_B8G8R8X8_UNORM:
return PIPE_FORMAT_B8G8R8X8_UNORM;
case DXGI_FORMAT_B8G8R8A8_TYPELESS:
return PIPE_FORMAT_B8G8R8A8_UNORM;
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
#if HAVE_SRGB
return PIPE_FORMAT_B8G8R8A8_SRGB;
#else
return PIPE_FORMAT_B8G8R8A8_UNORM;
#endif
case DXGI_FORMAT_B8G8R8X8_TYPELESS:
return PIPE_FORMAT_B8G8R8X8_UNORM;
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
#if HAVE_SRGB
return PIPE_FORMAT_B8G8R8X8_SRGB;
#else
return PIPE_FORMAT_B8G8R8X8_UNORM;
#endif
case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
return PIPE_FORMAT_R10G10B10A2_UNORM;
default:
DebugPrintf("%s: unsupported format %s\n",
__FUNCTION__, FormatToName(Format));
return PIPE_FORMAT_NONE;
}
}
#define CASE(fmt) case fmt: return #fmt
const char *
FormatToName(DXGI_FORMAT Format)
{
switch (Format) {
CASE(DXGI_FORMAT_UNKNOWN);
CASE(DXGI_FORMAT_R32G32B32A32_TYPELESS);
CASE(DXGI_FORMAT_R32G32B32A32_FLOAT);
CASE(DXGI_FORMAT_R32G32B32A32_UINT);
CASE(DXGI_FORMAT_R32G32B32A32_SINT);
CASE(DXGI_FORMAT_R32G32B32_TYPELESS);
CASE(DXGI_FORMAT_R32G32B32_FLOAT);
CASE(DXGI_FORMAT_R32G32B32_UINT);
CASE(DXGI_FORMAT_R32G32B32_SINT);
CASE(DXGI_FORMAT_R16G16B16A16_TYPELESS);
CASE(DXGI_FORMAT_R16G16B16A16_FLOAT);
CASE(DXGI_FORMAT_R16G16B16A16_UNORM);
CASE(DXGI_FORMAT_R16G16B16A16_UINT);
CASE(DXGI_FORMAT_R16G16B16A16_SNORM);
CASE(DXGI_FORMAT_R16G16B16A16_SINT);
CASE(DXGI_FORMAT_R32G32_TYPELESS);
CASE(DXGI_FORMAT_R32G32_FLOAT);
CASE(DXGI_FORMAT_R32G32_UINT);
CASE(DXGI_FORMAT_R32G32_SINT);
CASE(DXGI_FORMAT_R32G8X24_TYPELESS);
CASE(DXGI_FORMAT_D32_FLOAT_S8X24_UINT);
CASE(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS);
CASE(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT);
CASE(DXGI_FORMAT_R10G10B10A2_TYPELESS);
CASE(DXGI_FORMAT_R10G10B10A2_UNORM);
CASE(DXGI_FORMAT_R10G10B10A2_UINT);
CASE(DXGI_FORMAT_R11G11B10_FLOAT);
CASE(DXGI_FORMAT_R8G8B8A8_TYPELESS);
CASE(DXGI_FORMAT_R8G8B8A8_UNORM);
CASE(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
CASE(DXGI_FORMAT_R8G8B8A8_UINT);
CASE(DXGI_FORMAT_R8G8B8A8_SNORM);
CASE(DXGI_FORMAT_R8G8B8A8_SINT);
CASE(DXGI_FORMAT_R16G16_TYPELESS);
CASE(DXGI_FORMAT_R16G16_FLOAT);
CASE(DXGI_FORMAT_R16G16_UNORM);
CASE(DXGI_FORMAT_R16G16_UINT);
CASE(DXGI_FORMAT_R16G16_SNORM);
CASE(DXGI_FORMAT_R16G16_SINT);
CASE(DXGI_FORMAT_R32_TYPELESS);
CASE(DXGI_FORMAT_D32_FLOAT);
CASE(DXGI_FORMAT_R32_FLOAT);
CASE(DXGI_FORMAT_R32_UINT);
CASE(DXGI_FORMAT_R32_SINT);
CASE(DXGI_FORMAT_R24G8_TYPELESS);
CASE(DXGI_FORMAT_D24_UNORM_S8_UINT);
CASE(DXGI_FORMAT_R24_UNORM_X8_TYPELESS);
CASE(DXGI_FORMAT_X24_TYPELESS_G8_UINT);
CASE(DXGI_FORMAT_R8G8_TYPELESS);
CASE(DXGI_FORMAT_R8G8_UNORM);
CASE(DXGI_FORMAT_R8G8_UINT);
CASE(DXGI_FORMAT_R8G8_SNORM);
CASE(DXGI_FORMAT_R8G8_SINT);
CASE(DXGI_FORMAT_R16_TYPELESS);
CASE(DXGI_FORMAT_R16_FLOAT);
CASE(DXGI_FORMAT_D16_UNORM);
CASE(DXGI_FORMAT_R16_UNORM);
CASE(DXGI_FORMAT_R16_UINT);
CASE(DXGI_FORMAT_R16_SNORM);
CASE(DXGI_FORMAT_R16_SINT);
CASE(DXGI_FORMAT_R8_TYPELESS);
CASE(DXGI_FORMAT_R8_UNORM);
CASE(DXGI_FORMAT_R8_UINT);
CASE(DXGI_FORMAT_R8_SNORM);
CASE(DXGI_FORMAT_R8_SINT);
CASE(DXGI_FORMAT_A8_UNORM);
CASE(DXGI_FORMAT_R1_UNORM);
CASE(DXGI_FORMAT_R9G9B9E5_SHAREDEXP);
CASE(DXGI_FORMAT_R8G8_B8G8_UNORM);
CASE(DXGI_FORMAT_G8R8_G8B8_UNORM);
CASE(DXGI_FORMAT_BC1_TYPELESS);
CASE(DXGI_FORMAT_BC1_UNORM);
CASE(DXGI_FORMAT_BC1_UNORM_SRGB);
CASE(DXGI_FORMAT_BC2_TYPELESS);
CASE(DXGI_FORMAT_BC2_UNORM);
CASE(DXGI_FORMAT_BC2_UNORM_SRGB);
CASE(DXGI_FORMAT_BC3_TYPELESS);
CASE(DXGI_FORMAT_BC3_UNORM);
CASE(DXGI_FORMAT_BC3_UNORM_SRGB);
CASE(DXGI_FORMAT_BC4_TYPELESS);
CASE(DXGI_FORMAT_BC4_UNORM);
CASE(DXGI_FORMAT_BC4_SNORM);
CASE(DXGI_FORMAT_BC5_TYPELESS);
CASE(DXGI_FORMAT_BC5_UNORM);
CASE(DXGI_FORMAT_BC5_SNORM);
CASE(DXGI_FORMAT_B5G6R5_UNORM);
CASE(DXGI_FORMAT_B5G5R5A1_UNORM);
CASE(DXGI_FORMAT_B8G8R8A8_UNORM);
CASE(DXGI_FORMAT_B8G8R8X8_UNORM);
CASE(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM);
CASE(DXGI_FORMAT_B8G8R8A8_TYPELESS);
CASE(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB);
CASE(DXGI_FORMAT_B8G8R8X8_TYPELESS);
CASE(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB);
CASE(DXGI_FORMAT_BC6H_TYPELESS);
CASE(DXGI_FORMAT_BC6H_UF16);
CASE(DXGI_FORMAT_BC6H_SF16);
CASE(DXGI_FORMAT_BC7_TYPELESS);
CASE(DXGI_FORMAT_BC7_UNORM);
CASE(DXGI_FORMAT_BC7_UNORM_SRGB);
default:
return "???";
}
}

View File

@ -0,0 +1,45 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Format.h --
* Functions for handling formats.
*/
#ifndef FORMAT_H
#define FORMAT_H
#include "DriverIncludes.h"
enum pipe_format
FormatTranslate(DXGI_FORMAT Format, BOOL depth);
const char *
FormatToName(DXGI_FORMAT Format);
#endif

View File

@ -0,0 +1,370 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* InputAssembly.cpp --
* Functions that manipulate the input assembly stage.
*/
#include <stdio.h>
#if defined(_MSC_VER) && !defined(snprintf)
#define snprintf _snprintf
#endif
#include "InputAssembly.h"
#include "State.h"
#include "Debug.h"
#include "Format.h"
/*
* ----------------------------------------------------------------------
*
* IaSetTopology --
*
* The IaSetTopology function sets the primitive topology to
* enable drawing for the input assember.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
IaSetTopology(D3D10DDI_HDEVICE hDevice, // IN
D3D10_DDI_PRIMITIVE_TOPOLOGY PrimitiveTopology) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
enum pipe_prim_type primitive;
switch (PrimitiveTopology) {
case D3D10_DDI_PRIMITIVE_TOPOLOGY_UNDEFINED:
/* Apps might set topology to UNDEFINED when cleaning up on exit. */
primitive = PIPE_PRIM_MAX;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_POINTLIST:
primitive = PIPE_PRIM_POINTS;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_LINELIST:
primitive = PIPE_PRIM_LINES;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_LINESTRIP:
primitive = PIPE_PRIM_LINE_STRIP;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_TRIANGLELIST:
primitive = PIPE_PRIM_TRIANGLES;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP:
primitive = PIPE_PRIM_TRIANGLE_STRIP;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_LINELIST_ADJ:
primitive = PIPE_PRIM_LINES_ADJACENCY;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ:
primitive = PIPE_PRIM_LINE_STRIP_ADJACENCY;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ:
primitive = PIPE_PRIM_TRIANGLES_ADJACENCY;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ:
primitive = PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY;
break;
default:
assert(0);
primitive = PIPE_PRIM_MAX;
break;
}
pDevice->primitive = primitive;
}
/*
* ----------------------------------------------------------------------
*
* IaSetVertexBuffers --
*
* The IaSetVertexBuffers function sets vertex buffers
* for an input assembler.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
IaSetVertexBuffers(D3D10DDI_HDEVICE hDevice, // IN
UINT StartBuffer, // IN
UINT NumBuffers, // IN
__in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers, // IN
__in_ecount (NumBuffers) const UINT *pStrides, // IN
__in_ecount (NumBuffers) const UINT *pOffsets) // IN
{
static const float dummy[4] = {0.0f, 0.0f, 0.0f, 0.0f};
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_context *pipe = pDevice->pipe;
unsigned i;
for (i = 0; i < NumBuffers; i++) {
struct pipe_vertex_buffer *vb = &pDevice->vertex_buffers[StartBuffer + i];
struct pipe_resource *resource = CastPipeResource(phBuffers[i]);
Resource *res = CastResource(phBuffers[i]);
struct pipe_stream_output_target *so_target =
res ? res->so_target : NULL;
if (so_target && pDevice->draw_so_target != so_target) {
if (pDevice->draw_so_target) {
pipe_so_target_reference(&pDevice->draw_so_target, NULL);
}
pipe_so_target_reference(&pDevice->draw_so_target,
so_target);
}
if (resource) {
vb->stride = pStrides[i];
vb->buffer_offset = pOffsets[i];
if (vb->is_user_buffer) {
vb->buffer.resource = NULL;
vb->is_user_buffer = FALSE;
}
pipe_resource_reference(&vb->buffer.resource, resource);
}
else {
vb->stride = 0;
vb->buffer_offset = 0;
if (!vb->is_user_buffer) {
pipe_resource_reference(&vb->buffer.resource, NULL);
vb->is_user_buffer = TRUE;
}
vb->buffer.user = dummy;
}
}
for (i = 0; i < PIPE_MAX_ATTRIBS; ++i) {
struct pipe_vertex_buffer *vb = &pDevice->vertex_buffers[i];
/* XXX this is odd... */
if (!vb->is_user_buffer && !vb->buffer.resource) {
vb->stride = 0;
vb->buffer_offset = 0;
vb->is_user_buffer = TRUE;
vb->buffer.user = dummy;
}
}
/* Resubmit old and new vertex buffers.
*/
pipe->set_vertex_buffers(pipe, 0, PIPE_MAX_ATTRIBS, 0, FALSE, pDevice->vertex_buffers);
}
/*
* ----------------------------------------------------------------------
*
* IaSetIndexBuffer --
*
* The IaSetIndexBuffer function sets an index buffer for
* an input assembler.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
IaSetIndexBuffer(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRESOURCE hBuffer, // IN
DXGI_FORMAT Format, // IN
UINT Offset) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_resource *resource = CastPipeResource(hBuffer);
if (resource) {
pDevice->ib_offset = Offset;
switch (Format) {
case DXGI_FORMAT_R16_UINT:
pDevice->index_size = 2;
pDevice->restart_index = 0xffff;
break;
case DXGI_FORMAT_R32_UINT:
pDevice->restart_index = 0xffffffff;
pDevice->index_size = 4;
break;
default:
assert(0); /* should not happen */
pDevice->index_size = 2;
break;
}
pipe_resource_reference(&pDevice->index_buffer, resource);
} else {
pipe_resource_reference(&pDevice->index_buffer, NULL);
}
}
/*
* ----------------------------------------------------------------------
*
* CalcPrivateElementLayoutSize --
*
* The CalcPrivateElementLayoutSize 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 an element layout.
*
* ----------------------------------------------------------------------
*/
SIZE_T APIENTRY
CalcPrivateElementLayoutSize(
D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10DDIARG_CREATEELEMENTLAYOUT *pCreateElementLayout) // IN
{
return sizeof(ElementLayout);
}
/*
* ----------------------------------------------------------------------
*
* CreateElementLayout --
*
* The CreateElementLayout function creates an element layout.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CreateElementLayout(
D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10DDIARG_CREATEELEMENTLAYOUT *pCreateElementLayout, // IN
D3D10DDI_HELEMENTLAYOUT hElementLayout, // IN
D3D10DDI_HRTELEMENTLAYOUT hRTElementLayout) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
ElementLayout *pElementLayout = CastElementLayout(hElementLayout);
struct pipe_vertex_element elements[PIPE_MAX_ATTRIBS];
memset(elements, 0, sizeof elements);
unsigned num_elements = pCreateElementLayout->NumElements;
unsigned max_elements = 0;
for (unsigned i = 0; i < num_elements; i++) {
const D3D10DDIARG_INPUT_ELEMENT_DESC* pVertexElement =
&pCreateElementLayout->pVertexElements[i];
struct pipe_vertex_element *ve =
&elements[pVertexElement->InputRegister];
ve->src_offset = pVertexElement->AlignedByteOffset;
ve->vertex_buffer_index = pVertexElement->InputSlot;
ve->src_format = FormatTranslate(pVertexElement->Format, FALSE);
switch (pVertexElement->InputSlotClass) {
case D3D10_DDI_INPUT_PER_VERTEX_DATA:
ve->instance_divisor = 0;
break;
case D3D10_DDI_INPUT_PER_INSTANCE_DATA:
if (!pVertexElement->InstanceDataStepRate) {
LOG_UNSUPPORTED(!pVertexElement->InstanceDataStepRate);
ve->instance_divisor = ~0;
} else {
ve->instance_divisor = pVertexElement->InstanceDataStepRate;
}
break;
default:
assert(0);
break;
}
max_elements = MAX2(max_elements, pVertexElement->InputRegister + 1);
}
/* XXX: What do we do when there's a gap? */
if (max_elements != num_elements) {
DebugPrintf("%s: gap\n", __FUNCTION__);
}
pElementLayout->handle =
pipe->create_vertex_elements_state(pipe, max_elements, elements);
}
/*
* ----------------------------------------------------------------------
*
* DestroyElementLayout --
*
* The DestroyElementLayout function destroys the specified
* element layout object. The element layout object can be
* destoyed only if it is not currently bound to a display device.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DestroyElementLayout(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HELEMENTLAYOUT hElementLayout) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
ElementLayout *pElementLayout = CastElementLayout(hElementLayout);
pipe->delete_vertex_elements_state(pipe, pElementLayout->handle);}
/*
* ----------------------------------------------------------------------
*
* IaSetInputLayout --
*
* The IaSetInputLayout function sets an input layout for
* the input assembler.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
IaSetInputLayout(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HELEMENTLAYOUT hInputLayout) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
void *state = CastPipeInputLayout(hInputLayout);
pipe->bind_vertex_elements_state(pipe, state);
}

View File

@ -0,0 +1,63 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* InputAssembly.h --
* Functions that manipulate the input assembly stage.
*/
#ifndef INPUT_ASSEMBLY_H
#define INPUT_ASSEMBLY_H
#include "DriverIncludes.h"
void APIENTRY IaSetTopology(D3D10DDI_HDEVICE hDevice,
D3D10_DDI_PRIMITIVE_TOPOLOGY PrimitiveTopology);
void APIENTRY IaSetVertexBuffers(D3D10DDI_HDEVICE hDevice, UINT StartBuffer, UINT NumBuffers,
__in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers,
__in_ecount (NumBuffers) const UINT *pStrides,
__in_ecount (NumBuffers) const UINT *pOffsets);
void APIENTRY IaSetIndexBuffer(D3D10DDI_HDEVICE hDevice, D3D10DDI_HRESOURCE hBuffer,
DXGI_FORMAT Format, UINT Offset);
void APIENTRY IaSetInputLayout(D3D10DDI_HDEVICE hDevice, D3D10DDI_HELEMENTLAYOUT hInputLayout);
SIZE_T APIENTRY CalcPrivateElementLayoutSize(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATEELEMENTLAYOUT *pCreateElementLayout);
void APIENTRY CreateElementLayout(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATEELEMENTLAYOUT *pCreateElementLayout,
D3D10DDI_HELEMENTLAYOUT hElementLayout,
D3D10DDI_HRTELEMENTLAYOUT hRTElementLayout);
void APIENTRY DestroyElementLayout(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HELEMENTLAYOUT hElementLayout);
#endif /* INPUT_ASSEMBLY_H */

View File

@ -0,0 +1,998 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* OutputMerger.cpp --
* Functions that manipulate the output merger state.
*/
#include "OutputMerger.h"
#include "State.h"
#include "Debug.h"
#include "Format.h"
#include "util/u_framebuffer.h"
#include "util/format/u_format.h"
/*
* ----------------------------------------------------------------------
*
* CalcPrivateRenderTargetViewSize --
*
* The CalcPrivateRenderTargetViewSize 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 render target view.
*
* ----------------------------------------------------------------------
*/
SIZE_T APIENTRY
CalcPrivateRenderTargetViewSize(
D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10DDIARG_CREATERENDERTARGETVIEW *pCreateRenderTargetView) // IN
{
return sizeof(RenderTargetView);
}
/*
* ----------------------------------------------------------------------
*
* CreateRenderTargetView --
*
* The CreateRenderTargetView function creates a render target view.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CreateRenderTargetView(
D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10DDIARG_CREATERENDERTARGETVIEW *pCreateRenderTargetView, // IN
D3D10DDI_HRENDERTARGETVIEW hRenderTargetView, // IN
D3D10DDI_HRTRENDERTARGETVIEW hRTRenderTargetView) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
struct pipe_resource *resource = CastPipeResource(pCreateRenderTargetView->hDrvResource);
RenderTargetView *pRTView = CastRenderTargetView(hRenderTargetView);
struct pipe_surface desc;
memset(&desc, 0, sizeof desc);
desc.format = FormatTranslate(pCreateRenderTargetView->Format, FALSE);
switch (pCreateRenderTargetView->ResourceDimension) {
case D3D10DDIRESOURCE_BUFFER:
desc.u.buf.first_element = pCreateRenderTargetView->Buffer.FirstElement;
desc.u.buf.last_element = pCreateRenderTargetView->Buffer.NumElements - 1 +
desc.u.buf.first_element;
break;
case D3D10DDIRESOURCE_TEXTURE1D:
ASSERT(pCreateRenderTargetView->Tex1D.ArraySize != (UINT)-1);
desc.u.tex.level = pCreateRenderTargetView->Tex1D.MipSlice;
desc.u.tex.first_layer = pCreateRenderTargetView->Tex1D.FirstArraySlice;
desc.u.tex.last_layer = pCreateRenderTargetView->Tex1D.ArraySize - 1 +
desc.u.tex.first_layer;
break;
case D3D10DDIRESOURCE_TEXTURE2D:
ASSERT(pCreateRenderTargetView->Tex2D.ArraySize != (UINT)-1);
desc.u.tex.level = pCreateRenderTargetView->Tex2D.MipSlice;
desc.u.tex.first_layer = pCreateRenderTargetView->Tex2D.FirstArraySlice;
desc.u.tex.last_layer = pCreateRenderTargetView->Tex2D.ArraySize - 1 +
desc.u.tex.first_layer;
break;
case D3D10DDIRESOURCE_TEXTURE3D:
desc.u.tex.level = pCreateRenderTargetView->Tex3D.MipSlice;
desc.u.tex.first_layer = pCreateRenderTargetView->Tex3D.FirstW;
desc.u.tex.last_layer = pCreateRenderTargetView->Tex3D.WSize - 1 +
desc.u.tex.first_layer;
break;
case D3D10DDIRESOURCE_TEXTURECUBE:
ASSERT(pCreateRenderTargetView->TexCube.ArraySize != (UINT)-1);
desc.u.tex.level = pCreateRenderTargetView->TexCube.MipSlice;
desc.u.tex.first_layer = pCreateRenderTargetView->TexCube.FirstArraySlice;
desc.u.tex.last_layer = pCreateRenderTargetView->TexCube.ArraySize - 1 +
desc.u.tex.first_layer;;
break;
default:
ASSERT(0);
return;
}
pRTView->surface = pipe->create_surface(pipe, resource, &desc);
assert(pRTView->surface);
}
/*
* ----------------------------------------------------------------------
*
* DestroyRenderTargetView --
*
* The DestroyRenderTargetView function destroys the specified
* render target view object. The render target view object can
* be destoyed only if it is not currently bound to a display device.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DestroyRenderTargetView(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRENDERTARGETVIEW hRenderTargetView) // IN
{
LOG_ENTRYPOINT();
RenderTargetView *pRTView = CastRenderTargetView(hRenderTargetView);
pipe_surface_reference(&pRTView->surface, NULL);
}
/*
* ----------------------------------------------------------------------
*
* ClearRenderTargetView --
*
* The ClearRenderTargetView function clears the specified
* render target view by setting it to a constant value.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
ClearRenderTargetView(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRENDERTARGETVIEW hRenderTargetView, // IN
FLOAT pColorRGBA[4]) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
struct pipe_surface *surface = CastPipeRenderTargetView(hRenderTargetView);
union pipe_color_union clear_color;
/*
* DX10 always uses float clear color but gallium does not.
* Conversion should just be ordinary conversion. Actual clamping will
* be done later but need to make sure values exceeding int/uint range
* are handled correctly.
*/
if (util_format_is_pure_integer(surface->format)) {
if (util_format_is_pure_sint(surface->format)) {
unsigned i;
/* If only MIN_INT/UINT32 in c++ code would work... */
int min_int32 = 0x80000000;
int max_int32 = 0x7fffffff;
for (i = 0; i < 4; i++) {
float value = pColorRGBA[i];
/* This is an expanded clamp to handle NaN and integer conversion. */
if (util_is_nan(value)) {
clear_color.i[i] = 0;
} else if (value <= (float)min_int32) {
clear_color.i[i] = min_int32;
} else if (value >= (float)max_int32) {
clear_color.i[i] = max_int32;
} else {
clear_color.i[i] = value;
}
}
}
else {
assert(util_format_is_pure_uint(surface->format));
unsigned i;
unsigned max_uint32 = 0xffffffffU;
for (i = 0; i < 4; i++) {
float value = pColorRGBA[i];
/* This is an expanded clamp to handle NaN and integer conversion. */
if (!(value >= 0.0f)) {
/* Handles NaN. */
clear_color.ui[i] = 0;
} else if (value >= (float)max_uint32) {
clear_color.ui[i] = max_uint32;
} else {
clear_color.ui[i] = value;
}
}
}
}
else {
clear_color.f[0] = pColorRGBA[0];
clear_color.f[1] = pColorRGBA[1];
clear_color.f[2] = pColorRGBA[2];
clear_color.f[3] = pColorRGBA[3];
}
pipe->clear_render_target(pipe,
surface,
&clear_color,
0, 0,
surface->width,
surface->height,
TRUE);
}
/*
* ----------------------------------------------------------------------
*
* CalcPrivateDepthStencilViewSize --
*
* The CalcPrivateDepthStencilViewSize 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 depth stencil view.
*
* ----------------------------------------------------------------------
*/
SIZE_T APIENTRY
CalcPrivateDepthStencilViewSize(
D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10DDIARG_CREATEDEPTHSTENCILVIEW *pCreateDepthStencilView) // IN
{
return sizeof(DepthStencilView);
}
/*
* ----------------------------------------------------------------------
*
* CreateDepthStencilView --
*
* The CreateDepthStencilView function creates a depth stencil view.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CreateDepthStencilView(
D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10DDIARG_CREATEDEPTHSTENCILVIEW *pCreateDepthStencilView, // IN
D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView, // IN
D3D10DDI_HRTDEPTHSTENCILVIEW hRTDepthStencilView) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
struct pipe_resource *resource = CastPipeResource(pCreateDepthStencilView->hDrvResource);
DepthStencilView *pDSView = CastDepthStencilView(hDepthStencilView);
struct pipe_surface desc;
memset(&desc, 0, sizeof desc);
desc.format = FormatTranslate(pCreateDepthStencilView->Format, TRUE);
switch (pCreateDepthStencilView->ResourceDimension) {
case D3D10DDIRESOURCE_TEXTURE1D:
ASSERT(pCreateDepthStencilView->Tex1D.ArraySize != (UINT)-1);
desc.u.tex.level = pCreateDepthStencilView->Tex1D.MipSlice;
desc.u.tex.first_layer = pCreateDepthStencilView->Tex1D.FirstArraySlice;
desc.u.tex.last_layer = pCreateDepthStencilView->Tex1D.ArraySize - 1 +
desc.u.tex.first_layer;
break;
case D3D10DDIRESOURCE_TEXTURE2D:
ASSERT(pCreateDepthStencilView->Tex2D.ArraySize != (UINT)-1);
desc.u.tex.level = pCreateDepthStencilView->Tex2D.MipSlice;
desc.u.tex.first_layer = pCreateDepthStencilView->Tex2D.FirstArraySlice;
desc.u.tex.last_layer = pCreateDepthStencilView->Tex2D.ArraySize - 1 +
desc.u.tex.first_layer;
break;
case D3D10DDIRESOURCE_TEXTURECUBE:
ASSERT(pCreateDepthStencilView->TexCube.ArraySize != (UINT)-1);
desc.u.tex.level = pCreateDepthStencilView->TexCube.MipSlice;
desc.u.tex.first_layer = pCreateDepthStencilView->TexCube.FirstArraySlice;
desc.u.tex.last_layer = pCreateDepthStencilView->TexCube.ArraySize - 1 +
desc.u.tex.first_layer;
break;
default:
ASSERT(0);
return;
}
pDSView->surface = pipe->create_surface(pipe, resource, &desc);
assert(pDSView->surface);
}
/*
* ----------------------------------------------------------------------
*
* DestroyDepthStencilView --
*
* The DestroyDepthStencilView function destroys the specified
* depth stencil view object. The depth stencil view object can
* be destoyed only if it is not currently bound to a display device.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DestroyDepthStencilView(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView) // IN
{
LOG_ENTRYPOINT();
DepthStencilView *pDSView = CastDepthStencilView(hDepthStencilView);
pipe_surface_reference(&pDSView->surface, NULL);
}
/*
* ----------------------------------------------------------------------
*
* ClearDepthStencilView --
*
* The ClearDepthStencilView function clears the specified
* currently bound depth-stencil view.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
ClearDepthStencilView(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView, // IN
UINT Flags, // IN
FLOAT Depth, // IN
UINT8 Stencil) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
struct pipe_surface *surface = CastPipeDepthStencilView(hDepthStencilView);
unsigned flags = 0;
if (Flags & D3D10_DDI_CLEAR_DEPTH) {
flags |= PIPE_CLEAR_DEPTH;
}
if (Flags & D3D10_DDI_CLEAR_STENCIL) {
flags |= PIPE_CLEAR_STENCIL;
}
pipe->clear_depth_stencil(pipe,
surface,
flags,
Depth,
Stencil,
0, 0,
surface->width,
surface->height,
TRUE);
}
/*
* ----------------------------------------------------------------------
*
* CalcPrivateBlendStateSize --
*
* The CalcPrivateBlendStateSize 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 blend state.
*
* ----------------------------------------------------------------------
*/
SIZE_T APIENTRY
CalcPrivateBlendStateSize(D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10_DDI_BLEND_DESC *pBlendDesc) // IN
{
return sizeof(BlendState);
}
/*
* ----------------------------------------------------------------------
*
* CalcPrivateBlendStateSize1 --
*
* The CalcPrivateBlendStateSize 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 blend state.
*
* ----------------------------------------------------------------------
*/
SIZE_T APIENTRY
CalcPrivateBlendStateSize1(D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10_1_DDI_BLEND_DESC *pBlendDesc) // IN
{
return sizeof(BlendState);
}
/*
* ----------------------------------------------------------------------
*
* translateBlend --
*
* Translate blend function from svga3d to gallium representation.
*
* ----------------------------------------------------------------------
*/
static uint
translateBlendOp(D3D10_DDI_BLEND_OP op)
{
switch (op) {
case D3D10_DDI_BLEND_OP_ADD:
return PIPE_BLEND_ADD;
case D3D10_DDI_BLEND_OP_SUBTRACT:
return PIPE_BLEND_SUBTRACT;
case D3D10_DDI_BLEND_OP_REV_SUBTRACT:
return PIPE_BLEND_REVERSE_SUBTRACT;
case D3D10_DDI_BLEND_OP_MIN:
return PIPE_BLEND_MIN;
case D3D10_DDI_BLEND_OP_MAX:
return PIPE_BLEND_MAX;
default:
assert(0);
return PIPE_BLEND_ADD;
}
}
/*
* ----------------------------------------------------------------------
*
* translateBlend --
*
* Translate blend factor from svga3d to gallium representation.
*
* ----------------------------------------------------------------------
*/
static uint
translateBlend(Device *pDevice,
D3D10_DDI_BLEND blend)
{
if (!pDevice->max_dual_source_render_targets) {
switch (blend) {
case D3D10_DDI_BLEND_SRC1_COLOR:
case D3D10_DDI_BLEND_SRC1_ALPHA:
LOG_UNSUPPORTED(TRUE);
return D3D10_DDI_BLEND_ZERO;
case D3D10_DDI_BLEND_INV_SRC1_COLOR:
case D3D10_DDI_BLEND_INV_SRC1_ALPHA:
LOG_UNSUPPORTED(TRUE);
return D3D10_DDI_BLEND_ONE;
default:
break;
}
}
switch (blend) {
case D3D10_DDI_BLEND_ZERO:
return PIPE_BLENDFACTOR_ZERO;
case D3D10_DDI_BLEND_ONE:
return PIPE_BLENDFACTOR_ONE;
case D3D10_DDI_BLEND_SRC_COLOR:
return PIPE_BLENDFACTOR_SRC_COLOR;
case D3D10_DDI_BLEND_INV_SRC_COLOR:
return PIPE_BLENDFACTOR_INV_SRC_COLOR;
case D3D10_DDI_BLEND_SRC_ALPHA:
return PIPE_BLENDFACTOR_SRC_ALPHA;
case D3D10_DDI_BLEND_INV_SRC_ALPHA:
return PIPE_BLENDFACTOR_INV_SRC_ALPHA;
case D3D10_DDI_BLEND_DEST_ALPHA:
return PIPE_BLENDFACTOR_DST_ALPHA;
case D3D10_DDI_BLEND_INV_DEST_ALPHA:
return PIPE_BLENDFACTOR_INV_DST_ALPHA;
case D3D10_DDI_BLEND_DEST_COLOR:
return PIPE_BLENDFACTOR_DST_COLOR;
case D3D10_DDI_BLEND_INV_DEST_COLOR:
return PIPE_BLENDFACTOR_INV_DST_COLOR;
case D3D10_DDI_BLEND_SRC_ALPHASAT:
return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE;
case D3D10_DDI_BLEND_BLEND_FACTOR:
return PIPE_BLENDFACTOR_CONST_COLOR;
case D3D10_DDI_BLEND_INVBLEND_FACTOR:
return PIPE_BLENDFACTOR_INV_CONST_COLOR;
case D3D10_DDI_BLEND_SRC1_COLOR:
return PIPE_BLENDFACTOR_SRC1_COLOR;
case D3D10_DDI_BLEND_INV_SRC1_COLOR:
return PIPE_BLENDFACTOR_INV_SRC1_COLOR;
case D3D10_DDI_BLEND_SRC1_ALPHA:
return PIPE_BLENDFACTOR_SRC1_ALPHA;
case D3D10_DDI_BLEND_INV_SRC1_ALPHA:
return PIPE_BLENDFACTOR_INV_SRC1_ALPHA;
default:
assert(0);
return PIPE_BLENDFACTOR_ONE;
}
}
/*
* ----------------------------------------------------------------------
*
* CreateBlendState --
*
* The CreateBlendState function creates a blend state.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CreateBlendState(D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10_DDI_BLEND_DESC *pBlendDesc, // IN
D3D10DDI_HBLENDSTATE hBlendState, // IN
D3D10DDI_HRTBLENDSTATE hRTBlendState) // IN
{
unsigned i;
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_context *pipe = pDevice->pipe;
BlendState *pBlendState = CastBlendState(hBlendState);
struct pipe_blend_state state;
memset(&state, 0, sizeof state);
for (i = 0; i < MIN2(PIPE_MAX_COLOR_BUFS, D3D10_DDI_SIMULTANEOUS_RENDER_TARGET_COUNT); ++i) {
state.rt[i].blend_enable = pBlendDesc->BlendEnable[i];
state.rt[i].colormask = pBlendDesc->RenderTargetWriteMask[i];
if (pBlendDesc->BlendEnable[0] != pBlendDesc->BlendEnable[i] ||
pBlendDesc->RenderTargetWriteMask[0] != pBlendDesc->RenderTargetWriteMask[i]) {
state.independent_blend_enable = 1;
}
}
state.rt[0].rgb_func = translateBlendOp(pBlendDesc->BlendOp);
if (pBlendDesc->BlendOp == D3D10_DDI_BLEND_OP_MIN ||
pBlendDesc->BlendOp == D3D10_DDI_BLEND_OP_MAX) {
state.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
state.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
} else {
state.rt[0].rgb_src_factor = translateBlend(pDevice, pBlendDesc->SrcBlend);
state.rt[0].rgb_dst_factor = translateBlend(pDevice, pBlendDesc->DestBlend);
}
state.rt[0].alpha_func = translateBlendOp(pBlendDesc->BlendOpAlpha);
if (pBlendDesc->BlendOpAlpha == D3D10_DDI_BLEND_OP_MIN ||
pBlendDesc->BlendOpAlpha == D3D10_DDI_BLEND_OP_MAX) {
state.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
state.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
} else {
state.rt[0].alpha_src_factor = translateBlend(pDevice, pBlendDesc->SrcBlendAlpha);
state.rt[0].alpha_dst_factor = translateBlend(pDevice, pBlendDesc->DestBlendAlpha);
}
/*
* Propagate to all the other rendertargets
*/
for (i = 1; i < MIN2(PIPE_MAX_COLOR_BUFS, D3D10_DDI_SIMULTANEOUS_RENDER_TARGET_COUNT); ++i) {
state.rt[i].rgb_func = state.rt[0].rgb_func;
state.rt[i].rgb_src_factor = state.rt[0].rgb_src_factor;
state.rt[i].rgb_dst_factor = state.rt[0].rgb_dst_factor;
state.rt[i].alpha_func = state.rt[0].alpha_func;
state.rt[i].alpha_src_factor = state.rt[0].alpha_src_factor;
state.rt[i].alpha_dst_factor = state.rt[0].alpha_dst_factor;
}
state.alpha_to_coverage = pBlendDesc->AlphaToCoverageEnable;
pBlendState->handle = pipe->create_blend_state(pipe, &state);
}
/*
* ----------------------------------------------------------------------
*
* CreateBlendState1 --
*
* The CreateBlendState function creates a blend state.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CreateBlendState1(D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10_1_DDI_BLEND_DESC *pBlendDesc, // IN
D3D10DDI_HBLENDSTATE hBlendState, // IN
D3D10DDI_HRTBLENDSTATE hRTBlendState) // IN
{
unsigned i;
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_context *pipe = pDevice->pipe;
BlendState *pBlendState = CastBlendState(hBlendState);
struct pipe_blend_state state;
memset(&state, 0, sizeof state);
state.alpha_to_coverage = pBlendDesc->AlphaToCoverageEnable;
state.independent_blend_enable = pBlendDesc->IndependentBlendEnable;
for (i = 0; i < MIN2(PIPE_MAX_COLOR_BUFS, D3D10_DDI_SIMULTANEOUS_RENDER_TARGET_COUNT); ++i) {
state.rt[i].blend_enable = pBlendDesc->RenderTarget[i].BlendEnable;
state.rt[i].colormask = pBlendDesc->RenderTarget[i].RenderTargetWriteMask;
state.rt[i].rgb_func = translateBlendOp(pBlendDesc->RenderTarget[i].BlendOp);
if (pBlendDesc->RenderTarget[i].BlendOp == D3D10_DDI_BLEND_OP_MIN ||
pBlendDesc->RenderTarget[i].BlendOp == D3D10_DDI_BLEND_OP_MAX) {
state.rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
state.rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
} else {
state.rt[i].rgb_src_factor = translateBlend(pDevice, pBlendDesc->RenderTarget[i].SrcBlend);
state.rt[i].rgb_dst_factor = translateBlend(pDevice, pBlendDesc->RenderTarget[i].DestBlend);
}
state.rt[i].alpha_func = translateBlendOp(pBlendDesc->RenderTarget[i].BlendOpAlpha);
if (pBlendDesc->RenderTarget[i].BlendOpAlpha == D3D10_DDI_BLEND_OP_MIN ||
pBlendDesc->RenderTarget[i].BlendOpAlpha == D3D10_DDI_BLEND_OP_MAX) {
state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
} else {
state.rt[i].alpha_src_factor = translateBlend(pDevice, pBlendDesc->RenderTarget[i].SrcBlendAlpha);
state.rt[i].alpha_dst_factor = translateBlend(pDevice, pBlendDesc->RenderTarget[i].DestBlendAlpha);
}
}
pBlendState->handle = pipe->create_blend_state(pipe, &state);
}
/*
* ----------------------------------------------------------------------
*
* DestroyBlendState --
*
* The DestroyBlendState function destroys the specified blend
* state object. The blend state object can be destoyed only if
* it is not currently bound to a display device.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DestroyBlendState(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HBLENDSTATE hBlendState) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
BlendState *pBlendState = CastBlendState(hBlendState);
pipe->delete_blend_state(pipe, pBlendState->handle);
}
/*
* ----------------------------------------------------------------------
*
* SetBlendState --
*
* The SetBlendState function sets a blend state.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
SetBlendState(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HBLENDSTATE hState, // IN
const FLOAT pBlendFactor[4], // IN
UINT SampleMask) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
void *state = CastPipeBlendState(hState);
pipe->bind_blend_state(pipe, state);
struct pipe_blend_color color;
color.color[0] = pBlendFactor[0];
color.color[1] = pBlendFactor[1];
color.color[2] = pBlendFactor[2];
color.color[3] = pBlendFactor[3];
pipe->set_blend_color(pipe, &color);
pipe->set_sample_mask(pipe, SampleMask);
}
/*
* ----------------------------------------------------------------------
*
* SetRenderTargets --
*
* Set the rendertargets.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
SetRenderTargets(D3D10DDI_HDEVICE hDevice, // IN
__in_ecount (NumViews)
const D3D10DDI_HRENDERTARGETVIEW *phRenderTargetView, // IN
UINT RTargets, // IN
UINT ClearTargets, // IN
D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_context *pipe = pDevice->pipe;
pDevice->fb.nr_cbufs = 0;
for (unsigned i = 0; i < RTargets; ++i) {
pipe_surface_reference(&pDevice->fb.cbufs[i],
CastPipeRenderTargetView(phRenderTargetView[i]));
if (pDevice->fb.cbufs[i]) {
pDevice->fb.nr_cbufs = i + 1;
}
}
for (unsigned i = RTargets; i < PIPE_MAX_COLOR_BUFS; ++i) {
pipe_surface_reference(&pDevice->fb.cbufs[i], NULL);
}
pipe_surface_reference(&pDevice->fb.zsbuf,
CastPipeDepthStencilView(hDepthStencilView));
/*
* Calculate the width/height fields for this framebuffer. D3D10
* actually specifies that they be identical for all bound views.
*/
unsigned width, height;
util_framebuffer_min_size(&pDevice->fb, &width, &height);
pDevice->fb.width = width;
pDevice->fb.height = height;
pipe->set_framebuffer_state(pipe, &pDevice->fb);
}
/*
* ----------------------------------------------------------------------
*
* CalcPrivateDepthStencilStateSize --
*
* The CalcPrivateDepthStencilStateSize 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 depth stencil state.
*
* ----------------------------------------------------------------------
*/
SIZE_T APIENTRY
CalcPrivateDepthStencilStateSize(
D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10_DDI_DEPTH_STENCIL_DESC *pDepthStencilDesc) // IN
{
return sizeof(DepthStencilState);
}
/*
* ----------------------------------------------------------------------
*
* translateComparison --
*
* Translate comparison function from DX10 to gallium representation.
*
* ----------------------------------------------------------------------
*/
static uint
translateComparison(D3D10_DDI_COMPARISON_FUNC Func)
{
switch (Func) {
case D3D10_DDI_COMPARISON_NEVER:
return PIPE_FUNC_NEVER;
case D3D10_DDI_COMPARISON_LESS:
return PIPE_FUNC_LESS;
case D3D10_DDI_COMPARISON_EQUAL:
return PIPE_FUNC_EQUAL;
case D3D10_DDI_COMPARISON_LESS_EQUAL:
return PIPE_FUNC_LEQUAL;
case D3D10_DDI_COMPARISON_GREATER:
return PIPE_FUNC_GREATER;
case D3D10_DDI_COMPARISON_NOT_EQUAL:
return PIPE_FUNC_NOTEQUAL;
case D3D10_DDI_COMPARISON_GREATER_EQUAL:
return PIPE_FUNC_GEQUAL;
case D3D10_DDI_COMPARISON_ALWAYS:
return PIPE_FUNC_ALWAYS;
default:
assert(0);
return PIPE_FUNC_ALWAYS;
}
}
/*
* ----------------------------------------------------------------------
*
* translateStencilOp --
*
* Translate stencil op from DX10 to gallium representation.
*
* ----------------------------------------------------------------------
*/
static uint
translateStencilOp(D3D10_DDI_STENCIL_OP StencilOp)
{
switch (StencilOp) {
case D3D10_DDI_STENCIL_OP_KEEP:
return PIPE_STENCIL_OP_KEEP;
case D3D10_DDI_STENCIL_OP_ZERO:
return PIPE_STENCIL_OP_ZERO;
case D3D10_DDI_STENCIL_OP_REPLACE:
return PIPE_STENCIL_OP_REPLACE;
case D3D10_DDI_STENCIL_OP_INCR_SAT:
return PIPE_STENCIL_OP_INCR;
case D3D10_DDI_STENCIL_OP_DECR_SAT:
return PIPE_STENCIL_OP_DECR;
case D3D10_DDI_STENCIL_OP_INVERT:
return PIPE_STENCIL_OP_INVERT;
case D3D10_DDI_STENCIL_OP_INCR:
return PIPE_STENCIL_OP_INCR_WRAP;
case D3D10_DDI_STENCIL_OP_DECR:
return PIPE_STENCIL_OP_DECR_WRAP;
default:
assert(0);
return PIPE_STENCIL_OP_KEEP;
}
}
/*
* ----------------------------------------------------------------------
*
* CreateDepthStencilState --
*
* The CreateDepthStencilState function creates a depth stencil state.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CreateDepthStencilState(
D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10_DDI_DEPTH_STENCIL_DESC *pDepthStencilDesc, // IN
D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState, // IN
D3D10DDI_HRTDEPTHSTENCILSTATE hRTDepthStencilState) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
DepthStencilState *pDepthStencilState = CastDepthStencilState(hDepthStencilState);
struct pipe_depth_stencil_alpha_state state;
memset(&state, 0, sizeof state);
/* Depth. */
state.depth_enabled = (pDepthStencilDesc->DepthEnable ? 1 : 0);
state.depth_writemask = (pDepthStencilDesc->DepthWriteMask ? 1 : 0);
state.depth_func = translateComparison(pDepthStencilDesc->DepthFunc);
/* Stencil. */
if (pDepthStencilDesc->StencilEnable) {
struct pipe_stencil_state *face0 = &state.stencil[0];
struct pipe_stencil_state *face1 = &state.stencil[1];
face0->enabled = 1;
face0->func = translateComparison(pDepthStencilDesc->FrontFace.StencilFunc);
face0->fail_op = translateStencilOp(pDepthStencilDesc->FrontFace.StencilFailOp);
face0->zpass_op = translateStencilOp(pDepthStencilDesc->FrontFace.StencilPassOp);
face0->zfail_op = translateStencilOp(pDepthStencilDesc->FrontFace.StencilDepthFailOp);
face0->valuemask = pDepthStencilDesc->StencilReadMask;
face0->writemask = pDepthStencilDesc->StencilWriteMask;
face1->enabled = 1;
face1->func = translateComparison(pDepthStencilDesc->BackFace.StencilFunc);
face1->fail_op = translateStencilOp(pDepthStencilDesc->BackFace.StencilFailOp);
face1->zpass_op = translateStencilOp(pDepthStencilDesc->BackFace.StencilPassOp);
face1->zfail_op = translateStencilOp(pDepthStencilDesc->BackFace.StencilDepthFailOp);
face1->valuemask = pDepthStencilDesc->StencilReadMask;
face1->writemask = pDepthStencilDesc->StencilWriteMask;
#ifdef DEBUG
if (!pDepthStencilDesc->FrontEnable) {
ASSERT(face0->func == PIPE_FUNC_ALWAYS);
ASSERT(face0->fail_op == PIPE_STENCIL_OP_KEEP);
ASSERT(face0->zpass_op == PIPE_STENCIL_OP_KEEP);
ASSERT(face0->zfail_op == PIPE_STENCIL_OP_KEEP);
}
if (!pDepthStencilDesc->BackEnable) {
ASSERT(face1->func == PIPE_FUNC_ALWAYS);
ASSERT(face1->fail_op == PIPE_STENCIL_OP_KEEP);
ASSERT(face1->zpass_op == PIPE_STENCIL_OP_KEEP);
ASSERT(face1->zfail_op == PIPE_STENCIL_OP_KEEP);
}
#endif
}
pDepthStencilState->handle =
pipe->create_depth_stencil_alpha_state(pipe, &state);
}
/*
* ----------------------------------------------------------------------
*
* DestroyDepthStencilState --
*
* The CreateDepthStencilState function creates a depth stencil state.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DestroyDepthStencilState(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
DepthStencilState *pDepthStencilState = CastDepthStencilState(hDepthStencilState);
pipe->delete_depth_stencil_alpha_state(pipe, pDepthStencilState->handle);
}
/*
* ----------------------------------------------------------------------
*
* SetDepthStencilState --
*
* The SetDepthStencilState function sets a depth-stencil state.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
SetDepthStencilState(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HDEPTHSTENCILSTATE hState, // IN
UINT StencilRef) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
void *state = CastPipeDepthStencilState(hState);
struct pipe_stencil_ref psr;
psr.ref_value[0] = StencilRef;
psr.ref_value[1] = StencilRef;
pipe->bind_depth_stencil_alpha_state(pipe, state);
pipe->set_stencil_ref(pipe, psr);
}

View File

@ -0,0 +1,114 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* OutputMerger.h --
* Functions that manipulate the output merger state.
*/
#ifndef OUTPUT_MERGER_H
#define OUTPUT_MERGER_H
#include "DriverIncludes.h"
SIZE_T APIENTRY CalcPrivateRenderTargetViewSize(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATERENDERTARGETVIEW *pCreateRenderTargetView);
void APIENTRY CreateRenderTargetView(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATERENDERTARGETVIEW *pCreateRenderTargetView,
D3D10DDI_HRENDERTARGETVIEW hRenderTargetView,
D3D10DDI_HRTRENDERTARGETVIEW hRTRenderTargetView);
void APIENTRY DestroyRenderTargetView(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HRENDERTARGETVIEW hRenderTargetView);
void APIENTRY ClearRenderTargetView(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HRENDERTARGETVIEW hRenderTargetView,
FLOAT pColorRGBA[4]);
SIZE_T APIENTRY CalcPrivateDepthStencilViewSize(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATEDEPTHSTENCILVIEW *pCreateDepthStencilView);
void APIENTRY CreateDepthStencilView(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATEDEPTHSTENCILVIEW *pCreateDepthStencilView,
D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView,
D3D10DDI_HRTDEPTHSTENCILVIEW hRTDepthStencilView);
void APIENTRY DestroyDepthStencilView(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView);
void APIENTRY ClearDepthStencilView(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView,
UINT Flags, FLOAT Depth, UINT8 Stencil);
SIZE_T APIENTRY CalcPrivateBlendStateSize(D3D10DDI_HDEVICE hDevice,
__in const D3D10_DDI_BLEND_DESC *pBlendDesc);
SIZE_T APIENTRY CalcPrivateBlendStateSize1(D3D10DDI_HDEVICE hDevice,
__in const D3D10_1_DDI_BLEND_DESC *pBlendDesc);
void APIENTRY CreateBlendState(D3D10DDI_HDEVICE hDevice,
__in const D3D10_DDI_BLEND_DESC *pBlendDesc,
D3D10DDI_HBLENDSTATE hBlendState,
D3D10DDI_HRTBLENDSTATE hRTBlendState);
void APIENTRY CreateBlendState1(D3D10DDI_HDEVICE hDevice,
__in const D3D10_1_DDI_BLEND_DESC *pBlendDesc,
D3D10DDI_HBLENDSTATE hBlendState,
D3D10DDI_HRTBLENDSTATE hRTBlendState);
void APIENTRY DestroyBlendState(D3D10DDI_HDEVICE hDevice, D3D10DDI_HBLENDSTATE hBlendState);
void APIENTRY SetBlendState(D3D10DDI_HDEVICE hDevice, D3D10DDI_HBLENDSTATE hState,
const FLOAT pBlendFactor[4], UINT SampleMask);
void APIENTRY SetRenderTargets(
D3D10DDI_HDEVICE hDevice,
__in_ecount (NumViews) const D3D10DDI_HRENDERTARGETVIEW *phRenderTargetView,
UINT RTargets, UINT ClearTargets, D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView);
SIZE_T APIENTRY CalcPrivateDepthStencilStateSize(
D3D10DDI_HDEVICE hDevice,
__in const D3D10_DDI_DEPTH_STENCIL_DESC *pDepthStencilDesc);
void APIENTRY CreateDepthStencilState(
D3D10DDI_HDEVICE hDevice,
__in const D3D10_DDI_DEPTH_STENCIL_DESC *pDepthStencilDesc,
D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState,
D3D10DDI_HRTDEPTHSTENCILSTATE hRTDepthStencilState);
void APIENTRY DestroyDepthStencilState(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState);
void APIENTRY SetDepthStencilState(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HDEPTHSTENCILSTATE hState, UINT StencilRef);
#endif /* OUTPUT_MERGER_H */

View File

@ -0,0 +1,454 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Query.cpp --
* Functions that manipulate query resources.
*/
#include "Query.h"
#include "State.h"
#include "Debug.h"
/*
* ----------------------------------------------------------------------
*
* CalcPrivateQuerySize --
*
* The CalcPrivateQuerySize 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 query.
*
* ----------------------------------------------------------------------
*/
SIZE_T APIENTRY
CalcPrivateQuerySize(D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10DDIARG_CREATEQUERY *pCreateQuery) // IN
{
return sizeof(Query);
}
static uint
TranslateQueryType(D3D10DDI_QUERY query)
{
switch (query) {
case D3D10DDI_QUERY_EVENT:
return PIPE_QUERY_GPU_FINISHED;
case D3D10DDI_QUERY_OCCLUSION:
return PIPE_QUERY_OCCLUSION_COUNTER;
case D3D10DDI_QUERY_TIMESTAMP:
return PIPE_QUERY_TIMESTAMP;
case D3D10DDI_QUERY_TIMESTAMPDISJOINT:
return PIPE_QUERY_TIMESTAMP_DISJOINT;
case D3D10DDI_QUERY_PIPELINESTATS:
return PIPE_QUERY_PIPELINE_STATISTICS;
case D3D10DDI_QUERY_OCCLUSIONPREDICATE:
return PIPE_QUERY_OCCLUSION_PREDICATE;
case D3D10DDI_QUERY_STREAMOUTPUTSTATS:
return PIPE_QUERY_SO_STATISTICS;
case D3D10DDI_QUERY_STREAMOVERFLOWPREDICATE:
return PIPE_QUERY_SO_OVERFLOW_PREDICATE;
default:
LOG_UNSUPPORTED(TRUE);
return PIPE_QUERY_TYPES;
}
}
/*
* ----------------------------------------------------------------------
*
* CreateQuery --
*
* The CreateQuery function creates driver-side resources for a
* query that the Microsoft Direct3D runtime subsequently issues
* for processing.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CreateQuery(D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10DDIARG_CREATEQUERY *pCreateQuery, // IN
D3D10DDI_HQUERY hQuery, // IN
D3D10DDI_HRTQUERY hRTQuery) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_context *pipe = pDevice->pipe;
Query *pQuery = CastQuery(hQuery);
memset(pQuery, 0, sizeof *pQuery);
pQuery->Type = pCreateQuery->Query;
pQuery->Flags = pCreateQuery->MiscFlags;
pQuery->pipe_type = TranslateQueryType(pCreateQuery->Query);
if (pQuery->pipe_type < PIPE_QUERY_TYPES) {
pQuery->handle = pipe->create_query(pipe, pQuery->pipe_type, 0);
}
}
/*
* ----------------------------------------------------------------------
*
* DestroyQuery --
*
* The DestroyQuery function releases resources for a query.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DestroyQuery(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HQUERY hQuery) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
Query *pQuery = CastQuery(hQuery);
if (pQuery->handle) {
pipe->destroy_query(pipe, pQuery->handle);
}
}
/*
* ----------------------------------------------------------------------
*
* QueryBegin --
*
* The QueryBegin function marks the beginning of a sequence of
* graphics commands for a query and transitions the query to the
* "building" state.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
QueryBegin(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HQUERY hQuery) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_context *pipe = pDevice->pipe;
Query *pQuery = CastQuery(hQuery);
struct pipe_query *state = CastPipeQuery(hQuery);
if (state) {
assert(pQuery->pipe_type < PIPE_QUERY_TYPES);
pipe->begin_query(pipe, state);
}
}
/*
* ----------------------------------------------------------------------
*
* QueryEnd --
*
* The QueryEnd function marks the end of a sequence of graphics
* commands for a query and transitions the query to the
* "issued" state.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
QueryEnd(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HQUERY hQuery) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_context *pipe = pDevice->pipe;
Query *pQuery = CastQuery(hQuery);
struct pipe_query *state = pQuery->handle;
pQuery->SeqNo = ++pDevice->LastEmittedQuerySeqNo;
pQuery->GetDataCount = 0;
if (state) {
pipe->end_query(pipe, state);
}
}
/*
* ----------------------------------------------------------------------
*
* QueryGetData --
*
* The QueryGetData function polls for the state of a query operation.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
QueryGetData(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HQUERY hQuery, // IN
__out_bcount_full_opt (DataSize) void *pData, // OUT
UINT DataSize, // IN
UINT Flags) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_context *pipe = pDevice->pipe;
Query *pQuery = CastQuery(hQuery);
struct pipe_query *state = pQuery->handle;
/*
* Never return data for recently emitted queries immediately, to make
* wgfasync happy.
*/
if (DataSize == 0 &&
(pQuery->SeqNo - pDevice->LastFinishedQuerySeqNo) > 0 &&
(pQuery->GetDataCount++) == 0) {
SetError(hDevice, DXGI_DDI_ERR_WASSTILLDRAWING);
return;
}
boolean wait = !!(Flags & D3D10_DDI_GET_DATA_DO_NOT_FLUSH);
union pipe_query_result result;
memset(&result, 0, sizeof result);
boolean ret;
if (state) {
ret = pipe->get_query_result(pipe, state, wait, &result);
} else {
LOG_UNSUPPORTED(TRUE);
ret = TRUE;
}
if (!ret) {
SetError(hDevice, DXGI_DDI_ERR_WASSTILLDRAWING);
return;
}
if (pData) {
switch (pQuery->Type) {
case D3D10DDI_QUERY_EVENT:
case D3D10DDI_QUERY_OCCLUSIONPREDICATE:
case D3D10DDI_QUERY_STREAMOVERFLOWPREDICATE:
*(BOOL *)pData = result.b;
break;
case D3D10DDI_QUERY_OCCLUSION:
case D3D10DDI_QUERY_TIMESTAMP:
*(UINT64 *)pData = result.u64;
break;
case D3D10DDI_QUERY_TIMESTAMPDISJOINT:
{
D3D10_DDI_QUERY_DATA_TIMESTAMP_DISJOINT *pResult =
(D3D10_DDI_QUERY_DATA_TIMESTAMP_DISJOINT *)pData;
pResult->Frequency = result.timestamp_disjoint.frequency;
pResult->Disjoint = result.timestamp_disjoint.disjoint;
}
break;
case D3D10DDI_QUERY_PIPELINESTATS:
{
D3D10_DDI_QUERY_DATA_PIPELINE_STATISTICS *pResult =
(D3D10_DDI_QUERY_DATA_PIPELINE_STATISTICS *)pData;
pResult->IAVertices = result.pipeline_statistics.ia_vertices;
pResult->IAPrimitives = result.pipeline_statistics.ia_primitives;
pResult->VSInvocations = result.pipeline_statistics.vs_invocations;
pResult->GSInvocations = result.pipeline_statistics.gs_invocations;
pResult->GSPrimitives = result.pipeline_statistics.gs_primitives;
pResult->CInvocations = result.pipeline_statistics.c_invocations;
pResult->CPrimitives = result.pipeline_statistics.c_primitives;
pResult->PSInvocations = result.pipeline_statistics.ps_invocations;
//pResult->HSInvocations = result.pipeline_statistics.hs_invocations;
//pResult->DSInvocations = result.pipeline_statistics.ds_invocations;
//pResult->CSInvocations = result.pipeline_statistics.cs_invocations;
}
break;
case D3D10DDI_QUERY_STREAMOUTPUTSTATS:
{
D3D10_DDI_QUERY_DATA_SO_STATISTICS *pResult =
(D3D10_DDI_QUERY_DATA_SO_STATISTICS *)pData;
pResult->NumPrimitivesWritten = result.so_statistics.num_primitives_written;
pResult->PrimitivesStorageNeeded = result.so_statistics.primitives_storage_needed;
}
break;
default:
assert(0);
break;
}
}
/*
* Keep track of the last finished query, as wgfasync checks that queries
* are completed in order.
*/
if ((pQuery->SeqNo - pDevice->LastFinishedQuerySeqNo) > 0) {
pDevice->LastFinishedQuerySeqNo = pQuery->SeqNo;
}
pQuery->GetDataCount = 0x80000000;
}
/*
* ----------------------------------------------------------------------
*
* SetPredication --
*
* The SetPredication function specifies whether rendering and
* resource-manipulation commands that follow are actually performed.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
SetPredication(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HQUERY hQuery, // IN
BOOL PredicateValue) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
struct pipe_context *pipe = pDevice->pipe;
Query *pQuery = CastQuery(hQuery);
struct pipe_query *state = CastPipeQuery(hQuery);
enum pipe_render_cond_flag wait;
wait = (pQuery && pQuery->Flags & D3D10DDI_QUERY_MISCFLAG_PREDICATEHINT) ?
PIPE_RENDER_COND_NO_WAIT : PIPE_RENDER_COND_WAIT;
pipe->render_condition(pipe, state, PredicateValue, wait);
pDevice->pPredicate = pQuery;
pDevice->PredicateValue = PredicateValue;
}
/*
* ----------------------------------------------------------------------
*
* CheckPredicate --
*
* Check predicate value and whether to draw or not.
*
* ----------------------------------------------------------------------
*/
BOOL
CheckPredicate(Device *pDevice)
{
Query *pQuery = pDevice->pPredicate;
if (!pQuery) {
return TRUE;
}
assert(pQuery->Type == D3D10DDI_QUERY_OCCLUSIONPREDICATE ||
pQuery->Type == D3D10DDI_QUERY_STREAMOVERFLOWPREDICATE);
struct pipe_context *pipe = pDevice->pipe;
struct pipe_query *query = pQuery->handle;
assert(query);
union pipe_query_result result;
memset(&result, 0, sizeof result);
boolean ret;
ret = pipe->get_query_result(pipe, query, TRUE, &result);
assert(ret == TRUE);
if (!ret) {
return TRUE;
}
if (!!result.b == !!pDevice->PredicateValue) {
return FALSE;
}
return TRUE;
}
/*
* ----------------------------------------------------------------------
*
* CheckCounterInfo --
*
* The CheckCounterInfo function determines global information that
* is related to manipulating counters.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CheckCounterInfo(D3D10DDI_HDEVICE hDevice, // IN
__out D3D10DDI_COUNTER_INFO *pCounterInfo) // OUT
{
//LOG_ENTRYPOINT();
pCounterInfo->LastDeviceDependentCounter = (D3D10DDI_QUERY)0;
pCounterInfo->NumSimultaneousCounters = 0;
pCounterInfo->NumDetectableParallelUnits = 0;
}
/*
* ----------------------------------------------------------------------
*
* CheckCounter --
*
* The CheckCounter function retrieves information that
* describes a counter.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CheckCounter(
D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_QUERY Query, // IN
__out D3D10DDI_COUNTER_TYPE *pCounterType, // OUT
__out UINT *pActiveCounters, // OUT
__out_ecount_part_z_opt (*pNameLength, *pNameLength) LPSTR pName, // OUT
__inout_opt UINT *pNameLength, // OUT
__out_ecount_part_z_opt (*pUnitsLength, *pUnitsLength) LPSTR pUnits, // OUT
__inout_opt UINT *pUnitsLength, // OUT
__out_ecount_part_z_opt (*pDescriptionLength, *pDescriptionLength) LPSTR pDescription, // OUT
__inout_opt UINT* pDescriptionLength) // OUT
{
LOG_ENTRYPOINT();
SetError(hDevice, DXGI_DDI_ERR_UNSUPPORTED);
}

View File

@ -0,0 +1,76 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Query.h --
* Functions that manipulate query resources.
*/
#ifndef QUERY_H
#define QUERY_H
#include "DriverIncludes.h"
struct Device;
SIZE_T APIENTRY CalcPrivateQuerySize(D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATEQUERY *pCreateQuery);
void APIENTRY CreateQuery(D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATEQUERY *pCreateQuery,
D3D10DDI_HQUERY hQuery, D3D10DDI_HRTQUERY hRTQuery);
void APIENTRY APIENTRY DestroyQuery(D3D10DDI_HDEVICE hDevice, D3D10DDI_HQUERY hQuery);
void APIENTRY QueryBegin(D3D10DDI_HDEVICE hDevice, D3D10DDI_HQUERY hQuery);
void APIENTRY QueryEnd(D3D10DDI_HDEVICE hDevice, D3D10DDI_HQUERY hQuery);
void APIENTRY QueryGetData(D3D10DDI_HDEVICE hDevice, D3D10DDI_HQUERY hQuery,
__out_bcount_full_opt (DataSize) void *pData,
UINT DataSize, UINT Flags);
void APIENTRY SetPredication(D3D10DDI_HDEVICE hDevice, D3D10DDI_HQUERY hQuery,
BOOL PredicateValue);
void APIENTRY CheckCounterInfo(D3D10DDI_HDEVICE hDevice,
__out D3D10DDI_COUNTER_INFO *pCounterInfo);
void APIENTRY CheckCounter(D3D10DDI_HDEVICE hDevice,
D3D10DDI_QUERY Query,
__out D3D10DDI_COUNTER_TYPE *pCounterType,
__out UINT *pActiveCounters,
__out_ecount_part_z_opt (*pNameLength, *pNameLength) LPSTR pName,
__inout_opt UINT *pNameLength,
__out_ecount_part_z_opt (*pUnitsLength, *pUnitsLength) LPSTR pUnits,
__inout_opt UINT *pUnitsLength,
__out_ecount_part_z_opt (*pDescriptionLength, *pDescriptionLength) LPSTR pDescription,
__inout_opt UINT* pDescriptionLength);
BOOL CheckPredicate(Device *pDevice);
#endif /* QUERY_H */

View File

@ -0,0 +1,6 @@
This directory has a Gallium state tracker for D3D10 UMD DDI.
It still uses TGSI, not not NIR.
Currently it only supports SW rasterizers. See
src/gallium/targets/d3d10sw/README.md for further details.

View File

@ -0,0 +1,285 @@
/**************************************************************************
*
* 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.point_quad_rasterization = 1;
state.point_size = 1.0f;
state.point_tri_clip = 1;
state.line_width = 1.0f;
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);
}

View File

@ -0,0 +1,62 @@
/**************************************************************************
*
* 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.h --
* Functions that manipulate rasterizer state.
*/
#ifndef RASTERIZER_H
#define RASTERIZER_H
#include "DriverIncludes.h"
void APIENTRY SetViewports(
D3D10DDI_HDEVICE hDevice, UINT NumViewports, UINT ClearViewports,
__in_ecount (NumViewports) const D3D10_DDI_VIEWPORT *pViewports);
void APIENTRY SetScissorRects(
D3D10DDI_HDEVICE hDevice, UINT NumScissorRects, UINT ClearScissorRects,
__in_ecount (NumRects) const D3D10_DDI_RECT *pRects);
SIZE_T APIENTRY CalcPrivateRasterizerStateSize(
D3D10DDI_HDEVICE hDevice,
__in const D3D10_DDI_RASTERIZER_DESC *pRasterizerDesc);
void APIENTRY CreateRasterizerState(
D3D10DDI_HDEVICE hDevice,
__in const D3D10_DDI_RASTERIZER_DESC *pRasterizerDesc,
D3D10DDI_HRASTERIZERSTATE hRasterizerState,
D3D10DDI_HRTRASTERIZERSTATE hRTRasterizerState);
void APIENTRY DestroyRasterizerState(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HRASTERIZERSTATE hRasterizerState);
void APIENTRY SetRasterizerState(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HRASTERIZERSTATE hRasterizerState);
#endif /* RASTERIZER_H */

View File

@ -0,0 +1,880 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Resource.cpp --
* Functions that manipulate GPU resources.
*/
#include "Resource.h"
#include "Format.h"
#include "State.h"
#include "Query.h"
#include "Debug.h"
#include "util/u_math.h"
#include "util/u_rect.h"
#include "util/u_surface.h"
/*
* ----------------------------------------------------------------------
*
* CalcPrivateResourceSize --
*
* The CalcPrivateResourceSize 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).
*
* ----------------------------------------------------------------------
*/
SIZE_T APIENTRY
CalcPrivateResourceSize(D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10DDIARG_CREATERESOURCE *pCreateResource) // IN
{
LOG_ENTRYPOINT();
return sizeof(Resource);
}
static unsigned
translate_resource_usage( unsigned usage )
{
unsigned resource_usage = 0;
switch (usage) {
case D3D10_DDI_USAGE_DEFAULT:
resource_usage = PIPE_USAGE_DEFAULT;
break;
case D3D10_DDI_USAGE_IMMUTABLE:
resource_usage = PIPE_USAGE_IMMUTABLE;
break;
case D3D10_DDI_USAGE_DYNAMIC:
resource_usage = PIPE_USAGE_DYNAMIC;
break;
case D3D10_DDI_USAGE_STAGING:
resource_usage = PIPE_USAGE_STAGING;
break;
default:
assert(0);
break;
}
return resource_usage;
}
static unsigned
translate_resource_flags(UINT flags)
{
unsigned bind = 0;
if (flags & D3D10_DDI_BIND_VERTEX_BUFFER)
bind |= PIPE_BIND_VERTEX_BUFFER;
if (flags & D3D10_DDI_BIND_INDEX_BUFFER)
bind |= PIPE_BIND_INDEX_BUFFER;
if (flags & D3D10_DDI_BIND_CONSTANT_BUFFER)
bind |= PIPE_BIND_CONSTANT_BUFFER;
if (flags & D3D10_DDI_BIND_SHADER_RESOURCE)
bind |= PIPE_BIND_SAMPLER_VIEW;
if (flags & D3D10_DDI_BIND_RENDER_TARGET)
bind |= PIPE_BIND_RENDER_TARGET;
if (flags & D3D10_DDI_BIND_DEPTH_STENCIL)
bind |= PIPE_BIND_DEPTH_STENCIL;
if (flags & D3D10_DDI_BIND_STREAM_OUTPUT)
bind |= PIPE_BIND_STREAM_OUTPUT;
return bind;
}
static enum pipe_texture_target
translate_texture_target( D3D10DDIRESOURCE_TYPE ResourceDimension,
UINT ArraySize)
{
assert(ArraySize >= 1);
switch(ResourceDimension) {
case D3D10DDIRESOURCE_BUFFER:
assert(ArraySize == 1);
return PIPE_BUFFER;
case D3D10DDIRESOURCE_TEXTURE1D:
return ArraySize > 1 ? PIPE_TEXTURE_1D_ARRAY : PIPE_TEXTURE_1D;
case D3D10DDIRESOURCE_TEXTURE2D:
return ArraySize > 1 ? PIPE_TEXTURE_2D_ARRAY : PIPE_TEXTURE_2D;
case D3D10DDIRESOURCE_TEXTURE3D:
assert(ArraySize == 1);
return PIPE_TEXTURE_3D;
case D3D10DDIRESOURCE_TEXTURECUBE:
assert(ArraySize % 6 == 0);
return ArraySize > 6 ? PIPE_TEXTURE_CUBE_ARRAY : PIPE_TEXTURE_CUBE;
default:
assert(0);
return PIPE_TEXTURE_1D;
}
}
static void
subResourceBox(struct pipe_resource *resource, // IN
UINT SubResource, // IN
unsigned *pLevel, // OUT
struct pipe_box *pBox) // OUT
{
UINT MipLevels = resource->last_level + 1;
unsigned layer;
unsigned width;
unsigned height;
unsigned depth;
*pLevel = SubResource % MipLevels;
layer = SubResource / MipLevels;
width = u_minify(resource->width0, *pLevel);
height = u_minify(resource->height0, *pLevel);
depth = u_minify(resource->depth0, *pLevel);
pBox->x = 0;
pBox->y = 0;
pBox->z = 0 + layer;
pBox->width = width;
pBox->height = height;
pBox->depth = depth;
}
/*
* ----------------------------------------------------------------------
*
* CreateResource --
*
* The CreateResource function creates a resource.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CreateResource(D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10DDIARG_CREATERESOURCE *pCreateResource, // IN
D3D10DDI_HRESOURCE hResource, // IN
D3D10DDI_HRTRESOURCE hRTResource) // IN
{
LOG_ENTRYPOINT();
if ((pCreateResource->MiscFlags & D3D10_DDI_RESOURCE_MISC_SHARED) ||
(pCreateResource->pPrimaryDesc &&
pCreateResource->pPrimaryDesc->DriverFlags & DXGI_DDI_PRIMARY_OPTIONAL)) {
DebugPrintf("%s(%dx%dx%d hResource=%p)\n",
__FUNCTION__,
pCreateResource->pMipInfoList[0].TexelWidth,
pCreateResource->pMipInfoList[0].TexelHeight,
pCreateResource->pMipInfoList[0].TexelDepth,
hResource.pDrvPrivate);
DebugPrintf(" ResourceDimension = %u\n",
pCreateResource->ResourceDimension);
DebugPrintf(" Usage = %u\n",
pCreateResource->Usage);
DebugPrintf(" BindFlags = 0x%x\n",
pCreateResource->BindFlags);
DebugPrintf(" MapFlags = 0x%x\n",
pCreateResource->MapFlags);
DebugPrintf(" MiscFlags = 0x%x\n",
pCreateResource->MiscFlags);
DebugPrintf(" Format = %s\n",
FormatToName(pCreateResource->Format));
DebugPrintf(" SampleDesc.Count = %u\n", pCreateResource->SampleDesc.Count);
DebugPrintf(" SampleDesc.Quality = %u\n", pCreateResource->SampleDesc.Quality);
DebugPrintf(" MipLevels = %u\n", pCreateResource->MipLevels);
DebugPrintf(" ArraySize = %u\n", pCreateResource->ArraySize);
DebugPrintf(" pPrimaryDesc = %p\n", pCreateResource->pPrimaryDesc);
if (pCreateResource->pPrimaryDesc) {
DebugPrintf(" Flags = 0x%x\n",
pCreateResource->pPrimaryDesc->Flags);
DebugPrintf(" VidPnSourceId = %u\n", pCreateResource->pPrimaryDesc->VidPnSourceId);
DebugPrintf(" ModeDesc.Width = %u\n", pCreateResource->pPrimaryDesc->ModeDesc.Width);
DebugPrintf(" ModeDesc.Height = %u\n", pCreateResource->pPrimaryDesc->ModeDesc.Height);
DebugPrintf(" ModeDesc.Format = %u)\n",
pCreateResource->pPrimaryDesc->ModeDesc.Format);
DebugPrintf(" ModeDesc.RefreshRate.Numerator = %u\n", pCreateResource->pPrimaryDesc->ModeDesc.RefreshRate.Numerator);
DebugPrintf(" ModeDesc.RefreshRate.Denominator = %u\n", pCreateResource->pPrimaryDesc->ModeDesc.RefreshRate.Denominator);
DebugPrintf(" ModeDesc.ScanlineOrdering = %u\n",
pCreateResource->pPrimaryDesc->ModeDesc.ScanlineOrdering);
DebugPrintf(" ModeDesc.Rotation = %u\n",
pCreateResource->pPrimaryDesc->ModeDesc.Rotation);
DebugPrintf(" ModeDesc.Scaling = %u\n",
pCreateResource->pPrimaryDesc->ModeDesc.Scaling);
DebugPrintf(" DriverFlags = 0x%x\n",
pCreateResource->pPrimaryDesc->DriverFlags);
}
}
struct pipe_context *pipe = CastPipeContext(hDevice);
struct pipe_screen *screen = pipe->screen;
Resource *pResource = CastResource(hResource);
memset(pResource, 0, sizeof *pResource);
#if 0
if (pCreateResource->pPrimaryDesc) {
pCreateResource->pPrimaryDesc->DriverFlags = DXGI_DDI_PRIMARY_DRIVER_FLAG_NO_SCANOUT;
if (!(pCreateResource->pPrimaryDesc->DriverFlags & DXGI_DDI_PRIMARY_OPTIONAL)) {
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff568846.aspx
SetError(hDevice, DXGI_DDI_ERR_UNSUPPORTED);
return;
}
}
#endif
pResource->Format = pCreateResource->Format;
pResource->MipLevels = pCreateResource->MipLevels;
struct pipe_resource templat;
memset(&templat, 0, sizeof templat);
templat.target = translate_texture_target( pCreateResource->ResourceDimension,
pCreateResource->ArraySize );
if (pCreateResource->Format == DXGI_FORMAT_UNKNOWN) {
assert(pCreateResource->ResourceDimension == D3D10DDIRESOURCE_BUFFER);
templat.format = PIPE_FORMAT_R8_UINT;
} else {
BOOL bindDepthStencil = !!(pCreateResource->BindFlags & D3D10_DDI_BIND_DEPTH_STENCIL);
templat.format = FormatTranslate(pCreateResource->Format, bindDepthStencil);
}
templat.width0 = pCreateResource->pMipInfoList[0].TexelWidth;
templat.height0 = pCreateResource->pMipInfoList[0].TexelHeight;
templat.depth0 = pCreateResource->pMipInfoList[0].TexelDepth;
templat.array_size = pCreateResource->ArraySize;
templat.last_level = pCreateResource->MipLevels - 1;
templat.nr_samples = pCreateResource->SampleDesc.Count;
templat.nr_storage_samples = pCreateResource->SampleDesc.Count;
templat.bind = translate_resource_flags(pCreateResource->BindFlags);
templat.usage = translate_resource_usage(pCreateResource->Usage);
if (templat.target != PIPE_BUFFER) {
if (!screen->is_format_supported(screen,
templat.format,
templat.target,
templat.nr_samples,
templat.nr_storage_samples,
templat.bind)) {
debug_printf("%s: unsupported format %s\n",
__FUNCTION__, util_format_name(templat.format));
SetError(hDevice, E_OUTOFMEMORY);
return;
}
}
pResource->resource = screen->resource_create(screen, &templat);
if (!pResource) {
DebugPrintf("%s: failed to create resource\n", __FUNCTION__);
SetError(hDevice, E_OUTOFMEMORY);
return;
}
pResource->NumSubResources = pCreateResource->MipLevels * pCreateResource->ArraySize;
pResource->transfers = (struct pipe_transfer **)calloc(pResource->NumSubResources,
sizeof *pResource->transfers);
if (pCreateResource->pInitialDataUP) {
for (UINT SubResource = 0; SubResource < pResource->NumSubResources; ++SubResource) {
const D3D10_DDIARG_SUBRESOURCE_UP* pInitialDataUP =
&pCreateResource->pInitialDataUP[SubResource];
unsigned level;
struct pipe_box box;
subResourceBox(pResource->resource, SubResource, &level, &box);
struct pipe_transfer *transfer;
void *map;
map = pipe->transfer_map(pipe,
pResource->resource,
level,
PIPE_MAP_WRITE |
PIPE_MAP_UNSYNCHRONIZED,
&box,
&transfer);
assert(map);
if (map) {
for (int z = 0; z < box.depth; ++z) {
ubyte *dst = (ubyte*)map + z*transfer->layer_stride;
const ubyte *src = (const ubyte*)pInitialDataUP->pSysMem + z*pInitialDataUP->SysMemSlicePitch;
util_copy_rect(dst,
templat.format,
transfer->stride,
0, 0, box.width, box.height,
src,
pInitialDataUP->SysMemPitch,
0, 0);
}
pipe_transfer_unmap(pipe, transfer);
}
}
}
}
/*
* ----------------------------------------------------------------------
*
* CalcPrivateOpenedResourceSize --
*
* The CalcPrivateOpenedResourceSize function determines the size
* of the user-mode display driver's private shared region of memory
* (that is, the size of internal driver structures, not the size
* of the resource video memory) for an opened resource.
*
* ----------------------------------------------------------------------
*/
SIZE_T APIENTRY
CalcPrivateOpenedResourceSize(D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10DDIARG_OPENRESOURCE *pOpenResource) // IN
{
return sizeof(Resource);
}
/*
* ----------------------------------------------------------------------
*
* OpenResource --
*
* The OpenResource function opens a shared resource.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
OpenResource(D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10DDIARG_OPENRESOURCE *pOpenResource, // IN
D3D10DDI_HRESOURCE hResource, // IN
D3D10DDI_HRTRESOURCE hRTResource) // IN
{
LOG_UNSUPPORTED_ENTRYPOINT();
SetError(hDevice, E_OUTOFMEMORY);
}
/*
* ----------------------------------------------------------------------
*
* DestroyResource --
*
* The DestroyResource function destroys the specified resource
* object. The resource object can be destoyed only if it is not
* currently bound to a display device, and if all views that
* refer to the resource are also destroyed.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DestroyResource(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRESOURCE hResource) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
Resource *pResource = CastResource(hResource);
if (pResource->so_target) {
pipe_so_target_reference(&pResource->so_target, NULL);
}
for (UINT SubResource = 0; SubResource < pResource->NumSubResources; ++SubResource) {
if (pResource->transfers[SubResource]) {
pipe_transfer_unmap(pipe, pResource->transfers[SubResource]);
pResource->transfers[SubResource] = NULL;
}
}
free(pResource->transfers);
pipe_resource_reference(&pResource->resource, NULL);
}
/*
* ----------------------------------------------------------------------
*
* ResourceMap --
*
* The ResourceMap function maps a subresource of a resource.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
ResourceMap(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRESOURCE hResource, // IN
UINT SubResource, // IN
D3D10_DDI_MAP DDIMap, // IN
UINT Flags, // IN
__out D3D10DDI_MAPPED_SUBRESOURCE *pMappedSubResource) // OUT
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
Resource *pResource = CastResource(hResource);
struct pipe_resource *resource = pResource->resource;
unsigned usage;
switch (DDIMap) {
case D3D10_DDI_MAP_READ:
usage = PIPE_MAP_READ;
break;
case D3D10_DDI_MAP_READWRITE:
usage = PIPE_MAP_READ | PIPE_MAP_WRITE;
break;
case D3D10_DDI_MAP_WRITE:
usage = PIPE_MAP_WRITE;
break;
case D3D10_DDI_MAP_WRITE_DISCARD:
usage = PIPE_MAP_WRITE;
if (resource->last_level == 0 && resource->array_size == 1) {
usage |= PIPE_MAP_DISCARD_WHOLE_RESOURCE;
} else {
usage |= PIPE_MAP_DISCARD_RANGE;
}
break;
case D3D10_DDI_MAP_WRITE_NOOVERWRITE:
usage = PIPE_MAP_WRITE | PIPE_MAP_UNSYNCHRONIZED;
break;
default:
assert(0);
return;
}
assert(SubResource < pResource->NumSubResources);
unsigned level;
struct pipe_box box;
subResourceBox(resource, SubResource, &level, &box);
assert(!pResource->transfers[SubResource]);
void *map;
map = pipe->transfer_map(pipe,
resource,
level,
usage,
&box,
&pResource->transfers[SubResource]);
if (!map) {
DebugPrintf("%s: failed to map resource\n", __FUNCTION__);
SetError(hDevice, E_FAIL);
return;
}
pMappedSubResource->pData = map;
pMappedSubResource->RowPitch = pResource->transfers[SubResource]->stride;
pMappedSubResource->DepthPitch = pResource->transfers[SubResource]->layer_stride;
}
/*
* ----------------------------------------------------------------------
*
* ResourceUnmap --
*
* The ResourceUnmap function unmaps a subresource of a resource.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
ResourceUnmap(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRESOURCE hResource, // IN
UINT SubResource) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
Resource *pResource = CastResource(hResource);
assert(SubResource < pResource->NumSubResources);
if (pResource->transfers[SubResource]) {
pipe_transfer_unmap(pipe, pResource->transfers[SubResource]);
pResource->transfers[SubResource] = NULL;
}
}
/*
*----------------------------------------------------------------------
*
* areResourcesCompatible --
*
* Check whether two resources can be safely passed to
* pipe_context::resource_copy_region method.
*
* Results:
* As above.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static bool
areResourcesCompatible(const struct pipe_resource *src_resource, // IN
const struct pipe_resource *dst_resource) // IN
{
if (src_resource->format == dst_resource->format) {
/*
* Trivial.
*/
return TRUE;
} else if (src_resource->target == PIPE_BUFFER &&
dst_resource->target == PIPE_BUFFER) {
/*
* Buffer resources are merely a collection of bytes.
*/
return TRUE;
} else {
/*
* Check whether the formats are supported by
* the resource_copy_region method.
*/
const struct util_format_description *src_format_desc;
const struct util_format_description *dst_format_desc;
src_format_desc = util_format_description(src_resource->format);
dst_format_desc = util_format_description(dst_resource->format);
assert(src_format_desc->block.width == dst_format_desc->block.width);
assert(src_format_desc->block.height == dst_format_desc->block.height);
assert(src_format_desc->block.bits == dst_format_desc->block.bits);
return util_is_format_compatible(src_format_desc, dst_format_desc);
}
}
/*
* ----------------------------------------------------------------------
*
* ResourceCopy --
*
* The ResourceCopy function copies an entire source
* resource to a destination resource.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
ResourceCopy(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRESOURCE hDstResource, // IN
D3D10DDI_HRESOURCE hSrcResource) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
if (!CheckPredicate(pDevice)) {
return;
}
struct pipe_context *pipe = pDevice->pipe;
Resource *pDstResource = CastResource(hDstResource);
Resource *pSrcResource = CastResource(hSrcResource);
struct pipe_resource *dst_resource = pDstResource->resource;
struct pipe_resource *src_resource = pSrcResource->resource;
bool compatible;
assert(dst_resource->target == src_resource->target);
assert(dst_resource->width0 == src_resource->width0);
assert(dst_resource->height0 == src_resource->height0);
assert(dst_resource->depth0 == src_resource->depth0);
assert(dst_resource->last_level == src_resource->last_level);
assert(dst_resource->array_size == src_resource->array_size);
compatible = areResourcesCompatible(src_resource, dst_resource);
/* could also use one 3d copy for arrays */
for (unsigned layer = 0; layer < dst_resource->array_size; ++layer) {
for (unsigned level = 0; level <= dst_resource->last_level; ++level) {
struct pipe_box box;
box.x = 0;
box.y = 0;
box.z = 0 + layer;
box.width = u_minify(dst_resource->width0, level);
box.height = u_minify(dst_resource->height0, level);
box.depth = u_minify(dst_resource->depth0, level);
if (compatible) {
pipe->resource_copy_region(pipe,
dst_resource, level,
0, 0, layer,
src_resource, level,
&box);
} else {
util_resource_copy_region(pipe,
dst_resource, level,
0, 0, layer,
src_resource, level,
&box);
}
}
}
}
/*
* ----------------------------------------------------------------------
*
* ResourceCopyRegion --
*
* The ResourceCopyRegion function copies a source subresource
* region to a location on a destination subresource.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
ResourceCopyRegion(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRESOURCE hDstResource, // IN
UINT DstSubResource, // IN
UINT DstX, // IN
UINT DstY, // IN
UINT DstZ, // IN
D3D10DDI_HRESOURCE hSrcResource, // IN
UINT SrcSubResource, // IN
__in_opt const D3D10_DDI_BOX *pSrcBox) // IN (optional)
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
if (!CheckPredicate(pDevice)) {
return;
}
struct pipe_context *pipe = pDevice->pipe;
Resource *pDstResource = CastResource(hDstResource);
Resource *pSrcResource = CastResource(hSrcResource);
struct pipe_resource *dst_resource = pDstResource->resource;
struct pipe_resource *src_resource = pSrcResource->resource;
unsigned dst_level = DstSubResource % (dst_resource->last_level + 1);
unsigned dst_layer = DstSubResource / (dst_resource->last_level + 1);
unsigned src_level = SrcSubResource % (src_resource->last_level + 1);
unsigned src_layer = SrcSubResource / (src_resource->last_level + 1);
struct pipe_box src_box;
if (pSrcBox) {
src_box.x = pSrcBox->left;
src_box.y = pSrcBox->top;
src_box.z = pSrcBox->front + src_layer;
src_box.width = pSrcBox->right - pSrcBox->left;
src_box.height = pSrcBox->bottom - pSrcBox->top;
src_box.depth = pSrcBox->back - pSrcBox->front;
} else {
src_box.x = 0;
src_box.y = 0;
src_box.z = 0 + src_layer;
src_box.width = u_minify(src_resource->width0, src_level);
src_box.height = u_minify(src_resource->height0, src_level);
src_box.depth = u_minify(src_resource->depth0, src_level);
}
if (areResourcesCompatible(src_resource, dst_resource)) {
pipe->resource_copy_region(pipe,
dst_resource, dst_level,
DstX, DstY, DstZ + dst_layer,
src_resource, src_level,
&src_box);
} else {
util_resource_copy_region(pipe,
dst_resource, dst_level,
DstX, DstY, DstZ + dst_layer,
src_resource, src_level,
&src_box);
}
}
/*
* ----------------------------------------------------------------------
*
* ResourceResolveSubResource --
*
* The ResourceResolveSubResource function resolves
* multiple samples to one pixel.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
ResourceResolveSubResource(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRESOURCE hDstResource, // IN
UINT DstSubResource, // IN
D3D10DDI_HRESOURCE hSrcResource, // IN
UINT SrcSubResource, // IN
DXGI_FORMAT ResolveFormat) // IN
{
LOG_UNSUPPORTED_ENTRYPOINT();
}
/*
* ----------------------------------------------------------------------
*
* ResourceIsStagingBusy --
*
* The ResourceIsStagingBusy function determines whether a
* resource is currently being used by the graphics pipeline.
*
* ----------------------------------------------------------------------
*/
BOOL APIENTRY
ResourceIsStagingBusy(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRESOURCE hResource) // IN
{
LOG_ENTRYPOINT();
/* ignore */
return FALSE;
}
/*
* ----------------------------------------------------------------------
*
* ResourceReadAfterWriteHazard --
*
* The ResourceReadAfterWriteHazard function informs the user-mode
* display driver that the specified resource was used as an output
* from the graphics processing unit (GPU) and that the resource
* will be used as an input to the GPU.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
ResourceReadAfterWriteHazard(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRESOURCE hResource) // IN
{
LOG_ENTRYPOINT();
/* Not actually necessary */
}
/*
* ----------------------------------------------------------------------
*
* ResourceUpdateSubResourceUP --
*
* The ResourceUpdateSubresourceUP function updates a
* destination subresource region from a source
* system memory region.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
ResourceUpdateSubResourceUP(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRESOURCE hDstResource, // IN
UINT DstSubResource, // IN
__in_opt const D3D10_DDI_BOX *pDstBox, // IN
__in const void *pSysMemUP, // IN
UINT RowPitch, // IN
UINT DepthPitch) // IN
{
LOG_ENTRYPOINT();
Device *pDevice = CastDevice(hDevice);
if (!CheckPredicate(pDevice)) {
return;
}
struct pipe_context *pipe = pDevice->pipe;
struct pipe_resource *dst_resource = CastPipeResource(hDstResource);
unsigned level;
struct pipe_box box;
if (pDstBox) {
UINT DstMipLevels = dst_resource->last_level + 1;
level = DstSubResource % DstMipLevels;
unsigned dst_layer = DstSubResource / DstMipLevels;
box.x = pDstBox->left;
box.y = pDstBox->top;
box.z = pDstBox->front + dst_layer;
box.width = pDstBox->right - pDstBox->left;
box.height = pDstBox->bottom - pDstBox->top;
box.depth = pDstBox->back - pDstBox->front;
} else {
subResourceBox(dst_resource, DstSubResource, &level, &box);
}
struct pipe_transfer *transfer;
void *map;
map = pipe->transfer_map(pipe,
dst_resource,
level,
PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE,
&box,
&transfer);
assert(map);
if (map) {
for (int z = 0; z < box.depth; ++z) {
ubyte *dst = (ubyte*)map + z*transfer->layer_stride;
const ubyte *src = (const ubyte*)pSysMemUP + z*DepthPitch;
util_copy_rect(dst,
dst_resource->format,
transfer->stride,
0, 0, box.width, box.height,
src,
RowPitch,
0, 0);
}
pipe_transfer_unmap(pipe, transfer);
}
}

View File

@ -0,0 +1,93 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Resource.h --
* Functions that manipulate GPU resources.
*/
#ifndef RESOURCE_H
#define RESOURCE_H
#include "DriverIncludes.h"
SIZE_T APIENTRY CalcPrivateResourceSize(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATERESOURCE *pCreateResource);
void APIENTRY CreateResource(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATERESOURCE *pCreateResource,
D3D10DDI_HRESOURCE hResource,
D3D10DDI_HRTRESOURCE hRTResource);
SIZE_T APIENTRY CalcPrivateOpenedResourceSize(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_OPENRESOURCE *pOpenResource);
void APIENTRY OpenResource(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_OPENRESOURCE *pOpenResource,
D3D10DDI_HRESOURCE hResource,
D3D10DDI_HRTRESOURCE hRTResource);
void APIENTRY DestroyResource(D3D10DDI_HDEVICE hDevice, D3D10DDI_HRESOURCE hResource);
void APIENTRY ResourceMap(D3D10DDI_HDEVICE hDevice, D3D10DDI_HRESOURCE hResource,
UINT SubResource, D3D10_DDI_MAP DDIMap, UINT Flags,
__out D3D10DDI_MAPPED_SUBRESOURCE *pMappedSubResource);
void APIENTRY ResourceUnmap(D3D10DDI_HDEVICE hDevice, D3D10DDI_HRESOURCE hResource,
UINT SubResource);
void APIENTRY ResourceCopy(D3D10DDI_HDEVICE hDevice, D3D10DDI_HRESOURCE hDstResource,
D3D10DDI_HRESOURCE hSrcResource);
void APIENTRY ResourceCopyRegion(D3D10DDI_HDEVICE hDevice, D3D10DDI_HRESOURCE hResource,
UINT DstSubResource, UINT DstX, UINT DstY, UINT DstZ,
D3D10DDI_HRESOURCE hSrcResource, UINT SrcSubResource,
__in_opt const D3D10_DDI_BOX *pSrcBox);
void APIENTRY ResourceResolveSubResource(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HRESOURCE hDstResource,
UINT DstSubResource,
D3D10DDI_HRESOURCE hSrcResource,
UINT SrcSubResource,
DXGI_FORMAT ResolveFormat);
BOOL APIENTRY ResourceIsStagingBusy(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HRESOURCE hResource);
void APIENTRY ResourceReadAfterWriteHazard(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HRESOURCE hResource);
void APIENTRY ResourceUpdateSubResourceUP(
D3D10DDI_HDEVICE hDevice, D3D10DDI_HRESOURCE hResource,
UINT DstSubResource, __in_opt const D3D10_DDI_BOX *pDstBox,
__in const void *pSysMemUP, UINT RowPitch, UINT DepthPitch);
#endif /* RESOURCE_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,164 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Shader.h --
* Functions that manipulate shader resources.
*/
#ifndef SHADER_H
#define SHADER_H
#include "DriverIncludes.h"
struct Device;
struct Shader;
void *
CreateEmptyShader(Device *pDevice,
enum pipe_shader_type processor);
void
DeleteEmptyShader(Device *pDevice,
enum pipe_shader_type processor, void *handle);
unsigned
ShaderFindOutputMapping(Shader *shader, unsigned registerIndex);
SIZE_T APIENTRY
CalcPrivateShaderSize(D3D10DDI_HDEVICE hDevice,
__in_ecount (pShaderCode[1]) const UINT *pShaderCode,
__in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures);
void APIENTRY
DestroyShader(D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader);
SIZE_T APIENTRY
CalcPrivateSamplerSize(D3D10DDI_HDEVICE hDevice,
__in const D3D10_DDI_SAMPLER_DESC *pSamplerDesc);
void APIENTRY CreateSampler(D3D10DDI_HDEVICE hDevice,
__in const D3D10_DDI_SAMPLER_DESC *pSamplerDesc,
D3D10DDI_HSAMPLER hSampler, D3D10DDI_HRTSAMPLER hRTSampler);
void APIENTRY DestroySampler(D3D10DDI_HDEVICE hDevice, D3D10DDI_HSAMPLER hSampler);
void APIENTRY CreateVertexShader(D3D10DDI_HDEVICE hDevice,
__in_ecount (pShaderCode[1]) const UINT *pCode,
D3D10DDI_HSHADER hShader, D3D10DDI_HRTSHADER hRTShader,
__in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures);
void APIENTRY VsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader);
void APIENTRY VsSetShaderResources(
D3D10DDI_HDEVICE hDevice, UINT Offset, UINT NumViews,
__in_ecount (NumViews) const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews);
void APIENTRY VsSetConstantBuffers(D3D10DDI_HDEVICE hDevice, UINT StartBuffer, UINT NumBuffers,
__in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers);
void APIENTRY VsSetSamplers(D3D10DDI_HDEVICE hDevice, UINT Offset, UINT NumSamplers,
__in_ecount (NumSamplers) const D3D10DDI_HSAMPLER *phSamplers);
void APIENTRY CreateGeometryShader(D3D10DDI_HDEVICE hDevice,
__in_ecount (pShaderCode[1]) const UINT *pCode,
D3D10DDI_HSHADER hShader, D3D10DDI_HRTSHADER hRTShader,
__in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures);
void APIENTRY GsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader);
void APIENTRY GsSetShaderResources(
D3D10DDI_HDEVICE hDevice, UINT Offset, UINT NumViews,
__in_ecount (NumViews) const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews);
void APIENTRY GsSetConstantBuffers(D3D10DDI_HDEVICE hDevice, UINT StartBuffer, UINT NumBuffers,
__in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers);
void APIENTRY GsSetSamplers(D3D10DDI_HDEVICE hDevice, UINT Offset, UINT NumSamplers,
__in_ecount (NumSamplers) const D3D10DDI_HSAMPLER *phSamplers);
SIZE_T APIENTRY CalcPrivateGeometryShaderWithStreamOutput(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT *pCreateGeometryShaderWithStreamOutput,
__in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures);
void APIENTRY CreateGeometryShaderWithStreamOutput(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT *pCreateGeometryShaderWithStreamOutput,
D3D10DDI_HSHADER hShader, D3D10DDI_HRTSHADER hRTShader,
__in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures);
void APIENTRY SoSetTargets(D3D10DDI_HDEVICE hDevice, UINT SOTargets, UINT ClearTargets,
__in_ecount (SOTargets) const D3D10DDI_HRESOURCE *phResource,
__in_ecount (SOTargets) const UINT *pOffsets);
void APIENTRY CreatePixelShader(D3D10DDI_HDEVICE hDevice,
__in_ecount (pShaderCode[1]) const UINT *pCode,
D3D10DDI_HSHADER hShader, D3D10DDI_HRTSHADER hRTShader,
__in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures);
void APIENTRY PsSetShader(D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADER hShader);
void APIENTRY PsSetShaderResources(
D3D10DDI_HDEVICE hDevice, UINT Offset, UINT NumViews,
__in_ecount (NumViews) const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews);
void APIENTRY PsSetConstantBuffers(D3D10DDI_HDEVICE hDevice, UINT StartBuffer, UINT NumBuffers,
__in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers);
void APIENTRY PsSetSamplers(D3D10DDI_HDEVICE hDevice, UINT Offset, UINT NumSamplers,
__in_ecount (NumSamplers) const D3D10DDI_HSAMPLER *phSamplers);
void APIENTRY ShaderResourceViewReadAfterWriteHazard(
D3D10DDI_HDEVICE hDevice, D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView,
D3D10DDI_HRESOURCE hResource);
SIZE_T APIENTRY CalcPrivateShaderResourceViewSize(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATESHADERRESOURCEVIEW *pCreateShaderResourceView);
void APIENTRY CreateShaderResourceView(
D3D10DDI_HDEVICE hDevice,
__in const D3D10DDIARG_CREATESHADERRESOURCEVIEW *pCreateShaderResourceView,
D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView,
D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView);
SIZE_T APIENTRY CalcPrivateShaderResourceViewSize1(
D3D10DDI_HDEVICE hDevice,
__in const D3D10_1DDIARG_CREATESHADERRESOURCEVIEW *pCreateShaderResourceView);
void APIENTRY CreateShaderResourceView1(
D3D10DDI_HDEVICE hDevice,
__in const D3D10_1DDIARG_CREATESHADERRESOURCEVIEW *pCreateShaderResourceView,
D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView,
D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView);
void APIENTRY DestroyShaderResourceView(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView);
void APIENTRY GenMips(D3D10DDI_HDEVICE hDevice,
D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView);
#endif /* SHADER_H */

View File

@ -0,0 +1,72 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* ShaderDump.c --
* Functions for printing out shaders.
*/
#include "DriverIncludes.h"
#include "ShaderDump.h"
#include "util/u_debug.h"
static void
dump_uints(const unsigned *data,
unsigned count)
{
unsigned i;
for (i = 0; i < count; i++) {
if (i % 8 == 7) {
debug_printf("0x%08x,\n", data[i]);
} else {
debug_printf("0x%08x, ", data[i]);
}
}
if (i % 8) {
debug_printf("\n");
}
}
void
dx10_shader_dump_binary(const unsigned *code)
{
dump_uints(code, code[1]);
}
void
dx10_shader_dump_tokens(const unsigned *code)
{
/*
* TODO: Dump SM4/5 disassembly via D3DDisassemble. However this requires
* rebuilding DXBC container.
*/
dx10_shader_dump_binary(code);
}

View File

@ -0,0 +1,50 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* ShaderDump.h --
* Functions for printing out shaders.
*/
#ifndef SHADER_DUMP_H
#define SHADER_DUMP_H
#ifdef __cplusplus
extern "C" {
#endif
void
dx10_shader_dump_binary(const unsigned *code);
void
dx10_shader_dump_tokens(const unsigned *code);
#ifdef __cplusplus
}
#endif
#endif /* SHADER_DUMP_H */

View File

@ -0,0 +1,610 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* ShaderParse.c --
* Functions for parsing shader tokens.
*/
#include "Debug.h"
#include "ShaderParse.h"
#include "util/u_memory.h"
void
Shader_parse_init(struct Shader_parser *parser,
const unsigned *code)
{
parser->curr = parser->code = code;
parser->header.type = DECODE_D3D10_SB_TOKENIZED_PROGRAM_TYPE(*parser->curr);
parser->header.major_version = DECODE_D3D10_SB_TOKENIZED_PROGRAM_MAJOR_VERSION(*parser->curr);
parser->header.minor_version = DECODE_D3D10_SB_TOKENIZED_PROGRAM_MINOR_VERSION(*parser->curr);
parser->curr++;
parser->header.size = DECODE_D3D10_SB_TOKENIZED_PROGRAM_LENGTH(*parser->curr);
parser->curr++;
}
#define OP_NOT_DONE (1 << 0) /* not implemented yet */
#define OP_SATURATE (1 << 1) /* saturate in opcode specific control */
#define OP_TEST_BOOLEAN (1 << 2) /* test boolean in opcode specific control */
#define OP_DCL (1 << 3) /* custom opcode specific control */
#define OP_RESINFO_RET_TYPE (1 << 4) /* return type for resinfo */
struct dx10_opcode_info {
D3D10_SB_OPCODE_TYPE type;
const char *name;
unsigned num_dst;
unsigned num_src;
unsigned flags;
};
#define _(_opcode) _opcode, #_opcode
static const struct dx10_opcode_info
opcode_info[D3D10_SB_NUM_OPCODES] = {
{_(D3D10_SB_OPCODE_ADD), 1, 2, OP_SATURATE},
{_(D3D10_SB_OPCODE_AND), 1, 2, 0},
{_(D3D10_SB_OPCODE_BREAK), 0, 0, 0},
{_(D3D10_SB_OPCODE_BREAKC), 0, 1, OP_TEST_BOOLEAN},
{_(D3D10_SB_OPCODE_CALL), 0, 1, 0},
{_(D3D10_SB_OPCODE_CALLC), 0, 2, OP_TEST_BOOLEAN},
{_(D3D10_SB_OPCODE_CASE), 0, 1, 0},
{_(D3D10_SB_OPCODE_CONTINUE), 0, 0, 0},
{_(D3D10_SB_OPCODE_CONTINUEC), 0, 1, OP_TEST_BOOLEAN},
{_(D3D10_SB_OPCODE_CUT), 0, 0, 0},
{_(D3D10_SB_OPCODE_DEFAULT), 0, 0, 0},
{_(D3D10_SB_OPCODE_DERIV_RTX), 1, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_DERIV_RTY), 1, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_DISCARD), 0, 1, OP_TEST_BOOLEAN},
{_(D3D10_SB_OPCODE_DIV), 1, 2, OP_SATURATE},
{_(D3D10_SB_OPCODE_DP2), 1, 2, OP_SATURATE},
{_(D3D10_SB_OPCODE_DP3), 1, 2, OP_SATURATE},
{_(D3D10_SB_OPCODE_DP4), 1, 2, OP_SATURATE},
{_(D3D10_SB_OPCODE_ELSE), 0, 0, 0},
{_(D3D10_SB_OPCODE_EMIT), 0, 0, 0},
{_(D3D10_SB_OPCODE_EMITTHENCUT), 0, 0, 0},
{_(D3D10_SB_OPCODE_ENDIF), 0, 0, 0},
{_(D3D10_SB_OPCODE_ENDLOOP), 0, 0, 0},
{_(D3D10_SB_OPCODE_ENDSWITCH), 0, 0, 0},
{_(D3D10_SB_OPCODE_EQ), 1, 2, 0},
{_(D3D10_SB_OPCODE_EXP), 1, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_FRC), 1, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_FTOI), 1, 1, 0},
{_(D3D10_SB_OPCODE_FTOU), 1, 1, 0},
{_(D3D10_SB_OPCODE_GE), 1, 2, 0},
{_(D3D10_SB_OPCODE_IADD), 1, 2, 0},
{_(D3D10_SB_OPCODE_IF), 0, 1, OP_TEST_BOOLEAN},
{_(D3D10_SB_OPCODE_IEQ), 1, 2, 0},
{_(D3D10_SB_OPCODE_IGE), 1, 2, 0},
{_(D3D10_SB_OPCODE_ILT), 1, 2, 0},
{_(D3D10_SB_OPCODE_IMAD), 1, 3, 0},
{_(D3D10_SB_OPCODE_IMAX), 1, 2, 0},
{_(D3D10_SB_OPCODE_IMIN), 1, 2, 0},
{_(D3D10_SB_OPCODE_IMUL), 2, 2, 0},
{_(D3D10_SB_OPCODE_INE), 1, 2, 0},
{_(D3D10_SB_OPCODE_INEG), 1, 1, 0},
{_(D3D10_SB_OPCODE_ISHL), 1, 2, 0},
{_(D3D10_SB_OPCODE_ISHR), 1, 2, 0},
{_(D3D10_SB_OPCODE_ITOF), 1, 1, 0},
{_(D3D10_SB_OPCODE_LABEL), 0, 1, 0},
{_(D3D10_SB_OPCODE_LD), 1, 2, 0},
{_(D3D10_SB_OPCODE_LD_MS), 1, 3, 0},
{_(D3D10_SB_OPCODE_LOG), 1, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_LOOP), 0, 0, 0},
{_(D3D10_SB_OPCODE_LT), 1, 2, 0},
{_(D3D10_SB_OPCODE_MAD), 1, 3, OP_SATURATE},
{_(D3D10_SB_OPCODE_MIN), 1, 2, OP_SATURATE},
{_(D3D10_SB_OPCODE_MAX), 1, 2, OP_SATURATE},
{_(D3D10_SB_OPCODE_CUSTOMDATA), 0, 0, 0},
{_(D3D10_SB_OPCODE_MOV), 1, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_MOVC), 1, 3, OP_SATURATE},
{_(D3D10_SB_OPCODE_MUL), 1, 2, OP_SATURATE},
{_(D3D10_SB_OPCODE_NE), 1, 2, 0},
{_(D3D10_SB_OPCODE_NOP), 0, 0, 0},
{_(D3D10_SB_OPCODE_NOT), 1, 1, 0},
{_(D3D10_SB_OPCODE_OR), 1, 2, 0},
{_(D3D10_SB_OPCODE_RESINFO), 1, 2, OP_RESINFO_RET_TYPE},
{_(D3D10_SB_OPCODE_RET), 0, 0, 0},
{_(D3D10_SB_OPCODE_RETC), 0, 1, OP_TEST_BOOLEAN},
{_(D3D10_SB_OPCODE_ROUND_NE), 1, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_ROUND_NI), 1, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_ROUND_PI), 1, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_ROUND_Z), 1, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_RSQ), 1, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_SAMPLE), 1, 3, 0},
{_(D3D10_SB_OPCODE_SAMPLE_C), 1, 4, 0},
{_(D3D10_SB_OPCODE_SAMPLE_C_LZ), 1, 4, 0},
{_(D3D10_SB_OPCODE_SAMPLE_L), 1, 4, 0},
{_(D3D10_SB_OPCODE_SAMPLE_D), 1, 5, 0},
{_(D3D10_SB_OPCODE_SAMPLE_B), 1, 4, 0},
{_(D3D10_SB_OPCODE_SQRT), 1, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_SWITCH), 0, 1, 0},
{_(D3D10_SB_OPCODE_SINCOS), 2, 1, OP_SATURATE},
{_(D3D10_SB_OPCODE_UDIV), 2, 2, 0},
{_(D3D10_SB_OPCODE_ULT), 1, 2, 0},
{_(D3D10_SB_OPCODE_UGE), 1, 2, 0},
{_(D3D10_SB_OPCODE_UMUL), 2, 2, 0},
{_(D3D10_SB_OPCODE_UMAD), 1, 3, 0},
{_(D3D10_SB_OPCODE_UMAX), 1, 2, 0},
{_(D3D10_SB_OPCODE_UMIN), 1, 2, 0},
{_(D3D10_SB_OPCODE_USHR), 1, 2, 0},
{_(D3D10_SB_OPCODE_UTOF), 1, 1, 0},
{_(D3D10_SB_OPCODE_XOR), 1, 2, 0},
{_(D3D10_SB_OPCODE_DCL_RESOURCE), 1, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_CONSTANT_BUFFER), 0, 1, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_SAMPLER), 1, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_INDEX_RANGE), 1, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY), 0, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_GS_INPUT_PRIMITIVE), 0, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT), 0, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_INPUT), 1, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_INPUT_SGV), 1, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_INPUT_SIV), 1, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_INPUT_PS), 1, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_INPUT_PS_SGV), 1, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_INPUT_PS_SIV), 1, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_OUTPUT), 1, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_OUTPUT_SGV), 1, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_OUTPUT_SIV), 1, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_TEMPS), 0, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_INDEXABLE_TEMP), 0, 0, OP_DCL},
{_(D3D10_SB_OPCODE_DCL_GLOBAL_FLAGS), 0, 0, OP_DCL},
{_(D3D10_SB_OPCODE_RESERVED0), 0, 0, OP_NOT_DONE},
{_(D3D10_1_SB_OPCODE_LOD), 0, 0, OP_NOT_DONE},
{_(D3D10_1_SB_OPCODE_GATHER4), 0, 0, OP_NOT_DONE},
{_(D3D10_1_SB_OPCODE_SAMPLE_POS), 0, 0, OP_NOT_DONE},
{_(D3D10_1_SB_OPCODE_SAMPLE_INFO), 0, 0, OP_NOT_DONE}
};
#undef _
static void
parse_operand(const unsigned **curr,
struct Shader_operand *operand)
{
operand->type = DECODE_D3D10_SB_OPERAND_TYPE(**curr);
/* Index dimension. */
switch (DECODE_D3D10_SB_OPERAND_INDEX_DIMENSION(**curr)) {
case D3D10_SB_OPERAND_INDEX_0D:
operand->index_dim = 0;
break;
case D3D10_SB_OPERAND_INDEX_1D:
operand->index_dim = 1;
break;
case D3D10_SB_OPERAND_INDEX_2D:
operand->index_dim = 2;
break;
default:
assert(0);
}
if (operand->index_dim >= 1) {
operand->index[0].index_rep = DECODE_D3D10_SB_OPERAND_INDEX_REPRESENTATION(0, **curr);
if (operand->index_dim >= 2) {
operand->index[1].index_rep = DECODE_D3D10_SB_OPERAND_INDEX_REPRESENTATION(1, **curr);
}
}
(*curr)++;
}
static void
parse_relative_operand(const unsigned **curr,
struct Shader_relative_operand *operand)
{
assert(!DECODE_IS_D3D10_SB_OPERAND_EXTENDED(**curr));
assert(DECODE_D3D10_SB_OPERAND_NUM_COMPONENTS(**curr) == D3D10_SB_OPERAND_4_COMPONENT);
assert(DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE(**curr) == D3D10_SB_OPERAND_4_COMPONENT_SELECT_1_MODE);
operand->comp = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECT_1(**curr);
operand->type = DECODE_D3D10_SB_OPERAND_TYPE(**curr);
assert(operand->type != D3D10_SB_OPERAND_TYPE_IMMEDIATE32);
/* Index dimension. */
assert(DECODE_D3D10_SB_OPERAND_INDEX_REPRESENTATION(0, **curr) == D3D10_SB_OPERAND_INDEX_IMMEDIATE32);
if (DECODE_D3D10_SB_OPERAND_INDEX_DIMENSION(**curr) == D3D10_SB_OPERAND_INDEX_1D) {
(*curr)++;
operand->index[0].imm = **curr;
} else {
assert(DECODE_D3D10_SB_OPERAND_INDEX_DIMENSION(**curr) == D3D10_SB_OPERAND_INDEX_2D);
(*curr)++;
operand->index[0].imm = **curr;
(*curr)++;
operand->index[1].imm = **curr;
}
(*curr)++;
}
static void
parse_index(const unsigned **curr,
struct Shader_index *index)
{
switch (index->index_rep) {
case D3D10_SB_OPERAND_INDEX_IMMEDIATE32:
index->imm = *(*curr)++;
break;
case D3D10_SB_OPERAND_INDEX_RELATIVE:
index->imm = 0;
parse_relative_operand(curr, &index->rel);
break;
case D3D10_SB_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE:
index->imm = *(*curr)++;
parse_relative_operand(curr, &index->rel);
break;
default:
/* XXX: Support other index representations.
*/
assert(0);
}
}
static void
parse_operand_index(const unsigned **curr,
struct Shader_operand *operand)
{
if (operand->index_dim >= 1) {
parse_index(curr, &operand->index[0]);
if (operand->index_dim >= 2) {
parse_index(curr, &operand->index[1]);
}
}
}
boolean
Shader_parse_opcode(struct Shader_parser *parser,
struct Shader_opcode *opcode)
{
const unsigned *curr = parser->curr;
const struct dx10_opcode_info *info;
unsigned length;
boolean opcode_is_extended;
unsigned i;
if (curr >= parser->code + parser->header.size) {
return FALSE;
}
memset(opcode, 0, sizeof *opcode);
/* Opcode type. */
opcode->type = DECODE_D3D10_SB_OPCODE_TYPE(*curr);
if (opcode->type == D3D10_SB_OPCODE_CUSTOMDATA) {
opcode->customdata._class = DECODE_D3D10_SB_CUSTOMDATA_CLASS(*curr);
curr++;
assert(opcode->customdata._class == D3D10_SB_CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER);
opcode->customdata.u.constbuf.count = *curr - 2;
curr++;
opcode->customdata.u.constbuf.data = MALLOC(opcode->customdata.u.constbuf.count * sizeof(unsigned));
assert(opcode->customdata.u.constbuf.data);
memcpy(opcode->customdata.u.constbuf.data,
curr,
opcode->customdata.u.constbuf.count * sizeof(unsigned));
curr += opcode->customdata.u.constbuf.count;
parser->curr = curr;
return TRUE;
}
opcode->dcl_siv_name = D3D10_SB_NAME_UNDEFINED;
/* Lookup extra information based on opcode type. */
assert(opcode->type < D3D10_SB_NUM_OPCODES);
info = &opcode_info[opcode->type];
/* Opcode specific. */
switch (opcode->type) {
case D3D10_SB_OPCODE_DCL_RESOURCE:
opcode->specific.dcl_resource_dimension = DECODE_D3D10_SB_RESOURCE_DIMENSION(*curr);
break;
case D3D10_SB_OPCODE_DCL_SAMPLER:
opcode->specific.dcl_sampler_mode = DECODE_D3D10_SB_SAMPLER_MODE(*curr);
break;
case D3D10_SB_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY:
opcode->specific.dcl_gs_output_primitive_topology = DECODE_D3D10_SB_GS_OUTPUT_PRIMITIVE_TOPOLOGY(*curr);
break;
case D3D10_SB_OPCODE_DCL_GS_INPUT_PRIMITIVE:
opcode->specific.dcl_gs_input_primitive = DECODE_D3D10_SB_GS_INPUT_PRIMITIVE(*curr);
break;
case D3D10_SB_OPCODE_DCL_INPUT_PS:
case D3D10_SB_OPCODE_DCL_INPUT_PS_SIV:
opcode->specific.dcl_in_ps_interp = DECODE_D3D10_SB_INPUT_INTERPOLATION_MODE(*curr);
break;
case D3D10_SB_OPCODE_DCL_GLOBAL_FLAGS:
opcode->specific.global_flags.refactoring_allowed = DECODE_D3D10_SB_GLOBAL_FLAGS(*curr) ? 1 : 0;
break;
default:
/* Parse opcode-specific control bits */
if (info->flags & OP_DCL) {
/* no-op */
} else if (info->flags & OP_SATURATE) {
opcode->saturate =
!!DECODE_IS_D3D10_SB_INSTRUCTION_SATURATE_ENABLED(*curr);
} else if (info->flags & OP_TEST_BOOLEAN) {
opcode->specific.test_boolean =
DECODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN(*curr);
} else if (info->flags & OP_RESINFO_RET_TYPE) {
opcode->specific.resinfo_ret_type =
DECODE_D3D10_SB_RESINFO_INSTRUCTION_RETURN_TYPE(*curr);
} else {
/* Warn if there are bits set in the opcode-specific controls (bits 23:11 inclusive)*/
if (*curr & ((1 << 24) - (1 << 11))) {
debug_printf("warning: unexpected opcode-specific control in opcode %s\n",
info->name);
}
}
break;
}
/* Opcode length in DWORDs. */
length = DECODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(*curr);
assert(curr + length <= parser->code + parser->header.size);
/* Opcode specific fields in token0. */
switch (opcode->type) {
case D3D10_SB_OPCODE_DCL_CONSTANT_BUFFER:
opcode->specific.dcl_cb_access_pattern =
DECODE_D3D10_SB_CONSTANT_BUFFER_ACCESS_PATTERN(*curr);
break;
default:
break;
}
opcode_is_extended = DECODE_IS_D3D10_SB_OPCODE_EXTENDED(*curr);
curr++;
if (opcode_is_extended) {
/* NOTE: DECODE_IS_D3D10_SB_OPCODE_DOUBLE_EXTENDED is broken.
*/
assert(!((*curr & D3D10_SB_OPCODE_DOUBLE_EXTENDED_MASK) >> D3D10_SB_OPERAND_DOUBLE_EXTENDED_SHIFT));
switch (DECODE_D3D10_SB_EXTENDED_OPCODE_TYPE(*curr)) {
case D3D10_SB_EXTENDED_OPCODE_EMPTY:
break;
case D3D10_SB_EXTENDED_OPCODE_SAMPLE_CONTROLS:
opcode->imm_texel_offset.u = DECODE_IMMEDIATE_D3D10_SB_ADDRESS_OFFSET(D3D10_SB_IMMEDIATE_ADDRESS_OFFSET_U, *curr);
opcode->imm_texel_offset.v = DECODE_IMMEDIATE_D3D10_SB_ADDRESS_OFFSET(D3D10_SB_IMMEDIATE_ADDRESS_OFFSET_V, *curr);
opcode->imm_texel_offset.w = DECODE_IMMEDIATE_D3D10_SB_ADDRESS_OFFSET(D3D10_SB_IMMEDIATE_ADDRESS_OFFSET_W, *curr);
break;
default:
assert(0);
}
curr++;
}
if (info->flags & OP_NOT_DONE) {
/* XXX: Need to figure out the number of operands for this opcode.
* Should be okay to continue execution -- we have enough info
* to skip to the next instruction.
*/
LOG_UNSUPPORTED(TRUE);
opcode->num_dst = 0;
opcode->num_src = 0;
goto skip;
}
opcode->num_dst = info->num_dst;
opcode->num_src = info->num_src;
/* Destination operands. */
for (i = 0; i < info->num_dst; i++) {
D3D10_SB_OPERAND_NUM_COMPONENTS num_components;
assert(!DECODE_IS_D3D10_SB_OPERAND_EXTENDED(*curr));
num_components = DECODE_D3D10_SB_OPERAND_NUM_COMPONENTS(*curr);
if (num_components == D3D10_SB_OPERAND_4_COMPONENT) {
D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE selection_mode;
selection_mode = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE(*curr);
assert(selection_mode == D3D10_SB_OPERAND_4_COMPONENT_MASK_MODE);
opcode->dst[i].mask = DECODE_D3D10_SB_OPERAND_4_COMPONENT_MASK(*curr);
} else {
assert(num_components == D3D10_SB_OPERAND_0_COMPONENT ||
num_components == D3D10_SB_OPERAND_1_COMPONENT);
opcode->dst[i].mask = D3D10_SB_OPERAND_4_COMPONENT_MASK_X;
}
parse_operand(&curr, &opcode->dst[i].base);
parse_operand_index(&curr, &opcode->dst[i].base);
}
/* Source operands. */
for (i = 0; i < info->num_src; i++) {
boolean extended;
D3D10_SB_OPERAND_NUM_COMPONENTS num_components;
extended = DECODE_IS_D3D10_SB_OPERAND_EXTENDED(*curr);
num_components = DECODE_D3D10_SB_OPERAND_NUM_COMPONENTS(*curr);
if (num_components == D3D10_SB_OPERAND_4_COMPONENT) {
D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE selection_mode;
selection_mode = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECTION_MODE(*curr);
if (selection_mode == D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_MODE) {
opcode->src[i].swizzle[0] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_SOURCE(*curr, 0);
opcode->src[i].swizzle[1] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_SOURCE(*curr, 1);
opcode->src[i].swizzle[2] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_SOURCE(*curr, 2);
opcode->src[i].swizzle[3] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SWIZZLE_SOURCE(*curr, 3);
} else if (selection_mode == D3D10_SB_OPERAND_4_COMPONENT_SELECT_1_MODE) {
opcode->src[i].swizzle[0] =
opcode->src[i].swizzle[1] =
opcode->src[i].swizzle[2] =
opcode->src[i].swizzle[3] = DECODE_D3D10_SB_OPERAND_4_COMPONENT_SELECT_1(*curr);
} else {
/* This case apparently happens only for 4-component 32-bit
* immediate operands.
*/
assert(selection_mode == D3D10_SB_OPERAND_4_COMPONENT_MASK_MODE);
assert(DECODE_D3D10_SB_OPERAND_4_COMPONENT_MASK(*curr) == 0);
assert(DECODE_D3D10_SB_OPERAND_TYPE(*curr) == D3D10_SB_OPERAND_TYPE_IMMEDIATE32);
opcode->src[i].swizzle[0] = D3D10_SB_4_COMPONENT_X;
opcode->src[i].swizzle[1] = D3D10_SB_4_COMPONENT_Y;
opcode->src[i].swizzle[2] = D3D10_SB_4_COMPONENT_Z;
opcode->src[i].swizzle[3] = D3D10_SB_4_COMPONENT_W;
}
} else if (num_components == D3D10_SB_OPERAND_1_COMPONENT) {
opcode->src[i].swizzle[0] =
opcode->src[i].swizzle[1] =
opcode->src[i].swizzle[2] =
opcode->src[i].swizzle[3] = D3D10_SB_4_COMPONENT_X;
} else {
/* Samplers only?
*/
assert(num_components == D3D10_SB_OPERAND_0_COMPONENT);
assert(DECODE_D3D10_SB_OPERAND_TYPE(*curr) == D3D10_SB_OPERAND_TYPE_SAMPLER ||
DECODE_D3D10_SB_OPERAND_TYPE(*curr) == D3D10_SB_OPERAND_TYPE_LABEL);
opcode->src[i].swizzle[0] = D3D10_SB_4_COMPONENT_X;
opcode->src[i].swizzle[1] = D3D10_SB_4_COMPONENT_Y;
opcode->src[i].swizzle[2] = D3D10_SB_4_COMPONENT_Z;
opcode->src[i].swizzle[3] = D3D10_SB_4_COMPONENT_W;
}
parse_operand(&curr, &opcode->src[i].base);
opcode->src[i].modifier = D3D10_SB_OPERAND_MODIFIER_NONE;
if (extended) {
/* NOTE: DECODE_IS_D3D10_SB_OPERAND_DOUBLE_EXTENDED is broken.
*/
assert(!((*curr & D3D10_SB_OPERAND_DOUBLE_EXTENDED_MASK) >> D3D10_SB_OPERAND_DOUBLE_EXTENDED_SHIFT));
switch (DECODE_D3D10_SB_EXTENDED_OPERAND_TYPE(*curr)) {
case D3D10_SB_EXTENDED_OPERAND_EMPTY:
break;
case D3D10_SB_EXTENDED_OPERAND_MODIFIER:
opcode->src[i].modifier = DECODE_D3D10_SB_OPERAND_MODIFIER(*curr);
break;
default:
assert(0);
}
curr++;
}
parse_operand_index(&curr, &opcode->src[i].base);
if (opcode->src[i].base.type == D3D10_SB_OPERAND_TYPE_IMMEDIATE32) {
switch (num_components) {
case D3D10_SB_OPERAND_1_COMPONENT:
opcode->src[i].imm[0].u32 =
opcode->src[i].imm[1].u32 =
opcode->src[i].imm[2].u32 =
opcode->src[i].imm[3].u32 = *curr++;
break;
case D3D10_SB_OPERAND_4_COMPONENT:
opcode->src[i].imm[0].u32 = *curr++;
opcode->src[i].imm[1].u32 = *curr++;
opcode->src[i].imm[2].u32 = *curr++;
opcode->src[i].imm[3].u32 = *curr++;
break;
default:
/* XXX: Support other component sizes.
*/
assert(0);
}
}
}
/* Opcode specific trailing operands. */
switch (opcode->type) {
case D3D10_SB_OPCODE_DCL_RESOURCE:
opcode->dcl_resource_ret_type[0] = DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(*curr, 0);
opcode->dcl_resource_ret_type[1] = DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(*curr, 1);
opcode->dcl_resource_ret_type[2] = DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(*curr, 2);
opcode->dcl_resource_ret_type[3] = DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(*curr, 3);
curr++;
break;
case D3D10_SB_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT:
opcode->specific.dcl_max_output_vertex_count = *curr;
curr++;
break;
case D3D10_SB_OPCODE_DCL_INPUT_SGV:
case D3D10_SB_OPCODE_DCL_INPUT_SIV:
case D3D10_SB_OPCODE_DCL_INPUT_PS_SGV:
case D3D10_SB_OPCODE_DCL_INPUT_PS_SIV:
case D3D10_SB_OPCODE_DCL_OUTPUT_SIV:
case D3D10_SB_OPCODE_DCL_OUTPUT_SGV:
opcode->dcl_siv_name = DECODE_D3D10_SB_NAME(*curr);
curr++;
break;
case D3D10_SB_OPCODE_DCL_TEMPS:
opcode->specific.dcl_num_temps = *curr;
curr++;
break;
case D3D10_SB_OPCODE_DCL_INDEXABLE_TEMP:
opcode->specific.dcl_indexable_temp.index = *curr++;
opcode->specific.dcl_indexable_temp.count = *curr++;
opcode->specific.dcl_indexable_temp.components = *curr++;
break;
case D3D10_SB_OPCODE_DCL_INDEX_RANGE:
opcode->specific.index_range_count = *curr++;
break;
default:
break;
}
assert(curr == parser->curr + length);
skip:
/* Advance to the next opcode. */
parser->curr += length;
return TRUE;
}
void
Shader_opcode_free(struct Shader_opcode *opcode)
{
if (opcode->type == D3D10_SB_OPCODE_CUSTOMDATA) {
if (opcode->customdata._class == D3D10_SB_CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER) {
FREE(opcode->customdata.u.constbuf.data);
}
}
}

View File

@ -0,0 +1,183 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* ShaderParse.h --
* Functions for parsing shader tokens.
*/
#ifndef SHADER_PARSE_H
#define SHADER_PARSE_H
#include "DriverIncludes.h"
//#include "winddk/winddk_compat.h"
#include "winddk/d3d10tokenizedprogramformat.hpp"
#ifdef __cplusplus
extern "C" {
#endif
struct Shader_header {
D3D10_SB_TOKENIZED_PROGRAM_TYPE type;
unsigned major_version;
unsigned minor_version;
unsigned size;
};
struct dx10_imm_const_buf {
unsigned count;
unsigned *data;
};
struct dx10_customdata {
D3D10_SB_CUSTOMDATA_CLASS _class;
union {
struct dx10_imm_const_buf constbuf;
} u;
};
struct dx10_indexable_temp {
unsigned index;
unsigned count;
unsigned components;
};
struct dx10_global_flags {
unsigned refactoring_allowed:1;
};
struct Shader_relative_index {
unsigned imm;
};
struct Shader_relative_operand {
D3D10_SB_OPERAND_TYPE type;
struct Shader_relative_index index[2];
D3D10_SB_4_COMPONENT_NAME comp;
};
struct Shader_index {
unsigned imm;
struct Shader_relative_operand rel;
D3D10_SB_OPERAND_INDEX_REPRESENTATION index_rep;
};
struct Shader_operand {
D3D10_SB_OPERAND_TYPE type;
struct Shader_index index[2];
unsigned index_dim;
};
struct Shader_dst_operand {
struct Shader_operand base;
unsigned mask;
};
union Shader_immediate {
float f32;
int i32;
unsigned u32;
};
struct Shader_src_operand {
struct Shader_operand base;
union Shader_immediate imm[4];
D3D10_SB_4_COMPONENT_NAME swizzle[4];
D3D10_SB_OPERAND_MODIFIER modifier;
};
#define SHADER_MAX_DST_OPERANDS 2
#define SHADER_MAX_SRC_OPERANDS 5
struct Shader_opcode {
D3D10_SB_OPCODE_TYPE type;
unsigned num_dst;
unsigned num_src;
struct Shader_dst_operand dst[SHADER_MAX_DST_OPERANDS];
struct Shader_src_operand src[SHADER_MAX_SRC_OPERANDS];
/* Opcode specific data.
*/
union {
D3D10_SB_RESOURCE_DIMENSION dcl_resource_dimension;
D3D10_SB_SAMPLER_MODE dcl_sampler_mode;
D3D10_SB_CONSTANT_BUFFER_ACCESS_PATTERN dcl_cb_access_pattern;
D3D10_SB_INTERPOLATION_MODE dcl_in_ps_interp;
D3D10_SB_PRIMITIVE_TOPOLOGY dcl_gs_output_primitive_topology;
D3D10_SB_PRIMITIVE dcl_gs_input_primitive;
D3D10_SB_INSTRUCTION_TEST_BOOLEAN test_boolean;
D3D10_SB_RESINFO_INSTRUCTION_RETURN_TYPE resinfo_ret_type;
unsigned dcl_max_output_vertex_count;
unsigned dcl_num_temps;
struct dx10_indexable_temp dcl_indexable_temp;
unsigned index_range_count;
struct dx10_global_flags global_flags;
} specific;
D3D10_SB_NAME dcl_siv_name;
D3D10_SB_RESOURCE_RETURN_TYPE dcl_resource_ret_type[4];
boolean saturate;
struct {
int u:4;
int v:4;
int w:4;
} imm_texel_offset;
struct dx10_customdata customdata;
};
struct Shader_parser {
const unsigned *code;
const unsigned *curr;
struct Shader_header header;
};
void
Shader_parse_init(struct Shader_parser *parser,
const unsigned *code);
boolean
Shader_parse_opcode(struct Shader_parser *parser,
struct Shader_opcode *opcode);
void
Shader_opcode_free(struct Shader_opcode *opcode);
const struct tgsi_token *
Shader_tgsi_translate(const unsigned *code,
unsigned *output_mapping);
#ifdef __cplusplus
}
#endif
#endif /* SHADER_PARSE_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,411 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* State.h --
* State declarations.
*/
#include "DriverIncludes.h"
#include "util/u_hash_table.h"
#define SUPPORT_MSAA 0
#define SUPPORT_D3D10_1 0
#define SUPPORT_D3D11 0
struct Adapter
{
struct pipe_screen *screen;
};
static inline Adapter *
CastAdapter(D3D10DDI_HADAPTER hAdapter)
{
return static_cast<Adapter *>(hAdapter.pDrvPrivate);
}
struct Shader
{
void *handle;
uint type;
struct pipe_shader_state state;
unsigned output_mapping[PIPE_MAX_SHADER_OUTPUTS];
boolean output_resolved;
};
struct Query;
struct Device
{
struct pipe_context *pipe;
struct pipe_framebuffer_state fb;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
struct pipe_resource *index_buffer;
unsigned restart_index;
unsigned index_size;
unsigned ib_offset;
void *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
void *empty_fs;
void *empty_vs;
enum pipe_prim_type primitive;
struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
struct pipe_stream_output_target *draw_so_target;
Shader *bound_empty_gs;
Shader *bound_vs;
unsigned max_dual_source_render_targets;
D3D10DDI_HRTCORELAYER hRTCoreLayer;
HANDLE hDevice;
HANDLE hContext;
D3DDDI_DEVICECALLBACKS KTCallbacks;
D3D10DDI_CORELAYER_DEVICECALLBACKS UMCallbacks;
DXGI_DDI_BASE_CALLBACKS *pDXGIBaseCallbacks;
INT LastEmittedQuerySeqNo;
INT LastFinishedQuerySeqNo;
Query *pPredicate;
BOOL PredicateValue;
};
static inline Device *
CastDevice(D3D10DDI_HDEVICE hDevice)
{
return static_cast<Device *>(hDevice.pDrvPrivate);
}
static inline struct pipe_context *
CastPipeContext(D3D10DDI_HDEVICE hDevice)
{
Device *pDevice = CastDevice(hDevice);
return pDevice ? pDevice->pipe : NULL;
}
static inline Device *
CastDevice(DXGI_DDI_HDEVICE hDevice)
{
return reinterpret_cast<Device *>(hDevice);
}
static inline struct pipe_context *
CastPipeDevice(DXGI_DDI_HDEVICE hDevice)
{
Device *pDevice = CastDevice(hDevice);
return pDevice ? pDevice->pipe : NULL;
}
static inline void
SetError(D3D10DDI_HDEVICE hDevice, HRESULT hr)
{
if (FAILED(hr)) {
Device *pDevice = CastDevice(hDevice);
pDevice->UMCallbacks.pfnSetErrorCb(pDevice->hRTCoreLayer, hr);
}
}
struct Resource
{
DXGI_FORMAT Format;
UINT MipLevels;
UINT NumSubResources;
struct pipe_resource *resource;
struct pipe_transfer **transfers;
struct pipe_stream_output_target *so_target;
};
static inline Resource *
CastResource(D3D10DDI_HRESOURCE hResource)
{
return static_cast<Resource *>(hResource.pDrvPrivate);
}
static inline Resource *
CastResource(DXGI_DDI_HRESOURCE hResource)
{
return reinterpret_cast<Resource *>(hResource);
}
static inline struct pipe_resource *
CastPipeResource(D3D10DDI_HRESOURCE hResource)
{
Resource *pResource = CastResource(hResource);
return pResource ? pResource->resource : NULL;
}
static inline struct pipe_resource *
CastPipeResource(DXGI_DDI_HRESOURCE hResource)
{
Resource *pResource = CastResource(hResource);
return pResource ? pResource->resource : NULL;
}
static inline struct pipe_resource *
CastPipeBuffer(D3D10DDI_HRESOURCE hResource)
{
Resource *pResource = CastResource(hResource);
if (!pResource) {
return NULL;
}
return static_cast<struct pipe_resource *>(pResource->resource);
}
struct RenderTargetView
{
struct pipe_surface *surface;
D3D10DDI_HRTRENDERTARGETVIEW hRTRenderTargetView;
};
static inline RenderTargetView *
CastRenderTargetView(D3D10DDI_HRENDERTARGETVIEW hRenderTargetView)
{
return static_cast<RenderTargetView *>(hRenderTargetView.pDrvPrivate);
}
static inline struct pipe_surface *
CastPipeRenderTargetView(D3D10DDI_HRENDERTARGETVIEW hRenderTargetView)
{
RenderTargetView *pRenderTargetView = CastRenderTargetView(hRenderTargetView);
return pRenderTargetView ? pRenderTargetView->surface : NULL;
}
struct DepthStencilView
{
struct pipe_surface *surface;
D3D10DDI_HRTDEPTHSTENCILVIEW hRTDepthStencilView;
};
static inline DepthStencilView *
CastDepthStencilView(D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView)
{
return static_cast<DepthStencilView *>(hDepthStencilView.pDrvPrivate);
}
static inline struct pipe_surface *
CastPipeDepthStencilView(D3D10DDI_HDEPTHSTENCILVIEW hDepthStencilView)
{
DepthStencilView *pDepthStencilView = CastDepthStencilView(hDepthStencilView);
return pDepthStencilView ? pDepthStencilView->surface : NULL;
}
struct BlendState
{
void *handle;
};
static inline BlendState *
CastBlendState(D3D10DDI_HBLENDSTATE hBlendState)
{
return static_cast<BlendState *>(hBlendState.pDrvPrivate);
}
static inline void *
CastPipeBlendState(D3D10DDI_HBLENDSTATE hBlendState)
{
BlendState *pBlendState = CastBlendState(hBlendState);
return pBlendState ? pBlendState->handle : NULL;
}
struct DepthStencilState
{
void *handle;
};
static inline DepthStencilState *
CastDepthStencilState(D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState)
{
return static_cast<DepthStencilState *>(hDepthStencilState.pDrvPrivate);
}
static inline void *
CastPipeDepthStencilState(D3D10DDI_HDEPTHSTENCILSTATE hDepthStencilState)
{
DepthStencilState *pDepthStencilState = CastDepthStencilState(hDepthStencilState);
return pDepthStencilState ? pDepthStencilState->handle : NULL;
}
struct RasterizerState
{
void *handle;
};
static inline RasterizerState *
CastRasterizerState(D3D10DDI_HRASTERIZERSTATE hRasterizerState)
{
return static_cast<RasterizerState *>(hRasterizerState.pDrvPrivate);
}
static inline void *
CastPipeRasterizerState(D3D10DDI_HRASTERIZERSTATE hRasterizerState)
{
RasterizerState *pRasterizerState = CastRasterizerState(hRasterizerState);
return pRasterizerState ? pRasterizerState->handle : NULL;
}
static inline Shader *
CastShader(D3D10DDI_HSHADER hShader)
{
return static_cast<Shader *>(hShader.pDrvPrivate);
}
static inline void *
CastPipeShader(D3D10DDI_HSHADER hShader)
{
Shader *pShader = static_cast<Shader *>(hShader.pDrvPrivate);
return pShader ? pShader->handle : NULL;
}
struct ElementLayout
{
void *handle;
};
static inline ElementLayout *
CastElementLayout(D3D10DDI_HELEMENTLAYOUT hElementLayout)
{
return static_cast<ElementLayout *>(hElementLayout.pDrvPrivate);
}
static inline void *
CastPipeInputLayout(D3D10DDI_HELEMENTLAYOUT hElementLayout)
{
ElementLayout *pElementLayout = CastElementLayout(hElementLayout);
return pElementLayout ? pElementLayout->handle : NULL;
}
struct SamplerState
{
void *handle;
};
static inline SamplerState *
CastSamplerState(D3D10DDI_HSAMPLER hSampler)
{
return static_cast<SamplerState *>(hSampler.pDrvPrivate);
}
static inline void *
CastPipeSamplerState(D3D10DDI_HSAMPLER hSampler)
{
SamplerState *pSamplerState = CastSamplerState(hSampler);
return pSamplerState ? pSamplerState->handle : NULL;
}
struct ShaderResourceView
{
struct pipe_sampler_view *handle;
};
static inline ShaderResourceView *
CastShaderResourceView(D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView)
{
return static_cast<ShaderResourceView *>(hShaderResourceView.pDrvPrivate);
}
static inline struct pipe_sampler_view *
CastPipeShaderResourceView(D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView)
{
ShaderResourceView *pSRView = CastShaderResourceView(hShaderResourceView);
return pSRView ? pSRView->handle : NULL;
}
struct Query
{
D3D10DDI_QUERY Type;
UINT Flags;
unsigned pipe_type;
struct pipe_query *handle;
INT SeqNo;
UINT GetDataCount;
D3D10_DDI_QUERY_DATA_PIPELINE_STATISTICS Statistics;
};
static inline Query *
CastQuery(D3D10DDI_HQUERY hQuery)
{
return static_cast<Query *>(hQuery.pDrvPrivate);
}
static inline struct pipe_query *
CastPipeQuery(D3D10DDI_HQUERY hQuery)
{
Query *pQuery = CastQuery(hQuery);
return pQuery ? pQuery->handle : NULL;
}

View File

@ -0,0 +1,53 @@
EXPORTS
OpenAdapter10
OpenAdapter10_2
D3DKMTAcquireKeyedMutex
D3DKMTCloseAdapter
D3DKMTConfigureSharedResource
D3DKMTCreateAllocation
D3DKMTCreateAllocation2
D3DKMTCreateContext
D3DKMTCreateDevice
D3DKMTCreateKeyedMutex
D3DKMTCreateSynchronizationObject
D3DKMTCreateSynchronizationObject2
D3DKMTDestroyAllocation
D3DKMTDestroyContext
D3DKMTDestroyDevice
D3DKMTDestroyKeyedMutex
D3DKMTDestroySynchronizationObject
D3DKMTEscape
D3DKMTGetContextSchedulingPriority
;D3DKMTGetDeviceSchedulingPriority
D3DKMTGetDeviceState
D3DKMTGetDisplayModeList
D3DKMTGetMultisampleMethodList
D3DKMTGetRuntimeData
D3DKMTGetSharedPrimaryHandle
D3DKMTLock
D3DKMTOpenAdapterFromDeviceName
D3DKMTOpenAdapterFromGdiDisplayName
D3DKMTOpenKeyedMutex
D3DKMTOpenResource
D3DKMTOpenResource2
D3DKMTOpenSynchronizationObject
D3DKMTPresent
D3DKMTQueryAdapterInfo
D3DKMTQueryAllocationResidency
D3DKMTQueryResourceInfo
D3DKMTReleaseKeyedMutex
D3DKMTRender
D3DKMTSetAllocationPriority
D3DKMTSetContextSchedulingPriority
;D3DKMTSetDeviceSchedulingPriority
D3DKMTSetDisplayMode
D3DKMTSetDisplayPrivateDriverFormat
D3DKMTSetGammaRamp
D3DKMTSetVidPnSourceOwner
D3DKMTSetVidPnSourceOwner1
D3DKMTSignalSynchronizationObject
D3DKMTSignalSynchronizationObject2
D3DKMTUnlock
D3DKMTWaitForSynchronizationObject
D3DKMTWaitForSynchronizationObject2
D3DKMTWaitForVerticalBlankEvent

View File

@ -0,0 +1,35 @@
inc_d3d10umd = include_directories('.')
_c_args_d3d10umd = []
if cc.get_id() == 'gcc'
_c_args_d3d10umd += '-Wno-unknown-pragmas'
endif
inc_winddk = include_directories('../../../../include/winddk')
libd3d10umd = static_library(
'd3d10umd',
files(
'Adapter.cpp',
'Debug.cpp',
'Device.cpp',
'Draw.cpp',
'Dxgi.cpp',
'Format.cpp',
'InputAssembly.cpp',
'OutputMerger.cpp',
'Query.cpp',
'Rasterizer.cpp',
'Resource.cpp',
'Shader.cpp',
'ShaderDump.cpp',
'ShaderParse.c',
'ShaderTGSI.c',
'D3DKMT.cpp',
),
c_args : _c_args_d3d10umd,
cpp_args : _c_args_d3d10umd,
include_directories : [
inc_include, inc_src, inc_gallium, inc_gallium_aux, inc_winddk,
],
)

View File

@ -222,6 +222,10 @@ if with_gallium_st_nine
subdir('frontends/nine')
subdir('targets/d3dadapter9')
endif
if with_gallium_st_d3d10umd
subdir('frontends/d3d10umd')
subdir('targets/d3d10sw')
endif
if with_platform_windows
subdir('frontends/wgl')
if with_gallium_d3d12

View File

@ -0,0 +1,50 @@
The resulting d3d10sw.dll implements D3D10's software rendering interface, like
WARP.
It can be used directly from WLK 1.6 and WHCK 2.0 D3D10+ tests, via the -Src
and -SWDLL options. For example:
wgf11blend.exe -Debug -DoNotCatchExceptions -DXGI:1.1 -FeatureLevel:10.0 -Src:SW -SWDLL:d3d10sw.dll -LogClean -LogVerbose
However, as of WHCK version 2.1 this mechanism no longer works reliably.
Either you use WHCK 2.0 binaries, or you must use the alternative method
cribed below (of copying d3d10sw.dll into the executable directory and rename
it such that it matches the D3D10 UMD of the test machine).
Examples can be easily modified to load it too:
D3D10CreateDeviceAndSwapChain(NULL,
D3D10_DRIVER_TYPE_SOFTWARE,
LoadLibraryA("d3d10sw"), /* Software */
Flags,
D3D10_SDK_VERSION,
&SwapChainDesc,
&g_pSwapChain,
&g_pDevice);
D3D11CreateDeviceAndSwapChain(NULL, /* pAdapter */
D3D_DRIVER_TYPE_SOFTWARE,
LoadLibraryA("d3d10sw"), /* Software */
Flags,
FeatureLevels,
sizeof FeatureLevels / sizeof FeatureLevels[0],
D3D11_SDK_VERSION,
&SwapChainDesc,
&g_pSwapChain,
&g_pDevice,
NULL, /* pFeatureLevel */
&g_pDeviceContext); /* ppImmediateContext */
Alternatively, it can be renamed into the system's D3D10 UMD driver (e.g.,
vm3dum_10.dll for VMware vGPU, nvwgf2um.dll for NVIDIA GPU), and placed into
the application directory, or system's directory, and used instead.
For the DLL to be picked from the application directory you'll need to do the
following once:
reg add "HKLM\System\CurrentControlSet\Control\Session Manager" /v "SafeDllSearchMode" /t REG_DWORD /d 0 /f
See also https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order

View File

@ -0,0 +1,82 @@
/**************************************************************************
*
* 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.
*
*
**************************************************************************/
#include "util/u_debug.h"
#include "target-helpers/inline_debug_helper.h"
#include "llvmpipe/lp_public.h"
#include "softpipe/sp_public.h"
#include "sw/gdi/gdi_sw_winsys.h"
extern struct pipe_screen *
d3d10_create_screen(void);
struct pipe_screen *
d3d10_create_screen(void)
{
const char *default_driver;
const char *driver;
struct pipe_screen *screen = NULL;
struct sw_winsys *winsys;
winsys = gdi_create_sw_winsys();
if(!winsys)
goto no_winsys;
#ifdef GALLIUM_LLVMPIPE
default_driver = "llvmpipe";
#else
default_driver = "softpipe";
#endif
driver = debug_get_option("GALLIUM_DRIVER", default_driver);
#ifdef GALLIUM_LLVMPIPE
if (strcmp(driver, "llvmpipe") == 0) {
screen = llvmpipe_create_screen( winsys );
}
#else
(void)driver;
#endif
if (screen == NULL) {
screen = softpipe_create_screen( winsys );
}
if (screen == NULL)
goto no_screen;
return debug_screen_wrap( screen );
no_screen:
winsys->destroy(winsys);
no_winsys:
return NULL;
}

View File

@ -0,0 +1,45 @@
# Copyright © 2021 VMware, Inc
# Copyright © 2018 Intel Corporation
# 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, sublicense, 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 above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS 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.
d3d10sw_def = files('../../frontends/d3d10umd/d3d10_sw.def')[0]
_link_args_d3d10sw = []
if cc.get_id() == 'gcc'
_link_args_d3d10sw += '-Wl,--enable-stdcall-fixup'
endif
libd3d10sw = shared_library(
'd3d10sw',
['d3d10_gdi.c'],
vs_module_defs : d3d10sw_def,
include_directories : [
inc_include, inc_src, inc_gallium, inc_gallium_aux, inc_d3d10umd, inc_gallium_winsys, inc_gallium_winsys_sw, inc_gallium_drivers,
],
link_args : _link_args_d3d10sw,
link_whole : [libd3d10umd],
link_with : [
libgallium, libwsgdi
],
dependencies : [
dep_ws2_32, idep_nir, driver_swrast
],
name_prefix : '', # otherwise mingw will create libd3d10sw.dll
install : true,
)