DirectX 12 API support
This commit is contained in:
parent
3ac574b6b5
commit
588bf6adc9
@ -19,19 +19,22 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#if !defined(__d3d11_h__) && !defined(__d3d11_x_h__) && !defined(__d3d12_h__) && !defined(__d3d12_x_h__)
|
||||
#if defined(_XBOX_ONE) && defined(_TITLE)
|
||||
#include <d3d11_x.h>
|
||||
#define DCOMMON_H_INCLUDED
|
||||
#else
|
||||
#include <d3d11_1.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <directxmath.h>
|
||||
|
||||
#include <ocidl.h>
|
||||
|
||||
#define DIRECTX_TEX_VERSION 140
|
||||
#define DIRECTX_TEX_VERSION 150
|
||||
|
||||
struct IWICImagingFactory;
|
||||
struct IWICMetadataQueryReader;
|
||||
@ -542,11 +545,13 @@ namespace DirectX
|
||||
_In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float threshold, _Out_ ScratchImage& cImages );
|
||||
// Note that threshold is only used by BC1. TEX_THRESHOLD_DEFAULT is a typical value to use
|
||||
|
||||
#if defined(__d3d11_h__) || defined(__d3d11_x_h__)
|
||||
HRESULT __cdecl Compress( _In_ ID3D11Device* pDevice, _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _In_ DWORD compress,
|
||||
_In_ float alphaWeight, _Out_ ScratchImage& image );
|
||||
HRESULT __cdecl Compress( _In_ ID3D11Device* pDevice, _In_ const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||
_In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaWeight, _Out_ ScratchImage& cImages );
|
||||
// DirectCompute-based compression (alphaWeight is only used by BC7. 1.0 is the typical value to use)
|
||||
#endif
|
||||
|
||||
HRESULT __cdecl Decompress( _In_ const Image& cImage, _In_ DXGI_FORMAT format, _Out_ ScratchImage& image );
|
||||
HRESULT __cdecl Decompress( _In_reads_(nimages) const Image* cImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||
@ -657,6 +662,7 @@ namespace DirectX
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Direct3D 11 functions
|
||||
#if defined(__d3d11_h__) || defined(__d3d11_x_h__)
|
||||
bool __cdecl IsSupportedTexture( _In_ ID3D11Device* pDevice, _In_ const TexMetadata& metadata );
|
||||
|
||||
HRESULT __cdecl CreateTexture( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||
@ -674,6 +680,28 @@ namespace DirectX
|
||||
_Outptr_ ID3D11ShaderResourceView** ppSRV );
|
||||
|
||||
HRESULT __cdecl CaptureTexture( _In_ ID3D11Device* pDevice, _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _Out_ ScratchImage& result );
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Direct3D 12 functions
|
||||
#if defined(__d3d12_h__) || defined(__d3d12_x_h__)
|
||||
bool __cdecl IsSupportedTexture( _In_ ID3D12Device* pDevice, _In_ const TexMetadata& metadata );
|
||||
|
||||
HRESULT __cdecl CreateTexture( _In_ ID3D12Device* pDevice, _In_ const TexMetadata& metadata,
|
||||
_Outptr_ ID3D12Resource** ppResource );
|
||||
|
||||
HRESULT __cdecl CreateTextureEx( _In_ ID3D12Device* pDevice, _In_ const TexMetadata& metadata,
|
||||
_In_ D3D12_RESOURCE_FLAGS resFlags, _In_ bool forceSRGB,
|
||||
_Outptr_ ID3D12Resource** ppResource );
|
||||
|
||||
HRESULT __cdecl PrepareUpload( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
|
||||
std::vector<D3D12_SUBRESOURCE_DATA>& subresources );
|
||||
|
||||
HRESULT __cdecl CaptureTexture( _In_ ID3D12CommandQueue* pCommandQueue, _In_ ID3D12Resource* pSource, _In_ bool isCubeMap,
|
||||
_Out_ ScratchImage& result,
|
||||
_In_ D3D12_RESOURCE_STATES beforeState = D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
_In_ D3D12_RESOURCE_STATES afterState = D3D12_RESOURCE_STATE_RENDER_TARGET );
|
||||
#endif
|
||||
|
||||
#include "DirectXTex.inl"
|
||||
|
||||
|
716
DirectXTex/DirectXTexD3D12.cpp
Normal file
716
DirectXTex/DirectXTexD3D12.cpp
Normal file
@ -0,0 +1,716 @@
|
||||
//-------------------------------------------------------------------------------------
|
||||
// DirectXTexD3D12.cpp
|
||||
//
|
||||
// DirectX Texture Library - Direct3D 12 helpers
|
||||
//
|
||||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
// PARTICULAR PURPOSE.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
#include "directxtexp.h"
|
||||
|
||||
#if defined(_XBOX_ONE) && defined(_TITLE)
|
||||
#include "d3dx12_x.h"
|
||||
#else
|
||||
#include "d3dx12.h"
|
||||
#endif
|
||||
|
||||
#ifndef IID_GRAPHICS_PPV_ARGS
|
||||
#define IID_GRAPHICS_PPV_ARGS(x) IID_PPV_ARGS(x)
|
||||
#endif
|
||||
|
||||
using namespace DirectX;
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
static_assert(TEX_DIMENSION_TEXTURE1D == D3D12_RESOURCE_DIMENSION_TEXTURE1D, "header enum mismatch");
|
||||
static_assert(TEX_DIMENSION_TEXTURE2D == D3D12_RESOURCE_DIMENSION_TEXTURE2D, "header enum mismatch");
|
||||
static_assert(TEX_DIMENSION_TEXTURE3D == D3D12_RESOURCE_DIMENSION_TEXTURE3D, "header enum mismatch");
|
||||
|
||||
namespace
|
||||
{
|
||||
inline void TransitionResource(
|
||||
_In_ ID3D12GraphicsCommandList* commandList,
|
||||
_In_ ID3D12Resource* resource,
|
||||
_In_ D3D12_RESOURCE_STATES stateBefore,
|
||||
_In_ D3D12_RESOURCE_STATES stateAfter)
|
||||
{
|
||||
assert(commandList != 0);
|
||||
assert(resource != 0);
|
||||
|
||||
if (stateBefore == stateAfter)
|
||||
return;
|
||||
|
||||
D3D12_RESOURCE_BARRIER desc = {};
|
||||
desc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
desc.Transition.pResource = resource;
|
||||
desc.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
desc.Transition.StateBefore = stateBefore;
|
||||
desc.Transition.StateAfter = stateAfter;
|
||||
|
||||
commandList->ResourceBarrier(1, &desc);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
HRESULT Capture(_In_ ID3D12Device* device,
|
||||
_In_ ID3D12CommandQueue* pCommandQ,
|
||||
_In_ ID3D12Resource* pSource,
|
||||
const D3D12_RESOURCE_DESC& desc,
|
||||
ComPtr<ID3D12Resource>& pStaging,
|
||||
std::unique_ptr<uint8_t[]>& layoutBuff,
|
||||
UINT& numberOfResources,
|
||||
D3D12_RESOURCE_STATES beforeState,
|
||||
D3D12_RESOURCE_STATES afterState)
|
||||
{
|
||||
if (!pCommandQ || !pSource)
|
||||
return E_INVALIDARG;
|
||||
|
||||
D3D12_HEAP_PROPERTIES sourceHeapProperties;
|
||||
D3D12_HEAP_FLAGS sourceHeapFlags;
|
||||
HRESULT hr = pSource->GetHeapProperties(&sourceHeapProperties, &sourceHeapFlags);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// TODO - planar?
|
||||
numberOfResources = (desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
|
||||
? 1 : desc.DepthOrArraySize;
|
||||
numberOfResources *= desc.MipLevels;
|
||||
if (numberOfResources > D3D12_REQ_SUBRESOURCES)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
size_t memAlloc = (sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * numberOfResources;
|
||||
if (memAlloc > SIZE_MAX)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
layoutBuff.reset(new uint8_t[memAlloc]);
|
||||
|
||||
auto pLayout = reinterpret_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(layoutBuff.get());
|
||||
auto pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayout + numberOfResources);
|
||||
auto pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + numberOfResources);
|
||||
|
||||
UINT64 totalResourceSize = 0;
|
||||
device->GetCopyableFootprints(&desc, 0, numberOfResources, 0,
|
||||
pLayout, pNumRows, pRowSizesInBytes, &totalResourceSize);
|
||||
|
||||
if (sourceHeapProperties.Type == D3D12_HEAP_TYPE_READBACK)
|
||||
{
|
||||
// Handle case where the source is already a staging texture we can use directly
|
||||
pStaging = pSource;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Create a command allocator
|
||||
ComPtr<ID3D12CommandAllocator> commandAlloc;
|
||||
hr = device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_GRAPHICS_PPV_ARGS(commandAlloc.GetAddressOf()));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// Spin up a new command list
|
||||
ComPtr<ID3D12GraphicsCommandList> commandList;
|
||||
hr = device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAlloc.Get(), nullptr, IID_GRAPHICS_PPV_ARGS(commandList.GetAddressOf()));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// Create a fence
|
||||
ComPtr<ID3D12Fence> fence;
|
||||
hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_GRAPHICS_PPV_ARGS(fence.GetAddressOf()));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
CD3DX12_HEAP_PROPERTIES defaultHeapProperties(D3D12_HEAP_TYPE_DEFAULT);
|
||||
CD3DX12_HEAP_PROPERTIES readBackHeapProperties(D3D12_HEAP_TYPE_READBACK);
|
||||
|
||||
// Readback resources must be buffers
|
||||
D3D12_RESOURCE_DESC bufferDesc = {};
|
||||
bufferDesc.Alignment = desc.Alignment;
|
||||
bufferDesc.DepthOrArraySize = 1;
|
||||
bufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
bufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
bufferDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
bufferDesc.Height = 1;
|
||||
bufferDesc.Width = totalResourceSize;
|
||||
bufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
bufferDesc.MipLevels = 1;
|
||||
bufferDesc.SampleDesc.Count = 1;
|
||||
bufferDesc.SampleDesc.Quality = 0;
|
||||
|
||||
ComPtr<ID3D12Resource> copySource(pSource);
|
||||
if (desc.SampleDesc.Count > 1)
|
||||
{
|
||||
// MSAA content must be resolved before being copied to a staging texture
|
||||
auto descCopy = desc;
|
||||
descCopy.SampleDesc.Count = 1;
|
||||
descCopy.SampleDesc.Quality = 0;
|
||||
|
||||
ComPtr<ID3D12Resource> pTemp;
|
||||
hr = device->CreateCommittedResource(
|
||||
&defaultHeapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&descCopy,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_GRAPHICS_PPV_ARGS(pTemp.GetAddressOf()));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
assert(pTemp);
|
||||
|
||||
DXGI_FORMAT fmt = desc.Format;
|
||||
if (IsTypeless(fmt))
|
||||
{
|
||||
// Assume a UNORM if it exists otherwise use FLOAT
|
||||
fmt = MakeTypelessUNORM(fmt);
|
||||
fmt = MakeTypelessFLOAT(fmt);
|
||||
}
|
||||
|
||||
D3D12_FEATURE_DATA_FORMAT_SUPPORT formatInfo = { fmt };
|
||||
hr = device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &formatInfo, sizeof(formatInfo));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (!(formatInfo.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D))
|
||||
return E_FAIL;
|
||||
|
||||
for (UINT item = 0; item < desc.DepthOrArraySize; ++item)
|
||||
{
|
||||
for (UINT level = 0; level < desc.MipLevels; ++level)
|
||||
{
|
||||
UINT index = D3D12CalcSubresource(level, item, 0, desc.MipLevels, desc.DepthOrArraySize);
|
||||
commandList->ResolveSubresource(pTemp.Get(), index, pSource, index, fmt);
|
||||
}
|
||||
}
|
||||
|
||||
copySource = pTemp;
|
||||
}
|
||||
|
||||
// Create a staging texture
|
||||
hr = device->CreateCommittedResource(
|
||||
&readBackHeapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&bufferDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_GRAPHICS_PPV_ARGS(pStaging.GetAddressOf()));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
assert(pStaging);
|
||||
|
||||
// Transition the resource if necessary
|
||||
TransitionResource(commandList.Get(), pSource, beforeState, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
|
||||
// Get the copy target location
|
||||
for (UINT j = 0; j < numberOfResources; ++j)
|
||||
{
|
||||
CD3DX12_TEXTURE_COPY_LOCATION copyDest(pStaging.Get(), pLayout[j]);
|
||||
CD3DX12_TEXTURE_COPY_LOCATION copySrc(copySource.Get(), j);
|
||||
commandList->CopyTextureRegion(©Dest, 0, 0, 0, ©Src, nullptr);
|
||||
}
|
||||
|
||||
// Transition the resource to the next state
|
||||
TransitionResource(commandList.Get(), pSource, D3D12_RESOURCE_STATE_COPY_SOURCE, afterState);
|
||||
|
||||
hr = commandList->Close();
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// Execute the command list
|
||||
pCommandQ->ExecuteCommandLists(1, (ID3D12CommandList**)commandList.GetAddressOf());
|
||||
|
||||
// Signal the fence
|
||||
hr = pCommandQ->Signal(fence.Get(), 1);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// Block until the copy is complete
|
||||
while (fence->GetCompletedValue() < 1)
|
||||
SwitchToThread();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=====================================================================================
|
||||
// Entry-points
|
||||
//=====================================================================================
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Determine if given texture metadata is supported on the given device
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
bool DirectX::IsSupportedTexture(
|
||||
ID3D12Device* pDevice,
|
||||
const TexMetadata& metadata)
|
||||
{
|
||||
if (!pDevice)
|
||||
return false;
|
||||
|
||||
// Validate format
|
||||
DXGI_FORMAT fmt = metadata.format;
|
||||
|
||||
if (!IsValid(fmt))
|
||||
return false;
|
||||
|
||||
// Validate miplevel count
|
||||
if (metadata.mipLevels > D3D12_REQ_MIP_LEVELS)
|
||||
return false;
|
||||
|
||||
// Validate array size, dimension, and width/height
|
||||
size_t arraySize = metadata.arraySize;
|
||||
size_t iWidth = metadata.width;
|
||||
size_t iHeight = metadata.height;
|
||||
size_t iDepth = metadata.depth;
|
||||
|
||||
// Most cases are known apriori based on feature level, but we use this for robustness to handle the few optional cases
|
||||
D3D12_FEATURE_DATA_FORMAT_SUPPORT formatSupport = { fmt };
|
||||
HRESULT hr = pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &formatSupport, sizeof(formatSupport));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
memset(&formatSupport, 0, sizeof(formatSupport));
|
||||
}
|
||||
|
||||
if (metadata.mipLevels > 1 && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_MIP))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (metadata.dimension)
|
||||
{
|
||||
case TEX_DIMENSION_TEXTURE1D:
|
||||
if (!(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE1D))
|
||||
return false;
|
||||
|
||||
if ((arraySize > D3D12_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION)
|
||||
|| (iWidth > D3D12_REQ_TEXTURE1D_U_DIMENSION))
|
||||
return false;
|
||||
|
||||
{
|
||||
UINT numberOfResources = static_cast<UINT>(arraySize * metadata.mipLevels);
|
||||
if (numberOfResources > D3D12_REQ_SUBRESOURCES)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case TEX_DIMENSION_TEXTURE2D:
|
||||
if (metadata.IsCubemap())
|
||||
{
|
||||
if (!(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURECUBE))
|
||||
return false;
|
||||
|
||||
if ((arraySize > D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION)
|
||||
|| (iWidth > D3D12_REQ_TEXTURECUBE_DIMENSION)
|
||||
|| (iHeight > D3D12_REQ_TEXTURECUBE_DIMENSION))
|
||||
return false;
|
||||
}
|
||||
else // Not a cube map
|
||||
{
|
||||
if (!(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D))
|
||||
return false;
|
||||
|
||||
if ((arraySize > D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION)
|
||||
|| (iWidth > D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION)
|
||||
|| (iHeight > D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION))
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
UINT numberOfResources = static_cast<UINT>(arraySize * metadata.mipLevels);
|
||||
if (numberOfResources > D3D12_REQ_SUBRESOURCES)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case TEX_DIMENSION_TEXTURE3D:
|
||||
if (!(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE3D))
|
||||
return false;
|
||||
|
||||
if ((arraySize > 1)
|
||||
|| (iWidth > D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
|
||||
|| (iHeight > D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
|
||||
|| (iDepth > D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION))
|
||||
return false;
|
||||
|
||||
{
|
||||
UINT numberOfResources = static_cast<UINT>(metadata.mipLevels);
|
||||
if (numberOfResources > D3D12_REQ_SUBRESOURCES)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Not a supported dimension
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Create a texture resource
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::CreateTexture(
|
||||
ID3D12Device* pDevice,
|
||||
const TexMetadata& metadata,
|
||||
ID3D12Resource** ppResource)
|
||||
{
|
||||
return CreateTextureEx(
|
||||
pDevice, metadata,
|
||||
D3D12_RESOURCE_FLAG_NONE, false,
|
||||
ppResource);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::CreateTextureEx(
|
||||
ID3D12Device* pDevice,
|
||||
const TexMetadata& metadata,
|
||||
D3D12_RESOURCE_FLAGS resFlags,
|
||||
bool forceSRGB,
|
||||
ID3D12Resource** ppResource)
|
||||
{
|
||||
if (!pDevice || !ppResource)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*ppResource = nullptr;
|
||||
|
||||
if (!metadata.mipLevels || !metadata.arraySize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if ((metadata.width > UINT32_MAX) || (metadata.height > UINT32_MAX)
|
||||
|| (metadata.mipLevels > UINT16_MAX) || (metadata.arraySize > UINT16_MAX))
|
||||
return E_INVALIDARG;
|
||||
|
||||
DXGI_FORMAT format = metadata.format;
|
||||
if (forceSRGB)
|
||||
{
|
||||
format = MakeSRGB(format);
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_DESC desc = {};
|
||||
desc.Width = static_cast<UINT>(metadata.width);
|
||||
desc.Height = static_cast<UINT>(metadata.height);
|
||||
desc.MipLevels = static_cast<UINT16>(metadata.mipLevels);
|
||||
desc.DepthOrArraySize = (metadata.dimension == TEX_DIMENSION_TEXTURE3D)
|
||||
? static_cast<UINT16>(metadata.depth)
|
||||
: static_cast<UINT16>(metadata.arraySize);
|
||||
desc.Format = format;
|
||||
desc.Flags = resFlags;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Dimension = static_cast<D3D12_RESOURCE_DIMENSION>(metadata.dimension);
|
||||
|
||||
CD3DX12_HEAP_PROPERTIES defaultHeapProperties(D3D12_HEAP_TYPE_DEFAULT);
|
||||
|
||||
HRESULT hr = pDevice->CreateCommittedResource(
|
||||
&defaultHeapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&desc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_GRAPHICS_PPV_ARGS(ppResource));
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Prepares a texture resource for upload
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::PrepareUpload(
|
||||
const Image* srcImages,
|
||||
size_t nimages,
|
||||
const TexMetadata& metadata,
|
||||
std::vector<D3D12_SUBRESOURCE_DATA>& subresources)
|
||||
{
|
||||
if (!srcImages || !nimages || !metadata.mipLevels || !metadata.arraySize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
size_t numberOfResources = (metadata.dimension == TEX_DIMENSION_TEXTURE3D)
|
||||
? 1 : metadata.arraySize;
|
||||
numberOfResources *= metadata.mipLevels;
|
||||
if (numberOfResources > D3D12_REQ_SUBRESOURCES)
|
||||
return E_INVALIDARG;
|
||||
|
||||
subresources.reserve(numberOfResources);
|
||||
|
||||
// TODO - Needs special handling for planar formats (planes treated are independant subresources in DX12)
|
||||
|
||||
// Fill out subresource array
|
||||
if (metadata.IsVolumemap())
|
||||
{
|
||||
//--- Volume case -------------------------------------------------------------
|
||||
if (!metadata.depth)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (metadata.depth > UINT16_MAX)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (metadata.arraySize > 1)
|
||||
// Direct3D 12 doesn't support arrays of 3D textures
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
|
||||
size_t depth = metadata.depth;
|
||||
|
||||
for (size_t level = 0; level < metadata.mipLevels; ++level)
|
||||
{
|
||||
size_t index = metadata.ComputeIndex(level, 0, 0);
|
||||
if (index >= nimages)
|
||||
return E_FAIL;
|
||||
|
||||
const Image& img = srcImages[index];
|
||||
|
||||
if (img.format != metadata.format)
|
||||
return E_FAIL;
|
||||
|
||||
if (!img.pixels)
|
||||
return E_POINTER;
|
||||
|
||||
// Verify pixels in image 1 .. (depth-1) are exactly image->slicePitch apart
|
||||
// For 3D textures, this relies on all slices of the same miplevel being continous in memory
|
||||
// (this is how ScratchImage lays them out), which is why we just give the 0th slice to Direct3D 11
|
||||
const uint8_t* pSlice = img.pixels + img.slicePitch;
|
||||
for (size_t slice = 1; slice < depth; ++slice)
|
||||
{
|
||||
size_t tindex = metadata.ComputeIndex(level, 0, slice);
|
||||
if (tindex >= nimages)
|
||||
return E_FAIL;
|
||||
|
||||
const Image& timg = srcImages[tindex];
|
||||
|
||||
if (!timg.pixels)
|
||||
return E_POINTER;
|
||||
|
||||
if (timg.pixels != pSlice
|
||||
|| timg.format != metadata.format
|
||||
|| timg.rowPitch != img.rowPitch
|
||||
|| timg.slicePitch != img.slicePitch)
|
||||
return E_FAIL;
|
||||
|
||||
pSlice = timg.pixels + img.slicePitch;
|
||||
}
|
||||
|
||||
D3D12_SUBRESOURCE_DATA sr = { img.pixels, static_cast<LONG_PTR>(img.rowPitch), static_cast<LONG_PTR>(img.slicePitch) };
|
||||
subresources.emplace_back(sr);
|
||||
|
||||
if (depth > 1)
|
||||
depth >>= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- 1D or 2D texture case ---------------------------------------------------
|
||||
for (size_t item = 0; item < metadata.arraySize; ++item)
|
||||
{
|
||||
for (size_t level = 0; level < metadata.mipLevels; ++level)
|
||||
{
|
||||
size_t index = metadata.ComputeIndex(level, item, 0);
|
||||
if (index >= nimages)
|
||||
return E_FAIL;
|
||||
|
||||
const Image& img = srcImages[index];
|
||||
|
||||
if (img.format != metadata.format)
|
||||
return E_FAIL;
|
||||
|
||||
if (!img.pixels)
|
||||
return E_POINTER;
|
||||
|
||||
D3D12_SUBRESOURCE_DATA sr =
|
||||
{
|
||||
img.pixels,
|
||||
static_cast<LONG_PTR>(img.rowPitch),
|
||||
static_cast<LONG_PTR>(img.slicePitch)
|
||||
};
|
||||
subresources.emplace_back(sr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Save a texture resource
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::CaptureTexture(
|
||||
ID3D12CommandQueue* pCommandQueue,
|
||||
ID3D12Resource* pSource,
|
||||
bool isCubeMap,
|
||||
ScratchImage& result,
|
||||
D3D12_RESOURCE_STATES beforeState,
|
||||
D3D12_RESOURCE_STATES afterState)
|
||||
{
|
||||
if (!pCommandQueue || !pSource)
|
||||
return E_INVALIDARG;
|
||||
|
||||
ComPtr<ID3D12Device> device;
|
||||
pCommandQueue->GetDevice(IID_GRAPHICS_PPV_ARGS(device.GetAddressOf()));
|
||||
|
||||
auto desc = pSource->GetDesc();
|
||||
|
||||
ComPtr<ID3D12Resource> pStaging;
|
||||
std::unique_ptr<uint8_t[]> layoutBuff;
|
||||
UINT numberOfResources;
|
||||
HRESULT hr = Capture(device.Get(),
|
||||
pCommandQueue,
|
||||
pSource,
|
||||
desc,
|
||||
pStaging,
|
||||
layoutBuff,
|
||||
numberOfResources,
|
||||
beforeState,
|
||||
afterState);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (!layoutBuff || !numberOfResources)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
auto pLayout = reinterpret_cast<const D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(layoutBuff.get());
|
||||
auto pRowSizesInBytes = reinterpret_cast<const UINT64*>(pLayout + numberOfResources);
|
||||
auto pNumRows = reinterpret_cast<const UINT*>(pRowSizesInBytes + numberOfResources);
|
||||
|
||||
switch (desc.Dimension)
|
||||
{
|
||||
case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
|
||||
{
|
||||
TexMetadata mdata;
|
||||
mdata.width = static_cast<size_t>(desc.Width);
|
||||
mdata.height = mdata.depth = 1;
|
||||
mdata.arraySize = desc.DepthOrArraySize;
|
||||
mdata.mipLevels = desc.MipLevels;
|
||||
mdata.miscFlags = 0;
|
||||
mdata.miscFlags2 = 0;
|
||||
mdata.format = desc.Format;
|
||||
mdata.dimension = TEX_DIMENSION_TEXTURE1D;
|
||||
|
||||
hr = result.Initialize(mdata);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
break;
|
||||
|
||||
case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
|
||||
{
|
||||
TexMetadata mdata;
|
||||
mdata.width = static_cast<size_t>(desc.Width);
|
||||
mdata.height = desc.Height;
|
||||
mdata.depth = 1;
|
||||
mdata.arraySize = desc.DepthOrArraySize;
|
||||
mdata.mipLevels = desc.MipLevels;
|
||||
mdata.miscFlags = isCubeMap ? TEX_MISC_TEXTURECUBE : 0;
|
||||
mdata.miscFlags2 = 0;
|
||||
mdata.format = desc.Format;
|
||||
mdata.dimension = TEX_DIMENSION_TEXTURE2D;
|
||||
|
||||
hr = result.Initialize(mdata);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
break;
|
||||
|
||||
case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
|
||||
{
|
||||
TexMetadata mdata;
|
||||
mdata.width = static_cast<size_t>(desc.Width);
|
||||
mdata.height = desc.Height;
|
||||
mdata.depth = desc.DepthOrArraySize;
|
||||
mdata.arraySize = 1;
|
||||
mdata.mipLevels = desc.MipLevels;
|
||||
mdata.miscFlags = 0;
|
||||
mdata.miscFlags2 = 0;
|
||||
mdata.format = desc.Format;
|
||||
mdata.dimension = TEX_DIMENSION_TEXTURE3D;
|
||||
|
||||
hr = result.Initialize(mdata);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
BYTE* pData;
|
||||
hr = pStaging->Map(0, nullptr, reinterpret_cast<void**>(&pData));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
result.Release();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
UINT arraySize, depth;
|
||||
if (desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
|
||||
{
|
||||
arraySize = 1;
|
||||
depth = desc.DepthOrArraySize;
|
||||
}
|
||||
else
|
||||
{
|
||||
arraySize = desc.DepthOrArraySize;
|
||||
depth = 1;
|
||||
}
|
||||
|
||||
for (UINT item = 0; item < arraySize; ++item)
|
||||
{
|
||||
UINT height = desc.Height;
|
||||
|
||||
for (UINT level = 0; level < desc.MipLevels; ++level)
|
||||
{
|
||||
UINT dindex = D3D12CalcSubresource(level, item, 0 /* TODO planes */,
|
||||
desc.MipLevels, arraySize);
|
||||
assert(dindex < numberOfResources);
|
||||
|
||||
const Image* img = result.GetImage(level, item, 0);
|
||||
if (!img)
|
||||
{
|
||||
pStaging->Unmap(0, nullptr);
|
||||
result.Release();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (!img->pixels)
|
||||
{
|
||||
pStaging->Unmap(0, nullptr);
|
||||
result.Release();
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
D3D12_MEMCPY_DEST destData = { img->pixels, img->rowPitch, img->slicePitch };
|
||||
D3D12_SUBRESOURCE_DATA srcData =
|
||||
{
|
||||
pData + pLayout[dindex].Offset,
|
||||
static_cast<LONG_PTR>(pLayout[dindex].Footprint.RowPitch),
|
||||
static_cast<LONG_PTR>(pLayout[dindex].Footprint.RowPitch * pNumRows[dindex])
|
||||
};
|
||||
|
||||
if (pRowSizesInBytes[dindex] > (SIZE_T)-1)
|
||||
{
|
||||
pStaging->Unmap(0, nullptr);
|
||||
result.Release();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
MemcpySubresource(&destData, &srcData,
|
||||
(SIZE_T)pRowSizesInBytes[dindex],
|
||||
pNumRows[dindex],
|
||||
pLayout[dindex].Footprint.Depth);
|
||||
}
|
||||
|
||||
if (height > 1)
|
||||
height >>= 1;
|
||||
}
|
||||
|
||||
pStaging->Unmap(0, nullptr);
|
||||
|
||||
return S_OK;
|
||||
}
|
@ -32,6 +32,17 @@
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(_XBOX_ONE) && defined(_TITLE)
|
||||
#include <d3d12_x.h>
|
||||
#include <d3d11_x.h>
|
||||
#elif (_WIN32_WINNT >= _WIN32_WINNT_WIN10)
|
||||
#include <d3d12.h>
|
||||
#include <d3d11_4.h>
|
||||
#else
|
||||
#include <d3d11_1.h>
|
||||
#endif
|
||||
|
||||
#include <directxmath.h>
|
||||
#include <directxpackedvector.h>
|
||||
#include <assert.h>
|
||||
|
@ -393,6 +393,7 @@
|
||||
<ClCompile Include="BC4BC5.cpp" />
|
||||
<ClCompile Include="BC6HBC7.cpp" />
|
||||
<ClInclude Include="BCDirectCompute.h" />
|
||||
<ClInclude Include="d3dx12.h" />
|
||||
<CLInclude Include="DDS.h" />
|
||||
<ClInclude Include="filters.h" />
|
||||
<CLInclude Include="scoped.h" />
|
||||
@ -404,6 +405,7 @@
|
||||
<ClCompile Include="DirectXTexCompressGPU.cpp" />
|
||||
<ClCompile Include="DirectXTexConvert.cpp" />
|
||||
<ClCompile Include="DirectXTexD3D11.cpp" />
|
||||
<ClCompile Include="DirectXTexD3D12.cpp" />
|
||||
<ClCompile Include="DirectXTexDDS.cpp" />
|
||||
<ClCompile Include="DirectXTexFlipRotate.cpp" />
|
||||
<ClCompile Include="DirectXTexHDR.cpp" />
|
||||
|
@ -42,6 +42,9 @@
|
||||
<CLInclude Include="scoped.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</CLInclude>
|
||||
<ClInclude Include="d3dx12.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BC.cpp">
|
||||
@ -101,6 +104,9 @@
|
||||
<ClCompile Include="DirectXTexHDR.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectXTexD3D12.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CLInclude Include="BC.h">
|
||||
|
@ -35,6 +35,7 @@
|
||||
<ClCompile Include="DirectXTexCompressGPU.cpp" />
|
||||
<ClCompile Include="DirectXTexConvert.cpp" />
|
||||
<ClCompile Include="DirectXTexD3D11.cpp" />
|
||||
<ClCompile Include="DirectXTexD3D12.cpp" />
|
||||
<ClCompile Include="DirectXTexDDS.cpp" />
|
||||
<ClCompile Include="DirectXTexFlipRotate.cpp" />
|
||||
<ClCompile Include="DirectXTexHDR.cpp" />
|
||||
@ -58,6 +59,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="BC.h" />
|
||||
<ClInclude Include="BCDirectCompute.h" />
|
||||
<ClInclude Include="d3dx12.h" />
|
||||
<ClInclude Include="DDS.h" />
|
||||
<ClInclude Include="DirectXTex.h" />
|
||||
<ClInclude Include="DirectXTexP.h" />
|
||||
|
@ -61,6 +61,9 @@
|
||||
<ClCompile Include="DirectXTexHDR.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectXTexD3D12.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="DirectXTex.h">
|
||||
@ -84,6 +87,9 @@
|
||||
<ClInclude Include="scoped.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="d3dx12.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
|
@ -50,6 +50,7 @@
|
||||
<ClCompile Include="DirectXTexCompressGPU.cpp" />
|
||||
<ClCompile Include="DirectXTexConvert.cpp" />
|
||||
<ClCompile Include="DirectXTexD3D11.cpp" />
|
||||
<ClCompile Include="DirectXTexD3D12.cpp" />
|
||||
<ClCompile Include="DirectXTexDDS.cpp" />
|
||||
<ClCompile Include="DirectXTexFlipRotate.cpp" />
|
||||
<ClCompile Include="DirectXTexHDR.cpp" />
|
||||
|
@ -159,5 +159,8 @@
|
||||
<ClCompile Include="DirectXTexHDR.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectXTexD3D12.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
2040
DirectXTex/d3dx12.h
Normal file
2040
DirectXTex/d3dx12.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user