diff --git a/Auxiliary/DirectXTexXbox.h b/Auxiliary/DirectXTexXbox.h new file mode 100644 index 0000000..f2b244c --- /dev/null +++ b/Auxiliary/DirectXTexXbox.h @@ -0,0 +1,172 @@ +//-------------------------------------------------------------------------------------- +// File: DirectXTexXbox.h +// +// DirectXTex Auxillary functions for Xbox texture processing +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +//-------------------------------------------------------------------------------------- + +#pragma once + +#ifndef _M_X64 +#error This tool is only supported for x64 native +#endif + +#include "DirectXTex.h" + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonportable-system-include-path" +#pragma clang diagnostic ignored "-Wold-style-cast" +#endif + +#if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) +#include +#else +#include +#endif + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#ifdef _GAMING_XBOX_SCARLETT +#include +#elif defined(_GAMING_XBOX) +#include +#elif defined(_XBOX_ONE) && defined(_TITLE) +#include +#else +#include +#endif + +#define DIRECTX_TEX_XBOX_VERSION 150 + +namespace Xbox +{ +#if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + using XboxTileMode = XG_SWIZZLE_MODE; + constexpr XboxTileMode c_XboxTileModeInvalid = XG_SWIZZLE_MODE_INVALID; + constexpr XboxTileMode c_XboxTileModeLinear = XG_SWIZZLE_MODE_LINEAR; +#else + using XboxTileMode = XG_TILE_MODE; + constexpr XboxTileMode c_XboxTileModeInvalid = XG_TILE_MODE_INVALID; + constexpr XboxTileMode c_XboxTileModeLinear = XG_TILE_MODE_LINEAR; +#endif + + class XboxImage + { + public: + XboxImage() noexcept + : dataSize(0), baseAlignment(0), tilemode(c_XboxTileModeInvalid), metadata{}, memory(nullptr) {} + XboxImage(XboxImage&& moveFrom) noexcept + : dataSize(0), baseAlignment(0), tilemode(c_XboxTileModeInvalid), metadata{}, memory(nullptr) { *this = std::move(moveFrom); } + ~XboxImage() { Release(); } + + XboxImage& __cdecl operator= (XboxImage&& moveFrom) noexcept; + + XboxImage(const XboxImage&) = delete; + XboxImage& operator=(const XboxImage&) = delete; + + HRESULT Initialize(_In_ const XG_TEXTURE1D_DESC& desc, _In_ const XG_RESOURCE_LAYOUT& layout, _In_ uint32_t miscFlags2 = 0); + HRESULT Initialize(_In_ const XG_TEXTURE2D_DESC& desc, _In_ const XG_RESOURCE_LAYOUT& layout, _In_ uint32_t miscFlags2 = 0); + HRESULT Initialize(_In_ const XG_TEXTURE3D_DESC& desc, _In_ const XG_RESOURCE_LAYOUT& layout, _In_ uint32_t miscFlags2 = 0); + HRESULT Initialize(_In_ const DirectX::TexMetadata& mdata, _In_ XboxTileMode tm, _In_ uint32_t size, _In_ uint32_t alignment); + + void Release(); + + const DirectX::TexMetadata& GetMetadata() const { return metadata; } + XboxTileMode GetTileMode() const { return tilemode; } + + uint32_t GetSize() const { return dataSize; } + uint32_t GetAlignment() const { return baseAlignment; } + uint8_t* GetPointer() const { return memory; } + + private: + uint32_t dataSize; + uint32_t baseAlignment; + XboxTileMode tilemode; + DirectX::TexMetadata metadata; + uint8_t* memory; + }; + + //--------------------------------------------------------------------------------- + // Image I/O + + HRESULT GetMetadataFromDDSMemory( + _In_reads_bytes_(size) const void* pSource, _In_ size_t size, + _Out_ DirectX::TexMetadata& metadata, _Out_ bool& isXbox); + HRESULT GetMetadataFromDDSFile( + _In_z_ const wchar_t* szFile, _Out_ DirectX::TexMetadata& metadata, _Out_ bool& isXbox); + + HRESULT GetMetadataFromDDSMemoryEx( + _In_reads_bytes_(size) const void* pSource, _In_ size_t size, + _Out_ DirectX::TexMetadata& metadata, _Out_ bool& isXbox, + _Out_opt_ DirectX::DDSMetaData* ddPixelFormat); + HRESULT GetMetadataFromDDSFileEx( + _In_z_ const wchar_t* szFile, _Out_ DirectX::TexMetadata& metadata, _Out_ bool& isXbox, + _Out_opt_ DirectX::DDSMetaData* ddPixelFormat); + + HRESULT LoadFromDDSMemory( + _In_reads_bytes_(size) const void* pSource, _In_ size_t size, + _Out_opt_ DirectX::TexMetadata* metadata, _Out_ XboxImage& image); + HRESULT LoadFromDDSFile( + _In_z_ const wchar_t* szFile, + _Out_opt_ DirectX::TexMetadata* metadata, _Out_ XboxImage& image); + + HRESULT LoadFromDDSMemoryEx( + _In_reads_bytes_(size) const void* pSource, _In_ size_t size, + _Out_opt_ DirectX::TexMetadata* metadata, + _Out_opt_ DirectX::DDSMetaData* ddPixelFormat, + _Out_ XboxImage& image); + HRESULT LoadFromDDSFileEx( + _In_z_ const wchar_t* szFile, + _Out_opt_ DirectX::TexMetadata* metadata, + _Out_opt_ DirectX::DDSMetaData* ddPixelFormat, + _Out_ XboxImage& image); + + HRESULT SaveToDDSMemory(_In_ const XboxImage& xbox, _Out_ DirectX::Blob& blob); + HRESULT SaveToDDSFile(_In_ const XboxImage& xbox, _In_z_ const wchar_t* szFile); + + //--------------------------------------------------------------------------------- + // Xbox Texture Tiling / Detiling (requires XG DLL to be present at runtime) + + HRESULT Tile(_In_ const DirectX::Image& srcImage, _Out_ XboxImage& xbox, _In_ XboxTileMode mode = c_XboxTileModeInvalid); + HRESULT Tile( + _In_ const DirectX::Image* srcImages, _In_ size_t nimages, _In_ const DirectX::TexMetadata& metadata, + _Out_ XboxImage& xbox, _In_ XboxTileMode mode = c_XboxTileModeInvalid); + + HRESULT Detile(_In_ const XboxImage& xbox, _Out_ DirectX::ScratchImage& image); + + //--------------------------------------------------------------------------------- + // Direct3D 11.X functions + +#if defined(_XBOX_ONE) && defined(_TITLE) && defined(__d3d11_x_h__) + + HRESULT CreateTexture( + _In_ ID3D11DeviceX* d3dDevice, + _In_ const XboxImage& xbox, _Outptr_opt_ ID3D11Resource** ppResource, _Outptr_ void** grfxMemory); + + HRESULT CreateShaderResourceView( + _In_ ID3D11DeviceX* d3dDevice, + _In_ const XboxImage& xbox, _Outptr_opt_ ID3D11ShaderResourceView** ppSRV, _Outptr_ void** grfxMemory); + + void FreeTextureMemory(_In_ ID3D11DeviceX* d3dDevice, _In_opt_ void* grfxMemory); + +#endif + + //--------------------------------------------------------------------------------- + // Direct3D 12.X functions + +#if ((defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)) && (defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__)) + + HRESULT CreateTexture( + _In_ ID3D12Device* d3dDevice, + _In_ const XboxImage& xbox, _Outptr_opt_ ID3D12Resource** ppResource, _Outptr_ void** grfxMemory); + + void FreeTextureMemory(_In_ ID3D12Device* d3dDevice, _In_opt_ void* grfxMemory); + +#endif + +} // namespace diff --git a/Auxiliary/DirectXTexXboxD3D11X.cpp b/Auxiliary/DirectXTexXboxD3D11X.cpp new file mode 100644 index 0000000..b6b826b --- /dev/null +++ b/Auxiliary/DirectXTexXboxD3D11X.cpp @@ -0,0 +1,258 @@ +//------------------------------------------------------------------------------------- +// DirectXTexD3D11X.cpp +// +// DirectXTex Auxillary functions for creating resouces from XboxImage containers +// via the CreatePlacement APIs +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +//------------------------------------------------------------------------------------- + +#include "DirectXTexP.h" +#include "DirectXTexXbox.h" + +#ifdef _GAMING_XBOX +#error This module is not supported for GDK +#elif !defined(_XBOX_ONE) || !defined(_TITLE) +#error This module only supports Xbox One exclusive apps +#endif + +using namespace Xbox; +using Microsoft::WRL::ComPtr; + +namespace +{ + //-------------------------------------------------------------------------------------- + // Default XMemAlloc attributes for texture loading + //-------------------------------------------------------------------------------------- + const uint64_t c_XMemAllocAttributes = MAKE_XALLOC_ATTRIBUTES( + eXALLOCAllocatorId_MiddlewareReservedMin, + 0, + XALLOC_MEMTYPE_GRAPHICS_WRITECOMBINE_GPU_READONLY, + XALLOC_PAGESIZE_64KB, + XALLOC_ALIGNMENT_64K); +} + +//===================================================================================== +// Entry-points +//===================================================================================== + +//------------------------------------------------------------------------------------- +// Create a texture resource +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT Xbox::CreateTexture( + ID3D11DeviceX* d3dDevice, + const XboxImage& xbox, + ID3D11Resource** ppResource, + void** grfxMemory) +{ + if (!d3dDevice || !ppResource || !grfxMemory) + return E_INVALIDARG; + + *grfxMemory = nullptr; + *ppResource = nullptr; + + if (!xbox.GetPointer() || !xbox.GetAlignment() || !xbox.GetSize() || xbox.GetTileMode() == c_XboxTileModeInvalid) + return E_INVALIDARG; + + // Allocate graphics memory + *grfxMemory = XMemAlloc(xbox.GetSize(), c_XMemAllocAttributes); + if (!*grfxMemory) + return E_OUTOFMEMORY; + + // Copy tiled data into graphics memory + memcpy(*grfxMemory, xbox.GetPointer(), xbox.GetSize()); + + // Create texture resource + auto& metadata = xbox.GetMetadata(); + + HRESULT hr = E_FAIL; + + switch (metadata.dimension) + { + case DirectX::TEX_DIMENSION_TEXTURE1D: + { + D3D11_TEXTURE1D_DESC desc = {}; + desc.Width = static_cast(metadata.width); + desc.MipLevels = static_cast(metadata.mipLevels); + desc.ArraySize = static_cast(metadata.arraySize); + desc.Format = metadata.format; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + ID3D11Texture1D* tex = nullptr; + hr = d3dDevice->CreatePlacementTexture1D(&desc, xbox.GetTileMode(), 0, *grfxMemory, &tex); + if (SUCCEEDED(hr) && tex) + { + *ppResource = tex; + } + } + break; + + case DirectX::TEX_DIMENSION_TEXTURE2D: + { + D3D11_TEXTURE2D_DESC desc = {}; + desc.Width = static_cast(metadata.width); + desc.Height = static_cast(metadata.height); + desc.MipLevels = static_cast(metadata.mipLevels); + desc.ArraySize = static_cast(metadata.arraySize); + desc.Format = metadata.format; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.MiscFlags = (metadata.miscFlags & DirectX::TEX_MISC_TEXTURECUBE) ? D3D11_RESOURCE_MISC_TEXTURECUBE : 0; + + ID3D11Texture2D* tex = nullptr; + hr = d3dDevice->CreatePlacementTexture2D(&desc, xbox.GetTileMode(), 0, *grfxMemory, &tex); + if (SUCCEEDED(hr) && tex) + { + *ppResource = tex; + } + } + break; + + case DirectX::TEX_DIMENSION_TEXTURE3D: + { + D3D11_TEXTURE3D_DESC desc = {}; + desc.Width = static_cast(metadata.width); + desc.Height = static_cast(metadata.height); + desc.Depth = static_cast(metadata.depth); + desc.MipLevels = static_cast(metadata.mipLevels); + desc.Format = metadata.format; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + ID3D11Texture3D* tex = nullptr; + hr = d3dDevice->CreatePlacementTexture3D(&desc, xbox.GetTileMode(), 0, *grfxMemory, &tex); + if (SUCCEEDED(hr) && tex) + { + *ppResource = tex; + } + } + break; + + default: + hr = E_FAIL; + break; + } + + if (FAILED(hr)) + { + XMemFree(grfxMemory, c_XMemAllocAttributes); + *grfxMemory = nullptr; + } + + return hr; +} + + +//------------------------------------------------------------------------------------- +// Create a shader resource view and associated texture +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT Xbox::CreateShaderResourceView( + ID3D11DeviceX* d3dDevice, + const XboxImage& xbox, + ID3D11ShaderResourceView** ppSRV, + void** grfxMemory) +{ + if (!ppSRV) + return E_INVALIDARG; + + *ppSRV = nullptr; + + ComPtr resource; + HRESULT hr = CreateTexture(d3dDevice, xbox, resource.GetAddressOf(), grfxMemory); + if (FAILED(hr)) + return hr; + + assert(resource); + + auto& metadata = xbox.GetMetadata(); + + D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {}; + SRVDesc.Format = metadata.format; + + switch (metadata.dimension) + { + case DirectX::TEX_DIMENSION_TEXTURE1D: + if (metadata.arraySize > 1) + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; + SRVDesc.Texture1DArray.MipLevels = static_cast(metadata.mipLevels); + SRVDesc.Texture1DArray.ArraySize = static_cast(metadata.arraySize); + } + else + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; + SRVDesc.Texture1D.MipLevels = static_cast(metadata.mipLevels); + } + break; + + case DirectX::TEX_DIMENSION_TEXTURE2D: + if (metadata.IsCubemap()) + { + if (metadata.arraySize > 6) + { + assert((metadata.arraySize % 6) == 0); + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; + SRVDesc.TextureCubeArray.MipLevels = static_cast(metadata.mipLevels); + SRVDesc.TextureCubeArray.NumCubes = static_cast(metadata.arraySize / 6); + } + else + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + SRVDesc.TextureCube.MipLevels = static_cast(metadata.mipLevels); + } + } + else if (metadata.arraySize > 1) + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + SRVDesc.Texture2DArray.MipLevels = static_cast(metadata.mipLevels); + SRVDesc.Texture2DArray.ArraySize = static_cast(metadata.arraySize); + } + else + { + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + SRVDesc.Texture2D.MipLevels = static_cast(metadata.mipLevels); + } + break; + + case DirectX::TEX_DIMENSION_TEXTURE3D: + assert(metadata.arraySize == 1); + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + SRVDesc.Texture3D.MipLevels = static_cast(metadata.mipLevels); + break; + + default: + assert(grfxMemory != nullptr); + XMemFree(grfxMemory, c_XMemAllocAttributes); + *grfxMemory = nullptr; + return E_FAIL; + } + + hr = d3dDevice->CreateShaderResourceView(resource.Get(), &SRVDesc, ppSRV); + if (FAILED(hr)) + { + XMemFree(grfxMemory, c_XMemAllocAttributes); + *grfxMemory = nullptr; + } + + return hr; +} + + +//------------------------------------------------------------------------------------- +// Free allocated graphics memory +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +void Xbox::FreeTextureMemory(ID3D11DeviceX* d3dDevice, void* grfxMemory) +{ + UNREFERENCED_PARAMETER(d3dDevice); // used only for overload resolution + + if (grfxMemory) + { + XMemFree(grfxMemory, c_XMemAllocAttributes); + } +} diff --git a/Auxiliary/DirectXTexXboxD3D12X.cpp b/Auxiliary/DirectXTexXboxD3D12X.cpp new file mode 100644 index 0000000..0053d79 --- /dev/null +++ b/Auxiliary/DirectXTexXboxD3D12X.cpp @@ -0,0 +1,117 @@ +//------------------------------------------------------------------------------------- +// DirectXTexD3D12X.cpp +// +// DirectXTex Auxillary functions for creating resouces from XboxImage containers +// via the CreatePlacedResourceX API +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +//------------------------------------------------------------------------------------- + +#include "DirectXTexP.h" +#include "DirectXTexXbox.h" + +#if !(defined(_XBOX_ONE) && defined(_TITLE)) && !defined(_GAMING_XBOX) +#error This module only supports Xbox exclusive apps +#endif + +#ifdef _GAMING_XBOX +#include +#endif + +using namespace Xbox; +using Microsoft::WRL::ComPtr; + +namespace +{ + //-------------------------------------------------------------------------------------- + // Default XMemAlloc attributes for texture loading + //-------------------------------------------------------------------------------------- + const uint64_t c_XMemAllocAttributes = MAKE_XALLOC_ATTRIBUTES( + eXALLOCAllocatorId_MiddlewareReservedMin, + 0, + XALLOC_MEMTYPE_GRAPHICS_WRITECOMBINE_GPU_READONLY, + XALLOC_PAGESIZE_64KB, + XALLOC_ALIGNMENT_64K + #ifdef _GAMING_XBOX + , 0 + #endif + ); +} + +//===================================================================================== +// Entry-points +//===================================================================================== + +//------------------------------------------------------------------------------------- +// Create a texture resource +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT Xbox::CreateTexture( + ID3D12Device* d3dDevice, + const XboxImage& xbox, + ID3D12Resource** ppResource, + void** grfxMemory) +{ + if (!d3dDevice || !ppResource || !grfxMemory) + return E_INVALIDARG; + + *grfxMemory = nullptr; + *ppResource = nullptr; + + if (!xbox.GetPointer() || !xbox.GetAlignment() || !xbox.GetSize() || xbox.GetTileMode() == c_XboxTileModeInvalid) + return E_INVALIDARG; + + // Allocate graphics memory + *grfxMemory = XMemAlloc(xbox.GetSize(), c_XMemAllocAttributes); + if (!*grfxMemory) + return E_OUTOFMEMORY; + + // Copy tiled data into graphics memory + memcpy(*grfxMemory, xbox.GetPointer(), xbox.GetSize()); + + // Create texture resource + auto& metadata = xbox.GetMetadata(); + + D3D12_RESOURCE_DESC desc = {}; + desc.Width = static_cast(metadata.width); + desc.Height = static_cast(metadata.height); + desc.MipLevels = static_cast(metadata.mipLevels); + desc.DepthOrArraySize = (metadata.dimension == DirectX::TEX_DIMENSION_TEXTURE3D) ? static_cast(metadata.depth) : static_cast(metadata.arraySize); + desc.Format = metadata.format; + desc.Flags = D3D12_RESOURCE_FLAG_NONE; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Dimension = static_cast(metadata.dimension); + desc.Layout = static_cast(0x100 | xbox.GetTileMode()); + + HRESULT hr = d3dDevice->CreatePlacedResourceX( + reinterpret_cast(*grfxMemory), + &desc, + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, + nullptr, + IID_GRAPHICS_PPV_ARGS(ppResource)); + + if (FAILED(hr)) + { + XMemFree(*grfxMemory, c_XMemAllocAttributes); + *grfxMemory = nullptr; + } + + return hr; +} + + +//------------------------------------------------------------------------------------- +// Free allocated graphics memory +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +void Xbox::FreeTextureMemory(ID3D12Device* d3dDevice, void* grfxMemory) +{ + UNREFERENCED_PARAMETER(d3dDevice); // used only for overload resolution + + if (grfxMemory) + { + XMemFree(grfxMemory, c_XMemAllocAttributes); + } +} diff --git a/Auxiliary/DirectXTexXboxDDS.cpp b/Auxiliary/DirectXTexXboxDDS.cpp new file mode 100644 index 0000000..53ab2d3 --- /dev/null +++ b/Auxiliary/DirectXTexXboxDDS.cpp @@ -0,0 +1,869 @@ +//-------------------------------------------------------------------------------------- +// File: DirectXTexXboxDDS.cpp +// +// DirectXTex Auxillary functions for saving "XBOX" Xbox variants of DDS files +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +//-------------------------------------------------------------------------------------- + +#include "DirectXTexP.h" +#include "DirectXTexXbox.h" + +#include "DDS.h" + +#if defined(_GAMING_XBOX) || defined(_USE_GXDK) +#include "gxdk.h" +#else +#include "xdk.h" +#endif + +using namespace DirectX; +using namespace Xbox; + +namespace +{ + const DDS_PIXELFORMAT DDSPF_XBOX = + { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('X','B','O','X'), 0, 0, 0, 0, 0 }; + +#pragma pack(push,1) + + struct DDS_HEADER_XBOX + // Must match structure in XboxDDSTextureLoader module + { + DXGI_FORMAT dxgiFormat; + uint32_t resourceDimension; + uint32_t miscFlag; // see DDS_RESOURCE_MISC_FLAG + uint32_t arraySize; + uint32_t miscFlags2; // see DDS_MISC_FLAGS2 + uint32_t tileMode; // see XG_TILE_MODE / XG_SWIZZLE_MODE + uint32_t baseAlignment; + uint32_t dataSize; + uint32_t xdkVer; // matching _XDK_VER / _GXDK_VER + }; + +#pragma pack(pop) + + constexpr uint32_t XBOX_TILEMODE_SCARLETT = 0x1000000; + + static_assert(sizeof(DDS_HEADER_XBOX) == 36, "DDS XBOX Header size mismatch"); + static_assert(sizeof(DDS_HEADER_XBOX) >= sizeof(DDS_HEADER_DXT10), "DDS XBOX Header should be larger than DX10 header"); + + constexpr size_t XBOX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_XBOX); + + //------------------------------------------------------------------------------------- + // Decodes DDS header using XBOX extended header (variant of DX10 header) + //------------------------------------------------------------------------------------- + HRESULT DecodeDDSHeader( + _In_reads_bytes_(size) const void* pSource, + size_t size, + DirectX::TexMetadata& metadata, + _Out_opt_ DDSMetaData* ddPixelFormat, + _Out_opt_ XboxTileMode* tmode, + _Out_opt_ uint32_t* dataSize, + _Out_opt_ uint32_t* baseAlignment) + { + if (!pSource) + return E_INVALIDARG; + + if (tmode) + { + *tmode = c_XboxTileModeInvalid; + } + if (dataSize) + { + *dataSize = 0; + } + if (baseAlignment) + { + *baseAlignment = 0; + } + + metadata = {}; + + if (ddPixelFormat) + { + *ddPixelFormat = {}; + } + + if (size < (sizeof(DDS_HEADER) + sizeof(uint32_t))) + { + return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + } + + // DDS files always start with the same magic number ("DDS ") + auto const dwMagicNumber = *reinterpret_cast(pSource); + if (dwMagicNumber != DDS_MAGIC) + { + return E_FAIL; + } + + auto pHeader = reinterpret_cast(reinterpret_cast(pSource) + sizeof(uint32_t)); + + // Verify header to validate DDS file + if (pHeader->size != sizeof(DDS_HEADER) + || pHeader->ddspf.size != sizeof(DDS_PIXELFORMAT)) + { + return E_FAIL; + } + + metadata.mipLevels = pHeader->mipMapCount; + if (metadata.mipLevels == 0) + metadata.mipLevels = 1; + + // Check for XBOX extension + if (!(pHeader->ddspf.flags & DDS_FOURCC) + || (MAKEFOURCC('X', 'B', 'O', 'X') != pHeader->ddspf.fourCC)) + { + // We know it's a DDS file, but it's not an XBOX extension + return S_FALSE; + } + + // Buffer must be big enough for both headers and magic value + if (size < XBOX_HEADER_SIZE) + { + return E_FAIL; + } + + auto xboxext = reinterpret_cast( + reinterpret_cast(pSource) + sizeof(uint32_t) + sizeof(DDS_HEADER)); + + #ifdef _GXDK_VER + if (xboxext->xdkVer < _GXDK_VER) + { + OutputDebugStringA("WARNING: DDS XBOX file may be outdated and need regeneration\n"); + } + #elif defined(_XDK_VER) + if (xboxext->xdkVer < _XDK_VER) + { + OutputDebugStringA("WARNING: DDS XBOX file may be outdated and need regeneration\n"); + } + #endif + + metadata.arraySize = xboxext->arraySize; + if (metadata.arraySize == 0) + { + return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + } + + metadata.format = xboxext->dxgiFormat; + if (!IsValid(metadata.format)) + { + return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + } + + static_assert(static_cast(TEX_MISC_TEXTURECUBE) == static_cast(DDS_RESOURCE_MISC_TEXTURECUBE), "DDS header mismatch"); + + metadata.miscFlags = xboxext->miscFlag & ~static_cast(TEX_MISC_TEXTURECUBE); + + switch (xboxext->resourceDimension) + { + case DDS_DIMENSION_TEXTURE1D: + + if ((pHeader->flags & DDS_HEIGHT) && pHeader->height != 1) + { + return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + } + + metadata.width = pHeader->width; + metadata.height = 1; + metadata.depth = 1; + metadata.dimension = TEX_DIMENSION_TEXTURE1D; + break; + + case DDS_DIMENSION_TEXTURE2D: + if (xboxext->miscFlag & DDS_RESOURCE_MISC_TEXTURECUBE) + { + metadata.miscFlags |= TEX_MISC_TEXTURECUBE; + metadata.arraySize *= 6; + } + + metadata.width = pHeader->width; + metadata.height = pHeader->height; + metadata.depth = 1; + metadata.dimension = TEX_DIMENSION_TEXTURE2D; + break; + + case DDS_DIMENSION_TEXTURE3D: + if (!(pHeader->flags & DDS_HEADER_FLAGS_VOLUME)) + { + return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + } + + if (metadata.arraySize > 1) + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + + metadata.width = pHeader->width; + metadata.height = pHeader->height; + metadata.depth = pHeader->depth; + metadata.dimension = TEX_DIMENSION_TEXTURE3D; + break; + + default: + return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + } + + if (static_cast(xboxext->tileMode) == c_XboxTileModeInvalid) + { + return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + } + + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + else if (!(xboxext->tileMode & XBOX_TILEMODE_SCARLETT)) + { + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + } + #else + else if (xboxext->tileMode & XBOX_TILEMODE_SCARLETT) + { + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + } + #endif + + static_assert(static_cast(TEX_MISC2_ALPHA_MODE_MASK) == static_cast(DDS_MISC_FLAGS2_ALPHA_MODE_MASK), "DDS header mismatch"); + + static_assert(static_cast(TEX_ALPHA_MODE_UNKNOWN) == static_cast(DDS_ALPHA_MODE_UNKNOWN), "DDS header mismatch"); + static_assert(static_cast(TEX_ALPHA_MODE_STRAIGHT) == static_cast(DDS_ALPHA_MODE_STRAIGHT), "DDS header mismatch"); + static_assert(static_cast(TEX_ALPHA_MODE_PREMULTIPLIED) == static_cast(DDS_ALPHA_MODE_PREMULTIPLIED), "DDS header mismatch"); + static_assert(static_cast(TEX_ALPHA_MODE_OPAQUE) == static_cast(DDS_ALPHA_MODE_OPAQUE), "DDS header mismatch"); + static_assert(static_cast(TEX_ALPHA_MODE_CUSTOM) == static_cast(DDS_ALPHA_MODE_CUSTOM), "DDS header mismatch"); + + metadata.miscFlags2 = xboxext->miscFlags2; + + if (tmode) + { + *tmode = static_cast(xboxext->tileMode & ~XBOX_TILEMODE_SCARLETT); + } + + if (baseAlignment) + *baseAlignment = xboxext->baseAlignment; + + if (dataSize) + *dataSize = xboxext->dataSize; + + // Handle DDS-specific metadata + if (ddPixelFormat) + { + ddPixelFormat->size = pHeader->ddspf.size; + ddPixelFormat->flags = pHeader->ddspf.flags; + ddPixelFormat->fourCC = pHeader->ddspf.fourCC; + ddPixelFormat->RGBBitCount = pHeader->ddspf.RGBBitCount; + ddPixelFormat->RBitMask = pHeader->ddspf.RBitMask; + ddPixelFormat->GBitMask = pHeader->ddspf.GBitMask; + ddPixelFormat->BBitMask = pHeader->ddspf.BBitMask; + ddPixelFormat->ABitMask = pHeader->ddspf.ABitMask; + } + + return S_OK; + } + + + //------------------------------------------------------------------------------------- + // Encodes DDS file header (magic value, header, XBOX extended header) + //------------------------------------------------------------------------------------- + HRESULT EncodeDDSHeader( + const XboxImage& xbox, + _Out_writes_(maxsize) void* pDestination, + size_t maxsize) + { + if (!pDestination) + return E_POINTER; + + if (maxsize < XBOX_HEADER_SIZE) + return E_NOT_SUFFICIENT_BUFFER; + + *reinterpret_cast(pDestination) = DDS_MAGIC; + + auto header = reinterpret_cast(reinterpret_cast(pDestination) + sizeof(uint32_t)); + + memset(header, 0, sizeof(DDS_HEADER)); + header->size = sizeof(DDS_HEADER); + header->flags = DDS_HEADER_FLAGS_TEXTURE; + header->caps = DDS_SURFACE_FLAGS_TEXTURE; + + auto& metadata = xbox.GetMetadata(); + + if (metadata.mipLevels > 0) + { + header->flags |= DDS_HEADER_FLAGS_MIPMAP; + + if (metadata.mipLevels > UINT32_MAX) + return E_INVALIDARG; + + header->mipMapCount = static_cast(metadata.mipLevels); + + if (header->mipMapCount > 1) + header->caps |= DDS_SURFACE_FLAGS_MIPMAP; + } + + switch (metadata.dimension) + { + case TEX_DIMENSION_TEXTURE1D: + if (metadata.width > UINT32_MAX) + return E_INVALIDARG; + + header->width = static_cast(metadata.width); + header->height = header->depth = 1; + break; + + case TEX_DIMENSION_TEXTURE2D: + if (metadata.height > UINT32_MAX + || metadata.width > UINT32_MAX) + return E_INVALIDARG; + + header->height = static_cast(metadata.height); + header->width = static_cast(metadata.width); + header->depth = 1; + + if (metadata.IsCubemap()) + { + header->caps |= DDS_SURFACE_FLAGS_CUBEMAP; + header->caps2 |= DDS_CUBEMAP_ALLFACES; + } + break; + + case TEX_DIMENSION_TEXTURE3D: + if (metadata.height > UINT32_MAX + || metadata.width > UINT32_MAX + || metadata.depth > UINT32_MAX) + return E_INVALIDARG; + + header->flags |= DDS_HEADER_FLAGS_VOLUME; + header->caps2 |= DDS_FLAGS_VOLUME; + header->height = static_cast(metadata.height); + header->width = static_cast(metadata.width); + header->depth = static_cast(metadata.depth); + break; + + default: + return E_FAIL; + } + + size_t rowPitch, slicePitch; + ComputePitch(metadata.format, metadata.width, metadata.height, rowPitch, slicePitch, CP_FLAGS_NONE); + + if (slicePitch > UINT32_MAX + || rowPitch > UINT32_MAX) + return E_FAIL; + + if (IsCompressed(metadata.format)) + { + header->flags |= DDS_HEADER_FLAGS_LINEARSIZE; + header->pitchOrLinearSize = static_cast(slicePitch); + } + else + { + header->flags |= DDS_HEADER_FLAGS_PITCH; + header->pitchOrLinearSize = static_cast(rowPitch); + } + + memcpy_s(&header->ddspf, sizeof(header->ddspf), &DDSPF_XBOX, sizeof(DDS_PIXELFORMAT)); + + // Setup XBOX extended header + auto xboxext = reinterpret_cast(reinterpret_cast(header) + sizeof(DDS_HEADER)); + + memset(xboxext, 0, sizeof(DDS_HEADER_XBOX)); + xboxext->dxgiFormat = metadata.format; + xboxext->resourceDimension = metadata.dimension; + + if (metadata.arraySize > UINT32_MAX) + return E_INVALIDARG; + + static_assert(static_cast(TEX_MISC_TEXTURECUBE) == static_cast(DDS_RESOURCE_MISC_TEXTURECUBE), "DDS header mismatch"); + xboxext->miscFlag = metadata.miscFlags & ~static_cast(TEX_MISC_TEXTURECUBE); + + if (metadata.miscFlags & TEX_MISC_TEXTURECUBE) + { + xboxext->miscFlag |= TEX_MISC_TEXTURECUBE; + assert((metadata.arraySize % 6) == 0); + xboxext->arraySize = static_cast(metadata.arraySize / 6); + } + else + { + xboxext->arraySize = static_cast(metadata.arraySize); + } + + static_assert(static_cast(TEX_MISC2_ALPHA_MODE_MASK) == static_cast(DDS_MISC_FLAGS2_ALPHA_MODE_MASK), "DDS header mismatch"); + + static_assert(static_cast(TEX_ALPHA_MODE_UNKNOWN) == static_cast(DDS_ALPHA_MODE_UNKNOWN), "DDS header mismatch"); + static_assert(static_cast(TEX_ALPHA_MODE_STRAIGHT) == static_cast(DDS_ALPHA_MODE_STRAIGHT), "DDS header mismatch"); + static_assert(static_cast(TEX_ALPHA_MODE_PREMULTIPLIED) == static_cast(DDS_ALPHA_MODE_PREMULTIPLIED), "DDS header mismatch"); + static_assert(static_cast(TEX_ALPHA_MODE_OPAQUE) == static_cast(DDS_ALPHA_MODE_OPAQUE), "DDS header mismatch"); + static_assert(static_cast(TEX_ALPHA_MODE_CUSTOM) == static_cast(DDS_ALPHA_MODE_CUSTOM), "DDS header mismatch"); + + xboxext->miscFlags2 = metadata.miscFlags2; + + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + xboxext->tileMode = static_cast(xbox.GetTileMode()) | XBOX_TILEMODE_SCARLETT; + #else + xboxext->tileMode = static_cast(xbox.GetTileMode()); + #endif + + xboxext->baseAlignment = xbox.GetAlignment(); + xboxext->dataSize = xbox.GetSize(); + #ifdef _GXDK_VER + xboxext->xdkVer = _GXDK_VER; + #elif defined(_XDK_VER) + xboxext->xdkVer = _XDK_VER; + #endif + + return S_OK; + } +} + + +//===================================================================================== +// Entry-points +//===================================================================================== + +//------------------------------------------------------------------------------------- +// Obtain metadata from DDS file in memory/on disk +//------------------------------------------------------------------------------------- + +_Use_decl_annotations_ +HRESULT Xbox::GetMetadataFromDDSMemory( + const void* pSource, + size_t size, + TexMetadata& metadata, + bool& isXbox) +{ + return Xbox::GetMetadataFromDDSMemoryEx(pSource, size, metadata, isXbox, nullptr); +} + +_Use_decl_annotations_ +HRESULT Xbox::GetMetadataFromDDSMemoryEx( + const void* pSource, + size_t size, + TexMetadata& metadata, + bool& isXbox, + DDSMetaData* ddPixelFormat) +{ + if (!pSource || !size) + return E_INVALIDARG; + + isXbox = false; + + HRESULT hr = DecodeDDSHeader(pSource, size, metadata, ddPixelFormat, nullptr, nullptr, nullptr); + + if (hr == S_FALSE) + { + hr = DirectX::GetMetadataFromDDSMemoryEx(pSource, size, DirectX::DDS_FLAGS_NONE, metadata, ddPixelFormat); + } + else if (SUCCEEDED(hr)) + { + isXbox = true; + } + + return hr; +} + +_Use_decl_annotations_ +HRESULT Xbox::GetMetadataFromDDSFile( + const wchar_t* szFile, + TexMetadata& metadata, + bool& isXbox) +{ + return Xbox::GetMetadataFromDDSFileEx(szFile, metadata, isXbox, nullptr); +} + +_Use_decl_annotations_ +HRESULT Xbox::GetMetadataFromDDSFileEx( + const wchar_t* szFile, + TexMetadata& metadata, + bool& isXbox, + DDSMetaData* ddPixelFormat) +{ + if (!szFile) + return E_INVALIDARG; + + isXbox = false; + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) + ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); +#else + ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, nullptr))); +#endif + if (!hFile) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + // Get the file size + FILE_STANDARD_INFO fileInfo; + if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo))) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid DDS file) + if (fileInfo.EndOfFile.HighPart > 0) + { + return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); + } + + // Need at least enough data to fill the standard header and magic number to be a valid DDS + if (fileInfo.EndOfFile.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t))) + { + return E_FAIL; + } + + // Read the header in (including extended header if present) + uint8_t header[XBOX_HEADER_SIZE] = {}; + + DWORD bytesRead = 0; + if (!ReadFile(hFile.get(), header, XBOX_HEADER_SIZE, &bytesRead, nullptr)) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + HRESULT hr = DecodeDDSHeader(header, bytesRead, metadata, ddPixelFormat, nullptr, nullptr, nullptr); + + if (hr == S_FALSE) + { + hr = DirectX::GetMetadataFromDDSMemoryEx(header, bytesRead, DirectX::DDS_FLAGS_NONE, metadata, ddPixelFormat); + } + else if (SUCCEEDED(hr)) + { + isXbox = true; + } + + return hr; +} + + +//------------------------------------------------------------------------------------- +// Load a DDS file in memory +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT Xbox::LoadFromDDSMemory( + const void* pSource, + size_t size, + TexMetadata* metadata, + XboxImage& xbox) +{ + return Xbox::LoadFromDDSMemoryEx(pSource, size, metadata, nullptr, xbox); +} + +_Use_decl_annotations_ +HRESULT Xbox::LoadFromDDSMemoryEx( + const void* pSource, + size_t size, + TexMetadata* metadata, + DDSMetaData* ddPixelFormat, + XboxImage& xbox) +{ + if (!pSource || !size) + return E_INVALIDARG; + + xbox.Release(); + + TexMetadata mdata; + uint32_t dataSize; + uint32_t baseAlignment; + XboxTileMode tmode; + HRESULT hr = DecodeDDSHeader(pSource, size, mdata, ddPixelFormat, &tmode, &dataSize, &baseAlignment); + if (hr == S_FALSE) + { + // It's a DDS, but not an XBOX variant + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + } + if (FAILED(hr)) + { + return hr; + } + + if (!dataSize || !baseAlignment) + { + return E_FAIL; + } + + if (size <= XBOX_HEADER_SIZE) + { + return E_FAIL; + } + + // Copy tiled data + const size_t remaining = size - XBOX_HEADER_SIZE; + + if (remaining < dataSize) + { + return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); + } + + hr = xbox.Initialize(mdata, tmode, dataSize, baseAlignment); + if (FAILED(hr)) + return hr; + + assert(xbox.GetPointer() != nullptr); + + memcpy(xbox.GetPointer(), reinterpret_cast(pSource) + XBOX_HEADER_SIZE, dataSize); + + if (metadata) + memcpy(metadata, &mdata, sizeof(TexMetadata)); + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +// Load a DDS file from disk +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT Xbox::LoadFromDDSFile( + const wchar_t* szFile, + TexMetadata* metadata, + XboxImage& xbox) +{ + return Xbox::LoadFromDDSFileEx(szFile, metadata, nullptr, xbox); +} + +_Use_decl_annotations_ +HRESULT Xbox::LoadFromDDSFileEx( + const wchar_t* szFile, + TexMetadata* metadata, + DDSMetaData* ddPixelFormat, + XboxImage& xbox) +{ + if (!szFile) + return E_INVALIDARG; + + xbox.Release(); + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) + ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr))); +#else + ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, nullptr))); +#endif + + if (!hFile) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + // Get the file size + FILE_STANDARD_INFO fileInfo; + if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo))) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + // File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid DDS file) + if (fileInfo.EndOfFile.HighPart > 0) + { + return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); + } + + // Need at least enough data to fill the standard header and magic number to be a valid DDS + if (fileInfo.EndOfFile.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t))) + { + return E_FAIL; + } + + // Read the header in (including extended header if present) + uint8_t header[XBOX_HEADER_SIZE] = {}; + + DWORD bytesRead = 0; + if (!ReadFile(hFile.get(), header, XBOX_HEADER_SIZE, &bytesRead, nullptr)) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + TexMetadata mdata; + XboxTileMode tmode; + uint32_t dataSize; + uint32_t baseAlignment; + HRESULT hr = DecodeDDSHeader(header, bytesRead, mdata, ddPixelFormat, &tmode, &dataSize, &baseAlignment); + if (hr == S_FALSE) + { + // It's a DDS, but not an XBOX variant + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + } + if (FAILED(hr)) + return hr; + + if (!dataSize || !baseAlignment) + { + return E_FAIL; + } + + // Read tiled data + const DWORD remaining = fileInfo.EndOfFile.LowPart - XBOX_HEADER_SIZE; + if (remaining == 0) + return E_FAIL; + + if (remaining < dataSize) + { + return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); + } + + hr = xbox.Initialize(mdata, tmode, dataSize, baseAlignment); + if (FAILED(hr)) + return hr; + + assert(xbox.GetPointer() != nullptr); + + if (!ReadFile(hFile.get(), xbox.GetPointer(), dataSize, &bytesRead, nullptr)) + { + xbox.Release(); + return HRESULT_FROM_WIN32(GetLastError()); + } + + if (metadata) + memcpy(metadata, &mdata, sizeof(TexMetadata)); + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +// Save a DDS file to memory +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT Xbox::SaveToDDSMemory(const XboxImage& xbox, Blob& blob) +{ + if (!xbox.GetPointer() || !xbox.GetSize() || !xbox.GetAlignment()) + return E_INVALIDARG; + + blob.Release(); + + HRESULT hr = blob.Initialize(XBOX_HEADER_SIZE + xbox.GetSize()); + if (FAILED(hr)) + return hr; + + // Copy header + auto pDestination = reinterpret_cast(blob.GetBufferPointer()); + assert(pDestination); + + hr = EncodeDDSHeader(xbox, pDestination, XBOX_HEADER_SIZE); + if (FAILED(hr)) + { + blob.Release(); + return hr; + } + + // Copy tiled data + const size_t remaining = blob.GetBufferSize() - XBOX_HEADER_SIZE; + pDestination += XBOX_HEADER_SIZE; + + if (!remaining) + { + blob.Release(); + return E_FAIL; + } + + if (remaining < xbox.GetSize()) + { + blob.Release(); + return E_UNEXPECTED; + } + + memcpy(pDestination, xbox.GetPointer(), xbox.GetSize()); + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +// Save a DDS file to disk +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT Xbox::SaveToDDSFile(const XboxImage& xbox, const wchar_t* szFile) +{ + if (!szFile || !xbox.GetPointer() || !xbox.GetSize() || !xbox.GetAlignment()) + return E_INVALIDARG; + + // Create DDS Header + uint8_t header[XBOX_HEADER_SIZE] = {}; + HRESULT hr = EncodeDDSHeader(xbox, header, XBOX_HEADER_SIZE); + if (FAILED(hr)) + return hr; + + // Create file and write header +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) + ScopedHandle hFile(safe_handle(CreateFile2(szFile, + GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr))); +#else + ScopedHandle hFile(safe_handle(CreateFileW(szFile, + GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr))); +#endif + if (!hFile) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + DWORD bytesWritten; + if (!WriteFile(hFile.get(), header, static_cast(XBOX_HEADER_SIZE), &bytesWritten, nullptr)) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + if (bytesWritten != XBOX_HEADER_SIZE) + { + return E_FAIL; + } + + // Write tiled data + if (!WriteFile(hFile.get(), xbox.GetPointer(), static_cast(xbox.GetSize()), &bytesWritten, nullptr)) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + if (bytesWritten != xbox.GetSize()) + { + return E_FAIL; + } + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Adapters for /Zc:wchar_t- clients + +#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED) + +namespace Xbox +{ + HRESULT __cdecl GetMetadataFromDDSFile( + _In_z_ const __wchar_t* szFile, + _Out_ DirectX::TexMetadata& metadata, + _Out_ bool& isXbox) + { + return GetMetadataFromDDSFile(reinterpret_cast(szFile), metadata, isXbox); + } + + HRESULT __cdecl GetMetadataFromDDSFileEx( + _In_z_ const __wchar_t* szFile, + _Out_ DirectX::TexMetadata& metadata, + _Out_ bool& isXbox, + _Out_opt_ DirectX::DDSMetaData* ddPixelFormat) + { + return GetMetadataFromDDSFileEx(reinterpret_cast(szFile), metadata, isXbox, ddPixelFormat); + } + + HRESULT __cdecl LoadFromDDSFile( + _In_z_ const __wchar_t* szFile, + _Out_opt_ DirectX::TexMetadata* metadata, + _Out_ XboxImage& image) + { + return LoadFromDDSFile(reinterpret_cast(szFile), metadata, image); + } + + HRESULT __cdecl LoadFromDDSFileEx( + _In_z_ const __wchar_t* szFile, + _Out_opt_ DirectX::TexMetadata* metadata, + _Out_opt_ DirectX::DDSMetaData* ddPixelFormat, + _Out_ XboxImage& image) + { + return LoadFromDDSFileEx(reinterpret_cast(szFile), metadata, ddPixelFormat, image); + } + + HRESULT __cdecl SaveToDDSFile(_In_ const XboxImage& xbox, _In_z_ const __wchar_t* szFile) + { + return SaveToDDSFile(xbox, reinterpret_cast(szFile)); + } +} + +#endif // !_NATIVE_WCHAR_T_DEFINED diff --git a/Auxiliary/DirectXTexXboxDetile.cpp b/Auxiliary/DirectXTexXboxDetile.cpp new file mode 100644 index 0000000..43da57a --- /dev/null +++ b/Auxiliary/DirectXTexXboxDetile.cpp @@ -0,0 +1,877 @@ +//-------------------------------------------------------------------------------------- +// File: DirectXTexXboxDetile.cpp +// +// DirectXTex Auxillary functions for converting from Xbox tiled to linear +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +//-------------------------------------------------------------------------------------- + +#include "DirectXTexP.h" +#include "DirectXTexXbox.h" + +using Microsoft::WRL::ComPtr; +using namespace DirectX; +using namespace DirectX::Internal; +using namespace Xbox; + +namespace +{ + //---------------------------------------------------------------------------------- + inline HRESULT DetileByElement1D( + const XboxImage& xbox, + uint32_t level, + _In_ XGTextureAddressComputer* computer, + const XG_RESOURCE_LAYOUT& layout, + _In_reads_(nimages) const Image* const * result, + size_t nimages, + size_t bpp, + size_t w, + bool packed) + { + const uint8_t* sptr = xbox.GetPointer(); + const uint8_t* endPtr = sptr + layout.SizeBytes; + + for (uint32_t item = 0; item < nimages; ++item) + { + const Image* img = result[item]; + if (!img || !img->pixels) + return E_POINTER; + + assert(img->width == result[0]->width); + assert(img->height == result[0]->height); + assert(img->rowPitch == result[0]->rowPitch); + assert(img->format == result[0]->format); + + uint8_t* dptr = img->pixels; + + for (size_t x = 0; x < w; ++x) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + const UINT64 element = (packed) ? (x >> 1) : x; + const size_t offset = computer->GetTexelElementOffsetBytes(0, level, element, 0, item, 0, nullptr); + #else + const size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, 0, item, 0); + #endif + if (offset == size_t(-1)) + return E_FAIL; + + const uint8_t* src = sptr + offset; + + if ((src + bpp) > endPtr) + return E_FAIL; + + memcpy(dptr, src, bpp); + dptr += bpp; + + if (packed) + ++x; + } + } + + return S_OK; + } + + //---------------------------------------------------------------------------------- + inline HRESULT DetileByElement2D( + const XboxImage& xbox, + uint32_t level, + _In_ XGTextureAddressComputer* computer, + const XG_RESOURCE_LAYOUT& layout, + _In_reads_(nimages) const Image* const * result, + size_t nimages, + size_t bpp, + size_t w, + size_t h, + bool packed) + { + const uint8_t* sptr = xbox.GetPointer(); + const uint8_t* endPtr = sptr + layout.SizeBytes; + + for (uint32_t item = 0; item < nimages; ++item) + { + const Image* img = result[item]; + if (!img || !img->pixels) + return E_POINTER; + + assert(img->width == result[0]->width); + assert(img->height == result[0]->height); + assert(img->rowPitch == result[0]->rowPitch); + assert(img->format == result[0]->format); + + uint8_t* dptr = img->pixels; + + for (uint32_t y = 0; y < h; ++y) + { + uint8_t* tptr = dptr; + + for (size_t x = 0; x < w; ++x) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + const UINT64 element = (packed) ? (x >> 1) : x; + const size_t offset = computer->GetTexelElementOffsetBytes(0, level, element, y, item, 0, nullptr); + #else + const size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, y, item, 0); + #endif + if (offset == size_t(-1)) + return E_FAIL; + + const uint8_t* src = sptr + offset; + + if ((src + bpp) > endPtr) + return E_FAIL; + + memcpy(tptr, src, bpp); + tptr += bpp; + + if (packed) + ++x; + } + + dptr += img->rowPitch; + } + } + + return S_OK; + } + + //---------------------------------------------------------------------------------- + inline HRESULT DetileByElement3D( + const XboxImage& xbox, + uint32_t level, + uint32_t slices, + _In_ XGTextureAddressComputer* computer, + const XG_RESOURCE_LAYOUT& layout, + const Image& result, + size_t bpp, + size_t w, + size_t h, + bool packed) + { + const uint8_t* sptr = xbox.GetPointer(); + const uint8_t* endPtr = sptr + layout.SizeBytes; + + uint8_t* dptr = result.pixels; + + for (uint32_t z = 0; z < slices; ++z) + { + uint8_t* rptr = dptr; + + for (uint32_t y = 0; y < h; ++y) + { + uint8_t* tptr = rptr; + + for (size_t x = 0; x < w; ++x) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + const UINT64 element = (packed) ? (x >> 1) : x; + const size_t offset = computer->GetTexelElementOffsetBytes(0, level, element, y, z, 0, nullptr); + #else + const size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, y, z, 0); + #endif + if (offset == size_t(-1)) + return E_FAIL; + + const uint8_t* src = sptr + offset; + + if ((src + bpp) > endPtr) + return E_FAIL; + + memcpy(tptr, src, bpp); + tptr += bpp; + + if (packed) + ++x; + } + + rptr += result.rowPitch; + } + + dptr += result.slicePitch; + } + + return S_OK; + } + + //------------------------------------------------------------------------------------- + // 1D Tiling + //------------------------------------------------------------------------------------- + HRESULT Detile1D( + const XboxImage& xbox, + uint32_t level, + _In_ XGTextureAddressComputer* computer, + const XG_RESOURCE_LAYOUT& layout, + _In_reads_(nimages) const Image** result, + size_t nimages) + { + if (!nimages) + return E_INVALIDARG; + + if (!xbox.GetPointer() || !computer || !result || !result[0]) + return E_POINTER; + + assert(layout.Planes == 1); + + const DXGI_FORMAT format = result[0]->format; + + assert(format == xbox.GetMetadata().format); + + assert(!IsCompressed(format)); + + bool byelement = IsTypeless(format); + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + if (nimages > 1) + byelement = true; + #endif + + if (IsPacked(format)) + { + const size_t bpp = (BitsPerPixel(format) + 7) / 8; + + // XG (XboxOne) incorrectly returns 2 instead of 4 here for layout.Plane[0].BytesPerElement + + const size_t w = result[0]->width; + assert(((w + 1) / 2) == layout.Plane[0].MipLayout[level].WidthElements); + + return DetileByElement1D(xbox, level, computer, layout, result, nimages, bpp, w, true); + } + else if (byelement) + { + //--- Typeless is done with per-element copy ---------------------------------- + const size_t bpp = (BitsPerPixel(format) + 7) / 8; + assert(bpp == layout.Plane[0].BytesPerElement); + + const size_t w = result[0]->width; + assert(w == layout.Plane[0].MipLayout[level].WidthElements); + + return DetileByElement1D(xbox, level, computer, layout, result, nimages, bpp, w, false); + } + else + { + //--- Standard format handling ------------------------------------------------ + auto& mip = layout.Plane[0].MipLayout[level]; + + const UINT32 tiledPixels = mip.PitchPixels * mip.PaddedDepthOrArraySize; + + auto scanline = make_AlignedArrayXMVECTOR(tiledPixels + result[0]->width); + + XMVECTOR* target = scanline.get(); + XMVECTOR* tiled = target + result[0]->width; + + #ifdef _DEBUG + memset(target, 0xCD, sizeof(XMVECTOR) * result[0]->width); + memset(tiled, 0xDD, sizeof(XMVECTOR) * tiledPixels); + #endif + + // Load tiled texture + if ((xbox.GetSize() - mip.OffsetBytes) < mip.SizeBytes) + return E_FAIL; + + if (!LoadScanline(tiled, tiledPixels, xbox.GetPointer() + mip.OffsetBytes, mip.SizeBytes, xbox.GetMetadata().format)) + return E_FAIL; + + // Perform detiling + for (uint32_t item = 0; item < nimages; ++item) + { + const Image* img = result[item]; + if (!img || !img->pixels) + return E_POINTER; + + assert(img->width == result[0]->width); + assert(img->height == result[0]->height); + assert(img->rowPitch == result[0]->rowPitch); + assert(img->format == result[0]->format); + + for (size_t x = 0; x < img->width; ++x) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, 0, item, 0, nullptr); + #else + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, 0, item, 0); + #endif + if (offset == size_t(-1)) + return E_FAIL; + + assert(offset >= mip.OffsetBytes); + assert(offset < mip.OffsetBytes + mip.SizeBytes); + + offset = (offset - mip.OffsetBytes) / layout.Plane[0].BytesPerElement; + assert(offset < tiledPixels); + + target[x] = tiled[offset]; + } + + if (!StoreScanline(img->pixels, img->rowPitch, img->format, target, img->width)) + return E_FAIL; + } + } + + return S_OK; + } + + + //------------------------------------------------------------------------------------- + // 2D Tiling + //------------------------------------------------------------------------------------- + HRESULT Detile2D( + const XboxImage& xbox, + uint32_t level, + _In_ XGTextureAddressComputer* computer, + const XG_RESOURCE_LAYOUT& layout, + _In_reads_(nimages) const Image** result, + size_t nimages) + { + if (!nimages) + return E_INVALIDARG; + + if (!xbox.GetPointer() || !computer || !result || !result[0]) + return E_POINTER; + + assert(xbox.GetMetadata().format == result[0]->format); + + assert(layout.Planes == 1); + + const DXGI_FORMAT format = result[0]->format; + + assert(format == xbox.GetMetadata().format); + + bool byelement = IsTypeless(format); + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + if (nimages > 1) + byelement = true; + #endif + + if (IsCompressed(format)) + { + //--- BC formats use per-block copy ------------------------------------------- + const size_t nbw = std::max(1, (result[0]->width + 3) / 4); + const size_t nbh = std::max(1, (result[0]->height + 3) / 4); + + const size_t bpb = (format == DXGI_FORMAT_BC1_TYPELESS + || format == DXGI_FORMAT_BC1_UNORM + || format == DXGI_FORMAT_BC1_UNORM_SRGB + || format == DXGI_FORMAT_BC4_TYPELESS + || format == DXGI_FORMAT_BC4_UNORM + || format == DXGI_FORMAT_BC4_SNORM) ? 8 : 16; + + assert(nbw == layout.Plane[0].MipLayout[level].WidthElements); + assert(nbh == layout.Plane[0].MipLayout[level].HeightElements); + assert(bpb == layout.Plane[0].BytesPerElement); + + return DetileByElement2D(xbox, level, computer, layout, result, nimages, bpb, nbw, nbh, false); + } + else if (IsPacked(format)) + { + const size_t bpp = (BitsPerPixel(format) + 7) / 8; + + // XG (XboxOne) incorrectly returns 2 instead of 4 here for layout.Plane[0].BytesPerElement + + const size_t w = result[0]->width; + const size_t h = result[0]->height; + assert(((w + 1) / 2) == layout.Plane[0].MipLayout[level].WidthElements); + assert(h == layout.Plane[0].MipLayout[level].HeightElements); + + return DetileByElement2D(xbox, level, computer, layout, result, nimages, bpp, w, h, true); + } + else if (byelement) + { + //--- Typeless is done with per-element copy ---------------------------------- + const size_t bpp = (BitsPerPixel(format) + 7) / 8; + assert(bpp == layout.Plane[0].BytesPerElement); + + const size_t w = result[0]->width; + const size_t h = result[0]->height; + + assert(w == layout.Plane[0].MipLayout[level].WidthElements); + assert(h == layout.Plane[0].MipLayout[level].HeightElements); + + return DetileByElement2D(xbox, level, computer, layout, result, nimages, bpp, w, h, false); + } + else + { + //--- Standard format handling ------------------------------------------------ + auto& mip = layout.Plane[0].MipLayout[level]; + + const UINT32 tiledPixels = mip.PaddedWidthElements * mip.PaddedHeightElements * mip.PaddedDepthOrArraySize; + + auto scanline = make_AlignedArrayXMVECTOR(tiledPixels + result[0]->width); + + XMVECTOR* target = scanline.get(); + XMVECTOR* tiled = target + result[0]->width; + + #ifdef _DEBUG + memset(target, 0xCD, sizeof(XMVECTOR) * result[0]->width); + memset(tiled, 0xDD, sizeof(XMVECTOR) * tiledPixels); + #endif + + // Load tiled texture + if ((xbox.GetSize() - mip.OffsetBytes) < mip.SizeBytes) + return E_FAIL; + + if (!LoadScanline(tiled, tiledPixels, xbox.GetPointer() + mip.OffsetBytes, mip.SizeBytes, xbox.GetMetadata().format)) + return E_FAIL; + + // Perform detiling + for (uint32_t item = 0; item < nimages; ++item) + { + const Image* img = result[item]; + if (!img || !img->pixels) + return E_POINTER; + + assert(img->width == result[0]->width); + assert(img->height == result[0]->height); + assert(img->rowPitch == result[0]->rowPitch); + assert(img->format == result[0]->format); + + auto dptr = reinterpret_cast(img->pixels); + for (uint32_t y = 0; y < img->height; ++y) + { + for (size_t x = 0; x < img->width; ++x) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, y, item, 0, nullptr); + #else + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, y, item, 0); + #endif + if (offset == size_t(-1)) + return E_FAIL; + + assert(offset >= mip.OffsetBytes); + assert(offset < mip.OffsetBytes + mip.SizeBytes); + + offset = (offset - mip.OffsetBytes) / layout.Plane[0].BytesPerElement; + assert(offset < tiledPixels); + + target[x] = tiled[offset]; + } + + if (!StoreScanline(dptr, img->rowPitch, img->format, target, img->width)) + return E_FAIL; + + dptr += img->rowPitch; + } + } + } + + return S_OK; + } + + + //------------------------------------------------------------------------------------- + // 3D Tiling + //------------------------------------------------------------------------------------- + HRESULT Detile3D( + const XboxImage& xbox, + uint32_t level, + uint32_t slices, + _In_ XGTextureAddressComputer* computer, + const XG_RESOURCE_LAYOUT& layout, + const Image& result) + { + if (!computer || !xbox.GetPointer() || !result.pixels) + return E_POINTER; + + assert(xbox.GetMetadata().format == result.format); + + assert(layout.Planes == 1); + + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + const bool byelement = true; + #else + const bool byelement = IsTypeless(result.format); + #endif + + if (IsCompressed(result.format)) + { + //--- BC formats use per-block copy ------------------------------------------- + const size_t nbw = std::max(1, (result.width + 3) / 4); + const size_t nbh = std::max(1, (result.height + 3) / 4); + + const size_t bpb = (result.format == DXGI_FORMAT_BC1_TYPELESS + || result.format == DXGI_FORMAT_BC1_UNORM + || result.format == DXGI_FORMAT_BC1_UNORM_SRGB + || result.format == DXGI_FORMAT_BC4_TYPELESS + || result.format == DXGI_FORMAT_BC4_UNORM + || result.format == DXGI_FORMAT_BC4_SNORM) ? 8 : 16; + + assert(nbw == layout.Plane[0].MipLayout[level].WidthElements); + assert(nbh == layout.Plane[0].MipLayout[level].HeightElements); + assert(bpb == layout.Plane[0].BytesPerElement); + + return DetileByElement3D(xbox, level, slices, computer, layout, result, bpb, nbw, nbh, false); + } + else if (IsPacked(result.format)) + { + const size_t bpp = (BitsPerPixel(result.format) + 7) / 8; + + // XG (XboxOne) incorrectly returns 2 instead of 4 here for layout.Plane[0].BytesPerElement + + assert(((result.width + 1) / 2) == layout.Plane[0].MipLayout[level].WidthElements); + assert(result.height == layout.Plane[0].MipLayout[level].HeightElements); + + return DetileByElement3D(xbox, level, slices, computer, layout, result, bpp, result.width, result.height, true); + } + else if (byelement) + { + //--- Typeless is done with per-element copy ---------------------------------- + const size_t bpp = (BitsPerPixel(result.format) + 7) / 8; + assert(bpp == layout.Plane[0].BytesPerElement); + + assert(result.width == layout.Plane[0].MipLayout[level].WidthElements); + assert(result.height == layout.Plane[0].MipLayout[level].HeightElements); + + return DetileByElement3D(xbox, level, slices, computer, layout, result, bpp, result.width, result.height, false); + } + else + { + //--- Standard format handling ------------------------------------------------ + auto& mip = layout.Plane[0].MipLayout[level]; + + const UINT32 tiledPixels = mip.PaddedWidthElements * mip.PaddedHeightElements * mip.PaddedDepthOrArraySize; + assert(tiledPixels >= (result.width * result.height * slices)); + + auto scanline = make_AlignedArrayXMVECTOR(tiledPixels + result.width); + + XMVECTOR* target = scanline.get(); + XMVECTOR* tiled = target + result.width; + + #ifdef _DEBUG + memset(target, 0xCD, sizeof(XMVECTOR) * result.width); + memset(tiled, 0xDD, sizeof(XMVECTOR) * tiledPixels); + #endif + + // Load tiled texture + if ((xbox.GetSize() - mip.OffsetBytes) < mip.SizeBytes) + return E_FAIL; + + const uint8_t* sptr = xbox.GetPointer() + mip.OffsetBytes; + const uint8_t* endPtr = sptr + mip.SizeBytes; + XMVECTOR* tptr = tiled; + for (uint32_t z = 0; z < mip.PaddedDepthOrArraySize; ++z) + { + const uint8_t* rptr = sptr; + XMVECTOR* uptr = tptr; + + for (uint32_t y = 0; y < mip.PaddedHeightElements; ++y) + { + if ((rptr + mip.PitchBytes) > endPtr) + return E_FAIL; + + if (!LoadScanline(uptr, mip.PitchPixels, rptr, mip.PitchBytes, xbox.GetMetadata().format)) + return E_FAIL; + + rptr += mip.PitchBytes; + uptr += mip.PaddedWidthElements; + } + + sptr += mip.Slice2DSizeBytes; + tptr += size_t(mip.PaddedHeightElements) * size_t(mip.PaddedWidthElements); + } + + // Perform detiling + uint8_t* dptr = reinterpret_cast(result.pixels); + for (uint32_t z = 0; z < slices; ++z) + { + uint8_t* rptr = dptr; + + for (uint32_t y = 0; y < result.height; ++y) + { + for (size_t x = 0; x < result.width; ++x) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, y, z, 0, nullptr); + #else + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, y, z, 0); + #endif + if (offset == size_t(-1)) + return E_FAIL; + + assert(offset >= mip.OffsetBytes); + assert(offset < mip.OffsetBytes + mip.SizeBytes); + + offset = (offset - mip.OffsetBytes) / layout.Plane[0].BytesPerElement; + assert(offset < tiledPixels); + + target[x] = tiled[offset]; + } + + if (!StoreScanline(rptr, result.rowPitch, result.format, target, result.width)) + return E_FAIL; + + rptr += result.rowPitch; + } + + dptr += result.slicePitch; + } + } + + return S_OK; + } +} + +//===================================================================================== +// Entry-points +//===================================================================================== + +//------------------------------------------------------------------------------------- +// Detile image +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT Xbox::Detile( + const XboxImage& xbox, + DirectX::ScratchImage& image) +{ + if (!xbox.GetSize() || !xbox.GetPointer() || xbox.GetTileMode() == c_XboxTileModeInvalid) + return E_INVALIDARG; + + image.Release(); + + auto& metadata = xbox.GetMetadata(); + + if (metadata.format == DXGI_FORMAT_R1_UNORM + || IsVideo(metadata.format)) + { + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + } + + switch (metadata.format) + { + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + + default: + break; + } + + XG_RESOURCE_LAYOUT layout = {}; + + switch (metadata.dimension) + { + case TEX_DIMENSION_TEXTURE1D: + { + XG_TEXTURE1D_DESC desc = {}; + desc.Width = static_cast(metadata.width); + desc.MipLevels = static_cast(metadata.mipLevels); + desc.ArraySize = static_cast(metadata.arraySize); + desc.Format = static_cast(metadata.format); + desc.Usage = XG_USAGE_DEFAULT; + desc.BindFlags = XG_BIND_SHADER_RESOURCE; + desc.MiscFlags = (metadata.IsCubemap()) ? XG_RESOURCE_MISC_TEXTURECUBE : 0; + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + desc.SwizzleMode = xbox.GetTileMode(); + #else + desc.TileMode = xbox.GetTileMode(); + #endif + + ComPtr computer; + HRESULT hr = XGCreateTexture1DComputer(&desc, computer.GetAddressOf()); + if (FAILED(hr)) + return hr; + + hr = computer->GetResourceLayout(&layout); + if (FAILED(hr)) + return hr; + + if (layout.Planes != 1) + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + + if (layout.SizeBytes != xbox.GetSize() + || layout.BaseAlignmentBytes != xbox.GetAlignment()) + return E_UNEXPECTED; + + hr = image.Initialize(metadata); + if (FAILED(hr)) + return hr; + + for (uint32_t level = 0; level < metadata.mipLevels; ++level) + { + if (metadata.arraySize > 1) + { + std::vector images; + images.reserve(metadata.arraySize); + for (uint32_t item = 0; item < metadata.arraySize; ++item) + { + const Image* img = image.GetImage(level, item, 0); + if (!img) + { + image.Release(); + return E_FAIL; + } + + images.push_back(img); + } + + hr = Detile1D(xbox, level, computer.Get(), layout, &images[0], images.size()); + } + else + { + const Image* img = image.GetImage(level, 0, 0); + if (!img) + { + image.Release(); + return E_FAIL; + } + + hr = Detile1D(xbox, level, computer.Get(), layout, &img, 1); + } + + if (FAILED(hr)) + { + image.Release(); + return hr; + } + } + } + break; + + case TEX_DIMENSION_TEXTURE2D: + { + XG_TEXTURE2D_DESC desc = {}; + desc.Width = static_cast(metadata.width); + desc.Height = static_cast(metadata.height); + desc.MipLevels = static_cast(metadata.mipLevels); + desc.ArraySize = static_cast(metadata.arraySize); + desc.Format = static_cast(metadata.format); + desc.SampleDesc.Count = 1; + desc.Usage = XG_USAGE_DEFAULT; + desc.BindFlags = XG_BIND_SHADER_RESOURCE; + desc.MiscFlags = (metadata.miscFlags & TEX_MISC_TEXTURECUBE) ? XG_RESOURCE_MISC_TEXTURECUBE : 0; + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + desc.SwizzleMode = xbox.GetTileMode(); + #else + desc.TileMode = xbox.GetTileMode(); + #endif + + ComPtr computer; + HRESULT hr = XGCreateTexture2DComputer(&desc, computer.GetAddressOf()); + if (FAILED(hr)) + return hr; + + hr = computer->GetResourceLayout(&layout); + if (FAILED(hr)) + return hr; + + if (layout.Planes != 1) + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + + if (layout.SizeBytes != xbox.GetSize() + || layout.BaseAlignmentBytes != xbox.GetAlignment()) + return E_UNEXPECTED; + + hr = image.Initialize(metadata); + if (FAILED(hr)) + return hr; + + for (uint32_t level = 0; level < metadata.mipLevels; ++level) + { + if (metadata.arraySize > 1) + { + std::vector images; + images.reserve(metadata.arraySize); + for (uint32_t item = 0; item < metadata.arraySize; ++item) + { + const Image* img = image.GetImage(level, item, 0); + if (!img) + { + image.Release(); + return E_FAIL; + } + + images.push_back(img); + } + + hr = Detile2D(xbox, level, computer.Get(), layout, &images[0], images.size()); + } + else + { + const Image* img = image.GetImage(level, 0, 0); + if (!img) + { + image.Release(); + return E_FAIL; + } + + hr = Detile2D(xbox, level, computer.Get(), layout, &img, 1); + } + + if (FAILED(hr)) + { + image.Release(); + return hr; + } + } + } + break; + + case TEX_DIMENSION_TEXTURE3D: + { + XG_TEXTURE3D_DESC desc = {}; + desc.Width = static_cast(metadata.width); + desc.Height = static_cast(metadata.height); + desc.Depth = static_cast(metadata.depth); + desc.MipLevels = static_cast(metadata.mipLevels); + desc.Format = static_cast(metadata.format); + desc.Usage = XG_USAGE_DEFAULT; + desc.BindFlags = XG_BIND_SHADER_RESOURCE; + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + desc.SwizzleMode = xbox.GetTileMode(); + #else + desc.TileMode = xbox.GetTileMode(); + #endif + + ComPtr computer; + HRESULT hr = XGCreateTexture3DComputer(&desc, computer.GetAddressOf()); + if (FAILED(hr)) + return hr; + + hr = computer->GetResourceLayout(&layout); + if (FAILED(hr)) + return hr; + + if (layout.Planes != 1) + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + + if (layout.SizeBytes != xbox.GetSize() + || layout.BaseAlignmentBytes != xbox.GetAlignment()) + return E_UNEXPECTED; + + hr = image.Initialize(metadata); + if (FAILED(hr)) + return hr; + + uint32_t d = static_cast(metadata.depth); + + size_t index = 0; + for (uint32_t level = 0; level < metadata.mipLevels; ++level) + { + if ((index + d) > image.GetImageCount()) + { + image.Release(); + return E_FAIL; + } + + // Relies on the fact that slices are contiguous + hr = Detile3D(xbox, level, d, computer.Get(), layout, image.GetImages()[index]); + if (FAILED(hr)) + { + image.Release(); + return hr; + } + + index += d; + + if (d > 1) + d >>= 1; + } + } + break; + + default: + return E_FAIL; + } + + return S_OK; +} diff --git a/Auxiliary/DirectXTexXboxImage.cpp b/Auxiliary/DirectXTexXboxImage.cpp new file mode 100644 index 0000000..05b05be --- /dev/null +++ b/Auxiliary/DirectXTexXboxImage.cpp @@ -0,0 +1,319 @@ +//-------------------------------------------------------------------------------------- +// File: DirectXTexXboxImage.cpp +// +// DirectXTex Auxillary functions for Xbox texture blob +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +//-------------------------------------------------------------------------------------- + +#include "DirectXTexP.h" +#include "DirectXTexXbox.h" + +using namespace DirectX; +using namespace Xbox; + +// Sanity check XG library values against DirectXTex's values +static_assert(static_cast(XG_FORMAT_UNKNOWN) == static_cast(DXGI_FORMAT_UNKNOWN), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G32B32A32_TYPELESS) == static_cast(DXGI_FORMAT_R32G32B32A32_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G32B32A32_FLOAT) == static_cast(DXGI_FORMAT_R32G32B32A32_FLOAT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G32B32A32_UINT) == static_cast(DXGI_FORMAT_R32G32B32A32_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G32B32A32_SINT) == static_cast(DXGI_FORMAT_R32G32B32A32_SINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G32B32_TYPELESS) == static_cast(DXGI_FORMAT_R32G32B32_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G32B32_FLOAT) == static_cast(DXGI_FORMAT_R32G32B32_FLOAT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G32B32_UINT) == static_cast(DXGI_FORMAT_R32G32B32_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G32B32_SINT) == static_cast(DXGI_FORMAT_R32G32B32_SINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16G16B16A16_TYPELESS) == static_cast(DXGI_FORMAT_R16G16B16A16_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16G16B16A16_FLOAT) == static_cast(DXGI_FORMAT_R16G16B16A16_FLOAT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16G16B16A16_UNORM) == static_cast(DXGI_FORMAT_R16G16B16A16_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16G16B16A16_UINT) == static_cast(DXGI_FORMAT_R16G16B16A16_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16G16B16A16_SNORM) == static_cast(DXGI_FORMAT_R16G16B16A16_SNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16G16B16A16_SINT) == static_cast(DXGI_FORMAT_R16G16B16A16_SINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G32_TYPELESS) == static_cast(DXGI_FORMAT_R32G32_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G32_FLOAT) == static_cast(DXGI_FORMAT_R32G32_FLOAT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G32_UINT) == static_cast(DXGI_FORMAT_R32G32_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G32_SINT) == static_cast(DXGI_FORMAT_R32G32_SINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32G8X24_TYPELESS) == static_cast(DXGI_FORMAT_R32G8X24_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_D32_FLOAT_S8X24_UINT) == static_cast(DXGI_FORMAT_D32_FLOAT_S8X24_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32_FLOAT_X8X24_TYPELESS) == static_cast(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_X32_TYPELESS_G8X24_UINT) == static_cast(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R10G10B10A2_TYPELESS) == static_cast(DXGI_FORMAT_R10G10B10A2_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R10G10B10A2_UNORM) == static_cast(DXGI_FORMAT_R10G10B10A2_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R10G10B10A2_UINT) == static_cast(DXGI_FORMAT_R10G10B10A2_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R11G11B10_FLOAT) == static_cast(DXGI_FORMAT_R11G11B10_FLOAT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8G8B8A8_TYPELESS) == static_cast(DXGI_FORMAT_R8G8B8A8_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8G8B8A8_UNORM) == static_cast(DXGI_FORMAT_R8G8B8A8_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8G8B8A8_UNORM_SRGB) == static_cast(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8G8B8A8_UINT) == static_cast(DXGI_FORMAT_R8G8B8A8_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8G8B8A8_SNORM) == static_cast(DXGI_FORMAT_R8G8B8A8_SNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8G8B8A8_SINT) == static_cast(DXGI_FORMAT_R8G8B8A8_SINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16G16_TYPELESS) == static_cast(DXGI_FORMAT_R16G16_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16G16_FLOAT) == static_cast(DXGI_FORMAT_R16G16_FLOAT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16G16_UNORM) == static_cast(DXGI_FORMAT_R16G16_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16G16_UINT) == static_cast(DXGI_FORMAT_R16G16_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16G16_SNORM) == static_cast(DXGI_FORMAT_R16G16_SNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16G16_SINT) == static_cast(DXGI_FORMAT_R16G16_SINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32_TYPELESS) == static_cast(DXGI_FORMAT_R32_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_D32_FLOAT) == static_cast(DXGI_FORMAT_D32_FLOAT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32_FLOAT) == static_cast(DXGI_FORMAT_R32_FLOAT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32_UINT) == static_cast(DXGI_FORMAT_R32_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R32_SINT) == static_cast(DXGI_FORMAT_R32_SINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R24G8_TYPELESS) == static_cast(DXGI_FORMAT_R24G8_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_D24_UNORM_S8_UINT) == static_cast(DXGI_FORMAT_D24_UNORM_S8_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R24_UNORM_X8_TYPELESS) == static_cast(DXGI_FORMAT_R24_UNORM_X8_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_X24_TYPELESS_G8_UINT) == static_cast(DXGI_FORMAT_X24_TYPELESS_G8_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8G8_TYPELESS) == static_cast(DXGI_FORMAT_R8G8_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8G8_UNORM) == static_cast(DXGI_FORMAT_R8G8_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8G8_UINT) == static_cast(DXGI_FORMAT_R8G8_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8G8_SNORM) == static_cast(DXGI_FORMAT_R8G8_SNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8G8_SINT) == static_cast(DXGI_FORMAT_R8G8_SINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16_TYPELESS) == static_cast(DXGI_FORMAT_R16_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16_FLOAT) == static_cast(DXGI_FORMAT_R16_FLOAT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_D16_UNORM) == static_cast(DXGI_FORMAT_D16_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16_UNORM) == static_cast(DXGI_FORMAT_R16_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16_UINT) == static_cast(DXGI_FORMAT_R16_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16_SNORM) == static_cast(DXGI_FORMAT_R16_SNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R16_SINT) == static_cast(DXGI_FORMAT_R16_SINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8_TYPELESS) == static_cast(DXGI_FORMAT_R8_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8_UNORM) == static_cast(DXGI_FORMAT_R8_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8_UINT) == static_cast(DXGI_FORMAT_R8_UINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8_SNORM) == static_cast(DXGI_FORMAT_R8_SNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8_SINT) == static_cast(DXGI_FORMAT_R8_SINT), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_A8_UNORM) == static_cast(DXGI_FORMAT_A8_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R1_UNORM) == static_cast(DXGI_FORMAT_R1_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R9G9B9E5_SHAREDEXP) == static_cast(DXGI_FORMAT_R9G9B9E5_SHAREDEXP), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R8G8_B8G8_UNORM) == static_cast(DXGI_FORMAT_R8G8_B8G8_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_G8R8_G8B8_UNORM) == static_cast(DXGI_FORMAT_G8R8_G8B8_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC1_TYPELESS) == static_cast(DXGI_FORMAT_BC1_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC1_UNORM) == static_cast(DXGI_FORMAT_BC1_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC1_UNORM_SRGB) == static_cast(DXGI_FORMAT_BC1_UNORM_SRGB), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC2_TYPELESS) == static_cast(DXGI_FORMAT_BC2_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC2_UNORM) == static_cast(DXGI_FORMAT_BC2_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC2_UNORM_SRGB) == static_cast(DXGI_FORMAT_BC2_UNORM_SRGB), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC3_TYPELESS) == static_cast(DXGI_FORMAT_BC3_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC3_UNORM) == static_cast(DXGI_FORMAT_BC3_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC3_UNORM_SRGB) == static_cast(DXGI_FORMAT_BC3_UNORM_SRGB), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC4_TYPELESS) == static_cast(DXGI_FORMAT_BC4_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC4_UNORM) == static_cast(DXGI_FORMAT_BC4_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC4_SNORM) == static_cast(DXGI_FORMAT_BC4_SNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC5_TYPELESS) == static_cast(DXGI_FORMAT_BC5_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC5_UNORM) == static_cast(DXGI_FORMAT_BC5_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC5_SNORM) == static_cast(DXGI_FORMAT_BC5_SNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_B5G6R5_UNORM) == static_cast(DXGI_FORMAT_B5G6R5_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_B5G5R5A1_UNORM) == static_cast(DXGI_FORMAT_B5G5R5A1_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_B8G8R8A8_UNORM) == static_cast(DXGI_FORMAT_B8G8R8A8_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_B8G8R8X8_UNORM) == static_cast(DXGI_FORMAT_B8G8R8X8_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_R10G10B10_XR_BIAS_A2_UNORM) == static_cast(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_B8G8R8A8_TYPELESS) == static_cast(DXGI_FORMAT_B8G8R8A8_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_B8G8R8A8_UNORM_SRGB) == static_cast(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_B8G8R8X8_TYPELESS) == static_cast(DXGI_FORMAT_B8G8R8X8_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_B8G8R8X8_UNORM_SRGB) == static_cast(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC6H_TYPELESS) == static_cast(DXGI_FORMAT_BC6H_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC6H_UF16) == static_cast(DXGI_FORMAT_BC6H_UF16), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC6H_SF16) == static_cast(DXGI_FORMAT_BC6H_SF16), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC7_TYPELESS) == static_cast(DXGI_FORMAT_BC7_TYPELESS), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC7_UNORM) == static_cast(DXGI_FORMAT_BC7_UNORM), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_BC7_UNORM_SRGB) == static_cast(DXGI_FORMAT_BC7_UNORM_SRGB), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_AYUV) == static_cast(DXGI_FORMAT_AYUV), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_Y410) == static_cast(DXGI_FORMAT_Y410), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_Y416) == static_cast(DXGI_FORMAT_Y416), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_NV12) == static_cast(DXGI_FORMAT_NV12), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_P010) == static_cast(DXGI_FORMAT_P010), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_P016) == static_cast(DXGI_FORMAT_P016), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_420_OPAQUE) == static_cast(DXGI_FORMAT_420_OPAQUE), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_YUY2) == static_cast(DXGI_FORMAT_YUY2), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_Y210) == static_cast(DXGI_FORMAT_Y210), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_Y216) == static_cast(DXGI_FORMAT_Y216), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_NV11) == static_cast(DXGI_FORMAT_NV11), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_AI44) == static_cast(DXGI_FORMAT_AI44), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_IA44) == static_cast(DXGI_FORMAT_IA44), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_P8) == static_cast(DXGI_FORMAT_P8), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_A8P8) == static_cast(DXGI_FORMAT_A8P8), "XG vs. DXGI mismatch"); +static_assert(static_cast(XG_FORMAT_B4G4R4A4_UNORM) == static_cast(DXGI_FORMAT_B4G4R4A4_UNORM), "XG vs. DXGI mismatch"); + +static_assert(static_cast(XG_RESOURCE_DIMENSION_TEXTURE1D) == static_cast(TEX_DIMENSION_TEXTURE1D), "XG vs. Direct3D 11 mismatch"); +static_assert(static_cast(XG_RESOURCE_DIMENSION_TEXTURE2D) == static_cast(TEX_DIMENSION_TEXTURE2D), "XG vs. Direct3D 11 mismatch"); +static_assert(static_cast(XG_RESOURCE_DIMENSION_TEXTURE3D) == static_cast(TEX_DIMENSION_TEXTURE3D), "XG vs. Direct3D 11 mismatch"); + +static_assert(static_cast(XG_RESOURCE_MISC_TEXTURECUBE) == static_cast(TEX_MISC_TEXTURECUBE), "XG vs. Direct3D 11 mismatch"); + +//-------------------------------------------------------------------------------------- +// Initialize memory +//-------------------------------------------------------------------------------------- + +XboxImage& XboxImage::operator= (XboxImage&& moveFrom) noexcept +{ + if (this != &moveFrom) + { + Release(); + + dataSize = moveFrom.dataSize; + baseAlignment = moveFrom.baseAlignment; + tilemode = moveFrom.tilemode; + metadata = moveFrom.metadata; + memory = moveFrom.memory; + + moveFrom.dataSize = 0; + moveFrom.baseAlignment = 0; + moveFrom.tilemode = c_XboxTileModeInvalid; + moveFrom.memory = nullptr; + } + return *this; +} + +_Use_decl_annotations_ +HRESULT XboxImage::Initialize(const XG_TEXTURE1D_DESC& desc, const XG_RESOURCE_LAYOUT& layout, uint32_t miscFlags2) +{ + if (!layout.SizeBytes || !layout.BaseAlignmentBytes) + return E_INVALIDARG; + + Release(); + + if (layout.SizeBytes > UINT32_MAX + || layout.BaseAlignmentBytes > UINT32_MAX) + return E_FAIL; + + memory = reinterpret_cast(_aligned_malloc(layout.SizeBytes, 16)); + if (!memory) + return E_OUTOFMEMORY; + + memset(memory, 0, layout.SizeBytes); + + memset(&metadata, 0, sizeof(metadata)); + metadata.width = desc.Width; + metadata.height = 1; + metadata.depth = 1; + metadata.arraySize = desc.ArraySize; + metadata.mipLevels = layout.MipLevels; + metadata.format = static_cast(desc.Format); + metadata.dimension = TEX_DIMENSION_TEXTURE1D; + metadata.miscFlags2 = miscFlags2; + + dataSize = static_cast(layout.SizeBytes); + baseAlignment = static_cast(layout.BaseAlignmentBytes); +#if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + tilemode = desc.SwizzleMode; +#else + tilemode = desc.TileMode; +#endif + + return S_OK; +} + + +_Use_decl_annotations_ +HRESULT XboxImage::Initialize(const XG_TEXTURE2D_DESC& desc, const XG_RESOURCE_LAYOUT& layout, uint32_t miscFlags2) +{ + if (!layout.SizeBytes || !layout.BaseAlignmentBytes) + return E_INVALIDARG; + + Release(); + + if (layout.SizeBytes > UINT32_MAX + || layout.BaseAlignmentBytes > UINT32_MAX) + return E_FAIL; + + memory = reinterpret_cast(_aligned_malloc(layout.SizeBytes, 16)); + if (!memory) + return E_OUTOFMEMORY; + + memset(memory, 0, layout.SizeBytes); + + memset(&metadata, 0, sizeof(metadata)); + metadata.width = desc.Width; + metadata.height = desc.Height; + metadata.depth = 1; + metadata.arraySize = desc.ArraySize; + metadata.mipLevels = layout.MipLevels; + metadata.miscFlags = (desc.MiscFlags & XG_RESOURCE_MISC_TEXTURECUBE) ? TEX_MISC_TEXTURECUBE : 0; + metadata.format = static_cast(desc.Format); + metadata.dimension = TEX_DIMENSION_TEXTURE2D; + metadata.miscFlags2 = miscFlags2; + + dataSize = static_cast(layout.SizeBytes); + baseAlignment = static_cast(layout.BaseAlignmentBytes); +#if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + tilemode = desc.SwizzleMode; +#else + tilemode = desc.TileMode; +#endif + + return S_OK; +} + + +_Use_decl_annotations_ +HRESULT XboxImage::Initialize(const XG_TEXTURE3D_DESC& desc, const XG_RESOURCE_LAYOUT& layout, uint32_t miscFlags2) +{ + if (!layout.SizeBytes || !layout.BaseAlignmentBytes) + return E_INVALIDARG; + + Release(); + + if (layout.SizeBytes > UINT32_MAX + || layout.BaseAlignmentBytes > UINT32_MAX) + return E_FAIL; + + memory = reinterpret_cast(_aligned_malloc(layout.SizeBytes, 16)); + if (!memory) + return E_OUTOFMEMORY; + + memset(memory, 0, layout.SizeBytes); + + memset(&metadata, 0, sizeof(metadata)); + metadata.width = desc.Width; + metadata.height = desc.Height; + metadata.depth = desc.Depth; + metadata.arraySize = 1; + metadata.mipLevels = layout.MipLevels; + metadata.format = static_cast(desc.Format); + metadata.dimension = TEX_DIMENSION_TEXTURE3D; + metadata.miscFlags2 = miscFlags2; + + dataSize = static_cast(layout.SizeBytes); + baseAlignment = static_cast(layout.BaseAlignmentBytes); +#if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + tilemode = desc.SwizzleMode; +#else + tilemode = desc.TileMode; +#endif + + return S_OK; +} + + +_Use_decl_annotations_ +HRESULT XboxImage::Initialize(const DirectX::TexMetadata& mdata, XboxTileMode tm, uint32_t size, uint32_t alignment) +{ + if (!size || !alignment || tm == c_XboxTileModeInvalid) + return E_INVALIDARG; + + Release(); + + memory = reinterpret_cast(_aligned_malloc(size, 16)); + if (!memory) + return E_OUTOFMEMORY; + + memset(memory, 0, size); + + metadata = mdata; + + dataSize = size; + baseAlignment = alignment; + tilemode = tm; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Release memory +//-------------------------------------------------------------------------------------- +void XboxImage::Release() +{ + if (memory) + { + _aligned_free(memory); + memory = nullptr; + } +} diff --git a/Auxiliary/DirectXTexXboxTile.cpp b/Auxiliary/DirectXTexXboxTile.cpp new file mode 100644 index 0000000..421463a --- /dev/null +++ b/Auxiliary/DirectXTexXboxTile.cpp @@ -0,0 +1,1078 @@ +//-------------------------------------------------------------------------------------- +// File: DirectXTexXboxTile.cpp +// +// DirectXTex Auxillary functions for converting from linear to Xbox tiling +// +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +//-------------------------------------------------------------------------------------- + +#include "DirectXTexP.h" +#include "DirectXTexXbox.h" + +//#define VERBOSE + +using Microsoft::WRL::ComPtr; +using namespace DirectX; +using namespace DirectX::Internal; +using namespace Xbox; + +namespace +{ + //---------------------------------------------------------------------------------- + inline HRESULT TileByElement1D( + _In_reads_(nimages) const Image* const * images, + size_t nimages, + uint32_t level, + _In_ XGTextureAddressComputer* computer, + _In_ const XG_RESOURCE_LAYOUT& layout, + const XboxImage& xbox, + size_t bpp, + size_t w, + bool packed) + { + uint8_t* dptr = xbox.GetPointer(); + const uint8_t* endPtr = dptr + layout.SizeBytes; + + for (uint32_t item = 0; item < nimages; ++item) + { + const Image* img = images[item]; + + if (!img || !img->pixels) + return E_POINTER; + + assert(img->width == images[0]->width); + assert(img->height == images[0]->height); + assert(img->rowPitch == images[0]->rowPitch); + assert(img->format == images[0]->format); + + const uint8_t* sptr = img->pixels; + + for (size_t x = 0; x < w; ++x) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + UINT64 element = (packed) ? (x >> 1) : x; + size_t offset = computer->GetTexelElementOffsetBytes(0, level, element, 0, item, 0, nullptr); + #else + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, 0, item, 0); + #endif + if (offset == size_t(-1)) + return E_FAIL; + + uint8_t* dest = dptr + offset; + + if ((dest + bpp) > endPtr) + return E_FAIL; + + memcpy(dest, sptr, bpp); + sptr += bpp; + + if (packed) + ++x; + } + } + + return S_OK; + } + + //---------------------------------------------------------------------------------- + inline HRESULT TileByElement2D( + _In_reads_(nimages) const Image* const * images, + size_t nimages, + uint32_t level, + _In_ XGTextureAddressComputer* computer, + const XG_RESOURCE_LAYOUT& layout, + const XboxImage& xbox, + size_t bpp, + size_t w, + size_t h, + bool packed) + { + uint8_t* dptr = xbox.GetPointer(); + const uint8_t* endPtr = dptr + layout.SizeBytes; + + for (uint32_t item = 0; item < nimages; ++item) + { + const Image* img = images[item]; + + if (!img || !img->pixels) + return E_POINTER; + + assert(img->width == images[0]->width); + assert(img->height == images[0]->height); + assert(img->rowPitch == images[0]->rowPitch); + assert(img->format == images[0]->format); + + const uint8_t* sptr = img->pixels; + for (uint32_t y = 0; y < h; ++y) + { + const uint8_t* tptr = sptr; + + for (size_t x = 0; x < w; ++x) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + UINT64 element = (packed) ? (x >> 1) : x; + size_t offset = computer->GetTexelElementOffsetBytes(0, level, element, y, item, 0, nullptr); + #else + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, y, item, 0); + #endif + if (offset == size_t(-1)) + return E_FAIL; + + uint8_t* dest = dptr + offset; + + if ((dest + bpp) > endPtr) + return E_FAIL; + + memcpy(dest, tptr, bpp); + tptr += bpp; + + if (packed) + ++x; + } + + sptr += img->rowPitch; + } + } + + return S_OK; + } + + //---------------------------------------------------------------------------------- + inline HRESULT TileByElement3D( + const Image& image, + uint32_t level, + uint32_t slices, + _In_ XGTextureAddressComputer* computer, + const XG_RESOURCE_LAYOUT& layout, + const XboxImage& xbox, + size_t bpp, + size_t w, + size_t h, + bool packed) + { + uint8_t* dptr = xbox.GetPointer(); + const uint8_t* endPtr = dptr + layout.SizeBytes; + + const uint8_t* sptr = image.pixels; + for (uint32_t z = 0; z < slices; ++z) + { + const uint8_t* rptr = sptr; + + for (uint32_t y = 0; y < h; ++y) + { + const uint8_t* tptr = rptr; + + for (size_t x = 0; x < w; ++x) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + UINT64 element = (packed) ? (x >> 1) : x; + size_t offset = computer->GetTexelElementOffsetBytes(0, level, element, y, z, 0, nullptr); + #else + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, y, z, 0); + #endif + if (offset == size_t(-1)) + return E_FAIL; + + uint8_t* dest = dptr + offset; + + if ((dest + bpp) > endPtr) + return E_FAIL; + + memcpy(dest, tptr, bpp); + tptr += bpp; + + if (packed) + ++x; + } + + rptr += image.rowPitch; + } + + sptr += image.slicePitch; + } + + return S_OK; + } + + //---------------------------------------------------------------------------------- +#ifdef VERBOSE + void DebugPrintDesc(const XG_TEXTURE1D_DESC& desc) + { + wchar_t buff[2048] = {}; + swprintf_s(buff, L"XG_TEXTURE1D_DESC = { %u, %u, %u, %u, %u, %u, %u, %u, %u, %u }\n", + desc.Width, desc.MipLevels, desc.ArraySize, desc.Format, desc.Usage, desc.BindFlags, desc.CPUAccessFlags, desc.MiscFlags, + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + desc.SwizzleMode, + #else + desc.TileMode, + #endif + desc.Pitch); + OutputDebugStringW(buff); + } + + void DebugPrintDesc(const XG_TEXTURE2D_DESC& desc) + { + wchar_t buff[2048] = {}; + swprintf_s(buff, L"XG_TEXTURE2D_DESC = { %u, %u, %u, %u, %u, { %u, %u }, %u, %u, %u, %u, %u, %u }\n", + desc.Width, desc.Height, desc.MipLevels, desc.ArraySize, desc.Format, desc.SampleDesc.Count, desc.SampleDesc.Quality, desc.Usage, desc.BindFlags, desc.CPUAccessFlags, desc.MiscFlags, + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + desc.SwizzleMode, + #else + desc.TileMode, + #endif + desc.Pitch); + OutputDebugStringW(buff); + } + + void DebugPrintDesc(const XG_TEXTURE3D_DESC& desc) + { + wchar_t buff[2048] = {}; + swprintf_s(buff, L"XG_TEXTURE3D_DESC = { %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u }\n", + desc.Width, desc.Height, desc.Depth, desc.MipLevels, desc.Format, desc.Usage, desc.BindFlags, desc.CPUAccessFlags, desc.MiscFlags, + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + desc.SwizzleMode, + #else + desc.TileMode, + #endif + desc.Pitch); + OutputDebugStringW(buff); + } + + void DebugPrintLayout(const XG_RESOURCE_LAYOUT& layout) + { + wchar_t buff[2048] = {}; + + swprintf_s(buff, L"Layout %u planes, %uD, %u mips, %llu size, %llu alignment\n", layout.Planes, layout.Dimension - 1, layout.MipLevels, layout.SizeBytes, layout.BaseAlignmentBytes); + OutputDebugStringW(buff); + + for (size_t p = 0; p < layout.Planes; ++p) + { + auto& plane = layout.Plane[p]; + + swprintf_s(buff, L"Plane %zu: %u bpe, %llu size, %llu offset, %llu alignment\n", p, plane.BytesPerElement, plane.SizeBytes, plane.BaseOffsetBytes, plane.BaseAlignmentBytes); + OutputDebugStringW(buff); + + for (size_t level = 0; level < layout.MipLevels; ++level) + { + auto& mip = plane.MipLayout[level]; + + swprintf_s(buff, L"\tLevel %zu: %llu size, %llu slice2D, %llu offset, %u alignment\n", level, mip.SizeBytes, mip.Slice2DSizeBytes, mip.OffsetBytes, mip.AlignmentBytes); + OutputDebugStringW(buff); + + swprintf_s(buff, L"\t\t%u x %u x %u (padded %u x %u x %u)\n", mip.WidthElements, mip.HeightElements, mip.DepthOrArraySize, + mip.PaddedWidthElements, mip.PaddedHeightElements, mip.PaddedDepthOrArraySize); + OutputDebugStringW(buff); + + swprintf_s(buff, L"\t\tpitch %u pixels (%u bytes)\n", mip.PitchPixels, mip.PitchBytes); + OutputDebugStringW(buff); + + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + swprintf_s(buff, L"\t\t\t%u samples, %u swizzlemode\n", mip.SampleCount, mip.SwizzleMode); + #else + swprintf_s(buff, L"\t\t\t%u samples, %u tilemode\n", mip.SampleCount, mip.TileMode); + #endif + OutputDebugStringW(buff); + } + } + } +#endif + + //------------------------------------------------------------------------------------- + // 1D Tiling + //------------------------------------------------------------------------------------- + HRESULT Tile1D( + _In_reads_(nimages) const Image** images, + size_t nimages, + uint32_t level, + _In_ XGTextureAddressComputer* computer, + const XG_RESOURCE_LAYOUT& layout, + const XboxImage& xbox) + { + if (!nimages) + return E_INVALIDARG; + + if (!images || !images[0] || !computer || !xbox.GetPointer()) + return E_POINTER; + + assert(layout.Planes == 1); + + const DXGI_FORMAT format = images[0]->format; + + assert(format == xbox.GetMetadata().format); + + assert(!IsCompressed(format)); + + bool byelement = IsTypeless(format); + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + if (nimages > 1) + byelement = true; + #endif + + if (IsPacked(format)) + { + const size_t bpp = (BitsPerPixel(format) + 7) / 8; + + // XG (XboxOne) incorrectly returns 2 instead of 4 here for layout.Plane[0].BytesPerElement + + const size_t w = images[0]->width; + assert(((w + 1) / 2) == layout.Plane[0].MipLayout[level].WidthElements); + + return TileByElement1D(images, nimages, level, computer, layout, xbox, bpp, w, true); + } + else if (byelement) + { + //--- Typeless is done with per-element copy ---------------------------------- + const size_t bpp = (BitsPerPixel(format) + 7) / 8; + assert(bpp == layout.Plane[0].BytesPerElement); + + const size_t w = images[0]->width; + assert(w == layout.Plane[0].MipLayout[level].WidthElements); + + return TileByElement1D(images, nimages, level, computer, layout, xbox, bpp, w, false); + } + else + { + //--- Standard format handling ------------------------------------------------ + auto& mip = layout.Plane[0].MipLayout[level]; + + const UINT32 tiledPixels = mip.PitchPixels * mip.PaddedDepthOrArraySize; + + auto scanline = make_AlignedArrayXMVECTOR(images[0]->width + tiledPixels); + + XMVECTOR* row = scanline.get(); + XMVECTOR* tiled = row + images[0]->width; + + #ifdef _DEBUG + memset(row, 0xCD, sizeof(XMVECTOR) * images[0]->width); + #endif + + memset(tiled, 0, sizeof(XMVECTOR) * tiledPixels); + + // Perform tiling + for (uint32_t item = 0; item < nimages; ++item) + { + const Image* img = images[item]; + + if (!img || !img->pixels) + return E_POINTER; + + assert(img->width == images[0]->width); + assert(img->height == images[0]->height); + assert(img->rowPitch == images[0]->rowPitch); + assert(img->format == images[0]->format); + + if (!LoadScanline(row, img->width, img->pixels, img->rowPitch, img->format)) + return E_FAIL; + + for (size_t x = 0; x < img->width; ++x) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, 0, item, 0, nullptr); + #else + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, 0, item, 0); + #endif + if (offset == size_t(-1)) + return E_FAIL; + + assert(offset >= mip.OffsetBytes); + assert(offset < mip.OffsetBytes + mip.SizeBytes); + + offset = (offset - mip.OffsetBytes) / layout.Plane[0].BytesPerElement; + assert(offset < tiledPixels); + + tiled[offset] = row[x]; + } + } + + // Store tiled texture + assert(mip.OffsetBytes + mip.SizeBytes <= layout.SizeBytes); + if (!StoreScanline(xbox.GetPointer() + mip.OffsetBytes, mip.SizeBytes, xbox.GetMetadata().format, tiled, tiledPixels)) + return E_FAIL; + } + + return S_OK; + } + + + //------------------------------------------------------------------------------------- + // 2D Tiling + //------------------------------------------------------------------------------------- + HRESULT Tile2D( + _In_reads_(nimages) const Image** images, + size_t nimages, + uint32_t level, + _In_ XGTextureAddressComputer* computer, + const XG_RESOURCE_LAYOUT& layout, + const XboxImage& xbox) + { + if (!nimages) + return E_INVALIDARG; + + if (!images || !images[0] || !computer || !xbox.GetPointer()) + return E_POINTER; + + assert(layout.Planes == 1); + + const DXGI_FORMAT format = images[0]->format; + + assert(format == xbox.GetMetadata().format); + + bool byelement = IsTypeless(format); + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + if (nimages > 1) + byelement = true; + #endif + + if (IsCompressed(format)) + { + //--- BC formats use per-block copy ------------------------------------------- + const size_t nbw = std::max(1, (images[0]->width + 3) / 4); + const size_t nbh = std::max(1, (images[0]->height + 3) / 4); + + const size_t bpb = (format == DXGI_FORMAT_BC1_TYPELESS + || format == DXGI_FORMAT_BC1_UNORM + || format == DXGI_FORMAT_BC1_UNORM_SRGB + || format == DXGI_FORMAT_BC4_TYPELESS + || format == DXGI_FORMAT_BC4_UNORM + || format == DXGI_FORMAT_BC4_SNORM) ? 8 : 16; + + assert(nbw == layout.Plane[0].MipLayout[level].WidthElements); + assert(nbh == layout.Plane[0].MipLayout[level].HeightElements); + assert(bpb == layout.Plane[0].BytesPerElement); + + return TileByElement2D(images, nimages, level, computer, layout, xbox, bpb, nbw, nbh, false); + } + else if (IsPacked(format)) + { + const size_t bpp = (BitsPerPixel(format) + 7) / 8; + + // XG (XboxOne) incorrectly returns 2 instead of 4 here for layout.Plane[0].BytesPerElement + + const size_t w = images[0]->width; + const size_t h = images[0]->height; + assert(((w + 1) / 2) == layout.Plane[0].MipLayout[level].WidthElements); + assert(h == layout.Plane[0].MipLayout[level].HeightElements); + + return TileByElement2D(images, nimages, level, computer, layout, xbox, bpp, w, h, true); + } + else if (byelement) + { + //--- Typeless is done with per-element copy ---------------------------------- + const size_t bpp = (BitsPerPixel(format) + 7) / 8; + assert(bpp == layout.Plane[0].BytesPerElement); + + const size_t w = images[0]->width; + const size_t h = images[0]->height; + + assert(w == layout.Plane[0].MipLayout[level].WidthElements); + assert(h == layout.Plane[0].MipLayout[level].HeightElements); + + return TileByElement2D(images, nimages, level, computer, layout, xbox, bpp, w, h, false); + } + else + { + //--- Standard format handling ------------------------------------------------ + auto& mip = layout.Plane[0].MipLayout[level]; + + const UINT32 tiledPixels = mip.PaddedWidthElements * mip.PaddedHeightElements * mip.PaddedDepthOrArraySize; + + auto scanline = make_AlignedArrayXMVECTOR(images[0]->width + tiledPixels); + + XMVECTOR* row = scanline.get(); + XMVECTOR* tiled = row + images[0]->width; + + #ifdef _DEBUG + memset(row, 0xCD, sizeof(XMVECTOR) * images[0]->width); + #endif + + memset(tiled, 0, sizeof(XMVECTOR) * tiledPixels); + + // Perform tiling + for (uint32_t item = 0; item < nimages; ++item) + { + const Image* img = images[item]; + + if (!img || !img->pixels) + return E_POINTER; + + assert(img->width == images[0]->width); + assert(img->height == images[0]->height); + assert(img->rowPitch == images[0]->rowPitch); + assert(img->format == images[0]->format); + + auto sptr = reinterpret_cast(img->pixels); + for (uint32_t y = 0; y < img->height; ++y) + { + if (!LoadScanline(row, img->width, sptr, img->rowPitch, img->format)) + return E_FAIL; + + sptr += img->rowPitch; + + for (size_t x = 0; x < img->width; ++x) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, y, item, 0, nullptr); + #else + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, y, item, 0); + #endif + if (offset == size_t(-1)) + return E_FAIL; + + assert(offset >= mip.OffsetBytes); + assert(offset < mip.OffsetBytes + mip.SizeBytes); + + offset = (offset - mip.OffsetBytes) / layout.Plane[0].BytesPerElement; + assert(offset < tiledPixels); + + tiled[offset] = row[x]; + } + } + } + + // Store tiled texture + assert(mip.OffsetBytes + mip.SizeBytes <= layout.SizeBytes); + if (!StoreScanline(xbox.GetPointer() + mip.OffsetBytes, mip.SizeBytes, xbox.GetMetadata().format, tiled, tiledPixels)) + return E_FAIL; + } + + return S_OK; + } + + + //------------------------------------------------------------------------------------- + // 3D Tiling + //------------------------------------------------------------------------------------- + HRESULT Tile3D( + const Image& image, + uint32_t level, + uint32_t slices, + _In_ XGTextureAddressComputer* computer, + const XG_RESOURCE_LAYOUT& layout, + const XboxImage& xbox) + { + if (!image.pixels || !computer || !xbox.GetPointer()) + return E_POINTER; + + assert(slices > 0); + + assert(layout.Planes == 1); + + assert(image.format == xbox.GetMetadata().format); + + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + const bool byelement = true; + #else + const bool byelement = IsTypeless(image.format); + #endif + + if (IsCompressed(image.format)) + { + //--- BC formats use per-block copy ------------------------------------------- + const size_t nbw = std::max(1, (image.width + 3) / 4); + const size_t nbh = std::max(1, (image.height + 3) / 4); + + const size_t bpb = (image.format == DXGI_FORMAT_BC1_TYPELESS + || image.format == DXGI_FORMAT_BC1_UNORM + || image.format == DXGI_FORMAT_BC1_UNORM_SRGB + || image.format == DXGI_FORMAT_BC4_TYPELESS + || image.format == DXGI_FORMAT_BC4_UNORM + || image.format == DXGI_FORMAT_BC4_SNORM) ? 8 : 16; + + assert(nbw == layout.Plane[0].MipLayout[level].WidthElements); + assert(nbh == layout.Plane[0].MipLayout[level].HeightElements); + assert(bpb == layout.Plane[0].BytesPerElement); + + return TileByElement3D(image, level, slices, computer, layout, xbox, bpb, nbw, nbh, false); + } + else if (IsPacked(image.format)) + { + const size_t bpp = (BitsPerPixel(image.format) + 7) / 8; + + // XG (XboxOne) incorrectly returns 2 instead of 4 here for layout.Plane[0].BytesPerElement + + assert(((image.width + 1) / 2) == layout.Plane[0].MipLayout[level].WidthElements); + assert(image.height == layout.Plane[0].MipLayout[level].HeightElements); + + return TileByElement3D(image, level, slices, computer, layout, xbox, bpp, image.width, image.height, true); + } + else if (byelement) + { + //--- Typeless is done with per-element copy ---------------------------------- + const size_t bpp = (BitsPerPixel(image.format) + 7) / 8; + assert(bpp == layout.Plane[0].BytesPerElement); + + assert(image.width == layout.Plane[0].MipLayout[level].WidthElements); + assert(image.height == layout.Plane[0].MipLayout[level].HeightElements); + + return TileByElement3D(image, level, slices, computer, layout, xbox, bpp, image.width, image.height, false); + } + else + { + //--- Standard format handling ------------------------------------------------ + auto& mip = layout.Plane[0].MipLayout[level]; + + const UINT32 tiledPixels = mip.PaddedWidthElements * mip.PaddedHeightElements * mip.PaddedDepthOrArraySize; + assert(tiledPixels >= (image.width * image.height * slices)); + + auto scanline = make_AlignedArrayXMVECTOR(image.width + tiledPixels); + + XMVECTOR* row = scanline.get(); + XMVECTOR* tiled = row + image.width; + + #ifdef _DEBUG + memset(row, 0xCD, sizeof(XMVECTOR) * image.width); + #endif + + memset(tiled, 0, sizeof(XMVECTOR) * tiledPixels); + + // Perform tiling + const uint8_t* sptr = reinterpret_cast(image.pixels); + for (uint32_t z = 0; z < slices; ++z) + { + const uint8_t* rptr = sptr; + + for (uint32_t y = 0; y < image.height; ++y) + { + if (!LoadScanline(row, image.width, rptr, image.rowPitch, image.format)) + return E_FAIL; + + rptr += image.rowPitch; + + for (size_t x = 0; x < image.width; ++x) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, y, z, 0, nullptr); + #else + size_t offset = computer->GetTexelElementOffsetBytes(0, level, x, y, z, 0); + #endif + if (offset == size_t(-1)) + return E_FAIL; + + assert(offset >= mip.OffsetBytes); + assert(offset < mip.OffsetBytes + mip.SizeBytes); + + offset = (offset - mip.OffsetBytes) / layout.Plane[0].BytesPerElement; + assert(offset < tiledPixels); + + tiled[offset] = row[x]; + } + } + + sptr += image.slicePitch; + } + + // Store tiled texture + uint8_t* dptr = xbox.GetPointer() + mip.OffsetBytes; + const uint8_t* endPtr = dptr + mip.SizeBytes; + const XMVECTOR* tptr = tiled; + for (uint32_t z = 0; z < mip.PaddedDepthOrArraySize; ++z) + { + uint8_t* rptr = dptr; + const XMVECTOR* uptr = tptr; + + for (uint32_t y = 0; y < mip.PaddedHeightElements; ++y) + { + if ((rptr + mip.PitchBytes) > endPtr) + return E_FAIL; + + if (!StoreScanline(rptr, mip.PitchBytes, xbox.GetMetadata().format, uptr, mip.PitchPixels)) + return E_FAIL; + + rptr += mip.PitchBytes; + uptr += mip.PaddedWidthElements; + } + + dptr += mip.Slice2DSizeBytes; + tptr += size_t(mip.PaddedHeightElements) * size_t(mip.PaddedWidthElements); + } + } + + return S_OK; + } +} + + +//===================================================================================== +// Entry-points +//===================================================================================== + +//------------------------------------------------------------------------------------- +// Tile image +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT Xbox::Tile( + const DirectX::Image& srcImage, + XboxImage& xbox, + XboxTileMode mode) +{ + if (!srcImage.pixels + || srcImage.width > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION + || srcImage.height > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION) + return E_INVALIDARG; + + xbox.Release(); + + if (srcImage.format == DXGI_FORMAT_R1_UNORM + || IsVideo(srcImage.format)) + { + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + } + + if (mode == c_XboxTileModeInvalid) + { + // If no specific tile mode is given, assume the optimal default + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + mode = XGComputeOptimalSwizzleMode(XG_RESOURCE_DIMENSION_TEXTURE2D, static_cast(srcImage.format), + static_cast(srcImage.width), static_cast(srcImage.height), + 1, 1, XG_BIND_SHADER_RESOURCE); + #else + mode = XGComputeOptimalTileMode(XG_RESOURCE_DIMENSION_TEXTURE2D, static_cast(srcImage.format), + static_cast(srcImage.width), static_cast(srcImage.height), + 1, 1, XG_BIND_SHADER_RESOURCE); + #endif + } + + XG_TEXTURE2D_DESC desc = {}; + desc.Width = static_cast(srcImage.width); + desc.Height = static_cast(srcImage.height); + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = static_cast(srcImage.format); + desc.SampleDesc.Count = 1; + desc.Usage = XG_USAGE_DEFAULT; + desc.BindFlags = XG_BIND_SHADER_RESOURCE; +#if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + desc.SwizzleMode = mode; +#else + desc.TileMode = mode; +#endif + + ComPtr computer; + HRESULT hr = XGCreateTexture2DComputer(&desc, computer.GetAddressOf()); + if (FAILED(hr)) + return hr; + + XG_RESOURCE_LAYOUT layout; + hr = computer->GetResourceLayout(&layout); + if (FAILED(hr)) + return hr; + + if (layout.Planes != 1) + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + + hr = xbox.Initialize(desc, layout); + if (FAILED(hr)) + return hr; + + const Image* images = &srcImage; + hr = Tile2D(&images, 1, 0, computer.Get(), layout, xbox); + if (FAILED(hr)) + { + xbox.Release(); + return hr; + } + + return S_OK; +} + + +//------------------------------------------------------------------------------------- +// Tile image (complex) +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +HRESULT Xbox::Tile( + const DirectX::Image* srcImages, + size_t nimages, + const DirectX::TexMetadata& metadata, + XboxImage& xbox, + XboxTileMode mode) +{ + if (!srcImages + || !nimages + || metadata.width > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION + || metadata.height > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION + || metadata.depth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION + || metadata.arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION + || metadata.mipLevels > D3D11_REQ_MIP_LEVELS) + return E_INVALIDARG; + + xbox.Release(); + + if (metadata.format == DXGI_FORMAT_R1_UNORM + || IsVideo(metadata.format)) + { + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + } + + switch (metadata.format) + { + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + + default: + break; + } + + if (mode == c_XboxTileModeInvalid) + { + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + mode = XGComputeOptimalSwizzleMode(static_cast(metadata.dimension), static_cast(metadata.format), + static_cast(metadata.width), static_cast(metadata.height), + static_cast((metadata.dimension == TEX_DIMENSION_TEXTURE3D) ? metadata.depth : metadata.arraySize), + 1, XG_BIND_SHADER_RESOURCE); + #else + // If no specific tile mode is given, assume the optimal default + mode = XGComputeOptimalTileMode(static_cast(metadata.dimension), static_cast(metadata.format), + static_cast(metadata.width), static_cast(metadata.height), + static_cast((metadata.dimension == TEX_DIMENSION_TEXTURE3D) ? metadata.depth : metadata.arraySize), + 1, XG_BIND_SHADER_RESOURCE); + #endif + } + + XG_RESOURCE_LAYOUT layout = {}; + + switch (metadata.dimension) + { + case TEX_DIMENSION_TEXTURE1D: + { + XG_TEXTURE1D_DESC desc = {}; + desc.Width = static_cast(metadata.width); + desc.MipLevels = static_cast(metadata.mipLevels); + desc.ArraySize = static_cast(metadata.arraySize); + desc.Format = static_cast(metadata.format); + desc.Usage = XG_USAGE_DEFAULT; + desc.BindFlags = XG_BIND_SHADER_RESOURCE; + desc.MiscFlags = (metadata.IsCubemap()) ? XG_RESOURCE_MISC_TEXTURECUBE : 0; + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + desc.SwizzleMode = mode; + #else + desc.TileMode = mode; + #endif + + #ifdef VERBOSE + DebugPrintDesc(desc); + #endif + + ComPtr computer; + HRESULT hr = XGCreateTexture1DComputer(&desc, computer.GetAddressOf()); + if (FAILED(hr)) + return hr; + + hr = computer->GetResourceLayout(&layout); + if (FAILED(hr)) + return hr; + + #ifdef VERBOSE + DebugPrintLayout(layout); + #endif + + if (layout.Planes != 1) + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + + hr = xbox.Initialize(desc, layout, metadata.miscFlags2); + if (FAILED(hr)) + return hr; + + for (uint32_t level = 0; level < metadata.mipLevels; ++level) + { + if (metadata.arraySize > 1) + { + std::vector images; + images.reserve(metadata.arraySize); + for (uint32_t item = 0; item < metadata.arraySize; ++item) + { + const size_t index = metadata.ComputeIndex(level, item, 0); + if (index >= nimages) + { + xbox.Release(); + return E_FAIL; + } + + images.push_back(&srcImages[index]); + } + + hr = Tile1D(&images[0], images.size(), level, computer.Get(), layout, xbox); + } + else + { + const size_t index = metadata.ComputeIndex(level, 0, 0); + if (index >= nimages) + { + xbox.Release(); + return E_FAIL; + } + + const Image* images = &srcImages[index]; + hr = Tile1D(&images, 1, level, computer.Get(), layout, xbox); + } + + if (FAILED(hr)) + { + xbox.Release(); + return hr; + } + } + } + break; + + case TEX_DIMENSION_TEXTURE2D: + { + XG_TEXTURE2D_DESC desc = {}; + desc.Width = static_cast(metadata.width); + desc.Height = static_cast(metadata.height); + desc.MipLevels = static_cast(metadata.mipLevels); + desc.ArraySize = static_cast(metadata.arraySize); + desc.Format = static_cast(metadata.format); + desc.SampleDesc.Count = 1; + desc.Usage = XG_USAGE_DEFAULT; + desc.BindFlags = XG_BIND_SHADER_RESOURCE; + desc.MiscFlags = (metadata.miscFlags & TEX_MISC_TEXTURECUBE) ? XG_RESOURCE_MISC_TEXTURECUBE : 0; + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + desc.SwizzleMode = mode; + #else + desc.TileMode = mode; + #endif + + #ifdef VERBOSE + DebugPrintDesc(desc); + #endif + + ComPtr computer; + HRESULT hr = XGCreateTexture2DComputer(&desc, computer.GetAddressOf()); + if (FAILED(hr)) + return hr; + + hr = computer->GetResourceLayout(&layout); + if (FAILED(hr)) + return hr; + + #ifdef VERBOSE + DebugPrintLayout(layout); + #endif + + if (layout.Planes != 1) + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + + hr = xbox.Initialize(desc, layout, metadata.miscFlags2); + if (FAILED(hr)) + return hr; + + for (uint32_t level = 0; level < metadata.mipLevels; ++level) + { + if (metadata.arraySize > 1) + { + std::vector images; + images.reserve(metadata.arraySize); + for (uint32_t item = 0; item < metadata.arraySize; ++item) + { + const size_t index = metadata.ComputeIndex(level, item, 0); + if (index >= nimages) + { + xbox.Release(); + return E_FAIL; + } + + images.push_back(&srcImages[index]); + } + + hr = Tile2D(&images[0], images.size(), level, computer.Get(), layout, xbox); + } + else + { + const size_t index = metadata.ComputeIndex(level, 0, 0); + if (index >= nimages) + { + xbox.Release(); + return E_FAIL; + } + + const Image* images = &srcImages[index]; + hr = Tile2D(&images, 1, level, computer.Get(), layout, xbox); + } + + if (FAILED(hr)) + { + xbox.Release(); + return hr; + } + } + } + break; + + case TEX_DIMENSION_TEXTURE3D: + { + XG_TEXTURE3D_DESC desc = {}; + desc.Width = static_cast(metadata.width); + desc.Height = static_cast(metadata.height); + desc.Depth = static_cast(metadata.depth); + desc.MipLevels = static_cast(metadata.mipLevels); + desc.Format = static_cast(metadata.format); + desc.Usage = XG_USAGE_DEFAULT; + desc.BindFlags = XG_BIND_SHADER_RESOURCE; + #if defined(_GAMING_XBOX_SCARLETT) || defined(_USE_SCARLETT) + desc.SwizzleMode = mode; + #else + desc.TileMode = mode; + #endif + + #ifdef VERBOSE + DebugPrintDesc(desc); + #endif + + ComPtr computer; + HRESULT hr = XGCreateTexture3DComputer(&desc, computer.GetAddressOf()); + if (FAILED(hr)) + return hr; + + hr = computer->GetResourceLayout(&layout); + if (FAILED(hr)) + return hr; + + #ifdef VERBOSE + DebugPrintLayout(layout); + #endif + + if (layout.Planes != 1) + return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + + hr = xbox.Initialize(desc, layout, metadata.miscFlags2); + if (FAILED(hr)) + return hr; + + uint32_t d = static_cast(metadata.depth); + + size_t index = 0; + for (uint32_t level = 0; level < metadata.mipLevels; ++level) + { + if ((index + d) > nimages) + { + xbox.Release(); + return E_FAIL; + } + + // Relies on the fact that slices are contiguous + hr = Tile3D(srcImages[index], level, d, computer.Get(), layout, xbox); + if (FAILED(hr)) + { + xbox.Release(); + return hr; + } + + index += d; + + if (d > 1) + d >>= 1; + } + } + break; + + default: + return E_FAIL; + } + + return S_OK; +} diff --git a/CMakeLists.txt b/CMakeLists.txt index 99bbf36..07e7996 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,10 @@ option(BUILD_DX12 "Build with DirectX12 Runtime support" ON) # Enable the use of OpenMP for software BC6H/BC7 compression option(BC_USE_OPENMP "Build with OpenMP support" ON) +# Builds Xbox extensions for Host PC +option(BUILD_XBOX_EXTS_XBOXONE "Build Xbox library extensions for Xbox One" OFF) +option(BUILD_XBOX_EXTS_SCARLETT "Build Xbox library extensions for Xbox Series X|S" OFF) + # https://devblogs.microsoft.com/cppblog/spectre-mitigations-in-msvc/ option(ENABLE_SPECTRE_MITIGATION "Build using /Qspectre for MSVC" OFF) @@ -104,17 +108,52 @@ set(LIBRARY_SOURCES DirectXTex/DirectXTexUtil.cpp) if(WIN32) - set(LIBRARY_SOURCES ${LIBRARY_SOURCES} + list(APPEND LIBRARY_SOURCES DirectXTex/DirectXTexFlipRotate.cpp DirectXTex/DirectXTexWIC.cpp) endif() +if(DEFINED XBOX_CONSOLE_TARGET) + + list(APPEND LIBRARY_HEADERS Auxiliary/DirectXTexXbox.h) + + list(APPEND LIBRARY_SOURCES + Auxiliary/DirectXTexXboxDDS.cpp + Auxiliary/DirectXTexXboxDetile.cpp + Auxiliary/DirectXTexXboxImage.cpp + Auxiliary/DirectXTexXboxTile.cpp) + + if((XBOX_CONSOLE_TARGET STREQUAL "durango") AND BUILD_DX11) + list(APPEND LIBRARY_SOURCES Auxiliary/DirectXTexXboxD3D11X.cpp) + endif() + + if(BUILD_DX12) + list(APPEND LIBRARY_SOURCES Auxiliary/DirectXTexXboxD3D12X.cpp) + endif() + +elseif((BUILD_XBOX_EXTS_XBOXONE OR BUILD_XBOX_EXTS_SCARLETT) AND WIN32) + if(DEFINED ENV{GameDKLatest}) + cmake_path(SET GameDK_DIR "$ENV{GameDKLatest}") + endif() + if(DEFINED ENV{XboxOneXDKLatest}) + cmake_path(SET XboxOneXDK_DIR "$ENV{XboxOneXDKLatest}") + endif() + + list(APPEND LIBRARY_HEADERS Auxiliary/DirectXTexXbox.h) + + list(APPEND LIBRARY_SOURCES + Auxiliary/DirectXTexXboxDDS.cpp + Auxiliary/DirectXTexXboxDetile.cpp + Auxiliary/DirectXTexXboxImage.cpp + Auxiliary/DirectXTexXboxTile.cpp) +endif() + set(SHADER_SOURCES DirectXTex/Shaders/BC6HEncode.hlsl DirectXTex/Shaders/BC7Encode.hlsl) if(BUILD_DX11 AND WIN32) - set(LIBRARY_SOURCES ${LIBRARY_SOURCES} + list(APPEND LIBRARY_SOURCES DirectXTex/BCDirectCompute.h DirectXTex/BCDirectCompute.cpp DirectXTex/DirectXTexCompressGPU.cpp @@ -122,17 +161,16 @@ if(BUILD_DX11 AND WIN32) endif() if(BUILD_DX12) - set(LIBRARY_SOURCES ${LIBRARY_SOURCES} - DirectXTex/d3dx12.h - DirectXTex/DirectXTexD3D12.cpp) + list(APPEND LIBRARY_SOURCES DirectXTex/DirectXTexD3D12.cpp) + + if(NOT (DEFINED XBOX_CONSOLE_TARGET)) + list(APPEND LIBRARY_SOURCES DirectXTex/d3dx12.h) + endif() endif() if(ENABLE_OPENEXR_SUPPORT) - set(LIBRARY_HEADERS ${LIBRARY_HEADERS} - Auxiliary/DirectXTexEXR.h) - - set(LIBRARY_SOURCES ${LIBRARY_SOURCES} - Auxiliary/DirectXTexEXR.cpp) + list(APPEND LIBRARY_HEADERS Auxiliary/DirectXTexEXR.h) + list(APPEND LIBRARY_SOURCES Auxiliary/DirectXTexEXR.cpp) endif() if(BUILD_DX11 AND WIN32) @@ -146,8 +184,7 @@ if(BUILD_DX11 AND WIN32) file(TO_CMAKE_PATH ${COMPILED_SHADERS} COMPILED_SHADERS) endif() - set(LIBRARY_SOURCES ${LIBRARY_SOURCES} - ${COMPILED_SHADERS}/BC6HEncode_EncodeBlockCS.inc) + list(APPEND LIBRARY_SOURCES ${COMPILED_SHADERS}/BC6HEncode_EncodeBlockCS.inc) if(NOT USE_PREBUILT_SHADERS) add_custom_command( @@ -189,6 +226,27 @@ if(ENABLE_OPENEXR_SUPPORT) target_link_libraries(${PROJECT_NAME} PUBLIC OpenEXR::OpenEXR) endif() +if(BUILD_XBOX_EXTS_SCARLETT AND WIN32) + if (EXISTS "${GameDK_DIR}/GXDK/toolKit/include/gxdk.h") + message(STATUS "Building Xbox extensions for Xbox Series X|S") + target_compile_definitions(${PROJECT_NAME} PRIVATE _USE_GXDK _USE_SCARLETT) + target_include_directories(${PROJECT_NAME} PRIVATE ${GameDK_DIR}/GXDK/toolKit/include ${GameDK_DIR}/GXDK/toolKit/include/Scarlett) + else() + message(FATAL_ERROR "Building Xbox extensions requires GameDKLatest") + endif() +elseif(BUILD_XBOX_EXTS_XBOXONE AND WIN32) + if (EXISTS "${GameDK_DIR}/GXDK/toolKit/include/gxdk.h") + message(STATUS "Building Xbox extensions for XboxOne using the Microsoft GDK") + target_compile_definitions(${PROJECT_NAME} PRIVATE _USE_GXDK) + target_include_directories(${PROJECT_NAME} PRIVATE ${GameDK_DIR}/GXDK/toolKit/include ${GameDK_DIR}/GXDK/toolKit/include/XboxOne) + elseif (EXISTS "${XboxOneXDK_DIR}/PC/include/xdk.h") + message(STATUS "Building Xbox extensions for XboxOne using the Xbox One XDK") + target_include_directories(${PROJECT_NAME} PRIVATE ${XboxOneXDK_DIR}/PC/include) + else() + message(FATAL_ERROR "Building Xbox extensions requires GameDKLatest or XboxOneXDKLatest") + endif() +endif() + if(NOT MINGW) target_precompile_headers(${PROJECT_NAME} PRIVATE DirectXTex/DirectXTexP.h) endif() @@ -434,6 +492,19 @@ endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(WarningsLib -Wall -Wpedantic -Wextra) + + if((BUILD_XBOX_EXTS_XBOXONE OR BUILD_XBOX_EXTS_SCARLETT) AND WIN32) + list(APPEND WarningsLib "-Wno-microsoft-enum-value" "-Wno-non-virtual-dtor" "-Wno-ignored-pragmas" "-Wno-deprecated-dynamic-exception-spec") + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0) + list(APPEND WarningsLib "-Wno-reserved-identifier") + endif() + endif() + + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0) + list(APPEND WarningsLib "-Wno-unsafe-buffer-usage") + endif() + target_compile_options(${PROJECT_NAME} PRIVATE ${WarningsLib}) + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0) list(APPEND WarningsLib "-Wno-unsafe-buffer-usage") endif() @@ -470,6 +541,9 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") foreach(t IN LISTS TOOL_EXES ITEMS ${PROJECT_NAME}) target_compile_options(${t} PRIVATE /Zc:preprocessor /wd5105) endforeach() + if(BUILD_XBOX_EXTS_XBOXONE) + target_compile_options(${PROJECT_NAME} PRIVATE /wd5104 /wd5204) + endif() endif() if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.27) AND (NOT (${DIRECTX_ARCH} MATCHES "^arm"))) diff --git a/CMakePresets.json b/CMakePresets.json index 418a05c..b7d763f 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -95,6 +95,33 @@ }, "hidden": true }, + { + "name": "GDKX", + "cacheVariables": { + "BUILD_XBOX_EXTS_XBOXONE": true + }, + "environment": { + "XboxOneXDKLatest": "" + }, + "hidden": true + }, + { + "name": "GDKXS", + "cacheVariables": { + "BUILD_XBOX_EXTS_SCARLETT": true + }, + "hidden": true + }, + { + "name": "XDK", + "cacheVariables": { + "BUILD_XBOX_EXTS_XBOXONE": true + }, + "environment": { + "GameDKLatest": "" + }, + "hidden": true + }, { "name": "UWP", "cacheVariables": { @@ -233,6 +260,18 @@ { "name": "x86-Debug-Win7-Clang" , "description": "Clang/LLVM for x86 (Debug) for Windows 7", "inherits": [ "base", "x86", "Debug", "Clang", "Win7" ], "environment": { "CXXFLAGS": "-m32" } }, { "name": "x86-Release-Win7-Clang", "description": "Clang/LLVM for x86 (Release) for Windows 7", "inherits": [ "base", "x86", "Release", "Clang", "Win7" ], "environment": { "CXXFLAGS": "-m32" } }, + { "name": "x64-Debug-GDKX" , "description": "MSVC for x64 (Debug) Xbox One Extensions", "inherits": [ "base", "x64", "Debug", "GDKX", "MSVC" ] }, + { "name": "x64-Release-GDKX" , "description": "MSVC for x64 (Release) Xbox One Extensions", "inherits": [ "base", "x64", "Release", "GDKX", "MSVC" ] }, + { "name": "x64-Debug-GDKX-S" , "description": "MSVC for x64 (Debug) Xbox Series X|S Extensions", "inherits": [ "base", "x64", "Debug", "GDKXS", "MSVC" ] }, + { "name": "x64-Release-GDKX-S" , "description": "MSVC for x64 (Release) Xbox Series X|S Extensions", "inherits": [ "base", "x64", "Release", "GDKXS", "MSVC" ] }, + { "name": "x64-Debug-XDK" , "description": "MSVC for x64 (Debug) Xbox One Extensions (legacy)", "inherits": [ "base", "x64", "Debug", "XDK", "MSVC" ] }, + { "name": "x64-Release-XDK" , "description": "MSVC for x64 (Release) Xbox One Extensions (legacy)", "inherits": [ "base", "x64", "Release", "XDK", "MSVC" ] }, + + { "name": "x64-Debug-GDKX-Clang" , "description": "MSVC for x64 (Debug) Xbox One Extensions", "inherits": [ "base", "x64", "Debug", "GDKX", "Clang" ] }, + { "name": "x64-Release-GDKX-Clang" , "description": "MSVC for x64 (Release) Xbox One Extensions", "inherits": [ "base", "x64", "Release", "GDKX", "Clang" ] }, + { "name": "x64-Debug-GDKX-S-Clang" , "description": "MSVC for x64 (Debug) Xbox Series X|S Extensions", "inherits": [ "base", "x64", "Debug", "GDKXS", "Clang" ] }, + { "name": "x64-Release-GDKX-S-Clang" , "description": "MSVC for x64 (Release) Xbox Series X|S Extensions", "inherits": [ "base", "x64", "Release", "GDKXS", "Clang" ] }, + { "name": "x64-Debug-MinGW" , "description": "MinG-W64 (Debug)", "inherits": [ "base", "x64", "Debug", "GNUC", "VCPKG", "MinGW64" ] }, { "name": "x64-Release-MinGW", "description": "MinG-W64 (Release)", "inherits": [ "base", "x64", "Release", "GNUC", "VCPKG", "MinGW64" ] }, { "name": "x86-Debug-MinGW" , "description": "MinG-W32 (Debug)", "inherits": [ "base", "x86", "Debug", "GNUC", "VCPKG", "MinGW32" ] }, diff --git a/DirectXTex/DirectXTex_GDK_2019.vcxproj b/DirectXTex/DirectXTex_GDK_2019.vcxproj index 638caf5..46c3816 100644 --- a/DirectXTex/DirectXTex_GDK_2019.vcxproj +++ b/DirectXTex/DirectXTex_GDK_2019.vcxproj @@ -467,6 +467,11 @@ + + true + true + true + @@ -504,6 +509,31 @@ Create + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + diff --git a/DirectXTex/DirectXTex_GDK_2019.vcxproj.filters b/DirectXTex/DirectXTex_GDK_2019.vcxproj.filters index fbd667f..b9cc3ab 100644 --- a/DirectXTex/DirectXTex_GDK_2019.vcxproj.filters +++ b/DirectXTex/DirectXTex_GDK_2019.vcxproj.filters @@ -12,6 +12,9 @@ {c60baf7a-25a9-4215-842d-8d49d65d538e} + + {34568028-594c-4052-9a41-0973bbe526e1} + @@ -35,6 +38,9 @@ Source Files + + Auxiliary + @@ -106,5 +112,20 @@ Source Files + + Auxiliary + + + Auxiliary + + + Auxiliary + + + Auxiliary + + + Auxiliary + \ No newline at end of file diff --git a/DirectXTex/DirectXTex_GDK_2022.vcxproj b/DirectXTex/DirectXTex_GDK_2022.vcxproj index 17a2af2..b8446af 100644 --- a/DirectXTex/DirectXTex_GDK_2022.vcxproj +++ b/DirectXTex/DirectXTex_GDK_2022.vcxproj @@ -467,6 +467,11 @@ + + true + true + true + @@ -504,6 +509,31 @@ Create + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + + + true + true + true + diff --git a/DirectXTex/DirectXTex_GDK_2022.vcxproj.filters b/DirectXTex/DirectXTex_GDK_2022.vcxproj.filters index fbd667f..b9cc3ab 100644 --- a/DirectXTex/DirectXTex_GDK_2022.vcxproj.filters +++ b/DirectXTex/DirectXTex_GDK_2022.vcxproj.filters @@ -12,6 +12,9 @@ {c60baf7a-25a9-4215-842d-8d49d65d538e} + + {34568028-594c-4052-9a41-0973bbe526e1} + @@ -35,6 +38,9 @@ Source Files + + Auxiliary + @@ -106,5 +112,20 @@ Source Files + + Auxiliary + + + Auxiliary + + + Auxiliary + + + Auxiliary + + + Auxiliary + \ No newline at end of file diff --git a/DirectXTex/DirectXTex_GXDK_PC_2019.vcxproj b/DirectXTex/DirectXTex_GXDK_PC_2019.vcxproj new file mode 100644 index 0000000..01a9570 --- /dev/null +++ b/DirectXTex/DirectXTex_GXDK_PC_2019.vcxproj @@ -0,0 +1,285 @@ + + + + + Debug_Scarlett + x64 + + + Debug + x64 + + + Release_Scarlett + x64 + + + Release + x64 + + + + DirectXTex + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34} + DirectXTex + Win32Proj + 10.0 + x64 + + + + + StaticLibrary + true + Unicode + v142 + + + StaticLibrary + true + Unicode + v142 + + + StaticLibrary + Unicode + v142 + + + StaticLibrary + Unicode + v142 + + + + + + + + + + + + + + + + + + Bin\GXDKPC_2019\$(Platform)\$(Configuration)\ + Bin\GXDKPC_2019\$(Platform)\$(Configuration)\ + DirectXTex + $(GameDKLatest)GXDK\toolKit\include;$(GameDKLatest)GXDK\toolKit\include\XboxOne;$(VC_IncludePath);$(WindowsSDK_IncludePath); + $(GameDKLatest)GXDK\toolKit\lib\amd64\XboxOne;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 + true + + + Bin\GXDKPC_2019\$(Platform)\$(Configuration)\ + Bin\GXDKPC_2019\$(Platform)\$(Configuration)\ + DirectXTex + $(GameDKLatest)GXDK\toolKit\include;$(GameDKLatest)GXDK\toolKit\include\Scarlett;$(VC_IncludePath);$(WindowsSDK_IncludePath); + $(GameDKLatest)GXDK\toolKit\lib\amd64\Scarlett;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 + true + + + Bin\GXDKPC_2019\$(Platform)\$(Configuration)\ + Bin\GXDKPC_2019\$(Platform)\$(Configuration)\ + DirectXTex + $(GameDKLatest)GXDK\toolKit\include;$(GameDKLatest)GXDK\toolKit\include\XboxOne;$(VC_IncludePath);$(WindowsSDK_IncludePath); + $(GameDKLatest)GXDK\toolKit\lib\amd64\XboxOne;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 + true + + + Bin\GXDKPC_2019\$(Platform)\$(Configuration)\ + Bin\GXDKPC_2019\$(Platform)\$(Configuration)\ + DirectXTex + $(GameDKLatest)GXDK\toolKit\include;$(GameDKLatest)GXDK\toolKit\include\Scarlett;$(VC_IncludePath);$(WindowsSDK_IncludePath); + $(GameDKLatest)GXDK\toolKit\lib\amd64\Scarlett;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 + true + + + + EnableAllWarnings + Disabled + MultiThreadedDebugDLL + Fast + /Zc:twoPhase- /Zc:__cplusplus /ZH:SHA_256 %(AdditionalOptions) + _USE_GXDK;_UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN32_WINNT=0x0A00;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) + Use + DirectXTexP.h + $(ProjectDir);$(ProjectDir)Shaders\Compiled;%(AdditionalIncludeDirectories) + $(IntDir)$(TargetName).pdb + true + true + true + /Zc:twoPhase- /Zc:__cplusplus /ZH:SHA_256 %(AdditionalOptions) + Level4 + ProgramDatabase + false + + + Windows + true + + + false + + + + + EnableAllWarnings + Disabled + MultiThreadedDebugDLL + Fast + /Zc:twoPhase- /Zc:__cplusplus /ZH:SHA_256 %(AdditionalOptions) + _USE_GXDK;_USE_SCARLETT;_UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN32_WINNT=0x0A00;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) + Use + DirectXTexP.h + $(ProjectDir);$(ProjectDir)Shaders\Compiled;%(AdditionalIncludeDirectories) + $(IntDir)$(TargetName).pdb + true + true + true + /Zc:twoPhase- /Zc:__cplusplus /ZH:SHA_256 %(AdditionalOptions) + Level4 + ProgramDatabase + false + + + Windows + true + + + false + + + + + EnableAllWarnings + MaxSpeed + Fast + /Zc:twoPhase- /Zc:__cplusplus /ZH:SHA_256 %(AdditionalOptions) + _USE_GXDK;_UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN32_WINNT=0x0A00;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) + Use + DirectXTexP.h + $(ProjectDir);$(ProjectDir)Shaders\Compiled;%(AdditionalIncludeDirectories) + $(IntDir)$(TargetName).pdb + true + true + true + /Zc:twoPhase- /Zc:__cplusplus /ZH:SHA_256 %(AdditionalOptions) + Level4 + true + + + true + Windows + true + true + + + false + + + + + EnableAllWarnings + MaxSpeed + Fast + /Zc:twoPhase- /Zc:__cplusplus /ZH:SHA_256 %(AdditionalOptions) + _USE_GXDK;_USE_SCARLETT;_UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN32_WINNT=0x0A00;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) + Use + DirectXTexP.h + $(ProjectDir);$(ProjectDir)Shaders\Compiled;%(AdditionalIncludeDirectories) + $(IntDir)$(TargetName).pdb + true + true + true + /Zc:twoPhase- /Zc:__cplusplus /ZH:SHA_256 %(AdditionalOptions) + Level4 + true + + + true + Windows + true + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + Document + + + Document + + + + + + + + + + <_ATGFXCPath>$(WindowsSDK_ExecutablePath_x64.Split(';')[0]) + <_ATGFXCPath>$(_ATGFXCPath.Replace("x64","")) + <_ATGFXCPath Condition="'$(_ATGFXCPath)' != '' and !HasTrailingSlash('$(_ATGFXCPath)')">$(_ATGFXCPath)\ + + + + <_ATGFXCPath /> + + + + + <_ATGShaderHeaders Include="$(ProjectDir)Shaders/Compiled/*.inc" /> + <_ATGShaderSymbols Include="$(ProjectDir)Shaders/Compiled/*.pdb" /> + + + + + \ No newline at end of file diff --git a/DirectXTex/DirectXTex_GXDK_PC_2019.vcxproj.filters b/DirectXTex/DirectXTex_GXDK_PC_2019.vcxproj.filters new file mode 100644 index 0000000..b8a9acf --- /dev/null +++ b/DirectXTex/DirectXTex_GXDK_PC_2019.vcxproj.filters @@ -0,0 +1,134 @@ + + + + + {68652706-b700-4472-9af7-a56a482bd896} + + + {9b7fcbc5-2533-4b88-b75b-d4803e55fa7c} + + + {eb989628-e889-44bf-837a-05c9f09b258e} + + + {1cab8337-50f3-4e55-9ccf-c060bac667ee} + + + + + Header Files + + + Header Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Auxiliary + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Auxiliary + + + Auxiliary + + + Auxiliary + + + Auxiliary + + + + + Source Files + + + + + Source Files\Shaders + + + Source Files\Shaders + + + Source Files\Shaders + + + + \ No newline at end of file diff --git a/DirectXTex/DirectXTex_GXDK_PC_2022.vcxproj b/DirectXTex/DirectXTex_GXDK_PC_2022.vcxproj new file mode 100644 index 0000000..530f0a4 --- /dev/null +++ b/DirectXTex/DirectXTex_GXDK_PC_2022.vcxproj @@ -0,0 +1,285 @@ + + + + + Debug_Scarlett + x64 + + + Debug + x64 + + + Release_Scarlett + x64 + + + Release + x64 + + + + DirectXTex + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34} + DirectXTex + Win32Proj + 10.0 + x64 + + + + + StaticLibrary + true + Unicode + v143 + + + StaticLibrary + true + Unicode + v143 + + + StaticLibrary + Unicode + v143 + + + StaticLibrary + Unicode + v143 + + + + + + + + + + + + + + + + + + Bin\GXDKPC_2022\$(Platform)\$(Configuration)\ + Bin\GXDKPC_2022\$(Platform)\$(Configuration)\ + DirectXTex + $(GameDKLatest)GXDK\toolKit\include;$(GameDKLatest)GXDK\toolKit\include\XboxOne;$(VC_IncludePath);$(WindowsSDK_IncludePath); + $(GameDKLatest)GXDK\toolKit\lib\amd64\XboxOne;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 + true + + + Bin\GXDKPC_2022\$(Platform)\$(Configuration)\ + Bin\GXDKPC_2022\$(Platform)\$(Configuration)\ + DirectXTex + $(GameDKLatest)GXDK\toolKit\include;$(GameDKLatest)GXDK\toolKit\include\Scarlett;$(VC_IncludePath);$(WindowsSDK_IncludePath); + $(GameDKLatest)GXDK\toolKit\lib\amd64\Scarlett;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 + true + + + Bin\GXDKPC_2022\$(Platform)\$(Configuration)\ + Bin\GXDKPC_2022\$(Platform)\$(Configuration)\ + DirectXTex + $(GameDKLatest)GXDK\toolKit\include;$(GameDKLatest)GXDK\toolKit\include\XboxOne;$(VC_IncludePath);$(WindowsSDK_IncludePath); + $(GameDKLatest)GXDK\toolKit\lib\amd64\XboxOne;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 + true + + + Bin\GXDKPC_2022\$(Platform)\$(Configuration)\ + Bin\GXDKPC_2022\$(Platform)\$(Configuration)\ + DirectXTex + $(GameDKLatest)GXDK\toolKit\include;$(GameDKLatest)GXDK\toolKit\include\Scarlett;$(VC_IncludePath);$(WindowsSDK_IncludePath); + $(GameDKLatest)GXDK\toolKit\lib\amd64\Scarlett;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 + true + + + + EnableAllWarnings + Disabled + MultiThreadedDebugDLL + Fast + /Zc:twoPhase- /Zc:__cplusplus %(AdditionalOptions) + _USE_GXDK;_UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN32_WINNT=0x0A00;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) + Use + DirectXTexP.h + $(ProjectDir);$(ProjectDir)Shaders\Compiled;%(AdditionalIncludeDirectories) + $(IntDir)$(TargetName).pdb + true + true + true + /Zc:twoPhase- /Zc:__cplusplus %(AdditionalOptions) + Level4 + ProgramDatabase + false + + + Windows + true + + + false + + + + + EnableAllWarnings + Disabled + MultiThreadedDebugDLL + Fast + /Zc:twoPhase- /Zc:__cplusplus %(AdditionalOptions) + _USE_GXDK;_USE_SCARLETT;_UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN32_WINNT=0x0A00;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) + Use + DirectXTexP.h + $(ProjectDir);$(ProjectDir)Shaders\Compiled;%(AdditionalIncludeDirectories) + $(IntDir)$(TargetName).pdb + true + true + true + /Zc:twoPhase- /Zc:__cplusplus %(AdditionalOptions) + Level4 + ProgramDatabase + false + + + Windows + true + + + false + + + + + EnableAllWarnings + MaxSpeed + Fast + /Zc:twoPhase- /Zc:__cplusplus %(AdditionalOptions) + _USE_GXDK;_UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN32_WINNT=0x0A00;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) + Use + DirectXTexP.h + $(ProjectDir);$(ProjectDir)Shaders\Compiled;%(AdditionalIncludeDirectories) + $(IntDir)$(TargetName).pdb + true + true + true + /Zc:twoPhase- /Zc:__cplusplus %(AdditionalOptions) + Level4 + true + + + true + Windows + true + true + + + false + + + + + EnableAllWarnings + MaxSpeed + Fast + /Zc:twoPhase- /Zc:__cplusplus %(AdditionalOptions) + _USE_GXDK;_USE_SCARLETT;_UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN32_WINNT=0x0A00;_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS;%(PreprocessorDefinitions) + Use + DirectXTexP.h + $(ProjectDir);$(ProjectDir)Shaders\Compiled;%(AdditionalIncludeDirectories) + $(IntDir)$(TargetName).pdb + true + true + true + /Zc:twoPhase- /Zc:__cplusplus %(AdditionalOptions) + Level4 + true + + + true + Windows + true + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + Document + + + Document + + + + + + + + + + <_ATGFXCPath>$(WindowsSDK_ExecutablePath_x64.Split(';')[0]) + <_ATGFXCPath>$(_ATGFXCPath.Replace("x64","")) + <_ATGFXCPath Condition="'$(_ATGFXCPath)' != '' and !HasTrailingSlash('$(_ATGFXCPath)')">$(_ATGFXCPath)\ + + + + <_ATGFXCPath /> + + + + + <_ATGShaderHeaders Include="$(ProjectDir)Shaders/Compiled/*.inc" /> + <_ATGShaderSymbols Include="$(ProjectDir)Shaders/Compiled/*.pdb" /> + + + + + \ No newline at end of file diff --git a/DirectXTex/DirectXTex_GXDK_PC_2022.vcxproj.filters b/DirectXTex/DirectXTex_GXDK_PC_2022.vcxproj.filters new file mode 100644 index 0000000..4b1d4d7 --- /dev/null +++ b/DirectXTex/DirectXTex_GXDK_PC_2022.vcxproj.filters @@ -0,0 +1,134 @@ + + + + + {68652706-b700-4472-9af7-a56a482bd896} + + + {9b7fcbc5-2533-4b88-b75b-d4803e55fa7c} + + + {eb989628-e889-44bf-837a-05c9f09b258e} + + + {b21bd310-5ba0-485c-82e2-9621564caf70} + + + + + Header Files + + + Header Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Auxiliary + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Auxiliary + + + Auxiliary + + + Auxiliary + + + Auxiliary + + + + + Source Files + + + + + Source Files\Shaders + + + Source Files\Shaders + + + Source Files\Shaders + + + + \ No newline at end of file diff --git a/DirectXTex_GXDK_PC_2019.sln b/DirectXTex_GXDK_PC_2019.sln new file mode 100644 index 0000000..0a331d1 --- /dev/null +++ b/DirectXTex_GXDK_PC_2019.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 15.0.28307.1259 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "DirectXTex\DirectXTex_GXDK_PC_2019.vcxproj", "{9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{06070D23-4542-4B1C-9DC2-846B1694E365}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_Scarlett|x64 = Debug_Scarlett|x64 + Debug|x64 = Debug|x64 + Release_Scarlett|x64 = Release_Scarlett|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Debug_Scarlett|x64.ActiveCfg = Debug_Scarlett|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Debug_Scarlett|x64.Build.0 = Debug_Scarlett|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Debug|x64.ActiveCfg = Debug|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Debug|x64.Build.0 = Debug|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Release_Scarlett|x64.ActiveCfg = Release_Scarlett|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Release_Scarlett|x64.Build.0 = Release_Scarlett|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Release|x64.ActiveCfg = Release|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8EC36707-6F26-43CF-8458-C3E4E1113C22} + EndGlobalSection +EndGlobal diff --git a/DirectXTex_GXDK_PC_2022.sln b/DirectXTex_GXDK_PC_2022.sln new file mode 100644 index 0000000..eda35f0 --- /dev/null +++ b/DirectXTex_GXDK_PC_2022.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 15.0.28307.1259 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "DirectXTex\DirectXTex_GXDK_PC_2022.vcxproj", "{9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{06070D23-4542-4B1C-9DC2-846B1694E365}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_Scarlett|x64 = Debug_Scarlett|x64 + Debug|x64 = Debug|x64 + Release_Scarlett|x64 = Release_Scarlett|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Debug_Scarlett|x64.ActiveCfg = Debug_Scarlett|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Debug_Scarlett|x64.Build.0 = Debug_Scarlett|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Debug|x64.ActiveCfg = Debug|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Debug|x64.Build.0 = Debug|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Release_Scarlett|x64.ActiveCfg = Release_Scarlett|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Release_Scarlett|x64.Build.0 = Release_Scarlett|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Release|x64.ActiveCfg = Release|x64 + {9E4D1C18-9E5E-4B35-83BE-74830B9B3C34}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8EC36707-6F26-43CF-8458-C3E4E1113C22} + EndGlobalSection +EndGlobal diff --git a/NuGet.Config b/NuGet.Config new file mode 100644 index 0000000..7e49cd0 --- /dev/null +++ b/NuGet.Config @@ -0,0 +1,6 @@ + + + + + + diff --git a/build/DirectXTex-GitHub-CMake-Xbox-Dev17.yml b/build/DirectXTex-GitHub-CMake-Xbox-Dev17.yml new file mode 100644 index 0000000..e1ac87c --- /dev/null +++ b/build/DirectXTex-GitHub-CMake-Xbox-Dev17.yml @@ -0,0 +1,134 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# +# http://go.microsoft.com/fwlink/?LinkId=248926 + +# Builds the library with Xbox extensions using CMake. + +schedules: +- cron: "0 4 * * *" + displayName: 'Nightly build' + branches: + include: + - main + +trigger: none +pr: none + +resources: + repositories: + - repository: self + type: git + ref: refs/heads/main + +name: $(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r) + +variables: + VS_GENERATOR: 'Visual Studio 17 2022' + WIN10_SDK: '10.0.19041.0' + EXTRACTED_FOLDER: $(ExtractedFolder) + GDK_EDITION: $(GDKEditionNumber) + URL_FEED: $(ADOFeedURL) + GameDKLatest: '$(ExtractedFolder)\GDK\Microsoft.gdk.xbox.$(GDKEditionNumber)\native\$(GDKEditionNumber)\' + +pool: + vmImage: windows-2022 + +jobs: +- job: CMAKE_BUILD + displayName: CMake using VS Generator + steps: + - checkout: self + clean: true + fetchTags: false + - task: NuGetToolInstaller@1 + displayName: 'Use NuGet' + inputs: + versionSpec: '6.5.x' + - task: NuGetCommand@2 + # We have to use a nuget.config to provide the feed for the 'nuget install' option. + displayName: 'NuGet set package source to ADO feed' + inputs: + command: custom + arguments: sources add -Name xboxgdk-DirectXTex -Source $(URL_FEED) -ConfigFile $(Build.SourcesDirectory)\NuGet.config + - task: PowerShell@2 + displayName: 'Set nuget.config to single source' + inputs: + targetType: inline + script: | + $file = '.\NuGet.Config' + $doc = [xml](Get-Content $file) + $newelement = $doc.CreateElement("clear") + $clearadd = $doc.configuration.packageSources.PrependChild($newelement) + $doc.OuterXml | Set-Content $file + + - task: NuGetCommand@2 + displayName: NuGet install PGDK + inputs: + command: custom + arguments: install -prerelease Microsoft.GDK.PC.$(GDK_EDITION) -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\GDK + - task: NuGetCommand@2 + displayName: NuGet install GDKX + inputs: + command: custom + arguments: install -prerelease Microsoft.GDK.Xbox.$(GDK_EDITION) -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\GDK + - task: CMake@1 + displayName: 'CMake (MSVC): Config x64 (Xbox Series X|S)' + inputs: + cwd: '' + cmakeArgs: '-G "$(VS_GENERATOR)" -A x64 -B out -DCMAKE_SYSTEM_VERSION=$(WIN10_SDK) -DBUILD_XBOX_EXTS_SCARLETT=ON -DBUILD_SAMPLE=OFF' + - task: CMake@1 + displayName: 'CMake (MSVC): Build x64 Debug (Xbox Series X|S)' + inputs: + cwd: '' + cmakeArgs: --build out -v --config Debug + - task: CMake@1 + displayName: 'CMake (MSVC): Build x64 Release (Xbox Series X|S)' + inputs: + cwd: '' + cmakeArgs: --build out -v --config RelWithDebInfo + - task: CMake@1 + displayName: 'CMake (ClangCl): Config x64 (Xbox Series X|S)' + inputs: + cwd: '' + cmakeArgs: '-G "$(VS_GENERATOR)" -A x64 -T clangcl -B out2 -DCMAKE_SYSTEM_VERSION=$(WIN10_SDK) -DBUILD_XBOX_EXTS_SCARLETT=ON -DBUILD_SAMPLE=OFF' + - task: CMake@1 + displayName: 'CMake (ClangCl): Build x64 Debug (Xbox Series X|S)' + inputs: + cwd: '' + cmakeArgs: --build out2 -v --config Debug + - task: CMake@1 + displayName: 'CMake (ClangCl): Build x64 Release (Xbox Series X|S)' + inputs: + cwd: '' + cmakeArgs: --build out2 -v --config RelWithDebInfo + - task: CMake@1 + displayName: 'CMake (MSVC): Config x64 (Xbox One)' + inputs: + cwd: '' + cmakeArgs: '-G "$(VS_GENERATOR)" -A x64 -B out3 -DCMAKE_SYSTEM_VERSION=$(WIN10_SDK) -DBUILD_XBOX_EXTS_XBOXONE=ON -DBUILD_SAMPLE=OFF' + - task: CMake@1 + displayName: 'CMake (MSVC): Build x64 Debug (Xbox One)' + inputs: + cwd: '' + cmakeArgs: --build out3 -v --config Debug + - task: CMake@1 + displayName: 'CMake (MSVC): Build x64 Release (Xbox One)' + inputs: + cwd: '' + cmakeArgs: --build out3 -v --config RelWithDebInfo + - task: CMake@1 + displayName: 'CMake (ClangCl): Config x64 (Xbox One)' + inputs: + cwd: '' + cmakeArgs: '-G "$(VS_GENERATOR)" -A x64 -T clangcl -B out4 -DCMAKE_SYSTEM_VERSION=$(WIN10_SDK) -DBUILD_XBOX_EXTS_XBOXONE=ON -DBUILD_SAMPLE=OFF' + - task: CMake@1 + displayName: 'CMake (ClangCl): Build x64 Debug (Xbox One)' + inputs: + cwd: '' + cmakeArgs: --build out4 -v --config Debug + - task: CMake@1 + displayName: 'CMake (ClangCl): Build x64 Release (Xbox One)' + inputs: + cwd: '' + cmakeArgs: --build out4 -v --config RelWithDebInfo diff --git a/build/DirectXTex-GitHub-CMake-Xbox.yml b/build/DirectXTex-GitHub-CMake-Xbox.yml new file mode 100644 index 0000000..efd3ee0 --- /dev/null +++ b/build/DirectXTex-GitHub-CMake-Xbox.yml @@ -0,0 +1,147 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# +# http://go.microsoft.com/fwlink/?LinkId=248926 + +# Builds the library with Xbox extensions using CMake. + +schedules: +- cron: "0 4 * * *" + displayName: 'Nightly build' + branches: + include: + - main + +trigger: + branches: + include: + - main + paths: + include: + - CMakeLists.txt +pr: + branches: + include: + - main + paths: + include: + - CMakeLists.txt + drafts: false + +resources: + repositories: + - repository: self + type: git + ref: refs/heads/main + +name: $(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r) + +variables: + VS_GENERATOR: 'Visual Studio 16 2019' + WIN10_SDK: '10.0.19041.0' + EXTRACTED_FOLDER: $(ExtractedFolder) + GDK_EDITION: $(GDKEditionNumber) + URL_FEED: $(ADOFeedURL) + GameDKLatest: '$(ExtractedFolder)\GDK\Microsoft.gdk.xbox.$(GDKEditionNumber)\native\$(GDKEditionNumber)\' + +pool: + vmImage: windows-2019 + +jobs: +- job: CMAKE_BUILD + displayName: CMake using VS Generator + steps: + - checkout: self + clean: true + fetchTags: false + - task: NuGetToolInstaller@1 + displayName: 'Use NuGet' + inputs: + versionSpec: '6.5.x' + - task: NuGetCommand@2 + # We have to use a nuget.config to provide the feed for the 'nuget install' option. + displayName: 'NuGet set package source to ADO feed' + inputs: + command: custom + arguments: sources add -Name xboxgdk-DirectXTex -Source $(URL_FEED) -ConfigFile $(Build.SourcesDirectory)\NuGet.config + - task: PowerShell@2 + displayName: 'Set nuget.config to single source' + inputs: + targetType: inline + script: | + $file = '.\NuGet.Config' + $doc = [xml](Get-Content $file) + $newelement = $doc.CreateElement("clear") + $clearadd = $doc.configuration.packageSources.PrependChild($newelement) + $doc.OuterXml | Set-Content $file + + - task: NuGetCommand@2 + displayName: NuGet install PGDK + inputs: + command: custom + arguments: install -prerelease Microsoft.GDK.PC.$(GDK_EDITION) -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\GDK + - task: NuGetCommand@2 + displayName: NuGet install GDKX + inputs: + command: custom + arguments: install -prerelease Microsoft.GDK.Xbox.$(GDK_EDITION) -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\GDK + - task: CMake@1 + displayName: 'CMake (MSVC): Config x64 (Xbox Series X|S)' + inputs: + cwd: '' + cmakeArgs: '-G "$(VS_GENERATOR)" -A x64 -B out -DCMAKE_SYSTEM_VERSION=$(WIN10_SDK) -DBUILD_XBOX_EXTS_SCARLETT=ON -DBUILD_SAMPLE=OFF' + - task: CMake@1 + displayName: 'CMake (MSVC): Build x64 Debug (Xbox Series X|S)' + inputs: + cwd: '' + cmakeArgs: --build out -v --config Debug + - task: CMake@1 + displayName: 'CMake (MSVC): Build x64 Release (Xbox Series X|S)' + inputs: + cwd: '' + cmakeArgs: --build out -v --config RelWithDebInfo + - task: CMake@1 + displayName: 'CMake (ClangCl): Config x64 (Xbox Series X|S)' + inputs: + cwd: '' + cmakeArgs: '-G "$(VS_GENERATOR)" -A x64 -T clangcl -B out2 -DCMAKE_SYSTEM_VERSION=$(WIN10_SDK) -DBUILD_XBOX_EXTS_SCARLETT=ON -DBUILD_SAMPLE=OFF' + - task: CMake@1 + displayName: 'CMake (ClangCl): Build x64 Debug (Xbox Series X|S)' + inputs: + cwd: '' + cmakeArgs: --build out2 -v --config Debug + - task: CMake@1 + displayName: 'CMake (ClangCl): Build x64 Release (Xbox Series X|S)' + inputs: + cwd: '' + cmakeArgs: --build out2 -v --config RelWithDebInfo + - task: CMake@1 + displayName: 'CMake (MSVC): Config x64 (Xbox One)' + inputs: + cwd: '' + cmakeArgs: '-G "$(VS_GENERATOR)" -A x64 -B out3 -DCMAKE_SYSTEM_VERSION=$(WIN10_SDK) -DBUILD_XBOX_EXTS_XBOXONE=ON -DBUILD_SAMPLE=OFF' + - task: CMake@1 + displayName: 'CMake (MSVC): Build x64 Debug (Xbox One)' + inputs: + cwd: '' + cmakeArgs: --build out3 -v --config Debug + - task: CMake@1 + displayName: 'CMake (MSVC): Build x64 Release (Xbox One)' + inputs: + cwd: '' + cmakeArgs: --build out3 -v --config RelWithDebInfo + - task: CMake@1 + displayName: 'CMake (ClangCl): Config x64 (Xbox One)' + inputs: + cwd: '' + cmakeArgs: '-G "$(VS_GENERATOR)" -A x64 -T clangcl -B out4 -DCMAKE_SYSTEM_VERSION=$(WIN10_SDK) -DBUILD_XBOX_EXTS_XBOXONE=ON -DBUILD_SAMPLE=OFF' + - task: CMake@1 + displayName: 'CMake (ClangCl): Build x64 Debug (Xbox One)' + inputs: + cwd: '' + cmakeArgs: --build out4 -v --config Debug + - task: CMake@1 + displayName: 'CMake (ClangCl): Build x64 Release (Xbox One)' + inputs: + cwd: '' + cmakeArgs: --build out4 -v --config RelWithDebInfo diff --git a/build/DirectXTex-GitHub-GDK-Dev17.yml b/build/DirectXTex-GitHub-GDK-Dev17.yml new file mode 100644 index 0000000..28f1ec1 --- /dev/null +++ b/build/DirectXTex-GitHub-GDK-Dev17.yml @@ -0,0 +1,181 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# +# http://go.microsoft.com/fwlink/?LinkId=248926 + +# Builds the library with Xbox extensions using the Microsoft GDK. + +schedules: +- cron: "30 3 * * *" + displayName: 'Nightly build' + branches: + include: + - main + +trigger: none +pr: none + +resources: + repositories: + - repository: self + type: git + ref: refs/heads/main + +name: $(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r) + +pool: + vmImage: windows-2022 + +variables: + EXTRACTED_FOLDER: $(ExtractedFolder) + GDK_EDITION: $(GDKEditionNumber) + GDKEnableBWOI: true + GITHUB_PAT: $(GITHUBPUBLICTOKEN) + URL_FEED: $(ADOFeedURL) + +jobs: +- job: BUILD_GDK + displayName: 'Microsoft Game Development Kit (GDK)' + timeoutInMinutes: 120 + cancelTimeoutInMinutes: 1 + steps: + - checkout: self + clean: true + fetchTags: false + - task: NuGetToolInstaller@1 + displayName: 'Use NuGet' + inputs: + versionSpec: '6.5.x' + - task: NuGetCommand@2 + # We have to use a nuget.config to provide the feed for the 'nuget install' option. + displayName: 'NuGet set package source to ADO feed' + inputs: + command: custom + arguments: sources add -Name xboxgdk-DirectXTex -Source $(URL_FEED) -ConfigFile $(Build.SourcesDirectory)\NuGet.config + - task: PowerShell@2 + displayName: 'Set nuget.config to single source' + inputs: + targetType: inline + script: | + $file = '.\NuGet.Config' + $doc = [xml](Get-Content $file) + $newelement = $doc.CreateElement("clear") + $clearadd = $doc.configuration.packageSources.PrependChild($newelement) + $doc.OuterXml | Set-Content $file + + - task: NuGetCommand@2 + displayName: NuGet install PGDK + inputs: + command: custom + arguments: install -prerelease Microsoft.GDK.PC.$(GDK_EDITION) -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\GDK + - task: NuGetCommand@2 + displayName: NuGet install GDKX + inputs: + command: custom + arguments: install -prerelease Microsoft.GDK.Xbox.$(GDK_EDITION) -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\GDK + - task: CopyFiles@2 + displayName: Set up Directory.Build.props + inputs: + SourceFolder: build + Contents: 'Directory.Build.props' + TargetFolder: $(Build.SourcesDirectory) + - task: MSBuild@1 + displayName: Setup BWOI VCTargets + inputs: + solution: build/SetupBWOI.targets + msbuildVersion: 17.0 + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_2022 pcdbg + continueOnError: True + inputs: + solution: DirectXTex_GDK_2022.sln + vsVersion: 17.0 + platform: Gaming.Desktop.x64 + configuration: Debug + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_2022 pcrel + continueOnError: True + inputs: + solution: DirectXTex_GDK_2022.sln + vsVersion: 17.0 + platform: Gaming.Desktop.x64 + configuration: Release + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_2022 xbdbg + continueOnError: True + inputs: + solution: DirectXTex_GDK_2022.sln + vsVersion: 17.0 + platform: Gaming.Xbox.XboxOne.x64 + configuration: Debug + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_2022 xbrel + continueOnError: True + inputs: + solution: DirectXTex_GDK_2022.sln + vsVersion: 17.0 + platform: Gaming.Xbox.XboxOne.x64 + configuration: Release + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_2022 scardbg + continueOnError: True + inputs: + solution: DirectXTex_GDK_2022.sln + vsVersion: 17.0 + platform: Gaming.Xbox.Scarlett.x64 + configuration: Debug + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_2022 scarrel + continueOnError: True + inputs: + solution: DirectXTex_GDK_2022.sln + vsVersion: 17.0 + platform: Gaming.Xbox.Scarlett.x64 + configuration: Release + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_PC_2022 dbg + continueOnError: True + inputs: + solution: DirectXTex_GXDK_PC_2022.sln + vsVersion: 17.0 + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Debug + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_PC_2022 rel + continueOnError: True + inputs: + solution: DirectXTex_GXDK_PC_2022.sln + vsVersion: 17.0 + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Release + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_PC_2022 scardbg + continueOnError: True + inputs: + solution: DirectXTex_GXDK_PC_2022.sln + vsVersion: 17.0 + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Debug_Scarlett + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_PC_2022 scarrel + continueOnError: True + inputs: + solution: DirectXTex_GXDK_PC_2022.sln + vsVersion: 17.0 + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Release_Scarlett + msbuildArchitecture: x64 diff --git a/build/DirectXTex-GitHub-GDK.yml b/build/DirectXTex-GitHub-GDK.yml new file mode 100644 index 0000000..6d0a843 --- /dev/null +++ b/build/DirectXTex-GitHub-GDK.yml @@ -0,0 +1,202 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# +# http://go.microsoft.com/fwlink/?LinkId=248926 + +# Builds the library with Xbox extensions using the Microsoft GDK. + +# NOTE: We use x64 MSBuild for the GDK as the NuGets don't include 32-bit support to avoid cross-arch dependencies. + +schedules: +- cron: "30 3 * * *" + displayName: 'Nightly build' + branches: + include: + - main + +trigger: + branches: + include: + - main + paths: + exclude: + - README.md + - HISTORY.md + - SECURITY.md + - LICENSE +pr: + branches: + include: + - main + paths: + exclude: + - README.md + - HISTORY.md + - SECURITY.md + - LICENSE + drafts: false + +resources: + repositories: + - repository: self + type: git + ref: refs/heads/main + +name: $(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r) + +pool: + vmImage: windows-2019 + +variables: + EXTRACTED_FOLDER: $(ExtractedFolder) + GDK_EDITION: $(GDKEditionNumber) + GDKEnableBWOI: true + GITHUB_PAT: $(GITHUBPUBLICTOKEN) + URL_FEED: $(ADOFeedURL) + +jobs: +- job: BUILD_GDK + displayName: 'Microsoft Game Development Kit (GDK)' + timeoutInMinutes: 120 + cancelTimeoutInMinutes: 1 + steps: + - checkout: self + clean: true + fetchTags: false + - task: NuGetToolInstaller@1 + displayName: 'Use NuGet' + inputs: + versionSpec: '6.5.x' + - task: NuGetCommand@2 + # We have to use a nuget.config to provide the feed for the 'nuget install' option. + displayName: 'NuGet set package source to ADO feed' + inputs: + command: custom + arguments: sources add -Name xboxgdk-DirectXTex -Source $(URL_FEED) -ConfigFile $(Build.SourcesDirectory)\NuGet.config + - task: PowerShell@2 + displayName: 'Set nuget.config to single source' + inputs: + targetType: inline + script: | + $file = '.\NuGet.Config' + $doc = [xml](Get-Content $file) + $newelement = $doc.CreateElement("clear") + $clearadd = $doc.configuration.packageSources.PrependChild($newelement) + $doc.OuterXml | Set-Content $file + + - task: NuGetCommand@2 + displayName: NuGet install PGDK + inputs: + command: custom + arguments: install -prerelease Microsoft.GDK.PC.$(GDK_EDITION) -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\GDK + - task: NuGetCommand@2 + displayName: NuGet install GDKX + inputs: + command: custom + arguments: install -prerelease Microsoft.GDK.Xbox.$(GDK_EDITION) -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\GDK + - task: CopyFiles@2 + displayName: Set up Directory.Build.props + inputs: + SourceFolder: build + Contents: 'Directory.Build.props' + TargetFolder: $(Build.SourcesDirectory) + - task: MSBuild@1 + displayName: Setup BWOI VCTargets + inputs: + solution: build/SetupBWOI.targets + msbuildVersion: 16.0 + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_2019 pcdbg + continueOnError: True + inputs: + solution: DirectXTex_GDK_2019.sln + vsVersion: 16.0 + platform: Gaming.Desktop.x64 + configuration: Debug + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_2019 pcrel + continueOnError: True + inputs: + solution: DirectXTex_GDK_2019.sln + vsVersion: 16.0 + platform: Gaming.Desktop.x64 + configuration: Release + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_2019 xbdbg + continueOnError: True + inputs: + solution: DirectXTex_GDK_2019.sln + vsVersion: 16.0 + platform: Gaming.Xbox.XboxOne.x64 + configuration: Debug + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_2019 xbrel + continueOnError: True + inputs: + solution: DirectXTex_GDK_2019.sln + vsVersion: 16.0 + platform: Gaming.Xbox.XboxOne.x64 + configuration: Release + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_2019 scardbg + continueOnError: True + inputs: + solution: DirectXTex_GDK_2019.sln + vsVersion: 16.0 + platform: Gaming.Xbox.Scarlett.x64 + configuration: Debug + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_2019 scarrel + continueOnError: True + inputs: + solution: DirectXTex_GDK_2019.sln + vsVersion: 16.0 + platform: Gaming.Xbox.Scarlett.x64 + configuration: Release + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_PC_2019 dbg + continueOnError: True + inputs: + solution: DirectXTex_GXDK_PC_2019.sln + vsVersion: 16.0 + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Debug + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_PC_2019 rel + continueOnError: True + inputs: + solution: DirectXTex_GXDK_PC_2019.sln + vsVersion: 16.0 + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Release + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_PC_2019 scardbg + continueOnError: True + inputs: + solution: DirectXTex_GXDK_PC_2019.sln + vsVersion: 16.0 + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Debug_Scarlett + msbuildArchitecture: x64 + - task: VSBuild@1 + displayName: Build solution DirectXTex_GDK_PC_2019 scarrel + continueOnError: True + inputs: + solution: DirectXTex_GXDK_PC_2019.sln + vsVersion: 16.0 + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Release_Scarlett + msbuildArchitecture: x64 diff --git a/build/DirectXTex-GitHub-SDK-prerelease.yml b/build/DirectXTex-GitHub-SDK-prerelease.yml new file mode 100644 index 0000000..6475f59 --- /dev/null +++ b/build/DirectXTex-GitHub-SDK-prerelease.yml @@ -0,0 +1,247 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# +# http://go.microsoft.com/fwlink/?LinkId=248926 + +# Builds the library using the latest prerelease of the Windows SDK from nuget.org. + +schedules: +- cron: "0 3 * * 6" + displayName: 'Saturday night build' + branches: + include: + - main + always: true + +trigger: none +pr: none + +resources: + repositories: + - repository: self + type: git + ref: refs/heads/main + +name: $(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r) + +variables: + EXTRACTED_FOLDER: $(ExtractedFolder) + WSDKEnableBWOI: true + URL_FEED: $(ADOFeedURL) + +pool: + vmImage: windows-2019 + +jobs: +- job: DESKTOP_BUILD + displayName: 'Win32 Desktop' + timeoutInMinutes: 120 + cancelTimeoutInMinutes: 1 + steps: + - checkout: self + clean: true + fetchTags: false + - task: NuGetToolInstaller@1 + displayName: 'Use NuGet' + inputs: + versionSpec: '6.5.x' + - task: NuGetCommand@2 + # We have to use a nuget.config to provide the feed for the 'nuget install' option. + displayName: 'NuGet set package source to ADO feed' + inputs: + command: custom + arguments: sources add -Name xboxgdk-DirectXTex -Source $(URL_FEED) -ConfigFile $(Build.SourcesDirectory)\NuGet.config + - task: PowerShell@2 + displayName: 'Set nuget.config to single source' + inputs: + targetType: inline + script: | + $file = '.\NuGet.Config' + $doc = [xml](Get-Content $file) + $newelement = $doc.CreateElement("clear") + $clearadd = $doc.configuration.packageSources.PrependChild($newelement) + $doc.OuterXml | Set-Content $file + + - task: NuGetCommand@2 + displayName: NuGet Install WSDK x64 + inputs: + command: custom + arguments: install -prerelease Microsoft.Windows.SDK.CPP.x64 -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\SDK + - task: NuGetCommand@2 + displayName: NuGet Install WSDK x86 + inputs: + command: custom + arguments: install -prerelease Microsoft.Windows.SDK.CPP.x86 -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\SDK + - task: NuGetCommand@2 + displayName: NuGet Install WSDK arm64 + inputs: + command: custom + arguments: install -prerelease Microsoft.Windows.SDK.CPP.arm64 -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\SDK + - task: CopyFiles@2 + displayName: Set up Directory.Build.props + inputs: + SourceFolder: build + Contents: 'Directory.Build.props' + TargetFolder: $(Build.SourcesDirectory) + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019.sln 32dbg + inputs: + solution: DirectXTex_Desktop_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x86 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019.sln 32rel + inputs: + solution: DirectXTex_Desktop_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x86 + configuration: Release + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019.sln 64dbg + inputs: + solution: DirectXTex_Desktop_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019.sln 64rel + inputs: + solution: DirectXTex_Desktop_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Release + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019_Win10.sln 32dbg + inputs: + solution: DirectXTex_Desktop_2019_Win10.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x86 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019_Win10.sln 32rel + inputs: + solution: DirectXTex_Desktop_2019_Win10.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x86 + configuration: Release + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019_Win10.sln 64dbg + inputs: + solution: DirectXTex_Desktop_2019_Win10.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019_Win10.sln 64rel + inputs: + solution: DirectXTex_Desktop_2019_Win10.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Release + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019_Win10.sln arm64dbg + inputs: + solution: DirectXTex_Desktop_2019_Win10.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: ARM64 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019_Win10.sln arm64rel + inputs: + solution: DirectXTex_Desktop_2019_Win10.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: ARM64 + configuration: Release + +- job: UWP_BUILD + displayName: 'Universal Windows Platform (UWP)' + timeoutInMinutes: 120 + cancelTimeoutInMinutes: 1 + steps: + - checkout: self + clean: true + fetchTags: false + - task: NuGetToolInstaller@1 + displayName: 'Use NuGet' + inputs: + versionSpec: '6.5.x' + - task: NuGetCommand@2 + displayName: NuGet set package source to ADO feed + inputs: + command: custom + arguments: sources add -Name xboxgdk-DirectXTex -Source $(URL_FEED) -ConfigFile $(Build.SourcesDirectory)\NuGet.config + - task: PowerShell@2 + displayName: 'Set nuget.config to single source' + inputs: + targetType: inline + script: | + $file = '.\NuGet.Config' + $doc = [xml](Get-Content $file) + $newelement = $doc.CreateElement("clear") + $clearadd = $doc.configuration.packageSources.PrependChild($newelement) + $doc.OuterXml | Set-Content $file + + - task: NuGetCommand@2 + displayName: NuGet Install WSDK x64 + inputs: + command: custom + arguments: install -prerelease Microsoft.Windows.SDK.CPP.x64 -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\SDK + - task: NuGetCommand@2 + displayName: NuGet Install WSDK x86 + inputs: + command: custom + arguments: install -prerelease Microsoft.Windows.SDK.CPP.x86 -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\SDK + - task: NuGetCommand@2 + displayName: NuGet Install WSDK arm64 + inputs: + command: custom + arguments: install -prerelease Microsoft.Windows.SDK.CPP.arm64 -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\SDK + - task: CopyFiles@2 + displayName: Set up Directory.Build.props + inputs: + SourceFolder: build + Contents: 'Directory.Build.props' + TargetFolder: $(Build.SourcesDirectory) + - task: VSBuild@1 + displayName: Build solution DirectXTex_Windows10_2019.sln 32dbg + inputs: + solution: DirectXTex_Windows10_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x86 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Windows10_2019.sln 32rel + inputs: + solution: DirectXTex_Windows10_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x86 + configuration: Release + - task: VSBuild@1 + displayName: Build solution DirectXTex_Windows10_2019.sln 64dbg + inputs: + solution: DirectXTex_Windows10_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Windows10_2019.sln 64rel + inputs: + solution: DirectXTex_Windows10_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Release + - task: VSBuild@1 + displayName: Build solution DirectXTex_Windows10_2019.sln arm64dbg + inputs: + solution: DirectXTex_Windows10_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: ARM64 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Windows10_2019.sln arm64rel + inputs: + solution: DirectXTex_Windows10_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: ARM64 + configuration: Release diff --git a/build/DirectXTex-GitHub-SDK-release.yml b/build/DirectXTex-GitHub-SDK-release.yml new file mode 100644 index 0000000..1272921 --- /dev/null +++ b/build/DirectXTex-GitHub-SDK-release.yml @@ -0,0 +1,247 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# +# http://go.microsoft.com/fwlink/?LinkId=248926 + +# Builds the library using the latest release of the Windows SDK from nuget.org. + +schedules: +- cron: "0 3 * * 0" + displayName: 'Sunday night build' + branches: + include: + - main + always: true + +trigger: none +pr: none + +resources: + repositories: + - repository: self + type: git + ref: refs/heads/main + +name: $(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r) + +variables: + EXTRACTED_FOLDER: $(ExtractedFolder) + WSDKEnableBWOI: true + URL_FEED: $(ADOFeedURL) + +pool: + vmImage: windows-2019 + +jobs: +- job: DESKTOP_BUILD + displayName: 'Win32 Desktop' + timeoutInMinutes: 120 + cancelTimeoutInMinutes: 1 + steps: + - checkout: self + clean: true + fetchTags: false + - task: NuGetToolInstaller@1 + displayName: 'Use NuGet' + inputs: + versionSpec: '6.5.x' + - task: NuGetCommand@2 + # We have to use a nuget.config to provide the feed for the 'nuget install' option. + displayName: 'NuGet set package source to ADO feed' + inputs: + command: custom + arguments: sources add -Name xboxgdk-DirectXTex -Source $(URL_FEED) -ConfigFile $(Build.SourcesDirectory)\NuGet.config + - task: PowerShell@2 + displayName: 'Set nuget.config to single source' + inputs: + targetType: inline + script: | + $file = '.\NuGet.Config' + $doc = [xml](Get-Content $file) + $newelement = $doc.CreateElement("clear") + $clearadd = $doc.configuration.packageSources.PrependChild($newelement) + $doc.OuterXml | Set-Content $file + + - task: NuGetCommand@2 + displayName: NuGet Install WSDK x64 + inputs: + command: custom + arguments: install Microsoft.Windows.SDK.CPP.x64 -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\SDK + - task: NuGetCommand@2 + displayName: NuGet Install WSDK x86 + inputs: + command: custom + arguments: install Microsoft.Windows.SDK.CPP.x86 -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\SDK + - task: NuGetCommand@2 + displayName: NuGet Install WSDK arm64 + inputs: + command: custom + arguments: install Microsoft.Windows.SDK.CPP.arm64 -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\SDK + - task: CopyFiles@2 + displayName: Set up Directory.Build.props + inputs: + SourceFolder: build + Contents: 'Directory.Build.props' + TargetFolder: $(Build.SourcesDirectory) + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019.sln 32dbg + inputs: + solution: DirectXTex_Desktop_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x86 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019.sln 32rel + inputs: + solution: DirectXTex_Desktop_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x86 + configuration: Release + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019.sln 64dbg + inputs: + solution: DirectXTex_Desktop_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019.sln 64rel + inputs: + solution: DirectXTex_Desktop_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Release + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019_Win10.sln 32dbg + inputs: + solution: DirectXTex_Desktop_2019_Win10.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x86 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019_Win10.sln 32rel + inputs: + solution: DirectXTex_Desktop_2019_Win10.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x86 + configuration: Release + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019_Win10.sln 64dbg + inputs: + solution: DirectXTex_Desktop_2019_Win10.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019_Win10.sln 64rel + inputs: + solution: DirectXTex_Desktop_2019_Win10.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Release + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019_Win10.sln arm64dbg + inputs: + solution: DirectXTex_Desktop_2019_Win10.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: ARM64 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Desktop_2019_Win10.sln arm64rel + inputs: + solution: DirectXTex_Desktop_2019_Win10.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: ARM64 + configuration: Release + +- job: UWP_BUILD + displayName: 'Universal Windows Platform (UWP)' + timeoutInMinutes: 120 + cancelTimeoutInMinutes: 1 + steps: + - checkout: self + clean: true + fetchTags: false + - task: NuGetToolInstaller@1 + displayName: 'Use NuGet' + inputs: + versionSpec: '6.5.x' + - task: NuGetCommand@2 + displayName: NuGet set package source to ADO feed + inputs: + command: custom + arguments: sources add -Name xboxgdk-DirectXTex -Source $(URL_FEED) -ConfigFile $(Build.SourcesDirectory)\NuGet.config + - task: PowerShell@2 + displayName: 'Set nuget.config to single source' + inputs: + targetType: inline + script: | + $file = '.\NuGet.Config' + $doc = [xml](Get-Content $file) + $newelement = $doc.CreateElement("clear") + $clearadd = $doc.configuration.packageSources.PrependChild($newelement) + $doc.OuterXml | Set-Content $file + + - task: NuGetCommand@2 + displayName: NuGet Install WSDK x64 + inputs: + command: custom + arguments: install Microsoft.Windows.SDK.CPP.x64 -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\SDK + - task: NuGetCommand@2 + displayName: NuGet Install WSDK x86 + inputs: + command: custom + arguments: install Microsoft.Windows.SDK.CPP.x86 -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\SDK + - task: NuGetCommand@2 + displayName: NuGet Install WSDK arm64 + inputs: + command: custom + arguments: install Microsoft.Windows.SDK.CPP.arm64 -ExcludeVersion -OutputDirectory $(EXTRACTED_FOLDER)\SDK + - task: CopyFiles@2 + displayName: Set up Directory.Build.props + inputs: + SourceFolder: build + Contents: 'Directory.Build.props' + TargetFolder: $(Build.SourcesDirectory) + - task: VSBuild@1 + displayName: Build solution DirectXTex_Windows10_2019.sln 32dbg + inputs: + solution: DirectXTex_Windows10_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x86 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Windows10_2019.sln 32rel + inputs: + solution: DirectXTex_Windows10_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x86 + configuration: Release + - task: VSBuild@1 + displayName: Build solution DirectXTex_Windows10_2019.sln 64dbg + inputs: + solution: DirectXTex_Windows10_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Windows10_2019.sln 64rel + inputs: + solution: DirectXTex_Windows10_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: x64 + configuration: Release + - task: VSBuild@1 + displayName: Build solution DirectXTex_Windows10_2019.sln arm64dbg + inputs: + solution: DirectXTex_Windows10_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: ARM64 + configuration: Debug + - task: VSBuild@1 + displayName: Build solution DirectXTex_Windows10_2019.sln arm64rel + inputs: + solution: DirectXTex_Windows10_2019.sln + msbuildArgs: /p:PreferredToolArchitecture=x64 + platform: ARM64 + configuration: Release diff --git a/build/Directory.Build.props b/build/Directory.Build.props new file mode 100644 index 0000000..a8c567c --- /dev/null +++ b/build/Directory.Build.props @@ -0,0 +1,87 @@ + + + + + C:\xtracted\ + $(ExtractedFolder)\ + + <_AlternativeVCTargetsPath170>$(ExtractedFolder)VCTargets170\ + <_AlternativeVCTargetsPath160>$(ExtractedFolder)VCTargets160\ + <_AlternativeVCTargetsPath150>$(ExtractedFolder)VCTargets150\ + + + 15.0 + + + + + + + + + + + + + + + + + + + $(_AlternativeVCTargetsPath160) + true + $(_AlternativeVCTargetsPath150) + $(_AlternativeVCTargetsPath160) + + + + $(_AlternativeVCTargetsPath160) + true + $(_AlternativeVCTargetsPath150) + $(_AlternativeVCTargetsPath160) + + + + $(_AlternativeVCTargetsPath160) + true + $(_AlternativeVCTargetsPath150) + $(_AlternativeVCTargetsPath160) + + + + + true + $(_AlternativeVCTargetsPath150) + $(_AlternativeVCTargetsPath160) + $(_AlternativeVCTargetsPath170) + + + + true + $(_AlternativeVCTargetsPath150) + $(_AlternativeVCTargetsPath160) + $(_AlternativeVCTargetsPath170) + + + + true + $(_AlternativeVCTargetsPath150) + $(_AlternativeVCTargetsPath160) + $(_AlternativeVCTargetsPath170) + + \ No newline at end of file diff --git a/build/SetupBWOI.targets b/build/SetupBWOI.targets new file mode 100644 index 0000000..501a4fa --- /dev/null +++ b/build/SetupBWOI.targets @@ -0,0 +1,138 @@ + + + + + C:\xtracted\ + $(ExtractedFolder)\ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_BWOIFolder>%(BWOIVCFolders.Identity) + + + + <_MissingBWOIVCFolders Condition="'$(ForceVCTargetsBWOIRefresh)'=='true' or !Exists($(_BWOIFolder))" Include="$(_BWOIFolder)" /> + + + + <_ExtractedOutOfDate Condition="'@(_MissingBWOIVCFolders)' != ''">true + <_BWOIFolder /> + + + + + + + + + + <_VSFolder Condition="'$(VisualStudioVersion)' == '17.0'">VS2022 + <_VSFolder Condition="'$(VisualStudioVersion)' == '16.0'">VS2019 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +