This commit is contained in:
elwrcl committed 2026-06-06 13:25:15 +03:00
1 parent 04d4dc8b09
commit 818cab85dc
12511 files changed
+6156641

No files matched your search

+274
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",
__func__, 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_2 --
*
* The OpenAdapter10_2 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;
}
+725
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.
*
**************************************************************************/
/*
* D3DKMT.cpp --
* Implement kernel mode thunks, so that this can be loaded as a
* software DLL (D3D_DRIVER_TYPE_SOFTWARE).
*/
#include "DriverIncludes.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(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",
__func__, 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",
__func__, 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 D3DKMT_SETVIDPNSOURCEOWNER1 *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;
}
+81
View File
@@ -0,0 +1,81 @@
#include "Debug.h"
#include <stdarg.h>
#include <stdio.h>
#if MESA_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"},
DEBUG_NAMED_VALUE_END
};
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
}
+78
View File
@@ -0,0 +1,78 @@
#pragma once
#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 "util/u_debug.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ST_DEBUG_OLD_TEX_OPS (1 << 0)
#define ST_DEBUG_TGSI (1 << 1)
#if MESA_DEBUG
extern unsigned st_debug;
#else
#define st_debug 0
#endif
#if MESA_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, __func__, __LINE__)
#define CHECK_HRESULT(hr) \
CheckHResult(hr, __func__, __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__, __func__))
#else
#define ASSERT(expr) do { } while (0 && (expr))
#endif
#if 0 && !defined(NDEBUG)
#define LOG_ENTRYPOINT() DebugPrintf("%s\n", __func__)
#else
#define LOG_ENTRYPOINT() (void)0
#endif
#define LOG_UNSUPPORTED_ENTRYPOINT() DebugPrintf("%s XXX\n", __func__)
#define LOG_UNSUPPORTED(expr) \
do { if (expr) DebugPrintf("%s:%d XXX %s\n", __func__, __LINE__, #expr); } while(0)
#ifdef __cplusplus
}
#endif
+543
View File
@@ -0,0 +1,543 @@
/**************************************************************************
*
* 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 "DxgiFns.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"
#include "util/u_framebuffer.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",
__func__, 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->cso = cso_create_context(pipe, CSO_NO_VBUF);
pDevice->empty_vs = CreateEmptyShader(pDevice, MESA_SHADER_VERTEX);
pDevice->empty_fs = CreateEmptyShader(pDevice, MESA_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->caps.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
*/
D3D10DDI_DEVICEFUNCS *pDeviceFuncs = pCreateData->pDeviceFuncs;
pDeviceFuncs->pfnDefaultConstantBufferUpdateSubresourceUP = ResourceUpdateSubResourceUP;
pDeviceFuncs->pfnVsSetConstantBuffers = VsSetConstantBuffers;
pDeviceFuncs->pfnPsSetShaderResources = PsSetShaderResources;
pDeviceFuncs->pfnPsSetShader = PsSetShader;
pDeviceFuncs->pfnPsSetSamplers = PsSetSamplers;
pDeviceFuncs->pfnVsSetShader = VsSetShader;
pDeviceFuncs->pfnDrawIndexed = DrawIndexed;
pDeviceFuncs->pfnDraw = Draw;
pDeviceFuncs->pfnDynamicIABufferMapNoOverwrite = ResourceMap;
pDeviceFuncs->pfnDynamicIABufferUnmap = ResourceUnmap;
pDeviceFuncs->pfnDynamicConstantBufferMapDiscard = ResourceMap;
pDeviceFuncs->pfnDynamicIABufferMapDiscard = ResourceMap;
pDeviceFuncs->pfnDynamicConstantBufferUnmap = ResourceUnmap;
pDeviceFuncs->pfnPsSetConstantBuffers = PsSetConstantBuffers;
pDeviceFuncs->pfnIaSetInputLayout = IaSetInputLayout;
pDeviceFuncs->pfnIaSetVertexBuffers = IaSetVertexBuffers;
pDeviceFuncs->pfnIaSetIndexBuffer = IaSetIndexBuffer;
pDeviceFuncs->pfnDrawIndexedInstanced = DrawIndexedInstanced;
pDeviceFuncs->pfnDrawInstanced = DrawInstanced;
pDeviceFuncs->pfnDynamicResourceMapDiscard = ResourceMap;
pDeviceFuncs->pfnDynamicResourceUnmap = ResourceUnmap;
pDeviceFuncs->pfnGsSetConstantBuffers = GsSetConstantBuffers;
pDeviceFuncs->pfnGsSetShader = GsSetShader;
pDeviceFuncs->pfnIaSetTopology = IaSetTopology;
pDeviceFuncs->pfnStagingResourceMap = ResourceMap;
pDeviceFuncs->pfnStagingResourceUnmap = ResourceUnmap;
pDeviceFuncs->pfnVsSetShaderResources = VsSetShaderResources;
pDeviceFuncs->pfnVsSetSamplers = VsSetSamplers;
pDeviceFuncs->pfnGsSetShaderResources = GsSetShaderResources;
pDeviceFuncs->pfnGsSetSamplers = GsSetSamplers;
pDeviceFuncs->pfnSetRenderTargets = SetRenderTargets;
pDeviceFuncs->pfnShaderResourceViewReadAfterWriteHazard = ShaderResourceViewReadAfterWriteHazard;
pDeviceFuncs->pfnResourceReadAfterWriteHazard = ResourceReadAfterWriteHazard;
pDeviceFuncs->pfnSetBlendState = SetBlendState;
pDeviceFuncs->pfnSetDepthStencilState = SetDepthStencilState;
pDeviceFuncs->pfnSetRasterizerState = SetRasterizerState;
pDeviceFuncs->pfnQueryEnd = QueryEnd;
pDeviceFuncs->pfnQueryBegin = QueryBegin;
pDeviceFuncs->pfnResourceCopyRegion = ResourceCopyRegion;
pDeviceFuncs->pfnResourceUpdateSubresourceUP = ResourceUpdateSubResourceUP;
pDeviceFuncs->pfnSoSetTargets = SoSetTargets;
pDeviceFuncs->pfnDrawAuto = DrawAuto;
pDeviceFuncs->pfnSetViewports = SetViewports;
pDeviceFuncs->pfnSetScissorRects = SetScissorRects;
pDeviceFuncs->pfnClearRenderTargetView = ClearRenderTargetView;
pDeviceFuncs->pfnClearDepthStencilView = ClearDepthStencilView;
pDeviceFuncs->pfnSetPredication = SetPredication;
pDeviceFuncs->pfnQueryGetData = QueryGetData;
pDeviceFuncs->pfnFlush = Flush;
pDeviceFuncs->pfnGenMips = GenMips;
pDeviceFuncs->pfnResourceCopy = ResourceCopy;
pDeviceFuncs->pfnResourceResolveSubresource = ResourceResolveSubResource;
pDeviceFuncs->pfnResourceMap = ResourceMap;
pDeviceFuncs->pfnResourceUnmap = ResourceUnmap;
pDeviceFuncs->pfnResourceIsStagingBusy = ResourceIsStagingBusy;
pDeviceFuncs->pfnRelocateDeviceFuncs = RelocateDeviceFuncs;
pDeviceFuncs->pfnCalcPrivateResourceSize = CalcPrivateResourceSize;
pDeviceFuncs->pfnCalcPrivateOpenedResourceSize = CalcPrivateOpenedResourceSize;
pDeviceFuncs->pfnCreateResource = CreateResource;
pDeviceFuncs->pfnOpenResource = OpenResource;
pDeviceFuncs->pfnDestroyResource = DestroyResource;
pDeviceFuncs->pfnCalcPrivateShaderResourceViewSize = CalcPrivateShaderResourceViewSize;
pDeviceFuncs->pfnCreateShaderResourceView = CreateShaderResourceView;
pDeviceFuncs->pfnDestroyShaderResourceView = DestroyShaderResourceView;
pDeviceFuncs->pfnCalcPrivateRenderTargetViewSize = CalcPrivateRenderTargetViewSize;
pDeviceFuncs->pfnCreateRenderTargetView = CreateRenderTargetView;
pDeviceFuncs->pfnDestroyRenderTargetView = DestroyRenderTargetView;
pDeviceFuncs->pfnCalcPrivateDepthStencilViewSize = CalcPrivateDepthStencilViewSize;
pDeviceFuncs->pfnCreateDepthStencilView = CreateDepthStencilView;
pDeviceFuncs->pfnDestroyDepthStencilView = DestroyDepthStencilView;
pDeviceFuncs->pfnCalcPrivateElementLayoutSize = CalcPrivateElementLayoutSize;
pDeviceFuncs->pfnCreateElementLayout = CreateElementLayout;
pDeviceFuncs->pfnDestroyElementLayout = DestroyElementLayout;
pDeviceFuncs->pfnCalcPrivateBlendStateSize = CalcPrivateBlendStateSize;
pDeviceFuncs->pfnCreateBlendState = CreateBlendState;
pDeviceFuncs->pfnDestroyBlendState = DestroyBlendState;
pDeviceFuncs->pfnCalcPrivateDepthStencilStateSize = CalcPrivateDepthStencilStateSize;
pDeviceFuncs->pfnCreateDepthStencilState = CreateDepthStencilState;
pDeviceFuncs->pfnDestroyDepthStencilState = DestroyDepthStencilState;
pDeviceFuncs->pfnCalcPrivateRasterizerStateSize = CalcPrivateRasterizerStateSize;
pDeviceFuncs->pfnCreateRasterizerState = CreateRasterizerState;
pDeviceFuncs->pfnDestroyRasterizerState = DestroyRasterizerState;
pDeviceFuncs->pfnCalcPrivateShaderSize = CalcPrivateShaderSize;
pDeviceFuncs->pfnCreateVertexShader = CreateVertexShader;
pDeviceFuncs->pfnCreateGeometryShader = CreateGeometryShader;
pDeviceFuncs->pfnCreatePixelShader = CreatePixelShader;
pDeviceFuncs->pfnCalcPrivateGeometryShaderWithStreamOutput = CalcPrivateGeometryShaderWithStreamOutput;
pDeviceFuncs->pfnCreateGeometryShaderWithStreamOutput = CreateGeometryShaderWithStreamOutput;
pDeviceFuncs->pfnDestroyShader = DestroyShader;
pDeviceFuncs->pfnCalcPrivateSamplerSize = CalcPrivateSamplerSize;
pDeviceFuncs->pfnCreateSampler = CreateSampler;
pDeviceFuncs->pfnDestroySampler = DestroySampler;
pDeviceFuncs->pfnCalcPrivateQuerySize = CalcPrivateQuerySize;
pDeviceFuncs->pfnCreateQuery = CreateQuery;
pDeviceFuncs->pfnDestroyQuery = DestroyQuery;
pDeviceFuncs->pfnCheckFormatSupport = CheckFormatSupport;
pDeviceFuncs->pfnCheckMultisampleQualityLevels = CheckMultisampleQualityLevels;
pDeviceFuncs->pfnCheckCounterInfo = CheckCounterInfo;
pDeviceFuncs->pfnCheckCounter = CheckCounter;
pDeviceFuncs->pfnDestroyDevice = DestroyDevice;
pDeviceFuncs->pfnSetTextFilterSize = SetTextFilterSize;
if (pCreateData->Interface == D3D10_1_DDI_INTERFACE_VERSION ||
pCreateData->Interface == D3D10_1_x_DDI_INTERFACE_VERSION ||
pCreateData->Interface == D3D10_1_7_DDI_INTERFACE_VERSION) {
D3D10_1DDI_DEVICEFUNCS *p10_1DeviceFuncs = pCreateData->p10_1DeviceFuncs;
p10_1DeviceFuncs->pfnRelocateDeviceFuncs = RelocateDeviceFuncs1;
p10_1DeviceFuncs->pfnCalcPrivateShaderResourceViewSize = CalcPrivateShaderResourceViewSize1;
p10_1DeviceFuncs->pfnCreateShaderResourceView = CreateShaderResourceView1;
p10_1DeviceFuncs->pfnCalcPrivateBlendStateSize = CalcPrivateBlendStateSize1;
p10_1DeviceFuncs->pfnCreateBlendState = CreateBlendState1;
p10_1DeviceFuncs->pfnResourceConvert = ResourceCopy;
p10_1DeviceFuncs->pfnResourceConvertRegion = ResourceCopyRegion;
}
/*
* 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);
cso_destroy_context(pDevice->cso);
DeleteEmptyShader(pDevice, MESA_SHADER_FRAGMENT, pDevice->empty_fs);
DeleteEmptyShader(pDevice, MESA_SHADER_VERTEX, pDevice->empty_vs);
util_unreference_framebuffer_state(&pDevice->fb);
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, MESA_SHADER_FRAGMENT, 0,
PIPE_MAX_SHADER_SAMPLER_VIEWS, 0, sampler_views);
pipe->set_sampler_views(pipe, MESA_SHADER_VERTEX, 0,
PIPE_MAX_SHADER_SAMPLER_VIEWS, 0, sampler_views);
pipe->set_sampler_views(pipe, MESA_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 RelocateDeviceFuncs1 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);
}
+44
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 */
+366
View File
@@ -0,0 +1,366 @@
/**************************************************************************
*
* 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;
}
/* stride is required in order to set the element data */
static void
update_velems(Device *pDevice)
{
if (!pDevice->velems_changed)
return;
if(pDevice->element_layout) {
struct cso_velems_state *state = &pDevice->element_layout->state;
for (unsigned i = 0; i < state->count; i++)
state->velems[i].src_stride = pDevice->vertex_strides[state->velems[i].vertex_buffer_index];
cso_set_vertex_elements(pDevice->cso, state);
}
pDevice->velems_changed = false;
}
/*
* 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;
bool 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);
}
update_velems(pDevice);
if (pDevice->vbuffers_changed) {
cso_set_vertex_buffers(pDevice->cso, PIPE_MAX_ATTRIBS, pDevice->vertex_buffers);
pDevice->vbuffers_changed = false;
}
}
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 < MESA_PRIM_COUNT);
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 < MESA_PRIM_COUNT);
/* 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 < MESA_PRIM_COUNT);
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 < MESA_PRIM_COUNT);
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 < MESA_PRIM_COUNT);
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);
}
+52
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
@@ -0,0 +1,51 @@
/**************************************************************************
*
* 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
#include "Debug.h"
#include "util/u_inlines.h"
#include <winddk_compat.h>
#define D3D10DDI_MINOR_HEADER_VERSION 2
/* Unfortunately WinDDK's d3d10umddi.h defines D3D10.x constants as global
* const variables instead of preprocessor defines, causing LINK to fail due
* to duplicate symbols. Include d3d10_1.h to avoid the issue.
*/
#include <d3d10_1.h>
#include <d3d10umddi.h>
#endif /* DRIVER_INCLUDES_H */
+262
View File
@@ -0,0 +1,262 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* DxgiFns.cpp --
* DXGI related functions.
*/
#include <stdio.h>
#include "DxgiFns.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 Device *device = CastDevice(pPresentData->hDevice);
Resource *pSrcResource = CastResource(pPresentData->hSurfaceToPresent);
device->pipe->flush(device->pipe, NULL, 0);
device->pipe->screen->flush_frontbuffer(device->pipe->screen, device->pipe,
pSrcResource->resource, 0, 0, pPresentData->pDXGIContext, 0, NULL);
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;
}
+46
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.
*
**************************************************************************/
/*
* DxgiFns.h --
* DXGI related functions
*/
#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
+389
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",
__func__, 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 "???";
}
}
+45
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
@@ -0,0 +1,358 @@
/**************************************************************************
*
* 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>
#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 mesa_prim primitive;
switch (PrimitiveTopology) {
case D3D10_DDI_PRIMITIVE_TOPOLOGY_UNDEFINED:
/* Apps might set topology to UNDEFINED when cleaning up on exit. */
primitive = MESA_PRIM_COUNT;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_POINTLIST:
primitive = MESA_PRIM_POINTS;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_LINELIST:
primitive = MESA_PRIM_LINES;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_LINESTRIP:
primitive = MESA_PRIM_LINE_STRIP;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_TRIANGLELIST:
primitive = MESA_PRIM_TRIANGLES;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP:
primitive = MESA_PRIM_TRIANGLE_STRIP;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_LINELIST_ADJ:
primitive = MESA_PRIM_LINES_ADJACENCY;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ:
primitive = MESA_PRIM_LINE_STRIP_ADJACENCY;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ:
primitive = MESA_PRIM_TRIANGLES_ADJACENCY;
break;
case D3D10_DDI_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ:
primitive = MESA_PRIM_TRIANGLE_STRIP_ADJACENCY;
break;
default:
assert(0);
primitive = MESA_PRIM_COUNT;
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);
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) {
pDevice->vertex_strides[StartBuffer + i] = 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 {
pDevice->vertex_strides[StartBuffer + i] = 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) {
pDevice->vertex_strides[i] = 0;
vb->buffer_offset = 0;
vb->is_user_buffer = true;
vb->buffer.user = dummy;
}
}
/* Resubmit old and new vertex buffers.
*/
pDevice->velems_changed = true;
pDevice->vbuffers_changed = true;
}
/*
* ----------------------------------------------------------------------
*
* 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();
ElementLayout *pElementLayout = CastElementLayout(hElementLayout);
memset(pElementLayout, 0, sizeof *pElementLayout);
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 =
&pElementLayout->state.velems[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", __func__);
}
pElementLayout->state.count = max_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();
}
/*
* ----------------------------------------------------------------------
*
* 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();
Device *pDevice = CastDevice(hDevice);
pDevice->element_layout = CastElementLayout(hInputLayout);
pDevice->velems_changed = true;
}
@@ -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 */
@@ -0,0 +1,1000 @@
/**************************************************************************
*
* 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_resource *resource = CastPipeResource(pCreateRenderTargetView->hDrvResource);
RenderTargetView *pRTView = CastRenderTargetView(hRenderTargetView);
struct pipe_surface desc;
memset(&desc, 0, sizeof desc);
pipe_resource_reference(&desc.texture, resource);
desc.format = FormatTranslate(pCreateRenderTargetView->Format, false);
switch (pCreateRenderTargetView->ResourceDimension) {
case D3D10DDIRESOURCE_BUFFER:
LOG_UNSUPPORTED("Render target view into buffer!");
SetError(hDevice, E_NOTIMPL);
return;
case D3D10DDIRESOURCE_TEXTURE1D:
ASSERT(pCreateRenderTargetView->Tex1D.ArraySize != (UINT)-1);
desc.level = pCreateRenderTargetView->Tex1D.MipSlice;
desc.first_layer = pCreateRenderTargetView->Tex1D.FirstArraySlice;
desc.last_layer = pCreateRenderTargetView->Tex1D.ArraySize - 1 +
desc.first_layer;
break;
case D3D10DDIRESOURCE_TEXTURE2D:
ASSERT(pCreateRenderTargetView->Tex2D.ArraySize != (UINT)-1);
desc.level = pCreateRenderTargetView->Tex2D.MipSlice;
desc.first_layer = pCreateRenderTargetView->Tex2D.FirstArraySlice;
desc.last_layer = pCreateRenderTargetView->Tex2D.ArraySize - 1 +
desc.first_layer;
break;
case D3D10DDIRESOURCE_TEXTURE3D:
desc.level = pCreateRenderTargetView->Tex3D.MipSlice;
desc.first_layer = pCreateRenderTargetView->Tex3D.FirstW;
desc.last_layer = pCreateRenderTargetView->Tex3D.WSize - 1 +
desc.first_layer;
break;
case D3D10DDIRESOURCE_TEXTURECUBE:
ASSERT(pCreateRenderTargetView->TexCube.ArraySize != (UINT)-1);
desc.level = pCreateRenderTargetView->TexCube.MipSlice;
desc.first_layer = pCreateRenderTargetView->TexCube.FirstArraySlice;
desc.last_layer = pCreateRenderTargetView->TexCube.ArraySize - 1 +
desc.first_layer;
break;
default:
ASSERT(0);
return;
}
pRTView->surface = desc;
}
/*
* ----------------------------------------------------------------------
*
* 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_resource_reference(&pRTView->surface.texture, 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,
pipe_surface_width(surface),
pipe_surface_height(surface),
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_resource *resource = CastPipeResource(pCreateDepthStencilView->hDrvResource);
DepthStencilView *pDSView = CastDepthStencilView(hDepthStencilView);
struct pipe_surface desc;
memset(&desc, 0, sizeof desc);
pipe_resource_reference(&desc.texture, resource);
desc.format = FormatTranslate(pCreateDepthStencilView->Format, true);
switch (pCreateDepthStencilView->ResourceDimension) {
case D3D10DDIRESOURCE_TEXTURE1D:
ASSERT(pCreateDepthStencilView->Tex1D.ArraySize != (UINT)-1);
desc.level = pCreateDepthStencilView->Tex1D.MipSlice;
desc.first_layer = pCreateDepthStencilView->Tex1D.FirstArraySlice;
desc.last_layer = pCreateDepthStencilView->Tex1D.ArraySize - 1 +
desc.first_layer;
break;
case D3D10DDIRESOURCE_TEXTURE2D:
ASSERT(pCreateDepthStencilView->Tex2D.ArraySize != (UINT)-1);
desc.level = pCreateDepthStencilView->Tex2D.MipSlice;
desc.first_layer = pCreateDepthStencilView->Tex2D.FirstArraySlice;
desc.last_layer = pCreateDepthStencilView->Tex2D.ArraySize - 1 +
desc.first_layer;
break;
case D3D10DDIRESOURCE_TEXTURECUBE:
ASSERT(pCreateDepthStencilView->TexCube.ArraySize != (UINT)-1);
desc.level = pCreateDepthStencilView->TexCube.MipSlice;
desc.first_layer = pCreateDepthStencilView->TexCube.FirstArraySlice;
desc.last_layer = pCreateDepthStencilView->TexCube.ArraySize - 1 +
desc.first_layer;
break;
default:
ASSERT(0);
return;
}
pDSView->surface = desc;
}
/*
* ----------------------------------------------------------------------
*
* 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_resource_reference(&pDSView->surface.texture, 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,
pipe_surface_width(surface),
pipe_surface_height(surface),
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 CalcPrivateBlendStateSize1 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);
}
/*
* ----------------------------------------------------------------------
*
* translateBlendOp --
*
* 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 CreateBlendState1 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) {
struct pipe_surface *psurf = CastPipeRenderTargetView(phRenderTargetView[i]);
pipe_resource_reference(&pDevice->fb.cbufs[i].texture,
psurf && psurf->texture ? psurf->texture : NULL);
if (psurf && psurf->texture) {
pDevice->fb.nr_cbufs = i + 1;
pDevice->fb.cbufs[i] = *psurf;
}
}
for (unsigned i = RTargets; i < PIPE_MAX_COLOR_BUFS; ++i) {
pipe_resource_reference(&pDevice->fb.cbufs[i].texture, NULL);
}
struct pipe_surface *zsbuf = CastPipeDepthStencilView(hDepthStencilView);
pipe_resource_reference(&pDevice->fb.zsbuf.texture, zsbuf && zsbuf->texture ? zsbuf->texture : NULL);
if(zsbuf && zsbuf->texture) {
pDevice->fb.zsbuf = *zsbuf;
}
/*
* 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;
#if MESA_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 DestroyDepthStencilState function destroy 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);
}
@@ -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 */
+454
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;
}
bool wait = !!(Flags & D3D10_DDI_GET_DATA_DO_NOT_FLUSH);
union pipe_query_result result;
memset(&result, 0, sizeof result);
bool 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);
bool 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);
}
+76
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 */
+6
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/d3d10umd/README.md for further details.
@@ -0,0 +1,287 @@
/**************************************************************************
*
* Copyright 2012-2021 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
**************************************************************************/
/*
* Rasterizer.cpp --
* Functions that manipulate rasterizer state.
*/
#include "Rasterizer.h"
#include "State.h"
#include "Debug.h"
/*
* ----------------------------------------------------------------------
*
* SetViewports --
*
* The SetViewports function sets viewports.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
SetViewports(D3D10DDI_HDEVICE hDevice, // IN
UINT NumViewports, // IN
UINT ClearViewports, // IN
__in_ecount (NumViewports) const D3D10_DDI_VIEWPORT *pViewports) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
struct pipe_viewport_state states[PIPE_MAX_VIEWPORTS];
ASSERT(NumViewports + ClearViewports <=
D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE);
for (UINT i = 0; i < NumViewports; ++i) {
const D3D10_DDI_VIEWPORT *pViewport = &pViewports[i];
float width = pViewport->Width;
float height = pViewport->Height;
float x = pViewport->TopLeftX;
float y = pViewport->TopLeftY;
float z = pViewport->MinDepth;
float half_width = width / 2.0f;
float half_height = height / 2.0f;
float depth = pViewport->MaxDepth - z;
states[i].scale[0] = half_width;
states[i].scale[1] = -half_height;
states[i].scale[2] = depth;
states[i].translate[0] = half_width + x;
states[i].translate[1] = half_height + y;
states[i].translate[2] = z;
}
if (ClearViewports) {
memset(states + NumViewports, 0,
sizeof(struct pipe_viewport_state) * ClearViewports);
}
pipe->set_viewport_states(pipe, 0, NumViewports + ClearViewports,
states);
}
/*
* ----------------------------------------------------------------------
*
* SetScissorRects --
*
* The SetScissorRects function marks portions of render targets
* that rendering is confined to.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
SetScissorRects(D3D10DDI_HDEVICE hDevice, // IN
UINT NumScissorRects, // IN
UINT ClearScissorRects, // IN
__in_ecount (NumRects) const D3D10_DDI_RECT *pRects) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
struct pipe_scissor_state states[PIPE_MAX_VIEWPORTS];
ASSERT(NumScissorRects + ClearScissorRects <=
D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE);
for (UINT i = 0; i < NumScissorRects; ++i) {
const D3D10_DDI_RECT *pRect = &pRects[i];
/* gallium scissor values are unsigned so lets make
* sure that we don't overflow */
states[i].minx = pRect->left < 0 ? 0 : pRect->left;
states[i].miny = pRect->top < 0 ? 0 : pRect->top;
states[i].maxx = pRect->right < 0 ? 0 : pRect->right;
states[i].maxy = pRect->bottom < 0 ? 0 : pRect->bottom;
}
if (ClearScissorRects) {
memset(states + NumScissorRects, 0,
sizeof(struct pipe_scissor_state) * ClearScissorRects);
}
pipe->set_scissor_states(pipe, 0, NumScissorRects + ClearScissorRects,
states);
}
/*
* ----------------------------------------------------------------------
*
* CalcPrivateRasterizerStateSize --
*
* The CalcPrivateRasterizerStateSize function determines the size
* of the user-mode display driver's private region of memory
* (that is, the size of internal driver structures, not the size
* of the resource video memory) for a rasterizer state.
*
* ----------------------------------------------------------------------
*/
SIZE_T APIENTRY
CalcPrivateRasterizerStateSize(
D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10_DDI_RASTERIZER_DESC *pRasterizerDesc) // IN
{
return sizeof(RasterizerState);
}
static uint
translate_cull_mode(D3D10_DDI_CULL_MODE CullMode)
{
switch (CullMode) {
case D3D10_DDI_CULL_NONE:
return PIPE_FACE_NONE;
case D3D10_DDI_CULL_FRONT:
return PIPE_FACE_FRONT;
case D3D10_DDI_CULL_BACK:
return PIPE_FACE_BACK;
default:
assert(0);
return PIPE_FACE_NONE;
}
}
static uint
translate_fill_mode(D3D10_DDI_FILL_MODE FillMode)
{
switch (FillMode) {
case D3D10_DDI_FILL_WIREFRAME:
return PIPE_POLYGON_MODE_LINE;
case D3D10_DDI_FILL_SOLID:
return PIPE_POLYGON_MODE_FILL;
default:
assert(0);
return PIPE_POLYGON_MODE_FILL;
}
}
/*
* ----------------------------------------------------------------------
*
* CreateRasterizerState --
*
* The CreateRasterizerState function creates a rasterizer state.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
CreateRasterizerState(
D3D10DDI_HDEVICE hDevice, // IN
__in const D3D10_DDI_RASTERIZER_DESC *pRasterizerDesc, // IN
D3D10DDI_HRASTERIZERSTATE hRasterizerState, // IN
D3D10DDI_HRTRASTERIZERSTATE hRTRasterizerState) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
RasterizerState *pRasterizerState = CastRasterizerState(hRasterizerState);
struct pipe_rasterizer_state state;
memset(&state, 0, sizeof state);
state.flatshade_first = 1;
state.front_ccw = (pRasterizerDesc->FrontCounterClockwise ? 1 : 0);
state.cull_face = translate_cull_mode(pRasterizerDesc->CullMode);
state.fill_front = translate_fill_mode(pRasterizerDesc->FillMode);
state.fill_back = state.fill_front;
state.scissor = (pRasterizerDesc->ScissorEnable ? 1 : 0);
state.line_smooth = (pRasterizerDesc->AntialiasedLineEnable ? 1 : 0);
state.offset_units = (float)pRasterizerDesc->DepthBias;
state.offset_scale = pRasterizerDesc->SlopeScaledDepthBias;
state.offset_clamp = pRasterizerDesc->DepthBiasClamp;
state.multisample = /* pRasterizerDesc->MultisampleEnable */ 0;
state.half_pixel_center = 1;
state.bottom_edge_rule = 0;
state.clip_halfz = 1;
state.depth_clip_near = pRasterizerDesc->DepthClipEnable ? 1 : 0;
state.depth_clip_far = pRasterizerDesc->DepthClipEnable ? 1 : 0;
state.depth_clamp = 1;
state.point_quad_rasterization = 1;
state.point_size = 1.0f;
state.point_line_tri_clip = 1;
state.line_width = 1.0f;
state.line_rectangular = 0;
pRasterizerState->handle = pipe->create_rasterizer_state(pipe, &state);
}
/*
* ----------------------------------------------------------------------
*
* DestroyRasterizerState --
*
* The DestroyRasterizerState function destroys the specified
* rasterizer state object. The rasterizer state object can be
* destoyed only if it is not currently bound to a display device.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
DestroyRasterizerState(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRASTERIZERSTATE hRasterizerState) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
RasterizerState *pRasterizerState = CastRasterizerState(hRasterizerState);
pipe->delete_rasterizer_state(pipe, pRasterizerState->handle);
}
/*
* ----------------------------------------------------------------------
*
* SetRasterizerState --
*
* The SetRasterizerState function sets the rasterizer state.
*
* ----------------------------------------------------------------------
*/
void APIENTRY
SetRasterizerState(D3D10DDI_HDEVICE hDevice, // IN
D3D10DDI_HRASTERIZERSTATE hRasterizerState) // IN
{
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeContext(hDevice);
void *state = CastPipeRasterizerState(hRasterizerState);
pipe->bind_rasterizer_state(pipe, state);
}
@@ -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 */
+940
View File
@@ -0,0 +1,940 @@
/**************************************************************************
*
* 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 pipe_resource_usage
translate_resource_usage(UINT usage)
{
pipe_resource_usage resource_usage = PIPE_USAGE_DEFAULT;
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;
if (flags & D3D10_DDI_BIND_PRESENT)
bind |= PIPE_BIND_DISPLAY_TARGET;
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",
__func__,
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 );
pResource->buffer = templat.target == PIPE_BUFFER;
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",
__func__, 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", __func__);
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) {
if (pResource->buffer) {
assert(pResource->NumSubResources == 1);
const D3D10_DDIARG_SUBRESOURCE_UP* pInitialDataUP =
&pCreateResource->pInitialDataUP[0];
unsigned level;
struct pipe_box box;
subResourceBox(pResource->resource, 0, &level, &box);
struct pipe_transfer *transfer;
void *map;
map = pipe->buffer_map(pipe,
pResource->resource,
level,
PIPE_MAP_WRITE |
PIPE_MAP_UNSYNCHRONIZED,
&box,
&transfer);
assert(map);
if (map) {
memcpy(map, pInitialDataUP->pSysMem, box.width);
pipe_buffer_unmap(pipe, transfer);
}
} else {
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->texture_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) {
uint8_t *dst = (uint8_t*)map + z*transfer->layer_stride;
const uint8_t *src = (const uint8_t*)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_texture_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]) {
if (pResource->buffer) {
pipe_buffer_unmap(pipe, pResource->transfers[SubResource]);
} else {
pipe_texture_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;
if (pResource->buffer) {
map = pipe->buffer_map(pipe,
resource,
level,
usage,
&box,
&pResource->transfers[SubResource]);
} else {
map = pipe->texture_map(pipe,
resource,
level,
usage,
&box,
&pResource->transfers[SubResource]);
}
if (!map) {
DebugPrintf("%s: failed to map resource\n", __func__);
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]) {
if (pResource->buffer) {
pipe_buffer_unmap(pipe, pResource->transfers[SubResource]);
} else {
pipe_texture_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;
Resource *pDstResource = CastResource(hDstResource);
struct pipe_resource *dst_resource = pDstResource->resource;
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;
if (pDstResource->buffer) {
map = pipe->buffer_map(pipe,
dst_resource,
level,
PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE,
&box,
&transfer);
} else {
map = pipe->texture_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) {
uint8_t *dst = (uint8_t*)map + z*transfer->layer_stride;
const uint8_t *src = (const uint8_t*)pSysMemUP + z*DepthPitch;
util_copy_rect(dst,
dst_resource->format,
transfer->stride,
0, 0, box.width, box.height,
src,
RowPitch,
0, 0);
}
if (pDstResource->buffer) {
pipe_buffer_unmap(pipe, transfer);
} else {
pipe_texture_unmap(pipe, transfer);
}
}
}
+93
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
+164
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,
mesa_shader_stage processor);
void
DeleteEmptyShader(Device *pDevice,
mesa_shader_stage 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 */
@@ -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);
}
@@ -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 */
@@ -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]);
}
}
}
bool
Shader_parse_opcode(struct Shader_parser *parser,
struct Shader_opcode *opcode)
{
const unsigned *curr = parser->curr;
const struct dx10_opcode_info *info;
unsigned length;
bool 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_OPERAND_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++) {
bool 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);
}
}
}
@@ -0,0 +1,180 @@
/**************************************************************************
*
* 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"
#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];
bool 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);
bool
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
+410
View File
@@ -0,0 +1,410 @@
/**************************************************************************
*
* 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"
#include "cso_cache/cso_context.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];
bool output_resolved;
};
struct Query;
struct ElementLayout;
struct Device
{
struct pipe_context *pipe;
struct cso_context *cso;
struct pipe_framebuffer_state fb;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
unsigned vertex_strides[PIPE_MAX_ATTRIBS];
struct pipe_resource *index_buffer;
unsigned restart_index;
unsigned index_size;
unsigned ib_offset;
void *samplers[MESA_SHADER_STAGES][PIPE_MAX_SAMPLERS];
struct pipe_sampler_view *sampler_views[MESA_SHADER_STAGES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
void *empty_fs;
void *empty_vs;
enum mesa_prim 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;
ElementLayout *element_layout;
BOOL velems_changed;
BOOL vbuffers_changed;
};
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;
bool buffer;
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
{
struct cso_velems_state state;
};
static inline ElementLayout *
CastElementLayout(D3D10DDI_HELEMENTLAYOUT hElementLayout)
{
return static_cast<ElementLayout *>(hElementLayout.pDrvPrivate);
}
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;
}
@@ -0,0 +1,34 @@
inc_d3d10umd = include_directories('.')
_c_args_d3d10umd = []
if cc.get_argument_syntax() == 'gcc'
_c_args_d3d10umd += '-Wno-unknown-pragmas'
endif
libd3d10umd = static_library(
'd3d10umd',
files(
'Adapter.cpp',
'Debug.cpp',
'Device.cpp',
'Draw.cpp',
'DxgiFns.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,
],
dependencies: idep_mesautilformat,
)
File diff suppressed because it is too large. Load diff
+353
View File
@@ -0,0 +1,353 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Author: Keith Whitwell <[email protected]>
* Author: Jakob Bornecrantz <[email protected]>
*/
#include "dri_screen.h"
#include "dri_drawable.h"
#include "dri_context.h"
#include "frontend/drm_driver.h"
#include "pipe/p_context.h"
#include "pipe-loader/pipe_loader.h"
#include "state_tracker/st_context.h"
#include "util/u_cpu_detect.h"
#include "util/u_memory.h"
#include "util/u_debug.h"
struct dri_context *
dri_create_context(struct dri_screen *screen,
gl_api api, const struct gl_config *visual,
const struct __DriverContextConfig *ctx_config,
unsigned *error,
struct dri_context *sharedContextPrivate,
void *loaderPrivate,
bool thread_safe)
{
struct dri_context *ctx = NULL;
struct st_context *st_share = NULL;
struct st_context_attribs attribs;
enum st_context_error ctx_err = 0;
unsigned allowed_flags = __DRI_CTX_FLAG_DEBUG |
__DRI_CTX_FLAG_FORWARD_COMPATIBLE;
unsigned allowed_attribs =
__DRIVER_CONTEXT_ATTRIB_PRIORITY |
__DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR |
__DRIVER_CONTEXT_ATTRIB_NO_ERROR;
const struct driOptionCache *optionCache = &screen->dev->option_cache;
/* This is effectively doing error checking for GLX context creation (by both
* Mesa and the X server) when the driver doesn't support the robustness ext.
* EGL already checks, so it won't send us the flags if the ext isn't
* available.
*/
if (screen->has_reset_status_query) {
allowed_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS;
allowed_attribs |= __DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY;
}
if (screen->has_protected_context)
allowed_attribs |= __DRIVER_CONTEXT_ATTRIB_PROTECTED;
if (ctx_config->flags & ~allowed_flags) {
*error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
goto fail;
}
if (ctx_config->attribute_mask & ~allowed_attribs) {
*error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
goto fail;
}
memset(&attribs, 0, sizeof(attribs));
switch (api) {
case API_OPENGLES:
attribs.profile = API_OPENGLES;
break;
case API_OPENGLES2:
attribs.profile = API_OPENGLES2;
break;
case API_OPENGL_COMPAT:
case API_OPENGL_CORE:
if (driQueryOptionb(optionCache, "force_compat_profile")) {
attribs.profile = API_OPENGL_COMPAT;
} else {
attribs.profile = api == API_OPENGL_COMPAT ? API_OPENGL_COMPAT
: API_OPENGL_CORE;
}
attribs.major = ctx_config->major_version;
attribs.minor = ctx_config->minor_version;
if ((ctx_config->flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0)
attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
break;
default:
*error = __DRI_CTX_ERROR_BAD_API;
goto fail;
}
if ((ctx_config->flags & __DRI_CTX_FLAG_DEBUG) != 0)
attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
if (ctx_config->flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)
attribs.context_flags |= PIPE_CONTEXT_ROBUST_BUFFER_ACCESS;
if (ctx_config->attribute_mask & __DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY)
if (ctx_config->reset_strategy != __DRI_CTX_RESET_NO_NOTIFICATION)
attribs.context_flags |= PIPE_CONTEXT_LOSE_CONTEXT_ON_RESET;
if (ctx_config->attribute_mask & __DRIVER_CONTEXT_ATTRIB_NO_ERROR)
attribs.flags |= ctx_config->no_error ? ST_CONTEXT_FLAG_NO_ERROR : 0;
if (ctx_config->attribute_mask & __DRIVER_CONTEXT_ATTRIB_PRIORITY) {
switch (ctx_config->priority) {
case __DRI_CTX_PRIORITY_LOW:
attribs.context_flags |= PIPE_CONTEXT_LOW_PRIORITY;
break;
case __DRI_CTX_PRIORITY_HIGH:
attribs.context_flags |= PIPE_CONTEXT_HIGH_PRIORITY;
break;
case __DRI_CTX_PRIORITY_REALTIME:
attribs.context_flags |= PIPE_CONTEXT_REALTIME_PRIORITY;
break;
default:
break;
}
}
if ((ctx_config->attribute_mask & __DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR)
&& (ctx_config->release_behavior == __DRI_CTX_RELEASE_BEHAVIOR_NONE))
attribs.flags |= ST_CONTEXT_FLAG_RELEASE_NONE;
if (ctx_config->attribute_mask & __DRIVER_CONTEXT_ATTRIB_PROTECTED)
attribs.context_flags |= PIPE_CONTEXT_PROTECTED;
struct dri_context *share_ctx = NULL;
if (sharedContextPrivate) {
share_ctx = (struct dri_context *)sharedContextPrivate;
st_share = share_ctx->st;
}
ctx = CALLOC_STRUCT(dri_context);
if (ctx == NULL) {
*error = __DRI_CTX_ERROR_NO_MEMORY;
goto fail;
}
ctx->screen = screen;
ctx->loaderPrivate = loaderPrivate;
/* KHR_no_error is likely to crash, overflow memory, etc if an application
* has errors so don't enable it for setuid processes.
*/
if (debug_get_bool_option("MESA_NO_ERROR", false) ||
driQueryOptionb(&screen->dev->option_cache, "mesa_no_error"))
#if !defined(_WIN32)
if (__normal_user())
#endif
attribs.flags |= ST_CONTEXT_FLAG_NO_ERROR;
attribs.options = screen->options;
dri_fill_st_visual(&attribs.visual, screen, visual);
ctx->st = st_api_create_context(&screen->base, &attribs, &ctx_err,
st_share);
if (ctx->st == NULL) {
switch (ctx_err) {
case ST_CONTEXT_SUCCESS:
*error = __DRI_CTX_ERROR_SUCCESS;
break;
case ST_CONTEXT_ERROR_NO_MEMORY:
*error = __DRI_CTX_ERROR_NO_MEMORY;
break;
case ST_CONTEXT_ERROR_BAD_VERSION:
*error = __DRI_CTX_ERROR_BAD_VERSION;
break;
}
goto fail;
}
ctx->st->frontend_context = (void *) ctx;
if (ctx->st->cso_context) {
ctx->hud = hud_create(ctx->st->cso_context,
share_ctx ? share_ctx->hud : NULL,
ctx->st, st_context_invalidate_state);
}
/* order of precedence (least to most):
* - driver setting
* - app setting
* - user setting
*/
bool enable_glthread = driQueryOptionb(&screen->dev->option_cache, "mesa_glthread_driver");
/* always disable glthread by default if fewer than 5 "big" CPUs are active */
unsigned nr_big_cpus = util_get_cpu_caps()->nr_big_cpus;
if (util_get_cpu_caps()->nr_cpus < 4 || (nr_big_cpus && nr_big_cpus < 5))
enable_glthread = false;
int app_enable_glthread = driQueryOptioni(&screen->dev->option_cache, "mesa_glthread_app_profile");
if (app_enable_glthread != -1) {
/* if set (not -1), apply the app setting */
enable_glthread = app_enable_glthread == 1;
}
if (os_get_option("mesa_glthread")) {
/* only apply the env var if set */
bool user_enable_glthread = debug_get_bool_option("mesa_glthread", false);
if (user_enable_glthread != enable_glthread) {
/* print warning to mimic old behavior */
fprintf(stderr, "ATTENTION: default value of option mesa_glthread overridden by environment.\n");
}
enable_glthread = user_enable_glthread;
}
if (!thread_safe)
enable_glthread = false;
/* Do this last. */
if (enable_glthread)
_mesa_glthread_init(ctx->st->ctx);
*error = __DRI_CTX_ERROR_SUCCESS;
return ctx;
fail:
if (ctx && ctx->st)
st_destroy_context(ctx->st);
free(ctx);
return NULL;
}
void
dri_destroy_context(struct dri_context *ctx)
{
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(ctx->st->ctx);
if (ctx->hud) {
hud_destroy(ctx->hud, ctx->st->cso_context);
}
/* No particular reason to wait for command completion before
* destroying a context, but we flush the context here
* to avoid having to add code elsewhere to cope with flushing a
* partially destroyed context.
*/
st_context_flush(ctx->st, 0, NULL, NULL, NULL);
st_destroy_context(ctx->st);
free(ctx);
}
/* This is called inside MakeCurrent to unbind the context. */
bool
dri_unbind_context(struct dri_context *ctx)
{
/* dri_util.c ensures cPriv is not null */
struct st_context *st = ctx->st;
if (st == st_api_get_current()) {
_mesa_glthread_finish(st->ctx);
/* Record HUD queries for the duration the context was "current". */
if (ctx->hud)
hud_record_only(ctx->hud, st->pipe);
st_api_make_current(NULL, NULL, NULL);
}
if (ctx->draw || ctx->read) {
assert(ctx->draw);
dri_put_drawable(ctx->draw);
if (ctx->read != ctx->draw)
dri_put_drawable(ctx->read);
ctx->draw = NULL;
ctx->read = NULL;
}
return GL_TRUE;
}
bool
dri_make_current(struct dri_context *ctx,
struct dri_drawable *draw,
struct dri_drawable *read)
{
/* dri_unbind_context() is always called before this, so drawables are
* always NULL here.
*/
assert(!ctx->draw);
assert(!ctx->read);
if ((draw && !read) || (!draw && read))
return GL_FALSE; /* only both non-NULL or both NULL are allowed */
/* Wait for glthread to finish because we can't use st_context from
* multiple threads.
*/
_mesa_glthread_finish(ctx->st->ctx);
/* There are 2 cases that can occur here. Either we bind drawables, or we
* bind NULL for configless and surfaceless contexts.
*/
if (!draw && !read)
return st_api_make_current(ctx->st, NULL, NULL);
/* Bind drawables to the context */
ctx->draw = draw;
ctx->read = read;
dri_get_drawable(draw);
draw->texture_stamp = draw->lastStamp - 1;
if (draw != read) {
dri_get_drawable(read);
read->texture_stamp = read->lastStamp - 1;
}
st_api_make_current(ctx->st, &draw->base, &read->base);
return GL_TRUE;
}
struct dri_context *
dri_get_current(void)
{
struct st_context *st = st_api_get_current();
return (struct dri_context *) st ? st->frontend_context : NULL;
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */
+108
View File
@@ -0,0 +1,108 @@
/**************************************************************************
*
* Copyright (C) 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.
*
**************************************************************************/
/*
* Author: Keith Whitwell <[email protected]>
* Author: Jakob Bornecrantz <[email protected]>
*/
#ifndef DRI_CONTEXT_H
#define DRI_CONTEXT_H
#include "dri_util.h"
#include "util/compiler.h"
#include "hud/hud_context.h"
struct pipe_context;
struct pipe_fence;
struct st_context;
struct dri_drawable;
struct dri_screen;
struct dri_context
{
/* dri */
struct dri_screen *screen;
/**
* Pointer to drawable currently bound to this context for drawing.
*/
struct dri_drawable *draw;
/**
* Pointer to drawable currently bound to this context for reading.
*/
struct dri_drawable *read;
/**
* True if the dri_drawable's current __DRIimageBufferMask is
* __DRI_IMAGE_BUFFER_SHARED.
*/
bool is_shared_buffer_bound;
/**
* The loaders's private context data. This structure is opaque.
*/
void *loaderPrivate;
struct {
int draw_stamp;
int read_stamp;
} dri2;
/* gallium */
struct st_context *st;
struct hud_context *hud;
};
/***********************************************************************
* dri_context.c
*/
void dri_destroy_context(struct dri_context *ctx);
bool
dri_unbind_context(struct dri_context *ctx);
bool
dri_make_current(struct dri_context *ctx,
struct dri_drawable *draw,
struct dri_drawable *read);
struct dri_context *
dri_get_current(void);
struct dri_context *
dri_create_context(struct dri_screen *screen,
gl_api api, const struct gl_config *visual,
const struct __DriverContextConfig *ctx_config,
unsigned *error,
struct dri_context *sharedContextPrivate,
void *loaderPrivate,
bool thread_safe);
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */
+577
View File
@@ -0,0 +1,577 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Author: Keith Whitwell <[email protected]>
* Author: Jakob Bornecrantz <[email protected]>
*/
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_drawable.h"
#include "pipe/p_screen.h"
#include "util/format/u_format.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "state_tracker/st_context.h"
static uint32_t drifb_ID = 0;
static bool
dri_st_framebuffer_validate(struct st_context *st,
struct pipe_frontend_drawable *pdrawable,
const enum st_attachment_type *statts,
unsigned count,
struct pipe_resource **out,
struct pipe_resource **resolve)
{
struct dri_context *ctx = (struct dri_context *)st->frontend_context;
struct dri_drawable *drawable = (struct dri_drawable *)pdrawable;
struct dri_screen *screen = drawable->screen;
unsigned statt_mask, new_mask;
bool new_stamp;
int i;
unsigned int lastStamp;
struct pipe_resource **textures =
drawable->stvis.samples > 1 ? drawable->msaa_textures
: drawable->textures;
statt_mask = 0x0;
for (i = 0; i < count; i++)
statt_mask |= (1 << statts[i]);
/* record newly allocated textures */
new_mask = (statt_mask & ~drawable->texture_mask);
do {
lastStamp = drawable->lastStamp;
new_stamp = (drawable->texture_stamp != lastStamp);
if (new_stamp || new_mask) {
if (new_stamp && drawable->update_drawable_info)
drawable->update_drawable_info(drawable);
drawable->allocate_textures(ctx, drawable, statts, count);
/* add existing textures */
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
if (textures[i])
statt_mask |= (1 << i);
}
drawable->texture_stamp = lastStamp;
drawable->texture_mask = statt_mask;
}
} while (lastStamp != drawable->lastStamp);
/* Flush the pending set_damage_region request. */
struct pipe_screen *pscreen = screen->base.screen;
if (new_mask & (1 << ST_ATTACHMENT_BACK_LEFT) &&
pscreen->set_damage_region) {
struct pipe_resource *resource = textures[ST_ATTACHMENT_BACK_LEFT];
if (resource) {
pscreen->set_damage_region(pscreen, resource,
drawable->num_damage_rects,
drawable->damage_rects);
}
}
if (!out)
return true;
/* Set the window-system buffers for the gallium frontend. */
for (i = 0; i < count; i++)
pipe_resource_reference(&out[i], textures[statts[i]]);
if (resolve && drawable->stvis.samples > 1) {
if (statt_mask & BITFIELD_BIT(ST_ATTACHMENT_FRONT_LEFT))
pipe_resource_reference(resolve, drawable->textures[ST_ATTACHMENT_FRONT_LEFT]);
else if (statt_mask & BITFIELD_BIT(ST_ATTACHMENT_BACK_LEFT))
pipe_resource_reference(resolve, drawable->textures[ST_ATTACHMENT_BACK_LEFT]);
}
return true;
}
static bool
dri_st_framebuffer_flush_front(struct st_context *st,
struct pipe_frontend_drawable *pdrawable,
enum st_attachment_type statt)
{
struct dri_context *ctx = (struct dri_context *)st->frontend_context;
struct dri_drawable *drawable = (struct dri_drawable *)pdrawable;
/* XXX remove this and just set the correct one on the framebuffer */
return drawable->flush_frontbuffer(ctx, drawable, statt);
}
/**
* The gallium frontend framebuffer interface flush_swapbuffers callback
*/
static bool
dri_st_framebuffer_flush_swapbuffers(struct st_context *st,
struct pipe_frontend_drawable *pdrawable)
{
struct dri_context *ctx = (struct dri_context *)st->frontend_context;
struct dri_drawable *drawable = (struct dri_drawable *)pdrawable;
if (drawable->flush_swapbuffers)
drawable->flush_swapbuffers(ctx, drawable);
return true;
}
/**
* This is called when we need to set up GL rendering to a new X window.
*/
struct dri_drawable *
dri_create_drawable(struct dri_screen *screen, const struct dri_config *config,
bool isPixmap, void *loaderPrivate)
{
const struct gl_config *visual = &config->modes;
struct dri_drawable *drawable = NULL;
drawable = CALLOC_STRUCT(dri_drawable);
if (!drawable)
return NULL;
drawable->loaderPrivate = loaderPrivate;
drawable->refcount = 1;
drawable->lastStamp = 0;
drawable->w = 0;
drawable->h = 0;
dri_fill_st_visual(&drawable->stvis, screen, visual);
/* setup the pipe_frontend_drawable */
drawable->base.visual = &drawable->stvis;
drawable->base.flush_front = dri_st_framebuffer_flush_front;
drawable->base.validate = dri_st_framebuffer_validate;
drawable->base.flush_swapbuffers = dri_st_framebuffer_flush_swapbuffers;
drawable->screen = screen;
p_atomic_set(&drawable->base.stamp, 1);
drawable->base.ID = p_atomic_inc_return(&drifb_ID);
drawable->base.fscreen = &screen->base;
switch (screen->type) {
case DRI_SCREEN_DRI3:
case DRI_SCREEN_KMS_SWRAST:
dri2_init_drawable(drawable, isPixmap, visual->alphaBits);
break;
case DRI_SCREEN_SWRAST:
drisw_init_drawable(drawable, isPixmap, visual->alphaBits);
break;
case DRI_SCREEN_KOPPER:
kopper_init_drawable(drawable, isPixmap, visual->alphaBits);
break;
}
return drawable;
}
static void
dri_destroy_drawable(struct dri_drawable *drawable)
{
struct dri_screen *screen = drawable->screen;
int i;
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_resource_reference(&drawable->textures[i], NULL);
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_resource_reference(&drawable->msaa_textures[i], NULL);
screen->base.screen->fence_reference(screen->base.screen,
&drawable->throttle_fence, NULL);
/* Notify the st manager that this drawable is no longer valid */
st_api_destroy_drawable(&drawable->base);
if (screen->type == DRI_SCREEN_KOPPER)
kopper_destroy_drawable(drawable);
FREE(drawable->damage_rects);
FREE(drawable);
}
void
dri_put_drawable(struct dri_drawable *drawable)
{
if (drawable) {
int refcount = --drawable->refcount;
assert(refcount >= 0);
if (!refcount)
dri_destroy_drawable(drawable);
}
}
/**
* Validate the texture at an attachment. Allocate the texture if it does not
* exist. Used by the TFP extension.
*/
static void
dri_drawable_validate_att(struct dri_context *ctx,
struct dri_drawable *drawable,
enum st_attachment_type statt)
{
enum st_attachment_type statts[ST_ATTACHMENT_COUNT];
unsigned i, count = 0;
/* check if buffer already exists */
if (drawable->texture_mask & (1 << statt))
return;
/* make sure DRI2 does not destroy existing buffers */
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
if (drawable->texture_mask & (1 << i)) {
statts[count++] = i;
}
}
statts[count++] = statt;
drawable->texture_stamp = drawable->lastStamp - 1;
drawable->base.validate(ctx->st, &drawable->base, statts, count, NULL, NULL);
}
/**
* These are used for GLX_EXT_texture_from_pixmap
*/
void
dri_set_tex_buffer2(struct dri_context *ctx, GLint target,
GLint format, struct dri_drawable *drawable)
{
struct st_context *st = ctx->st;
struct pipe_resource *pt;
_mesa_glthread_finish(st->ctx);
dri_drawable_validate_att(ctx, drawable, ST_ATTACHMENT_FRONT_LEFT);
/* Use the pipe resource associated with the X drawable */
pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
if (pt) {
enum pipe_format internal_format = pt->format;
if (format == __DRI_TEXTURE_FORMAT_RGB) {
/* only need to cover the formats recognized by dri_fill_st_visual */
switch (internal_format) {
case PIPE_FORMAT_R16G16B16A16_FLOAT:
internal_format = PIPE_FORMAT_R16G16B16X16_FLOAT;
break;
case PIPE_FORMAT_B10G10R10A2_UNORM:
internal_format = PIPE_FORMAT_B10G10R10X2_UNORM;
break;
case PIPE_FORMAT_R10G10B10A2_UNORM:
internal_format = PIPE_FORMAT_R10G10B10X2_UNORM;
break;
case PIPE_FORMAT_BGRA8888_UNORM:
internal_format = PIPE_FORMAT_BGRX8888_UNORM;
break;
case PIPE_FORMAT_ARGB8888_UNORM:
internal_format = PIPE_FORMAT_XRGB8888_UNORM;
break;
default:
break;
}
}
drawable->update_tex_buffer(drawable, ctx, pt);
st_context_teximage(ctx->st, target, 0, internal_format, pt, false);
}
}
/**
* Get the format and binding of an attachment.
*/
void
dri_drawable_get_format(struct dri_drawable *drawable,
enum st_attachment_type statt,
enum pipe_format *format,
unsigned *bind)
{
switch (statt) {
case ST_ATTACHMENT_FRONT_LEFT:
case ST_ATTACHMENT_BACK_LEFT:
case ST_ATTACHMENT_FRONT_RIGHT:
case ST_ATTACHMENT_BACK_RIGHT:
/* Other pieces of the driver stack get confused and behave incorrectly
* when they get an sRGB drawable. st/mesa receives "drawable->stvis"
* though other means and handles it correctly, so we don't really need
* to use an sRGB format here.
*/
*format = util_format_linear(drawable->stvis.color_format);
*bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
break;
case ST_ATTACHMENT_DEPTH_STENCIL:
*format = drawable->stvis.depth_stencil_format;
*bind = PIPE_BIND_DEPTH_STENCIL; /* XXX sampler? */
break;
default:
*format = PIPE_FORMAT_NONE;
*bind = 0;
break;
}
}
void
dri_pipe_blit(struct pipe_context *pipe,
struct pipe_resource *dst,
struct pipe_resource *src)
{
struct pipe_blit_info blit;
if (!dst || !src)
return;
/* From the GL spec, version 4.2, section 4.1.11 (Additional Multisample
* Fragment Operations):
*
* If a framebuffer object is not bound, after all operations have
* been completed on the multisample buffer, the sample values for
* each color in the multisample buffer are combined to produce a
* single color value, and that value is written into the
* corresponding color buffers selected by DrawBuffer or
* DrawBuffers. An implementation may defer the writing of the color
* buffers until a later time, but the state of the framebuffer must
* behave as if the color buffers were updated as each fragment was
* processed. The method of combination is not specified. If the
* framebuffer contains sRGB values, then it is recommended that the
* an average of sample values is computed in a linearized space, as
* for blending (see section 4.1.7).
*
* In other words, to do a resolve operation in a linear space, we have
* to set sRGB formats if the original resources were sRGB, so don't use
* util_format_linear.
*/
memset(&blit, 0, sizeof(blit));
blit.dst.resource = dst;
blit.dst.box.width = dst->width0;
blit.dst.box.height = dst->height0;
blit.dst.box.depth = 1;
blit.dst.format = dst->format;
blit.src.resource = src;
blit.src.box.width = src->width0;
blit.src.box.height = src->height0;
blit.src.box.depth = 1;
blit.src.format = src->format;
blit.mask = PIPE_MASK_RGBA;
blit.filter = PIPE_TEX_FILTER_NEAREST;
pipe->blit(pipe, &blit);
}
struct notify_before_flush_cb_args {
struct dri_context *ctx;
struct dri_drawable *drawable;
unsigned flags;
enum __DRI2throttleReason reason;
bool swap_msaa_buffers;
};
static void
notify_before_flush_cb(void* _args)
{
struct notify_before_flush_cb_args *args = (struct notify_before_flush_cb_args *) _args;
struct st_context *st = args->ctx->st;
struct pipe_context *pipe = st->pipe;
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(st->ctx);
if (args->drawable->stvis.samples > 1 &&
(args->reason == __DRI2_THROTTLE_SWAPBUFFER ||
args->reason == __DRI2_NOTHROTTLE_SWAPBUFFER ||
args->reason == __DRI2_THROTTLE_COPYSUBBUFFER)) {
/* Resolve the MSAA back buffer. */
dri_pipe_blit(st->pipe,
args->drawable->textures[ST_ATTACHMENT_BACK_LEFT],
args->drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT]);
if ((args->reason == __DRI2_THROTTLE_SWAPBUFFER ||
args->reason == __DRI2_NOTHROTTLE_SWAPBUFFER) &&
args->drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT] &&
args->drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT]) {
args->swap_msaa_buffers = true;
}
/* FRONT_LEFT is resolved in drawable->flush_frontbuffer. */
}
if (pipe->invalidate_resource &&
(args->flags & __DRI2_FLUSH_INVALIDATE_ANCILLARY)) {
if (args->drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL])
pipe->invalidate_resource(pipe, args->drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);
if (args->drawable->msaa_textures[ST_ATTACHMENT_DEPTH_STENCIL])
pipe->invalidate_resource(pipe, args->drawable->msaa_textures[ST_ATTACHMENT_DEPTH_STENCIL]);
}
if (args->ctx->hud) {
hud_run(args->ctx->hud, args->ctx->st->cso_context,
args->drawable->textures[ST_ATTACHMENT_BACK_LEFT]);
}
pipe->flush_resource(pipe, args->drawable->textures[ST_ATTACHMENT_BACK_LEFT]);
}
/**
* DRI2 flush extension, the flush_with_flags function.
*
* \param context the context
* \param drawable the drawable to flush
* \param flags a combination of _DRI2_FLUSH_xxx flags
* \param throttle_reason the reason for throttling, 0 = no throttling
*/
void
dri_flush(struct dri_context *ctx,
struct dri_drawable *drawable,
unsigned flags,
enum __DRI2throttleReason reason)
{
struct st_context *st;
unsigned flush_flags;
struct notify_before_flush_cb_args args = { 0 };
if (!ctx) {
assert(0);
return;
}
st = ctx->st;
_mesa_glthread_finish(st->ctx);
if (drawable) {
/* prevent recursion */
if (drawable->flushing)
return;
drawable->flushing = true;
}
else {
flags &= ~__DRI2_FLUSH_DRAWABLE;
}
if ((flags & __DRI2_FLUSH_DRAWABLE) &&
drawable->textures[ST_ATTACHMENT_BACK_LEFT]) {
/* We can't do operations on the back buffer here, because there
* may be some pending operations that will get flushed by the
* call to st->flush (eg: FLUSH_VERTICES).
* Instead we register a callback to be notified when all operations
* have been submitted but before the call to st_flush.
*/
args.ctx = ctx;
args.drawable = drawable;
args.flags = flags;
args.reason = reason;
}
flush_flags = 0;
if (flags & __DRI2_FLUSH_CONTEXT)
flush_flags |= ST_FLUSH_FRONT;
if (reason == __DRI2_THROTTLE_SWAPBUFFER ||
reason == __DRI2_NOTHROTTLE_SWAPBUFFER)
flush_flags |= ST_FLUSH_END_OF_FRAME;
/* Flush the context and throttle if needed. */
if (ctx->screen->throttle &&
drawable &&
(reason == __DRI2_THROTTLE_SWAPBUFFER ||
reason == __DRI2_THROTTLE_FLUSHFRONT)) {
struct pipe_screen *screen = drawable->screen->base.screen;
struct pipe_fence_handle *new_fence = NULL;
st_context_flush(st, flush_flags, &new_fence, args.ctx ? notify_before_flush_cb : NULL, &args);
/* throttle on the previous fence */
if (drawable->throttle_fence) {
screen->fence_finish(screen, NULL, drawable->throttle_fence, OS_TIMEOUT_INFINITE);
screen->fence_reference(screen, &drawable->throttle_fence, NULL);
}
drawable->throttle_fence = new_fence;
}
else if (flags & (__DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT)) {
st_context_flush(st, flush_flags, NULL, args.ctx ? notify_before_flush_cb : NULL, &args);
}
if (drawable) {
drawable->flushing = false;
}
/* Swap the MSAA front and back buffers, so that reading
* from the front buffer after SwapBuffers returns what was
* in the back buffer.
*/
if (args.swap_msaa_buffers) {
struct pipe_resource *tmp =
drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT];
drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT] =
drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT];
drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT] = tmp;
/* Now that we have swapped the buffers, this tells the gallium
* frontend to revalidate the framebuffer.
*/
p_atomic_inc(&drawable->base.stamp);
}
st_context_invalidate_state(st, ST_INVALIDATE_FB_STATE);
}
/**
* DRI2 flush extension.
*/
void
dri_flush_drawable(struct dri_drawable *dPriv)
{
struct dri_context *ctx = dri_get_current();
if (ctx)
dri_flush(ctx, dPriv, __DRI2_FLUSH_DRAWABLE, -1);
}
/**
* dri_throttle - A DRI2ThrottleExtension throttling function.
*/
void
dri_throttle(struct dri_context *cPriv, struct dri_drawable *dPriv,
enum __DRI2throttleReason reason)
{
dri_flush(cPriv, dPriv, 0, reason);
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */
+173
View File
@@ -0,0 +1,173 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
#ifndef DRI_DRAWABLE_H
#define DRI_DRAWABLE_H
#include "util/compiler.h"
#include "util/format/u_formats.h"
#include "frontend/api.h"
#include "dri_util.h"
#ifdef VK_USE_PLATFORM_XCB_KHR
#include <xcb/xcb.h>
#endif
struct pipe_context;
struct dri_context;
struct dri_screen;
struct dri_drawable
{
struct pipe_frontend_drawable base;
struct st_visual stvis;
struct dri_screen *screen;
__DRIbuffer old[__DRI_BUFFER_COUNT];
unsigned old_num;
unsigned old_w;
unsigned old_h;
struct pipe_box *damage_rects;
unsigned int num_damage_rects;
struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
struct pipe_resource *msaa_textures[ST_ATTACHMENT_COUNT];
unsigned int texture_mask, texture_stamp;
int swap_interval;
struct pipe_fence_handle *throttle_fence;
bool flushing; /* prevents recursion in dri_flush */
/**
* Private data from the loader. We just hold on to it and pass
* it back when calling into loader provided functions.
*/
void *loaderPrivate;
/**
* Reference count for number of context's currently bound to this
* drawable.
*
* Once it reaches zero, the drawable can be destroyed.
*
* \note This behavior will change with GLX 1.3.
*/
int refcount;
/**
* Increased when the loader calls invalidate.
*
* If this changes, the drawable information (below) should be retrieved
* from the loader.
*/
unsigned int lastStamp;
int w, h;
/* generic for swrast */
unsigned buffer_age;
/* kopper */
struct kopper_loader_info info;
struct dri_image *image; //texture_from_pixmap
bool is_window;
bool window_valid;
#ifdef VK_USE_PLATFORM_XCB_KHR
xcb_special_event_t *special_event;
#endif
/* hooks filled in by dri2 & drisw */
void (*allocate_textures)(struct dri_context *ctx,
struct dri_drawable *drawable,
const enum st_attachment_type *statts,
unsigned count);
void (*update_drawable_info)(struct dri_drawable *drawable);
bool (*flush_frontbuffer)(struct dri_context *ctx,
struct dri_drawable *drawable,
enum st_attachment_type statt);
void (*update_tex_buffer)(struct dri_drawable *drawable,
struct dri_context *ctx,
struct pipe_resource *res);
void (*flush_swapbuffers)(struct dri_context *ctx,
struct dri_drawable *drawable);
void (*swap_buffers)(struct dri_drawable *drawable);
void (*swap_buffers_with_damage)(struct dri_drawable *drawable, int nrects, const int *rects);
};
static inline void
dri_get_drawable(struct dri_drawable *drawable)
{
drawable->refcount++;
}
/***********************************************************************
* dri_drawable.c
*/
void
dri_put_drawable(struct dri_drawable *drawable);
void
dri_drawable_get_format(struct dri_drawable *drawable,
enum st_attachment_type statt,
enum pipe_format *format,
unsigned *bind);
void
dri_pipe_blit(struct pipe_context *pipe,
struct pipe_resource *dst,
struct pipe_resource *src);
void
dri_flush(struct dri_context *ctx,
struct dri_drawable *drawable,
unsigned flags,
enum __DRI2throttleReason reason);
void
dri_flush_drawable(struct dri_drawable *dPriv);
void
drisw_update_tex_buffer(struct dri_drawable *drawable,
struct dri_context *ctx,
struct pipe_resource *res);
void
kopper_init_drawable(struct dri_drawable *drawable, bool isPixmap, int alphaBits);
void
drisw_init_drawable(struct dri_drawable *drawable, bool isPixmap, int alphaBits);
void
dri2_init_drawable(struct dri_drawable *drawable, bool isPixmap, int alphaBits);
void
kopper_destroy_drawable(struct dri_drawable *drawable);
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */
+886
View File
@@ -0,0 +1,886 @@
/*
* Copyright (C) 1999-2007 Brian Paul 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, 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.
*/
#include <dlfcn.h>
#include "drm-uapi/drm_fourcc.h"
#include "util/u_memory.h"
#include "pipe/p_screen.h"
#include "state_tracker/st_texture.h"
#include "state_tracker/st_context.h"
#include "main/texobj.h"
#include "util/libsync.h"
#include "dri_helpers.h"
#include "loader_dri_helper.h"
static bool
dri2_is_opencl_interop_loaded_locked(struct dri_screen *screen)
{
return screen->opencl_dri_event_add_ref &&
screen->opencl_dri_event_release &&
screen->opencl_dri_event_wait &&
screen->opencl_dri_event_get_fence;
}
static bool
dri2_load_opencl_interop(struct dri_screen *screen)
{
#if defined(RTLD_DEFAULT)
bool success;
mtx_lock(&screen->opencl_func_mutex);
if (dri2_is_opencl_interop_loaded_locked(screen)) {
mtx_unlock(&screen->opencl_func_mutex);
return true;
}
screen->opencl_dri_event_add_ref =
dlsym(RTLD_DEFAULT, "opencl_dri_event_add_ref");
screen->opencl_dri_event_release =
dlsym(RTLD_DEFAULT, "opencl_dri_event_release");
screen->opencl_dri_event_wait =
dlsym(RTLD_DEFAULT, "opencl_dri_event_wait");
screen->opencl_dri_event_get_fence =
dlsym(RTLD_DEFAULT, "opencl_dri_event_get_fence");
success = dri2_is_opencl_interop_loaded_locked(screen);
mtx_unlock(&screen->opencl_func_mutex);
return success;
#else
return false;
#endif
}
struct dri2_fence {
struct dri_screen *driscreen;
struct pipe_fence_handle *pipe_fence;
void *cl_event;
};
unsigned
dri_fence_get_caps(struct dri_screen *driscreen)
{
struct pipe_screen *screen = driscreen->base.screen;
unsigned caps = 0;
if (screen->caps.native_fence_fd)
caps |= __DRI_FENCE_CAP_NATIVE_FD;
return caps;
}
void *
dri_create_fence(struct dri_context *ctx)
{
struct st_context *st = ctx->st;
struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
if (!fence)
return NULL;
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(st->ctx);
st_context_flush(st, 0, &fence->pipe_fence, NULL, NULL);
if (!fence->pipe_fence) {
FREE(fence);
return NULL;
}
fence->driscreen = ctx->screen;
return fence;
}
void *
dri_create_fence_fd(struct dri_context *dri_ctx, int fd)
{
struct st_context *st = dri_ctx->st;
struct pipe_context *ctx = st->pipe;
struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(st->ctx);
if (fd == -1) {
/* exporting driver created fence, flush: */
st_context_flush(st, ST_FLUSH_FENCE_FD, &fence->pipe_fence, NULL, NULL);
} else {
/* importing a foreign fence fd: */
ctx->create_fence_fd(ctx, &fence->pipe_fence, fd, PIPE_FD_TYPE_NATIVE_SYNC);
}
if (!fence->pipe_fence) {
FREE(fence);
return NULL;
}
fence->driscreen = dri_ctx->screen;
return fence;
}
int
dri_get_fence_fd(struct dri_screen *driscreen, void *_fence)
{
struct pipe_screen *screen = driscreen->base.screen;
struct dri2_fence *fence = (struct dri2_fence*)_fence;
return screen->fence_get_fd(screen, fence->pipe_fence);
}
void *
dri_get_fence_from_cl_event(struct dri_screen *driscreen, intptr_t cl_event)
{
struct dri2_fence *fence;
if (!dri2_load_opencl_interop(driscreen))
return NULL;
fence = CALLOC_STRUCT(dri2_fence);
if (!fence)
return NULL;
fence->cl_event = (void*)cl_event;
if (!driscreen->opencl_dri_event_add_ref(fence->cl_event)) {
free(fence);
return NULL;
}
fence->driscreen = driscreen;
return fence;
}
void
dri_destroy_fence(struct dri_screen *driscreen, void *_fence)
{
struct pipe_screen *screen = driscreen->base.screen;
struct dri2_fence *fence = (struct dri2_fence*)_fence;
if (fence->pipe_fence)
screen->fence_reference(screen, &fence->pipe_fence, NULL);
else if (fence->cl_event)
driscreen->opencl_dri_event_release(fence->cl_event);
else
assert(0);
FREE(fence);
}
GLboolean
dri_client_wait_sync(struct dri_context *_ctx, void *_fence, unsigned flags,
uint64_t timeout)
{
struct dri2_fence *fence = (struct dri2_fence*)_fence;
struct dri_screen *driscreen = fence->driscreen;
struct pipe_screen *screen = driscreen->base.screen;
/* No need to flush. The context was flushed when the fence was created. */
if (fence->pipe_fence)
return screen->fence_finish(screen, NULL, fence->pipe_fence, timeout);
else if (fence->cl_event) {
struct pipe_fence_handle *pipe_fence =
driscreen->opencl_dri_event_get_fence(fence->cl_event);
if (pipe_fence)
return screen->fence_finish(screen, NULL, pipe_fence, timeout);
else
return driscreen->opencl_dri_event_wait(fence->cl_event, timeout);
}
else {
assert(0);
return false;
}
}
void
dri_server_wait_sync(struct dri_context *_ctx, void *_fence, unsigned flags)
{
struct st_context *st = _ctx->st;
struct pipe_context *ctx = st->pipe;
struct dri2_fence *fence = (struct dri2_fence*)_fence;
/* We might be called here with a NULL fence as a result of WaitSyncKHR
* on a EGL_KHR_reusable_sync fence. Nothing to do here in such case.
*/
if (!fence)
return;
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(st->ctx);
if (ctx->fence_server_sync)
ctx->fence_server_sync(ctx, fence->pipe_fence, 0);
}
struct dri_image *
dri_create_image_from_renderbuffer(struct dri_context *dri_ctx,
int renderbuffer, void *loaderPrivate,
unsigned *error)
{
struct st_context *st = dri_ctx->st;
struct gl_context *ctx = st->ctx;
struct pipe_context *p_ctx = st->pipe;
struct gl_renderbuffer *rb;
struct pipe_resource *tex;
struct dri_image *img;
/* Wait for glthread to finish to get up-to-date GL object lookups. */
_mesa_glthread_finish(st->ctx);
/* Section 3.9 (EGLImage Specification and Management) of the EGL 1.5
* specification says:
*
* "If target is EGL_GL_RENDERBUFFER and buffer is not the name of a
* renderbuffer object, or if buffer is the name of a multisampled
* renderbuffer object, the error EGL_BAD_PARAMETER is generated."
*
* "If target is EGL_GL_TEXTURE_2D , EGL_GL_TEXTURE_CUBE_MAP_*,
* EGL_GL_RENDERBUFFER or EGL_GL_TEXTURE_3D and buffer refers to the
* default GL texture object (0) for the corresponding GL target, the
* error EGL_BAD_PARAMETER is generated."
* (rely on _mesa_lookup_renderbuffer returning NULL in this case)
*/
rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
if (!rb || rb->NumSamples > 0) {
*error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
return NULL;
}
tex = rb->texture;
if (!tex) {
*error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
return NULL;
}
img = CALLOC_STRUCT(dri_image);
if (!img) {
*error = __DRI_IMAGE_ERROR_BAD_ALLOC;
return NULL;
}
img->dri_format = tex->format;
img->internal_format = rb->InternalFormat;
img->loader_private = loaderPrivate;
img->screen = dri_ctx->screen;
img->in_fence_fd = -1;
pipe_resource_reference(&img->texture, tex);
/* If the resource supports EGL_MESA_image_dma_buf_export, make sure that
* it's in a shareable state. Do this now while we still have the access to
* the context.
*/
if (dri2_get_mapping_by_format(img->dri_format)) {
p_ctx->flush_resource(p_ctx, tex);
st_context_flush(st, 0, NULL, NULL, NULL);
}
ctx->Shared->HasExternallySharedImages = true;
*error = __DRI_IMAGE_ERROR_SUCCESS;
return img;
}
void
dri2_destroy_image(struct dri_image *img)
{
const __DRIimageLoaderExtension *imgLoader = img->screen->image.loader;
if (imgLoader && imgLoader->base.version >= 4 &&
imgLoader->destroyLoaderImageState) {
imgLoader->destroyLoaderImageState(img->loader_private);
}
pipe_resource_reference(&img->texture, NULL);
if (img->in_fence_fd != -1)
close(img->in_fence_fd);
FREE(img);
}
struct dri_image *
dri2_create_from_texture(struct dri_context *dri_ctx, int target, unsigned texture,
int depth, int level, unsigned *error,
void *loaderPrivate)
{
struct dri_image *img;
struct st_context *st = dri_ctx->st;
struct gl_context *ctx = st->ctx;
struct pipe_context *p_ctx = st->pipe;
struct gl_texture_object *obj;
struct gl_texture_image *glimg;
GLuint face = 0;
/* Wait for glthread to finish to get up-to-date GL object lookups. */
_mesa_glthread_finish(st->ctx);
obj = _mesa_lookup_texture(ctx, texture);
if (!obj || obj->Target != target) {
*error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
return NULL;
}
if (target == GL_TEXTURE_CUBE_MAP)
face = depth;
_mesa_test_texobj_completeness(ctx, obj);
if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
*error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
return NULL;
}
if (level < obj->Attrib.BaseLevel || level > obj->_MaxLevel) {
*error = __DRI_IMAGE_ERROR_BAD_MATCH;
return NULL;
}
glimg = obj->Image[face][level];
if (!glimg || !glimg->pt) {
*error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
return NULL;
}
if (target == GL_TEXTURE_3D && glimg->Depth < depth) {
*error = __DRI_IMAGE_ERROR_BAD_MATCH;
return NULL;
}
img = CALLOC_STRUCT(dri_image);
if (!img) {
*error = __DRI_IMAGE_ERROR_BAD_ALLOC;
return NULL;
}
img->level = level;
img->layer = depth;
img->in_fence_fd = -1;
img->dri_format = glimg->pt->format;
img->internal_format = glimg->InternalFormat;
img->loader_private = loaderPrivate;
img->screen = dri_ctx->screen;
pipe_resource_reference(&img->texture, glimg->pt);
/* If the resource supports EGL_MESA_image_dma_buf_export, make sure that
* it's in a shareable state. Do this now while we still have the access to
* the context.
*/
if (dri2_get_mapping_by_format(img->dri_format)) {
p_ctx->flush_resource(p_ctx, glimg->pt);
st_context_flush(st, 0, NULL, NULL, NULL);
}
ctx->Shared->HasExternallySharedImages = true;
*error = __DRI_IMAGE_ERROR_SUCCESS;
return img;
}
static const struct dri2_format_mapping dri2_format_table[] = {
/*
* RGB formats:
*/
{ DRM_FORMAT_ABGR16161616F, __DRI_IMAGE_FORMAT_ABGR16161616F,
PIPE_FORMAT_R16G16B16A16_FLOAT, 1, },
{ DRM_FORMAT_XBGR16161616F, __DRI_IMAGE_FORMAT_XBGR16161616F,
PIPE_FORMAT_R16G16B16X16_FLOAT, 1, },
{ DRM_FORMAT_ABGR16161616, __DRI_IMAGE_FORMAT_ABGR16161616,
PIPE_FORMAT_R16G16B16A16_UNORM, 1, },
{ DRM_FORMAT_XBGR16161616, __DRI_IMAGE_FORMAT_XBGR16161616,
PIPE_FORMAT_R16G16B16X16_UNORM, 1, },
{ DRM_FORMAT_ARGB2101010, __DRI_IMAGE_FORMAT_ARGB2101010,
PIPE_FORMAT_B10G10R10A2_UNORM, 1, },
{ DRM_FORMAT_XRGB2101010, __DRI_IMAGE_FORMAT_XRGB2101010,
PIPE_FORMAT_B10G10R10X2_UNORM, 1, },
{ DRM_FORMAT_ABGR2101010, __DRI_IMAGE_FORMAT_ABGR2101010,
PIPE_FORMAT_R10G10B10A2_UNORM, 1, },
{ DRM_FORMAT_XBGR2101010, __DRI_IMAGE_FORMAT_XBGR2101010,
PIPE_FORMAT_R10G10B10X2_UNORM, 1, },
{ DRM_FORMAT_ARGB8888, __DRI_IMAGE_FORMAT_ARGB8888,
PIPE_FORMAT_BGRA8888_UNORM, 1, },
{ DRM_FORMAT_BGRA8888, PIPE_FORMAT_A8R8G8B8_UNORM,
PIPE_FORMAT_A8R8G8B8_UNORM, 1, },
{ DRM_FORMAT_ABGR8888, __DRI_IMAGE_FORMAT_ABGR8888,
PIPE_FORMAT_RGBA8888_UNORM, 1, },
{ DRM_FORMAT_RGBA8888, PIPE_FORMAT_A8B8G8R8_UNORM,
PIPE_FORMAT_A8B8G8R8_UNORM, 1, },
{ __DRI_IMAGE_FOURCC_SARGB8888, __DRI_IMAGE_FORMAT_SARGB8,
PIPE_FORMAT_BGRA8888_SRGB, 1, },
{ DRM_FORMAT_XRGB8888, __DRI_IMAGE_FORMAT_XRGB8888,
PIPE_FORMAT_BGRX8888_UNORM, 1, },
{ DRM_FORMAT_BGRX8888, PIPE_FORMAT_X8R8G8B8_UNORM,
PIPE_FORMAT_X8R8G8B8_UNORM, 1, },
{ DRM_FORMAT_RGB888, __DRI_IMAGE_FORMAT_RGB888,
PIPE_FORMAT_B8G8R8_UNORM, 1, },
{ DRM_FORMAT_XBGR8888, __DRI_IMAGE_FORMAT_XBGR8888,
PIPE_FORMAT_RGBX8888_UNORM, 1, },
{ DRM_FORMAT_RGBX8888, PIPE_FORMAT_X8B8G8R8_UNORM,
PIPE_FORMAT_X8B8G8R8_UNORM, 1, },
{ DRM_FORMAT_BGR888, __DRI_IMAGE_FORMAT_BGR888,
PIPE_FORMAT_R8G8B8_UNORM, 1, },
{ DRM_FORMAT_ARGB1555, __DRI_IMAGE_FORMAT_ARGB1555,
PIPE_FORMAT_B5G5R5A1_UNORM, 1, },
{ DRM_FORMAT_ABGR1555, __DRI_IMAGE_FORMAT_ABGR1555,
PIPE_FORMAT_R5G5B5A1_UNORM, 1, },
{ DRM_FORMAT_ARGB4444, __DRI_IMAGE_FORMAT_ARGB4444,
PIPE_FORMAT_B4G4R4A4_UNORM, 1, },
{ DRM_FORMAT_ABGR4444, __DRI_IMAGE_FORMAT_ABGR4444,
PIPE_FORMAT_R4G4B4A4_UNORM, 1, },
{ DRM_FORMAT_RGB565, __DRI_IMAGE_FORMAT_RGB565,
PIPE_FORMAT_B5G6R5_UNORM, 1, },
{ DRM_FORMAT_R8, __DRI_IMAGE_FORMAT_R8,
PIPE_FORMAT_R8_UNORM, 1, },
{ DRM_FORMAT_R16, __DRI_IMAGE_FORMAT_R16,
PIPE_FORMAT_R16_UNORM, 1, },
{ DRM_FORMAT_GR88, __DRI_IMAGE_FORMAT_GR88,
PIPE_FORMAT_RG88_UNORM, 1, },
{ DRM_FORMAT_GR1616, __DRI_IMAGE_FORMAT_GR1616,
PIPE_FORMAT_RG1616_UNORM, 1, },
{ DRM_FORMAT_R16F, PIPE_FORMAT_R16_FLOAT,
PIPE_FORMAT_R16_FLOAT, 1 },
{ DRM_FORMAT_R32F, PIPE_FORMAT_R32_FLOAT,
PIPE_FORMAT_R32_FLOAT, 1 },
{ DRM_FORMAT_GR1616F, PIPE_FORMAT_R16G16_FLOAT,
PIPE_FORMAT_R16G16_FLOAT, 1 },
{ DRM_FORMAT_GR3232F, PIPE_FORMAT_R32G32_FLOAT,
PIPE_FORMAT_R32G32_FLOAT, 1 },
{ DRM_FORMAT_BGR161616, PIPE_FORMAT_R16G16B16_UNORM,
PIPE_FORMAT_R16G16B16_UNORM, 1 },
{ DRM_FORMAT_BGR161616F, PIPE_FORMAT_R16G16B16_FLOAT,
PIPE_FORMAT_R16G16B16_FLOAT, 1 },
{ DRM_FORMAT_BGR323232F, PIPE_FORMAT_R32G32B32_FLOAT,
PIPE_FORMAT_R32G32B32_FLOAT, 1 },
{ DRM_FORMAT_ABGR32323232F, PIPE_FORMAT_R32G32B32A32_FLOAT,
PIPE_FORMAT_R32G32B32A32_FLOAT, 1 },
/*
* YUV formats:
*/
{ DRM_FORMAT_YUV410, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_IYUV, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 2, 2, __DRI_IMAGE_FORMAT_R8 },
{ 2, 2, 2, __DRI_IMAGE_FORMAT_R8 } } },
{ DRM_FORMAT_YUV411, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_IYUV, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 2, 0, __DRI_IMAGE_FORMAT_R8 },
{ 2, 2, 0, __DRI_IMAGE_FORMAT_R8 } } },
{ DRM_FORMAT_YUV420, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_IYUV, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 1, 1, __DRI_IMAGE_FORMAT_R8 },
{ 2, 1, 1, __DRI_IMAGE_FORMAT_R8 } } },
{ DRM_FORMAT_YUV422, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_IYUV, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 1, 0, __DRI_IMAGE_FORMAT_R8 },
{ 2, 1, 0, __DRI_IMAGE_FORMAT_R8 } } },
{ DRM_FORMAT_YUV444, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_IYUV, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 2, 0, 0, __DRI_IMAGE_FORMAT_R8 } } },
{ DRM_FORMAT_YVU410, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_IYUV, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 2, 2, 2, __DRI_IMAGE_FORMAT_R8 },
{ 1, 2, 2, __DRI_IMAGE_FORMAT_R8 } } },
{ DRM_FORMAT_YVU411, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_IYUV, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 2, 2, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 2, 0, __DRI_IMAGE_FORMAT_R8 } } },
{ DRM_FORMAT_YVU420, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_IYUV, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 2, 1, 1, __DRI_IMAGE_FORMAT_R8 },
{ 1, 1, 1, __DRI_IMAGE_FORMAT_R8 } } },
{ DRM_FORMAT_YVU422, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_IYUV, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 2, 1, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 1, 0, __DRI_IMAGE_FORMAT_R8 } } },
{ DRM_FORMAT_YVU444, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_IYUV, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 2, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 0, 0, __DRI_IMAGE_FORMAT_R8 } } },
{ DRM_FORMAT_S010, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y10X6_U10X6_V10X6_420_UNORM, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 1, 1, __DRI_IMAGE_FORMAT_R16 },
{ 2, 1, 1, __DRI_IMAGE_FORMAT_R16 } } },
{ DRM_FORMAT_S210, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y10X6_U10X6_V10X6_422_UNORM, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 1, 0, __DRI_IMAGE_FORMAT_R16 },
{ 2, 1, 0, __DRI_IMAGE_FORMAT_R16 } } },
{ DRM_FORMAT_S410, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y10X6_U10X6_V10X6_444_UNORM, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 2, 0, 0, __DRI_IMAGE_FORMAT_R16 } } },
{ DRM_FORMAT_S012, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y12X4_U12X4_V12X4_420_UNORM, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 1, 1, __DRI_IMAGE_FORMAT_R16 },
{ 2, 1, 1, __DRI_IMAGE_FORMAT_R16 } } },
{ DRM_FORMAT_S212, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y12X4_U12X4_V12X4_422_UNORM, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 1, 0, __DRI_IMAGE_FORMAT_R16 },
{ 2, 1, 0, __DRI_IMAGE_FORMAT_R16 } } },
{ DRM_FORMAT_S412, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y12X4_U12X4_V12X4_444_UNORM, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 2, 0, 0, __DRI_IMAGE_FORMAT_R16 } } },
{ DRM_FORMAT_S016, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y16_U16_V16_420_UNORM, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 1, 1, __DRI_IMAGE_FORMAT_R16 },
{ 2, 1, 1, __DRI_IMAGE_FORMAT_R16 } } },
{ DRM_FORMAT_S216, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y16_U16_V16_422_UNORM, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 1, 0, __DRI_IMAGE_FORMAT_R16 },
{ 2, 1, 0, __DRI_IMAGE_FORMAT_R16 } } },
{ DRM_FORMAT_S416, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y16_U16_V16_444_UNORM, 3,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 2, 0, 0, __DRI_IMAGE_FORMAT_R16 } } },
{ DRM_FORMAT_NV12, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_NV12, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } } },
{ DRM_FORMAT_NV21, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_NV21, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } } },
/* 10 bit 4:2:0 and 4:2:2 formats; the components
are tightly packed, so the planes don't correspond
to any native DRI format */
{ DRM_FORMAT_NV15, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_NV15, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_NONE },
{ 1, 1, 1, __DRI_IMAGE_FORMAT_NONE } } },
{ DRM_FORMAT_NV20, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_NV20, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_NONE },
{ 1, 1, 0, __DRI_IMAGE_FORMAT_NONE } } },
{ DRM_FORMAT_P010, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_P010, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616 } } },
{ DRM_FORMAT_P012, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_P012, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616 } } },
{ DRM_FORMAT_P016, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_P016, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616 } } },
{ DRM_FORMAT_P030, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_P030, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R16 },
{ 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616 } } },
{ DRM_FORMAT_NV16, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_NV16, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 1, 0, __DRI_IMAGE_FORMAT_GR88 } } },
{ DRM_FORMAT_NV61, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_NV61, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 1, 0, __DRI_IMAGE_FORMAT_GR88 } } },
{ DRM_FORMAT_NV24, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_NV24, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 0, 0, __DRI_IMAGE_FORMAT_GR88 } } },
{ DRM_FORMAT_NV42, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_NV42, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 },
{ 1, 0, 0, __DRI_IMAGE_FORMAT_GR88 } } },
{ DRM_FORMAT_AYUV, __DRI_IMAGE_FORMAT_ABGR8888,
PIPE_FORMAT_AYUV, 1,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } },
{ DRM_FORMAT_XYUV8888, __DRI_IMAGE_FORMAT_XBGR8888,
PIPE_FORMAT_XYUV, 1,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR8888 } } },
{ DRM_FORMAT_Y410, __DRI_IMAGE_FORMAT_ABGR2101010,
PIPE_FORMAT_Y410, 1,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR2101010 } } },
/* Y412 is an unusual format. It has the same layout as Y416 (i.e.,
* 16-bits of physical storage per channel), but the low 4 bits of each
* component are unused padding. The writer is supposed to write zeros
* to these bits.
*/
{ DRM_FORMAT_Y412, __DRI_IMAGE_FORMAT_ABGR16161616,
PIPE_FORMAT_Y412, 1,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } },
{ DRM_FORMAT_Y416, __DRI_IMAGE_FORMAT_ABGR16161616,
PIPE_FORMAT_Y416, 1,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } },
/* For YUYV and UYVY buffers, we set up two overlapping DRI images
* and treat them as planar buffers in the compositors.
* Plane 0 is GR88 and samples YU or YV pairs and places Y into
* the R component, while plane 1 is ARGB/ABGR and samples YUYV/UYVY
* clusters and places pairs and places U into the G component and
* V into A. This lets the texture sampler interpolate the Y
* components correctly when sampling from plane 0, and interpolate
* U and V correctly when sampling from plane 1. */
{ DRM_FORMAT_YUYV, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_YUYV, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 },
{ 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } },
{ DRM_FORMAT_YVYU, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_YVYU, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 },
{ 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } },
{ DRM_FORMAT_UYVY, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_UYVY, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 },
{ 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } },
{ DRM_FORMAT_VYUY, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_VYUY, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 },
{ 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } },
/* The Y21x formats work in a similar fashion to the YUYV and UYVY
* formats.
*/
{ DRM_FORMAT_Y210, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y210, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616 },
{ 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } },
/* Y212 is an unusual format. It has the same layout as Y216 (i.e.,
* 16-bits of physical storage per channel), but the low 4 bits of each
* component are unused padding. The writer is supposed to write zeros
* to these bits.
*/
{ DRM_FORMAT_Y212, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y212, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616 },
{ 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } },
{ DRM_FORMAT_Y216, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y216, 2,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616 },
{ 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR16161616 } } },
/* YUV420_8BIT is a single plane with all components, but in an
unspecified order */
{ DRM_FORMAT_YUV420_8BIT, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y8U8V8_420_UNORM_PACKED, 1,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_NONE } } },
/* YUV420_10BIT is a single plane with all components, but in an
unspecified order */
{ DRM_FORMAT_YUV420_10BIT, __DRI_IMAGE_FORMAT_NONE,
PIPE_FORMAT_Y10U10V10_420_UNORM_PACKED, 1,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_NONE } } },
};
const struct dri2_format_mapping *
dri2_get_mapping_by_fourcc(int fourcc)
{
for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) {
if (dri2_format_table[i].dri_fourcc == fourcc)
return &dri2_format_table[i];
}
return NULL;
}
const struct dri2_format_mapping *
dri2_get_mapping_by_format(int format)
{
if (format == __DRI_IMAGE_FORMAT_NONE)
return NULL;
for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) {
if (dri2_format_table[i].dri_format == format)
return &dri2_format_table[i];
}
return NULL;
}
static enum pipe_format
alt_pipe_format(enum pipe_format yuv_fmt)
{
switch(yuv_fmt) {
case PIPE_FORMAT_NV12:
return PIPE_FORMAT_R8_G8B8_420_UNORM;
case PIPE_FORMAT_NV16:
return PIPE_FORMAT_R8_G8B8_422_UNORM;
case PIPE_FORMAT_NV21:
return PIPE_FORMAT_R8_B8G8_420_UNORM;
case PIPE_FORMAT_NV15:
return PIPE_FORMAT_R10_G10B10_420_UNORM;
case PIPE_FORMAT_NV20:
return PIPE_FORMAT_R10_G10B10_422_UNORM;
case PIPE_FORMAT_Y8U8V8_420_UNORM_PACKED:
return PIPE_FORMAT_R8G8B8_420_UNORM_PACKED;
case PIPE_FORMAT_Y10U10V10_420_UNORM_PACKED:
return PIPE_FORMAT_R10G10B10_420_UNORM_PACKED;
default:
return yuv_fmt;
}
}
bool
dri2_yuv_dma_buf_supported(struct dri_screen *screen,
const struct dri2_format_mapping *map)
{
struct pipe_screen *pscreen = screen->base.screen;
if (pscreen->is_format_supported(pscreen, alt_pipe_format(map->pipe_format),
screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW))
return true;
if (!util_format_is_yuv(map->pipe_format))
return false;
for (unsigned i = 0; i < map->nplanes; i++) {
/* Some planar-YUV formats can't be lowered unless the HW supports
* specific YUV-as-RGB formats. Those have their plane format set
* to __DRI_IMAGE_FORMAT_NONE. */
if (map->planes[i].dri_format == __DRI_IMAGE_FORMAT_NONE ||
!pscreen->is_format_supported(pscreen, map->planes[i].dri_format,
screen->target, 0, 0,
PIPE_BIND_SAMPLER_VIEW))
return false;
}
return true;
}
bool
dri_query_dma_buf_formats(struct dri_screen *screen, int max, int *formats,
int *count)
{
struct pipe_screen *pscreen = screen->base.screen;
int i, j;
for (i = 0, j = 0; (i < ARRAY_SIZE(dri2_format_table)) &&
(j < max || max == 0); i++) {
const struct dri2_format_mapping *map = &dri2_format_table[i];
/* The sRGB format is not a real FourCC as defined by drm_fourcc.h, so we
* must not leak it out to clients. */
if (dri2_format_table[i].dri_fourcc == __DRI_IMAGE_FOURCC_SARGB8888)
continue;
if (pscreen->is_format_supported(pscreen, map->pipe_format,
screen->target, 0, 0,
PIPE_BIND_RENDER_TARGET) ||
pscreen->is_format_supported(pscreen, map->pipe_format,
screen->target, 0, 0,
PIPE_BIND_SAMPLER_VIEW) ||
pscreen->is_format_supported(pscreen, map->pipe_format,
screen->target, 0, 0,
PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_SAMPLER_VIEW_SUBOPTIMAL) ||
dri2_yuv_dma_buf_supported(screen, map)) {
if (j < max)
formats[j] = map->dri_fourcc;
j++;
}
}
*count = j;
return true;
}
struct dri_image *
dri_create_image_with_modifiers(struct dri_screen *screen,
uint32_t width, uint32_t height,
uint32_t dri_format, uint32_t dri_usage,
const uint64_t *modifiers,
unsigned int modifiers_count,
void *loaderPrivate)
{
if (modifiers && modifiers_count > 0) {
bool has_valid_modifier = false;
int i;
/* It's acceptable to create an image with INVALID modifier in the list,
* but it cannot be on the only modifier (since it will certainly fail
* later). While we could easily catch this after modifier creation, doing
* the check here is a convenient debug check likely pointing at whatever
* interface the client is using to build its modifier list.
*/
for (i = 0; i < modifiers_count; i++) {
if (modifiers[i] != DRM_FORMAT_MOD_INVALID) {
has_valid_modifier = true;
break;
}
}
if (!has_valid_modifier)
return NULL;
}
return dri_create_image(screen, width, height, dri_format,
modifiers, modifiers_count, dri_usage,
loaderPrivate);
}
void
dri_image_fence_sync(struct dri_context *ctx, struct dri_image *img)
{
struct pipe_context *pipe = ctx->st->pipe;
struct pipe_fence_handle *fence;
int fd = img->in_fence_fd;
if (fd == -1)
return;
validate_fence_fd(fd);
img->in_fence_fd = -1;
pipe->create_fence_fd(pipe, &fence, fd, PIPE_FD_TYPE_NATIVE_SYNC);
pipe->fence_server_sync(pipe, fence, 0);
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
close(fd);
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */
+59
View File
@@ -0,0 +1,59 @@
/*
* Copyright (C) 1999-2007 Brian Paul 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, 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.
*/
#ifndef DRI_HELPERS_H
#define DRI_HELPERS_H
#include "dri_context.h"
#include "dri_screen.h"
struct dri2_format_mapping {
int dri_fourcc;
int dri_format; /* image format */
enum pipe_format pipe_format;
int nplanes;
struct {
int buffer_index;
int width_shift;
int height_shift;
uint32_t dri_format; /* plane format */
} planes[3];
};
const struct dri2_format_mapping *
dri2_get_mapping_by_fourcc(int fourcc);
const struct dri2_format_mapping *
dri2_get_mapping_by_format(int format);
bool
dri2_yuv_dma_buf_supported(struct dri_screen *screen,
const struct dri2_format_mapping *map);
bool
dri2_validate_egl_image(struct dri_screen *screen, void *handle);
void
dri_image_fence_sync(struct dri_context *ctx, struct dri_image *img);
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */
@@ -0,0 +1,133 @@
#include "dri_query_renderer.h"
#include "util/u_inlines.h"
#include "frontend/drm_driver.h"
#include "dri_screen.h"
#include "dri_query_renderer.h"
#include "pipe-loader/pipe_loader.h"
/**
* Implement queries for values that are common across all Mesa drivers
*
* Currently only the following queries are supported by this function:
*
* - \c __DRI2_RENDERER_VERSION
* - \c __DRI2_RENDERER_PREFERRED_PROFILE
* - \c __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION
* - \c __DRI2_RENDERER_OPENGL_COMPATIBLITY_PROFILE_VERSION
* - \c __DRI2_RENDERER_ES_PROFILE_VERSION
* - \c __DRI2_RENDERER_ES2_PROFILE_VERSION
*
* \returns
* Zero if a recognized value of \c param is supplied, -1 otherwise.
*/
static int
driQueryRendererIntegerCommon(struct dri_screen *screen, int param, unsigned int *value)
{
switch (param) {
case __DRI2_RENDERER_VERSION: {
static const char *const ver = PACKAGE_VERSION;
char *endptr;
int v[3];
v[0] = strtol(ver, &endptr, 10);
assert(endptr[0] == '.');
if (endptr[0] != '.')
return -1;
v[1] = strtol(endptr + 1, &endptr, 10);
assert(endptr[0] == '.');
if (endptr[0] != '.')
return -1;
v[2] = strtol(endptr + 1, &endptr, 10);
value[0] = v[0];
value[1] = v[1];
value[2] = v[2];
return 0;
}
case __DRI2_RENDERER_PREFERRED_PROFILE:
value[0] = (screen->max_gl_core_version != 0)
? (1U << __DRI_API_OPENGL_CORE) : (1U << __DRI_API_OPENGL);
return 0;
case __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION:
value[0] = screen->max_gl_core_version / 10;
value[1] = screen->max_gl_core_version % 10;
return 0;
case __DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION:
value[0] = screen->max_gl_compat_version / 10;
value[1] = screen->max_gl_compat_version % 10;
return 0;
case __DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION:
value[0] = screen->max_gl_es1_version / 10;
value[1] = screen->max_gl_es1_version % 10;
return 0;
case __DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION:
value[0] = screen->max_gl_es2_version / 10;
value[1] = screen->max_gl_es2_version % 10;
return 0;
default:
break;
}
return -1;
}
int
dri_query_renderer_integer(struct dri_screen *screen, int param,
unsigned int *value)
{
switch (param) {
case __DRI2_RENDERER_VENDOR_ID:
value[0] =
(unsigned int)screen->base.screen->caps.vendor_id;
return 0;
case __DRI2_RENDERER_DEVICE_ID:
value[0] =
(unsigned int)screen->base.screen->caps.device_id;
return 0;
case __DRI2_RENDERER_ACCELERATED:
value[0] =
(unsigned int)!!screen->base.screen->caps.accelerated;
return 0;
case __DRI2_RENDERER_VIDEO_MEMORY: {
int ov = driQueryOptioni(&screen->dev->option_cache, "override_vram_size");
value[0] =
(unsigned int)screen->base.screen->caps.video_memory;
if (ov >= 0)
value[0] = MIN2(ov, value[0]);
return 0;
}
case __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE:
value[0] =
(unsigned int)screen->base.screen->caps.uma;
return 0;
case __DRI2_RENDERER_PREFER_BACK_BUFFER_REUSE:
value[0] =
screen->base.screen->caps.prefer_back_buffer_reuse;
return 0;
default:
return driQueryRendererIntegerCommon(screen, param, value);
}
}
int
dri_query_renderer_string(struct dri_screen *screen, int param,
const char **value)
{
switch (param) {
case __DRI2_RENDERER_VENDOR_ID:
value[0] = screen->base.screen->get_vendor(screen->base.screen);
return 0;
case __DRI2_RENDERER_DEVICE_ID:
value[0] = screen->base.screen->get_name(screen->base.screen);
return 0;
default:
return -1;
}
}
@@ -0,0 +1,6 @@
#ifndef DRI_QUERY_RENDERER_H
#define DRI_QUERY_RENDERER_H
#include "dri_util.h"
#endif
+661
View File
@@ -0,0 +1,661 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Author: Keith Whitwell <[email protected]>
* Author: Jakob Bornecrantz <[email protected]>
*/
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_helpers.h"
#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "util/format/u_formats.h"
#include "pipe-loader/pipe_loader.h"
#include "frontend/drm_driver.h"
#include "util/u_debug.h"
#include "util/u_driconf.h"
#include "util/format/u_format_s3tc.h"
#include "state_tracker/st_context.h"
#include "driver_trace/tr_screen.h"
#ifdef HAVE_LIBDRM
#include <xf86drm.h>
#endif
#define MSAA_VISUAL_MAX_SAMPLES 32
#undef false
const __DRIconfigOptionsExtension gallium_config_options = {
.base = { __DRI_CONFIG_OPTIONS, 2 },
.getXml = pipe_loader_get_driinfo_xml
};
#define false 0
void
dri_init_options(struct dri_screen *screen)
{
pipe_loader_config_options(screen->dev);
struct st_config_options *options = &screen->options;
const struct driOptionCache *optionCache = &screen->dev->option_cache;
u_driconf_fill_st_options(options, optionCache);
}
static unsigned
dri_loader_get_cap(struct dri_screen *screen, enum dri_loader_cap cap)
{
const __DRIimageLoaderExtension *image_loader = screen->image.loader;
if (image_loader && image_loader->base.version >= 2 &&
image_loader->getCapability)
return image_loader->getCapability(screen->loaderPrivate, cap);
return 0;
}
/**
* Creates a set of \c struct gl_config that a driver will expose.
*
* A set of \c struct gl_config will be created based on the supplied
* parameters. The number of modes processed will be 2 *
* \c num_depth_stencil_bits * \c num_db_modes.
*
* For the most part, data is just copied from \c depth_bits, \c stencil_bits,
* \c db_modes, and \c visType into each \c struct gl_config element.
* However, the meanings of \c fb_format and \c fb_type require further
* explanation. The \c fb_format specifies which color components are in
* each pixel and what the default order is. For example, \c GL_RGB specifies
* that red, green, blue are available and red is in the "most significant"
* position and blue is in the "least significant". The \c fb_type specifies
* the bit sizes of each component and the actual ordering. For example, if
* \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
* are the blue value, bits [10:5] are the green value, and bits [4:0] are
* the red value.
*
* One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
* of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
* \c struct gl_config structure is \b identical to the \c GL_RGBA or
* \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
* far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
* still uses 32-bits.
*
* If in doubt, look at the tables used in the function.
*
* \param ptr_to_modes Pointer to a pointer to a linked list of
* \c struct gl_config. Upon completion, a pointer to
* the next element to be process will be stored here.
* If the function fails and returns \c GL_FALSE, this
* value will be unmodified, but some elements in the
* linked list may be modified.
* \param format Mesa mesa_format enum describing the pixel format
* \param zs_formats Array of depth/stencil formats to expose
* \param num_zs_formats Number of entries in \c depth_stencil_formats.
* \param db_modes Array of buffer swap modes.
* \param num_db_modes Number of entries in \c db_modes.
* \param msaa_samples Array of msaa sample count. 0 represents a visual
* without a multisample buffer.
* \param num_msaa_modes Number of entries in \c msaa_samples.
* \param enable_accum Add an accum buffer to the configs
* \param color_depth_match Whether the color depth must match the zs depth
* This forces 32-bit color to have 24-bit depth, and
* 16-bit color to have 16-bit depth.
*
* \returns
* Pointer to any array of pointers to the \c struct dri_config structures created
* for the specified formats. If there is an error, \c NULL is returned.
* Currently the only cause of failure is a bad parameter (i.e., unsupported
* \c format).
*/
static struct dri_config **
driCreateConfigs(enum pipe_format format,
enum pipe_format *zs_formats, unsigned num_zs_formats,
const bool *db_modes, unsigned num_db_modes,
const uint8_t * msaa_samples, unsigned num_msaa_modes,
GLboolean enable_accum, GLboolean color_depth_match)
{
uint32_t masks[4];
int shifts[4];
int color_bits[4];
struct dri_config **configs, **c;
struct gl_config *modes;
unsigned i, j, k, h;
unsigned num_modes;
unsigned num_accum_bits = (enable_accum) ? 2 : 1;
bool is_srgb;
bool is_float;
bool is_unorm16;
is_srgb = util_format_is_srgb(format);
is_float = util_format_is_float(format);
is_unorm16 = util_format_is_unorm16(util_format_description(format));
for (i = 0; i < 4; i++) {
color_bits[i] =
util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, i);
if (color_bits[i] > 0) {
shifts[i] =
util_format_get_component_shift(format, UTIL_FORMAT_COLORSPACE_RGB, i);
} else {
shifts[i] = -1;
}
/* is_float and is_unorm16 is only true on non-x11 target platforms, which
* don't actually use redMask, greenMask, ..., so avoid setting masks[]
* to prevent a meaningless "undefined behaviour" build warning.
*/
if (is_float || is_unorm16 || color_bits[i] == 0)
masks[i] = 0;
else
masks[i] = ((1u << color_bits[i]) - 1) << shifts[i];
}
num_modes = num_zs_formats * num_db_modes * num_accum_bits * num_msaa_modes;
configs = calloc(num_modes + 1, sizeof *configs);
if (configs == NULL)
return NULL;
c = configs;
for ( k = 0 ; k < num_zs_formats ; k++ ) {
unsigned depth_bits, stencil_bits;
if (zs_formats[k] != PIPE_FORMAT_NONE) {
depth_bits =
util_format_get_component_bits(zs_formats[k],
UTIL_FORMAT_COLORSPACE_ZS, 0);
stencil_bits =
util_format_get_component_bits(zs_formats[k],
UTIL_FORMAT_COLORSPACE_ZS, 1);
} else {
depth_bits = 0;
stencil_bits = 0;
}
for ( i = 0 ; i < num_db_modes ; i++ ) {
for ( h = 0 ; h < num_msaa_modes; h++ ) {
for ( j = 0 ; j < num_accum_bits ; j++ ) {
if (color_depth_match &&
(depth_bits || stencil_bits)) {
/* Depth can really only be 0, 16, 24, or 32. A 32-bit
* color format still matches 24-bit depth, as there
* is an implicit 8-bit stencil. So really we just
* need to make sure that color/depth are both 16 or
* both non-16.
*/
if ((depth_bits + stencil_bits == 16) !=
(color_bits[0] + color_bits[1] +
color_bits[2] + color_bits[3] == 16))
continue;
}
*c = malloc (sizeof **c);
modes = &(*c)->modes;
c++;
memset(modes, 0, sizeof *modes);
modes->color_format = format;
modes->zs_format = zs_formats[k];
if (j > 0)
modes->accum_format = PIPE_FORMAT_R16G16B16A16_SNORM;
else
modes->accum_format = PIPE_FORMAT_NONE;
modes->floatMode = is_float;
modes->redBits = color_bits[0];
modes->redShift = shifts[0];
modes->redMask = masks[0];
modes->greenBits = color_bits[1];
modes->greenShift = shifts[1];
modes->greenMask = masks[1];
modes->blueBits = color_bits[2];
modes->blueShift = shifts[2];
modes->blueMask = masks[2];
modes->alphaBits = color_bits[3];
modes->alphaMask = masks[3];
modes->alphaShift = shifts[3];
modes->rgbBits = modes->redBits + modes->greenBits
+ modes->blueBits + modes->alphaBits;
modes->accumRedBits = 16 * j;
modes->accumGreenBits = 16 * j;
modes->accumBlueBits = 16 * j;
modes->accumAlphaBits = 16 * j;
modes->stencilBits = stencil_bits;
modes->depthBits = depth_bits;
modes->doubleBufferMode = db_modes[i];
modes->samples = msaa_samples[h];
modes->sRGBCapable = is_srgb;
}
}
}
}
*c = NULL;
return configs;
}
static struct dri_config **
driConcatConfigs(struct dri_config **a, struct dri_config **b)
{
struct dri_config **all;
int i, j, index;
if (a == NULL || a[0] == NULL)
return b;
else if (b == NULL || b[0] == NULL)
return a;
i = 0;
while (a[i] != NULL)
i++;
j = 0;
while (b[j] != NULL)
j++;
all = malloc((i + j + 1) * sizeof *all);
index = 0;
for (i = 0; a[i] != NULL; i++)
all[index++] = a[i];
for (j = 0; b[j] != NULL; j++)
all[index++] = b[j];
all[index++] = NULL;
free(a);
free(b);
return all;
}
static const struct dri_config **
dri_fill_in_modes(struct dri_screen *screen)
{
/* The 32-bit RGBA format must not precede the 32-bit BGRA format.
* Likewise for RGBX and BGRX. Otherwise, the GLX client and the GLX
* server may disagree on which format the GLXFBConfig represents,
* resulting in swapped color channels.
*
* The problem, as of 2017-05-30:
* When matching a GLXFBConfig to a struct dri_config, GLX ignores the channel
* order and chooses the first struct dri_config with the expected channel
* sizes. Specifically, GLX compares the GLXFBConfig's and struct dri_config's
* __DRI_ATTRIB_{CHANNEL}_SIZE but ignores __DRI_ATTRIB_{CHANNEL}_MASK.
*
* EGL does not suffer from this problem. It correctly compares the
* channel masks when matching EGLConfig to struct dri_config.
*/
static const enum pipe_format pipe_formats[] = {
PIPE_FORMAT_B10G10R10A2_UNORM,
PIPE_FORMAT_B10G10R10X2_UNORM,
PIPE_FORMAT_R10G10B10A2_UNORM,
PIPE_FORMAT_R10G10B10X2_UNORM,
PIPE_FORMAT_BGRA8888_UNORM,
PIPE_FORMAT_BGRX8888_UNORM,
PIPE_FORMAT_BGRA8888_SRGB,
PIPE_FORMAT_BGRX8888_SRGB,
PIPE_FORMAT_B5G6R5_UNORM,
PIPE_FORMAT_R16G16B16A16_FLOAT,
PIPE_FORMAT_R16G16B16X16_FLOAT,
PIPE_FORMAT_R16G16B16A16_UNORM,
PIPE_FORMAT_R16G16B16X16_UNORM,
PIPE_FORMAT_RGBA8888_UNORM,
PIPE_FORMAT_RGBX8888_UNORM,
PIPE_FORMAT_RGBA8888_SRGB,
PIPE_FORMAT_RGBX8888_SRGB,
PIPE_FORMAT_B5G5R5A1_UNORM,
PIPE_FORMAT_R5G5B5A1_UNORM,
PIPE_FORMAT_B4G4R4A4_UNORM,
PIPE_FORMAT_R4G4B4A4_UNORM,
};
struct dri_config **configs = NULL;
enum pipe_format zs_formats[5];
unsigned num_zs_formats = 0;
unsigned i;
struct pipe_screen *p_screen = screen->base.screen;
bool mixed_color_depth;
bool allow_rgba_ordering;
bool allow_rgb10;
bool allow_rgb16;
bool allow_fp16;
static const bool db_modes[] = { false, true };
if (!driQueryOptionb(&screen->dev->option_cache, "always_have_depth_buffer"))
zs_formats[num_zs_formats++] = PIPE_FORMAT_NONE;
allow_rgba_ordering = dri_loader_get_cap(screen, DRI_LOADER_CAP_RGBA_ORDERING);
allow_rgb10 = driQueryOptionb(&screen->dev->option_cache, "allow_rgb10_configs");
allow_rgb16 = driQueryOptionb(&screen->dev->option_cache, "allow_rgb16_configs");
allow_fp16 = dri_loader_get_cap(screen, DRI_LOADER_CAP_FP16);
#define HAS_ZS(fmt) \
p_screen->is_format_supported(p_screen, PIPE_FORMAT_##fmt, \
PIPE_TEXTURE_2D, 0, 0, \
PIPE_BIND_DEPTH_STENCIL)
if (HAS_ZS(Z16_UNORM))
zs_formats[num_zs_formats++] = PIPE_FORMAT_Z16_UNORM;
if (HAS_ZS(Z24X8_UNORM))
zs_formats[num_zs_formats++] = PIPE_FORMAT_Z24X8_UNORM;
else if (HAS_ZS(X8Z24_UNORM))
zs_formats[num_zs_formats++] = PIPE_FORMAT_X8Z24_UNORM;
if (HAS_ZS(Z24_UNORM_S8_UINT))
zs_formats[num_zs_formats++] = PIPE_FORMAT_Z24_UNORM_S8_UINT;
else if (HAS_ZS(S8_UINT_Z24_UNORM))
zs_formats[num_zs_formats++] = PIPE_FORMAT_S8_UINT_Z24_UNORM;
if (HAS_ZS(Z32_UNORM))
zs_formats[num_zs_formats++] = PIPE_FORMAT_Z32_UNORM;
#undef HAS_ZS
mixed_color_depth =
p_screen->caps.mixed_color_depth_bits;
/* Add configs. */
for (unsigned f = 0; f < ARRAY_SIZE(pipe_formats); f++) {
struct dri_config **new_configs = NULL;
unsigned num_msaa_modes = 0; /* includes a single-sample mode */
uint8_t msaa_modes[MSAA_VISUAL_MAX_SAMPLES];
/* Expose only BGRA ordering if the loader doesn't support RGBA ordering. */
if (!allow_rgba_ordering &&
(pipe_formats[f] == PIPE_FORMAT_RGBA8888_UNORM ||
pipe_formats[f] == PIPE_FORMAT_RGBX8888_UNORM ||
pipe_formats[f] == PIPE_FORMAT_RGBA8888_SRGB ||
pipe_formats[f] == PIPE_FORMAT_RGBX8888_SRGB ||
pipe_formats[f] == PIPE_FORMAT_R5G5B5A1_UNORM ||
pipe_formats[f] == PIPE_FORMAT_R5G5B5X1_UNORM ||
pipe_formats[f] == PIPE_FORMAT_R4G4B4A4_UNORM ||
pipe_formats[f] == PIPE_FORMAT_R4G4B4X4_UNORM))
continue;
if (!allow_rgb10 &&
util_format_get_component_bits(pipe_formats[f],
UTIL_FORMAT_COLORSPACE_RGB, 0) == 10 &&
util_format_get_component_bits(pipe_formats[f],
UTIL_FORMAT_COLORSPACE_RGB, 1) == 10 &&
util_format_get_component_bits(pipe_formats[f],
UTIL_FORMAT_COLORSPACE_RGB, 2) == 10)
continue;
/* Block RGB[A]16_UNORM formats, if forbidden by config */
if (!allow_rgb16 && !util_format_is_float(pipe_formats[f]) &&
util_format_get_component_bits(pipe_formats[f],
UTIL_FORMAT_COLORSPACE_RGB, 0) == 16 &&
util_format_get_component_bits(pipe_formats[f],
UTIL_FORMAT_COLORSPACE_RGB, 1) == 16 &&
util_format_get_component_bits(pipe_formats[f],
UTIL_FORMAT_COLORSPACE_RGB, 2) == 16)
continue;
if (!allow_fp16 && util_format_is_float(pipe_formats[f]))
continue;
if (!p_screen->is_format_supported(p_screen, pipe_formats[f],
PIPE_TEXTURE_2D, 0, 0,
PIPE_BIND_RENDER_TARGET |
PIPE_BIND_DISPLAY_TARGET))
continue;
for (i = 1; i <= MSAA_VISUAL_MAX_SAMPLES; i++) {
int samples = i > 1 ? i : 0;
if (p_screen->is_format_supported(p_screen, pipe_formats[f],
PIPE_TEXTURE_2D, samples, samples,
PIPE_BIND_RENDER_TARGET)) {
msaa_modes[num_msaa_modes++] = samples;
}
}
if (num_msaa_modes) {
/* Single-sample configs with an accumulation buffer. */
new_configs = driCreateConfigs(pipe_formats[f],
zs_formats, num_zs_formats,
db_modes, ARRAY_SIZE(db_modes),
msaa_modes, 1,
GL_TRUE, !mixed_color_depth);
configs = driConcatConfigs(configs, new_configs);
/* Multi-sample configs without an accumulation buffer. */
if (num_msaa_modes > 1) {
new_configs = driCreateConfigs(pipe_formats[f],
zs_formats, num_zs_formats,
db_modes, ARRAY_SIZE(db_modes),
msaa_modes+1, num_msaa_modes-1,
GL_FALSE, !mixed_color_depth);
configs = driConcatConfigs(configs, new_configs);
}
}
}
if (configs == NULL) {
debug_printf("%s: driCreateConfigs failed\n", __func__);
return NULL;
}
return (const struct dri_config **)configs;
}
/**
* Roughly the converse of dri_fill_in_modes.
*/
void
dri_fill_st_visual(struct st_visual *stvis,
const struct dri_screen *screen,
const struct gl_config *mode)
{
memset(stvis, 0, sizeof(*stvis));
if (!mode)
return;
assert(mode->color_format != PIPE_FORMAT_NONE);
stvis->color_format = mode->color_format;
stvis->accum_format = mode->accum_format;
stvis->depth_stencil_format = mode->zs_format;
if (mode->samples > 0) {
if (debug_get_bool_option("DRI_NO_MSAA", false))
stvis->samples = 0;
else
stvis->samples = mode->samples;
}
stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
if (mode->doubleBufferMode) {
stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
}
if (mode->stereoMode) {
stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
if (mode->doubleBufferMode)
stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
}
if (mode->depthBits > 0 || mode->stencilBits > 0)
stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
/* let the gallium frontend allocate the accum buffer */
}
static bool
dri_get_egl_image(struct pipe_frontend_screen *fscreen,
void *egl_image,
struct st_egl_image *stimg)
{
struct dri_screen *screen = (struct dri_screen *)fscreen;
const __DRIimageLookupExtension *loader = screen->dri2.image;
struct dri_image *img = NULL;
const struct dri2_format_mapping *map;
img = loader->lookupEGLImageValidated(egl_image, screen->loaderPrivate);
if (!img)
return false;
stimg->texture = NULL;
pipe_resource_reference(&stimg->texture, img->texture);
map = dri2_get_mapping_by_fourcc(img->dri_fourcc);
stimg->format = map ? map->pipe_format : img->texture->format;
stimg->level = img->level;
stimg->layer = img->layer;
stimg->imported_dmabuf = img->imported_dmabuf;
if (img->imported_dmabuf && map) {
/* Guess sized internal format for dma-bufs. Could be used
* by EXT_EGL_image_storage.
*/
stimg->internalformat = driImageFormatToSizedInternalGLFormat(map->dri_format);
} else {
stimg->internalformat = img->internal_format;
}
stimg->yuv_color_space = img->yuv_color_space;
stimg->yuv_range = img->sample_range;
return true;
}
static bool
dri_validate_egl_image(struct pipe_frontend_screen *fscreen,
void *egl_image)
{
struct dri_screen *screen = (struct dri_screen *)fscreen;
const __DRIimageLookupExtension *loader = screen->dri2.image;
if (loader)
return loader->validateEGLImage(egl_image, screen->loaderPrivate);
else
return true;
}
static int
dri_get_param(struct pipe_frontend_screen *fscreen,
enum st_manager_param param)
{
return 0;
}
void
dri_release_screen(struct dri_screen * screen)
{
st_screen_destroy(&screen->base);
if (screen->base.screen) {
screen->base.screen->destroy(screen->base.screen);
screen->base.screen = NULL;
}
if (screen->dev) {
pipe_loader_release(&screen->dev, 1);
screen->dev = NULL;
}
mtx_destroy(&screen->opencl_func_mutex);
}
void
dri_destroy_screen(struct dri_screen *screen)
{
dri_release_screen(screen);
free(screen->options.force_explicit_uniform_loc_zero);
free(screen->options.force_gl_vendor);
free(screen->options.force_gl_renderer);
free(screen->options.mesa_extension_override);
driDestroyOptionCache(&screen->optionCache);
driDestroyOptionInfo(&screen->optionInfo);
/* The caller in dri_util preserves the fd ownership */
free(screen);
}
static void
dri_set_background_context(struct st_context *st,
struct util_queue_monitoring *queue_info)
{
struct dri_context *ctx = (struct dri_context *)st->frontend_context;
if (ctx->hud)
hud_add_queue_for_monitoring(ctx->hud, queue_info);
}
const struct dri_config **
dri_init_screen(struct dri_screen *screen,
struct pipe_screen *pscreen,
bool has_multibuffer)
{
screen->base.screen = pscreen;
screen->base.get_egl_image = dri_get_egl_image;
screen->base.get_param = dri_get_param;
screen->base.set_background_context = dri_set_background_context;
screen->base.validate_egl_image = dri_validate_egl_image;
if (pscreen->caps.npot_textures)
screen->target = PIPE_TEXTURE_2D;
else
screen->target = PIPE_TEXTURE_RECT;
dri_init_options(screen);
st_api_query_versions(&screen->base,
&screen->options,
&screen->max_gl_core_version,
&screen->max_gl_compat_version,
&screen->max_gl_es1_version,
&screen->max_gl_es2_version);
screen->throttle = pscreen->caps.throttle;
if (pscreen->caps.device_protected_context)
screen->has_protected_context = true;
screen->has_reset_status_query = pscreen->caps.device_reset_status_query;
screen->has_multibuffer = has_multibuffer;
#ifdef HAVE_LIBDRM
unsigned dmabuf_caps = pscreen->caps.dmabuf;
if (dmabuf_caps & DRM_PRIME_CAP_IMPORT)
screen->dmabuf_import = true;
if (screen->dmabuf_import && dmabuf_caps & DRM_PRIME_CAP_EXPORT)
screen->has_dmabuf = true;
#endif
return dri_fill_in_modes(screen);
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */
+196
View File
@@ -0,0 +1,196 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*
* Author: Keith Whitwell <[email protected]>
* Author: Jakob Bornecrantz <[email protected]>
*/
#ifndef DRI_SCREEN_H
#define DRI_SCREEN_H
#include "dri_util.h"
#include "util/compiler.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "frontend/api.h"
#include "frontend/opencl_interop.h"
#include "util/u_thread.h"
#include "kopper_interface.h"
struct dri_context;
struct dri_drawable;
struct pipe_loader_device;
struct dri_screen
{
/* st_api */
struct pipe_frontend_screen base;
/* dri */
/* Current screen's number */
int myNum;
void *loaderPrivate;
int max_gl_core_version;
int max_gl_compat_version;
int max_gl_es1_version;
int max_gl_es2_version;
enum dri_screen_type type;
const __DRIswrastLoaderExtension *swrast_loader;
const __DRIkopperLoaderExtension *kopper_loader;
struct {
const __DRIimageLookupExtension *image;
} dri2;
struct {
const __DRIimageLoaderExtension *loader;
} image;
struct {
const __DRImutableRenderBufferLoaderExtension *loader;
} mutableRenderBuffer;
driOptionCache optionInfo;
driOptionCache optionCache;
unsigned int api_mask;
bool throttle;
bool dmabuf_import;
bool has_multibuffer;
struct st_config_options options;
/* drm */
int fd;
bool can_share_buffer;
struct pipe_loader_device *dev;
/* gallium */
bool has_reset_status_query;
bool has_protected_context;
enum pipe_texture_target target;
bool swrast_no_present;
/* DRI exts on this screen. Populated at init time based on device caps. */
const __DRIextension *screen_extensions[14];
/* OpenCL interop */
mtx_t opencl_func_mutex;
opencl_dri_event_add_ref_t opencl_dri_event_add_ref;
opencl_dri_event_release_t opencl_dri_event_release;
opencl_dri_event_wait_t opencl_dri_event_wait;
opencl_dri_event_get_fence_t opencl_dri_event_get_fence;
/* kopper */
bool has_dmabuf;
bool is_sw;
};
static inline const __DRIkopperLoaderExtension *
dri_screen_get_kopper(struct dri_screen *screen)
{
return screen->kopper_loader;
}
struct dri_image {
struct pipe_resource *texture;
unsigned level;
unsigned layer;
uint32_t dri_format;
uint32_t dri_fourcc;
/* Provided by eglCreateImageKHR if creating from a
* texture or a renderbuffer. 0 otherwise.
*/
uint32_t internal_format;
unsigned use;
unsigned plane;
int in_fence_fd;
void *loader_private;
bool imported_dmabuf;
/**
* Provided by EGL_EXT_image_dma_buf_import.
*/
enum __DRIYUVColorSpace yuv_color_space;
enum __DRISampleRange sample_range;
enum __DRIChromaSiting horizontal_siting;
enum __DRIChromaSiting vertical_siting;
struct dri_screen *screen;
};
void
dri_fill_st_visual(struct st_visual *stvis,
const struct dri_screen *screen,
const struct gl_config *mode);
void
dri_init_options(struct dri_screen *screen);
const struct dri_config **
dri_init_screen(struct dri_screen *screen,
struct pipe_screen *pscreen,
bool has_multibuffer);
void
dri_release_screen(struct dri_screen * screen);
void
dri_destroy_screen(struct dri_screen *screen);
struct pipe_screen *
dri2_init_screen(struct dri_screen *screen, bool driver_name_is_inferred);
struct pipe_screen *
dri_swrast_kms_init_screen(struct dri_screen *screen, bool driver_name_is_inferred);
struct pipe_screen *
kopper_init_screen(struct dri_screen *screen, bool driver_name_is_inferred);
struct pipe_screen *
drisw_init_screen(struct dri_screen *screen, bool driver_name_is_inferred);
extern const struct __DriverAPIRec dri_swrast_kms_driver_api;
extern const __DRIextension *dri_swrast_kms_driver_extensions[];
extern const struct __DriverAPIRec galliumdrm_driver_api;
extern const __DRIextension *galliumdrm_driver_extensions[];
extern const struct __DriverAPIRec galliumsw_driver_api;
extern const __DRIextension *galliumsw_driver_extensions[];
extern const struct __DriverAPIRec galliumvk_driver_api;
extern const __DRIextension *galliumvk_driver_extensions[];
extern const __DRIconfigOptionsExtension gallium_config_options;
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */
File diff suppressed because it is too large. Load diff
+349
View File
@@ -0,0 +1,349 @@
/*
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
* 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 PRECISION INSIGHT 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 dri_util.h
* DRI utility functions definitions.
*
* \author Kevin E. Martin <[email protected]>
* \author Brian Paul <[email protected]>
*/
#ifndef _DRI_UTIL_H_
#define _DRI_UTIL_H_
#include <GL/gl.h>
#include "mesa_interface.h"
#include "kopper_interface.h"
#include "main/formats.h"
#include "main/glconfig.h"
#include "main/menums.h"
#include "util/xmlconfig.h"
#include "pipe/p_defines.h"
#include <stdbool.h>
struct pipe_screen;
struct dri_screen;
struct mesa_glinterop_device_info;
struct mesa_glinterop_export_in;
struct mesa_glinterop_export_out;
struct mesa_glinterop_flush_out;
#define __DRI_BACKEND_VTABLE "DRI_DriverVtable"
struct dri_config {
struct gl_config modes;
};
enum dri_screen_type {
DRI_SCREEN_DRI3,
DRI_SCREEN_KOPPER,
DRI_SCREEN_SWRAST,
DRI_SCREEN_KMS_SWRAST,
};
/**
* Description of the attributes used to create a config.
*
* This is passed as the context_config parameter to CreateContext. The idea
* with this struct is that it can be extended without having to modify all of
* the drivers. The first three members (major/minor_version and flags) are
* always valid, but the remaining members are only valid if the corresponding
* flag is set for the attribute. If the flag is not set then the default
* value should be assumed. That way the driver can quickly check if any
* attributes were set that it doesn't understand and report an error.
*/
struct __DriverContextConfig {
/* These members are always valid */
unsigned major_version;
unsigned minor_version;
uint32_t flags;
/* Flags describing which of the remaining members are valid */
uint32_t attribute_mask;
/* Only valid if __DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY is set */
int reset_strategy;
/* Only valid if __DRIVER_CONTEXT_PRIORITY is set */
unsigned priority;
/* Only valid if __DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR is set */
int release_behavior;
/* Only valid if __DRIVER_CONTEXT_ATTRIB_NO_ERROR is set */
int no_error;
/* Only valid if __DRIVER_CONTEXT_ATTRIB_PROTECTED is set */
int protected_context;
};
#define __DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY (1 << 0)
#define __DRIVER_CONTEXT_ATTRIB_PRIORITY (1 << 1)
#define __DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR (1 << 2)
#define __DRIVER_CONTEXT_ATTRIB_NO_ERROR (1 << 3)
#define __DRIVER_CONTEXT_ATTRIB_PROTECTED (1 << 4)
PUBLIC struct dri_screen *
driCreateNewScreen3(int scrn, int fd,
const __DRIextension **loader_extensions,
enum dri_screen_type type,
const struct dri_config ***driver_configs, bool driver_name_is_inferred,
bool has_multibuffer, void *data);
PUBLIC struct dri_context *
driCreateContextAttribs(struct dri_screen *psp, int api,
const struct dri_config *config,
struct dri_context *shared,
unsigned num_attribs,
const uint32_t *attribs,
unsigned *error,
void *data,
bool thread_safe);
extern uint32_t
driImageFormatToSizedInternalGLFormat(uint32_t image_format);
PUBLIC unsigned int
driGetAPIMask(struct dri_screen *screen);
PUBLIC struct dri_drawable *
dri_create_drawable(struct dri_screen *psp, const struct dri_config *config,
bool isPixmap, void *loaderPrivate);
PUBLIC void driDestroyScreen(struct dri_screen *psp);
PUBLIC int
driGetConfigAttrib(const struct dri_config *config, unsigned int attrib, unsigned int *value);
PUBLIC int
driIndexConfigAttrib(const struct dri_config *config, int index, unsigned int *attrib, unsigned int *value);
PUBLIC void
driDestroyDrawable(struct dri_drawable *drawable);
PUBLIC void
driSwapBuffers(struct dri_drawable *drawable);
PUBLIC void
driSwapBuffersWithDamage(struct dri_drawable *drawable, int nrects, const int *rects);
PUBLIC struct dri_context *
driCreateNewContext(struct dri_screen *screen, const struct dri_config *config,
struct dri_context *shared, void *data, bool thread_safe);
PUBLIC int
driCopyContext(struct dri_context *dest, struct dri_context *src, unsigned long mask);
PUBLIC void
driDestroyContext(struct dri_context *ctx);
PUBLIC int driBindContext(struct dri_context *ctx, struct dri_drawable *draw, struct dri_drawable *read);
PUBLIC int driUnbindContext(struct dri_context *ctx);
PUBLIC int64_t
kopperSwapBuffers(struct dri_drawable *dPriv, uint32_t flush_flags);
PUBLIC int64_t
kopperSwapBuffersWithDamage(struct dri_drawable *drawable, uint32_t flush_flags, int nrects, const int *rects);
PUBLIC struct dri_drawable *
kopperCreateNewDrawable(struct dri_screen *psp,
const struct dri_config *config,
void *data,
__DRIkopperDrawableInfo *info);
PUBLIC void
kopperSetSwapInterval(struct dri_drawable *drawable, int interval);
PUBLIC int
kopperQueryBufferAge(struct dri_drawable *drawable);
PUBLIC void
kopperQuerySurfaceSize(struct dri_drawable *drawable, int *width, int *height);
PUBLIC void
driswCopySubBuffer(struct dri_drawable *drawable, int x, int y, int w, int h);
PUBLIC int
kopperGetSyncValues(struct dri_drawable *drawable, int64_t target_msc, int64_t divisor,
int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
PUBLIC void
dri_set_tex_buffer2(struct dri_context *ctx, GLint target,
GLint format, struct dri_drawable *drawable);
PUBLIC int
dri_query_renderer_string(struct dri_screen *_screen, int param,
const char **value);
PUBLIC int
dri_query_renderer_integer(struct dri_screen *_screen, int param,
unsigned int *value);
PUBLIC void
dri_flush_drawable(struct dri_drawable *dPriv);
PUBLIC void
dri_flush(struct dri_context *cPriv,
struct dri_drawable *dPriv,
unsigned flags,
enum __DRI2throttleReason reason);
PUBLIC void
dri_invalidate_drawable(struct dri_drawable *drawable);
PUBLIC int
dri2GalliumConfigQueryb(struct dri_screen *sPriv, const char *var,
unsigned char *val);
PUBLIC int
dri2GalliumConfigQueryi(struct dri_screen *sPriv, const char *var, int *val);
PUBLIC int
dri2GalliumConfigQueryf(struct dri_screen *sPriv, const char *var, float *val);
PUBLIC int
dri2GalliumConfigQuerys(struct dri_screen *sPriv, const char *var, char **val);
PUBLIC int dri_get_initial_swap_interval(struct dri_screen *driScreen);
PUBLIC bool dri_valid_swap_interval(struct dri_screen *driScreen, int interval);
PUBLIC void
dri_throttle(struct dri_context *cPriv, struct dri_drawable *dPriv,
enum __DRI2throttleReason reason);
PUBLIC int
dri_interop_query_device_info(struct dri_context *ctx,
struct mesa_glinterop_device_info *out);
PUBLIC int
dri_interop_export_object(struct dri_context *ctx,
struct mesa_glinterop_export_in *in,
struct mesa_glinterop_export_out *out);
PUBLIC int
dri_interop_flush_objects(struct dri_context *_ctx,
unsigned count, struct mesa_glinterop_export_in *objects,
struct mesa_glinterop_flush_out *out);
PUBLIC struct dri_image *
dri_create_image_from_renderbuffer(struct dri_context *dri_ctx,
int renderbuffer, void *loaderPrivate,
unsigned *error);
PUBLIC void
dri2_destroy_image(struct dri_image *img);
PUBLIC struct dri_image *
dri2_create_from_texture(struct dri_context *dri_ctx, int target, unsigned texture,
int depth, int level, unsigned *error,
void *loaderPrivate);
PUBLIC struct dri_image *
dri_create_image(struct dri_screen *screen,
int width, int height,
int format,
const uint64_t *modifiers,
const unsigned _count,
unsigned int use,
void *loaderPrivate);
PUBLIC GLboolean
dri2_query_image(struct dri_image *image, int attrib, int *value);
PUBLIC struct dri_image *
dri2_dup_image(struct dri_image *image, void *loaderPrivate);
PUBLIC GLboolean
dri2_validate_usage(struct dri_image *image, unsigned int use);
PUBLIC struct dri_image *
dri2_from_planar(struct dri_image *image, int plane, void *loaderPrivate);
PUBLIC struct dri_image *
dri2_from_dma_bufs(struct dri_screen *screen,
int width, int height, int fourcc,
uint64_t modifier, int *fds, int num_fds,
int *strides, int *offsets,
enum __DRIYUVColorSpace yuv_color_space,
enum __DRISampleRange sample_range,
enum __DRIChromaSiting horizontal_siting,
enum __DRIChromaSiting vertical_siting,
uint32_t dri_flags,
unsigned *error,
void *loaderPrivate);
PUBLIC void
dri2_blit_image(struct dri_context *ctx, struct dri_image *dst, struct dri_image *src,
int dstx0, int dsty0, int dstwidth, int dstheight,
int srcx0, int srcy0, int srcwidth, int srcheight,
int flush_flag);
PUBLIC void *
dri2_map_image(struct dri_context *ctx, struct dri_image *image,
int x0, int y0, int width, int height,
unsigned int flags, int *stride, void **data);
PUBLIC void
dri2_unmap_image(struct dri_context *ctx, struct dri_image *image, void *data);
PUBLIC bool
dri_query_dma_buf_formats(struct dri_screen *_screen, int max, int *formats,
int *count);
PUBLIC bool
dri_query_dma_buf_modifiers(struct dri_screen *_screen, int fourcc, int max,
uint64_t *modifiers, unsigned int *external_only,
int *count);
PUBLIC bool
dri2_query_dma_buf_format_modifier_attribs(struct dri_screen *_screen,
uint32_t fourcc, uint64_t modifier,
int attrib, uint64_t *value);
PUBLIC struct dri_image *
dri_create_image_with_modifiers(struct dri_screen *screen,
uint32_t width, uint32_t height,
uint32_t dri_format, uint32_t dri_usage,
const uint64_t *modifiers,
unsigned int modifiers_count,
void *loaderPrivate);
PUBLIC int
dri_query_compatible_render_only_device_fd(int kms_only_fd);
PUBLIC int
driSWRastQueryBufferAge(struct dri_drawable *drawable);
PUBLIC void
dri2_set_in_fence_fd(struct dri_image *img, int fd);
PUBLIC bool
dri2_query_compression_rates(struct dri_screen *_screen, const struct dri_config *config, int max,
enum __DRIFixedRateCompression *rates, int *count);
PUBLIC bool
dri2_query_compression_modifiers(struct dri_screen *_screen, uint32_t fourcc,
enum __DRIFixedRateCompression rate, int max,
uint64_t *modifiers, int *count);
PUBLIC void
dri_set_damage_region(struct dri_drawable *drawable, unsigned int nrects, int *rects);
PUBLIC unsigned
dri_fence_get_caps(struct dri_screen *screen);
PUBLIC void *
dri_create_fence(struct dri_context *ctx);
PUBLIC void *
dri_create_fence_fd(struct dri_context *_ctx, int fd);
PUBLIC int
dri_get_fence_fd(struct dri_screen *driscreen, void *_fence);
PUBLIC void *
dri_get_fence_from_cl_event(struct dri_screen *driscreen, intptr_t cl_event);
PUBLIC void
dri_destroy_fence(struct dri_screen *driscreen, void *_fence);
PUBLIC GLboolean
dri_client_wait_sync(struct dri_context *_ctx, void *_fence, unsigned flags,
uint64_t timeout);
PUBLIC void
dri_server_wait_sync(struct dri_context *ctx, void *_fence, unsigned flags);
PUBLIC void
dri_set_blob_cache_funcs(struct dri_screen *screen, __DRIblobCacheSet set,
__DRIblobCacheGet get);
PUBLIC struct pipe_screen *
dri_get_pipe_screen(struct dri_screen *driScreen);
PUBLIC char*
driGetDriInfoXML(const char* driverName);
PUBLIC bool
dri_get_drm_device_info(const char *device_name, uint8_t *device_uuid, uint8_t *driver_uuid,
char **vendor_name, char **renderer_name, char **driver_name);
#endif /* _DRI_UTIL_H_ */
+634
View File
@@ -0,0 +1,634 @@
/**************************************************************************
*
* Copyright 2009, VMware, Inc.
* All Rights Reserved.
* Copyright 2010 George Sapountzis <[email protected]>
*
* 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.
*
**************************************************************************/
#include "mesa_interface.h"
#include "git_sha1.h"
#include "util/format/u_format.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/box.h"
#include "pipe/p_context.h"
#include "pipe-loader/pipe_loader.h"
#include "frontend/drisw_api.h"
#include "state_tracker/st_context.h"
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_drawable.h"
#include "dri_helpers.h"
#include "dri_query_renderer.h"
#include "util/libsync.h"
#ifdef HAVE_LIBDRM
#include <xf86drm.h>
#endif
DEBUG_GET_ONCE_BOOL_OPTION(swrast_no_present, "SWRAST_NO_PRESENT", false);
static inline void
get_drawable_info(struct dri_drawable *drawable, int *x, int *y, int *w, int *h)
{
const __DRIswrastLoaderExtension *loader = drawable->screen->swrast_loader;
loader->getDrawableInfo(drawable, x, y, w, h,
drawable->loaderPrivate);
}
static inline void
put_image(struct dri_drawable *drawable, void *data, unsigned width, unsigned height)
{
const __DRIswrastLoaderExtension *loader = drawable->screen->swrast_loader;
loader->putImage(drawable, __DRI_SWRAST_IMAGE_OP_SWAP,
0, 0, width, height,
data, drawable->loaderPrivate);
}
static inline void
put_image2(struct dri_drawable *drawable, void *data, int x, int y,
unsigned width, unsigned height, unsigned stride)
{
const __DRIswrastLoaderExtension *loader = drawable->screen->swrast_loader;
loader->putImage2(drawable, __DRI_SWRAST_IMAGE_OP_SWAP,
x, y, width, height, stride,
data, drawable->loaderPrivate);
}
static inline void
put_image_shm(struct dri_drawable *drawable, int shmid, char *shmaddr,
unsigned offset, unsigned offset_x, int x, int y,
unsigned width, unsigned height, unsigned stride)
{
const __DRIswrastLoaderExtension *loader = drawable->screen->swrast_loader;
/* if we have the newer interface, don't have to add the offset_x here. */
if (loader->base.version > 4 && loader->putImageShm2)
loader->putImageShm2(drawable, __DRI_SWRAST_IMAGE_OP_SWAP,
x, y, width, height, stride,
shmid, shmaddr, offset, drawable->loaderPrivate);
else
loader->putImageShm(drawable, __DRI_SWRAST_IMAGE_OP_SWAP,
x, y, width, height, stride,
shmid, shmaddr, offset + offset_x, drawable->loaderPrivate);
}
static inline void
get_image(struct dri_drawable *drawable, int x, int y, int width, int height, void *data)
{
const __DRIswrastLoaderExtension *loader = drawable->screen->swrast_loader;
loader->getImage(drawable, x, y, width, height,
data, drawable->loaderPrivate);
}
static inline void
get_image2(struct dri_drawable *drawable, int x, int y, int width, int height, int stride, void *data)
{
const __DRIswrastLoaderExtension *loader = drawable->screen->swrast_loader;
/* getImage2 support is only in version 3 or newer */
if (loader->base.version < 3)
return;
loader->getImage2(drawable, x, y, width, height, stride,
data, drawable->loaderPrivate);
}
static inline bool
get_image_shm(struct dri_drawable *drawable, int x, int y, int width, int height,
struct pipe_resource *res)
{
const __DRIswrastLoaderExtension *loader = drawable->screen->swrast_loader;
struct winsys_handle whandle;
whandle.type = WINSYS_HANDLE_TYPE_SHMID;
if (loader->base.version < 4 || !loader->getImageShm)
return false;
if (!res->screen->resource_get_handle(res->screen, NULL, res, &whandle, PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE))
return false;
if (loader->base.version > 5 && loader->getImageShm2)
return loader->getImageShm2(drawable, x, y, width, height, whandle.handle, drawable->loaderPrivate);
loader->getImageShm(drawable, x, y, width, height, whandle.handle, drawable->loaderPrivate);
return true;
}
static void
drisw_update_drawable_info(struct dri_drawable *drawable)
{
int x, y;
get_drawable_info(drawable, &x, &y, &drawable->w, &drawable->h);
}
static void
drisw_get_image(struct dri_drawable *drawable,
int x, int y, unsigned width, unsigned height, unsigned stride,
void *data)
{
int draw_x, draw_y, draw_w, draw_h;
get_drawable_info(drawable, &draw_x, &draw_y, &draw_w, &draw_h);
get_image2(drawable, x, y, draw_w, draw_h, stride, data);
}
static void
drisw_put_image(struct dri_drawable *drawable,
void *data, unsigned width, unsigned height)
{
put_image(drawable, data, width, height);
}
static void
drisw_put_image2(struct dri_drawable *drawable,
void *data, int x, int y, unsigned width, unsigned height,
unsigned stride)
{
put_image2(drawable, data, x, y, width, height, stride);
}
static inline void
drisw_put_image_shm(struct dri_drawable *drawable,
int shmid, char *shmaddr, unsigned offset,
unsigned offset_x,
int x, int y, unsigned width, unsigned height,
unsigned stride)
{
put_image_shm(drawable, shmid, shmaddr, offset, offset_x, x, y, width, height, stride);
}
static inline void
drisw_present_texture(struct pipe_context *pipe, struct dri_drawable *drawable,
struct pipe_resource *ptex, unsigned nrects, struct pipe_box *sub_box)
{
struct dri_screen *screen = drawable->screen;
if (screen->swrast_no_present)
return;
screen->base.screen->flush_frontbuffer(screen->base.screen, pipe, ptex, 0, 0, drawable, nrects, sub_box);
}
static inline void
drisw_invalidate_drawable(struct dri_drawable *drawable)
{
drawable->texture_stamp = drawable->lastStamp - 1;
p_atomic_inc(&drawable->base.stamp);
}
static inline void
drisw_copy_to_front(struct pipe_context *pipe,
struct dri_drawable *drawable,
struct pipe_resource *ptex,
int nboxes, struct pipe_box *boxes)
{
drisw_present_texture(pipe, drawable, ptex, nboxes, boxes);
drisw_invalidate_drawable(drawable);
}
/*
* Backend functions for pipe_frontend_drawable and swap_buffers.
*/
static void
drisw_swap_buffers_with_damage(struct dri_drawable *drawable, int nrects, const int *rects)
{
/* Damage regions still require us to update the whole front buffer
* in case the compositor doesn't obey them, so we will just ignore
* the passed in damage regions and swap the whole buffer
*/
(void)nrects;
(void)rects;
struct dri_context *ctx = dri_get_current();
struct dri_screen *screen = drawable->screen;
struct pipe_resource *ptex;
if (!ctx)
return;
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(ctx->st->ctx);
ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
if (ptex) {
struct pipe_fence_handle *fence = NULL;
if (ctx->hud)
hud_run(ctx->hud, ctx->st->cso_context, ptex);
st_context_flush(ctx->st, ST_FLUSH_FRONT, &fence, NULL, NULL);
if (drawable->stvis.samples > 1) {
/* Resolve the back buffer. */
dri_pipe_blit(ctx->st->pipe,
drawable->textures[ST_ATTACHMENT_BACK_LEFT],
drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT]);
}
screen->base.screen->fence_finish(screen->base.screen, ctx->st->pipe,
fence, OS_TIMEOUT_INFINITE);
screen->base.screen->fence_reference(screen->base.screen, &fence, NULL);
drisw_copy_to_front(ctx->st->pipe, drawable, ptex, 0, NULL);
drawable->buffer_age = 1;
/* TODO: remove this if the framebuffer state doesn't change. */
st_context_invalidate_state(ctx->st, ST_INVALIDATE_FB_STATE);
}
}
static void
drisw_swap_buffers(struct dri_drawable *drawable)
{
drisw_swap_buffers_with_damage(drawable, 0, NULL);
}
static void
drisw_copy_sub_buffer(struct dri_drawable *drawable, int x, int y,
int w, int h)
{
struct dri_context *ctx = dri_get_current();
struct dri_screen *screen = drawable->screen;
struct pipe_resource *ptex;
struct pipe_box box;
if (!ctx)
return;
ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
if (ptex) {
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(ctx->st->ctx);
struct pipe_fence_handle *fence = NULL;
st_context_flush(ctx->st, ST_FLUSH_FRONT, &fence, NULL, NULL);
screen->base.screen->fence_finish(screen->base.screen, ctx->st->pipe,
fence, OS_TIMEOUT_INFINITE);
screen->base.screen->fence_reference(screen->base.screen, &fence, NULL);
if (drawable->stvis.samples > 1) {
/* Resolve the back buffer. */
dri_pipe_blit(ctx->st->pipe,
drawable->textures[ST_ATTACHMENT_BACK_LEFT],
drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT]);
}
u_box_2d(x, drawable->h - y - h, w, h, &box);
drisw_present_texture(ctx->st->pipe, drawable, ptex, 1, &box);
}
}
static bool
drisw_flush_frontbuffer(struct dri_context *ctx,
struct dri_drawable *drawable,
enum st_attachment_type statt)
{
struct pipe_resource *ptex;
if (!ctx || statt != ST_ATTACHMENT_FRONT_LEFT)
return false;
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(ctx->st->ctx);
if (drawable->stvis.samples > 1) {
/* Resolve the front buffer. */
dri_pipe_blit(ctx->st->pipe,
drawable->textures[ST_ATTACHMENT_FRONT_LEFT],
drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT]);
}
ptex = drawable->textures[statt];
if (ptex) {
drisw_copy_to_front(ctx->st->pipe, ctx->draw, ptex, 0, NULL);
}
return true;
}
extern bool
dri_image_drawable_get_buffers(struct dri_drawable *drawable,
struct __DRIimageList *images,
const enum st_attachment_type *statts,
unsigned statts_count);
static void
handle_in_fence(struct dri_context *ctx, struct dri_image *img)
{
struct pipe_context *pipe = ctx->st->pipe;
struct pipe_fence_handle *fence;
int fd = img->in_fence_fd;
if (fd == -1)
return;
validate_fence_fd(fd);
img->in_fence_fd = -1;
pipe->create_fence_fd(pipe, &fence, fd, PIPE_FD_TYPE_NATIVE_SYNC);
pipe->fence_server_sync(pipe, fence, 0);
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
close(fd);
}
/**
* Allocate framebuffer attachments.
*
* During fixed-size operation, the function keeps allocating new attachments
* as they are requested. Unused attachments are not removed, not until the
* framebuffer is resized or destroyed.
*/
static void
drisw_allocate_textures(struct dri_context *stctx,
struct dri_drawable *drawable,
const enum st_attachment_type *statts,
unsigned count)
{
struct dri_screen *screen = drawable->screen;
const __DRIswrastLoaderExtension *loader = drawable->screen->swrast_loader;
struct pipe_resource templ;
unsigned width, height;
bool resized;
unsigned i;
const __DRIimageLoaderExtension *image = screen->image.loader;
struct __DRIimageList images;
bool imported_buffers = true;
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(stctx->st->ctx);
/* First try to get the buffers from the loader */
if (image) {
if (!dri_image_drawable_get_buffers(drawable, &images,
statts, count))
imported_buffers = false;
}
width = drawable->w;
height = drawable->h;
resized = (drawable->old_w != width ||
drawable->old_h != height);
/* remove outdated textures */
if (resized) {
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
pipe_resource_reference(&drawable->textures[i], NULL);
pipe_resource_reference(&drawable->msaa_textures[i], NULL);
}
drawable->buffer_age = 0;
}
memset(&templ, 0, sizeof(templ));
templ.target = screen->target;
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
templ.array_size = 1;
templ.last_level = 0;
if (imported_buffers && image) {
if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
struct pipe_resource **buf =
&drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
struct pipe_resource *texture = images.front->texture;
drawable->w = texture->width0;
drawable->h = texture->height0;
pipe_resource_reference(buf, texture);
handle_in_fence(stctx, images.front);
}
if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
struct pipe_resource **buf =
&drawable->textures[ST_ATTACHMENT_BACK_LEFT];
struct pipe_resource *texture = images.back->texture;
drawable->w = texture->width0;
drawable->h = texture->height0;
pipe_resource_reference(buf, texture);
handle_in_fence(stctx, images.back);
}
if (images.image_mask & __DRI_IMAGE_BUFFER_SHARED) {
struct pipe_resource **buf =
&drawable->textures[ST_ATTACHMENT_BACK_LEFT];
struct pipe_resource *texture = images.back->texture;
drawable->w = texture->width0;
drawable->h = texture->height0;
pipe_resource_reference(buf, texture);
handle_in_fence(stctx, images.back);
}
/* Note: if there is both a back and a front buffer,
* then they have the same size.
*/
templ.width0 = drawable->w;
templ.height0 = drawable->h;
} else {
for (i = 0; i < count; i++) {
enum pipe_format format;
unsigned bind;
/* the texture already exists or not requested */
if (drawable->textures[statts[i]])
continue;
dri_drawable_get_format(drawable, statts[i], &format, &bind);
/* if we don't do any present, no need for display targets */
if (statts[i] != ST_ATTACHMENT_DEPTH_STENCIL && !screen->swrast_no_present)
bind |= PIPE_BIND_DISPLAY_TARGET;
if (format == PIPE_FORMAT_NONE)
continue;
templ.format = format;
templ.bind = bind;
templ.nr_samples = 0;
templ.nr_storage_samples = 0;
if (statts[i] == ST_ATTACHMENT_FRONT_LEFT &&
screen->base.screen->resource_create_front &&
loader->base.version >= 3) {
drawable->textures[statts[i]] =
screen->base.screen->resource_create_front(screen->base.screen, &templ, (const void *)drawable);
} else
drawable->textures[statts[i]] =
screen->base.screen->resource_create(screen->base.screen, &templ);
if (drawable->stvis.samples > 1) {
templ.bind = templ.bind &
~(PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_DISPLAY_TARGET);
templ.nr_samples = drawable->stvis.samples;
templ.nr_storage_samples = drawable->stvis.samples;
drawable->msaa_textures[statts[i]] =
screen->base.screen->resource_create(screen->base.screen, &templ);
dri_pipe_blit(stctx->st->pipe,
drawable->msaa_textures[statts[i]],
drawable->textures[statts[i]]);
}
}
}
drawable->old_w = width;
drawable->old_h = height;
}
void
drisw_update_tex_buffer(struct dri_drawable *drawable,
struct dri_context *ctx,
struct pipe_resource *res)
{
struct st_context *st_ctx = (struct st_context *)ctx->st;
struct pipe_context *pipe = st_ctx->pipe;
struct pipe_transfer *transfer;
char *map;
int x, y, w, h;
int ximage_stride, line;
int cpp = util_format_get_blocksize(res->format);
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(ctx->st->ctx);
get_drawable_info(drawable, &x, &y, &w, &h);
map = pipe_texture_map(pipe, res,
0, 0, // level, layer,
PIPE_MAP_WRITE,
x, y, w, h, &transfer);
/* Copy the Drawable content to the mapped texture buffer */
if (!get_image_shm(drawable, x, y, w, h, res))
get_image(drawable, x, y, w, h, map);
/* The pipe transfer has a pitch rounded up to the nearest 64 pixels.
get_image() has a pitch rounded up to 4 bytes. */
ximage_stride = ((w * cpp) + 3) & -4;
for (line = h-1; line; --line) {
memmove(&map[line * transfer->stride],
&map[line * ximage_stride],
ximage_stride);
}
pipe_texture_unmap(pipe, transfer);
}
/*
* Backend function for init_screen.
*/
static const struct drisw_loader_funcs drisw_lf = {
.get_image = drisw_get_image,
.put_image = drisw_put_image,
.put_image2 = drisw_put_image2
};
static const struct drisw_loader_funcs drisw_shm_lf = {
.get_image = drisw_get_image,
.put_image = drisw_put_image,
.put_image2 = drisw_put_image2,
.put_image_shm = drisw_put_image_shm
};
void
drisw_init_drawable(struct dri_drawable *drawable, bool isPixmap, int alphaBits)
{
drawable->allocate_textures = drisw_allocate_textures;
drawable->update_drawable_info = drisw_update_drawable_info;
drawable->flush_frontbuffer = drisw_flush_frontbuffer;
drawable->update_tex_buffer = drisw_update_tex_buffer;
drawable->swap_buffers = drisw_swap_buffers;
drawable->swap_buffers_with_damage = drisw_swap_buffers_with_damage;
}
struct pipe_screen *
drisw_init_screen(struct dri_screen *screen, bool driver_name_is_inferred)
{
const __DRIswrastLoaderExtension *loader = screen->swrast_loader;
struct pipe_screen *pscreen = NULL;
const struct drisw_loader_funcs *lf = &drisw_lf;
screen->swrast_no_present = debug_get_option_swrast_no_present();
if (loader->base.version >= 4) {
if (loader->putImageShm)
lf = &drisw_shm_lf;
}
bool success = false;
#ifdef HAVE_DRISW_KMS
if (screen->fd != -1)
success = pipe_loader_sw_probe_kms(&screen->dev, screen->fd);
#endif
if (!success)
success = pipe_loader_sw_probe_dri(&screen->dev, lf);
if (success)
pscreen = pipe_loader_create_screen(screen->dev, driver_name_is_inferred);
return pscreen;
}
/* swrast copy sub buffer entrypoint. */
void
driswCopySubBuffer(struct dri_drawable *drawable, int x, int y, int w, int h)
{
assert(drawable->screen->swrast_loader);
drisw_copy_sub_buffer(drawable, x, y, w, h);
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */
+686
View File
@@ -0,0 +1,686 @@
/*
* Copyright 2020 Red Hat, Inc.
*
* 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 (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 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.
*/
#include "mesa_interface.h"
#include "git_sha1.h"
#include "util/format/u_format.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/box.h"
#include "util/log.h"
#include "pipe/p_context.h"
#include "pipe-loader/pipe_loader.h"
#include "state_tracker/st_context.h"
#include "zink/zink_public.h"
#include "zink/zink_kopper.h"
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_drawable.h"
#include "dri_helpers.h"
#include <vulkan/vulkan.h>
#ifdef VK_USE_PLATFORM_XCB_KHR
#include <xcb/xcb.h>
#include <xcb/dri3.h>
#include <xcb/present.h>
#include <xcb/xfixes.h>
#include "util/libsync.h"
#include <X11/Xlib-xcb.h>
#include "drm-uapi/drm_fourcc.h"
#include "loader_dri3_helper.h"
#endif
struct pipe_screen *
kopper_init_screen(struct dri_screen *screen, bool driver_name_is_inferred)
{
struct pipe_screen *pscreen = NULL;
if (!screen->kopper_loader) {
fprintf(stderr, "mesa: Kopper interface not found!\n"
" Ensure the versions of %s built with this version of Zink are\n"
" in your library path!\n", KOPPER_LIB_NAMES);
return NULL;
}
screen->can_share_buffer = true;
bool success;
#ifdef HAVE_LIBDRM
if (screen->fd != -1)
success = pipe_loader_drm_probe_fd(&screen->dev, screen->fd, false);
else
success = pipe_loader_vk_probe_dri(&screen->dev);
#else
success = pipe_loader_vk_probe_dri(&screen->dev);
#endif
if (success)
pscreen = pipe_loader_create_screen(screen->dev, driver_name_is_inferred);
if (!pscreen)
return NULL;
assert(pscreen->caps.device_reset_status_query);
screen->is_sw = zink_kopper_is_cpu(kopper_get_zink_screen(pscreen));
return pscreen;
}
// copypasta alert
extern bool
dri_image_drawable_get_buffers(struct dri_drawable *drawable,
struct __DRIimageList *images,
const enum st_attachment_type *statts,
unsigned statts_count);
#ifdef VK_USE_PLATFORM_XCB_KHR
/* Translate from the pipe_format enums used by Gallium to the DRM FourCC
* codes used by dmabuf import */
static int
pipe_format_to_fourcc(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_BGRA8888_SRGB: return __DRI_IMAGE_FOURCC_SABGR8888;
case PIPE_FORMAT_BGRX8888_SRGB: return __DRI_IMAGE_FOURCC_SXRGB8888;
case PIPE_FORMAT_RGBA8888_SRGB: return __DRI_IMAGE_FOURCC_SABGR8888;
case PIPE_FORMAT_B5G6R5_UNORM: return DRM_FORMAT_RGB565;
case PIPE_FORMAT_BGRX8888_UNORM: return DRM_FORMAT_XRGB8888;
case PIPE_FORMAT_BGRA8888_UNORM: return DRM_FORMAT_ARGB8888;
case PIPE_FORMAT_RGBA8888_UNORM: return DRM_FORMAT_ABGR8888;
case PIPE_FORMAT_RGBX8888_UNORM: return DRM_FORMAT_XBGR8888;
case PIPE_FORMAT_B10G10R10X2_UNORM: return DRM_FORMAT_XRGB2101010;
case PIPE_FORMAT_B10G10R10A2_UNORM: return DRM_FORMAT_ARGB2101010;
case PIPE_FORMAT_R10G10B10X2_UNORM: return DRM_FORMAT_XBGR2101010;
case PIPE_FORMAT_R10G10B10A2_UNORM: return DRM_FORMAT_ABGR2101010;
case PIPE_FORMAT_R16G16B16A16_FLOAT: return DRM_FORMAT_XBGR16161616F;
case PIPE_FORMAT_R16G16B16X16_FLOAT: return DRM_FORMAT_ABGR16161616F;
case PIPE_FORMAT_B5G5R5A1_UNORM: return DRM_FORMAT_ARGB1555;
case PIPE_FORMAT_R5G5B5A1_UNORM: return DRM_FORMAT_ABGR1555;
case PIPE_FORMAT_B4G4R4A4_UNORM: return DRM_FORMAT_ARGB4444;
case PIPE_FORMAT_R4G4B4A4_UNORM: return DRM_FORMAT_ABGR4444;
default: return DRM_FORMAT_INVALID;
}
}
/** kopper_get_pixmap_buffer
*
* Get the DRM object for a pixmap from the X server and
* wrap that with a struct dri_image structure using createImageFromDmaBufs
*/
static struct pipe_resource *
kopper_get_pixmap_buffer(struct dri_drawable *drawable,
enum pipe_format pf)
{
xcb_drawable_t pixmap;
int width;
int height;
uint32_t fourcc = pipe_format_to_fourcc(pf);
struct kopper_loader_info *info = &drawable->info;
assert(info->bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR);
VkXcbSurfaceCreateInfoKHR *xcb = (VkXcbSurfaceCreateInfoKHR *)&info->bos;
xcb_connection_t *conn = xcb->connection;
pixmap = xcb->window;
if (drawable->image)
return drawable->image->texture;
/* FIXME: probably broken for OBS studio?
* see dri3_get_pixmap_buffer()
*/
struct dri_screen *screen = drawable->screen;
#ifndef GLX_USE_APPLE
drawable->image = loader_dri3_get_pixmap_buffer(conn, pixmap, screen,
fourcc, drawable->screen->has_multibuffer, &width, &height, drawable);
#else
drawable->image = NULL;
#endif
if (!drawable->image)
return NULL;
drawable->w = width;
drawable->h = height;
return drawable->image->texture;
}
#endif //VK_USE_PLATFORM_XCB_KHR
static void
kopper_allocate_textures(struct dri_context *ctx,
struct dri_drawable *drawable,
const enum st_attachment_type *statts,
unsigned statts_count)
{
struct dri_screen *screen = drawable->screen;
struct pipe_resource templ;
unsigned width, height;
bool resized;
unsigned i;
struct __DRIimageList images;
const __DRIimageLoaderExtension *image = screen->image.loader;
bool is_window = drawable->is_window;
bool is_pixmap = !is_window && drawable->info.bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(ctx->st->ctx);
/* First get the buffers from the loader */
if (image) {
if (!dri_image_drawable_get_buffers(drawable, &images,
statts, statts_count))
return;
}
if (image) {
if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
struct pipe_resource **buf =
&drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
struct pipe_resource *texture = images.front->texture;
drawable->w = texture->width0;
drawable->h = texture->height0;
pipe_resource_reference(buf, texture);
}
if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
struct pipe_resource **buf =
&drawable->textures[ST_ATTACHMENT_BACK_LEFT];
struct pipe_resource *texture = images.back->texture;
drawable->w = texture->width0;
drawable->h = texture->height0;
pipe_resource_reference(buf, texture);
}
if (images.image_mask & __DRI_IMAGE_BUFFER_SHARED) {
struct pipe_resource **buf =
&drawable->textures[ST_ATTACHMENT_BACK_LEFT];
struct pipe_resource *texture = images.back->texture;
drawable->w = texture->width0;
drawable->h = texture->height0;
pipe_resource_reference(buf, texture);
ctx->is_shared_buffer_bound = true;
} else {
ctx->is_shared_buffer_bound = false;
}
}
/* check size after possible loader image resize */
width = drawable->w;
height = drawable->h;
resized = (drawable->old_w != width ||
drawable->old_h != height);
if (!image) {
/* remove outdated textures */
if (resized) {
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
if (drawable->textures[i] && i < ST_ATTACHMENT_DEPTH_STENCIL && !is_pixmap) {
drawable->textures[i]->width0 = width;
drawable->textures[i]->height0 = height;
/* force all contexts to revalidate framebuffer */
p_atomic_inc(&drawable->base.stamp);
} else
pipe_resource_reference(&drawable->textures[i], NULL);
pipe_resource_reference(&drawable->msaa_textures[i], NULL);
if (is_pixmap && i == ST_ATTACHMENT_FRONT_LEFT) {
FREE(drawable->image);
drawable->image = NULL;
}
}
}
}
drawable->old_w = width;
drawable->old_h = height;
memset(&templ, 0, sizeof(templ));
templ.target = screen->target;
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
templ.array_size = 1;
templ.last_level = 0;
#if 0
XXX do this once swapinterval is hooked up
/* pixmaps always have front buffers.
* Exchange swaps also mandate fake front buffers.
*/
if (draw->type != LOADER_DRI3_DRAWABLE_WINDOW)
buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
#endif
uint32_t attachments = 0;
for (i = 0; i < statts_count; i++)
attachments |= BITFIELD_BIT(statts[i]);
bool front_only = attachments & ST_ATTACHMENT_FRONT_LEFT_MASK && !(attachments & ST_ATTACHMENT_BACK_LEFT_MASK);
for (i = 0; i < statts_count; i++) {
enum pipe_format format;
unsigned bind;
dri_drawable_get_format(drawable, statts[i], &format, &bind);
templ.format = format;
/* the texture already exists or not requested */
if (!drawable->textures[statts[i]]) {
if (statts[i] == ST_ATTACHMENT_BACK_LEFT ||
statts[i] == ST_ATTACHMENT_DEPTH_STENCIL ||
(statts[i] == ST_ATTACHMENT_FRONT_LEFT && front_only))
bind |= PIPE_BIND_DISPLAY_TARGET;
if (format == PIPE_FORMAT_NONE)
continue;
templ.bind = bind;
templ.nr_samples = 0;
templ.nr_storage_samples = 0;
if (statts[i] < ST_ATTACHMENT_DEPTH_STENCIL && is_window) {
void *data;
if (statts[i] == ST_ATTACHMENT_BACK_LEFT || (statts[i] == ST_ATTACHMENT_FRONT_LEFT && front_only))
data = &drawable->info;
else
data = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
assert(data);
drawable->textures[statts[i]] =
screen->base.screen->resource_create_drawable(screen->base.screen, &templ, data);
drawable->window_valid = !!drawable->textures[statts[i]];
}
#ifdef VK_USE_PLATFORM_XCB_KHR
else if (is_pixmap && statts[i] == ST_ATTACHMENT_FRONT_LEFT && !screen->is_sw) {
drawable->textures[statts[i]] = kopper_get_pixmap_buffer(drawable, format);
if (drawable->textures[statts[i]])
dri_image_fence_sync(ctx, drawable->image);
}
#endif
if (!drawable->textures[statts[i]])
drawable->textures[statts[i]] =
screen->base.screen->resource_create(screen->base.screen, &templ);
}
if (drawable->stvis.samples > 1 && !drawable->msaa_textures[statts[i]]) {
templ.bind = bind &
~(PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_DISPLAY_TARGET);
templ.nr_samples = drawable->stvis.samples;
templ.nr_storage_samples = drawable->stvis.samples;
drawable->msaa_textures[statts[i]] =
screen->base.screen->resource_create(screen->base.screen, &templ);
dri_pipe_blit(ctx->st->pipe,
drawable->msaa_textures[statts[i]],
drawable->textures[statts[i]]);
}
}
}
static inline void
get_drawable_info(struct dri_drawable *drawable, int *w, int *h)
{
const __DRIkopperLoaderExtension *loader = drawable->screen->kopper_loader;
if (loader)
loader->GetDrawableInfo(drawable, w, h, drawable->loaderPrivate);
}
static void
kopper_update_drawable_info(struct dri_drawable *drawable)
{
struct dri_screen *screen = drawable->screen;
bool is_window = drawable->info.bos.sType != 0;
struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT] ?
drawable->textures[ST_ATTACHMENT_BACK_LEFT] :
drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
bool do_kopper_update = is_window && ptex && screen->fd == -1;
if (drawable->info.bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR && do_kopper_update)
zink_kopper_update(kopper_get_zink_screen(screen->base.screen), ptex, &drawable->w, &drawable->h);
else
get_drawable_info(drawable, &drawable->w, &drawable->h);
}
static inline void
kopper_present_texture(struct pipe_context *pipe, struct dri_drawable *drawable,
struct pipe_resource *ptex, unsigned nboxes, struct pipe_box *sub_box)
{
struct dri_screen *screen = drawable->screen;
screen->base.screen->flush_frontbuffer(screen->base.screen, pipe, ptex, 0, 0, drawable, nboxes, sub_box);
}
static inline void
kopper_copy_to_front(struct pipe_context *pipe,
struct dri_drawable *drawable,
struct pipe_resource *ptex,
unsigned nrects,
struct pipe_box *boxes)
{
kopper_present_texture(pipe, drawable, ptex, nrects, boxes);
drawable->lastStamp++;
p_atomic_inc(&drawable->base.stamp);
}
static bool
kopper_flush_frontbuffer(struct dri_context *ctx,
struct dri_drawable *drawable,
enum st_attachment_type statt)
{
struct pipe_resource *ptex;
if (!ctx || statt != ST_ATTACHMENT_FRONT_LEFT)
return false;
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(ctx->st->ctx);
/* prevent recursion */
if (drawable->flushing)
return true;
drawable->flushing = true;
if (drawable->stvis.samples > 1) {
/* Resolve the front buffer. */
dri_pipe_blit(ctx->st->pipe,
drawable->textures[ST_ATTACHMENT_FRONT_LEFT],
drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT]);
}
ptex = drawable->textures[statt];
if (ptex) {
ctx->st->pipe->flush_resource(ctx->st->pipe, drawable->textures[ST_ATTACHMENT_FRONT_LEFT]);
struct pipe_screen *screen = drawable->screen->base.screen;
struct st_context *st;
struct pipe_fence_handle *new_fence = NULL;
st = ctx->st;
st_context_flush(st, ST_FLUSH_FRONT, &new_fence, NULL, NULL);
drawable->flushing = false;
/* throttle on the previous fence */
if (drawable->throttle_fence) {
screen->fence_finish(screen, NULL, drawable->throttle_fence, OS_TIMEOUT_INFINITE);
screen->fence_reference(screen, &drawable->throttle_fence, NULL);
}
drawable->throttle_fence = new_fence;
kopper_copy_to_front(st->pipe, ctx->draw, ptex, 0, NULL);
}
return true;
}
static void
kopper_update_tex_buffer(struct dri_drawable *drawable,
struct dri_context *ctx,
struct pipe_resource *res)
{
struct dri_screen *screen = drawable->screen;
if (screen->has_dmabuf || drawable->is_window || drawable->info.bos.sType != VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR)
return;
drisw_update_tex_buffer(drawable, ctx, res);
}
static void
kopper_flush_swapbuffers(struct dri_context *ctx,
struct dri_drawable *drawable)
{
/* does this actually need to do anything? */
}
static void
kopper_swap_buffers(struct dri_drawable *drawable);
static void
kopper_swap_buffers_with_damage(struct dri_drawable *drawable, int nrects, const int *rects);
void
kopper_init_drawable(struct dri_drawable *drawable, bool isPixmap, int alphaBits)
{
struct dri_screen *screen = drawable->screen;
drawable->allocate_textures = kopper_allocate_textures;
drawable->update_drawable_info = kopper_update_drawable_info;
drawable->flush_frontbuffer = kopper_flush_frontbuffer;
drawable->update_tex_buffer = kopper_update_tex_buffer;
drawable->flush_swapbuffers = kopper_flush_swapbuffers;
drawable->swap_buffers = kopper_swap_buffers;
drawable->swap_buffers_with_damage = kopper_swap_buffers_with_damage;
drawable->info.has_alpha = alphaBits > 0;
if (screen->kopper_loader->SetSurfaceCreateInfo)
screen->kopper_loader->SetSurfaceCreateInfo(drawable->loaderPrivate,
&drawable->info);
drawable->is_window = !isPixmap && drawable->info.bos.sType != 0;
#ifdef VK_USE_PLATFORM_XCB_KHR
if (drawable->info.bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR) {
VkXcbSurfaceCreateInfoKHR *xcb = (VkXcbSurfaceCreateInfoKHR *)&drawable->info.bos;
xcb_connection_t *conn = xcb->connection;
int32_t eid = xcb_generate_id(conn);
if (drawable->is_window) {
xcb_present_select_input(conn, eid, xcb->window,
XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY);
}
drawable->special_event =
xcb_register_for_special_xge(conn, &xcb_present_id, eid, NULL);
}
#endif
}
void
kopper_destroy_drawable(struct dri_drawable *drawable)
{
#ifdef VK_USE_PLATFORM_XCB_KHR
if (drawable->info.bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR) {
VkXcbSurfaceCreateInfoKHR *xcb = (VkXcbSurfaceCreateInfoKHR *)&drawable->info.bos;
xcb_connection_t *conn = xcb->connection;
xcb_unregister_for_special_event(conn, drawable->special_event);
}
#endif
}
int64_t
kopperSwapBuffersWithDamage(struct dri_drawable *drawable, uint32_t flush_flags, int nrects, const int *rects)
{
struct dri_context *ctx = dri_get_current();
struct pipe_resource *ptex;
if (!ctx)
return 0;
ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
if (!ptex)
return 0;
/* ensure invalidation is applied before renderpass ends */
if (flush_flags & __DRI2_FLUSH_INVALIDATE_ANCILLARY)
_mesa_glthread_invalidate_zsbuf(ctx->st->ctx);
drawable->texture_stamp = drawable->lastStamp - 1;
dri_flush(ctx, drawable,
__DRI2_FLUSH_DRAWABLE | flush_flags,
__DRI2_THROTTLE_SWAPBUFFER);
struct pipe_box stack_boxes[64];
if (nrects > ARRAY_SIZE(stack_boxes))
nrects = 0;
if (nrects) {
for (unsigned int i = 0; i < nrects; i++) {
const int *rect = &rects[i * 4];
u_box_2d(rect[0], rect[1], rect[2], rect[3], &stack_boxes[i]);
}
}
kopper_copy_to_front(ctx->st->pipe, drawable, ptex, nrects, stack_boxes);
if (drawable->is_window && !zink_kopper_check(ptex))
return -1;
if (!drawable->textures[ST_ATTACHMENT_FRONT_LEFT]) {
return 0;
}
/* have to manually swap the pointers here to make frontbuffer readback work */
drawable->textures[ST_ATTACHMENT_BACK_LEFT] = drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
drawable->textures[ST_ATTACHMENT_FRONT_LEFT] = ptex;
return 0;
}
int64_t
kopperSwapBuffers(struct dri_drawable *dPriv, uint32_t flush_flags)
{
return kopperSwapBuffersWithDamage(dPriv, flush_flags, 0, NULL);
}
static void
kopper_swap_buffers_with_damage(struct dri_drawable *drawable, int nrects, const int *rects)
{
kopperSwapBuffersWithDamage(drawable, 0, nrects, rects);
}
static void
kopper_swap_buffers(struct dri_drawable *drawable)
{
kopper_swap_buffers_with_damage(drawable, 0, NULL);
}
void
kopperSetSwapInterval(struct dri_drawable *drawable, int interval)
{
struct dri_screen *screen = drawable->screen;
struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT] ?
drawable->textures[ST_ATTACHMENT_BACK_LEFT] :
drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
drawable->info.initial_swap_interval = interval;
/* can't set swap interval on non-windows */
if (!drawable->window_valid)
return;
/* the conditional is because we can be called before buffer allocation. If
* we're before allocation, then the initial_swap_interval will be used when
* the swapchain is eventually created.
*/
if (ptex) {
struct pipe_screen *pscreen = kopper_get_zink_screen(screen->base.screen);
zink_kopper_set_swap_interval(pscreen, ptex, interval);
}
}
int
kopperQueryBufferAge(struct dri_drawable *drawable)
{
struct dri_context *ctx = dri_get_current();
struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT] ?
drawable->textures[ST_ATTACHMENT_BACK_LEFT] :
drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
/* can't get buffer age from non-window swapchain */
if (!drawable->window_valid)
return 0;
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
_mesa_glthread_finish(ctx->st->ctx);
return zink_kopper_query_buffer_age(ctx->st->pipe, ptex);
}
void
kopperQuerySurfaceSize(struct dri_drawable *drawable, int *width, int *height)
{
*width = drawable->w;
*height = drawable->h;
}
int
kopperGetSyncValues(struct dri_drawable *drawable, int64_t target_msc, int64_t divisor,
int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
{
#ifdef VK_USE_PLATFORM_XCB_KHR
struct kopper_loader_info *info = &drawable->info;
assert(info->bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR);
VkXcbSurfaceCreateInfoKHR *xcb = (VkXcbSurfaceCreateInfoKHR *)&info->bos;
xcb_connection_t *conn = xcb->connection;
xcb_void_cookie_t cookie =
xcb_present_notify_msc(conn, xcb->window, 0, target_msc, divisor, remainder);
xcb_generic_event_t *event;
int ret = 0;
xcb_flush(conn);
while ((event = xcb_wait_for_special_event(conn, drawable->special_event)) != NULL) {
xcb_present_generic_event_t *ev = (xcb_present_generic_event_t *)event;
if (ev->evtype == XCB_PRESENT_COMPLETE_NOTIFY) {
xcb_present_complete_notify_event_t *ce =
(xcb_present_complete_notify_event_t *) event;
if (ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC) {
*ust = ce->ust;
*msc = ce->msc;
*sbc = ce->serial;
if (event->full_sequence != cookie.sequence) {
free(event);
continue;
}
ret = 1;
free(event);
break;
}
}
free(event);
}
return ret;
#else
return 0;
#endif
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */
+63
View File
@@ -0,0 +1,63 @@
/* SPDX-License-Identifier: MIT */
#include "dri_drawable.h"
#include "dri_util.h"
int64_t
kopperSwapBuffers(struct dri_drawable *dPriv, uint32_t flush_flags)
{
return 0;
}
int64_t
kopperSwapBuffersWithDamage(struct dri_drawable *dPriv, uint32_t flush_flags, int nrects, const int *rects)
{
return 0;
}
void
kopperSetSwapInterval(struct dri_drawable *dPriv, int interval)
{
}
int
kopperQueryBufferAge(struct dri_drawable *dPriv)
{
return 0;
}
void
kopperQuerySurfaceSize(struct dri_drawable *drawable, int *width, int *height)
{
*width = *height = 1;
}
int
kopperGetSyncValues(struct dri_drawable *drawable, int64_t target_msc, int64_t divisor,
int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
{
return 0;
}
const struct dri_config **
kopper_init_screen(struct dri_screen *screen, bool driver_name_is_inferred);
const struct dri_config **
kopper_init_screen(struct dri_screen *screen, bool driver_name_is_inferred)
{
return NULL;
}
struct dri_drawable;
void
kopper_init_drawable(struct dri_drawable *drawable, bool isPixmap, int alphaBits);
void
kopper_init_drawable(struct dri_drawable *drawable, bool isPixmap, int alphaBits)
{
}
void
kopper_destroy_drawable(struct dri_drawable *drawable);
void
kopper_destroy_drawable(struct dri_drawable *drawable)
{
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,285 @@
/*
* Copyright © 2013 Keith Packard
* Copyright © 2015 Boyan Ding
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifndef LOADER_DRI3_HEADER_H
#define LOADER_DRI3_HEADER_H
#include <stdbool.h>
#include <stdint.h>
#include <xcb/xcb.h>
#include <xcb/dri3.h>
#include <xcb/present.h>
#include <GL/gl.h>
#include "mesa_interface.h"
#include "util/macros.h"
#include <c11/threads.h>
enum loader_dri3_buffer_type {
loader_dri3_buffer_back = 0,
loader_dri3_buffer_front = 1
};
struct loader_dri3_buffer {
struct dri_image *image;
uint32_t pixmap;
/* default case: linear buffer allocated in render gpu vram.
* p2p case: linear buffer allocated in display gpu vram and imported
* to render gpu. p2p case is enabled when driver name matches
* while creating screen in dri3_create_screen() function.
*/
struct dri_image *linear_buffer;
/* Synchronization between the client and X server is done using an
* xshmfence that is mapped into an X server SyncFence. This lets the
* client check whether the X server is done using a buffer with a simple
* xshmfence call, rather than going to read X events from the wire.
*
* However, we can only wait for one xshmfence to be triggered at a time,
* so we need to know *which* buffer is going to be idle next. We do that
* by waiting for a PresentIdleNotify event. When that event arrives, the
* 'busy' flag gets cleared and the client knows that the fence has been
* triggered, and that the wait call will not block.
*/
uint32_t sync_fence; /* XID of X SyncFence object */
struct xshmfence *shm_fence; /* pointer to xshmfence object */
bool busy; /* Set on swap, cleared on IdleNotify */
bool own_pixmap; /* We allocated the pixmap ID, free on destroy */
bool reallocate; /* Buffer should be reallocated and not reused */
uint32_t num_planes;
int strides[4];
int offsets[4];
uint64_t modifier;
uint32_t cpp;
uint32_t flags;
uint32_t width, height;
uint64_t last_swap;
};
#define LOADER_DRI3_MAX_BACK 4
#define LOADER_DRI3_BACK_ID(i) (i)
#define LOADER_DRI3_FRONT_ID (LOADER_DRI3_MAX_BACK)
static inline int
loader_dri3_pixmap_buf_id(enum loader_dri3_buffer_type buffer_type)
{
if (buffer_type == loader_dri3_buffer_back)
return LOADER_DRI3_BACK_ID(0);
else
return LOADER_DRI3_FRONT_ID;
}
struct loader_dri3_drawable;
struct loader_dri3_vtable {
void (*set_drawable_size)(struct loader_dri3_drawable *, int, int);
bool (*in_current_context)(struct loader_dri3_drawable *);
struct dri_context *(*get_dri_context)(struct loader_dri3_drawable *);
struct dri_screen *(*get_dri_screen)(void);
void (*flush_drawable)(struct loader_dri3_drawable *, unsigned);
};
#define LOADER_DRI3_NUM_BUFFERS (1 + LOADER_DRI3_MAX_BACK)
enum loader_dri3_drawable_type {
LOADER_DRI3_DRAWABLE_UNKNOWN,
LOADER_DRI3_DRAWABLE_WINDOW,
LOADER_DRI3_DRAWABLE_PIXMAP,
LOADER_DRI3_DRAWABLE_PBUFFER,
};
struct loader_dri3_drawable {
xcb_connection_t *conn;
xcb_screen_t *screen;
struct dri_drawable *dri_drawable;
xcb_drawable_t drawable;
xcb_window_t window;
xcb_xfixes_region_t region;
int width;
int height;
int depth;
uint8_t have_back;
uint8_t have_fake_front;
enum loader_dri3_drawable_type type;
/* Information about the GPU owning the buffer */
bool multiplanes_available;
bool prefer_back_buffer_reuse;
struct dri_screen *dri_screen_render_gpu;
/* dri_screen_display_gpu holds display GPU in case of prime gpu offloading else
* dri_screen_render_gpu and dri_screen_display_gpu is same.
* In case of prime gpu offloading, if display and render driver names are different
* (potentially not compatible), dri_screen_display_gpu will be NULL but fd_display_gpu
* will still hold fd for display driver.
*/
struct dri_screen *dri_screen_display_gpu;
/* SBC numbers are tracked by using the serial numbers
* in the present request and complete events
*/
uint64_t send_sbc;
uint64_t recv_sbc;
/* Last received UST/MSC values for pixmap present complete */
uint64_t ust, msc;
/* Last received UST/MSC values from present notify msc event */
uint64_t notify_ust, notify_msc;
struct loader_dri3_buffer *buffers[LOADER_DRI3_NUM_BUFFERS];
int cur_back;
int cur_num_back;
int max_num_back;
int cur_blit_source;
uint32_t *stamp;
xcb_present_event_t eid;
xcb_gcontext_t gc;
xcb_special_event_t *special_event;
bool first_init;
bool adaptive_sync;
bool adaptive_sync_active;
bool block_on_depleted_buffers;
bool queries_buffer_age;
int swap_interval;
const struct loader_dri3_vtable *vtable;
unsigned int back_format;
xcb_present_complete_mode_t last_present_mode;
bool is_protected_content;
/* Currently protects the following fields:
* event_cnd, has_event_waiter,
* recv_sbc, ust, msc, recv_msc_serial,
* notify_ust, notify_msc
*/
mtx_t mtx;
cnd_t event_cnd;
unsigned last_special_event_sequence;
bool has_event_waiter;
};
PUBLIC void
loader_dri3_set_swap_interval(struct loader_dri3_drawable *draw,
int interval);
PUBLIC void
loader_dri3_drawable_fini(struct loader_dri3_drawable *draw);
PUBLIC int
loader_dri3_drawable_init(xcb_connection_t *conn,
xcb_drawable_t drawable,
enum loader_dri3_drawable_type type,
struct dri_screen *dri_screen_render_gpu,
struct dri_screen *dri_screen_display_gpu,
bool is_multiplanes_available,
bool prefer_back_buffer_reuse,
const struct dri_config *dri_config,
const struct loader_dri3_vtable *vtable,
struct loader_dri3_drawable*);
PUBLIC bool loader_dri3_wait_for_msc(struct loader_dri3_drawable *draw,
int64_t target_msc,
int64_t divisor, int64_t remainder,
int64_t *ust, int64_t *msc, int64_t *sbc);
PUBLIC int64_t
loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
int64_t target_msc, int64_t divisor,
int64_t remainder, unsigned flush_flags,
const int *rects, int n_rects,
bool force_copy);
PUBLIC int
loader_dri3_wait_for_sbc(struct loader_dri3_drawable *draw,
int64_t target_sbc, int64_t *ust,
int64_t *msc, int64_t *sbc);
PUBLIC int loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw);
PUBLIC void
loader_dri3_flush(struct loader_dri3_drawable *draw,
unsigned flags,
enum __DRI2throttleReason throttle_reason);
PUBLIC void
loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
int x, int y,
int width, int height,
bool flush);
PUBLIC void
loader_dri3_copy_drawable(struct loader_dri3_drawable *draw,
xcb_drawable_t dest,
xcb_drawable_t src);
PUBLIC void
loader_dri3_wait_x(struct loader_dri3_drawable *draw);
PUBLIC void
loader_dri3_wait_gl(struct loader_dri3_drawable *draw);
PUBLIC struct dri_image *
loader_dri3_create_image(xcb_connection_t *c,
xcb_dri3_buffer_from_pixmap_reply_t *bp_reply,
unsigned int fourcc,
struct dri_screen *dri_screen,
void *loaderPrivate);
PUBLIC struct dri_image *
loader_dri3_create_image_from_buffers(xcb_connection_t *c,
xcb_dri3_buffers_from_pixmap_reply_t *bp_reply,
unsigned int fourcc,
struct dri_screen *dri_screen,
void *loaderPrivate);
PUBLIC int
loader_dri3_get_buffers(struct dri_drawable *driDrawable,
unsigned int format,
uint32_t *stamp,
void *loaderPrivate,
uint32_t buffer_mask,
struct __DRIimageList *buffers);
PUBLIC void
loader_dri3_update_drawable_geometry(struct loader_dri3_drawable *draw);
PUBLIC void
loader_dri3_swapbuffer_barrier(struct loader_dri3_drawable *draw);
PUBLIC void
loader_dri3_close_screen(struct dri_screen *dri_screen);
struct dri_image *
loader_dri3_get_pixmap_buffer(xcb_connection_t *conn, xcb_drawable_t pixmap, struct dri_screen *screen,
unsigned fourcc, bool multiplanes_available,
int *width, int *height, void *loader_data);
#endif
+83
View File
@@ -0,0 +1,83 @@
# Copyright © 2017 Dylan Baker
# SPDX-License-Identifier: MIT
inc_st_dri = include_directories('.')
deps_for_libdri = []
files_libdri = files(
'dri_context.c',
'dri_context.h',
'dri_drawable.c',
'dri_drawable.h',
'dri_helpers.c',
'dri_helpers.h',
'dri_query_renderer.c',
'dri_query_renderer.h',
'dri_screen.c',
'dri_screen.h',
'dri_util.c',
'dri_util.h',
)
if with_platform_x11
deps_for_libdri += dep_xcb
if with_dri_platform == 'drm' or with_dri_platform == 'pseudo-drm'
deps_for_libdri += [dep_xcb_dri3, dep_xcb_present, dep_xcb_sync,
dep_xshmfence, dep_xcb_xfixes]
files_libdri += files('loader_dri3_helper.c')
endif
endif
if with_dri
files_libdri += files('drisw.c')
endif
if with_dri2
files_libdri += files('dri2.c')
endif
libdri_c_args = []
if with_gallium_zink and not with_platform_android
if with_glvnd
libdri_c_args += '-DKOPPER_LIB_NAMES="libEGL_@0@ and libGLX_@0@"'.format(glvnd_vendor_name)
else
libdri_c_args += '-DKOPPER_LIB_NAMES="libEGL and libGLX"'
endif
files_libdri += files('kopper.c')
deps_for_libdri += vulkan_wsi_deps
else
files_libdri += files('kopper_stubs.c')
endif
libdri = static_library(
'dri',
[ files_libdri, sha1_h ],
include_directories : [
inc_include, inc_util, inc_mesa, inc_src, inc_gallium,
inc_gallium_aux, inc_util, inc_gallium_drivers, inc_loader,
],
c_args : [libdri_c_args],
gnu_symbol_visibility : 'hidden',
dependencies : [
dep_libdrm,
idep_mesautil,
deps_for_libdri,
],
link_with : [libloader],
)
if with_dri
dri_req_private = []
if dep_libdrm.found()
dri_req_private = ['libdrm >= @0@'.format(_drm_ver)]
endif
pkg.generate(
name : 'dri',
filebase : 'dri',
description : 'Direct Rendering Infrastructure',
version : meson.project_version(),
variables : ['dridriverdir=@0@'.format(dri_drivers_path)],
requires_private : dri_req_private,
)
endif
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,212 @@
/*
* Mesa 3-D graphics library
*
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
* Copyright (C) 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, 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.
*/
/**
* glXGetProcAddress()
*/
#define GLX_GLXEXT_PROTOTYPES
#include <string.h>
#include "util/compiler.h"
#include "GL/glx.h"
#include "glapi/glapi/glapi.h"
struct name_address_pair {
const char *Name;
__GLXextFuncPtr Address;
};
static const struct name_address_pair GLX_functions[] = {
/*** GLX_VERSION_1_0 ***/
{ "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual },
{ "glXCopyContext", (__GLXextFuncPtr) glXCopyContext },
{ "glXCreateContext", (__GLXextFuncPtr) glXCreateContext },
{ "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap },
{ "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext },
{ "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap },
{ "glXGetConfig", (__GLXextFuncPtr) glXGetConfig },
{ "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext },
{ "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable },
{ "glXIsDirect", (__GLXextFuncPtr) glXIsDirect },
{ "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent },
{ "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension },
{ "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion },
{ "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers },
{ "glXUseXFont", (__GLXextFuncPtr) glXUseXFont },
{ "glXWaitGL", (__GLXextFuncPtr) glXWaitGL },
{ "glXWaitX", (__GLXextFuncPtr) glXWaitX },
/*** GLX_VERSION_1_1 ***/
{ "glXGetClientString", (__GLXextFuncPtr) glXGetClientString },
{ "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString },
{ "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString },
/*** GLX_VERSION_1_2 ***/
{ "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay },
/*** GLX_VERSION_1_3 ***/
{ "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig },
{ "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext },
{ "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer },
{ "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap },
{ "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow },
{ "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer },
{ "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap },
{ "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow },
{ "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable },
{ "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib },
{ "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs },
{ "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent },
{ "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig },
{ "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent },
{ "glXQueryContext", (__GLXextFuncPtr) glXQueryContext },
{ "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable },
{ "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent },
/*** GLX_VERSION_1_4 ***/
{ "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress },
/*** GLX_SGI_swap_control ***/
{ "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI },
/*** GLX_SGI_video_sync ***/
{ "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI },
{ "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI },
/*** GLX_SGI_make_current_read ***/
{ "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI },
{ "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI },
/*** GLX_SGIX_video_source ***/
#if defined(_VL_H)
{ "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX },
{ "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX },
#endif
/*** GLX_EXT_import_context ***/
{ "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT },
{ "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT },
{ "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT },
{ "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT },
{ "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT },
/*** GLX_SGIX_fbconfig ***/
{ "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX },
{ "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX },
{ "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX },
{ "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX },
{ "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX },
{ "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX },
/*** GLX_SGIX_pbuffer ***/
{ "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX },
{ "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX },
{ "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX },
{ "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX },
{ "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX },
/*** GLX_SGI_cushion ***/
{ "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI },
/*** GLX_SGIX_video_resize ***/
{ "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX },
{ "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX },
{ "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX },
{ "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX },
{ "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX },
/*** GLX_SGIX_dmbuffer **/
#if defined(_DM_BUFFER_H_)
{ "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX },
#endif
/*** GLX_SUN_get_transparent_index ***/
{ "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN },
/*** GLX_MESA_copy_sub_buffer ***/
{ "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA },
/*** GLX_MESA_pixmap_colormap ***/
{ "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA },
/*** GLX_MESA_release_buffers ***/
{ "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA },
/*** GLX_ARB_get_proc_address ***/
{ "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB },
/*** GLX_ARB_create_context ***/
{ "glXCreateContextAttribsARB", (__GLXextFuncPtr) glXCreateContextAttribsARB },
/*** GLX_EXT_texture_from_pixmap ***/
{ "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT },
{ "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT },
{ NULL, NULL } /* end of list */
};
/**
* Return address of named glX function, or NULL if not found.
*/
static __GLXextFuncPtr
_glxapi_get_proc_address(const char *funcName)
{
GLuint i;
for (i = 0; GLX_functions[i].Name; i++) {
if (strcmp(GLX_functions[i].Name, funcName) == 0)
return GLX_functions[i].Address;
}
return NULL;
}
PUBLIC __GLXextFuncPtr
glXGetProcAddressARB(const GLubyte *procName)
{
__GLXextFuncPtr f;
f = _glxapi_get_proc_address((const char *) procName);
if (f) {
return f;
}
f = (__GLXextFuncPtr) _mesa_glapi_get_proc_address((const char *) procName);
return f;
}
/* GLX 1.4 */
PUBLIC
void (*glXGetProcAddress(const GLubyte *procName))()
{
return glXGetProcAddressARB(procName);
}
@@ -0,0 +1,375 @@
/*
* Mesa 3-D graphics library
*
* Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
* Copyright (C) 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, 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.
*/
/**
* Fake implementation of glXUseXFont().
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <GL/glx.h>
#include "main/errors.h"
#include "dispatch.h"
#include "mesa/glapi/glapi/glapi.h"
/* Some debugging info. */
#if MESA_DEBUG
#include <ctype.h>
int debug_xfonts = 0;
static void
dump_char_struct(XCharStruct * ch, char *prefix)
{
printf("%slbearing = %d, rbearing = %d, width = %d\n",
prefix, ch->lbearing, ch->rbearing, ch->width);
printf("%sascent = %d, descent = %d, attributes = %u\n",
prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes);
}
static void
dump_font_struct(XFontStruct * font)
{
printf("ascent = %d, descent = %d\n", font->ascent, font->descent);
printf("char_or_byte2 = (%u,%u)\n",
font->min_char_or_byte2, font->max_char_or_byte2);
printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1);
printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False");
printf("default_char = %c (\\%03o)\n",
(char) (isprint(font->default_char) ? font->default_char : ' '),
font->default_char);
dump_char_struct(&font->min_bounds, "min> ");
dump_char_struct(&font->max_bounds, "max> ");
#if 0
for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) {
char prefix[8];
sprintf(prefix, "%d> ", c);
dump_char_struct(&font->per_char[c], prefix);
}
#endif
}
static void
dump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap)
{
unsigned int x, y;
printf(" ");
for (x = 0; x < 8 * width; x++)
printf("%o", 7 - (x % 8));
putchar('\n');
for (y = 0; y < height; y++) {
printf("%3o:", y);
for (x = 0; x < 8 * width; x++)
putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x %
8))))
? '*' : '.');
printf(" ");
for (x = 0; x < width; x++)
printf("0x%02x, ", bitmap[width * (height - y - 1) + x]);
putchar('\n');
}
}
#endif /* MESA_DEBUG */
/* Implementation. */
/* Fill a BITMAP with a character C from thew current font
in the graphics context GC. WIDTH is the width in bytes
and HEIGHT is the height in bits.
Note that the generated bitmaps must be used with
glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
Possible optimizations:
* use only one reusable pixmap with the maximum dimensions.
* draw the entire font into a single pixmap (careful with
proportional fonts!).
*/
/*
* Generate OpenGL-compatible bitmap.
*/
static void
fill_bitmap(Display * dpy, Window win, GC gc,
unsigned int width, unsigned int height,
int x0, int y0, unsigned int c, GLubyte * bitmap)
{
XImage *image;
unsigned int x, y;
Pixmap pixmap;
XChar2b char2b;
pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1);
XSetForeground(dpy, gc, 0);
XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height);
XSetForeground(dpy, gc, 1);
char2b.byte1 = (c >> 8) & 0xff;
char2b.byte2 = (c & 0xff);
XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1);
image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap);
if (image) {
/* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */
for (y = 0; y < height; y++)
for (x = 0; x < 8 * width; x++)
if (XGetPixel(image, x, y))
bitmap[width * (height - y - 1) + x / 8] |=
(1 << (7 - (x % 8)));
XDestroyImage(image);
}
XFreePixmap(dpy, pixmap);
}
/*
* determine if a given glyph is valid and return the
* corresponding XCharStruct.
*/
static XCharStruct *
isvalid(XFontStruct * fs, unsigned int which)
{
unsigned int rows, pages;
unsigned int byte1 = 0, byte2 = 0;
int i, valid = 1;
rows = fs->max_byte1 - fs->min_byte1 + 1;
pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
if (rows == 1) {
/* "linear" fonts */
if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which))
valid = 0;
}
else {
/* "matrix" fonts */
byte2 = which & 0xff;
byte1 = which >> 8;
if ((fs->min_char_or_byte2 > byte2) ||
(fs->max_char_or_byte2 < byte2) ||
(fs->min_byte1 > byte1) || (fs->max_byte1 < byte1))
valid = 0;
}
if (valid) {
if (fs->per_char) {
if (rows == 1) {
/* "linear" fonts */
return (fs->per_char + (which - fs->min_char_or_byte2));
}
else {
/* "matrix" fonts */
i = ((byte1 - fs->min_byte1) * pages) +
(byte2 - fs->min_char_or_byte2);
return (fs->per_char + i);
}
}
else {
return (&fs->min_bounds);
}
}
return (NULL);
}
PUBLIC void
glXUseXFont(Font font, int first, int count, int listbase)
{
Display *dpy;
Window win;
Pixmap pixmap;
GC gc;
XGCValues values;
unsigned long valuemask;
XFontStruct *fs;
GLint swapbytes, lsbfirst, rowlength;
GLint skiprows, skippixels, alignment;
unsigned int max_width, max_height, max_bm_width, max_bm_height;
GLubyte *bm;
int i;
dpy = glXGetCurrentDisplay();
if (!dpy)
return; /* I guess glXMakeCurrent wasn't called */
i = DefaultScreen(dpy);
win = RootWindow(dpy, i);
fs = XQueryFont(dpy, font);
if (!fs) {
_mesa_error(NULL, GL_INVALID_VALUE,
"Couldn't get font structure information");
return;
}
/* Allocate a bitmap that can fit all characters. */
max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
max_bm_width = (max_width + 7) / 8;
max_bm_height = max_height;
bm = malloc((max_bm_width * max_bm_height) * sizeof(GLubyte));
if (!bm) {
XFreeFontInfo(NULL, fs, 1);
_mesa_error(NULL, GL_OUT_OF_MEMORY,
"Couldn't allocate bitmap in glXUseXFont()");
return;
}
#if 0
/* get the page info */
pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2;
lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2;
rows = fs->max_byte1 - fs->min_byte1 + 1;
unsigned int first_char, last_char, pages, rows;
#endif
/* Save the current packing mode for bitmaps. */
CALL_GetIntegerv(GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, &swapbytes));
CALL_GetIntegerv(GET_DISPATCH(), (GL_UNPACK_LSB_FIRST, &lsbfirst));
CALL_GetIntegerv(GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, &rowlength));
CALL_GetIntegerv(GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, &skiprows));
CALL_GetIntegerv(GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, &skippixels));
CALL_GetIntegerv(GET_DISPATCH(), (GL_UNPACK_ALIGNMENT, &alignment));
/* Enforce a standard packing mode which is compatible with
fill_bitmap() from above. This is actually the default mode,
except for the (non)alignment. */
CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, GL_FALSE));
CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_LSB_FIRST, GL_FALSE));
CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, 0));
CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0));
CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0));
CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_ALIGNMENT, 1));
pixmap = XCreatePixmap(dpy, win, 10, 10, 1);
values.foreground = BlackPixel(dpy, DefaultScreen(dpy));
values.background = WhitePixel(dpy, DefaultScreen(dpy));
values.font = fs->fid;
valuemask = GCForeground | GCBackground | GCFont;
gc = XCreateGC(dpy, pixmap, valuemask, &values);
XFreePixmap(dpy, pixmap);
#if MESA_DEBUG
if (debug_xfonts)
dump_font_struct(fs);
#endif
for (i = 0; i < count; i++) {
unsigned int width, height, bm_width, bm_height;
GLfloat x0, y0, dx, dy;
XCharStruct *ch;
int x, y;
unsigned int c = first + i;
int list = listbase + i;
int valid;
/* check on index validity and get the bounds */
ch = isvalid(fs, c);
if (!ch) {
ch = &fs->max_bounds;
valid = 0;
}
else {
valid = 1;
}
#if MESA_DEBUG
if (debug_xfonts) {
char s[7];
sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c);
dump_char_struct(ch, s);
}
#endif
/* glBitmap()' parameters:
straight from the glXUseXFont(3) manpage. */
width = ch->rbearing - ch->lbearing;
height = ch->ascent + ch->descent;
x0 = -ch->lbearing;
y0 = ch->descent - 0; /* XXX used to subtract 1 here */
/* but that caused a conformace failure */
dx = ch->width;
dy = 0;
/* X11's starting point. */
x = -ch->lbearing;
y = ch->ascent;
/* Round the width to a multiple of eight. We will use this also
for the pixmap for capturing the X11 font. This is slightly
inefficient, but it makes the OpenGL part real easy. */
bm_width = (width + 7) / 8;
bm_height = height;
CALL_NewList(GET_DISPATCH(), (list, GL_COMPILE));
if (valid && (bm_width > 0) && (bm_height > 0)) {
memset(bm, '\0', bm_width * bm_height);
fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm);
CALL_Bitmap(GET_DISPATCH(), (width, height, x0, y0, dx, dy, bm));
#if MESA_DEBUG
if (debug_xfonts) {
printf("width/height = %u/%u\n", width, height);
printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height);
dump_bitmap(bm_width, bm_height, bm);
}
#endif
}
else {
CALL_Bitmap(GET_DISPATCH(), (0, 0, 0.0, 0.0, dx, dy, NULL));
}
CALL_EndList(GET_DISPATCH(), ());
}
free(bm);
XFreeFontInfo(NULL, fs, 1);
XFreeGC(dpy, gc);
/* Restore saved packing modes. */
CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, swapbytes));
CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_LSB_FIRST, lsbfirst));
CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, rowlength));
CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, skiprows));
CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, skippixels));
CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_ALIGNMENT, alignment));
}
@@ -0,0 +1,10 @@
# Copyright © 2017 Intel Corporation
# SPDX-License-Identifier: MIT
libxlib = static_library(
'xlib',
files('glx_api.c', 'glx_getproc.c', 'glx_usefont.c', 'xm_api.c', 'xm_st.c'),
gnu_symbol_visibility : 'hidden',
include_directories : [inc_include, inc_src, inc_gallium, inc_gallium_aux, inc_mesa],
dependencies : [dep_x11, dep_xext, dep_xcb, dep_glproto, idep_mesautil, idep_dispatch_h],
)
File diff suppressed because it is too large. Load diff
+399
View File
@@ -0,0 +1,399 @@
/*
* Mesa 3-D graphics library
*
* Copyright (C) 1999-2007 Brian Paul 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, 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.
*/
/* Sample Usage:
In addition to the usual X calls to select a visual, create a colormap
and create a window, you must do the following to use the X/Mesa interface:
1. Call XMesaCreateVisual() to make an XMesaVisual from an XVisualInfo.
2. Call XMesaCreateContext() to create an X/Mesa rendering context, given
the XMesaVisual.
3. Call XMesaCreateWindowBuffer() to create an XMesaBuffer from an X window
and XMesaVisual.
4. Call XMesaMakeCurrent() to bind the XMesaBuffer to an XMesaContext and
to make the context the current one.
5. Make gl* calls to render your graphics.
6. Use XMesaSwapBuffers() when double buffering to swap front/back buffers.
7. Before the X window is destroyed, call XMesaDestroyBuffer().
8. Before exiting, call XMesaDestroyVisual and XMesaDestroyContext.
*/
#ifndef XM_API_H
#define XM_API_H
#include <stdbool.h>
#include "main/glconfig.h" /* for gl_config */
#include "frontend/api.h"
#include "util/u_thread.h"
#include "frontend/xlibsw_api.h"
# include <X11/Xlib.h>
# include <X11/Xlibint.h>
# include <X11/Xutil.h>
struct st_context;
struct hud_context;
typedef struct xmesa_display *XMesaDisplay;
typedef struct xmesa_buffer *XMesaBuffer;
typedef struct xmesa_context *XMesaContext;
typedef struct xmesa_visual *XMesaVisual;
struct xmesa_display {
mtx_t mutex;
Display *display;
struct pipe_screen *screen;
struct pipe_frontend_screen *fscreen;
struct pipe_context *pipe;
};
/*
* Create a new X/Mesa visual.
* Input: display - X11 display
* visinfo - an XVisualInfo pointer
* rgb_flag - GL_TRUE = RGB mode,
* GL_FALSE = color index mode
* alpha_flag - alpha buffer requested?
* db_flag - GL_TRUE = double-buffered,
* GL_FALSE = single buffered
* stereo_flag - stereo visual?
* ximage_flag - GL_TRUE = use an XImage for back buffer,
* GL_FALSE = use an off-screen pixmap for back buffer
* depth_size - requested bits/depth values, or zero
* stencil_size - requested bits/stencil values, or zero
* accum_red_size - requested bits/red accum values, or zero
* accum_green_size - requested bits/green accum values, or zero
* accum_blue_size - requested bits/blue accum values, or zero
* accum_alpha_size - requested bits/alpha accum values, or zero
* num_samples - number of samples/pixel if multisampling, or zero
* level - visual level, usually 0
* visualCaveat - ala the GLX extension, usually GLX_NONE_EXT
* Return; a new XMesaVisual or 0 if error.
*/
extern XMesaVisual XMesaCreateVisual( Display *display,
XVisualInfo * visinfo,
GLboolean rgb_flag,
GLboolean alpha_flag,
GLboolean db_flag,
GLboolean stereo_flag,
GLboolean ximage_flag,
GLint depth_size,
GLint stencil_size,
GLint accum_red_size,
GLint accum_green_size,
GLint accum_blue_size,
GLint accum_alpha_size,
GLint num_samples,
GLint level,
GLint visualCaveat );
/*
* Destroy an XMesaVisual, but not the associated XVisualInfo.
*/
extern void XMesaDestroyVisual( XMesaVisual v );
/*
* Create a new XMesaContext for rendering into an X11 window.
*
* Input: visual - an XMesaVisual
* share_list - another XMesaContext with which to share display
* lists or NULL if no sharing is wanted.
* Return: an XMesaContext or NULL if error.
*/
extern XMesaContext XMesaCreateContext( XMesaVisual v,
XMesaContext share_list,
GLuint major, GLuint minor,
GLuint profileMask,
GLuint contextFlags);
/*
* Destroy a rendering context as returned by XMesaCreateContext()
*/
extern void XMesaDestroyContext( XMesaContext c );
/*
* Create an XMesaBuffer from an X window.
*/
extern XMesaBuffer XMesaCreateWindowBuffer( XMesaVisual v, Window w );
/*
* Create an XMesaBuffer from an X pixmap.
*/
extern XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v,
Pixmap p,
Colormap cmap );
/*
* Destroy an XMesaBuffer, but not the corresponding window or pixmap.
*/
extern void XMesaDestroyBuffer( XMesaBuffer b );
/*
* Return the XMesaBuffer handle which corresponds to an X drawable, if any.
*
* New in Mesa 2.3.
*/
extern XMesaBuffer XMesaFindBuffer( Display *dpy,
Drawable d );
/*
* Bind two buffers (read and draw) to a context and make the
* context the current one.
* New in Mesa 3.3
*/
extern GLboolean XMesaMakeCurrent2( XMesaContext c,
XMesaBuffer drawBuffer,
XMesaBuffer readBuffer );
/*
* Unbind the current context from its buffer.
*/
extern GLboolean XMesaUnbindContext( XMesaContext c );
/*
* Return a handle to the current context.
*/
extern XMesaContext XMesaGetCurrentContext( void );
/*
* Swap the front and back buffers for the given buffer. No action is
* taken if the buffer is not double buffered.
*/
extern void XMesaSwapBuffers( XMesaBuffer b );
/*
* Copy a sub-region of the back buffer to the front buffer.
*
* New in Mesa 2.6
*/
extern void XMesaCopySubBuffer( XMesaBuffer b,
int x,
int y,
int width,
int height );
/*
* Flush/sync a context
*/
extern void XMesaFlush( XMesaContext c );
/*
* Scan for XMesaBuffers whose window/pixmap has been destroyed, then free
* any memory used by that buffer.
*
* New in Mesa 2.3.
*/
extern void XMesaGarbageCollect( void );
/*
* Create a pbuffer.
* New in Mesa 4.1
*/
extern XMesaBuffer XMesaCreatePBuffer(XMesaVisual v, Colormap cmap,
unsigned int width, unsigned int height);
/*
* Texture from Pixmap
* New in Mesa 7.1
*/
extern void
XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer,
const int *attrib_list);
extern void
XMesaReleaseTexImage(Display *dpy, XMesaBuffer drawable, int buffer);
extern XMesaBuffer
XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
Colormap cmap,
int format, int target, int mipmap);
extern void
XMesaCopyContext(XMesaContext src, XMesaContext dst, unsigned long mask);
/***********************************************************************
*/
/**
* Visual inforation, derived from GLvisual.
* Basically corresponds to an XVisualInfo.
*/
struct xmesa_visual {
struct gl_config mesa_visual;/* Device independent visual parameters */
int screen, visualID, visualType;
Display *display; /* The X11 display */
XVisualInfo * visinfo; /* X's visual info (pointer to private copy) */
GLint BitsPerPixel; /* True bits per pixel for XImages */
GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */
struct st_visual stvis;
};
/**
* Context info, derived from st_context.
* Basically corresponds to a GLXContext.
*/
struct xmesa_context {
struct st_context *st;
XMesaVisual xm_visual; /** pixel format info */
XMesaBuffer xm_buffer; /** current drawbuffer */
XMesaBuffer xm_read_buffer; /** current readbuffer */
struct hud_context *hud;
};
/**
* Types of X/GLX drawables we might render into.
*/
typedef enum {
WINDOW, /* An X window */
GLXWINDOW, /* GLX window */
PIXMAP, /* GLX pixmap */
PBUFFER /* GLX Pbuffer */
} BufferType;
/**
* Framebuffer information, derived from.
* Basically corresponds to a GLXDrawable.
*/
struct xmesa_buffer {
struct pipe_frontend_drawable *drawable;
struct xlib_drawable ws;
GLboolean wasCurrent; /* was ever the current buffer? */
XMesaVisual xm_visual; /* the X/Mesa visual */
Colormap cmap; /* the X colormap */
BufferType type; /* window, pixmap, pbuffer or glxwindow */
GLboolean largestPbuffer; /**< for pbuffers */
GLboolean preservedContents; /**< for pbuffers */
XImage *tempImage;
unsigned long selectedEvents;/* for pbuffers only */
GC gc; /* scratch GC for span, line, tri drawing */
/* GLX_EXT_texture_from_pixmap */
GLint TextureTarget; /** GLX_TEXTURE_1D_EXT, for example */
GLint TextureFormat; /** GLX_TEXTURE_FORMAT_RGB_EXT, for example */
GLint TextureMipmap; /** 0 or 1 */
struct xmesa_buffer *Next; /* Linked list pointer: */
unsigned width, height;
};
extern const char *
xmesa_get_name(void);
extern int
xmesa_init(Display *dpy);
extern XMesaBuffer
xmesa_find_buffer(Display *dpy, Colormap cmap, XMesaBuffer notThis);
extern void
xmesa_get_window_size(Display *dpy, XMesaBuffer b,
GLuint *width, GLuint *height);
extern void
xmesa_notify_invalid_buffer(XMesaBuffer b);
extern void
xmesa_check_buffer_size(XMesaBuffer b);
extern void
xmesa_destroy_buffers_on_display(Display *dpy);
extern void
xmesa_close_display(Display *dpy);
static inline GLuint
xmesa_buffer_width(XMesaBuffer b)
{
return b->width;
}
static inline GLuint
xmesa_buffer_height(XMesaBuffer b)
{
return b->height;
}
bool xmesa_strict_invalidate(void);
#endif
+431
View File
@@ -0,0 +1,431 @@
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
*
* 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.
*
* Authors:
* Chia-I Wu <[email protected]>
*/
#include "xm_api.h"
#include "xm_st.h"
#include "util/u_inlines.h"
#include "util/u_atomic.h"
#include "util/u_memory.h"
#include "state_tracker/st_context.h"
struct xmesa_st_framebuffer {
struct pipe_frontend_drawable base;
XMesaDisplay display;
XMesaBuffer buffer;
struct pipe_screen *screen;
struct st_visual stvis;
enum pipe_texture_target target;
unsigned texture_width, texture_height, texture_mask;
struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
struct pipe_resource *display_resource;
};
static inline struct xmesa_st_framebuffer *
xmesa_st_framebuffer(struct pipe_frontend_drawable *drawable)
{
return (struct xmesa_st_framebuffer *)drawable;
}
/**
* Display (present) an attachment to the xlib_drawable of the framebuffer.
*/
static bool
xmesa_st_framebuffer_display(struct pipe_frontend_drawable *drawable,
struct st_context *st,
enum st_attachment_type statt,
unsigned nboxes,
struct pipe_box *box)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable);
struct pipe_resource *ptex = xstfb->textures[statt];
struct pipe_resource *pres;
struct pipe_context *pctx = st ? st->pipe : NULL;
if (!ptex)
return true;
pres = xstfb->display_resource;
/* (re)allocate the surface for the texture to be displayed */
if (!pres || pres != ptex) {
pipe_resource_reference(&xstfb->display_resource, ptex);
pres = xstfb->display_resource;
}
xstfb->screen->flush_frontbuffer(xstfb->screen, pctx, pres, 0, 0, &xstfb->buffer->ws, nboxes, box);
return true;
}
/**
* Copy the contents between the attachments.
*/
static void
xmesa_st_framebuffer_copy_textures(struct pipe_frontend_drawable *drawable,
enum st_attachment_type src_statt,
enum st_attachment_type dst_statt,
unsigned x, unsigned y,
unsigned width, unsigned height)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable);
struct pipe_resource *src_ptex = xstfb->textures[src_statt];
struct pipe_resource *dst_ptex = xstfb->textures[dst_statt];
struct pipe_box src_box;
struct pipe_context *pipe;
if (!src_ptex || !dst_ptex)
return;
pipe = xmesa_get_context(drawable);
u_box_2d(x, y, width, height, &src_box);
if (src_ptex && dst_ptex)
pipe->resource_copy_region(pipe, dst_ptex, 0, x, y, 0,
src_ptex, 0, &src_box);
}
/**
* Remove outdated textures and create the requested ones.
* This is a helper used during framebuffer validation.
*/
bool
xmesa_st_framebuffer_validate_textures(struct pipe_frontend_drawable *drawable,
unsigned width, unsigned height,
unsigned mask)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable);
struct pipe_resource templ;
enum st_attachment_type i;
/* remove outdated textures */
if (xstfb->texture_width != width || xstfb->texture_height != height) {
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_resource_reference(&xstfb->textures[i], NULL);
}
memset(&templ, 0, sizeof(templ));
templ.target = xstfb->target;
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
templ.array_size = 1;
templ.last_level = 0;
templ.nr_samples = xstfb->stvis.samples;
templ.nr_storage_samples = xstfb->stvis.samples;
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
enum pipe_format format;
unsigned bind;
/* the texture already exists or not requested */
if (xstfb->textures[i] || !(mask & (1 << i))) {
/* remember the texture */
if (xstfb->textures[i])
mask |= (1 << i);
continue;
}
switch (i) {
case ST_ATTACHMENT_FRONT_LEFT:
case ST_ATTACHMENT_BACK_LEFT:
case ST_ATTACHMENT_FRONT_RIGHT:
case ST_ATTACHMENT_BACK_RIGHT:
format = xstfb->stvis.color_format;
bind = PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_RENDER_TARGET;
break;
case ST_ATTACHMENT_DEPTH_STENCIL:
format = xstfb->stvis.depth_stencil_format;
bind = PIPE_BIND_DEPTH_STENCIL;
break;
default:
format = PIPE_FORMAT_NONE;
break;
}
if (format != PIPE_FORMAT_NONE) {
templ.format = format;
templ.bind = bind;
xstfb->textures[i] =
xstfb->screen->resource_create(xstfb->screen, &templ);
if (!xstfb->textures[i])
return false;
}
}
xstfb->texture_width = width;
xstfb->texture_height = height;
xstfb->texture_mask = mask;
return true;
}
/**
* Check that a framebuffer's attachments match the window's size.
*
* Called via pipe_frontend_drawable::validate()
*
* \param statts array of framebuffer attachments
* \param count number of framebuffer attachments in statts[]
* \param out returns resources for each of the attachments
*/
static bool
xmesa_st_framebuffer_validate(struct st_context *st,
struct pipe_frontend_drawable *drawable,
const enum st_attachment_type *statts,
unsigned count,
struct pipe_resource **out,
struct pipe_resource **resolve)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable);
unsigned statt_mask, new_mask, i;
bool resized;
bool ret;
/* build mask of ST_ATTACHMENT bits */
statt_mask = 0x0;
for (i = 0; i < count; i++)
statt_mask |= 1 << statts[i];
/* record newly allocated textures */
new_mask = statt_mask & ~xstfb->texture_mask;
/* If xmesa_strict_invalidate is not set, we will not yet have
* called XGetGeometry(). Do so here:
*/
if (!xmesa_strict_invalidate())
xmesa_check_buffer_size(xstfb->buffer);
resized = (xstfb->buffer->width != xstfb->texture_width ||
xstfb->buffer->height != xstfb->texture_height);
/* revalidate textures */
if (resized || new_mask) {
ret = xmesa_st_framebuffer_validate_textures(drawable,
xstfb->buffer->width, xstfb->buffer->height, statt_mask);
if (!ret)
return ret;
if (!resized) {
enum st_attachment_type back, front;
back = ST_ATTACHMENT_BACK_LEFT;
front = ST_ATTACHMENT_FRONT_LEFT;
/* copy the contents if front is newly allocated and back is not */
if ((statt_mask & (1 << back)) &&
(new_mask & (1 << front)) &&
!(new_mask & (1 << back))) {
xmesa_st_framebuffer_copy_textures(drawable, back, front,
0, 0, xstfb->texture_width, xstfb->texture_height);
}
}
}
for (i = 0; i < count; i++)
pipe_resource_reference(&out[i], xstfb->textures[statts[i]]);
if (resolve && drawable->visual->samples > 1) {
if (statt_mask & BITFIELD_BIT(ST_ATTACHMENT_FRONT_LEFT))
pipe_resource_reference(resolve, xstfb->display_resource);
else if (statt_mask & BITFIELD_BIT(ST_ATTACHMENT_BACK_LEFT))
pipe_resource_reference(resolve, xstfb->display_resource);
}
return true;
}
/**
* Called via pipe_frontend_drawable::flush_front()
*/
static bool
xmesa_st_framebuffer_flush_front(struct st_context *st,
struct pipe_frontend_drawable *drawable,
enum st_attachment_type statt)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable);
bool ret;
if (statt != ST_ATTACHMENT_FRONT_LEFT)
return false;
ret = xmesa_st_framebuffer_display(drawable, st, statt, 0, NULL);
if (ret && xmesa_strict_invalidate())
xmesa_check_buffer_size(xstfb->buffer);
return ret;
}
static uint32_t xmesa_drawable_ID = 0;
struct pipe_frontend_drawable *
xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b)
{
struct xmesa_st_framebuffer *xstfb;
assert(xmdpy->display == b->xm_visual->display);
xstfb = CALLOC_STRUCT(xmesa_st_framebuffer);
if (!xstfb) {
free(xstfb);
return NULL;
}
xstfb->display = xmdpy;
xstfb->buffer = b;
xstfb->screen = xmdpy->screen;
xstfb->stvis = b->xm_visual->stvis;
if (xstfb->screen->caps.npot_textures)
xstfb->target = PIPE_TEXTURE_2D;
else
xstfb->target = PIPE_TEXTURE_RECT;
xstfb->base.visual = &xstfb->stvis;
xstfb->base.flush_front = xmesa_st_framebuffer_flush_front;
xstfb->base.validate = xmesa_st_framebuffer_validate;
xstfb->base.ID = p_atomic_inc_return(&xmesa_drawable_ID);
xstfb->base.fscreen = xmdpy->fscreen;
p_atomic_set(&xstfb->base.stamp, 1);
return &xstfb->base;
}
void
xmesa_destroy_st_framebuffer(struct pipe_frontend_drawable *drawable)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable);
int i;
pipe_resource_reference(&xstfb->display_resource, NULL);
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_resource_reference(&xstfb->textures[i], NULL);
free(xstfb);
}
/**
* Return the pipe_surface which corresponds to the given
* framebuffer attachment.
*/
struct pipe_resource *
xmesa_get_framebuffer_resource(struct pipe_frontend_drawable *drawable,
enum st_attachment_type att)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable);
return xstfb->textures[att];
}
void
xmesa_swap_st_framebuffer(struct pipe_frontend_drawable *drawable)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable);
bool ret;
ret = xmesa_st_framebuffer_display(drawable, NULL, ST_ATTACHMENT_BACK_LEFT, 0, NULL);
if (ret) {
struct pipe_resource **front, **back, *tmp;
front = &xstfb->textures[ST_ATTACHMENT_FRONT_LEFT];
back = &xstfb->textures[ST_ATTACHMENT_BACK_LEFT];
/* swap textures only if the front texture has been allocated */
if (*front) {
tmp = *front;
*front = *back;
*back = tmp;
/* the current context should validate the buffer after swapping */
if (!xmesa_strict_invalidate())
xmesa_notify_invalid_buffer(xstfb->buffer);
}
if (xmesa_strict_invalidate())
xmesa_check_buffer_size(xstfb->buffer);
}
}
void
xmesa_copy_st_framebuffer(struct pipe_frontend_drawable *drawable,
enum st_attachment_type src,
enum st_attachment_type dst,
int x, int y, int w, int h)
{
xmesa_st_framebuffer_copy_textures(drawable, src, dst, x, y, w, h);
if (dst == ST_ATTACHMENT_FRONT_LEFT) {
struct pipe_box box = {};
box.x = x;
box.y = y;
box.width = w;
box.height = h;
xmesa_st_framebuffer_display(drawable, NULL, src, 1, &box);
}
}
struct pipe_resource*
xmesa_get_attachment(struct pipe_frontend_drawable *drawable,
enum st_attachment_type st_attachment)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable);
struct pipe_resource *res;
res = xstfb->textures[st_attachment];
return res;
}
struct pipe_context*
xmesa_get_context(struct pipe_frontend_drawable *drawable)
{
struct pipe_context *pipe;
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(drawable);
pipe = xstfb->display->pipe;
if (!pipe) {
pipe = xstfb->screen->context_create(xstfb->screen, NULL, 0);
if (!pipe)
return NULL;
xstfb->display->pipe = pipe;
}
return pipe;
}
+66
View File
@@ -0,0 +1,66 @@
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
*
* 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.
*
* Authors:
* Chia-I Wu <[email protected]>
*/
#ifndef _XM_ST_H_
#define _XM_ST_H_
#include "util/compiler.h"
#include "frontend/api.h"
#include "xm_api.h"
struct pipe_frontend_drawable *
xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b);
void
xmesa_destroy_st_framebuffer(struct pipe_frontend_drawable *drawable);
struct pipe_resource *
xmesa_get_framebuffer_resource(struct pipe_frontend_drawable *drawable,
enum st_attachment_type att);
void
xmesa_swap_st_framebuffer(struct pipe_frontend_drawable *drawable);
void
xmesa_copy_st_framebuffer(struct pipe_frontend_drawable *drawable,
enum st_attachment_type src,
enum st_attachment_type dst,
int x, int y, int w, int h);
struct pipe_resource*
xmesa_get_attachment(struct pipe_frontend_drawable *drawable,
enum st_attachment_type st_attachment);
struct pipe_context*
xmesa_get_context(struct pipe_frontend_drawable* drawable);
bool
xmesa_st_framebuffer_validate_textures(struct pipe_frontend_drawable *drawable,
unsigned width, unsigned height,
unsigned mask);
#endif /* _XM_ST_H_ */
+2
View File
@@ -0,0 +1,2 @@
[*.{c,h,cpp,hpp}]
indent_style = tab
+378
View File
@@ -0,0 +1,378 @@
/*
* Copyright 2012-2014, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski, [email protected]
* Alexander von Gluck IV, [email protected]
*/
#include "hgl_context.h"
#include <stdio.h>
#include "util/format/u_formats.h"
#include "util/u_atomic.h"
#include "util/format/u_format.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "state_tracker/st_context.h"
#if MESA_DEBUG
# define TRACE(x...) printf("hgl:frontend: " x)
# define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
#else
# define TRACE(x...)
# define CALLED()
#endif
#define ERROR(x...) printf("hgl:frontend: " x)
// Perform a safe void to hgl_context cast
static inline struct hgl_context*
hgl_st_context(struct st_context *st)
{
struct hgl_context* context;
assert(st);
context = (struct hgl_context*)st->frontend_context;
assert(context);
return context;
}
// Perform a safe void to hgl_buffer cast
static struct hgl_buffer*
hgl_st_framebuffer(struct pipe_frontend_drawable *drawable)
{
struct hgl_buffer* buffer;
assert(drawable);
buffer = (struct hgl_buffer*)drawable;
assert(buffer);
return buffer;
}
static bool
hgl_st_framebuffer_flush_front(struct st_context *st,
struct pipe_frontend_drawable* drawable, enum st_attachment_type statt)
{
CALLED();
struct hgl_buffer* buffer = hgl_st_framebuffer(drawable);
struct pipe_resource* ptex = buffer->textures[statt];
if (statt != ST_ATTACHMENT_FRONT_LEFT)
return false;
if (!ptex)
return true;
// TODO: pipe_context here??? Might be needed for hw renderers
buffer->screen->flush_frontbuffer(buffer->screen, NULL, ptex, 0, 0,
buffer->winsysContext, 0, NULL);
return true;
}
static bool
hgl_st_framebuffer_validate_textures(struct pipe_frontend_drawable *drawable,
unsigned width, unsigned height, unsigned mask)
{
struct hgl_buffer* buffer;
enum st_attachment_type i;
struct pipe_resource templat;
CALLED();
buffer = hgl_st_framebuffer(drawable);
if (buffer->width != width || buffer->height != height) {
TRACE("validate_textures: size changed: %d, %d -> %d, %d\n",
buffer->width, buffer->height, width, height);
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_resource_reference(&buffer->textures[i], NULL);
}
memset(&templat, 0, sizeof(templat));
templat.target = buffer->target;
templat.width0 = width;
templat.height0 = height;
templat.depth0 = 1;
templat.array_size = 1;
templat.last_level = 0;
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
enum pipe_format format;
unsigned bind;
if (((1 << i) & buffer->visual.buffer_mask) && buffer->textures[i] == NULL) {
switch (i) {
case ST_ATTACHMENT_FRONT_LEFT:
case ST_ATTACHMENT_BACK_LEFT:
case ST_ATTACHMENT_FRONT_RIGHT:
case ST_ATTACHMENT_BACK_RIGHT:
format = buffer->visual.color_format;
bind = PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_RENDER_TARGET;
break;
case ST_ATTACHMENT_DEPTH_STENCIL:
format = buffer->visual.depth_stencil_format;
bind = PIPE_BIND_DEPTH_STENCIL;
break;
default:
format = PIPE_FORMAT_NONE;
bind = 0;
break;
}
if (format != PIPE_FORMAT_NONE) {
templat.format = format;
templat.bind = bind;
TRACE("resource_create(%d, %d, %d)\n", i, format, bind);
buffer->textures[i] = buffer->screen->resource_create(buffer->screen,
&templat);
if (!buffer->textures[i])
return false;
}
}
}
buffer->width = width;
buffer->height = height;
buffer->mask = mask;
return true;
}
/**
* Called by the st manager to validate the framebuffer (allocate
* its resources).
*/
static bool
hgl_st_framebuffer_validate(struct st_context *st,
struct pipe_frontend_drawable *drawable, const enum st_attachment_type *statts,
unsigned count, struct pipe_resource **out, struct pipe_resource **resolve)
{
struct hgl_buffer* buffer;
unsigned stAttachmentMask, newMask;
unsigned i;
bool resized;
CALLED();
buffer = hgl_st_framebuffer(drawable);
// Build mask of current attachments
stAttachmentMask = 0;
for (i = 0; i < count; i++)
stAttachmentMask |= 1 << statts[i];
newMask = stAttachmentMask & ~buffer->mask;
resized = (buffer->width != buffer->newWidth)
|| (buffer->height != buffer->newHeight);
if (resized || newMask) {
bool ret;
TRACE("%s: resize event. old: %d x %d; new: %d x %d\n", __func__,
buffer->width, buffer->height, buffer->newWidth, buffer->newHeight);
ret = hgl_st_framebuffer_validate_textures(drawable,
buffer->newWidth, buffer->newHeight, stAttachmentMask);
if (!ret)
return ret;
}
for (i = 0; i < count; i++)
pipe_resource_reference(&out[i], buffer->textures[statts[i]]);
return true;
}
static int
hgl_st_manager_get_param(struct pipe_frontend_screen *fscreen, enum st_manager_param param)
{
CALLED();
switch (param) {
case ST_MANAGER_BROKEN_INVALIDATE:
return 1;
}
return 0;
}
static uint32_t hgl_fb_ID = 0;
/**
* Create new framebuffer
*/
struct hgl_buffer *
hgl_create_st_framebuffer(struct hgl_display *display, struct st_visual* visual, void *winsysContext)
{
struct hgl_buffer *buffer;
CALLED();
// Our requires before creating a framebuffer
assert(display);
assert(visual);
buffer = CALLOC_STRUCT(hgl_buffer);
assert(buffer);
// Prepare our buffer
buffer->visual = *visual;
buffer->screen = display->fscreen->screen;
buffer->winsysContext = winsysContext;
if (buffer->screen->caps.npot_textures)
buffer->target = PIPE_TEXTURE_2D;
else
buffer->target = PIPE_TEXTURE_RECT;
// Prepare our frontend interface
buffer->base.flush_front = hgl_st_framebuffer_flush_front;
buffer->base.validate = hgl_st_framebuffer_validate;
buffer->base.visual = &buffer->visual;
p_atomic_set(&buffer->base.stamp, 1);
buffer->base.ID = p_atomic_inc_return(&hgl_fb_ID);
buffer->base.fscreen = display->fscreen;
return buffer;
}
void
hgl_destroy_st_framebuffer(struct hgl_buffer *buffer)
{
CALLED();
int i;
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_resource_reference(&buffer->textures[i], NULL);
FREE(buffer);
}
struct hgl_context*
hgl_create_context(struct hgl_display *display, struct st_visual* visual, struct st_context* shared)
{
struct hgl_context* context = CALLOC_STRUCT(hgl_context);
assert(context);
context->display = display;
struct st_context_attribs attribs;
memset(&attribs, 0, sizeof(attribs));
attribs.options.force_glsl_extensions_warn = false;
attribs.profile = API_OPENGL_COMPAT;
attribs.visual = *visual;
attribs.major = 1;
attribs.minor = 0;
enum st_context_error result;
context->st = st_api_create_context(display->fscreen, &attribs, &result, shared);
if (context->st == NULL) {
FREE(context);
return NULL;
}
assert(!context->st->frontend_context);
context->st->frontend_context = (void*)context;
struct st_context *stContext = (struct st_context*)context->st;
return context;
}
void
hgl_destroy_context(struct hgl_context* context)
{
if (context->st) {
st_context_flush(context->st, 0, NULL, NULL, NULL);
st_destroy_context(context->st);
}
FREE(context);
}
void
hgl_get_st_visual(struct st_visual* visual, ulong options)
{
CALLED();
assert(visual);
// Determine color format
if ((options & HGL_INDEX) != 0) {
// Index color
visual->color_format = PIPE_FORMAT_B5G6R5_UNORM;
// TODO: Indexed color depth buffer?
visual->depth_stencil_format = PIPE_FORMAT_NONE;
} else {
// RGB color
visual->color_format = (options & HGL_ALPHA)
? PIPE_FORMAT_BGRA8888_UNORM : PIPE_FORMAT_BGRX8888_UNORM;
// TODO: Determine additional stencil formats
visual->depth_stencil_format = (options & HGL_DEPTH)
? PIPE_FORMAT_Z24_UNORM_S8_UINT : PIPE_FORMAT_NONE;
}
visual->accum_format = (options & HGL_ACCUM)
? PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
visual->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
if ((options & HGL_DOUBLE) != 0) {
TRACE("double buffer enabled\n");
visual->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
}
#if 0
if ((options & HGL_STEREO) != 0) {
visual->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
if ((options & HGL_DOUBLE) != 0)
visual->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
}
#endif
if ((options & HGL_DEPTH) || (options & HGL_STENCIL))
visual->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
TRACE("%s: Visual color format: %s\n", __func__,
util_format_name(visual->color_format));
}
struct hgl_display*
hgl_create_display(struct pipe_screen* screen)
{
struct hgl_display* display;
display = CALLOC_STRUCT(hgl_display);
assert(display);
display->fscreen = CALLOC_STRUCT(pipe_frontend_screen);
assert(display->fscreen);
display->fscreen->screen = screen;
display->fscreen->get_param = hgl_st_manager_get_param;
// display->fscreen->st_screen is used by llvmpipe
return display;
}
void
hgl_destroy_display(struct hgl_display *display)
{
st_screen_destroy(display->fscreen);
FREE(display->fscreen);
FREE(display);
}
+96
View File
@@ -0,0 +1,96 @@
/*
* Copyright 2009-2023, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Alexander von Gluck IV, [email protected]
*/
#ifndef HGL_CONTEXT_H
#define HGL_CONTEXT_H
#include "util/u_thread.h"
#include "util/format/u_formats.h"
#include "util/compiler.h"
#include "pipe/p_screen.h"
#include "frontend/api.h"
// visual options
#define HGL_RGB 0
#define HGL_INDEX 1
#define HGL_SINGLE 0
#define HGL_DOUBLE 2
#define HGL_DIRECT 0
#define HGL_INDIRECT 4
#define HGL_ACCUM 8
#define HGL_ALPHA 16
#define HGL_DEPTH 32
#define HGL_OVERLAY 64
#define HGL_UNDERLAY 128
#define HGL_STENCIL 512
#define HGL_SHARE_CONTEXT 1024
#ifdef __cplusplus
extern "C" {
#endif
#define CONTEXT_MAX 32
typedef int64 context_id;
struct hgl_buffer
{
struct pipe_frontend_drawable base;
struct st_visual visual;
unsigned width;
unsigned height;
unsigned newWidth;
unsigned newHeight;
unsigned mask;
struct pipe_screen* screen;
void* winsysContext;
enum pipe_texture_target target;
struct pipe_resource* textures[ST_ATTACHMENT_COUNT];
};
struct hgl_display
{
mtx_t mutex;
struct pipe_frontend_screen *fscreen;
};
struct hgl_context
{
struct hgl_display* display;
struct st_context* st;
};
// hgl framebuffer
struct hgl_buffer* hgl_create_st_framebuffer(struct hgl_display *display, struct st_visual* visual, void *winsysContext);
void hgl_destroy_st_framebuffer(struct hgl_buffer *buffer);
struct hgl_context* hgl_create_context(struct hgl_display *display, struct st_visual* visual, struct st_context* shared);
void hgl_destroy_context(struct hgl_context* context);
// hgl visual
void hgl_get_st_visual(struct st_visual* visual, ulong options);
// hgl display
struct hgl_display* hgl_create_display(struct pipe_screen* screen);
void hgl_destroy_display(struct hgl_display *display);
#ifdef __cplusplus
}
#endif
#endif /* HGL_CONTEXT_H */
+17
View File
@@ -0,0 +1,17 @@
# Copyright © 2017 Dylan Baker
# SPDX-License-Identifier: MIT
files_libsthgl = files(
'hgl_context.h',
'hgl.c',
)
libsthgl = static_library(
'sthgl',
files_libsthgl,
include_directories : [
inc_include, inc_util, inc_mesa, inc_src,
inc_gallium, inc_gallium_aux
],
gnu_symbol_visibility : 'hidden',
)
@@ -0,0 +1,39 @@
# Run one GLES 2 test to check the version and renderer
[[deqp]]
deqp = "/data/deqp/deqp-gles2"
caselists = ["/data/deqp/gles2-main.txt"]
include = [ "dEQP-GLES2.info.renderer" ]
deqp_args = [
"--deqp-surface-width=256",
"--deqp-surface-height=256",
"--deqp-surface-type=pbuffer",
"--deqp-gl-config-name=rgba8888d24s8ms0",
"--deqp-visibility=hidden"
]
version_check = "GL ES 3.1.*ANGLE 2.1.1 git"
renderer_check = "ANGLE.*llvmpipe"
# AHB test set
[[deqp]]
deqp = "/data/deqp/deqp-vk"
caselists = ["/data/deqp/vk-main.txt"]
include = ["dEQP-VK.api.external.memory.android_hardware_buffer.*"]
renderer_check = "llvmpipe"
# Vulkan WSI test set
[[deqp]]
deqp = "/data/deqp/deqp-vk"
caselists = ["/data/deqp/vk-main.txt"]
include = ["dEQP-VK.wsi.android.*"]
# EGL test set
[[deqp]]
deqp = "/data/deqp/deqp-egl-android"
caselists = ["/data/deqp/egl-main.txt"]
deqp_args = [
"--deqp-surface-width=256",
"--deqp-surface-height=256",
"--deqp-surface-type=pbuffer",
"--deqp-gl-config-name=rgba8888d24s8ms0",
"--deqp-visibility=hidden"
]
@@ -0,0 +1,5 @@
[[deqp]]
deqp = "/deqp-vk/external/vulkancts/modules/vulkan/deqp-vk"
caselists = ["/deqp-vk/mustpass/vk-main.txt"]
tests_per_group = 1
renderer_check = "llvmpipe"
@@ -0,0 +1,17 @@
[[deqp]]
deqp = "/deqp-vk/external/vulkancts/modules/vulkan/deqp-vk"
caselists = ["/deqp-vk/mustpass/vk-main.txt"]
renderer_check = "llvmpipe"
tests_per_group = 5000
fraction = 3
# Do some nir clone/serialize validation, but not on the whole run.
[[deqp]]
deqp = "/deqp-vk/external/vulkancts/modules/vulkan/deqp-vk"
caselists = ["/deqp-vk/mustpass/vk-main.txt"]
renderer_check = "llvmpipe"
tests_per_group = 5000
fraction = 100
prefix = "nir-stress="
[deqp.env]
NIR_DEBUG = "clone,serialize"
@@ -0,0 +1,44 @@
.lavapipe-rules:
stage: software-renderer
rules:
- !reference [.test, rules]
- !reference [.vulkan-rules, rules]
- !reference [.gallium-core-rules, rules]
- changes: &lavapipe_file_list
- src/gallium/drivers/llvmpipe/*
- src/gallium/frontends/lavapipe/*
- src/gallium/frontends/lavapipe/ci/gitlab-ci.yml
- src/gallium/frontends/lavapipe/ci/gitlab-ci-inc.yml
- src/gallium/frontends/lavapipe/ci/deqp-$DEQP_SUITE.toml
- src/gallium/frontends/lavapipe/ci/$GPU_VERSION-fails.txt
- src/gallium/frontends/lavapipe/ci/$GPU_VERSION-flakes.txt
- src/gallium/frontends/lavapipe/ci/$GPU_VERSION-skips.txt
- src/gallium/frontends/lavapipe/ci/$VK_DRIVER-skips.txt
- src/gallium/frontends/lavapipe/ci/$GALLIUM_DRIVER-skips.txt
- src/gallium/frontends/lavapipe/ci/$DRIVER_NAME-skips.txt
- src/gallium/frontends/lavapipe/ci/$PIGLIT_TRACES_FILE
- src/gallium/frontends/lavapipe/ci/$REPLAY_CONFIG
- src/gallium/winsys/sw/**/*
- src/gallium/auxiliary/draw/**/*
- src/gallium/auxiliary/gallivm/**/*
when: on_success
.lavapipe-manual-rules:
stage: software-renderer-nightly
extends: .no-auto-retry
rules:
- !reference [.test, rules]
- !reference [.vulkan-manual-rules, rules]
- !reference [.gl-manual-rules, rules]
- changes: *lavapipe_file_list
when: manual
.lavapipe-test:
extends:
- .test-vk
tags:
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64
variables:
VK_DRIVER: lvp
LVP_POISON_MEMORY: "1"
HWCI_START_WESTON: 1
@@ -0,0 +1,98 @@
include:
- local: 'src/gallium/frontends/lavapipe/ci/gitlab-ci-inc.yml'
lavapipe-vkcts:
timeout: 15m
variables:
DEQP_SUITE: lvp
GPU_VERSION: lvp
DEQP_FRACTION: 9
extends:
- .deqp-test
- .lavapipe-test
- .lavapipe-rules
lavapipe-vkcts-full:
extends:
- lavapipe-vkcts
- .lavapipe-manual-rules
timeout: 2h # base runtime = 1h15m
variables:
DEQP_FRACTION: 1
lavapipe-vkcts-asan:
timeout: 15m
extends:
- .deqp-test
- .lavapipe-test
- .lavapipe-rules
variables:
DEQP_SUITE: lvp-asan
GPU_VERSION: lvp-asan
DEQP_FORCE_ASAN: 1
S3_ARTIFACT_NAME: mesa-x86_64-asan-debugoptimized
DEQP_FRACTION: 1000
needs:
- job: debian/x86_64_test-vk
optional: true
- job: debian-x86_64-asan
lavapipe-vkcts-asan-full:
extends:
- lavapipe-vkcts-asan
- .lavapipe-manual-rules
timeout: 2h
variables:
DEQP_FRACTION: 40
lavapipe-vkd3d:
extends:
- .lavapipe-test
- .lavapipe-rules
- .test-vkd3d-proton
timeout: 15m # base runtime = 8m
variables:
GPU_VERSION: lvp
script: install/vkd3d-runner.sh
lavapipe-traces:
variables:
REPLAY_CONFIG: traces-lavapipe.toml
GPU_VERSION: lvp
extends:
- .test-vkd3d-proton
- .traces-test
- .test-wine
- .lavapipe-test
- .lavapipe-rules
script: |
export LD_LIBRARY_PATH="$CI_PROJECT_DIR/install/lib"
export LIBGL_DRIVERS_PATH="$CI_PROJECT_DIR/install/lib/dri"
section_start weston "weston: prepare"
. "$CI_PROJECT_DIR/install/common/weston.sh"
section_end weston
$HWCI_TEST_SCRIPT
android-angle-lavapipe:
variables:
CUTTLEFISH_GPU_MODE: mesa_swrast_guest_angle
DEQP_SUITE: android-angle-lavapipe
GPU_VERSION: lvp-android-angle
VK_DRIVER: lvp
timeout: 15m
extends:
- .test-android
- .lavapipe-rules
- .test-angle
android-angle-lavapipe-cts-full:
variables:
CUTTLEFISH_GPU_MODE: mesa_swrast_guest_angle
GPU_VERSION: lvp-android-angle
VK_DRIVER: lvp
timeout: 45m
extends:
- .test-android
- .test-android-cts
- .lavapipe-manual-rules
- .test-angle
@@ -0,0 +1,11 @@
x86_64 CtsGraphicsTestCases
x86_64 CtsNativeHardwareTestCases
x86_64 CtsSkQPTestCases
# When adding more entries like the ones below, remember to add the
# respective modules (e.g. CtsDeqpTestCases) to ANDROID_CTS_MODULES in
# .gitlab-ci/container/build-android-cts.sh if they are not already there.
# And update DEBIAN_TEST_ANDROID_TAG in .gitlab-ci/image-tags.yml if needed.
#x86_64 CtsDeqpTestCases dEQP-VK.wsi.android.*
#x86_64 CtsDeqpTestCases dEQP-VK.api.external.memory.android_hardware_buffer.*
@@ -0,0 +1,25 @@
### CtsGraphicsTestCases
# Failures
x86_64 CtsGraphicsTestCases android.graphics.cts.VulkanFeaturesTest#testAndroidBaselineProfile2021Support
x86_64 CtsGraphicsTestCases android.graphics.drawable.cts.AnimatedVectorDrawableParameterizedTest
# New failures with Android 16
x86_64 CtsGraphicsTestCases android.graphics.fonts.SystemFontsTest#testFontsFallbackUnreadable[0]
x86_64 CtsGraphicsTestCases android.graphics.fonts.SystemFontsTest#testAvailableFonts_ReadOnlyFile[0]
# New flakes with Android 16
x86_64 CtsGraphicsTestCases android.graphics.cts.DynamicColorsTest
### CtsSkQPTestCases
# Failures
x86_64 CtsSkQPTestCases org.skia.skqp.SkQPRunner#UnitTest_BulkTextureRectTest
x86_64 CtsSkQPTestCases org.skia.skqp.SkQPRunner#UnitTest_ES2BlendWithNoTexture
# New failures with VK_EXT_blend_operation_advanced
x86_64 CtsSkQPTestCases org.skia.skqp.SkQPRunner#UnitTest_BlendRequiringDstReadWithLargeCoordinates
x86_64 CtsSkQPTestCases org.skia.skqp.SkQPRunner#UnitTest_SkRuntimeBlender_GPU
# Flaky, can hit null pointer dereference possibly due to race condition of lavapipe queue thread and the app calling thread
x86_64 CtsSkQPTestCases org.skia.skqp.SkQPRunner#UnitTest_SurfaceResolveTest
@@ -0,0 +1,145 @@
# Lavapipe bug with ANGLE
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_render_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_render_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_render_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_render_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_render_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_render_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_clear_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_clear_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_clear_render_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_clear_render_even_none,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_clear_render_even_render,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_clear_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_clear_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_clear_even_render,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_clear_even_render_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_clear_even_render_render,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_even_none,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_even_render,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_render_even_none,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_render_even_render,Fail
dEQP-EGL.functional.buffer_age.preserve.no_resize.odd_render_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_clear_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_clear_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_clear_render_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_clear_render_even_none,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_clear_render_even_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_clear_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_clear_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_clear_even_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_clear_even_render_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_clear_even_render_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_even_none,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_even_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_render_even_none,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_render_even_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_after_swap.odd_render_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_clear_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_clear_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_clear_render_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_clear_render_even_none,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_clear_render_even_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_clear_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_clear_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_clear_even_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_clear_even_render_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_clear_even_render_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_even_none,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_even_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_render_even_none,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_render_even_render,Fail
dEQP-EGL.functional.buffer_age.preserve.resize_before_swap.odd_render_render_even_render_render,Fail
dEQP-EGL.functional.fence_sync.valid.egl_fence_persistent_buffer,Fail
dEQP-EGL.functional.partial_update.odd_clear_render_even_clear,Fail
dEQP-EGL.functional.partial_update.odd_clear_render_even_clear_clear,Fail
dEQP-EGL.functional.partial_update.odd_clear_render_even_clear_render,Fail
dEQP-EGL.functional.partial_update.odd_clear_render_even_none,Fail
dEQP-EGL.functional.partial_update.odd_clear_render_even_render,Fail
dEQP-EGL.functional.partial_update.odd_clear_render_even_render_render,Fail
dEQP-EGL.functional.partial_update.odd_render_clear_even_clear,Fail
dEQP-EGL.functional.partial_update.odd_render_clear_even_clear_clear,Fail
dEQP-EGL.functional.partial_update.odd_render_clear_even_clear_render,Fail
dEQP-EGL.functional.partial_update.odd_render_clear_even_none,Fail
dEQP-EGL.functional.partial_update.odd_render_clear_even_render,Fail
dEQP-EGL.functional.partial_update.odd_render_clear_even_render_clear,Fail
dEQP-EGL.functional.partial_update.odd_render_clear_even_render_render,Fail
dEQP-EGL.functional.partial_update.odd_render_even_clear,Fail
dEQP-EGL.functional.partial_update.odd_render_even_none,Fail
dEQP-EGL.functional.partial_update.odd_render_even_render,Fail
dEQP-EGL.functional.partial_update.odd_render_render_even_clear_clear,Fail
dEQP-EGL.functional.partial_update.odd_render_render_even_none,Fail
dEQP-EGL.functional.partial_update.odd_render_render_even_render,Fail
dEQP-EGL.functional.partial_update.odd_render_render_even_render_render,Fail
dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.uniform_block.compute,Crash
dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.uniform_block.fragment,Crash
dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.uniform_block.vertex_and_fragment,Crash
dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.local_array.compute,Crash
dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.shader_storage_block.compute,Crash
dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.uniform_block.compute,Crash
@@ -0,0 +1,50 @@
# New CTS failures in 1.3.5.0
dEQP-VK.binding_model.descriptor_buffer.basic.limits,Fail
# New CTS failures in 1.3.6.3
dEQP-VK.pipeline.monolithic.extended_dynamic_state.two_draws_dynamic.tess_domain_origin_lower_left,Fail
dEQP-VK.ray_tracing_pipeline.acceleration_structures.format.cpu_built.r32g32_sfloat.nopadding.index_uint16,Fail
# New CTS failures in 1.3.7.0
dEQP-VK.descriptor_indexing.sampled_image,Fail
dEQP-VK.pipeline.shader_object_unlinked_spirv.logic_op.r16g16b16a16_uint.equivalent,Fail
dEQP-VK.pipeline.fast_linked_library.logic_op.r32g32b32a32_uint.and_inverted,Fail
dEQP-VK.pipeline.pipeline_library.logic_op.r8g8b8a8_uint.invert,Fail
dEQP-VK.pipeline.shader_object_linked_spirv.bind_buffers_2.maintenance5.robustness2.triangle_strip.buffers9.stride_offset_rnd543.true_size.beyond_size,Fail
dEQP-VK.ray_tracing_pipeline.acceleration_structures.format.gpu_built.r8g8b8a8_snorm.nopadding.index_uint16,Fail
# New CTS failures in 1.3.8.0
dEQP-VK.pipeline.shader_object_linked_spirv.logic_op.r8g8_uint.or_reverse,Fail
# New CTS failures in 1.3.8.2
dEQP-VK.pipeline.monolithic.logic_op.r32g32_uint.clear,Fail
dEQP-VK.dgc.ext.graphics.draw.token_draw.shader_objects_with_geom_preprocess_same_state_cmd_buffer_unordered,Fail
# New fails in 1.4.1.0
dEQP-VK.dgc.ext.compute.smoke.1024_sequences_device_local_from_host_preprocess_state_separate_universal_queue,Fail
dEQP-VK.dynamic_state.monolithic.compute_transfer.single.compute.vertex_input_binding_stride.after,Fail
# New fails in 1.4.1.1
dEQP-VK.pipeline.pipeline_library.bind_buffers_2.maintenance5.robustness2.triangle_list.buffers9.stride_offset_rnd654.true_size.beyond_size,Fail
# New fails from nightly job
dEQP-VK.image.queue_transfer.3d.4x3x1.r64g64b64a64_sint,Crash
dEQP-VK.image.subresource_layout.2d.1_level.r64g64b64a64_sint_offset,Crash
dEQP-VK.image.subresource_layout.3d.2_levels.r64g64b64a64_sint,Crash
dEQP-VK.pipeline.pipeline_library.extended_dynamic_state.two_draws_static.tess_domain_origin_upper_left,Fail
dEQP-VK.pipeline.shader_object_unlinked_binary.bind_buffers_2.maintenance5.robustness2.triangle_list.buffers9.stride_offset_rnd654.true_size.beyond_size,Fail
dEQP-VK.pipeline.shader_object_unlinked_spirv.bind_buffers_2.maintenance5.robustness2.triangle_list.buffers5.stride_offset_rnd654.true_size.beyond_size,Fail
dEQP-VK.shader_object.misc.state.pipeline.vert_tess_frag.depth.clamp,Fail
dEQP-VK.shader_object.misc.state.pipeline.vert_tess_geom_frag.rasterization_discard.disabled,Fail
# New failures with VKCTS 1.4.4.0
dEQP-VK.pipeline.monolithic.extended_dynamic_state.cmd_buffer_start.large_stride_with_offset_and_padding,Fail
dEQP-VK.pipeline.pipeline_library.extended_dynamic_state.before_good_static.tess_domain_origin_upper_left,Fail
dEQP-VK.pipeline.shader_object_linked_spirv.bind_buffers_2.maintenance5.robustness2.triangle_list.buffers9.stride_offset_rnd654.true_size.beyond_size,Fail
dEQP-VK.pipeline.shader_object_unlinked_spirv.extended_dynamic_state.cmd_buffer_start.stride_with_offset_and_padding,Fail
dEQP-VK.shader_object.misc.state.pipeline.vert_tess_frag.color_write.true,Fail
# VKCTS 1.4.4.2 -> 1.4.5.3 uprev
dEQP-VK.dgc.ext.graphics.misc.mix_normal_dgc_preprocess_with_vbo_token,Fail
@@ -0,0 +1,14 @@
# Lots of timeouts
dEQP-VK.texture.filtering.*.combinations.*
dEQP-VK.binding_model.buffer_device_address.set3.depth3.*
dEQP-VK.ssbo.layout.*instance_array
dEQP-VK.ssbo.layout.random.8bit.all_per_block_buffers.6
dEQP-VK.ssbo.layout.random.all_shared_buffer.5
dEQP-VK.tessellation.invariance.*
dEQP-VK.subgroups.ballot_broadcast.compute.subgroupbroadcast.*
dEQP-VK.ssbo.layout.3_level_unsized_array.scalar.*
dEQP-VK.ssbo.layout.3_level_array.scalar.*
dEQP-VK.ssbo.phys.layout.unsized_struct_array.per_block_buffer.*_instance_array_comp_access_store_cols
# Leaky in VKCTS 1.4.1.1
dEQP-VK.video.*
@@ -0,0 +1,879 @@
# Vertex 0: Expected red, got (-0.372549, -0.372549, -0.372549, -0.372549) (Fail)
# Likely fixed by VK-GL-CTS a3ac66a77e14 ("Zero initialize XFB counter buffer")
dEQP-VK.rasterization.provoking_vertex.transform_feedback.first.line_strip_with_adjacency,Fail
dEQP-VK.rasterization.provoking_vertex.transform_feedback.per_pipeline.triangle_strip_with_adjacency,Fail
dEQP-VK.draw.dynamic_rendering.primary_cmd_buff.multiple_interpolation.structured.no_sample_decoration.4_samples,Fail
dEQP-VK.dynamic_rendering.complete_secondary_cmd_buff.suballocation.unused_attachment.loadopclear.storeopdontcare.stencilloadopdontcare.stencilstoreopdontcare,Fail
dEQP-VK.dynamic_rendering.complete_secondary_cmd_buff.suballocation.unused_attachment.loadopdontcare.storeopdontcare.stencilloadopdontcare.stencilstoreopdontcare,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.attachment_allocation.input_output.63,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.attachment_allocation.input_output_chain.14,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.attachment_allocation.input_output_chain.20,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.attachment_allocation.input_output_chain.21,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a2b10g10r10_uint_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a2b10g10r10_uint_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a2b10g10r10_uint_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a2b10g10r10_uint_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a2b10g10r10_unorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a2b10g10r10_unorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a2b10g10r10_unorm_pack32.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a2r10g10b10_unorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a2r10g10b10_unorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a2r10g10b10_unorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8_unorm_khr.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8_unorm_khr.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8_unorm_khr.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8_unorm_khr.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_sint_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_sint_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_sint_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_sint_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_sint_pack32.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_snorm_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_snorm_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_snorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_snorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_srgb_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_srgb_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_srgb_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_uint_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_uint_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_uint_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_uint_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_uint_pack32.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_unorm_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_unorm_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_unorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_unorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_unorm_pack32.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.b8g8r8a8_srgb.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.b8g8r8a8_srgb.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.b8g8r8a8_srgb.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.b8g8r8a8_srgb.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.b8g8r8a8_srgb.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.b8g8r8a8_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.b8g8r8a8_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_snorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_snorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_sfloat.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_snorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_sfloat.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32g32b32a32_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r5g6b5_unorm_pack16.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r5g6b5_unorm_pack16.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r5g6b5_unorm_pack16.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r5g6b5_unorm_pack16.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_snorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8_unorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_snorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_snorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_srgb.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_srgb.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_srgb.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_srgb.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.attachment_allocation.input_output.63,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.attachment_allocation.input_output_chain.10,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.attachment_allocation.input_output_chain.21,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.attachment_allocation.input_output_chain.59,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.attachment_allocation.input_output_chain.66,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.attachment_allocation.input_output_chain.93,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2b10g10r10_uint_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2b10g10r10_uint_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2b10g10r10_uint_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2b10g10r10_uint_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2b10g10r10_unorm_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2b10g10r10_unorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2b10g10r10_unorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2b10g10r10_unorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2b10g10r10_unorm_pack32.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2r10g10b10_unorm_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2r10g10b10_unorm_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2r10g10b10_unorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2r10g10b10_unorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2r10g10b10_unorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8_unorm_khr.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8_unorm_khr.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8_unorm_khr.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8_unorm_khr.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8_unorm_khr.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8_unorm_khr.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_sint_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_sint_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_sint_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_sint_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_snorm_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_snorm_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_snorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_snorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_snorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_srgb_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_srgb_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_srgb_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_srgb_pack32.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_uint_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_uint_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_uint_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_unorm_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_unorm_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_unorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_unorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_unorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_unorm_pack32.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.b8g8r8a8_srgb.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.b8g8r8a8_srgb.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.b8g8r8a8_srgb.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.b8g8r8a8_srgb.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.b8g8r8a8_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.b8g8r8a8_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.b8g8r8a8_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.b8g8r8a8_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.b8g8r8a8_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_sfloat.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_snorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_unorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_snorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16b16a16_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_sfloat.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r32g32b32a32_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r5g6b5_unorm_pack16.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r5g6b5_unorm_pack16.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r5g6b5_unorm_pack16.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r5g6b5_unorm_pack16.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_snorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_snorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_snorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_unorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_snorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_srgb.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_srgb.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_srgb.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_srgb.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_srgb.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.unused_attachment.loadopclear.storeopdontcare.stencilloadopdontcare.stencilstoreopdontcare,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.unused_attachment.loadopdontcare.storeopdontcare.stencilloadopdontcare.stencilstoreopdontcare,Fail
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.unused_attachment.loadopload.storeopdontcare.stencilloadopdontcare.stencilstoreopdontcare,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.attachment_allocation.input_output_chain.10,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.attachment_allocation.input_output_chain.20,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.attachment_allocation.input_output_chain.59,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.attachment_allocation.input_output_chain.93,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a2b10g10r10_uint_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a2b10g10r10_uint_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a2b10g10r10_uint_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a2b10g10r10_unorm_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a2b10g10r10_unorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a2b10g10r10_unorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a2b10g10r10_unorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a2r10g10b10_unorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a2r10g10b10_unorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8_unorm_khr.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8_unorm_khr.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8_unorm_khr.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_sint_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_sint_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_sint_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_sint_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_snorm_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_snorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_snorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_snorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_snorm_pack32.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_srgb_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_srgb_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_srgb_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_srgb_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_srgb_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_srgb_pack32.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_uint_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_uint_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_uint_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_uint_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_unorm_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_unorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.a8b8g8r8_unorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.b8g8r8a8_srgb.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.b8g8r8a8_srgb.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.b8g8r8a8_srgb.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.b8g8r8a8_srgb.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.b8g8r8a8_srgb.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.b8g8r8a8_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.b8g8r8a8_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.b8g8r8a8_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.b8g8r8a8_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.b8g8r8a8_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_sfloat.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_snorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_sfloat.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_snorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_unorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32_sfloat.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_sfloat.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r32g32b32a32_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r5g6b5_unorm_pack16.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r5g6b5_unorm_pack16.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r5g6b5_unorm_pack16.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r5g6b5_unorm_pack16.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r5g6b5_unorm_pack16.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_snorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_unorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_snorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_snorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_srgb.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_unorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.attachment_allocation.input_output.63,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.attachment_allocation.input_output_chain.10,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.attachment_allocation.input_output_chain.14,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.attachment_allocation.input_output_chain.20,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.attachment_allocation.input_output_chain.21,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.attachment_allocation.input_output_chain.59,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.attachment_allocation.input_output_chain.66,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.attachment_allocation.input_output_chain.93,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a2b10g10r10_uint_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a2b10g10r10_uint_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a2b10g10r10_uint_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a2b10g10r10_uint_pack32.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a2b10g10r10_unorm_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a2b10g10r10_unorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a2b10g10r10_unorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a2r10g10b10_unorm_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a2r10g10b10_unorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a2r10g10b10_unorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a2r10g10b10_unorm_pack32.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8_unorm_khr.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8_unorm_khr.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8_unorm_khr.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8_unorm_khr.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_sint_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_sint_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_sint_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_sint_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_snorm_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_snorm_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_snorm_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_snorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_snorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_snorm_pack32.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_srgb_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_srgb_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_srgb_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_srgb_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_uint_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_uint_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_uint_pack32.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_uint_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_unorm_pack32.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_unorm_pack32.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_unorm_pack32.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_unorm_pack32.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.b8g8r8a8_srgb.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.b8g8r8a8_srgb.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.b8g8r8a8_srgb.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.b8g8r8a8_srgb.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.b8g8r8a8_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.b8g8r8a8_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.b8g8r8a8_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.b8g8r8a8_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.b8g8r8a8_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.b8g8r8a8_unorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_snorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_unorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_snorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_unorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_unorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16b16a16_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32_sfloat.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32_sfloat.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32b32a32_sfloat.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32b32a32_sfloat.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32b32a32_sfloat.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32b32a32_sfloat.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32b32a32_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32b32a32_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32b32a32_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32b32a32_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32b32a32_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32b32a32_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32b32a32_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32b32a32_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r5g6b5_unorm_pack16.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r5g6b5_unorm_pack16.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r5g6b5_unorm_pack16.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r5g6b5_unorm_pack16.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_sint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_snorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_snorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_uint.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_sint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_snorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_uint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_uint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_uint.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_unorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_sint.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_sint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_sint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_sint.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_snorm.input.clear.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_snorm.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_snorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_snorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_snorm.input.load.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_srgb.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_srgb.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_uint.input.clear.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_uint.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_unorm.input.dont_care.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_unorm.input.dont_care.dont_care.draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_unorm.input.load.dont_care.clear_draw,Fail
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.unused_attachment.loadopclear.storeopdontcare.stencilloadopdontcare.stencilstoreopdontcare,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.attachment_allocation.input_output_chain.66,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a2b10g10r10_uint_pack32.input.dont_care.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_sint_pack32.input.load.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.a8b8g8r8_snorm_pack32.input.clear.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16_unorm.input.load.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r16g16b16a16_uint.input.dont_care.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r32_uint.input.clear.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_snorm.input.dont_care.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats.r8g8b8a8_unorm.input.dont_care.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2b10g10r10_unorm_pack32.input.dont_care.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a2b10g10r10_unorm_pack32.input.load.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_uint_pack32.input.clear.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_unorm_pack32.input.dont_care.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_sfloat.input.dont_care.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r16g16_sfloat.input.load.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8_unorm.input.dont_care.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.r8g8b8a8_srgb.input.dont_care.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_snorm.input.clear.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16_unorm.input.clear.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r16g16b16a16_snorm.input.load.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r5g6b5_unorm_pack16.input.clear.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_uint.input.clear.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8_uint.input.dont_care.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8_unorm.input.dont_care.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_unorm.input.dont_care.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a2b10g10r10_uint_pack32.input.clear.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.a8b8g8r8_uint_pack32.input.clear.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.b8g8r8a8_unorm.input.clear.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16_sint.input.dont_care.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_sint.input.clear.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r16g16_unorm.input.dont_care.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r32g32_uint.input.dont_care.dont_care.clear_draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8_unorm.input.dont_care.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_sint.input.clear.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8_unorm.input.load.dont_care.draw,Fail
nir-stress=dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.unused_attachment.loadopdontcare.storeopdontcare.stencilloadopdontcare.stencilstoreopdontcare,Fail
dEQP-VK.sparse_resources.image_block_shapes.2d.g8b8g8r8_422_unorm.samples_1,Fail
dEQP-VK.sparse_resources.image_block_shapes.2d_array.g8b8g8r8_422_unorm.samples_1,Fail
# New fails in 1.4.3.3
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.b8g8r8a8_unorm.input.load.store.self_dep_clear_draw,Fail
dEQP-VK.mesh_shader.ext.smoke.fast_lib.depth_only_triangles_position_components,Fail
dEQP-VK.mesh_shader.ext.smoke.monolithic.depth_only_points_position_components,Fail
dEQP-VK.mesh_shader.ext.smoke.optimized_lib.depth_only_points_position_components,Fail
dEQP-VK.mesh_shader.ext.smoke.shader_objects.depth_only_triangles_position_components,Fail
# New failures with VKCTS 1.4.4.0
dEQP-VK.mesh_shader.ext.smoke.optimized_lib.depth_only_triangles_position_components,Fail
dEQP-VK.mesh_shader.ext.smoke.monolithic.depth_only_triangles_position_components,Fail
dEQP-VK.mesh_shader.ext.smoke.shader_objects.depth_only_points_position_components,Fail
dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_unorm.input.dont_care.store.self_dep_clear_draw,Fail
dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_unorm.input.load.store.self_dep_clear_draw,Fail
dEQP-VK.sparse_resources.image_block_shapes.2d.b8g8r8g8_422_unorm.samples_1,Fail
dEQP-VK.sparse_resources.image_block_shapes.2d_array.b8g8r8g8_422_unorm.samples_1,Fail
# VKCTS 1.4.4.2 -> 1.4.5.3 uprev
dEQP-VK.dgc.ext.graphics.misc.mix_normal_dgc_preprocess_with_vbo_token,Fail
dEQP-VK.mesh_shader.ext.smoke.fast_lib.depth_only_points_position_components,Fail
dEQP-VK.reconvergence.maximal.compute.nesting4.3.38,Crash
@@ -0,0 +1,133 @@
# "smooth produced different results (Fail)"
dEQP-VK.draw.dynamic_rendering.multiple_interpolation.structured.no_sample_decoration.4_samples
nir-stress=dEQP-VK.draw.dynamic_rendering.multiple_interpolation.structured.no_sample_decoration.4_samples
dEQP-VK.dynamic_rendering.graphics_pipeline_library.dedicated_allocation.formats..*.input.load.dont_care.draw
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats..*.input.load.dont_care.draw
dEQP-VK.dynamic_rendering.graphics_pipeline_library.suballocation.formats.a8b8g8r8_unorm_pack32.input.load.store.self_dep_clear_draw
dEQP-VK.dynamic_rendering.partial_secondary_cmd_buff.suballocation.subpass_dependencies.separate_channels.r8g8b8a8_unorm
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats..*.input.load.dont_care.draw
dEQP-VK.dynamic_rendering.primary_cmd_buff.dedicated_allocation.formats.r8g8b8a8_unorm.input.load.store.self_dep_draw
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats..*.input.load.dont_care.draw
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats..*.input.load.store.self_dep_clear_draw
dEQP-VK.dynamic_rendering.primary_cmd_buff.suballocation.formats.r8g8b8a8_unorm.input.dont_care.store.self_dep_draw
dEQP-VK.image.general_layout.input_attachment.sampled.memory.render_pass
dEQP-VK.pipeline.shader_object_unlinked_spirv.blend.dual_source.multi_attachments.a2r10g10b10_unorm_pack32
dEQP-VK.rasterization.culling.front_triangle_fan_point
dEQP-VK.rasterization.primitives.dynamic_stipple.smooth_lines_with_adjacency_wide
dEQP-VK.rasterization.primitives.dynamic_stipple_and_topology.rectangular_line_strip_with_adjacency_wide
dEQP-VK.rasterization.primitives.no_stipple.strict_line_strip_with_adjacency
dEQP-VK.rasterization.primitives.static_stipple.lines_wide
dEQP-VK.rasterization.provoking_vertex.transform_feedback.first.line_strip_with_adjacency
dEQP-VK.rasterization.provoking_vertex.transform_feedback.last.triangle_list_with_adjacency
dEQP-VK.rasterization.provoking_vertex.transform_feedback.per_pipeline.triangle_strip_with_adjacency
dEQP-VK.rasterization.rasterization_order_attachment_access.format_integer.attachments_4_samples_4.multi_draw
dEQP-VK.ray_query.builtin.intersectiont.frag.triangles
dEQP-VK.ray_query.builtin.worldtoobject.frag.triangles
dEQP-VK.ray_query.stress.fragment_shader.triangles
dEQP-VK.ray_tracing_pipeline.misc.recursiveTraces_AABB_12
dEQP-VK.ray_tracing_pipeline.misc.recursiveTraces_tri_13
dEQP-VK.sparse_resources.buffer.vertex_buffer.sparse_binding_aliased
dEQP-VK.sparse_resources.device_group_image_sparse_binding.cube_array.rg16i.256_256_6
dEQP-VK.sparse_resources.device_group_image_sparse_binding.multiple_bind_sparse_info.cube_array.r32ui.256_256_6
dEQP-VK.sparse_resources.device_group_image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.1d.r8_snorm.1024_1_1
dEQP-VK.sparse_resources.device_group_image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.cube.rgba32i.128_128_1
dEQP-VK.sparse_resources.device_group_image_sparse_binding.multiple_sparse_memory_bind.2d_array.g12x4b12x4g12x4r12x4_422_unorm_4pack16.1024_128_8
dEQP-VK.sparse_resources.image_rebind.3d.rgba32i.256_256_16
dEQP-VK.sparse_resources.image_rebind.cube.r16ui.256_256_1
dEQP-VK.sparse_resources.image_rebind.cube_array.rgba8_snorm.256_256_6
dEQP-VK.sparse_resources.image_sparse_binding.1d.rgba16i.512_1_1
dEQP-VK.sparse_resources.image_sparse_binding.1d.rgba8ui.1024_1_1
dEQP-VK.sparse_resources.image_sparse_binding.2d.g10x6_b10x6r10x6_2plane_422_unorm_3pack16.1024_128_1
dEQP-VK.sparse_resources.image_sparse_binding.2d.rg8.512_256_1
dEQP-VK.sparse_resources.image_sparse_binding.2d_array.r8_snorm.1024_128_8
dEQP-VK.sparse_resources.image_sparse_binding.2d_array.rg8i.1024_128_8
dEQP-VK.sparse_resources.image_sparse_binding.cube_array.rg8ui.137_137_3
dEQP-VK.sparse_resources.image_sparse_binding.multiple_bind_sparse_info.2d_array.r16i.1024_128_8
dEQP-VK.sparse_resources.image_sparse_binding.multiple_bind_sparse_info.2d_array.r32ui.1024_128_8
dEQP-VK.sparse_resources.image_sparse_binding.multiple_bind_sparse_info.3d.rg8i.512_256_6
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.1d.r16ui.11_1_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.1d.rg16ui.512_1_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.1d_array.r16_snorm.512_1_64
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.1d_array.r64i.11_1_3
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.1d_array.rg16.512_1_64
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.2d.b12x4g12x4r12x4g12x4_422_unorm_4pack16.512_256_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.2d.g16_b16r16_2plane_420_unorm.1024_128_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.2d.g16b16g16r16_422_unorm.1024_128_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.2d.g8_b8_r8_3plane_444_unorm.512_256_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.2d.r32ui.1024_128_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.2d.rgba16.11_137_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.2d.rgba32i.1024_128_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.2d.rgba8i.512_256_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.2d_array.g10x6_b10x6r10x6_2plane_420_unorm_3pack16.1024_128_8
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.2d_array.g12x4_b12x4_r12x4_3plane_420_unorm_3pack16.512_256_6
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.1d.r16i.512_1_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.1d.r64ui.512_1_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.1d.rg16_snorm.512_1_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.1d.rg8i.1024_1_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.1d.rgba16ui.512_1_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.1d.rgba32ui.1024_1_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.1d_array.r16.1024_1_8
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.1d_array.rg16i.512_1_64
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.1d_array.rg8.1024_1_8
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.1d_array.rg8_snorm.512_1_64
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.1d_array.rgba16i.11_1_3
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.1d_array.rgba8i.512_1_64
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.2d.g12x4_b12x4_r12x4_3plane_422_unorm_3pack16.512_256_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.2d.rg16.512_256_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.2d_array.g8_b8r8_2plane_422_unorm.1024_128_8
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.2d_array.r16ui.1024_128_8
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.2d_array.r32i.1024_128_8
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.2d_array.rg8.11_137_3
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.2d_array.rgba8.1024_128_8
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.3d.r8_snorm.512_256_6
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.3d.rgba16i.512_256_6
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.3d.rgba8_snorm.512_256_6
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.cube.rg32ui.137_137_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.cube.rgba16_snorm.128_128_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.cube.rgba32i.256_256_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.cube_array.r8ui.256_256_6
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_memory_bind.cube_array.rgba32i.137_137_3
dEQP-VK.sparse_resources.image_sparse_residency.2d.rg8.1024_128_1
dEQP-VK.sparse_resources.image_sparse_residency.3d.r32i.11_137_3
dEQP-VK.sparse_resources.image_sparse_residency.cube.rgba16_snorm.137_137_1
dEQP-VK.sparse_resources.image_sparse_residency.cube_array.r16ui.256_256_6
dEQP-VK.sparse_resources.image_sparse_residency.cube_array.rg8i.137_137_3
dEQP-VK.sparse_resources.shader_intrinsics.2d_array_sparse_gather.rgba8_snorm.512_256_6
dEQP-VK.sparse_resources.shader_intrinsics.2d_sparse_gather.r12x4g12x4b12x4a12x4_unorm_4pack16.128_128_1
dEQP-VK.sparse_resources.transfer_queue.2d.r10x6g10x6_unorm_2pack16.1024_128_1
dEQP-VK.synchronization.implicit.timeline_semaphore.write_ssbo_vertex_read_ssbo_vertex.buffer_16384.3033
dEQP-VK.synchronization2.basic.timeline_semaphore.one_queue
dEQP-VK.synchronization2.implicit.timeline_semaphore.write_ssbo_vertex_read_copy_buffer.buffer_16384.2001
dEQP-VK.synchronization2.implicit.timeline_semaphore.write_ssbo_vertex_read_ssbo_vertex.buffer_16384.3113
dEQP-VK.synchronization2.implicit.timeline_semaphore.write_ssbo_vertex_read_ssbo_vertex.buffer_16384.3212
dEQP-VK.synchronization2.op.single_queue.fence.write_ssbo_geometry_read_ubo_fragment.buffer_16384_specialized_access_flag
dEQP-VK.synchronization2.op.single_queue.fence.write_ssbo_tess_control_read_ssbo_geometry.buffer_262144
dEQP-VK\.synchronization2?\.timeline_semaphore\..*
dEQP-VK.tessellation.invariance.one_minus_tess_coord_component.isolines_fractional_even_spacing_ccw_point_mode
dEQP-VK.tessellation.invariance.one_minus_tess_coord_component.triangles_equal_spacing_ccw
dEQP-VK.tessellation.invariance.outer_edge_division.quads_fractional_odd_spacing
dEQP-VK.tessellation.invariance.outer_edge_division.triangles_equal_spacing
dEQP-VK.tessellation.invariance.primitive_set.isolines_fractional_even_spacing_ccw
dEQP-VK.tessellation.invariance.primitive_set.triangles_fractional_odd_spacing_cw
dEQP-VK.tessellation.invariance.tess_coord_component_range.quads_fractional_odd_spacing_cw_point_mode
dEQP-VK.tessellation.limits.max_tessellation_patch_size
dEQP-VK.tessellation.misc_draw.fill_cover_triangles_equal_spacing
dEQP-VK.tessellation.primitive_discard.isolines_fractional_odd_spacing_cw
dEQP-VK.tessellation.primitive_discard.quads_equal_spacing_ccw
dEQP-VK.tessellation.shader_input_output.cross_invocation_per_vertex_uint
dEQP-VK.tessellation.shader_input_output.cross_invocation_per_vertex_vec4
dEQP-VK.tessellation.user_defined_io.per_patch_block_array.vertex_io_array_size_implicit.triangles
dEQP-VK.tessellation.winding.lower_left_domain.hlsl_quads_ccw_yflip
dEQP-VK.texture.explicit_lod.2d.sizes.128x128_nearest_linear_mipmap_linear_repeat
nir-stress=dEQP-VK.sparse_resources.buffer.vertex_buffer.sparse_binding
@@ -0,0 +1,89 @@
# Note: skips lists for CI are just a list of lines that, when
# non-zero-length and not starting with '#', will regex match to
# delete lines from the test list. Be careful.
# still timing out in llvm jit
dEQP-VK.pipeline.monolithic.blend.dual_source.format.r16_unorm.states.color_1ms1a_cc_max_alpha_1msa_1mca_sub-color_o_1mdc_max_alpha_1mda_1ms1c_rsub-color_sas_da_max_alpha_1msa_1msc_add-color_sc_1msc_add_alpha_sas_1ms1a_rsub
dEQP-VK.pipeline.monolithic.blend.format.r16_unorm.states.color_sas_sa_min_alpha_ca_1mda_max-color_1mdc_dc_add_alpha_1mda_sas_rsub-color_sas_1mca_max_alpha_1mca_1mcc_min-color_o_1msa_rsub_alpha_dc_da_min
dEQP-VK.pipeline.pipeline_library.blend.dual_source.format.r16_unorm.states.color_1ms1a_cc_max_alpha_1msa_1mca_sub-color_o_1mdc_max_alpha_1mda_1ms1c_rsub-color_sas_da_max_alpha_1msa_1msc_add-color_sc_1msc_add_alpha_sas_1ms1a_rsub
dEQP-VK.pipeline.pipeline_library.blend.dual_source.format.r16_unorm.states.color_z_s1c_min_alpha_1mcc_s1c_rsub-color_ca_1mca_add_alpha_cc_1ms1a_min-color_ca_1ms1c_rsub_alpha_sa_sas_min-color_1ms1c_s1a_add_alpha_1mda_1ms1a_min
dEQP-VK.pipeline.pipeline_library.blend.format.r16_unorm.states.color_sas_sa_min_alpha_ca_1mda_max-color_1mdc_dc_add_alpha_1mda_sas_rsub-color_sas_1mca_max_alpha_1mca_1mcc_min-color_o_1msa_rsub_alpha_dc_da_min
dEQP-VK.graphicsfuzz.spv-stable-pillars-O-op-select-to-op-phi
dEQP-VK.graphicsfuzz.spv-composites
# These tests started hitting timeouts when we upgraded LLVM from v11 to 13
dEQP-VK.pipeline.fast_linked_library.blend.dual_source.format.r16_unorm.states.color_1ms1a_cc_max_alpha_1msa_1mca_sub-color_o_1mdc_max_alpha_1mda_1ms1c_rsub-color_sas_da_max_alpha_1msa_1msc_add-color_sc_1msc_add_alpha_sas_1ms1a_rsub
dEQP-VK.pipeline.fast_linked_library.blend.format.r16_unorm.states.color_sas_sa_min_alpha_ca_1mda_max-color_1mdc_dc_add_alpha_1mda_sas_rsub-color_sas_1mca_max_alpha_1mca_1mcc_min-color_o_1msa_rsub_alpha_dc_da_min
dEQP-VK.graphicsfuzz.spv-stable-maze-flatten-copy-composite
# Those tests time out reliably
dEQP-VK.graphicsfuzz.spv-stable-pillars-volatile-nontemporal-store
# timing out in llvm jit
dEQP-VK.ray_query.advanced.null_as.tese.aabbs
dEQP-VK.ray_query.advanced.null_as.tese.triangles
dEQP-VK.ray_query.watertightness.nomiss.tesc.aabbs
dEQP-VK.ray_query.watertightness.nomiss.tesc.triangles
dEQP-VK.ray_query.watertightness.nomiss.tese.aabbs
dEQP-VK.ray_query.watertightness.nomiss.tese.triangles
dEQP-VK.ray_query.watertightness.nomiss.vert.aabbs
dEQP-VK.ray_query.watertightness.nomiss.vert.triangles
dEQP-VK.ray_query.watertightness.singlehit.tesc.triangles
dEQP-VK.ray_query.watertightness.singlehit.tese.triangles
dEQP-VK.ray_query.watertightness.singlehit.vert.triangles
dEQP-VK.ray_query.builtin.flow.tesc.aabbs
dEQP-VK.ray_query.builtin.flow.tesc.triangles
dEQP-VK.ray_query.builtin.flow.tese.aabbs
dEQP-VK.ray_query.builtin.flow.tese.triangles
dEQP-VK.ray_query.builtin.instancecustomindex.tesc.aabbs
dEQP-VK.ray_query.builtin.instancecustomindex.tesc.triangles
dEQP-VK.ray_query.builtin.instancecustomindex.tese.aabbs
dEQP-VK.ray_query.builtin.instancecustomindex.tese.triangles
dEQP-VK.ray_query.builtin.instanceid.tesc.triangles
dEQP-VK.ray_query.builtin.primitiveid.tesc.aabbs
dEQP-VK.ray_query.builtin.primitiveid.tese.triangles
dEQP-VK.ray_tracing_pipeline.misc.recursiveTraces_AABB_12
dEQP-VK.ray_tracing_pipeline.misc.recursiveTraces_AABB_14
dEQP-VK.ray_tracing_pipeline.misc.recursiveTraces_AABB_15
dEQP-VK.ray_tracing_pipeline.misc.recursiveTraces_tri_14
# These take just under 60sec to run, and sometimes go over and timeout
dEQP-VK.binding_model.descriptor_buffer.multiple.graphics_frag_buffers2_sets4_imm_samplers
dEQP-VK.binding_model.descriptor_buffer.multiple.graphics_vert_buffers8_sets1
dEQP-VK.mesh_shader.ext.misc.many_task_work_groups_y
dEQP-VK.mesh_shader.ext.misc.many_task_work_groups_z
# Times out since a commit in the range 6006588a...edcad250
dEQP-VK.api.descriptor_pool.repeated_free_reset_long
# Trying to allocate all the memory we can is not a great idea on shared runners.
dEQP-VK.api.device_init.create_instance_device_intentional_alloc_fail.basic
# Times out
dEQP-VK.api.descriptor_pool.repeated_reset_long
dEQP-VK.memory.allocation.basic.percent_1.reverse.count_12
dEQP-VK.rasterization.primitives_multisample_4_bit.static_stipple.bresenham_line_strip_wide
dEQP-VK.ray_query.builtin.instanceid.tese.aabbs
dEQP-VK.ray_query.builtin.instanceid.tesc.aabbs
dEQP-VK.ray_query.builtin.instanceid.tese.triangles
dEQP-VK.sparse_resources.buffer.transfer.rebind.buffer_size_2_20
dEQP-VK.sparse_resources.device_group_image_sparse_binding.multiple_sparse_memory_bind.2d.r64ui.11_137_1
dEQP-VK.sparse_resources.image_sparse_binding.multiple_sparse_image_opaque_memory_bind_info.1d.r64i.1024_1_1
dEQP-VK.synchronization2.op.single_queue.fence.write_fill_buffer_read_ubo_texel_tess_eval.buffer_16384
dEQP-VK.synchronization2.timeline_semaphore.device_host.write_blit_image_read_image_vertex.image_64x64x8_r32_sfloat
dEQP-VK.synchronization2.timeline_semaphore.device_host.write_blit_image_read_copy_image_to_buffer.image_128_r32_uint
dEQP-VK.synchronization2.timeline_semaphore.device_host.write_copy_buffer_to_image_read_blit_image.image_128_r32_uint
dEQP-VK.synchronization2.timeline_semaphore.device_host.write_image_fragment_read_copy_image_to_buffer.image_128x128_r16_uint
dEQP-VK.synchronization2.timeline_semaphore.device_host.write_image_tess_control_read_image_vertex.image_128x128_r32g32b32a32_sfloat
dEQP-VK.tessellation.invariance.outer_edge_symmetry.triangles_fractional_odd_spacing_ccw
dEQP-VK.tessellation.misc_draw.fill_overlap_quads_equal_spacing_draw_indirect
dEQP-VK.tessellation.misc_draw.fill_overlap_triangles_equal_spacing_draw_indirect
dEQP-VK.tessellation.shader_input_output.tess_level_inner_1_tes
dEQP-VK.tessellation.tesscoord.triangles_equal_spacing_execution_mode_in_tesc
dEQP-VK.texture.explicit_lod.2d.sizes.128x128_linear_linear_mipmap_linear_clamp
dEQP-VK.texture.explicit_lod.2d.sizes.128x128_linear_linear_mipmap_linear_repeat
nir-stress=dEQP-VK.ray_query.builtin.instanceid.tese.triangles
@@ -0,0 +1,22 @@
# The tests assumes a dubgroup size >= 16
test_shader_waveop_maximal_convergence,Fail
# The test uses multiplanar formats for render targets which is unsupported
test_planar_video_formats,Fail
# The test expect lod=0.5 to load level 1 with nearest sampling
test_sample_instructions,Fail
test_sampler_rounding,Fail
test_view_min_lod,Fail
test_null_descriptor_resinfo_dxbc,Fail
test_null_descriptor_resinfo_dxil,Fail
test_undefined_structured_raw_alias_dxbc,Fail
test_undefined_structured_raw_alias_dxil,Fail
test_undefined_structured_raw_read_typed_dxbc,Fail
test_undefined_structured_raw_read_typed_dxil,Fail
test_copy_subresource_depth_stencil_batch,Fail
test_uav_clear_exhaustive_descriptors,Crash
@@ -0,0 +1,2 @@
test_unused_attachments_mix_and_match
test_fence_pending_signal_cpu_rewind_plain
@@ -0,0 +1,40 @@
[traces_db]
download_url = "https://s3.freedesktop.org/mesa-tracie-public/"
[[traces]]
path = "unigine/sanctuary-d3d9.trace-dxgi"
# This trace is not trimmed to a single frame, so it takes too long to render.
[[traces]]
path = "unigine/tropics-d3d9.trace-dxgi"
# This trace is not trimmed to a single frame, so it takes too long to render.
# Note that all the unigine/heaven traces crash when using --loops=
[[traces]]
path = "unigine/heaven-scene1-low-d3d9.trace-dxgi"
nonloopable = true
devices = { lvp = { checksum = "555efa5bcc89a638ed58df874aa13d0727bc7e798bfd9b42b2aa1854e3447688" } }
[[traces]]
path = "unigine/heaven-scene1-low-d3d11.trace-dxgi"
nonloopable = true
devices = { lvp = { checksum = "9ab7ad92594c3ec45ebdea32c28f21c3b5f05518d56468be53ecd31fb4c2e2e8" } }
[[traces]]
path = "unigine/heaven-scene1-ultra-d3d11.trace-dxgi"
nonloopable = true
devices = { lvp = { checksum = "aa114d950a0f32ea729e71c772b704f5b2d4b5063c7ab3a44c7a919b32d52066" } }
[[traces]]
path = "unigine/heaven-scene12-low-d3d9.trace-dxgi"
nonloopable = true
devices = { lvp = { checksum = "9f6586cd18b7add22d8d17b283b03e0e669b5cbcb3199d2cc655f5dde0d753df" } }
[[traces]]
path = "unigine/heaven-scene12-ultra-d3d11.trace-dxgi"
nonloopable = true
devices = { lvp = { checksum = "e742c05cdabcbaa634fe2607b642fbd16edc944e820009271fd70edd7ace46dd" } }
[[traces]]
path = "./LunarG-VulkanSamples/amd/polaris10/Hologram:-w:640:-h:480.gfxr"
devices = { lvp = { checksum = "13a59c0dc941b1ef954d6b55b43bc458791c41fd7056d98a1f5bb9bb74b9e0a6" } }
@@ -0,0 +1,709 @@
/*
* Copyright © 2023 Valve Corporation
* SPDX-License-Identifier: MIT
*/
#include "lvp_acceleration_structure.h"
#include "lvp_entrypoints.h"
#include "lvp_private.h"
#include "radix_sort/radix_sort_u64.h"
#include "bvh/vk_bvh.h"
struct radix_sort_vk_target_config lvp_radix_sort_config = {
.keyval_dwords = 2,
.init = {
.workgroup_size_log2 = 4,
},
.fill = {
.workgroup_size_log2 = 4,
.block_rows = 4,
},
.histogram = {
.workgroup_size_log2 = 7,
.subgroup_size_log2 = 3,
.block_rows = 16,
},
.prefix = {
.workgroup_size_log2 = 8,
.subgroup_size_log2 = 3,
},
.scatter = {
.workgroup_size_log2 = 7,
.subgroup_size_log2 = 3,
.block_rows = 8,
},
.nonsequential_dispatch = true,
};
static void
lvp_init_radix_sort(struct lvp_device *device)
{
simple_mtx_lock(&device->radix_sort_lock);
if (device->radix_sort) {
simple_mtx_unlock(&device->radix_sort_lock);
return;
}
device->radix_sort =
vk_create_radix_sort_u64(lvp_device_to_handle(device),
&device->vk.alloc, VK_NULL_HANDLE,
lvp_radix_sort_config);
device->accel_struct_args.radix_sort_64 = device->radix_sort;
simple_mtx_unlock(&device->radix_sort_lock);
}
static void
lvp_get_leaf_node_size(VkGeometryTypeKHR geometry_type, uint32_t *ir_leaf_node_size,
uint32_t *output_leaf_node_size)
{
switch (geometry_type) {
case VK_GEOMETRY_TYPE_TRIANGLES_KHR:
*ir_leaf_node_size = sizeof(struct vk_ir_triangle_node);
*output_leaf_node_size = sizeof(struct lvp_bvh_triangle_node);
break;
case VK_GEOMETRY_TYPE_AABBS_KHR:
*ir_leaf_node_size = sizeof(struct vk_ir_aabb_node);
*output_leaf_node_size = sizeof(struct lvp_bvh_aabb_node);
break;
case VK_GEOMETRY_TYPE_INSTANCES_KHR:
*ir_leaf_node_size = sizeof(struct vk_ir_instance_node);
*output_leaf_node_size = sizeof(struct lvp_bvh_instance_node);
break;
default:
break;
}
}
static VkDeviceSize
lvp_get_as_size_internal(VkGeometryTypeKHR geometry_type, uint32_t leaf_node_count)
{
uint32_t internal_node_count = MAX2(leaf_node_count, 2) - 1;
uint32_t nodes_size = internal_node_count * sizeof(struct lvp_bvh_box_node);
uint32_t ir_leaf_node_size = 0;
uint32_t output_leaf_node_size = 0;
lvp_get_leaf_node_size(geometry_type, &ir_leaf_node_size, &output_leaf_node_size);
nodes_size += leaf_node_count * output_leaf_node_size;
nodes_size = util_align_npot(nodes_size, LVP_BVH_NODE_PREFETCH_SIZE);
return sizeof(struct lvp_bvh_header) + nodes_size;
}
static VkDeviceSize
lvp_get_as_size(VkDevice device, const struct vk_acceleration_structure_build_state *state)
{
return lvp_get_as_size_internal(vk_get_as_geometry_type(state->build_info), state->leaf_node_count);
}
static void
lvp_write_buffer_cp(VkCommandBuffer cmdbuf, VkDeviceAddress addr,
void *data, uint32_t size)
{
VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, cmdbuf);
struct vk_cmd_queue_entry *entry =
linear_zalloc_child(cmd_buffer->vk.cmd_queue.ctx, offsetof(struct vk_cmd_queue_entry, u) + sizeof(struct lvp_cmd_write_buffer_cp) + size);
if (!entry)
return;
entry->type = LVP_CMD_WRITE_BUFFER_CP;
struct lvp_cmd_write_buffer_cp *cmd = (struct lvp_cmd_write_buffer_cp *)((uint8_t *)entry + offsetof(struct vk_cmd_queue_entry, u));
cmd->addr = addr;
cmd->data = cmd + 1;
cmd->size = size;
memcpy(cmd->data, data, size);
list_addtail(&entry->cmd_link, &cmd_buffer->vk.cmd_queue.cmds);
}
static void
lvp_flush_buffer_write_cp(VkCommandBuffer cmdbuf)
{
}
static void
lvp_cmd_dispatch_unaligned(VkCommandBuffer cmdbuf, uint32_t invocations_x,
uint32_t invocations_y, uint32_t invocations_z)
{
VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, cmdbuf);
struct vk_cmd_queue_entry *entry =
linear_zalloc_child(cmd_buffer->vk.cmd_queue.ctx, offsetof(struct vk_cmd_queue_entry, u) + sizeof(struct vk_cmd_dispatch));
if (!entry)
return;
entry->type = LVP_CMD_DISPATCH_UNALIGNED;
entry->u.dispatch.group_count_x = invocations_x;
entry->u.dispatch.group_count_y = invocations_y;
entry->u.dispatch.group_count_z = invocations_z;
list_addtail(&entry->cmd_link, &cmd_buffer->vk.cmd_queue.cmds);
}
static void
lvp_cmd_fill_buffer_addr(VkCommandBuffer cmdbuf, VkDeviceAddress addr,
VkDeviceSize size, uint32_t data)
{
VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, cmdbuf);
struct vk_cmd_queue_entry *entry =
linear_zalloc_child(cmd_buffer->vk.cmd_queue.ctx, offsetof(struct vk_cmd_queue_entry, u) + sizeof(struct lvp_cmd_fill_buffer_addr));
if (!entry)
return;
entry->type = LVP_CMD_FILL_BUFFER_ADDR;
struct lvp_cmd_fill_buffer_addr *cmd = (struct lvp_cmd_fill_buffer_addr *)((uint8_t *)entry + offsetof(struct vk_cmd_queue_entry, u));
cmd->addr = addr;
cmd->size = size;
cmd->data = data;
list_addtail(&entry->cmd_link, &cmd_buffer->vk.cmd_queue.cmds);
}
static void
lvp_enqueue_encode_as(VkCommandBuffer commandBuffer, const struct vk_acceleration_structure_build_state *state)
{
VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
VK_FROM_HANDLE(vk_acceleration_structure, dst, state->build_info->dstAccelerationStructure);
struct vk_cmd_queue_entry *entry =
linear_zalloc_child(cmd_buffer->vk.cmd_queue.ctx, offsetof(struct vk_cmd_queue_entry, u) + sizeof(struct lvp_cmd_encode_as));
if (!entry)
return;
entry->type = LVP_CMD_ENCODE_AS;
uint64_t intermediate_header_addr = state->build_info->scratchData.deviceAddress + state->scratch.header_offset;
uint64_t intermediate_bvh_addr = state->build_info->scratchData.deviceAddress + state->scratch.ir_offset;
struct lvp_cmd_encode_as *cmd = (struct lvp_cmd_encode_as *)((uint8_t *)entry + offsetof(struct vk_cmd_queue_entry, u));
cmd->dst = dst;
cmd->intermediate_as_addr = intermediate_bvh_addr;
cmd->intermediate_header_addr = intermediate_header_addr;
cmd->leaf_count = state->leaf_node_count;
cmd->geometry_type = vk_get_as_geometry_type(state->build_info);
list_addtail(&entry->cmd_link, &cmd_buffer->vk.cmd_queue.cmds);
}
static uint32_t
ir_id_to_offset(uint32_t id)
{
return id & (~3u);
}
static uint32_t
lvp_pack_sbt_offset_and_flags(uint32_t sbt_offset, VkGeometryInstanceFlagsKHR flags)
{
uint32_t ret = sbt_offset;
if (flags & VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR)
ret |= LVP_INSTANCE_FORCE_OPAQUE;
if (!(flags & VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR))
ret |= LVP_INSTANCE_NO_FORCE_NOT_OPAQUE;
if (flags & VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR)
ret |= LVP_INSTANCE_TRIANGLE_FACING_CULL_DISABLE;
if (flags & VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR)
ret |= LVP_INSTANCE_TRIANGLE_FLIP_FACING;
return ret;
}
static void
lvp_select_subtrees_to_flatten(const struct vk_ir_header *header, const struct vk_ir_box_node *ir_box_nodes,
const uint32_t *node_depth, const uint32_t *child_counts, uint32_t root_offset,
uint32_t index, struct util_dynarray *subtrees, uint32_t *max_subtree_size)
{
uint32_t depth = node_depth[header->ir_internal_node_count - index - 1];
uint32_t available_depth = 23 - depth;
uint32_t allowed_child_count = 1 << available_depth;
uint32_t child_count = child_counts[index];
bool flatten = child_count > allowed_child_count;
const struct vk_ir_box_node *node = ir_box_nodes + index;
bool has_internal_child = false;
for (uint32_t child_index = 0; child_index < 2; child_index++) {
if (node->children[child_index] == VK_BVH_INVALID_NODE)
continue;
uint32_t ir_child_offset = ir_id_to_offset(node->children[child_index]);
if (ir_child_offset < root_offset)
continue;
if (!flatten) {
uint32_t src_index = (ir_child_offset - root_offset) / sizeof(struct vk_ir_box_node);
lvp_select_subtrees_to_flatten(header, ir_box_nodes, node_depth, child_counts, root_offset,
src_index, subtrees, max_subtree_size);
}
has_internal_child = true;
}
if (flatten && has_internal_child) {
util_dynarray_append(subtrees, index);
*max_subtree_size = MAX2(*max_subtree_size, child_count);
return;
}
}
static void
lvp_gather_subtree(const uint8_t *output, uint32_t offset, uint32_t *leaf_nodes,
vk_aabb *leaf_bounds, uint32_t *leaf_node_count, uint32_t *internal_nodes,
uint32_t *internal_node_count)
{
const struct lvp_bvh_box_node *node = (void *)(output + offset);
for (uint32_t child_index = 0; child_index < 2; child_index++) {
if (node->children[child_index] == VK_BVH_INVALID_NODE)
continue;
uint32_t type = node->children[child_index] & 3;
if (type == lvp_bvh_node_internal) {
internal_nodes[*internal_node_count] = node->children[child_index];
(*internal_node_count)++;
uint32_t ir_child_offset = ir_id_to_offset(node->children[child_index]);
lvp_gather_subtree(output, ir_child_offset, leaf_nodes, leaf_bounds,
leaf_node_count, internal_nodes, internal_node_count);
} else {
leaf_nodes[*leaf_node_count] = node->children[child_index];
leaf_bounds[*leaf_node_count] = node->bounds[child_index];
(*leaf_node_count)++;
}
}
}
static uint32_t
lvp_rebuild_subtree(const uint8_t *output, uint32_t *leaf_nodes, vk_aabb *leaf_bounds,
uint32_t *internal_nodes, uint32_t leaf_node_count,
uint32_t *internal_node_index)
{
uint32_t child_nodes[2];
vk_aabb child_leaf_bounds[2];
if (leaf_node_count < 2)
return leaf_nodes[0];
uint32_t node_id = internal_nodes[*internal_node_index];
(*internal_node_index)++;
uint32_t split_index = leaf_node_count / 2;
child_leaf_bounds[0] = leaf_bounds[0];
child_nodes[0] = lvp_rebuild_subtree(output, leaf_nodes, leaf_bounds, internal_nodes, split_index, internal_node_index);
child_leaf_bounds[1] = leaf_bounds[split_index];
child_nodes[1] = lvp_rebuild_subtree(output, leaf_nodes + split_index, leaf_bounds + split_index, internal_nodes,
leaf_node_count - split_index, internal_node_index);
struct lvp_bvh_box_node *node = (void *)(output + ir_id_to_offset(node_id));
for (uint32_t i = 0; i < 2; i++) {
node->children[i] = child_nodes[i];
uint32_t type = child_nodes[i] & 3;
if (type == lvp_bvh_node_internal) {
const struct lvp_bvh_box_node *child_node =
(void *)(output + ir_id_to_offset(child_nodes[i]));
node->bounds[i].min.x = MIN2(child_node->bounds[0].min.x, child_node->bounds[1].min.x);
node->bounds[i].min.y = MIN2(child_node->bounds[0].min.y, child_node->bounds[1].min.y);
node->bounds[i].min.z = MIN2(child_node->bounds[0].min.z, child_node->bounds[1].min.z);
node->bounds[i].max.x = MAX2(child_node->bounds[0].max.x, child_node->bounds[1].max.x);
node->bounds[i].max.y = MAX2(child_node->bounds[0].max.y, child_node->bounds[1].max.y);
node->bounds[i].max.z = MAX2(child_node->bounds[0].max.z, child_node->bounds[1].max.z);
} else {
node->bounds[i] = child_leaf_bounds[i];
}
}
return node_id;
}
static void
lvp_flatten_as(const struct vk_ir_header *header, const struct vk_ir_box_node *ir_box_nodes,
uint32_t root_offset, const uint32_t *node_depth, uint8_t *output)
{
struct util_dynarray subtrees = { 0 };
uint32_t *child_counts = NULL;
uint32_t *leaf_nodes = NULL;
vk_aabb *leaf_bounds = NULL;
uint32_t *internal_nodes = NULL;
child_counts = calloc(header->ir_internal_node_count, sizeof(uint32_t));
if (!child_counts)
goto ret;
/* Iterate over the internal nodes in bottom-up order and
* compute the the number child leafs for each internal node.
*/
for (uint32_t i = 0; i < header->ir_internal_node_count; i++) {
const struct vk_ir_box_node *ir_box = ir_box_nodes + i;
for (uint32_t child_index = 0; child_index < 2; child_index++) {
if (ir_box->children[child_index] == VK_BVH_INVALID_NODE)
continue;
uint32_t ir_child_offset = ir_id_to_offset(ir_box->children[child_index]);
if (ir_child_offset < root_offset) {
child_counts[i]++;
} else {
uint32_t src_index = (ir_child_offset - root_offset) / sizeof(struct vk_ir_box_node);
child_counts[i] += child_counts[src_index];
}
}
}
/* Select the subtrees that have to be rebuilt in order to
* limit the BVH to a supported depth.
*/
subtrees = UTIL_DYNARRAY_INIT;
uint32_t max_subtree_size = 0;
lvp_select_subtrees_to_flatten(header, ir_box_nodes, node_depth, child_counts,
root_offset, header->ir_internal_node_count - 1,
&subtrees, &max_subtree_size);
leaf_nodes = calloc(max_subtree_size, sizeof(uint32_t));
leaf_bounds = calloc(max_subtree_size, sizeof(vk_aabb));
internal_nodes = calloc(max_subtree_size, sizeof(uint32_t));
if (!leaf_nodes || !leaf_bounds || !internal_nodes)
goto ret;
util_dynarray_foreach(&subtrees, uint32_t, root_index) {
uint32_t offset = sizeof(struct lvp_bvh_header) +
(header->ir_internal_node_count - 1 - *root_index) * sizeof(struct lvp_bvh_box_node);
internal_nodes[0] = offset | lvp_bvh_node_internal;
uint32_t leaf_node_count = 0;
uint32_t internal_node_count = 1;
lvp_gather_subtree(output, offset, leaf_nodes, leaf_bounds, &leaf_node_count, internal_nodes, &internal_node_count);
uint32_t internal_node_index = 0;
lvp_rebuild_subtree(output, leaf_nodes, leaf_bounds, internal_nodes, leaf_node_count, &internal_node_index);
}
ret:
util_dynarray_fini(&subtrees);
free(child_counts);
free(leaf_nodes);
free(leaf_bounds);
free(internal_nodes);
}
void
lvp_encode_as(struct vk_acceleration_structure *dst, VkDeviceAddress intermediate_as_addr,
VkDeviceAddress intermediate_header_addr, uint32_t leaf_count,
VkGeometryTypeKHR geometry_type)
{
const struct vk_ir_header *header = (const void *)(uintptr_t)intermediate_header_addr;
const uint8_t *ir_bvh = (const void *)(uintptr_t)intermediate_as_addr;
uint8_t *output = (void *)(uintptr_t)vk_acceleration_structure_get_va(dst);
struct lvp_bvh_header *output_header = (void *)output;
uint32_t ir_leaf_node_size = 0;
uint32_t output_leaf_node_size = 0;
lvp_get_leaf_node_size(geometry_type, &ir_leaf_node_size, &output_leaf_node_size);
uint32_t root_offset = leaf_count * ir_leaf_node_size;
const struct vk_ir_box_node *ir_box_nodes = (const void *)(ir_bvh + root_offset);
output_header->bounds = ir_box_nodes[header->ir_internal_node_count - 1].base.aabb;
if (geometry_type == VK_GEOMETRY_TYPE_INSTANCES_KHR)
output_header->instance_count = leaf_count;
else
output_header->instance_count = 0;
output_header->leaf_nodes_offset = sizeof(struct lvp_bvh_header) + header->ir_internal_node_count * sizeof(struct lvp_bvh_box_node);
uint32_t bvh_size = lvp_get_as_size_internal(geometry_type, leaf_count);
output_header->compacted_size = bvh_size;
output_header->serialization_size = sizeof(struct lvp_accel_struct_serialization_header) +
sizeof(uint64_t) * output_header->instance_count + bvh_size;
for (uint32_t i = 0; i < header->active_leaf_count; i++) {
const void *ir_leaf = ir_bvh + i * ir_leaf_node_size;
void *output_leaf = output + output_header->leaf_nodes_offset + i * output_leaf_node_size;
switch (geometry_type) {
case VK_GEOMETRY_TYPE_TRIANGLES_KHR: {
const struct vk_ir_triangle_node *ir_triangle = ir_leaf;
struct lvp_bvh_triangle_node *output_triangle = output_leaf;
memcpy(output_triangle->coords, ir_triangle->coords, sizeof(output_triangle->coords));
output_triangle->primitive_id = ir_triangle->triangle_id;
output_triangle->geometry_id_and_flags = ir_triangle->geometry_id_and_flags;
break;
}
case VK_GEOMETRY_TYPE_AABBS_KHR: {
const struct vk_ir_aabb_node *ir_aabb = ir_leaf;
struct lvp_bvh_aabb_node *output_aabb = output_leaf;
output_aabb->bounds = ir_aabb->base.aabb;
output_aabb->primitive_id = ir_aabb->primitive_id;
output_aabb->geometry_id_and_flags = ir_aabb->geometry_id_and_flags;
break;
}
case VK_GEOMETRY_TYPE_INSTANCES_KHR: {
const struct vk_ir_instance_node *ir_instance = ir_leaf;
struct lvp_bvh_instance_node *output_instance = output_leaf;
output_instance->bvh_ptr = ir_instance->base_ptr;
output_instance->custom_instance_and_mask = ir_instance->custom_instance_and_mask;
output_instance->sbt_offset_and_flags =
lvp_pack_sbt_offset_and_flags(ir_instance->sbt_offset_and_flags & 0xFFFFFF,
ir_instance->sbt_offset_and_flags >> 24);
output_instance->instance_id = ir_instance->instance_id;
output_instance->otw_matrix = ir_instance->otw_matrix;
float transform[16], inv_transform[16];
memcpy(transform, &ir_instance->otw_matrix.values, sizeof(ir_instance->otw_matrix.values));
transform[12] = transform[13] = transform[14] = 0.0f;
transform[15] = 1.0f;
util_invert_mat4x4(inv_transform, transform);
memcpy(output_instance->wto_matrix.values, inv_transform, sizeof(output_instance->wto_matrix.values));
break;
}
default:
break;
}
}
uint32_t *node_depth = calloc(header->ir_internal_node_count, sizeof(uint32_t));
if (!node_depth)
return;
uint32_t max_node_depth = 0;
for (uint32_t i = 0; i < header->ir_internal_node_count; i++) {
const struct vk_ir_box_node *ir_box = ir_box_nodes + (header->ir_internal_node_count - i - 1);
struct lvp_bvh_box_node *output_box =
(void *)(output + sizeof(struct lvp_bvh_header) + i * sizeof(struct lvp_bvh_box_node));
for (uint32_t child_index = 0; child_index < 2; child_index++) {
if (ir_box->children[child_index] == VK_BVH_INVALID_NODE) {
output_box->bounds[child_index] = (struct vk_aabb){
.min.x = NAN,
.min.y = NAN,
.min.z = NAN,
.max.x = NAN,
.max.y = NAN,
.max.z = NAN,
};
output_box->children[child_index] = LVP_BVH_INVALID_NODE;
continue;
}
uint32_t ir_child_offset = ir_id_to_offset(ir_box->children[child_index]);
const struct vk_ir_node *ir_child = (const void *)(ir_bvh + ir_child_offset);
output_box->bounds[child_index] = ir_child->aabb;
/* Increase the bounding box size a bit for watertightness. */
output_box->bounds[child_index].min.x -= MAX2(fabsf(output_box->bounds[child_index].min.x), 1.0) * FLT_EPSILON;
output_box->bounds[child_index].min.y -= MAX2(fabsf(output_box->bounds[child_index].min.y), 1.0) * FLT_EPSILON;
output_box->bounds[child_index].min.z -= MAX2(fabsf(output_box->bounds[child_index].min.z), 1.0) * FLT_EPSILON;
output_box->bounds[child_index].max.x += MAX2(fabsf(output_box->bounds[child_index].max.x), 1.0) * FLT_EPSILON;
output_box->bounds[child_index].max.y += MAX2(fabsf(output_box->bounds[child_index].max.y), 1.0) * FLT_EPSILON;
output_box->bounds[child_index].max.z += MAX2(fabsf(output_box->bounds[child_index].max.z), 1.0) * FLT_EPSILON;
if (ir_child_offset < root_offset) {
output_box->children[child_index] =
output_header->leaf_nodes_offset + (ir_child_offset / ir_leaf_node_size) * output_leaf_node_size;
switch (geometry_type) {
case VK_GEOMETRY_TYPE_TRIANGLES_KHR:
output_box->children[child_index] |= lvp_bvh_node_triangle;
break;
case VK_GEOMETRY_TYPE_AABBS_KHR:
output_box->children[child_index] |= lvp_bvh_node_aabb;
break;
case VK_GEOMETRY_TYPE_INSTANCES_KHR:
output_box->children[child_index] |= lvp_bvh_node_instance;
break;
default:
break;
}
} else {
uint32_t src_index = (ir_child_offset - root_offset) / sizeof(struct vk_ir_box_node);
uint32_t dst_index = header->ir_internal_node_count - src_index - 1;
output_box->children[child_index] =
sizeof(struct lvp_bvh_header) + dst_index * sizeof(struct lvp_bvh_box_node);
output_box->children[child_index] |= lvp_bvh_node_internal;
node_depth[dst_index] = node_depth[i] + 1;
max_node_depth = MAX2(max_node_depth, node_depth[dst_index]);
}
}
}
/* The BVH exceeds the maximum depth supported by the traversal stack,
* flatten the offending parts of the tree.
*/
if (max_node_depth >= (geometry_type == VK_GEOMETRY_TYPE_INSTANCES_KHR ? LVP_MAX_TLAS_DEPTH : LVP_MAX_BLAS_DEPTH))
lvp_flatten_as(header, ir_box_nodes, root_offset, node_depth, output);
free(node_depth);
}
static_assert(sizeof(struct lvp_bvh_triangle_node) % 8 == 0, "lvp_bvh_triangle_node is not padded");
static_assert(sizeof(struct lvp_bvh_aabb_node) % 8 == 0, "lvp_bvh_aabb_node is not padded");
static_assert(sizeof(struct lvp_bvh_instance_node) % 8 == 0, "lvp_bvh_instance_node is not padded");
static_assert(sizeof(struct lvp_bvh_box_node) % 8 == 0, "lvp_bvh_box_node is not padded");
VKAPI_ATTR void VKAPI_CALL
lvp_GetAccelerationStructureBuildSizesKHR(
VkDevice _device, VkAccelerationStructureBuildTypeKHR buildType,
const VkAccelerationStructureBuildGeometryInfoKHR *pBuildInfo,
const uint32_t *pMaxPrimitiveCounts, VkAccelerationStructureBuildSizesInfoKHR *pSizeInfo)
{
VK_FROM_HANDLE(lvp_device, device, _device);
lvp_init_radix_sort(device);
vk_get_as_build_sizes(_device, buildType, pBuildInfo, pMaxPrimitiveCounts,
pSizeInfo, &device->accel_struct_args);
}
VKAPI_ATTR VkResult VKAPI_CALL
lvp_WriteAccelerationStructuresPropertiesKHR(
VkDevice _device, uint32_t accelerationStructureCount,
const VkAccelerationStructureKHR *pAccelerationStructures, VkQueryType queryType,
size_t dataSize, void *pData, size_t stride)
{
UNREACHABLE("Unimplemented");
return VK_ERROR_FEATURE_NOT_PRESENT;
}
VKAPI_ATTR VkResult VKAPI_CALL
lvp_BuildAccelerationStructuresKHR(
VkDevice _device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount,
const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
const VkAccelerationStructureBuildRangeInfoKHR *const *ppBuildRangeInfos)
{
UNREACHABLE("Unimplemented");
return VK_ERROR_FEATURE_NOT_PRESENT;
}
VKAPI_ATTR void VKAPI_CALL
lvp_GetDeviceAccelerationStructureCompatibilityKHR(
VkDevice _device, const VkAccelerationStructureVersionInfoKHR *pVersionInfo,
VkAccelerationStructureCompatibilityKHR *pCompatibility)
{
uint8_t uuid[VK_UUID_SIZE];
lvp_device_get_cache_uuid(uuid);
bool compat = memcmp(pVersionInfo->pVersionData, uuid, VK_UUID_SIZE) == 0;
*pCompatibility = compat ? VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR
: VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR;
}
VKAPI_ATTR VkResult VKAPI_CALL
lvp_CopyAccelerationStructureKHR(VkDevice _device, VkDeferredOperationKHR deferredOperation,
const VkCopyAccelerationStructureInfoKHR *pInfo)
{
UNREACHABLE("Unimplemented");
return VK_ERROR_FEATURE_NOT_PRESENT;
}
VKAPI_ATTR VkResult VKAPI_CALL
lvp_CopyMemoryToAccelerationStructureKHR(VkDevice _device, VkDeferredOperationKHR deferredOperation,
const VkCopyMemoryToAccelerationStructureInfoKHR *pInfo)
{
UNREACHABLE("Unimplemented");
return VK_ERROR_FEATURE_NOT_PRESENT;
}
VKAPI_ATTR VkResult VKAPI_CALL
lvp_CopyAccelerationStructureToMemoryKHR(VkDevice _device, VkDeferredOperationKHR deferredOperation,
const VkCopyAccelerationStructureToMemoryInfoKHR *pInfo)
{
UNREACHABLE("Unimplemented");
return VK_ERROR_FEATURE_NOT_PRESENT;
}
static VkResult
lvp_encode_prepare(VkCommandBuffer cmd_buffer, const struct vk_acceleration_structure_build_state *state)
{
return VK_SUCCESS;
}
const struct vk_acceleration_structure_build_ops accel_struct_ops = {
.get_as_size = lvp_get_as_size,
.encode_prepare[0] = lvp_encode_prepare,
.encode_as[0] = lvp_enqueue_encode_as,
};
VkResult
lvp_device_init_accel_struct_state(struct lvp_device *device)
{
device->accel_struct_args.subgroup_size = lp_native_vector_width / 32;
device->vk.as_build_ops = &accel_struct_ops;
device->vk.write_buffer_cp = lvp_write_buffer_cp;
device->vk.flush_buffer_write_cp = lvp_flush_buffer_write_cp;
device->vk.cmd_dispatch_unaligned = lvp_cmd_dispatch_unaligned;
device->vk.cmd_fill_buffer_addr = lvp_cmd_fill_buffer_addr;
simple_mtx_init(&device->radix_sort_lock, mtx_plain);
return VK_SUCCESS;
}
void
lvp_device_finish_accel_struct_state(struct lvp_device *device)
{
simple_mtx_destroy(&device->radix_sort_lock);
if (device->radix_sort)
radix_sort_vk_destroy(device->radix_sort, lvp_device_to_handle(device), &device->vk.alloc);
}
static void
lvp_enqueue_save_state(VkCommandBuffer cmdbuf)
{
VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, cmdbuf);
struct vk_cmd_queue_entry *entry =
linear_zalloc_child(cmd_buffer->vk.cmd_queue.ctx, offsetof(struct vk_cmd_queue_entry, u));
if (!entry)
return;
entry->type = LVP_CMD_SAVE_STATE;
list_addtail(&entry->cmd_link, &cmd_buffer->vk.cmd_queue.cmds);
}
static void
lvp_enqueue_restore_state(VkCommandBuffer cmdbuf)
{
VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, cmdbuf);
struct vk_cmd_queue_entry *entry =
linear_zalloc_child(cmd_buffer->vk.cmd_queue.ctx, offsetof(struct vk_cmd_queue_entry, u));
if (!entry)
return;
entry->type = LVP_CMD_RESTORE_STATE;
list_addtail(&entry->cmd_link, &cmd_buffer->vk.cmd_queue.cmds);
}
VKAPI_ATTR void VKAPI_CALL
lvp_CmdBuildAccelerationStructuresKHR(VkCommandBuffer commandBuffer, uint32_t infoCount,
const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
const VkAccelerationStructureBuildRangeInfoKHR *const *ppBuildRangeInfos)
{
VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
struct lvp_device *device = lvp_cmd_buffer_device(cmd_buffer);
lvp_init_radix_sort(device);
lvp_enqueue_save_state(commandBuffer);
vk_cmd_build_acceleration_structures(commandBuffer, &device->vk, &device->meta,
infoCount, pInfos, ppBuildRangeInfos, &device->accel_struct_args);
lvp_enqueue_restore_state(commandBuffer);
}
@@ -0,0 +1,101 @@
/*
* Copyright © 2021 Google
* Copyright © 2023 Valve Corporation
* SPDX-License-Identifier: MIT
*/
#ifndef LVP_ACCELERATION_STRUCTURE_H
#define LVP_ACCELERATION_STRUCTURE_H
#include "lvp_private.h"
#include "bvh/vk_bvh.h"
#define LVP_GEOMETRY_OPAQUE (1u << 31)
#define LVP_INSTANCE_FORCE_OPAQUE (1u << 31)
#define LVP_INSTANCE_NO_FORCE_NOT_OPAQUE (1u << 30)
#define LVP_INSTANCE_TRIANGLE_FACING_CULL_DISABLE (1u << 29)
#define LVP_INSTANCE_TRIANGLE_FLIP_FACING (1u << 28)
#define lvp_bvh_node_triangle 0
#define lvp_bvh_node_internal 1
#define lvp_bvh_node_instance 2
#define lvp_bvh_node_aabb 3
/* 48 bytes */
struct lvp_bvh_triangle_node {
float coords[3][3];
uint32_t padding;
uint32_t primitive_id;
/* flags in upper 4 bits */
uint32_t geometry_id_and_flags;
};
/* 32 bytes */
struct lvp_bvh_aabb_node {
vk_aabb bounds;
uint32_t primitive_id;
/* flags in upper 4 bits */
uint32_t geometry_id_and_flags;
};
/* 120 bytes */
struct lvp_bvh_instance_node {
uint64_t bvh_ptr;
/* lower 24 bits are the custom instance index, upper 8 bits are the visibility mask */
uint32_t custom_instance_and_mask;
/* lower 24 bits are the sbt offset, upper 8 bits are VkGeometryInstanceFlagsKHR */
uint32_t sbt_offset_and_flags;
mat3x4 wto_matrix;
uint32_t padding;
uint32_t instance_id;
/* Object to world matrix transposed from the initial transform. */
mat3x4 otw_matrix;
};
/* 56 bytes */
struct lvp_bvh_box_node {
vk_aabb bounds[2];
uint32_t children[2];
};
#define LVP_BVH_NODE_PREFETCH_SIZE 56
struct lvp_bvh_header {
vk_aabb bounds;
uint32_t compacted_size;
uint32_t serialization_size;
uint32_t instance_count;
uint32_t leaf_nodes_offset;
};
struct lvp_accel_struct_serialization_header {
uint8_t driver_uuid[VK_UUID_SIZE];
uint8_t accel_struct_compat[VK_UUID_SIZE];
uint64_t serialization_size;
uint64_t compacted_size;
uint64_t instance_count;
uint64_t instances[];
};
/* The root node is the first node after the header. */
#define LVP_BVH_ROOT_NODE_OFFSET (sizeof(struct lvp_bvh_header))
#define LVP_BVH_ROOT_NODE (LVP_BVH_ROOT_NODE_OFFSET | lvp_bvh_node_internal)
#define LVP_BVH_INVALID_NODE 0xFFFFFFFF
VkResult
lvp_device_init_accel_struct_state(struct lvp_device *device);
void
lvp_device_finish_accel_struct_state(struct lvp_device *device);
#endif
@@ -0,0 +1,166 @@
/*
* Copyright © 2024, Google Inc.
*
* 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 (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 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.
*/
#include <hardware/gralloc.h>
#if ANDROID_API_LEVEL >= 26
#include <hardware/gralloc1.h>
#include <vndk/hardware_buffer.h>
#endif
#include <vulkan/vk_android_native_buffer.h>
#include "vk_android.h"
#include "lvp_private.h"
VKAPI_ATTR VkResult VKAPI_CALL
lvp_GetSwapchainGrallocUsageANDROID(VkDevice device_h,
VkFormat format,
VkImageUsageFlags imageUsage,
int *grallocUsage)
{
*grallocUsage = GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN;
return VK_SUCCESS;
}
#if ANDROID_API_LEVEL >= 26
VKAPI_ATTR VkResult VKAPI_CALL
lvp_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h,
VkFormat format,
VkImageUsageFlags imageUsage,
VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
uint64_t *grallocConsumerUsage,
uint64_t *grallocProducerUsage)
{
*grallocConsumerUsage = 0;
*grallocProducerUsage = GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN | GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN;
return VK_SUCCESS;
}
#endif
VkResult
lvp_import_ahb_memory(struct lvp_device *device,
const VkMemoryAllocateInfo *alloc_info,
struct lvp_device_memory *mem)
{
const VkMemoryDedicatedAllocateInfo *dedicated_info =
vk_find_struct_const(alloc_info->pNext, MEMORY_DEDICATED_ALLOCATE_INFO);
if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) {
VK_FROM_HANDLE(lvp_image, image, dedicated_info->image);
VkResult result;
VkImageDrmFormatModifierExplicitCreateInfoEXT eci;
VkSubresourceLayout layouts[LVP_MAX_PLANE_COUNT];
result = vk_android_get_ahb_layout(mem->vk.ahardware_buffer, &eci,
layouts, LVP_MAX_PLANE_COUNT);
if (result != VK_SUCCESS)
return result;
image->vk.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
const uint32_t queue_family_index = 0;
const VkImageCreateInfo create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = &eci,
.flags = image->vk.create_flags,
.imageType = image->vk.image_type,
.format = image->vk.format,
.extent = image->vk.extent,
.mipLevels = image->vk.mip_levels,
.arrayLayers = image->vk.array_layers,
.samples = image->vk.samples,
.tiling = image->vk.tiling,
.usage = image->vk.usage,
.sharingMode = image->vk.sharing_mode,
.queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &queue_family_index,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
};
result = lvp_image_init(device, image, &create_info);
if (result != VK_SUCCESS)
return result;
}
const native_handle_t *handle =
AHardwareBuffer_getNativeHandle(mem->vk.ahardware_buffer);
int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
if (dma_buf < 0)
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
uint64_t size;
if (!device->pscreen->import_memory_fd(device->pscreen, dma_buf, &mem->pmem,
&size, true))
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
mem->vk.size = size;
mem->map = device->pscreen->map_memory(device->pscreen, mem->pmem);
mem->memory_type = LVP_DEVICE_MEMORY_TYPE_DMA_BUF;
return VK_SUCCESS;
}
VkResult
lvp_bind_anb_memory(struct lvp_device *device,
const VkBindImageMemoryInfo *bind_info)
{
VK_FROM_HANDLE(lvp_image, image, bind_info->image);
/* ANB info is the only addition here. Fish it out and strip the pNext. */
const VkNativeBufferANDROID *anb_info =
vk_find_struct_const(bind_info->pNext, NATIVE_BUFFER_ANDROID);
assert(anb_info);
VkNativeBufferANDROID local_anb_info = *anb_info;
local_anb_info.pNext = NULL;
/* We can use the common vk_image info to reconstruct the VkImageCreateInfo
* for deferred layouting and the ANB memory import. This step can be lossy
* for some hw drivers but is fine for lavapipe.
*/
const uint32_t queue_family_index = 0;
const VkImageCreateInfo create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = &local_anb_info,
.flags = image->vk.create_flags,
.imageType = image->vk.image_type,
.format = image->vk.format,
.extent = image->vk.extent,
.mipLevels = image->vk.mip_levels,
.arrayLayers = image->vk.array_layers,
.samples = image->vk.samples,
.tiling = image->vk.tiling,
.usage = image->vk.usage,
.sharingMode = image->vk.sharing_mode,
.queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &queue_family_index,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
};
VkResult result = lvp_image_init(device, image, &create_info);
if (result != VK_SUCCESS)
return result;
return vk_android_import_anb(&device->vk, &create_info, &device->vk.alloc,
&image->vk);
}
@@ -0,0 +1,100 @@
/*
* Copyright © 2019 Red Hat.
*
* 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 (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 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.
*/
#include "lvp_private.h"
#include "pipe/p_context.h"
#include "vk_render_pass.h"
#include "vk_util.h"
#include "vk_common_entrypoints.h"
static void
lvp_cmd_buffer_destroy(struct vk_command_buffer *cmd_buffer)
{
vk_command_buffer_finish(cmd_buffer);
vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
}
static VkResult
lvp_create_cmd_buffer(struct vk_command_pool *pool,
VkCommandBufferLevel level,
struct vk_command_buffer **cmd_buffer_out)
{
struct lvp_device *device =
container_of(pool->base.device, struct lvp_device, vk);
struct lvp_cmd_buffer *cmd_buffer;
cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (cmd_buffer == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
VkResult result = vk_command_buffer_init(pool, &cmd_buffer->vk,
&lvp_cmd_buffer_ops, level);
if (result != VK_SUCCESS) {
vk_free(&pool->alloc, cmd_buffer);
return result;
}
*cmd_buffer_out = &cmd_buffer->vk;
return VK_SUCCESS;
}
static void
lvp_reset_cmd_buffer(struct vk_command_buffer *vk_cmd_buffer,
UNUSED VkCommandBufferResetFlags flags)
{
vk_command_buffer_reset(vk_cmd_buffer);
}
const struct vk_command_buffer_ops lvp_cmd_buffer_ops = {
.create = lvp_create_cmd_buffer,
.reset = lvp_reset_cmd_buffer,
.destroy = lvp_cmd_buffer_destroy,
};
VKAPI_ATTR VkResult VKAPI_CALL lvp_BeginCommandBuffer(
VkCommandBuffer commandBuffer,
const VkCommandBufferBeginInfo* pBeginInfo)
{
VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
vk_command_buffer_begin(&cmd_buffer->vk, pBeginInfo);
if (cmd_buffer->vk.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
const VkCommandBufferInheritanceRenderingInfo *rendering_info =
vk_get_command_buffer_inheritance_rendering_info(VK_COMMAND_BUFFER_LEVEL_SECONDARY, pBeginInfo);
if (rendering_info)
cmd_buffer->rendering_info = *rendering_info;
}
return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL lvp_EndCommandBuffer(
VkCommandBuffer commandBuffer)
{
VK_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
return vk_command_buffer_end(&cmd_buffer->vk);
}
+103
View File
@@ -0,0 +1,103 @@
/*
* Copyright © 2019 Red Hat.
*
* 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 (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 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.
*/
#pragma once
static inline unsigned vk_cull_to_pipe(uint32_t vk_cull)
{
/* these correspond */
return vk_cull;
}
static inline unsigned vk_polygon_mode_to_pipe(uint32_t vk_poly_mode)
{
/* these correspond */
return vk_poly_mode;
}
static inline unsigned vk_conv_stencil_op(uint32_t vk_stencil_op)
{
switch (vk_stencil_op) {
case VK_STENCIL_OP_KEEP:
return PIPE_STENCIL_OP_KEEP;
case VK_STENCIL_OP_ZERO:
return PIPE_STENCIL_OP_ZERO;
case VK_STENCIL_OP_REPLACE:
return PIPE_STENCIL_OP_REPLACE;
case VK_STENCIL_OP_INCREMENT_AND_CLAMP:
return PIPE_STENCIL_OP_INCR;
case VK_STENCIL_OP_DECREMENT_AND_CLAMP:
return PIPE_STENCIL_OP_DECR;
case VK_STENCIL_OP_INVERT:
return PIPE_STENCIL_OP_INVERT;
case VK_STENCIL_OP_INCREMENT_AND_WRAP:
return PIPE_STENCIL_OP_INCR_WRAP;
case VK_STENCIL_OP_DECREMENT_AND_WRAP:
return PIPE_STENCIL_OP_DECR_WRAP;
default:
assert(0);
return 0;
}
}
static inline unsigned vk_conv_wrap_mode(VkSamplerAddressMode addr_mode)
{
switch (addr_mode) {
case VK_SAMPLER_ADDRESS_MODE_REPEAT:
return PIPE_TEX_WRAP_REPEAT;
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
return PIPE_TEX_WRAP_MIRROR_REPEAT;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;
default:
assert(0);
return 0;
}
}
static inline enum pipe_swizzle vk_conv_swizzle(VkComponentSwizzle swiz,
enum pipe_swizzle identity)
{
switch (swiz) {
case VK_COMPONENT_SWIZZLE_ZERO:
return PIPE_SWIZZLE_0;
case VK_COMPONENT_SWIZZLE_ONE:
return PIPE_SWIZZLE_1;
case VK_COMPONENT_SWIZZLE_R:
return PIPE_SWIZZLE_X;
case VK_COMPONENT_SWIZZLE_G:
return PIPE_SWIZZLE_Y;
case VK_COMPONENT_SWIZZLE_B:
return PIPE_SWIZZLE_Z;
case VK_COMPONENT_SWIZZLE_A:
return PIPE_SWIZZLE_W;
case VK_COMPONENT_SWIZZLE_IDENTITY:
return identity;
default:
UNREACHABLE("Invalid VkComponentSwizzle value");
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,330 @@
/*
* Copyright © 2023 Valve 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 (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 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.
*/
#include "lvp_private.h"
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateIndirectExecutionSetEXT(
VkDevice _device,
const VkIndirectExecutionSetCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkIndirectExecutionSetEXT* pIndirectExecutionSet)
{
VK_FROM_HANDLE(lvp_device, device, _device);
bool is_shaders = pCreateInfo->type == VK_INDIRECT_EXECUTION_SET_INFO_TYPE_SHADER_OBJECTS_EXT;
size_t size = 0;
if (is_shaders) {
size += pCreateInfo->info.pShaderInfo->maxShaderCount;
} else {
size += pCreateInfo->info.pPipelineInfo->maxPipelineCount;
}
size *= sizeof(int64_t);
size += sizeof(struct lvp_indirect_execution_set);
struct lvp_indirect_execution_set *iset =
vk_zalloc2(&device->vk.alloc, pAllocator, size, alignof(struct lvp_indirect_execution_set),
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!iset)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
vk_object_base_init(&device->vk, &iset->base, VK_OBJECT_TYPE_INDIRECT_EXECUTION_SET_EXT);
iset->is_shaders = is_shaders;
if (is_shaders) {
for (unsigned i = 0; i < pCreateInfo->info.pShaderInfo->shaderCount; i++)
iset->array[i] = pCreateInfo->info.pShaderInfo->pInitialShaders[i];
} else {
iset->array[0] = pCreateInfo->info.pPipelineInfo->initialPipeline;
}
*pIndirectExecutionSet = lvp_indirect_execution_set_to_handle(iset);
return VK_SUCCESS;
}
VKAPI_ATTR void VKAPI_CALL lvp_DestroyIndirectExecutionSetEXT(
VkDevice _device,
VkIndirectExecutionSetEXT indirectExecutionSet,
const VkAllocationCallbacks* pAllocator)
{
VK_FROM_HANDLE(lvp_device, device, _device);
VK_FROM_HANDLE(lvp_indirect_execution_set, iset, indirectExecutionSet);
if (!iset)
return;
vk_object_base_finish(&iset->base);
vk_free2(&device->vk.alloc, pAllocator, iset);
}
VKAPI_ATTR void VKAPI_CALL lvp_UpdateIndirectExecutionSetPipelineEXT(
VkDevice device,
VkIndirectExecutionSetEXT indirectExecutionSet,
uint32_t executionSetWriteCount,
const VkWriteIndirectExecutionSetPipelineEXT* pExecutionSetWrites)
{
VK_FROM_HANDLE(lvp_indirect_execution_set, iset, indirectExecutionSet);
assert(!iset->is_shaders);
for (unsigned i = 0; i < executionSetWriteCount; i++) {
iset->array[pExecutionSetWrites[i].index] = pExecutionSetWrites[i].pipeline;
}
}
VKAPI_ATTR void VKAPI_CALL lvp_UpdateIndirectExecutionSetShaderEXT(
VkDevice device,
VkIndirectExecutionSetEXT indirectExecutionSet,
uint32_t executionSetWriteCount,
const VkWriteIndirectExecutionSetShaderEXT* pExecutionSetWrites)
{
VK_FROM_HANDLE(lvp_indirect_execution_set, iset, indirectExecutionSet);
assert(iset->is_shaders);
for (unsigned i = 0; i < executionSetWriteCount; i++) {
iset->array[pExecutionSetWrites[i].index] = pExecutionSetWrites[i].shader;
}
}
static size_t
get_token_info_size(VkIndirectCommandsTokenTypeEXT type)
{
switch (type) {
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_EXT:
return sizeof(VkIndirectCommandsVertexBufferTokenEXT);
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_SEQUENCE_INDEX_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_DATA_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_DATA_SEQUENCE_INDEX_EXT:
return sizeof(VkIndirectCommandsPushConstantTokenEXT);
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_EXT:
return sizeof(VkIndirectCommandsIndexBufferTokenEXT);
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_EXECUTION_SET_EXT:
return sizeof(VkIndirectCommandsExecutionSetTokenEXT);
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_COUNT_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_COUNT_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_NV_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_COUNT_NV_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_COUNT_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_TRACE_RAYS2_EXT:
return 0;
default: break;
}
UNREACHABLE("unknown token type");
}
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateIndirectCommandsLayoutEXT(
VkDevice _device,
const VkIndirectCommandsLayoutCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkIndirectCommandsLayoutEXT* pIndirectCommandsLayout)
{
VK_FROM_HANDLE(lvp_device, device, _device);
struct lvp_indirect_command_layout_ext *elayout;
size_t token_size = pCreateInfo->tokenCount * sizeof(VkIndirectCommandsLayoutTokenEXT);
for (unsigned i = 0; i < pCreateInfo->tokenCount; i++) {
const VkIndirectCommandsLayoutTokenEXT *token = &pCreateInfo->pTokens[i];
token_size += get_token_info_size(token->type);
}
elayout = vk_indirect_command_layout_create(&device->vk, pCreateInfo, pAllocator, sizeof(struct lvp_indirect_command_layout_ext) + token_size);
if (!elayout)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
enum lvp_indirect_layout_type type = LVP_INDIRECT_COMMAND_LAYOUT_DRAW;
for (unsigned i = 0; i < pCreateInfo->tokenCount; i++) {
const VkIndirectCommandsLayoutTokenEXT *token = &pCreateInfo->pTokens[i];
switch (token->type) {
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_NV_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_EXT:
type = LVP_INDIRECT_COMMAND_LAYOUT_DRAW;
break;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_COUNT_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_COUNT_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_COUNT_NV_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_COUNT_EXT:
type = LVP_INDIRECT_COMMAND_LAYOUT_DRAW_COUNT;
break;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_EXT:
type = LVP_INDIRECT_COMMAND_LAYOUT_DISPATCH;
break;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_TRACE_RAYS2_EXT:
type = LVP_INDIRECT_COMMAND_LAYOUT_RAYS;
break;
default: break;
}
}
elayout->type = type;
/* tokens are the last member of the struct */
size_t tokens_offset = sizeof(struct lvp_indirect_command_layout_ext) + pCreateInfo->tokenCount * sizeof(VkIndirectCommandsLayoutTokenEXT);
typed_memcpy(elayout->tokens, pCreateInfo->pTokens, pCreateInfo->tokenCount);
uint8_t *ptr = ((uint8_t *)elayout) + tokens_offset;
/* after the tokens comes the token data */
for (unsigned i = 0; i < pCreateInfo->tokenCount; i++) {
const VkIndirectCommandsLayoutTokenEXT *token = &pCreateInfo->pTokens[i];
size_t tsize = get_token_info_size(token->type);
if (tsize) {
elayout->tokens[i].data.pPushConstant = (void*)ptr;
memcpy(ptr, token->data.pPushConstant, tsize);
}
ptr += tsize;
}
*pIndirectCommandsLayout = lvp_indirect_command_layout_ext_to_handle(elayout);
return VK_SUCCESS;
}
VKAPI_ATTR void VKAPI_CALL lvp_DestroyIndirectCommandsLayoutEXT(
VkDevice _device,
VkIndirectCommandsLayoutEXT indirectCommandsLayout,
const VkAllocationCallbacks* pAllocator)
{
VK_FROM_HANDLE(lvp_device, device, _device);
VK_FROM_HANDLE(lvp_indirect_command_layout_ext, elayout, indirectCommandsLayout);
if (!elayout)
return;
vk_indirect_command_layout_destroy(&device->vk, pAllocator, &elayout->vk);
}
enum vk_cmd_type
lvp_ext_dgc_token_to_cmd_type(const struct lvp_indirect_command_layout_ext *elayout, const VkIndirectCommandsLayoutTokenEXT *token)
{
switch (token->type) {
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_EXT:
return VK_CMD_BIND_VERTEX_BUFFERS2;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_SEQUENCE_INDEX_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_DATA_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_DATA_SEQUENCE_INDEX_EXT:
return VK_CMD_PUSH_CONSTANTS2;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_EXT:
return VK_CMD_BIND_INDEX_BUFFER2;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_EXECUTION_SET_EXT:
return elayout->vk.is_shaders ? VK_CMD_BIND_SHADERS_EXT : VK_CMD_BIND_PIPELINE;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_EXT:
return VK_CMD_DRAW_INDEXED;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_EXT:
return VK_CMD_DRAW;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_COUNT_EXT:
return VK_CMD_DRAW_INDEXED_INDIRECT;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_COUNT_EXT:
return VK_CMD_DRAW_INDIRECT;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_EXT:
return VK_CMD_DISPATCH;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_TRACE_RAYS2_EXT:
return VK_CMD_TRACE_RAYS_KHR;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_NV_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_COUNT_NV_EXT:
UNREACHABLE("unsupported NV mesh");
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_EXT:
return VK_CMD_DRAW_MESH_TASKS_EXT;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_COUNT_EXT:
return VK_CMD_DRAW_MESH_TASKS_INDIRECT_EXT;
default:
UNREACHABLE("unknown token type");
}
return UINT32_MAX;
}
size_t
lvp_ext_dgc_token_size(const struct lvp_indirect_command_layout_ext *elayout, const VkIndirectCommandsLayoutTokenEXT *token)
{
UNUSED struct vk_cmd_queue_entry *cmd;
enum vk_cmd_type type = lvp_ext_dgc_token_to_cmd_type(elayout, token);
size_t size = vk_cmd_queue_type_sizes[type];
if (token->type == VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_EXT ||
token->type == VK_INDIRECT_COMMANDS_TOKEN_TYPE_SEQUENCE_INDEX_EXT ||
token->type == VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_DATA_EXT ||
token->type == VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_DATA_SEQUENCE_INDEX_EXT) {
size += sizeof(*cmd->u.push_constants2.push_constants_info);
size += token->data.pPushConstant->updateRange.size;
return size;
}
if (token->type == VK_INDIRECT_COMMANDS_TOKEN_TYPE_EXECUTION_SET_EXT) {
/* special case: switch between pipelines/shaders */
/* CmdBindShaders has 2 dynamically sized arrays */
if (elayout->vk.is_shaders)
size += sizeof(int64_t) * util_bitcount(token->data.pExecutionSet->shaderStages) * 2;
return size;
}
if (token->type == VK_INDIRECT_COMMANDS_TOKEN_TYPE_TRACE_RAYS2_EXT)
return size + sizeof(VkStridedDeviceAddressRegionKHR) * 4;
switch (token->type) {
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_EXT:
size += sizeof(*cmd->u.bind_vertex_buffers.buffers);
size += sizeof(*cmd->u.bind_vertex_buffers.offsets);
size += sizeof(*cmd->u.bind_vertex_buffers2.sizes) + sizeof(*cmd->u.bind_vertex_buffers2.strides);
break;
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_EXECUTION_SET_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_COUNT_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_COUNT_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_NV_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_COUNT_NV_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_COUNT_EXT:
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_TRACE_RAYS2_EXT:
break;
default:
UNREACHABLE("unknown type!");
}
return size;
}
VKAPI_ATTR void VKAPI_CALL lvp_GetGeneratedCommandsMemoryRequirementsEXT(
VkDevice device,
const VkGeneratedCommandsMemoryRequirementsInfoEXT* pInfo,
VkMemoryRequirements2* pMemoryRequirements)
{
VK_FROM_HANDLE(lvp_indirect_command_layout_ext, elayout, pInfo->indirectCommandsLayout);
size_t size = sizeof(struct list_head);
for (unsigned i = 0; i < elayout->vk.token_count; i++) {
const VkIndirectCommandsLayoutTokenEXT *token = &elayout->tokens[i];
size += lvp_ext_dgc_token_size(elayout, token);
}
if (elayout->type == LVP_INDIRECT_COMMAND_LAYOUT_DRAW || elayout->type == LVP_INDIRECT_COMMAND_LAYOUT_DRAW_COUNT)
/* set/unset indirect draw offset */
size += sizeof(struct vk_cmd_queue_entry) * (pInfo->maxSequenceCount + 1);
size *= pInfo->maxSequenceCount;
pMemoryRequirements->memoryRequirements.memoryTypeBits = 1;
pMemoryRequirements->memoryRequirements.alignment = 4;
pMemoryRequirements->memoryRequirements.size = align(size, pMemoryRequirements->memoryRequirements.alignment);
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,706 @@
/*
* Copyright © 2019 Red Hat.
*
* 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 (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 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.
*/
#include "lvp_private.h"
#include "util/detect.h"
#include "pipe/p_defines.h"
#include "util/format/u_format.h"
#include "util/u_math.h"
#include "vk_android.h"
#include "vk_util.h"
#include "vk_enum_defines.h"
static bool lvp_is_filter_minmax_format_supported(VkFormat format)
{
/* From the Vulkan spec 1.1.71:
*
* "The following formats must support the
* VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT feature with
* VK_IMAGE_TILING_OPTIMAL, if they support
* VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT."
*/
/* TODO: enable more formats. */
switch (format) {
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R8_SNORM:
case VK_FORMAT_R16_UNORM:
case VK_FORMAT_R16_SNORM:
case VK_FORMAT_R16_SFLOAT:
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_X8_D24_UNORM_PACK32:
case VK_FORMAT_D32_SFLOAT:
case VK_FORMAT_D16_UNORM_S8_UINT:
case VK_FORMAT_D24_UNORM_S8_UINT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
return true;
default:
return false;
}
}
static void
lvp_physical_device_get_format_properties(struct lvp_physical_device *physical_device,
VkFormat format,
VkFormatProperties3 *out_properties)
{
const enum pipe_format pformat = lvp_vk_format_to_pipe_format(format);
const struct util_format_description *desc = util_format_description(pformat);
struct pipe_screen *pscreen = physical_device->pscreen;
VkFormatFeatureFlags2 features = 0, buffer_features = 0;
if (pformat == PIPE_FORMAT_NONE) {
out_properties->linearTilingFeatures = 0;
out_properties->optimalTilingFeatures = 0;
out_properties->bufferFeatures = 0;
return;
}
if (pscreen->is_format_supported(pscreen, pformat, PIPE_TEXTURE_2D, 0, 0,
PIPE_BIND_DEPTH_STENCIL)) {
out_properties->linearTilingFeatures = 0;
out_properties->optimalTilingFeatures =
(VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT |
VK_FORMAT_FEATURE_2_BLIT_SRC_BIT | VK_FORMAT_FEATURE_2_BLIT_DST_BIT |
VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT |
VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_2_COPY_IMAGE_INDIRECT_DST_BIT_KHR);
if (lvp_is_filter_minmax_format_supported(format))
out_properties->optimalTilingFeatures |=
VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
out_properties->bufferFeatures = 0;
return;
}
if (util_format_is_compressed(pformat)) {
if (pscreen->is_format_supported(pscreen, pformat, PIPE_TEXTURE_2D, 0, 0,
PIPE_BIND_SAMPLER_VIEW)) {
features |= (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_2_BLIT_SRC_BIT |
VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT |
VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT |
VK_FORMAT_FEATURE_2_COPY_IMAGE_INDIRECT_DST_BIT_KHR);
}
out_properties->linearTilingFeatures = features;
out_properties->optimalTilingFeatures = features;
out_properties->bufferFeatures = buffer_features;
return;
}
if (!util_format_is_srgb(pformat) &&
pscreen->is_format_supported(pscreen, pformat, PIPE_BUFFER, 0, 0,
PIPE_BIND_VERTEX_BUFFER)) {
buffer_features |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT;
}
if (pscreen->is_format_supported(pscreen, pformat, PIPE_BUFFER, 0, 0,
PIPE_BIND_CONSTANT_BUFFER)) {
buffer_features |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT;
}
if (pscreen->is_format_supported(pscreen, pformat, PIPE_BUFFER, 0, 0,
PIPE_BIND_SHADER_IMAGE)) {
buffer_features |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT |
VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
}
const struct vk_format_ycbcr_info *ycbcr_info =
vk_format_get_ycbcr_info(format);
if (pscreen->is_format_supported(pscreen, pformat, PIPE_TEXTURE_2D, 0, 0,
PIPE_BIND_SAMPLER_VIEW) || ycbcr_info) {
features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT;
if (util_format_has_depth(util_format_description(pformat)))
features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT;
if (!util_format_is_pure_integer(pformat))
features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
if (lvp_is_filter_minmax_format_supported(format))
features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
if (ycbcr_info) {
if (ycbcr_info->n_planes > 1)
features |= VK_FORMAT_FEATURE_DISJOINT_BIT;
features |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT |
VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT;
for (uint8_t plane = 0; plane < ycbcr_info->n_planes; plane++) {
const struct vk_format_ycbcr_plane *plane_info = &ycbcr_info->planes[plane];
if (plane_info->denominator_scales[0] > 1 ||
plane_info->denominator_scales[1] > 1)
features &= ~VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT;
}
/* The subsampled formats have no support for linear filters. */
if (desc->layout != UTIL_FORMAT_LAYOUT_SUBSAMPLED)
features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT;
}
}
if (pscreen->is_format_supported(pscreen, pformat, PIPE_TEXTURE_2D, 0, 0,
PIPE_BIND_RENDER_TARGET)) {
features |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT;
if (!util_format_is_pure_integer(pformat) &&
!(util_format_is_snorm(pformat) && !physical_device->snorm_blend))
features |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT;
}
if (pscreen->is_format_supported(pscreen, pformat, PIPE_TEXTURE_2D, 0, 0,
PIPE_BIND_SHADER_IMAGE)) {
features |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT |
VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT |
VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
}
if (pformat == PIPE_FORMAT_R32_UINT ||
pformat == PIPE_FORMAT_R32_SINT ||
pformat == PIPE_FORMAT_R64_UINT ||
pformat == PIPE_FORMAT_R64_SINT ||
pformat == PIPE_FORMAT_R32_FLOAT) {
features |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT;
buffer_features |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
} else if (pformat == PIPE_FORMAT_R11G11B10_FLOAT ||
pformat == PIPE_FORMAT_R9G9B9E5_FLOAT) {
features |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT;
}
if (features && buffer_features != VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT) {
features |= (VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT |
VK_FORMAT_FEATURE_2_COPY_IMAGE_INDIRECT_DST_BIT_KHR);
}
if (pformat == PIPE_FORMAT_B5G6R5_UNORM) {
features |= (VK_FORMAT_FEATURE_2_BLIT_SRC_BIT |
VK_FORMAT_FEATURE_2_BLIT_DST_BIT);
}
if ((pformat != PIPE_FORMAT_R9G9B9E5_FLOAT) &&
util_format_get_nr_components(pformat) != 3 &&
!ycbcr_info && !util_format_is_int64(desc) &&
pformat != PIPE_FORMAT_R10G10B10A2_SNORM &&
pformat != PIPE_FORMAT_B10G10R10A2_SNORM &&
pformat != PIPE_FORMAT_B10G10R10A2_UNORM) {
features |= (VK_FORMAT_FEATURE_2_BLIT_SRC_BIT |
VK_FORMAT_FEATURE_2_BLIT_DST_BIT);
}
if (vk_acceleration_struct_vtx_format_supported(format))
buffer_features |= VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR;
out_properties->linearTilingFeatures = features;
out_properties->optimalTilingFeatures = features;
out_properties->bufferFeatures = buffer_features;
if (out_properties->linearTilingFeatures)
out_properties->linearTilingFeatures |= VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT;
if (out_properties->optimalTilingFeatures)
out_properties->optimalTilingFeatures |= VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT;
}
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFormatProperties2(
VkPhysicalDevice physicalDevice,
VkFormat format,
VkFormatProperties2* pFormatProperties)
{
VK_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
VkFormatProperties3 format_props;
lvp_physical_device_get_format_properties(physical_device,
format,
&format_props);
pFormatProperties->formatProperties.linearTilingFeatures = vk_format_features2_to_features(format_props.linearTilingFeatures);
pFormatProperties->formatProperties.optimalTilingFeatures = vk_format_features2_to_features(format_props.optimalTilingFeatures);
pFormatProperties->formatProperties.bufferFeatures = vk_format_features2_to_features(format_props.bufferFeatures);
VkFormatProperties3 *prop3 = (void*)vk_find_struct_const(pFormatProperties->pNext, FORMAT_PROPERTIES_3);
if (prop3) {
prop3->linearTilingFeatures = format_props.linearTilingFeatures;
prop3->optimalTilingFeatures = format_props.optimalTilingFeatures;
prop3->bufferFeatures = format_props.bufferFeatures;
}
VkSubpassResolvePerformanceQueryEXT *perf = (void*)vk_find_struct_const(pFormatProperties->pNext, SUBPASS_RESOLVE_PERFORMANCE_QUERY_EXT);
if (perf)
perf->optimal = VK_FALSE;
#if DETECT_OS_LINUX
vk_foreach_struct(ext, pFormatProperties->pNext) {
switch ((unsigned)ext->sType) {
case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT: {
struct VkDrmFormatModifierPropertiesListEXT *modlist = (void *)ext;
modlist->drmFormatModifierCount = 0;
if (pFormatProperties->formatProperties.optimalTilingFeatures) {
modlist->drmFormatModifierCount = 1;
VkDrmFormatModifierPropertiesEXT *mods = &modlist->pDrmFormatModifierProperties[0];
if (mods) {
mods->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
mods->drmFormatModifierPlaneCount = util_format_get_num_planes(lvp_vk_format_to_pipe_format(format));
mods->drmFormatModifierTilingFeatures = pFormatProperties->formatProperties.optimalTilingFeatures;
}
}
break;
}
case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT: {
struct VkDrmFormatModifierPropertiesList2EXT *modlist = (void *)ext;
modlist->drmFormatModifierCount = 0;
if (format_props.optimalTilingFeatures) {
modlist->drmFormatModifierCount = 1;
VkDrmFormatModifierProperties2EXT *mods = &modlist->pDrmFormatModifierProperties[0];
if (mods) {
mods->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
mods->drmFormatModifierPlaneCount = util_format_get_num_planes(lvp_vk_format_to_pipe_format(format));
mods->drmFormatModifierTilingFeatures = format_props.optimalTilingFeatures;
}
}
break;
}
default:
break;
}
}
#endif
}
VKAPI_ATTR VkResult VKAPI_CALL
lvp_GetImageDrmFormatModifierPropertiesEXT(VkDevice _device, VkImage _image,
VkImageDrmFormatModifierPropertiesEXT *pProperties)
{
#if DETECT_OS_LINUX
pProperties->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
return VK_SUCCESS;
#else
return VK_ERROR_OUT_OF_HOST_MEMORY;
#endif
}
static VkResult lvp_get_image_format_properties(struct lvp_physical_device *physical_device,
const VkPhysicalDeviceImageFormatInfo2 *info,
VkImageFormatProperties *pImageFormatProperties)
{
VkFormatProperties3 format_props;
VkFormatFeatureFlags2 format_feature_flags;
VkExtent3D maxExtent;
uint32_t maxMipLevels;
uint32_t maxArraySize;
VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
enum pipe_format pformat = lvp_vk_format_to_pipe_format(info->format);
lvp_physical_device_get_format_properties(physical_device, info->format,
&format_props);
if (info->tiling == VK_IMAGE_TILING_LINEAR) {
format_feature_flags = format_props.linearTilingFeatures;
} else if (info->tiling == VK_IMAGE_TILING_OPTIMAL ||
info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
format_feature_flags = format_props.optimalTilingFeatures;
} else {
UNREACHABLE("bad VkImageTiling");
}
if (format_feature_flags == 0)
goto unsupported;
uint32_t max_2d_ext = physical_device->pscreen->caps.max_texture_2d_size;
uint32_t max_layers = physical_device->pscreen->caps.max_texture_array_layers;
switch (info->type) {
default:
UNREACHABLE("bad vkimage type\n");
case VK_IMAGE_TYPE_1D:
if (util_format_is_compressed(pformat))
goto unsupported;
maxExtent.width = max_2d_ext;
maxExtent.height = 1;
maxExtent.depth = 1;
maxMipLevels = util_logbase2(max_2d_ext) + 1;
maxArraySize = max_layers;
break;
case VK_IMAGE_TYPE_2D:
maxExtent.width = max_2d_ext;
maxExtent.height = max_2d_ext;
maxExtent.depth = 1;
maxMipLevels = util_logbase2(max_2d_ext) + 1;
maxArraySize = max_layers;
if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
!(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
!util_format_is_compressed(pformat) &&
(format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)))
sampleCounts |= VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_8_BIT;
break;
case VK_IMAGE_TYPE_3D:
maxExtent.width = max_2d_ext;
maxExtent.height = max_2d_ext;
maxExtent.depth = (1 << physical_device->pscreen->caps.max_texture_3d_levels);
maxMipLevels = util_logbase2(max_2d_ext) + 1;
maxArraySize = 1;
break;
}
if (info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT)
goto skip_checks;
if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
if (!(format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT))) {
goto unsupported;
}
}
skip_checks:
*pImageFormatProperties = (VkImageFormatProperties) {
.maxExtent = maxExtent,
.maxMipLevels = maxMipLevels,
.maxArrayLayers = maxArraySize,
.sampleCounts = sampleCounts,
/* FINISHME: Accurately calculate
* VkImageFormatProperties::maxResourceSize.
*/
.maxResourceSize = UINT32_MAX,
};
return VK_SUCCESS;
unsupported:
*pImageFormatProperties = (VkImageFormatProperties) {
.maxExtent = { 0, 0, 0 },
.maxMipLevels = 0,
.maxArrayLayers = 0,
.sampleCounts = 0,
.maxResourceSize = 0,
};
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPhysicalDeviceImageFormatProperties2(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceImageFormatInfo2 *base_info,
VkImageFormatProperties2 *base_props)
{
VK_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
VkExternalImageFormatProperties *external_props = NULL;
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
VkHostImageCopyDevicePerformanceQueryEXT *hic;
VkResult result;
result = lvp_get_image_format_properties(physical_device, base_info,
&base_props->imageFormatProperties);
if (result != VK_SUCCESS)
return result;
vk_foreach_struct_const(s, base_info->pNext) {
switch (s->sType) {
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
external_info = (const void *) s;
break;
default:
break;
}
}
/* Extract output structs */
vk_foreach_struct(s, base_props->pNext) {
switch (s->sType) {
case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
external_props = (void *) s;
break;
case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
ycbcr_props = (void *) s;
break;
case VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY_EXT:
hic = (void*)s;
hic->optimalDeviceAccess = VK_TRUE;
hic->identicalMemoryLayout = VK_TRUE;
break;
default:
break;
}
}
if (external_info &&
external_info->handleType ==
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) {
result = vk_android_get_ahb_image_properties(physicalDevice,
base_info, base_props);
if (result != VK_SUCCESS)
return result;
base_props->imageFormatProperties.maxMipLevels = 1;
base_props->imageFormatProperties.maxArrayLayers = 1;
} else if (external_info && external_info->handleType != 0 && external_props) {
VkExternalMemoryFeatureFlagBits flags = 0;
VkExternalMemoryHandleTypeFlags export_flags = 0;
VkExternalMemoryHandleTypeFlags compat_flags = 0;
switch (external_info->handleType) {
#if defined(HAVE_LIBDRM) && defined(HAVE_LINUX_UDMABUF_H)
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: {
int params = physical_device->pscreen->caps.dmabuf;
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
if (params & DRM_PRIME_CAP_EXPORT) {
flags |= VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
compat_flags |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
}
break;
}
#endif
#ifdef PIPE_MEMORY_FD
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
#if defined(HAVE_LIBDRM) && defined(HAVE_LINUX_UDMABUF_H)
int params = physical_device->pscreen->caps.dmabuf;
if (params & DRM_PRIME_CAP_EXPORT)
compat_flags |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
#endif
break;
#endif
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
break;
default:
break;
}
external_props->externalMemoryProperties = (VkExternalMemoryProperties) {
.externalMemoryFeatures = flags,
.exportFromImportedHandleTypes = export_flags,
.compatibleHandleTypes = compat_flags,
};
}
if (ycbcr_props)
ycbcr_props->combinedImageSamplerDescriptorCount = vk_format_get_plane_count(base_info->format);
return VK_SUCCESS;
}
static void
fill_sparse_image_format_properties(VkImageType type,
VkFormat format, VkSampleCountFlagBits samples,
VkSparseImageFormatProperties *prop)
{
enum pipe_format pformat = vk_format_to_pipe_format(format);
prop->aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
prop->flags = 0;
prop->imageGranularity = (VkExtent3D){
.width = util_format_get_tilesize(pformat, type + 1, samples, 0) * util_format_get_blockwidth(pformat),
.height = util_format_get_tilesize(pformat, type + 1, samples, 1) * util_format_get_blockheight(pformat),
.depth = util_format_get_tilesize(pformat, type + 1, samples, 2) * util_format_get_blockdepth(pformat),
};
}
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceSparseImageFormatProperties2(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
uint32_t *pPropertyCount,
VkSparseImageFormatProperties2 *pProperties)
{
VK_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
VkResult result;
if (pFormatInfo->samples > VK_SAMPLE_COUNT_1_BIT) {
*pPropertyCount = 0;
return;
}
const struct util_format_description *desc = vk_format_description(pFormatInfo->format);
if (util_format_is_int64(desc)) {
*pPropertyCount = 0;
return;
}
const VkPhysicalDeviceImageFormatInfo2 fmt_info = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
.format = pFormatInfo->format,
.type = pFormatInfo->type,
.tiling = pFormatInfo->tiling,
.usage = pFormatInfo->usage,
.flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT};
VkImageFormatProperties fmt_props;
result = lvp_get_image_format_properties(physical_device, &fmt_info,
&fmt_props);
if (result != VK_SUCCESS) {
*pPropertyCount = 0;
return;
}
VK_OUTARRAY_MAKE_TYPED(VkSparseImageFormatProperties2, out, pProperties, pPropertyCount);
vk_outarray_append_typed(VkSparseImageFormatProperties2, &out, prop)
{
fill_sparse_image_format_properties(pFormatInfo->type, pFormatInfo->format,
pFormatInfo->samples, &prop->properties);
};
}
VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceImageSparseMemoryRequirements(
VkDevice _device,
const VkDeviceImageMemoryRequirements* pInfo,
uint32_t* pSparseMemoryRequirementCount,
VkSparseImageMemoryRequirements2* pSparseMemoryRequirements)
{
if (!(pInfo->pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
*pSparseMemoryRequirementCount = 0;
return;
}
VK_OUTARRAY_MAKE_TYPED(VkSparseImageMemoryRequirements2, out, pSparseMemoryRequirements,
pSparseMemoryRequirementCount);
vk_outarray_append_typed(VkSparseImageMemoryRequirements2, &out, req)
{
fill_sparse_image_format_properties(pInfo->pCreateInfo->imageType,
pInfo->pCreateInfo->format, pInfo->pCreateInfo->samples,
&req->memoryRequirements.formatProperties);
req->memoryRequirements.imageMipTailFirstLod = pInfo->pCreateInfo->mipLevels;
req->memoryRequirements.imageMipTailSize = 0;
req->memoryRequirements.imageMipTailOffset = 0;
req->memoryRequirements.imageMipTailStride = 0;
};
}
VKAPI_ATTR void VKAPI_CALL lvp_GetImageSparseMemoryRequirements2(
VkDevice _device,
const VkImageSparseMemoryRequirementsInfo2* pInfo,
uint32_t* pSparseMemoryRequirementCount,
VkSparseImageMemoryRequirements2* pSparseMemoryRequirements)
{
VK_FROM_HANDLE(lvp_image, image, pInfo->image);
if (!(image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
*pSparseMemoryRequirementCount = 0;
return;
}
VK_OUTARRAY_MAKE_TYPED(VkSparseImageMemoryRequirements2, out, pSparseMemoryRequirements,
pSparseMemoryRequirementCount);
vk_outarray_append_typed(VkSparseImageMemoryRequirements2, &out, req)
{
fill_sparse_image_format_properties(image->vk.image_type,
image->vk.format, image->vk.samples,
&req->memoryRequirements.formatProperties);
req->memoryRequirements.imageMipTailFirstLod = image->vk.mip_levels;
req->memoryRequirements.imageMipTailSize = 0;
req->memoryRequirements.imageMipTailOffset = 0;
req->memoryRequirements.imageMipTailStride = 0;
};
}
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalBufferProperties(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
VkExternalBufferProperties *pExternalBufferProperties)
{
if (pExternalBufferInfo->handleType ==
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) {
vk_android_get_ahb_buffer_properties(
physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
return;
}
VkExternalMemoryFeatureFlagBits flags = 0;
VkExternalMemoryHandleTypeFlags export_flags = 0;
VkExternalMemoryHandleTypeFlags compat_flags = 0;
switch (pExternalBufferInfo->handleType) {
#if defined(HAVE_LIBDRM) && defined(HAVE_LINUX_UDMABUF_H)
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: {
VK_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
int params = physical_device->pscreen->caps.dmabuf;
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
if (params & DRM_PRIME_CAP_EXPORT)
flags |= VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
break;
}
#endif
#ifdef PIPE_MEMORY_FD
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
break;
#endif
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
break;
default:
break;
}
pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryProperties) {
.externalMemoryFeatures = flags,
.exportFromImportedHandleTypes = export_flags,
.compatibleHandleTypes = compat_flags,
};
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,317 @@
/*
* Copyright © 2022 Collabora Ltd.
*
* 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 (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 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.
*/
#include "lvp_private.h"
#include "util/timespec.h"
#include "vk_common_entrypoints.h"
static void
lvp_pipe_sync_validate(ASSERTED struct lvp_pipe_sync *sync)
{
if (sync->signaled)
assert(sync->fence == NULL);
}
static VkResult
lvp_pipe_sync_init(UNUSED struct vk_device *vk_device,
struct vk_sync *vk_sync,
uint64_t initial_value)
{
struct lvp_pipe_sync *sync = vk_sync_as_lvp_pipe_sync(vk_sync);
mtx_init(&sync->lock, mtx_plain);
cnd_init(&sync->changed);
sync->signaled = (initial_value != 0);
sync->fence = NULL;
return VK_SUCCESS;
}
static void
lvp_pipe_sync_finish(struct vk_device *vk_device,
struct vk_sync *vk_sync)
{
struct lvp_device *device = container_of(vk_device, struct lvp_device, vk);
struct lvp_pipe_sync *sync = vk_sync_as_lvp_pipe_sync(vk_sync);
lvp_pipe_sync_validate(sync);
if (sync->fence)
device->pscreen->fence_reference(device->pscreen, &sync->fence, NULL);
cnd_destroy(&sync->changed);
mtx_destroy(&sync->lock);
}
void
lvp_pipe_sync_signal_with_fence(struct lvp_device *device,
struct lvp_pipe_sync *sync,
struct pipe_fence_handle *fence)
{
mtx_lock(&sync->lock);
lvp_pipe_sync_validate(sync);
sync->signaled = fence == NULL;
device->pscreen->fence_reference(device->pscreen, &sync->fence, fence);
cnd_broadcast(&sync->changed);
mtx_unlock(&sync->lock);
}
static VkResult
lvp_pipe_sync_signal(struct vk_device *vk_device,
struct vk_sync *vk_sync,
uint64_t value)
{
struct lvp_device *device = container_of(vk_device, struct lvp_device, vk);
struct lvp_pipe_sync *sync = vk_sync_as_lvp_pipe_sync(vk_sync);
mtx_lock(&sync->lock);
lvp_pipe_sync_validate(sync);
sync->signaled = true;
if (sync->fence)
device->pscreen->fence_reference(device->pscreen, &sync->fence, NULL);
cnd_broadcast(&sync->changed);
mtx_unlock(&sync->lock);
return VK_SUCCESS;
}
static VkResult
lvp_pipe_sync_reset(struct vk_device *vk_device,
struct vk_sync *vk_sync)
{
struct lvp_device *device = container_of(vk_device, struct lvp_device, vk);
struct lvp_pipe_sync *sync = vk_sync_as_lvp_pipe_sync(vk_sync);
mtx_lock(&sync->lock);
lvp_pipe_sync_validate(sync);
sync->signaled = false;
if (sync->fence)
device->pscreen->fence_reference(device->pscreen, &sync->fence, NULL);
cnd_broadcast(&sync->changed);
mtx_unlock(&sync->lock);
return VK_SUCCESS;
}
static VkResult
lvp_pipe_sync_move(struct vk_device *vk_device,
struct vk_sync *vk_dst,
struct vk_sync *vk_src)
{
struct lvp_device *device = container_of(vk_device, struct lvp_device, vk);
struct lvp_pipe_sync *dst = vk_sync_as_lvp_pipe_sync(vk_dst);
struct lvp_pipe_sync *src = vk_sync_as_lvp_pipe_sync(vk_src);
/* Pull the fence out of the source */
mtx_lock(&src->lock);
struct pipe_fence_handle *fence = src->fence;
bool signaled = src->signaled;
src->fence = NULL;
src->signaled = false;
cnd_broadcast(&src->changed);
mtx_unlock(&src->lock);
mtx_lock(&dst->lock);
if (dst->fence)
device->pscreen->fence_reference(device->pscreen, &dst->fence, NULL);
dst->fence = fence;
dst->signaled = signaled;
cnd_broadcast(&dst->changed);
mtx_unlock(&dst->lock);
return VK_SUCCESS;
}
static VkResult
lvp_pipe_sync_wait_locked(struct lvp_device *device,
struct lvp_pipe_sync *sync,
uint64_t wait_value,
enum vk_sync_wait_flags wait_flags,
uint64_t abs_timeout_ns)
{
assert(!(wait_flags & VK_SYNC_WAIT_ANY));
lvp_pipe_sync_validate(sync);
uint64_t now_ns = os_time_get_nano();
while (!sync->signaled && !sync->fence) {
if (now_ns >= abs_timeout_ns)
return VK_TIMEOUT;
int ret;
if (abs_timeout_ns >= INT64_MAX) {
/* Common infinite wait case */
ret = cnd_wait(&sync->changed, &sync->lock);
} else {
/* This is really annoying. The C11 threads API uses CLOCK_REALTIME
* while all our absolute timeouts are in CLOCK_MONOTONIC. Best
* thing we can do is to convert and hope the system admin doesn't
* change the time out from under us.
*/
uint64_t rel_timeout_ns = abs_timeout_ns - now_ns;
struct timespec now_ts, abs_timeout_ts;
timespec_get(&now_ts, TIME_UTC);
if (timespec_add_nsec(&abs_timeout_ts, &now_ts, rel_timeout_ns)) {
/* Overflowed; may as well be infinite */
ret = cnd_wait(&sync->changed, &sync->lock);
} else {
ret = cnd_timedwait(&sync->changed, &sync->lock, &abs_timeout_ts);
}
}
if (ret == thrd_error)
return vk_errorf(device, VK_ERROR_UNKNOWN, "cnd_timedwait failed");
lvp_pipe_sync_validate(sync);
/* We don't trust the timeout condition on cnd_timedwait() because of
* the potential clock issues caused by using CLOCK_REALTIME. Instead,
* update now_ns, go back to the top of the loop, and re-check.
*/
now_ns = os_time_get_nano();
}
if (sync->signaled || (wait_flags & VK_SYNC_WAIT_PENDING))
return VK_SUCCESS;
/* Grab a reference before we drop the lock */
struct pipe_fence_handle *fence = NULL;
device->pscreen->fence_reference(device->pscreen, &fence, sync->fence);
mtx_unlock(&sync->lock);
uint64_t rel_timeout_ns =
now_ns >= abs_timeout_ns ? 0 : abs_timeout_ns - now_ns;
bool complete = device->pscreen->fence_finish(device->pscreen, NULL,
fence, rel_timeout_ns);
device->pscreen->fence_reference(device->pscreen, &fence, NULL);
mtx_lock(&sync->lock);
lvp_pipe_sync_validate(sync);
if (!complete)
return VK_TIMEOUT;
if (sync->fence == fence) {
device->pscreen->fence_reference(device->pscreen, &sync->fence, NULL);
sync->signaled = true;
}
return VK_SUCCESS;
}
static VkResult
lvp_pipe_sync_wait(struct vk_device *vk_device,
struct vk_sync *vk_sync,
uint64_t wait_value,
enum vk_sync_wait_flags wait_flags,
uint64_t abs_timeout_ns)
{
struct lvp_device *device = container_of(vk_device, struct lvp_device, vk);
struct lvp_pipe_sync *sync = vk_sync_as_lvp_pipe_sync(vk_sync);
mtx_lock(&sync->lock);
VkResult result = lvp_pipe_sync_wait_locked(device, sync, wait_value,
wait_flags, abs_timeout_ns);
mtx_unlock(&sync->lock);
return result;
}
#ifdef HAVE_LIBDRM
static VkResult
lvp_pipe_import_sync_file(struct vk_device *vk_device,
struct vk_sync *vk_sync,
int sync_file)
{
struct lvp_device *device = container_of(vk_device, struct lvp_device, vk);
struct lvp_pipe_sync *sync = vk_sync_as_lvp_pipe_sync(vk_sync);
struct pipe_fence_handle *fence;
device->queue.ctx->create_fence_fd(
device->queue.ctx, &fence, sync_file, PIPE_FD_TYPE_NATIVE_SYNC);
if (fence == NULL)
return VK_ERROR_OUT_OF_HOST_MEMORY;
lvp_pipe_sync_signal_with_fence(device, sync, fence);
device->pscreen->fence_reference(device->pscreen, &fence, NULL);
return VK_SUCCESS;
}
static VkResult
lvp_pipe_export_sync_file(struct vk_device *vk_device,
struct vk_sync *vk_sync,
int *sync_file)
{
struct lvp_pipe_sync *sync = vk_sync_as_lvp_pipe_sync(vk_sync);
/* It's not ideal, but since we cannot properly support sync files
* from userspace, what we will do instead is wait for lavapipe to
* finish rendering, so that we can safely export a sync file that
* has already been signalled.
*/
vk_common_DeviceWaitIdle(vk_device_to_handle(vk_device));
struct lvp_device *device = container_of(vk_device, struct lvp_device, vk);
/* If native_fence_fd is supported we use the gallium context to perform the
* export, otherwise we return -1 which is still a valid sync fd in vulkan
*/
if (device->pscreen->caps.native_fence_fd) {
*sync_file = device->pscreen->fence_get_fd(device->pscreen, sync->fence);
return *sync_file != -1 ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
} else {
struct pipe_fence_handle *handle = NULL;
device->queue.ctx->flush(device->queue.ctx, &handle, 0);
device->pscreen->fence_finish(device->pscreen, NULL,
handle, OS_TIMEOUT_INFINITE);
device->pscreen->fence_reference(device->pscreen, &handle, NULL);
*sync_file = -1;
return VK_SUCCESS;
}
}
#endif
const struct vk_sync_type lvp_pipe_sync_type = {
.size = sizeof(struct lvp_pipe_sync),
.features = VK_SYNC_FEATURE_BINARY |
VK_SYNC_FEATURE_GPU_WAIT |
VK_SYNC_FEATURE_GPU_MULTI_WAIT |
VK_SYNC_FEATURE_CPU_WAIT |
VK_SYNC_FEATURE_CPU_RESET |
VK_SYNC_FEATURE_CPU_SIGNAL |
VK_SYNC_FEATURE_WAIT_PENDING,
.init = lvp_pipe_sync_init,
.finish = lvp_pipe_sync_finish,
.signal = lvp_pipe_sync_signal,
.reset = lvp_pipe_sync_reset,
.move = lvp_pipe_sync_move,
.wait = lvp_pipe_sync_wait,
#ifdef HAVE_LIBDRM
.import_sync_file = lvp_pipe_import_sync_file,
.export_sync_file = lvp_pipe_export_sync_file,
#endif
};
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,101 @@
/*
* Copyright © 2019 Red Hat.
*
* 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 (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 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.
*/
#include "lvp_private.h"
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreatePipelineCache(
VkDevice _device,
const VkPipelineCacheCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkPipelineCache* pPipelineCache)
{
VK_FROM_HANDLE(lvp_device, device, _device);
struct lvp_pipeline_cache *cache;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO);
cache = vk_alloc2(&device->vk.alloc, pAllocator,
sizeof(*cache), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (cache == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
vk_object_base_init(&device->vk, &cache->base,
VK_OBJECT_TYPE_PIPELINE_CACHE);
if (pAllocator)
cache->alloc = *pAllocator;
else
cache->alloc = device->vk.alloc;
*pPipelineCache = lvp_pipeline_cache_to_handle(cache);
return VK_SUCCESS;
}
VKAPI_ATTR void VKAPI_CALL lvp_DestroyPipelineCache(
VkDevice _device,
VkPipelineCache _cache,
const VkAllocationCallbacks* pAllocator)
{
VK_FROM_HANDLE(lvp_device, device, _device);
VK_FROM_HANDLE(lvp_pipeline_cache, cache, _cache);
if (!_cache)
return;
// lvp_pipeline_cache_finish(cache);
vk_object_base_finish(&cache->base);
vk_free2(&device->vk.alloc, pAllocator, cache);
}
VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPipelineCacheData(
VkDevice _device,
VkPipelineCache _cache,
size_t* pDataSize,
void* pData)
{
VkResult result = VK_SUCCESS;
if (pData) {
if (*pDataSize < 32) {
*pDataSize = 0;
result = VK_INCOMPLETE;
} else {
uint32_t *hdr = (uint32_t *)pData;
hdr[0] = 32;
hdr[1] = 1;
hdr[2] = VK_VENDOR_ID_MESA;
hdr[3] = 0;
lvp_device_get_cache_uuid(&hdr[4]);
}
} else
*pDataSize = 32;
return result;
}
VKAPI_ATTR VkResult VKAPI_CALL lvp_MergePipelineCaches(
VkDevice _device,
VkPipelineCache destCache,
uint32_t srcCacheCount,
const VkPipelineCache* pSrcCaches)
{
return VK_SUCCESS;
}
@@ -0,0 +1,901 @@
/*
* Copyright © 2019 Red Hat.
*
* 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 (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 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.
*/
#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
#include <llvm/Config/llvm-config.h>
#include "util/macros.h"
#include "util/list.h"
#include "util/u_dynarray.h"
#include "util/simple_mtx.h"
#include "util/u_queue.h"
#include "util/u_upload_mgr.h"
#include "compiler/shader_enums.h"
#include "pipe/p_screen.h"
#include "pipe/p_state.h"
#include "cso_cache/cso_context.h"
#include "nir.h"
#include "nir/nir_lower_blend.h"
#ifdef HAVE_LIBDRM
#include <drm-uapi/drm.h>
#include "drm-uapi/drm_fourcc.h"
#endif
/* Pre-declarations needed for WSI entrypoints */
struct wl_surface;
struct wl_display;
typedef struct xcb_connection_t xcb_connection_t;
typedef uint32_t xcb_visualid_t;
typedef uint32_t xcb_window_t;
#define VK_PROTOTYPES
#include <vulkan/vulkan.h>
#include <vulkan/vk_icd.h>
#include "lvp_entrypoints.h"
#include "vk_acceleration_structure.h"
#include "vk_buffer.h"
#include "vk_buffer_view.h"
#include "vk_device.h"
#include "vk_device_generated_commands.h"
#include "vk_device_memory.h"
#include "vk_instance.h"
#include "vk_image.h"
#include "vk_log.h"
#include "vk_physical_device.h"
#include "vk_shader_module.h"
#include "vk_util.h"
#include "vk_format.h"
#include "vk_cmd_queue.h"
#include "vk_command_buffer.h"
#include "vk_command_pool.h"
#include "vk_descriptor_set_layout.h"
#include "vk_graphics_state.h"
#include "vk_pipeline_layout.h"
#include "vk_queue.h"
#include "vk_query_pool.h"
#include "vk_sampler.h"
#include "vk_sync.h"
#include "vk_sync_timeline.h"
#include "vk_ycbcr_conversion.h"
#include "vk_meta.h"
#include "lp_jit.h"
#include "wsi_common.h"
#include <assert.h>
#ifdef __cplusplus
extern "C" {
#endif
#define LVP_NUM_QUEUES 1
#define MAX_SETS 8
#define MAX_DESCRIPTORS ((1<<20) - (1<<15)) /* Required by VK_EXT_descriptor_heap */
#define MAX_PUSH_CONSTANTS_SIZE 256
#define MAX_PUSH_DESCRIPTORS 32
#define MAX_DESCRIPTOR_UNIFORM_BLOCK_SIZE MAX_DESCRIPTORS
#define MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS 8
#define MAX_DGC_STREAMS 16
#define MAX_DGC_TOKENS 16
#define LVP_MAX_PLANE_COUNT 3
#define LVP_MAX_TLAS_DEPTH 24
#define LVP_MAX_BLAS_DEPTH 29
#ifdef _WIN32
#define lvp_printflike(a, b)
#else
#define lvp_printflike(a, b) __attribute__((__format__(__printf__, a, b)))
#endif
#define LVP_DEBUG_ALL_ENTRYPOINTS (1 << 0)
void __lvp_finishme(const char *file, int line, const char *format, ...)
lvp_printflike(3, 4);
#define lvp_finishme(format, ...) \
__lvp_finishme(__FILE__, __LINE__, format, ##__VA_ARGS__);
#define stub_return(v) \
do { \
lvp_finishme("stub %s", __func__); \
return (v); \
} while (0)
#define stub() \
do { \
lvp_finishme("stub %s", __func__); \
return; \
} while (0)
#define LVP_SHADER_STAGES (MESA_SHADER_CALLABLE + 1)
#define LVP_STAGE_MASK BITFIELD_MASK(LVP_SHADER_STAGES)
#define LVP_STAGE_MASK_GFX (BITFIELD_MASK(MESA_SHADER_MESH_STAGES) & ~BITFIELD_BIT(MESA_SHADER_COMPUTE))
#define lvp_forall_stage(stage) \
for (mesa_shader_stage stage = MESA_SHADER_VERTEX; stage < LVP_SHADER_STAGES; stage++)
#define lvp_forall_gfx_stage(stage) \
for (mesa_shader_stage stage, \
__tmp = (mesa_shader_stage)(LVP_STAGE_MASK_GFX); \
stage = ffs(__tmp) - 1, __tmp; \
__tmp &= ~(1 << (stage)))
enum lvp_descriptor_heap {
LVP_DESCRIPTOR_HEAP_RESOURCE,
LVP_DESCRIPTOR_HEAP_SAMPLER,
LVP_DESCRIPTOR_HEAP_EMBEDDED,
LVP_DESCRIPTOR_HEAP_COUNT,
};
struct lvp_physical_device {
struct vk_physical_device vk;
struct pipe_loader_device *pld;
struct pipe_screen *pscreen;
const nir_shader_compiler_options *drv_options[LVP_SHADER_STAGES];
uint32_t max_images;
bool snorm_blend;
struct vk_sync_timeline_type sync_timeline_type;
const struct vk_sync_type *sync_types[3];
struct wsi_device wsi_device;
};
struct lvp_instance {
struct vk_instance vk;
uint64_t debug_flags;
struct pipe_loader_device *devs;
int num_devices;
};
VkResult lvp_init_wsi(struct lvp_physical_device *physical_device);
void lvp_finish_wsi(struct lvp_physical_device *physical_device);
bool lvp_physical_device_extension_supported(struct lvp_physical_device *dev,
const char *name);
struct lvp_queue {
struct vk_queue vk;
struct pipe_context *ctx;
struct cso_context *cso;
struct u_upload_mgr *uploader;
struct pipe_fence_handle *last_fence;
void *state;
struct util_dynarray pipeline_destroys;
simple_mtx_t lock;
};
static inline struct lvp_device *
lvp_queue_device(const struct lvp_queue *queue)
{
return (struct lvp_device *)queue->vk.base.device;
}
struct lvp_pipeline_cache {
struct vk_object_base base;
VkAllocationCallbacks alloc;
};
struct lvp_device {
struct vk_device vk;
struct lvp_queue queue;
struct pipe_screen *pscreen;
void *noop_fs;
simple_mtx_t bda_lock;
struct hash_table bda;
struct pipe_resource *zero_buffer; /* for zeroed bda */
bool poison_mem;
bool print_cmds;
struct lp_texture_handle *null_texture_handle;
struct lp_texture_handle *null_image_handle;
struct util_dynarray bda_texture_handles;
struct util_dynarray bda_image_handles;
uint32_t group_handle_alloc;
struct vk_meta_device meta;
radix_sort_vk_t *radix_sort;
simple_mtx_t radix_sort_lock;
struct vk_acceleration_structure_build_args accel_struct_args;
};
static inline const struct lvp_physical_device *
lvp_device_physical(const struct lvp_device *dev)
{
return (struct lvp_physical_device *)dev->vk.physical;
}
void lvp_device_get_cache_uuid(void *uuid);
enum lvp_device_memory_type {
LVP_DEVICE_MEMORY_TYPE_DEFAULT,
LVP_DEVICE_MEMORY_TYPE_USER_PTR,
LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD,
LVP_DEVICE_MEMORY_TYPE_DMA_BUF,
};
struct lvp_device_memory {
struct vk_device_memory vk;
struct pipe_memory_allocation *pmem;
struct llvmpipe_memory_allocation mem_alloc;
VkDeviceSize map_size;
void *map;
enum lvp_device_memory_type memory_type;
int backed_fd;
};
struct lvp_pipe_sync {
struct vk_sync base;
mtx_t lock;
cnd_t changed;
bool signaled;
struct pipe_fence_handle *fence;
};
extern const struct vk_sync_type lvp_pipe_sync_type;
void lvp_pipe_sync_signal_with_fence(struct lvp_device *device,
struct lvp_pipe_sync *sync,
struct pipe_fence_handle *fence);
static inline struct lvp_pipe_sync *
vk_sync_as_lvp_pipe_sync(struct vk_sync *sync)
{
assert(sync->type == &lvp_pipe_sync_type);
return container_of(sync, struct lvp_pipe_sync, base);
}
struct lvp_image_plane {
struct pipe_resource *bo;
VkDeviceSize offset;
VkDeviceSize size;
};
struct lvp_image {
struct vk_image vk;
VkDeviceSize size;
uint32_t alignment;
bool disjoint;
uint8_t plane_count;
struct lvp_image_plane planes[3];
};
struct lvp_image_view {
struct vk_image_view vk;
enum pipe_format pformat;
uint8_t plane_count;
struct pipe_surface surface; /* have we created a pipe surface for this? */
struct lvp_image_view *multisample; //VK_EXT_multisampled_render_to_single_sampled
struct {
unsigned image_plane;
struct pipe_sampler_view *sv;
struct pipe_image_view iv;
struct lp_texture_handle *texture_handle;
struct lp_texture_handle *image_handle;
} planes[3];
};
struct lvp_sampler {
struct vk_sampler vk;
struct lp_sampler_descriptor desc;
};
struct lvp_descriptor_set_binding_layout {
uint32_t offset;
/* Number of array elements in this binding */
VkDescriptorType type;
uint32_t stride; /* used for planar samplers */
uint32_t max_plane_count;
uint32_t array_size;
bool valid;
uint32_t dynamic_index;
uint32_t uniform_block_offset;
uint32_t uniform_block_size;
/* Immutable samplers (or NULL if no immutable samplers) */
struct lp_sampler_descriptor *immutable_samplers;
struct vk_ycbcr_conversion_state *immutable_ycbcr;
};
struct lvp_descriptor_set_layout {
struct vk_descriptor_set_layout vk;
/* add new members after this */
uint32_t immutable_sampler_count;
/* Number of bindings in this descriptor set */
uint32_t binding_count;
/* Total size of the descriptor set with room for all array entries */
uint32_t size;
/* Shader stages affected by this descriptor set */
uint32_t shader_stages;
/* Number of dynamic offsets used by this descriptor set */
uint32_t dynamic_offset_count;
/* if this layout is comprised solely of immutable samplers, this will be a bindable set */
struct lvp_descriptor_set *immutable_set;
/* Bindings in this descriptor set */
struct lvp_descriptor_set_binding_layout binding[0];
};
static inline const struct lvp_descriptor_set_layout *
vk_to_lvp_descriptor_set_layout(const struct vk_descriptor_set_layout *layout)
{
return container_of(layout, const struct lvp_descriptor_set_layout, vk);
}
struct lvp_descriptor_set {
struct vk_object_base base;
struct lvp_descriptor_set_layout *layout;
struct list_head link;
/* Buffer holding the descriptors. */
struct pipe_memory_allocation *pmem;
struct pipe_resource *bo;
uint8_t *map;
};
struct lvp_descriptor_pool {
struct vk_object_base base;
VkDescriptorPoolCreateFlags flags;
uint32_t max_sets;
struct list_head sets;
};
VkResult
lvp_descriptor_set_create(struct lvp_device *device,
struct lvp_descriptor_set_layout *layout,
struct lvp_descriptor_set **out_set);
void
lvp_descriptor_set_destroy(struct lvp_device *device,
struct lvp_descriptor_set *set);
void
lvp_descriptor_set_update_with_template(VkDevice _device, VkDescriptorSet descriptorSet,
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
const void *pData);
struct lvp_image_sampler_descriptor {
struct lp_image_descriptor image;
struct lp_sampler_descriptor sampler;
};
uint32_t lvp_get_descriptor_size(VkDescriptorType type);
uint32_t lvp_get_sampler_descriptor_offset(VkDescriptorType type);
struct lvp_pipeline_layout {
struct vk_pipeline_layout vk;
uint32_t push_constant_size;
VkShaderStageFlags push_constant_stages;
};
struct lvp_pipeline_layout *
lvp_pipeline_layout_create(struct lvp_device *device,
const VkPipelineLayoutCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator);
struct lvp_pipeline_nir {
int ref_cnt;
nir_shader *nir;
};
struct lvp_pipeline_nir *
lvp_create_pipeline_nir(nir_shader *nir);
static inline void
lvp_pipeline_nir_ref(struct lvp_pipeline_nir **dst, struct lvp_pipeline_nir *src)
{
struct lvp_pipeline_nir *old_dst = *dst;
if (old_dst == src || (old_dst && src && old_dst->nir == src->nir))
return;
if (old_dst && p_atomic_dec_zero(&old_dst->ref_cnt)) {
ralloc_free(old_dst->nir);
ralloc_free(old_dst);
}
if (src)
p_atomic_inc(&src->ref_cnt);
*dst = src;
}
struct lvp_shader {
struct vk_object_base base;
struct lvp_pipeline_layout *layout;
struct pipe_memory_allocation *embedded_samplers_memory;
struct lp_sampler_descriptor *embedded_samplers_map;
struct pipe_resource *embedded_samplers;
struct lvp_pipeline_nir *pipeline_nir;
struct lvp_pipeline_nir *tess_ccw;
void *shader_cso;
void *tess_ccw_cso;
struct pipe_stream_output_info stream_output;
struct blob blob; //preserved for GetShaderBinaryDataEXT
uint32_t push_constant_size;
bool heaps;
};
enum lvp_pipeline_type {
LVP_PIPELINE_GRAPHICS,
LVP_PIPELINE_COMPUTE,
LVP_PIPELINE_RAY_TRACING,
LVP_PIPELINE_EXEC_GRAPH,
LVP_PIPELINE_TYPE_COUNT,
};
static inline enum lvp_pipeline_type
lvp_pipeline_type_from_bind_point(VkPipelineBindPoint bind_point)
{
switch (bind_point) {
case VK_PIPELINE_BIND_POINT_GRAPHICS: return LVP_PIPELINE_GRAPHICS;
case VK_PIPELINE_BIND_POINT_COMPUTE: return LVP_PIPELINE_COMPUTE;
case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR: return LVP_PIPELINE_RAY_TRACING;
#ifdef VK_ENABLE_BETA_EXTENSIONS
case VK_PIPELINE_BIND_POINT_EXECUTION_GRAPH_AMDX: return LVP_PIPELINE_EXEC_GRAPH;
#endif
default: UNREACHABLE("Unsupported VkPipelineBindPoint");
}
}
#define LVP_RAY_TRACING_STAGES (VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR | \
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR | \
VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR)
static inline uint32_t
lvp_pipeline_types_from_shader_stages(VkShaderStageFlags stageFlags)
{
uint32_t types = 0;
#ifdef VK_ENABLE_BETA_EXTENSIONS
if (stageFlags & MESA_VK_SHADER_STAGE_WORKGRAPH_HACK_BIT_FIXME)
types |= BITFIELD_BIT(LVP_PIPELINE_EXEC_GRAPH);
#endif
if (stageFlags & LVP_RAY_TRACING_STAGES)
types |= BITFIELD_BIT(LVP_PIPELINE_RAY_TRACING);
if (stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
types |= BITFIELD_BIT(LVP_PIPELINE_COMPUTE);
if (stageFlags & (VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_MESH_BIT_EXT | VK_SHADER_STAGE_TASK_BIT_EXT))
types |= BITFIELD_BIT(LVP_PIPELINE_GRAPHICS);
return types;
}
#define LVP_RAY_TRACING_GROUP_HANDLE_SIZE 32
#define LVP_RAY_HIT_ATTRIBS_SIZE 32
struct lvp_ray_tracing_group_handle {
uint32_t index;
};
struct lvp_ray_tracing_group {
struct lvp_ray_tracing_group_handle handle;
uint32_t recursive_index;
uint32_t ahit_index;
uint32_t isec_index;
};
struct lvp_pipeline {
struct vk_object_base base;
struct lvp_pipeline_layout *layout;
enum lvp_pipeline_type type;
VkPipelineCreateFlags2KHR flags;
void *state_data;
bool force_min_sample;
struct lvp_shader shaders[LVP_SHADER_STAGES];
mesa_shader_stage last_vertex;
struct vk_graphics_pipeline_state graphics_state;
VkGraphicsPipelineLibraryFlagsEXT stages;
bool line_smooth;
bool disable_multisample;
bool line_rectangular;
bool library;
bool compiled;
bool used;
bool heaps;
struct {
const char *name;
const char *next_name;
uint32_t index;
uint32_t scratch_size;
} exec_graph;
struct {
struct lvp_pipeline_nir **stages;
struct lvp_ray_tracing_group *groups;
uint32_t stage_count;
uint32_t group_count;
} rt;
uint8_t advanced_blend_rts;
unsigned num_groups;
unsigned num_groups_total;
VkPipeline groups[0];
};
static inline struct lvp_device *
lvp_pipeline_device(const struct lvp_pipeline *pipeline)
{
return (struct lvp_device *)pipeline->base.device;
}
/* Minimum requirement by the spec. */
#define LVP_MAX_EXEC_GRAPH_PAYLOADS 256
struct lvp_exec_graph_shader_output {
uint32_t payload_count;
uint32_t node_index;
};
struct lvp_exec_graph_internal_data {
/* inputs */
void *payload_in;
void *payloads;
/* outputs */
struct lvp_exec_graph_shader_output outputs[LVP_MAX_EXEC_GRAPH_PAYLOADS];
};
void
lvp_pipeline_shaders_compile(struct lvp_pipeline *pipeline, bool locked);
struct lvp_event {
struct vk_object_base base;
volatile uint64_t event_storage;
};
struct lvp_buffer {
struct vk_buffer vk;
struct pipe_resource *bo;
uint64_t total_size;
void *map;
struct pipe_transfer *transfer;
};
struct lvp_buffer_view {
struct vk_buffer_view vk;
enum pipe_format pformat;
struct pipe_sampler_view *sv;
struct pipe_image_view iv;
struct lp_texture_handle *texture_handle;
struct lp_texture_handle *image_handle;
};
#define LVP_QUERY_ACCELERATION_STRUCTURE_COMPACTED_SIZE (PIPE_QUERY_TYPES)
#define LVP_QUERY_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE (PIPE_QUERY_TYPES + 1)
#define LVP_QUERY_ACCELERATION_STRUCTURE_SIZE (PIPE_QUERY_TYPES + 2)
#define LVP_QUERY_ACCELERATION_STRUCTURE_INSTANCE_COUNT (PIPE_QUERY_TYPES + 3)
struct lvp_query_pool {
struct vk_query_pool vk;
enum pipe_query_type base_type;
struct pipe_query *queries[0];
};
struct lvp_cmd_buffer {
struct vk_command_buffer vk;
uint8_t push_constants[MAX_PUSH_CONSTANTS_SIZE];
VkCommandBufferInheritanceRenderingInfo rendering_info; //for secondaries
};
static inline struct lvp_device *
lvp_cmd_buffer_device(const struct lvp_cmd_buffer *cmd_buffer)
{
return (struct lvp_device *)cmd_buffer->vk.base.device;
}
struct lvp_indirect_command_layout_nv {
struct vk_object_base base;
uint8_t stream_count;
uint8_t token_count;
uint16_t stream_strides[MAX_DGC_STREAMS];
VkPipelineBindPoint bind_point;
VkIndirectCommandsLayoutUsageFlagsNV flags;
VkIndirectCommandsLayoutTokenNV tokens[0];
};
struct lvp_indirect_execution_set {
struct vk_object_base base;
bool is_shaders;
#if VK_USE_64_BIT_PTR_DEFINES
void *array[0];
#else
uint64_t array[0];
#endif
};
enum lvp_indirect_layout_type {
LVP_INDIRECT_COMMAND_LAYOUT_DRAW,
LVP_INDIRECT_COMMAND_LAYOUT_DRAW_COUNT,
LVP_INDIRECT_COMMAND_LAYOUT_DISPATCH,
LVP_INDIRECT_COMMAND_LAYOUT_RAYS,
};
struct lvp_indirect_command_layout_ext {
struct vk_indirect_command_layout vk;
enum lvp_indirect_layout_type type;
VkIndirectCommandsLayoutTokenEXT tokens[0];
};
extern const struct vk_command_buffer_ops lvp_cmd_buffer_ops;
static inline const struct lvp_descriptor_set_layout *
get_set_layout(const struct lvp_pipeline_layout *layout, uint32_t set)
{
return container_of(layout->vk.set_layouts[set],
const struct lvp_descriptor_set_layout, vk);
}
static inline const struct lvp_descriptor_set_binding_layout *
get_binding_layout(const struct lvp_pipeline_layout *layout,
uint32_t set, uint32_t binding)
{
return &get_set_layout(layout, set)->binding[binding];
}
VK_DEFINE_HANDLE_CASTS(lvp_cmd_buffer, vk.base, VkCommandBuffer,
VK_OBJECT_TYPE_COMMAND_BUFFER)
VK_DEFINE_HANDLE_CASTS(lvp_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE)
VK_DEFINE_HANDLE_CASTS(lvp_instance, vk.base, VkInstance, VK_OBJECT_TYPE_INSTANCE)
VK_DEFINE_HANDLE_CASTS(lvp_physical_device, vk.base, VkPhysicalDevice,
VK_OBJECT_TYPE_PHYSICAL_DEVICE)
VK_DEFINE_HANDLE_CASTS(lvp_queue, vk.base, VkQueue, VK_OBJECT_TYPE_QUEUE)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_buffer, vk.base, VkBuffer,
VK_OBJECT_TYPE_BUFFER)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_buffer_view, vk.base, VkBufferView,
VK_OBJECT_TYPE_BUFFER_VIEW)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_descriptor_pool, base, VkDescriptorPool,
VK_OBJECT_TYPE_DESCRIPTOR_POOL)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_descriptor_set, base, VkDescriptorSet,
VK_OBJECT_TYPE_DESCRIPTOR_SET)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_descriptor_set_layout, vk.base, VkDescriptorSetLayout,
VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_device_memory, vk.base, VkDeviceMemory,
VK_OBJECT_TYPE_DEVICE_MEMORY)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_event, base, VkEvent, VK_OBJECT_TYPE_EVENT)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_image_view, vk.base, VkImageView,
VK_OBJECT_TYPE_IMAGE_VIEW);
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_pipeline_cache, base, VkPipelineCache,
VK_OBJECT_TYPE_PIPELINE_CACHE)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_pipeline, base, VkPipeline,
VK_OBJECT_TYPE_PIPELINE)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_shader, base, VkShaderEXT,
VK_OBJECT_TYPE_SHADER_EXT)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_pipeline_layout, vk.base, VkPipelineLayout,
VK_OBJECT_TYPE_PIPELINE_LAYOUT)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_query_pool, vk.base, VkQueryPool,
VK_OBJECT_TYPE_QUERY_POOL)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_sampler, vk.base, VkSampler,
VK_OBJECT_TYPE_SAMPLER)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_indirect_command_layout_nv, base, VkIndirectCommandsLayoutNV,
VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_indirect_command_layout_ext, vk.base, VkIndirectCommandsLayoutEXT,
VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_EXT)
VK_DEFINE_NONDISP_HANDLE_CASTS(lvp_indirect_execution_set, base, VkIndirectExecutionSetEXT,
VK_OBJECT_TYPE_INDIRECT_EXECUTION_SET_EXT)
void lvp_add_enqueue_cmd_entrypoints(struct vk_device_dispatch_table *disp);
VkResult lvp_buffer_bind_sparse(struct lvp_device *device,
struct lvp_queue *queue,
VkSparseBufferMemoryBindInfo *bind);
VkResult lvp_image_bind_opaque_sparse(struct lvp_device *device,
struct lvp_queue *queue,
VkSparseImageOpaqueMemoryBindInfo *bind);
VkResult lvp_image_bind_sparse(struct lvp_device *device,
struct lvp_queue *queue,
VkSparseImageMemoryBindInfo *bind);
VkResult lvp_execute_cmds(struct lvp_device *device,
struct lvp_queue *queue,
struct lvp_cmd_buffer *cmd_buffer);
size_t
lvp_get_rendering_state_size(void);
static inline enum pipe_format
lvp_vk_format_to_pipe_format(VkFormat format)
{
/* Some formats cause problems with CTS right now.*/
switch (format) {
case VK_FORMAT_R8_SRGB:
case VK_FORMAT_R8G8_SRGB:
case VK_FORMAT_R64G64B64A64_SFLOAT:
case VK_FORMAT_R64_SFLOAT:
case VK_FORMAT_R64G64_SFLOAT:
case VK_FORMAT_R64G64B64_SFLOAT:
case VK_FORMAT_A2R10G10B10_SINT_PACK32:
case VK_FORMAT_A2B10G10R10_SINT_PACK32:
case VK_FORMAT_D16_UNORM_S8_UINT:
return PIPE_FORMAT_NONE;
case VK_FORMAT_R10X6_UNORM_PACK16:
case VK_FORMAT_R12X4_UNORM_PACK16:
return PIPE_FORMAT_R16_UNORM;
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
return PIPE_FORMAT_R16G16_UNORM;
default:
return vk_format_to_pipe_format(format);
}
}
void
lvp_nir_lower_blend(nir_shader *nir, const nir_lower_blend_options *opts);
void
lvp_sampler_init(struct lvp_device *device, struct lp_sampler_descriptor *desc, const struct vk_sampler_state *vk_state);
static inline uint8_t
lvp_image_aspects_to_plane(ASSERTED const struct lvp_image *image,
VkImageAspectFlags aspectMask)
{
/* If we are requesting the first plane of image with only one plane, return that */
if (image->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT && aspectMask == VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT)
return 0;
/* Verify that the aspects are actually in the image */
assert(!(aspectMask & ~image->vk.aspects));
/* Must only be one aspect unless it's depth/stencil */
assert(aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT |
VK_IMAGE_ASPECT_STENCIL_BIT) ||
util_bitcount(aspectMask) == 1);
switch(aspectMask) {
case VK_IMAGE_ASPECT_PLANE_1_BIT: return 1;
case VK_IMAGE_ASPECT_PLANE_2_BIT: return 2;
default: return 0;
}
}
void
lvp_pipeline_destroy(struct lvp_device *device, struct lvp_pipeline *pipeline, bool locked);
void
queue_thread_noop(void *data, void *gdata, int thread_index);
VkResult
lvp_spirv_to_nir(struct lvp_pipeline *pipeline, const void *pipeline_pNext,
const VkPipelineShaderStageCreateInfo *sinfo, nir_shader **out_nir);
void
lvp_shader_init(struct lvp_shader *shader, nir_shader *nir);
void
lvp_shader_optimize(nir_shader *nir);
void *
lvp_shader_compile(struct lvp_device *device, struct lvp_shader *shader, nir_shader *nir, bool locked);
enum vk_cmd_type
lvp_nv_dgc_token_to_cmd_type(const VkIndirectCommandsLayoutTokenNV *token);
VkResult
lvp_image_init(struct lvp_device *device, struct lvp_image *image,
const VkImageCreateInfo *pCreateInfo);
#if DETECT_OS_ANDROID
VkResult
lvp_import_ahb_memory(struct lvp_device *device,
const VkMemoryAllocateInfo *alloc_info,
struct lvp_device_memory *mem);
VkResult
lvp_bind_anb_memory(struct lvp_device *device,
const VkBindImageMemoryInfo *bind_info);
#endif
enum vk_cmd_type
lvp_ext_dgc_token_to_cmd_type(const struct lvp_indirect_command_layout_ext *elayout, const VkIndirectCommandsLayoutTokenEXT *token);
size_t
lvp_ext_dgc_token_size(const struct lvp_indirect_command_layout_ext *elayout, const VkIndirectCommandsLayoutTokenEXT *token);
struct lvp_cmd_write_buffer_cp {
VkDeviceAddress addr;
void *data;
uint32_t size;
};
struct lvp_cmd_fill_buffer_addr {
VkDeviceAddress addr;
VkDeviceSize size;
uint32_t data;
};
void
lvp_encode_as(struct vk_acceleration_structure *dst, VkDeviceAddress intermediate_as_addr,
VkDeviceAddress intermediate_header_addr, uint32_t leaf_count,
VkGeometryTypeKHR geometry_type);
struct lvp_cmd_encode_as {
struct vk_acceleration_structure *dst;
VkDeviceAddress intermediate_as_addr;
VkDeviceAddress intermediate_header_addr;
uint32_t leaf_count;
VkGeometryTypeKHR geometry_type;
};
enum {
LVP_CMD_WRITE_BUFFER_CP = VK_CMD_TYPE_COUNT,
LVP_CMD_DISPATCH_UNALIGNED,
LVP_CMD_FILL_BUFFER_ADDR,
LVP_CMD_ENCODE_AS,
LVP_CMD_SAVE_STATE,
LVP_CMD_RESTORE_STATE,
};
#define LVP_CMD_WRITE_BUFFER_CP ((enum vk_cmd_type)LVP_CMD_WRITE_BUFFER_CP)
#define LVP_CMD_DISPATCH_UNALIGNED ((enum vk_cmd_type)LVP_CMD_DISPATCH_UNALIGNED)
#define LVP_CMD_FILL_BUFFER_ADDR ((enum vk_cmd_type)LVP_CMD_FILL_BUFFER_ADDR)
#define LVP_CMD_ENCODE_AS ((enum vk_cmd_type)LVP_CMD_ENCODE_AS)
#define LVP_CMD_SAVE_STATE ((enum vk_cmd_type)LVP_CMD_SAVE_STATE)
#define LVP_CMD_RESTORE_STATE ((enum vk_cmd_type)LVP_CMD_RESTORE_STATE)
void
lvp_image_copy_depth_box(uint8_t *dst,
enum pipe_format dst_format,
unsigned dst_stride, uint64_t dst_slice_stride,
unsigned dst_x, unsigned dst_y, unsigned dst_z,
unsigned width, unsigned height, unsigned depth,
const uint8_t * src,
enum pipe_format src_format,
int src_stride, uint64_t src_slice_stride,
unsigned src_x, unsigned src_y, unsigned src_z);
#ifdef __cplusplus
}
#endif
+238
View File
@@ -0,0 +1,238 @@
/*
* Copyright © 2019 Red Hat.
*
* 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 (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 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.
*/
#include "lvp_private.h"
#include "pipe/p_context.h"
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateQueryPool(
VkDevice _device,
const VkQueryPoolCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkQueryPool* pQueryPool)
{
VK_FROM_HANDLE(lvp_device, device, _device);
uint32_t query_size = sizeof(struct pipe_query *);
enum pipe_query_type pipeq;
switch (pCreateInfo->queryType) {
case VK_QUERY_TYPE_OCCLUSION:
pipeq = PIPE_QUERY_OCCLUSION_COUNTER;
break;
case VK_QUERY_TYPE_TIMESTAMP:
pipeq = PIPE_QUERY_TIMESTAMP;
break;
case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT:
pipeq = PIPE_QUERY_SO_STATISTICS;
break;
case VK_QUERY_TYPE_PIPELINE_STATISTICS:
pipeq = PIPE_QUERY_PIPELINE_STATISTICS;
break;
case VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT:
case VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT:
pipeq = PIPE_QUERY_PRIMITIVES_GENERATED;
break;
case VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR:
query_size = sizeof(uint64_t);
pipeq = LVP_QUERY_ACCELERATION_STRUCTURE_COMPACTED_SIZE;
break;
case VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR:
query_size = sizeof(uint64_t);
pipeq = LVP_QUERY_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE;
break;
case VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR:
query_size = sizeof(uint64_t);
pipeq = LVP_QUERY_ACCELERATION_STRUCTURE_SIZE;
break;
case VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR:
query_size = sizeof(uint64_t);
pipeq = LVP_QUERY_ACCELERATION_STRUCTURE_INSTANCE_COUNT;
break;
default:
return VK_ERROR_FEATURE_NOT_PRESENT;
}
struct lvp_query_pool *pool = vk_query_pool_create(&device->vk,
pCreateInfo,
pAllocator,
sizeof(*pool)
+ pCreateInfo->queryCount * query_size);
if (!pool)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
pool->base_type = pipeq;
*pQueryPool = lvp_query_pool_to_handle(pool);
return VK_SUCCESS;
}
VKAPI_ATTR void VKAPI_CALL lvp_DestroyQueryPool(
VkDevice _device,
VkQueryPool _pool,
const VkAllocationCallbacks* pAllocator)
{
VK_FROM_HANDLE(lvp_device, device, _device);
VK_FROM_HANDLE(lvp_query_pool, pool, _pool);
if (!pool)
return;
if (pool->base_type < PIPE_QUERY_TYPES) {
for (unsigned i = 0; i < pool->vk.query_count; i++)
if (pool->queries[i])
device->queue.ctx->destroy_query(device->queue.ctx, pool->queries[i]);
}
vk_query_pool_destroy(&device->vk, pAllocator, &pool->vk);
}
VKAPI_ATTR VkResult VKAPI_CALL lvp_GetQueryPoolResults(
VkDevice _device,
VkQueryPool queryPool,
uint32_t firstQuery,
uint32_t queryCount,
size_t dataSize,
void* pData,
VkDeviceSize stride,
VkQueryResultFlags flags)
{
VK_FROM_HANDLE(lvp_device, device, _device);
VK_FROM_HANDLE(lvp_query_pool, pool, queryPool);
VkResult vk_result = VK_SUCCESS;
device->vk.dispatch_table.DeviceWaitIdle(_device);
void *data = &pool->queries;
for (unsigned i = firstQuery; i < firstQuery + queryCount; i++) {
uint8_t *dest = (uint8_t *)((char *)pData + (stride * (i - firstQuery)));
union pipe_query_result result;
bool ready = false;
if (pool->base_type >= PIPE_QUERY_TYPES) {
if (flags & VK_QUERY_RESULT_64_BIT) {
uint64_t *dst = (uint64_t *)dest;
uint64_t *src = (uint64_t *)data;
*dst = src[i];
if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
*(dst + 1) = 1;
} else {
uint32_t *dst = (uint32_t *)dest;
uint64_t *src = (uint64_t *)data;
*dst = src[i];
if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
*(dst + 1) = 1;
}
continue;
}
if (pool->queries[i]) {
ready = device->queue.ctx->get_query_result(device->queue.ctx,
pool->queries[i],
(flags & VK_QUERY_RESULT_WAIT_BIT),
&result);
} else {
result.u64 = 0;
}
if (!ready && !(flags & VK_QUERY_RESULT_PARTIAL_BIT))
vk_result = VK_NOT_READY;
if (flags & VK_QUERY_RESULT_64_BIT) {
uint64_t *dest64 = (uint64_t *) dest;
if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) {
if (pool->vk.query_type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {
uint32_t mask = pool->vk.pipeline_statistics;
const uint64_t *pstats = result.pipeline_statistics.counters;
while (mask) {
uint32_t i = u_bit_scan(&mask);
*dest64++ = pstats[i];
}
} else if (pool->vk.query_type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) {
*dest64++ = result.so_statistics.num_primitives_written;
*dest64++ = result.so_statistics.primitives_storage_needed;
} else {
*dest64++ = result.u64;
}
} else {
if (pool->vk.query_type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) {
dest64 += 2; // 16 bytes
} else {
dest64 += 1; // 8 bytes
}
}
if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
*dest64 = ready;
}
} else {
uint32_t *dest32 = (uint32_t *) dest;
if (ready || (flags & VK_QUERY_RESULT_PARTIAL_BIT)) {
if (pool->vk.query_type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {
uint32_t mask = pool->vk.pipeline_statistics;
const uint64_t *pstats = result.pipeline_statistics.counters;
while (mask) {
uint32_t i = u_bit_scan(&mask);
*dest32++ = (uint32_t) MIN2(pstats[i], UINT32_MAX);
}
} else if (pool->vk.query_type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) {
*dest32++ = (uint32_t)
MIN2(result.so_statistics.num_primitives_written, UINT32_MAX);
*dest32++ = (uint32_t)
MIN2(result.so_statistics.primitives_storage_needed, UINT32_MAX);
} else {
*dest32++ = (uint32_t) (result.u64 & UINT32_MAX);
}
} else {
if (pool->vk.query_type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) {
dest32 += 2; // 8 bytes
} else {
dest32 += 1; // 4 bytes
}
}
if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
*dest32 = ready;
}
}
}
return vk_result;
}
VKAPI_ATTR void VKAPI_CALL lvp_ResetQueryPool(
VkDevice _device,
VkQueryPool queryPool,
uint32_t firstQuery,
uint32_t queryCount)
{
VK_FROM_HANDLE(lvp_device, device, _device);
VK_FROM_HANDLE(lvp_query_pool, pool, queryPool);
if (pool->base_type >= PIPE_QUERY_TYPES)
return;
for (uint32_t i = 0; i < queryCount; i++) {
uint32_t idx = i + firstQuery;
if (pool->queries[idx]) {
device->queue.ctx->destroy_query(device->queue.ctx, pool->queries[idx]);
pool->queries[idx] = NULL;
}
}
}
File diff suppressed because it is too large. Load diff
+37
View File
@@ -0,0 +1,37 @@
/*
* Copyright © 2019 Red Hat.
*
* 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 (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 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.
*/
#include "lvp_private.h"
#include "vk_enum_to_str.h"
void lvp_printflike(3, 4)
__lvp_finishme(const char *file, int line, const char *format, ...)
{
va_list ap;
char buffer[256];
va_start(ap, format);
vsnprintf(buffer, sizeof(buffer), format, ap);
va_end(ap);
fprintf(stderr, "%s:%d: FINISHME: %s\n", file, line, buffer);
}
+59
View File
@@ -0,0 +1,59 @@
/*
* Copyright © 2015 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 (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 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.
*/
#include "lvp_wsi.h"
static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
lvp_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
{
VK_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);
return vk_instance_get_proc_addr_unchecked(pdevice->vk.instance, pName);
}
VkResult
lvp_init_wsi(struct lvp_physical_device *physical_device)
{
VkResult result;
result = wsi_device_init(&physical_device->wsi_device,
lvp_physical_device_to_handle(physical_device),
lvp_wsi_proc_addr,
&physical_device->vk.instance->alloc,
-1, NULL,
&(struct wsi_device_options){.sw_device = true});
if (result != VK_SUCCESS)
return result;
physical_device->wsi_device.wants_linear = true;
physical_device->vk.wsi_device = &physical_device->wsi_device;
return VK_SUCCESS;
}
void
lvp_finish_wsi(struct lvp_physical_device *physical_device)
{
physical_device->vk.wsi_device = NULL;
wsi_device_finish(&physical_device->wsi_device,
&physical_device->vk.instance->alloc);
}
+71
View File
@@ -0,0 +1,71 @@
/*
* Copyright © 2015 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 (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 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.
*/
#pragma once
#include "lvp_private.h"
struct lvp_swapchain;
struct lvp_wsi_interface {
VkResult (*get_support)(VkIcdSurfaceBase *surface,
struct lvp_physical_device *device,
uint32_t queueFamilyIndex,
VkBool32* pSupported);
VkResult (*get_capabilities)(VkIcdSurfaceBase *surface,
struct lvp_physical_device *device,
VkSurfaceCapabilitiesKHR* pSurfaceCapabilities);
VkResult (*get_formats)(VkIcdSurfaceBase *surface,
struct lvp_physical_device *device,
uint32_t* pSurfaceFormatCount,
VkSurfaceFormatKHR* pSurfaceFormats);
VkResult (*get_present_modes)(VkIcdSurfaceBase *surface,
struct lvp_physical_device *device,
uint32_t* pPresentModeCount,
VkPresentModeKHR* pPresentModes);
VkResult (*create_swapchain)(VkIcdSurfaceBase *surface,
struct lvp_device *device,
const VkSwapchainCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
struct lvp_swapchain **swapchain);
};
struct lvp_swapchain {
struct lvp_device *device;
VkResult (*destroy)(struct lvp_swapchain *swapchain,
const VkAllocationCallbacks *pAllocator);
VkResult (*get_images)(struct lvp_swapchain *swapchain,
uint32_t *pCount, VkImage *pSwapchainImages);
VkResult (*acquire_next_image)(struct lvp_swapchain *swap_chain,
uint64_t timeout, VkSemaphore semaphore,
uint32_t *image_index);
VkResult (*queue_present)(struct lvp_swapchain *swap_chain,
struct lvp_queue *queue,
uint32_t image_index);
};
VkResult lvp_x11_init_wsi(struct lvp_instance *instance);
void lvp_x11_finish_wsi(struct lvp_instance *instance);
VkResult lvp_wl_init_wsi(struct lvp_instance *instance);
void lvp_wl_finish_wsi(struct lvp_instance *instance);
Loaded 100 of 12511 files, more files were not shown because too many files have changed in this diff. Show more