mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2025-03-14 00:49:53 -04:00
D3D11: Added multidraw indexed via AMD's AGS.
This commit is contained in:
parent
cd4be4168b
commit
52c89c8cc8
1 changed files with 220 additions and 12 deletions
|
@ -441,6 +441,67 @@ namespace bgfx { namespace d3d11
|
|||
return false;
|
||||
};
|
||||
|
||||
enum AGS_RETURN_CODE
|
||||
{
|
||||
AGS_SUCCESS,
|
||||
AGS_INVALID_ARGS,
|
||||
AGS_OUT_OF_MEMORY,
|
||||
AGS_ERROR_MISSING_DLL,
|
||||
AGS_ERROR_LEGACY_DRIVER,
|
||||
AGS_EXTENSION_NOT_SUPPORTED,
|
||||
AGS_ADL_FAILURE,
|
||||
};
|
||||
|
||||
enum AGS_DRIVER_EXTENSION
|
||||
{
|
||||
AGS_EXTENSION_QUADLIST = 1 << 0,
|
||||
AGS_EXTENSION_UAV_OVERLAP = 1 << 1,
|
||||
AGS_EXTENSION_DEPTH_BOUNDS_TEST = 1 << 2,
|
||||
AGS_EXTENSION_MULTIDRAWINDIRECT = 1 << 3,
|
||||
};
|
||||
|
||||
struct AGSDriverVersionInfo
|
||||
{
|
||||
char strDriverVersion[256];
|
||||
char strCatalystVersion[256];
|
||||
char strCatalystWebLink[256];
|
||||
};
|
||||
|
||||
struct AGSContext;
|
||||
|
||||
typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_INIT)(AGSContext**);
|
||||
typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DEINIT)(AGSContext*);
|
||||
typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_CROSSFIRE_GPU_COUNT)(AGSContext*, int32_t*);
|
||||
typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_TOTAL_GPU_COUNT)(AGSContext*, int32_t*);
|
||||
typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_GPU_MEMORY_SIZE)(AGSContext*, int32_t, int64_t*);
|
||||
typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_DRIVER_VERSION_INFO)(AGSContext*, AGSDriverVersionInfo*);
|
||||
typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_INIT)(AGSContext*, ID3D11Device*, uint32_t*);
|
||||
typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_DEINIT)(AGSContext*);
|
||||
typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INSTANCED_INDIRECT)(AGSContext*, uint32_t, ID3D11Buffer*, uint32_t, uint32_t);
|
||||
typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INDEXED_INSTANCED_INDIRECT)(AGSContext*, uint32_t, ID3D11Buffer*, uint32_t, uint32_t);
|
||||
|
||||
static PFN_AGS_INIT agsInit;
|
||||
static PFN_AGS_DEINIT agsDeInit;
|
||||
static PFN_AGS_GET_CROSSFIRE_GPU_COUNT agsGetCrossfireGPUCount;
|
||||
static PFN_AGS_GET_TOTAL_GPU_COUNT agsGetTotalGPUCount;
|
||||
static PFN_AGS_GET_GPU_MEMORY_SIZE agsGetGPUMemorySize;
|
||||
static PFN_AGS_GET_DRIVER_VERSION_INFO agsGetDriverVersionInfo;
|
||||
static PFN_AGS_DRIVER_EXTENSIONS_INIT agsDriverExtensions_Init;
|
||||
static PFN_AGS_DRIVER_EXTENSIONS_DEINIT agsDriverExtensions_DeInit;
|
||||
static PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INSTANCED_INDIRECT agsDriverExtensions_MultiDrawInstancedIndirect;
|
||||
static PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INDEXED_INSTANCED_INDIRECT agsDriverExtensions_MultiDrawIndexedInstancedIndirect;
|
||||
|
||||
typedef void (* MultiDrawIndirectFn)(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride);
|
||||
|
||||
void stubMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride);
|
||||
void stubMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride);
|
||||
|
||||
void amdAgsMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride);
|
||||
void amdAgsMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride);
|
||||
|
||||
static MultiDrawIndirectFn multiDrawInstancedIndirect;
|
||||
static MultiDrawIndirectFn multiDrawIndexedInstancedIndirect;
|
||||
|
||||
#if USE_D3D11_DYNAMIC_LIB
|
||||
static PFN_D3D11_CREATE_DEVICE D3D11CreateDevice;
|
||||
static PFN_CREATE_DXGI_FACTORY CreateDXGIFactory;
|
||||
|
@ -459,6 +520,8 @@ namespace bgfx { namespace d3d11
|
|||
, m_dxgidll(NULL)
|
||||
, m_dxgidebugdll(NULL)
|
||||
, m_renderdocdll(NULL)
|
||||
, m_agsdll(NULL)
|
||||
, m_ags(NULL)
|
||||
, m_driverType(D3D_DRIVER_TYPE_NULL)
|
||||
, m_featureLevel(D3D_FEATURE_LEVEL(0) )
|
||||
, m_adapter(NULL)
|
||||
|
@ -522,6 +585,88 @@ namespace bgfx { namespace d3d11
|
|||
memset(m_uniforms, 0, sizeof(m_uniforms) );
|
||||
memset(&m_resolution, 0, sizeof(m_resolution) );
|
||||
|
||||
m_ags = NULL;
|
||||
m_agsdll = bx::dlopen(
|
||||
#if BX_ARCH_32BIT
|
||||
"amd_ags_x86.dll"
|
||||
#else
|
||||
"amd_ags_x64.dll"
|
||||
#endif // BX_ARCH_32BIT
|
||||
);
|
||||
if (NULL != m_agsdll)
|
||||
{
|
||||
agsInit = (PFN_AGS_INIT )bx::dlsym(m_agsdll, "agsInit");
|
||||
agsDeInit = (PFN_AGS_DEINIT)bx::dlsym(m_agsdll, "agsDeInit");
|
||||
agsGetCrossfireGPUCount = (PFN_AGS_GET_CROSSFIRE_GPU_COUNT )bx::dlsym(m_agsdll, "agsGetCrossfireGPUCount");
|
||||
agsGetTotalGPUCount = (PFN_AGS_GET_TOTAL_GPU_COUNT )bx::dlsym(m_agsdll, "agsGetTotalGPUCount");
|
||||
agsGetGPUMemorySize = (PFN_AGS_GET_GPU_MEMORY_SIZE )bx::dlsym(m_agsdll, "agsGetGPUMemorySize");
|
||||
agsGetDriverVersionInfo = (PFN_AGS_GET_DRIVER_VERSION_INFO )bx::dlsym(m_agsdll, "agsGetDriverVersionInfo");
|
||||
agsDriverExtensions_Init = (PFN_AGS_DRIVER_EXTENSIONS_INIT )bx::dlsym(m_agsdll, "agsDriverExtensions_Init");
|
||||
agsDriverExtensions_DeInit = (PFN_AGS_DRIVER_EXTENSIONS_DEINIT)bx::dlsym(m_agsdll, "agsDriverExtensions_DeInit");
|
||||
agsDriverExtensions_MultiDrawInstancedIndirect = (PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INSTANCED_INDIRECT )bx::dlsym(m_agsdll, "agsDriverExtensions_MultiDrawInstancedIndirect");
|
||||
agsDriverExtensions_MultiDrawIndexedInstancedIndirect = (PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INDEXED_INSTANCED_INDIRECT)bx::dlsym(m_agsdll, "agsDriverExtensions_MultiDrawIndexedInstancedIndirect");
|
||||
|
||||
bool agsSupported = true
|
||||
&& NULL != agsInit
|
||||
&& NULL != agsDeInit
|
||||
&& NULL != agsGetCrossfireGPUCount
|
||||
&& NULL != agsGetTotalGPUCount
|
||||
&& NULL != agsGetGPUMemorySize
|
||||
&& NULL != agsGetDriverVersionInfo
|
||||
&& NULL != agsDriverExtensions_Init
|
||||
&& NULL != agsDriverExtensions_DeInit
|
||||
&& NULL != agsDriverExtensions_MultiDrawInstancedIndirect
|
||||
&& NULL != agsDriverExtensions_MultiDrawIndexedInstancedIndirect
|
||||
;
|
||||
if (agsSupported)
|
||||
{
|
||||
AGS_RETURN_CODE result = agsInit(&m_ags);
|
||||
agsSupported = AGS_SUCCESS == result;
|
||||
if (agsSupported)
|
||||
{
|
||||
AGS_RETURN_CODE result;
|
||||
|
||||
AGSDriverVersionInfo vi;
|
||||
result = agsGetDriverVersionInfo(m_ags, &vi);
|
||||
BX_TRACE(" Driver version: %s", vi.strDriverVersion);
|
||||
BX_TRACE(" Catalyst version: %s", vi.strCatalystVersion);
|
||||
|
||||
int32_t numCrossfireGPUs = 0;
|
||||
result = agsGetCrossfireGPUCount(m_ags, &numCrossfireGPUs);
|
||||
BX_TRACE(" Num crossfire GPUs: %d", numCrossfireGPUs);
|
||||
|
||||
int32_t numGPUs = 0;
|
||||
result = agsGetTotalGPUCount(m_ags, &numGPUs);
|
||||
BX_TRACE(" Num GPUs: %d", numGPUs);
|
||||
|
||||
for (int32_t ii = 0; ii < numGPUs; ++ii)
|
||||
{
|
||||
long long memSize;
|
||||
result = agsGetGPUMemorySize(m_ags, ii, &memSize);
|
||||
char memSizeStr[16];
|
||||
bx::prettify(memSizeStr, BX_COUNTOF(memSizeStr), memSize);
|
||||
BX_TRACE(" GPU #%d mem size: %s", ii, memSizeStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!agsSupported)
|
||||
{
|
||||
if (NULL != m_ags)
|
||||
{
|
||||
agsDeInit(m_ags);
|
||||
m_ags = NULL;
|
||||
}
|
||||
|
||||
bx::dlclose(m_agsdll);
|
||||
m_agsdll = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
BX_TRACE("AMD/AGS supported.");
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_D3D11_DYNAMIC_LIB
|
||||
m_d3d11dll = bx::dlopen("d3d11.dll");
|
||||
BX_WARN(NULL != m_d3d11dll, "Failed to load d3d11.dll.");
|
||||
|
@ -760,6 +905,32 @@ namespace bgfx { namespace d3d11
|
|||
}
|
||||
}
|
||||
|
||||
multiDrawInstancedIndirect = stubMultiDrawInstancedIndirect;
|
||||
multiDrawIndexedInstancedIndirect = stubMultiDrawIndexedInstancedIndirect;
|
||||
if (NULL != m_ags)
|
||||
{
|
||||
uint32_t flags;
|
||||
AGS_RETURN_CODE result = agsDriverExtensions_Init(m_ags, m_device, &flags);
|
||||
bool hasExtensions = AGS_SUCCESS == result;
|
||||
|
||||
if (hasExtensions
|
||||
&& 0 != (flags & AGS_EXTENSION_MULTIDRAWINDIRECT) )
|
||||
{
|
||||
multiDrawInstancedIndirect = amdAgsMultiDrawInstancedIndirect;
|
||||
multiDrawIndexedInstancedIndirect = amdAgsMultiDrawIndexedInstancedIndirect;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasExtensions)
|
||||
{
|
||||
agsDriverExtensions_DeInit(m_ags);
|
||||
}
|
||||
|
||||
agsDeInit(m_ags);
|
||||
m_ags = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
IDXGIDevice* device = NULL;
|
||||
IDXGIAdapter* adapter = NULL;
|
||||
|
@ -1212,6 +1383,12 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
#endif // USE_D3D11_DYNAMIC_LIB
|
||||
|
||||
case ErrorState::Default:
|
||||
if (NULL != m_ags)
|
||||
{
|
||||
agsDeInit(m_ags);
|
||||
}
|
||||
bx::dlclose(m_agsdll);
|
||||
m_agsdll = NULL;
|
||||
unloadRenderDoc(m_renderdocdll);
|
||||
m_ovr.shutdown();
|
||||
break;
|
||||
|
@ -2875,6 +3052,9 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
void* m_dxgidebugdll;
|
||||
|
||||
void* m_renderdocdll;
|
||||
void* m_agsdll;
|
||||
AGSContext* m_ags;
|
||||
|
||||
|
||||
D3D_DRIVER_TYPE m_driverType;
|
||||
D3D_FEATURE_LEVEL m_featureLevel;
|
||||
|
@ -2977,6 +3157,36 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
s_renderD3D11 = NULL;
|
||||
}
|
||||
|
||||
void stubMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride)
|
||||
{
|
||||
ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;
|
||||
for (uint32_t ii = 0; ii < _numDrawIndirect; ++ii)
|
||||
{
|
||||
deviceCtx->DrawInstancedIndirect(_ptr, _offset);
|
||||
_offset += _stride;
|
||||
}
|
||||
}
|
||||
|
||||
void stubMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride)
|
||||
{
|
||||
ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;
|
||||
for (uint32_t ii = 0; ii < _numDrawIndirect; ++ii)
|
||||
{
|
||||
deviceCtx->DrawIndexedInstancedIndirect(_ptr, _offset);
|
||||
_offset += _stride;
|
||||
}
|
||||
}
|
||||
|
||||
void amdAgsMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride)
|
||||
{
|
||||
agsDriverExtensions_MultiDrawInstancedIndirect(s_renderD3D11->m_ags, _numDrawIndirect, _ptr, _offset, _stride);
|
||||
}
|
||||
|
||||
void amdAgsMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride)
|
||||
{
|
||||
agsDriverExtensions_MultiDrawIndexedInstancedIndirect(s_renderD3D11->m_ags, _numDrawIndirect, _ptr, _offset, _stride);
|
||||
}
|
||||
|
||||
struct UavFormat
|
||||
{
|
||||
DXGI_FORMAT format[3];
|
||||
|
@ -4567,12 +4777,11 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
: draw.m_numIndirect
|
||||
;
|
||||
|
||||
uint32_t args = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
|
||||
for (uint32_t ii = 0; ii < numDrawIndirect; ++ii)
|
||||
{
|
||||
deviceCtx->DrawIndexedInstancedIndirect(ptr, args);
|
||||
args += BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
|
||||
}
|
||||
multiDrawIndexedInstancedIndirect(numDrawIndirect
|
||||
, ptr
|
||||
, draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE
|
||||
, BGFX_CONFIG_DRAW_INDIRECT_STRIDE
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4581,12 +4790,11 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
: draw.m_numIndirect
|
||||
;
|
||||
|
||||
uint32_t args = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
|
||||
for (uint32_t ii = 0; ii < numDrawIndirect; ++ii)
|
||||
{
|
||||
deviceCtx->DrawInstancedIndirect(ptr, args);
|
||||
args += BGFX_CONFIG_DRAW_INDIRECT_STRIDE;
|
||||
}
|
||||
multiDrawInstancedIndirect(numDrawIndirect
|
||||
, ptr
|
||||
, draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE
|
||||
, BGFX_CONFIG_DRAW_INDIRECT_STRIDE
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue