|
@@ -8,19 +8,48 @@
|
|
|
#include <dxcapi.h>
|
|
|
#endif
|
|
|
|
|
|
+#ifdef HL_XBS
|
|
|
+#ifdef _GAMING_XBOX_SCARLETT
|
|
|
+#include <d3d12_xs.h>
|
|
|
+#include <d3dx12_xs.h>
|
|
|
+#include <dxcapi_xs.h>
|
|
|
+#else
|
|
|
+#include <d3d12_x.h>
|
|
|
+#include <d3dx12_x.h>
|
|
|
+#include <dxcapi_x.h>
|
|
|
+#endif
|
|
|
+
|
|
|
+#define IID_PPV_ARGS_OLD(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)
|
|
|
+#undef IID_PPV_ARGS
|
|
|
+#define IID_PPV_ARGS IID_GRAPHICS_PPV_ARGS
|
|
|
+#endif
|
|
|
+
|
|
|
#define DXERR(cmd) { HRESULT __ret = cmd; if( __ret == E_OUTOFMEMORY ) return NULL; if( __ret != S_OK ) ReportDxError(__ret,__LINE__); }
|
|
|
#define CHKERR(cmd) { HRESULT __ret = cmd; if( __ret != S_OK ) ReportDxError(__ret,__LINE__); }
|
|
|
|
|
|
typedef struct {
|
|
|
HWND wnd;
|
|
|
+ ID3D12CommandQueue *commandQueue;
|
|
|
+#ifndef HL_XBS
|
|
|
IDXGIFactory4 *factory;
|
|
|
IDXGIAdapter1 *adapter;
|
|
|
IDXGISwapChain4 *swapchain;
|
|
|
ID3D12Device *device;
|
|
|
- ID3D12CommandQueue *commandQueue;
|
|
|
ID3D12Debug1 *debug;
|
|
|
- ID3D12DebugDevice *debugDevice;
|
|
|
+ ID3D12DebugDevice *debugDevice;
|
|
|
ID3D12InfoQueue *infoQueue;
|
|
|
+#else
|
|
|
+ ID3D12Device2 *device;
|
|
|
+ ID3D12Debug *debug;
|
|
|
+ ID3D12DebugDevice *debugDevice;
|
|
|
+ // SwapChain
|
|
|
+ UINT swapBufferCount;
|
|
|
+ UINT backBufferIndex;
|
|
|
+ ID3D12Resource **swapBuffers;
|
|
|
+ D3D12XBOX_FRAME_PIPELINE_TOKEN pipelineToken;
|
|
|
+ // Cached values
|
|
|
+ IDXGIAdapter *adapter;
|
|
|
+#endif
|
|
|
} dx_driver;
|
|
|
|
|
|
static dx_driver *static_driver = NULL;
|
|
@@ -44,6 +73,7 @@ void *pContext ) {
|
|
|
}
|
|
|
|
|
|
HL_PRIM varray *HL_NAME(list_devices)() {
|
|
|
+#ifndef HL_XBS
|
|
|
static int MAX_DEVICES = 64;
|
|
|
int index = 0, write = 0;
|
|
|
IDXGIAdapter1 *adapter = NULL;
|
|
@@ -64,24 +94,38 @@ HL_PRIM varray *HL_NAME(list_devices)() {
|
|
|
if( !static_driver )
|
|
|
factory->Release();
|
|
|
return arr;
|
|
|
+#else
|
|
|
+ varray *arr = hl_alloc_array(&hlt_bytes, 1);
|
|
|
+ DXGI_ADAPTER_DESC desc;
|
|
|
+ static_driver->adapter->GetDesc(&desc);
|
|
|
+ hl_aptr(arr, uchar*)[0] = ustrdup(desc.Description);
|
|
|
+ return arr;
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
|
|
|
HL_PRIM dx_driver *HL_NAME(create)( HWND window, int flags, uchar *dev_desc ) {
|
|
|
UINT dxgiFlags = 0;
|
|
|
dx_driver *drv = (dx_driver*)hl_gc_alloc_raw(sizeof(dx_driver));
|
|
|
- memset(drv,0,sizeof(dx_driver));
|
|
|
+ memset(drv, 0, sizeof(dx_driver));
|
|
|
drv->wnd = window;
|
|
|
|
|
|
if( flags & 1 ) {
|
|
|
ID3D12Debug *debugController;
|
|
|
D3D12GetDebugInterface(IID_PPV_ARGS(&debugController));
|
|
|
+ debugController->EnableDebugLayer();
|
|
|
+#ifndef HL_XBS
|
|
|
debugController->QueryInterface(&drv->debug);
|
|
|
drv->debug->EnableDebugLayer();
|
|
|
drv->debug->SetEnableGPUBasedValidation(true);
|
|
|
dxgiFlags |= DXGI_CREATE_FACTORY_DEBUG;
|
|
|
+#else
|
|
|
+ debugController->QueryInterface(IID_PPV_ARGS(&drv->debug));
|
|
|
+#endif
|
|
|
debugController->Release();
|
|
|
}
|
|
|
+
|
|
|
+#ifndef HL_XBS
|
|
|
CHKERR(CreateDXGIFactory2(dxgiFlags, IID_PPV_ARGS(&drv->factory)));
|
|
|
|
|
|
UINT index = 0;
|
|
@@ -107,6 +151,42 @@ HL_PRIM dx_driver *HL_NAME(create)( HWND window, int flags, uchar *dev_desc ) {
|
|
|
CHKERR(drv->device->QueryInterface(IID_PPV_ARGS(&drv->infoQueue)));
|
|
|
drv->infoQueue->ClearStoredMessages();
|
|
|
}
|
|
|
+#else
|
|
|
+ D3D12XBOX_CREATE_DEVICE_PARAMETERS params = {};
|
|
|
+ params.Version = D3D12_SDK_VERSION;
|
|
|
+#if defined(_DEBUG)
|
|
|
+ params.ProcessDebugFlags = D3D12_PROCESS_DEBUG_FLAG_DEBUG_LAYER_ENABLED;
|
|
|
+#endif
|
|
|
+ params.GraphicsCommandQueueRingSizeBytes = static_cast<UINT>(D3D12XBOX_DEFAULT_SIZE_BYTES);
|
|
|
+ params.GraphicsScratchMemorySizeBytes = static_cast<UINT>(D3D12XBOX_DEFAULT_SIZE_BYTES);
|
|
|
+ params.ComputeScratchMemorySizeBytes = static_cast<UINT>(D3D12XBOX_DEFAULT_SIZE_BYTES);
|
|
|
+ params.DisableGeometryShaderAllocations = TRUE;
|
|
|
+ params.DisableTessellationShaderAllocations = TRUE;
|
|
|
+#ifdef _GAMING_XBOX_SCARLETT
|
|
|
+ params.DisableDXR = TRUE;
|
|
|
+ params.CreateDeviceFlags = D3D12XBOX_CREATE_DEVICE_FLAG_NONE;
|
|
|
+#endif
|
|
|
+
|
|
|
+ CHKERR(D3D12XboxCreateDevice(nullptr,¶ms, IID_PPV_ARGS(&drv->device)))
|
|
|
+ drv->device->SetName(L"HL_DX12_XBS");
|
|
|
+ if (drv->debug) {
|
|
|
+ CHKERR(drv->device->QueryInterface(IID_PPV_ARGS(&drv->debugDevice)));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Prepare for PresentX
|
|
|
+ {
|
|
|
+ IDXGIDevice1 *dxgiDevice;
|
|
|
+ CHKERR(drv->device->QueryInterface(IID_PPV_ARGS(&dxgiDevice)));
|
|
|
+ IDXGIAdapter *dxgiAdapter;
|
|
|
+ CHKERR(dxgiDevice->GetAdapter(&dxgiAdapter));
|
|
|
+ DXGI_ADAPTER_DESC desc;
|
|
|
+ dxgiAdapter->GetDesc(&desc);
|
|
|
+ if (dev_desc) {
|
|
|
+ wcsstr(desc.Description, dev_desc);
|
|
|
+ }
|
|
|
+ drv->adapter = dxgiAdapter;
|
|
|
+ }
|
|
|
+#endif
|
|
|
|
|
|
{
|
|
|
D3D12_COMMAND_QUEUE_DESC desc = {};
|
|
@@ -114,15 +194,47 @@ HL_PRIM dx_driver *HL_NAME(create)( HWND window, int flags, uchar *dev_desc ) {
|
|
|
desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
|
|
|
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
|
|
desc.NodeMask = CURRENT_NODEMASK;
|
|
|
- CHKERR(drv->device->CreateCommandQueue(&desc,IID_PPV_ARGS(&drv->commandQueue)));
|
|
|
+ CHKERR(drv->device->CreateCommandQueue(&desc, IID_PPV_ARGS(&drv->commandQueue)));
|
|
|
}
|
|
|
|
|
|
static_driver = drv;
|
|
|
return drv;
|
|
|
}
|
|
|
|
|
|
+#ifdef HL_XBS
|
|
|
+void register_frame_events() {
|
|
|
+ dx_driver *drv = static_driver;
|
|
|
+ // Prepare PresentX
|
|
|
+ IDXGIOutput *dxgiOutput;
|
|
|
+ CHKERR(drv->adapter->EnumOutputs(0, &dxgiOutput));
|
|
|
+ // May return S_OK, S_FALSE
|
|
|
+ HRESULT hr = drv->device->SetFrameIntervalX(dxgiOutput, D3D12XBOX_FRAME_INTERVAL_60_HZ, drv->swapBufferCount - 1u /* Allow n-1 frames of latency */, D3D12XBOX_FRAME_INTERVAL_FLAG_NONE);
|
|
|
+ if (hr < 0) ReportDxError(hr, __LINE__);
|
|
|
+ CHKERR(drv->device->ScheduleFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, 0U, nullptr, D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE));
|
|
|
+
|
|
|
+ // Prepare first pipeline token
|
|
|
+ drv->pipelineToken = D3D12XBOX_FRAME_PIPELINE_TOKEN_NULL;
|
|
|
+ CHKERR(drv->device->WaitFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, INFINITE, nullptr, D3D12XBOX_WAIT_FRAME_EVENT_FLAG_NONE, &drv->pipelineToken));
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+HL_PRIM void HL_NAME(suspend)() {
|
|
|
+#ifdef HL_XBS
|
|
|
+ // Must be called from the render thread
|
|
|
+ CHKERR(static_driver->commandQueue->SuspendX(0));
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+HL_PRIM void HL_NAME(resume)() {
|
|
|
+#ifdef HL_XBS
|
|
|
+ CHKERR(static_driver->commandQueue->ResumeX());
|
|
|
+ register_frame_events();
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
HL_PRIM void HL_NAME(resize)( int width, int height, int buffer_count, DXGI_FORMAT format ) {
|
|
|
dx_driver *drv = static_driver;
|
|
|
+#ifndef HL_XBS
|
|
|
if( drv->swapchain ) {
|
|
|
CHKERR(drv->swapchain->ResizeBuffers(buffer_count, width, height, format, 0));
|
|
|
} else {
|
|
@@ -140,17 +252,59 @@ HL_PRIM void HL_NAME(resize)( int width, int height, int buffer_count, DXGI_FORM
|
|
|
if( !swapchain ) CHKERR(E_INVALIDARG);
|
|
|
swapchain->QueryInterface(IID_PPV_ARGS(&drv->swapchain));
|
|
|
}
|
|
|
+#else
|
|
|
+ if (drv->swapBuffers) {
|
|
|
+ free(drv->swapBuffers);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create swap buffers
|
|
|
+ CD3DX12_HEAP_PROPERTIES swapChainHeapProperties(D3D12_HEAP_TYPE_DEFAULT);
|
|
|
+ D3D12_RESOURCE_DESC swapChainBufferDesc = CD3DX12_RESOURCE_DESC::Tex2D(format, width, height,
|
|
|
+ 1, // This resource has only one texture.
|
|
|
+ 1 // Use a single mipmap level.
|
|
|
+ );
|
|
|
+ swapChainBufferDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
|
|
+ D3D12_CLEAR_VALUE swapChainOptimizedClearValue = {};
|
|
|
+ swapChainOptimizedClearValue.Format = format;
|
|
|
+ drv->swapBuffers = (ID3D12Resource**) malloc(sizeof(ID3D12Resource*) * buffer_count);
|
|
|
+ if (drv->swapBuffers == nullptr)
|
|
|
+ hl_error("malloc drv->swapBuffers failed");
|
|
|
+ drv->swapBufferCount = buffer_count;
|
|
|
+ drv->backBufferIndex = 0;
|
|
|
+ for (int n = 0; n < buffer_count; n++)
|
|
|
+ {
|
|
|
+ drv->device->CreateCommittedResource(&swapChainHeapProperties, D3D12_HEAP_FLAG_ALLOW_DISPLAY, &swapChainBufferDesc, D3D12_RESOURCE_STATE_PRESENT, &swapChainOptimizedClearValue, IID_PPV_ARGS(&drv->swapBuffers[n]));
|
|
|
+ }
|
|
|
+
|
|
|
+ register_frame_events();
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
HL_PRIM void HL_NAME(present)( bool vsync ) {
|
|
|
dx_driver *drv = static_driver;
|
|
|
+#ifndef HL_XBS
|
|
|
UINT syncInterval = vsync ? 1 : 0;
|
|
|
UINT presentFlags = 0;
|
|
|
CHKERR(drv->swapchain->Present(syncInterval, presentFlags));
|
|
|
+#else
|
|
|
+ D3D12XBOX_PRESENT_PLANE_PARAMETERS planeParameters = {};
|
|
|
+ planeParameters.Token = drv->pipelineToken;
|
|
|
+ planeParameters.ResourceCount = 1;
|
|
|
+ planeParameters.ppResources = &drv->swapBuffers[drv->backBufferIndex];
|
|
|
+ CHKERR(drv->commandQueue->PresentX(1, &planeParameters, nullptr));
|
|
|
+ drv->backBufferIndex = (drv->backBufferIndex + 1) % drv->swapBufferCount;
|
|
|
+ // Prepare next pipeline token
|
|
|
+ drv->pipelineToken = D3D12XBOX_FRAME_PIPELINE_TOKEN_NULL;
|
|
|
+ CHKERR(drv->device->WaitFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, INFINITE, nullptr, D3D12XBOX_WAIT_FRAME_EVENT_FLAG_NONE, &drv->pipelineToken));
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
int HL_NAME(get_current_back_buffer_index)() {
|
|
|
+#ifndef HL_XBS
|
|
|
return static_driver->swapchain->GetCurrentBackBufferIndex();
|
|
|
+#else
|
|
|
+ return static_driver->backBufferIndex;
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
void HL_NAME(signal)( ID3D12Fence *fence, int64 value ) {
|
|
@@ -158,6 +312,7 @@ void HL_NAME(signal)( ID3D12Fence *fence, int64 value ) {
|
|
|
}
|
|
|
|
|
|
void HL_NAME(flush_messages)() {
|
|
|
+#ifndef HL_XBS
|
|
|
dx_driver *drv = static_driver;
|
|
|
if( !drv->infoQueue ) return;
|
|
|
int count = (int)drv->infoQueue->GetNumStoredMessages();
|
|
@@ -174,10 +329,12 @@ void HL_NAME(flush_messages)() {
|
|
|
fflush(stdout);
|
|
|
}
|
|
|
drv->infoQueue->ClearStoredMessages();
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
uchar *HL_NAME(get_device_name)() {
|
|
|
DXGI_ADAPTER_DESC desc;
|
|
|
+#ifndef HL_XBS
|
|
|
IDXGIAdapter *adapter = NULL;
|
|
|
if( !static_driver ) {
|
|
|
IDXGIFactory4 *factory = NULL;
|
|
@@ -188,7 +345,10 @@ uchar *HL_NAME(get_device_name)() {
|
|
|
} else
|
|
|
adapter = static_driver->adapter;
|
|
|
adapter->GetDesc(&desc);
|
|
|
- return (uchar*)hl_copy_bytes((vbyte*)desc.Description,(int)(ustrlen((uchar*)desc.Description)+1)*2);
|
|
|
+#else
|
|
|
+ static_driver->adapter->GetDesc(&desc);
|
|
|
+#endif
|
|
|
+ return (uchar*)hl_copy_bytes((vbyte*)desc.Description, (int)(ustrlen((uchar*)desc.Description) + 1) * 2);
|
|
|
}
|
|
|
|
|
|
int64 HL_NAME(get_timestamp_frequency)() {
|
|
@@ -204,6 +364,8 @@ DEFINE_PRIM(_ARR, list_devices, _NO_ARG);
|
|
|
DEFINE_PRIM(_DRIVER, create, _ABSTRACT(dx_window) _I32 _BYTES);
|
|
|
DEFINE_PRIM(_VOID, resize, _I32 _I32 _I32 _I32);
|
|
|
DEFINE_PRIM(_VOID, present, _BOOL);
|
|
|
+DEFINE_PRIM(_VOID, suspend, _NO_ARG);
|
|
|
+DEFINE_PRIM(_VOID, resume, _NO_ARG);
|
|
|
DEFINE_PRIM(_I32, get_current_back_buffer_index, _NO_ARG);
|
|
|
DEFINE_PRIM(_VOID, signal, _RES _I64);
|
|
|
DEFINE_PRIM(_VOID, flush_messages, _NO_ARG);
|
|
@@ -212,151 +374,162 @@ DEFINE_PRIM(_I64, get_timestamp_frequency, _NO_ARG);
|
|
|
|
|
|
/// --- utilities (from d3dx12.h)
|
|
|
|
|
|
+#ifndef HL_XBS
|
|
|
struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION
|
|
|
{
|
|
|
- CD3DX12_TEXTURE_COPY_LOCATION() = default;
|
|
|
- explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) noexcept :
|
|
|
- D3D12_TEXTURE_COPY_LOCATION(o)
|
|
|
- {}
|
|
|
- CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes) noexcept
|
|
|
- {
|
|
|
- pResource = pRes;
|
|
|
- Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
|
|
- PlacedFootprint = {};
|
|
|
- }
|
|
|
- CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) noexcept
|
|
|
- {
|
|
|
- pResource = pRes;
|
|
|
- Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
|
|
- PlacedFootprint = Footprint;
|
|
|
- }
|
|
|
- CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes, UINT Sub) noexcept
|
|
|
- {
|
|
|
- pResource = pRes;
|
|
|
- Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
|
|
- PlacedFootprint = {};
|
|
|
- SubresourceIndex = Sub;
|
|
|
- }
|
|
|
+ CD3DX12_TEXTURE_COPY_LOCATION() = default;
|
|
|
+ explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) noexcept :
|
|
|
+ D3D12_TEXTURE_COPY_LOCATION(o)
|
|
|
+ {}
|
|
|
+ CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes) noexcept
|
|
|
+ {
|
|
|
+ pResource = pRes;
|
|
|
+ Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
|
|
+ PlacedFootprint = {};
|
|
|
+ }
|
|
|
+ CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) noexcept
|
|
|
+ {
|
|
|
+ pResource = pRes;
|
|
|
+ Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
|
|
+ PlacedFootprint = Footprint;
|
|
|
+ }
|
|
|
+ CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes, UINT Sub) noexcept
|
|
|
+ {
|
|
|
+ pResource = pRes;
|
|
|
+ Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
|
|
+ PlacedFootprint = {};
|
|
|
+ SubresourceIndex = Sub;
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
inline void MemcpySubresource(
|
|
|
- _In_ const D3D12_MEMCPY_DEST* pDest,
|
|
|
- _In_ const D3D12_SUBRESOURCE_DATA* pSrc,
|
|
|
- SIZE_T RowSizeInBytes,
|
|
|
- UINT NumRows,
|
|
|
- UINT NumSlices) noexcept
|
|
|
+ _In_ const D3D12_MEMCPY_DEST* pDest,
|
|
|
+ _In_ const D3D12_SUBRESOURCE_DATA* pSrc,
|
|
|
+ SIZE_T RowSizeInBytes,
|
|
|
+ UINT NumRows,
|
|
|
+ UINT NumSlices) noexcept
|
|
|
{
|
|
|
- for (UINT z = 0; z < NumSlices; ++z)
|
|
|
- {
|
|
|
- auto pDestSlice = static_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
|
|
|
- auto pSrcSlice = static_cast<const BYTE*>(pSrc->pData) + pSrc->SlicePitch * LONG_PTR(z);
|
|
|
- for (UINT y = 0; y < NumRows; ++y)
|
|
|
- {
|
|
|
- memcpy(pDestSlice + pDest->RowPitch * y,
|
|
|
- pSrcSlice + pSrc->RowPitch * LONG_PTR(y),
|
|
|
- RowSizeInBytes);
|
|
|
- }
|
|
|
- }
|
|
|
+ for (UINT z = 0; z < NumSlices; ++z)
|
|
|
+ {
|
|
|
+ auto pDestSlice = static_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
|
|
|
+ auto pSrcSlice = static_cast<const BYTE*>(pSrc->pData) + pSrc->SlicePitch * LONG_PTR(z);
|
|
|
+ for (UINT y = 0; y < NumRows; ++y)
|
|
|
+ {
|
|
|
+ memcpy(pDestSlice + pDest->RowPitch * y,
|
|
|
+ pSrcSlice + pSrc->RowPitch * LONG_PTR(y),
|
|
|
+ RowSizeInBytes);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
inline UINT64 UpdateSubresources(
|
|
|
- _In_ ID3D12GraphicsCommandList* pCmdList,
|
|
|
- _In_ ID3D12Resource* pDestinationResource,
|
|
|
- _In_ ID3D12Resource* pIntermediate,
|
|
|
- _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
|
|
|
- _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
|
|
|
- UINT64 RequiredSize,
|
|
|
- _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
|
|
|
- _In_reads_(NumSubresources) const UINT* pNumRows,
|
|
|
- _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
|
|
|
- _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
|
|
|
+ _In_ ID3D12GraphicsCommandList* pCmdList,
|
|
|
+ _In_ ID3D12Resource* pDestinationResource,
|
|
|
+ _In_ ID3D12Resource* pIntermediate,
|
|
|
+ _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
|
|
|
+ _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
|
|
|
+ UINT64 RequiredSize,
|
|
|
+ _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
|
|
|
+ _In_reads_(NumSubresources) const UINT* pNumRows,
|
|
|
+ _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
|
|
|
+ _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
|
|
|
{
|
|
|
- // Minor validation
|
|
|
- auto IntermediateDesc = pIntermediate->GetDesc();
|
|
|
- auto DestinationDesc = pDestinationResource->GetDesc();
|
|
|
- if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
|
|
|
- IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
|
|
|
- RequiredSize > SIZE_T(-1) ||
|
|
|
- (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
|
|
|
- (FirstSubresource != 0 || NumSubresources != 1)))
|
|
|
- {
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- BYTE* pData;
|
|
|
- HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast<void**>(&pData));
|
|
|
- if (FAILED(hr))
|
|
|
- {
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- for (UINT i = 0; i < NumSubresources; ++i)
|
|
|
- {
|
|
|
- if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0;
|
|
|
- D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) };
|
|
|
- MemcpySubresource(&DestData, &pSrcData[i], static_cast<SIZE_T>(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth);
|
|
|
- }
|
|
|
- pIntermediate->Unmap(0, nullptr);
|
|
|
-
|
|
|
- if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
|
|
- {
|
|
|
- pCmdList->CopyBufferRegion(
|
|
|
- pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- for (UINT i = 0; i < NumSubresources; ++i)
|
|
|
- {
|
|
|
- CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
|
|
|
- CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
|
|
|
- pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
|
|
|
- }
|
|
|
- }
|
|
|
- return RequiredSize;
|
|
|
+ // Minor validation
|
|
|
+ auto IntermediateDesc = pIntermediate->GetDesc();
|
|
|
+ auto DestinationDesc = pDestinationResource->GetDesc();
|
|
|
+ if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
|
|
|
+ IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
|
|
|
+ RequiredSize > SIZE_T(-1) ||
|
|
|
+ (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
|
|
|
+ (FirstSubresource != 0 || NumSubresources != 1)))
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ BYTE* pData;
|
|
|
+ HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast<void**>(&pData));
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (UINT i = 0; i < NumSubresources; ++i)
|
|
|
+ {
|
|
|
+ if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0;
|
|
|
+ D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) };
|
|
|
+ MemcpySubresource(&DestData, &pSrcData[i], static_cast<SIZE_T>(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth);
|
|
|
+ }
|
|
|
+ pIntermediate->Unmap(0, nullptr);
|
|
|
+
|
|
|
+ if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
|
|
+ {
|
|
|
+ pCmdList->CopyBufferRegion(
|
|
|
+ pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for (UINT i = 0; i < NumSubresources; ++i)
|
|
|
+ {
|
|
|
+ CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
|
|
|
+ CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
|
|
|
+ pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return RequiredSize;
|
|
|
}
|
|
|
|
|
|
inline UINT64 UpdateSubresources(
|
|
|
- _In_ ID3D12GraphicsCommandList* pCmdList,
|
|
|
- _In_ ID3D12Resource* pDestinationResource,
|
|
|
- _In_ ID3D12Resource* pIntermediate,
|
|
|
- UINT64 IntermediateOffset,
|
|
|
- _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
|
|
|
- _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
|
|
|
- _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
|
|
|
+ _In_ ID3D12GraphicsCommandList* pCmdList,
|
|
|
+ _In_ ID3D12Resource* pDestinationResource,
|
|
|
+ _In_ ID3D12Resource* pIntermediate,
|
|
|
+ UINT64 IntermediateOffset,
|
|
|
+ _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
|
|
|
+ _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
|
|
|
+ _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
|
|
|
{
|
|
|
- UINT64 RequiredSize = 0;
|
|
|
- auto MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
|
|
|
- if (MemToAlloc > SIZE_MAX)
|
|
|
- {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
|
|
|
- if (pMem == nullptr)
|
|
|
- {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- auto pLayouts = static_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
|
|
|
- auto pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
|
|
|
- auto pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
|
|
|
-
|
|
|
- auto Desc = pDestinationResource->GetDesc();
|
|
|
- static_driver->device->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
|
|
|
-
|
|
|
- UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData);
|
|
|
- HeapFree(GetProcessHeap(), 0, pMem);
|
|
|
- return Result;
|
|
|
+ UINT64 RequiredSize = 0;
|
|
|
+ auto MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
|
|
|
+ if (MemToAlloc > SIZE_MAX)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
|
|
|
+ if (pMem == nullptr)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ auto pLayouts = static_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
|
|
|
+ auto pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
|
|
|
+ auto pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
|
|
|
+
|
|
|
+ auto Desc = pDestinationResource->GetDesc();
|
|
|
+ static_driver->device->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
|
|
|
+
|
|
|
+ UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData);
|
|
|
+ HeapFree(GetProcessHeap(), 0, pMem);
|
|
|
+ return Result;
|
|
|
}
|
|
|
|
|
|
+#endif
|
|
|
+
|
|
|
// ---- RESOURCES
|
|
|
|
|
|
ID3D12Resource *HL_NAME(get_back_buffer)( int index ) {
|
|
|
ID3D12Resource *buf = NULL;
|
|
|
+#ifndef HL_XBS
|
|
|
static_driver->swapchain->GetBuffer(index, IID_PPV_ARGS(&buf));
|
|
|
+#else
|
|
|
+ buf = static_driver->swapBuffers[index];
|
|
|
+#endif
|
|
|
return buf;
|
|
|
}
|
|
|
|
|
|
ID3D12Resource *HL_NAME(create_committed_resource)( D3D12_HEAP_PROPERTIES *heapProperties, D3D12_HEAP_FLAGS heapFlags, D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initialState, D3D12_CLEAR_VALUE *clearValue ) {
|
|
|
ID3D12Resource *res = NULL;
|
|
|
+#ifdef HL_XBS
|
|
|
+ // In normal dx, INDIRECT_ARGUMENT is included in GENERIC_READ (but we never use it alone) , so we remove it to obtain GENERIC_READ in xbox
|
|
|
+ initialState = (D3D12_RESOURCE_STATES)(initialState & ~D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT);
|
|
|
+#endif
|
|
|
DXERR(static_driver->device->CreateCommittedResource(heapProperties, heapFlags, desc, initialState, clearValue, IID_PPV_ARGS(&res)));
|
|
|
return res;
|
|
|
}
|
|
@@ -404,10 +577,15 @@ void HL_NAME(resource_unmap)( ID3D12Resource *res, int subres, D3D12_RANGE *rang
|
|
|
}
|
|
|
|
|
|
int64 HL_NAME(get_required_intermediate_size)( ID3D12Resource *res, int first, int count ) {
|
|
|
- auto desc = res->GetDesc();
|
|
|
- UINT64 size = 0;
|
|
|
- static_driver->device->GetCopyableFootprints(&desc, first, count, 0, NULL, NULL, NULL, &size);
|
|
|
- return size;
|
|
|
+ auto desc = res->GetDesc();
|
|
|
+ UINT64 size = 0;
|
|
|
+ static_driver->device->GetCopyableFootprints(&desc, first, count, 0, NULL, NULL, NULL, &size);
|
|
|
+#ifdef HL_XBS
|
|
|
+ D3D12_PLACED_SUBRESOURCE_FOOTPRINT pLayouts;
|
|
|
+ static_driver->device->GetCopyableFootprints(&desc, first, 1, 0, &pLayouts, NULL, NULL, NULL);
|
|
|
+ size += pLayouts.Offset;
|
|
|
+#endif
|
|
|
+ return size;
|
|
|
}
|
|
|
|
|
|
bool HL_NAME(update_sub_resource)( ID3D12GraphicsCommandList *cmd, ID3D12Resource *res, ID3D12Resource *tmp, int64 tmpOffs, int first, int count, D3D12_SUBRESOURCE_DATA *data ) {
|
|
@@ -415,7 +593,7 @@ bool HL_NAME(update_sub_resource)( ID3D12GraphicsCommandList *cmd, ID3D12Resourc
|
|
|
}
|
|
|
|
|
|
void HL_NAME(get_copyable_footprints)( D3D12_RESOURCE_DESC *desc, int first, int count, int64 offset, D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts, int *numRows, int64 *rowSizes, int64 *totalBytes ) {
|
|
|
- static_driver->device->GetCopyableFootprints(desc, first, count, offset, layouts, (UINT*)numRows, (UINT64*)rowSizes, (UINT64*)totalBytes);
|
|
|
+ static_driver->device->GetCopyableFootprints(desc, first, count, offset, layouts, (UINT*)numRows, (UINT64*)rowSizes, (UINT64*)totalBytes);
|
|
|
}
|
|
|
|
|
|
DEFINE_PRIM(_VOID, create_render_target_view, _RES _STRUCT _I64);
|
|
@@ -437,25 +615,49 @@ DEFINE_PRIM(_VOID, get_copyable_footprints, _STRUCT _I32 _I32 _I64 _STRUCT _BYTE
|
|
|
// ---- SHADERS
|
|
|
|
|
|
typedef struct {
|
|
|
+#ifndef HL_XBS
|
|
|
IDxcLibrary *library;
|
|
|
IDxcCompiler *compiler;
|
|
|
+#else
|
|
|
+ IDxcUtils *utils;
|
|
|
+ IDxcCompiler3 *compiler;
|
|
|
+#endif
|
|
|
} dx_compiler;
|
|
|
|
|
|
dx_compiler *HL_NAME(compiler_create)() {
|
|
|
dx_compiler *comp = (dx_compiler*)hl_gc_alloc_raw(sizeof(dx_compiler));
|
|
|
memset(comp,0,sizeof(dx_compiler));
|
|
|
+#ifndef HL_XBS
|
|
|
CHKERR(DxcCreateInstance(CLSID_DxcLibrary, IID_PPV_ARGS(&comp->library)));
|
|
|
CHKERR(DxcCreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&comp->compiler)));
|
|
|
+#else
|
|
|
+ CHKERR(DxcCreateInstance(CLSID_DxcUtils, IID_PPV_ARGS_OLD(&comp->utils)));
|
|
|
+ CHKERR(DxcCreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS_OLD(&comp->compiler)));
|
|
|
+#endif
|
|
|
return comp;
|
|
|
}
|
|
|
|
|
|
vbyte *HL_NAME(compiler_compile)( dx_compiler *comp, uchar *source, uchar *profile, varray *args, int *dataLen ) {
|
|
|
IDxcBlobEncoding *blob = NULL;
|
|
|
IDxcOperationResult *result = NULL;
|
|
|
+#ifndef HL_XBS
|
|
|
comp->library->CreateBlobWithEncodingFromPinned(source,(int)ustrlen(source)*2,1200/*DXC_CP_UTF16*/,&blob);
|
|
|
+#else
|
|
|
+ comp->utils->CreateBlobFromPinned(source, (int)ustrlen(source) * 2, 1200/*DXC_CP_UTF16*/, &blob);
|
|
|
+#endif
|
|
|
if( blob == NULL )
|
|
|
hl_error("Could not create blob");
|
|
|
+#ifndef HL_XBS
|
|
|
comp->compiler->Compile(blob,L"",L"main",profile,hl_aptr(args,LPCWSTR),args->size,NULL,0,NULL,&result);
|
|
|
+#else
|
|
|
+ BOOL knownEncoding = FALSE;
|
|
|
+ UINT32 encoding = 0U;
|
|
|
+ blob->GetEncoding(&knownEncoding, &encoding);
|
|
|
+ DxcBuffer dxcBuffer = { blob->GetBufferPointer(), blob->GetBufferSize(), encoding };
|
|
|
+ std::vector<LPCWSTR> arguments(hl_aptr(args, LPCWSTR), hl_aptr(args, LPCWSTR) + args->size);
|
|
|
+ arguments.insert(arguments.end(), { L"-E", L"main", L"-T", profile, L"-D", L"__XBOX_DISABLE_PRECOMPILE" });
|
|
|
+ CHKERR(comp->compiler->Compile(&dxcBuffer, arguments.data(), arguments.size(), NULL, IID_PPV_ARGS_OLD(&result)));
|
|
|
+#endif
|
|
|
HRESULT hr;
|
|
|
result->GetStatus(&hr);
|
|
|
if( !SUCCEEDED(hr) ) {
|