diff --git a/Kits/ATGTK/ControllerHelp.cpp b/Kits/ATGTK/ControllerHelp.cpp index a2df47c3..bf1e4f7a 100644 --- a/Kits/ATGTK/ControllerHelp.cpp +++ b/Kits/ATGTK/ControllerHelp.cpp @@ -13,6 +13,7 @@ #include "ControllerHelp.h" #include "DDSTextureLoader.h" #include "SimpleMath.h" +#include "DirectXHelpers.h" #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) #include "FindMedia.h" @@ -645,7 +646,7 @@ ATG::Help::Help(const wchar_t* title, const wchar_t* description, const HelpButt ++m_calloutCount; } - bool dpadLabels = true; + bool dpadLabels = false; float dpadYOffset[4] = {0.f, 0.f, 0.f, 0.f}; static const float c_fontSize18 = 31.9218750f; @@ -878,6 +879,8 @@ void ATG::Help::RestoreDevice(ID3D12Device* device, ResourceUploadBatch& uploadB CommonStates::DepthNone, CommonStates::CullNone, rtState, D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE); m_lineEffect = std::make_unique(device, EffectFlags::VertexColor, fxPsoDesc); + unsigned int loadFlags = m_linearColors ? DDS_LOADER_FORCE_SRGB : DDS_LOADER_DEFAULT; + #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) wchar_t buff[MAX_PATH]; DX::FindMediaFile(buff, MAX_PATH, L"Media//Fonts//SegoeUI_18.spritefont"); @@ -890,21 +893,21 @@ void ATG::Help::RestoreDevice(ID3D12Device* device, ResourceUploadBatch& uploadB m_spriteFonts[SEGOE_UI_36PT] = std::make_unique(device, uploadBatch, buff, m_descriptorHeap->GetCpuHandle(Descriptors::Segoe36), m_descriptorHeap->GetGpuHandle(Descriptors::Segoe36)); DX::FindMediaFile(buff, MAX_PATH, L"Media//Textures//callout_circle.dds"); - DX::ThrowIfFailed(CreateDDSTextureFromFileEx(device, uploadBatch, buff, 0, D3D12_RESOURCE_FLAG_NONE, m_linearColors, false, m_circleTex.ReleaseAndGetAddressOf())); + DX::ThrowIfFailed(CreateDDSTextureFromFileEx(device, uploadBatch, buff, 0, D3D12_RESOURCE_FLAG_NONE, loadFlags, m_circleTex.ReleaseAndGetAddressOf())); DX::FindMediaFile(buff, MAX_PATH, L"Media//Textures//gamepad.dds"); - DX::ThrowIfFailed(CreateDDSTextureFromFileEx(device, uploadBatch, buff, 0, D3D12_RESOURCE_FLAG_NONE, m_linearColors, false, m_gamepadTex.ReleaseAndGetAddressOf())); + DX::ThrowIfFailed(CreateDDSTextureFromFileEx(device, uploadBatch, buff, 0, D3D12_RESOURCE_FLAG_NONE, loadFlags, m_gamepadTex.ReleaseAndGetAddressOf())); DX::FindMediaFile(buff, MAX_PATH, L"Media//Textures//ATGSampleBackground.DDS"); - DX::ThrowIfFailed(CreateDDSTextureFromFileEx(device, uploadBatch, buff, 0, D3D12_RESOURCE_FLAG_NONE, m_linearColors, false, m_backgroundTex.ReleaseAndGetAddressOf())); + DX::ThrowIfFailed(CreateDDSTextureFromFileEx(device, uploadBatch, buff, 0, D3D12_RESOURCE_FLAG_NONE, loadFlags, m_backgroundTex.ReleaseAndGetAddressOf())); #else m_spriteFonts[SEGOE_UI_18PT] = std::make_unique(device, uploadBatch, L"SegoeUI_18.spritefont", m_descriptorHeap->GetCpuHandle(Descriptors::Segoe18), m_descriptorHeap->GetGpuHandle(Descriptors::Segoe18)); m_spriteFonts[SEGOE_UI_22PT] = std::make_unique(device, uploadBatch, L"SegoeUI_22.spritefont", m_descriptorHeap->GetCpuHandle(Descriptors::Segoe22), m_descriptorHeap->GetGpuHandle(Descriptors::Segoe22)); m_spriteFonts[SEGOE_UI_36PT] = std::make_unique(device, uploadBatch, L"SegoeUI_36.spritefont", m_descriptorHeap->GetCpuHandle(Descriptors::Segoe36), m_descriptorHeap->GetGpuHandle(Descriptors::Segoe36)); - DX::ThrowIfFailed(CreateDDSTextureFromFileEx(device, uploadBatch, L"callout_circle.dds", 0, D3D12_RESOURCE_FLAG_NONE, m_linearColors, false, m_circleTex.ReleaseAndGetAddressOf())); - DX::ThrowIfFailed(CreateDDSTextureFromFileEx(device, uploadBatch, L"gamepad.dds", 0, D3D12_RESOURCE_FLAG_NONE, m_linearColors, false, m_gamepadTex.ReleaseAndGetAddressOf())); - DX::ThrowIfFailed(CreateDDSTextureFromFileEx(device, uploadBatch, L"ATGSampleBackground.DDS", 0, D3D12_RESOURCE_FLAG_NONE, m_linearColors, false, m_backgroundTex.ReleaseAndGetAddressOf())); + DX::ThrowIfFailed(CreateDDSTextureFromFileEx(device, uploadBatch, L"callout_circle.dds", 0, D3D12_RESOURCE_FLAG_NONE, loadFlags, m_circleTex.ReleaseAndGetAddressOf())); + DX::ThrowIfFailed(CreateDDSTextureFromFileEx(device, uploadBatch, L"gamepad.dds", 0, D3D12_RESOURCE_FLAG_NONE, loadFlags, m_gamepadTex.ReleaseAndGetAddressOf())); + DX::ThrowIfFailed(CreateDDSTextureFromFileEx(device, uploadBatch, L"ATGSampleBackground.DDS", 0, D3D12_RESOURCE_FLAG_NONE, loadFlags, m_backgroundTex.ReleaseAndGetAddressOf())); #endif DirectX::CreateShaderResourceView(device, m_circleTex.Get(), m_descriptorHeap->GetCpuHandle(Descriptors::CircleTex), false); diff --git a/Kits/ATGTK/PBREffect/PBREffect.cpp b/Kits/ATGTK/PBREffect/PBREffect.cpp new file mode 100644 index 00000000..fe301168 --- /dev/null +++ b/Kits/ATGTK/PBREffect/PBREffect.cpp @@ -0,0 +1,459 @@ +//-------------------------------------------------------------------------------------- +// PBREffect.cpp +// +// A physically based shader for forward rendering on DirectX 12. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "pch.h" +#include "PBREffect.h" +#include <..\Src\EffectCommon.h> + +using namespace DirectX; +using namespace ATG; + +// Include the precompiled shader code. +namespace +{ +#if defined(_XBOX_ONE) && defined(_TITLE) +#include "Compiled/XboxOnePBREffect_VSConstant.inc" + +#include "Compiled/XboxOnePBREffect_PSConstant.inc" +#include "Compiled/XboxOnePBREffect_PSTextured.inc" + +#else +#include "Compiled/PBREffect_VSConstant.inc" + +#include "Compiled/PBREffect_PSConstant.inc" +#include "Compiled/PBREffect_PSTextured.inc" +#endif +} + +// Constant buffer layout. Must match the shader! +struct PBREffectConstants +{ + XMVECTOR eyePosition; + XMMATRIX world; + XMVECTOR worldInverseTranspose[3]; + XMMATRIX worldViewProj; + + XMVECTOR lightDirection[IEffectLights::MaxDirectionalLights]; + XMVECTOR lightDiffuseColor[IEffectLights::MaxDirectionalLights]; + + // New PBR Parameters + XMVECTOR Albedo; + float Metallic; + float Roughness; + + int numRadianceMipLevels; +}; + +static_assert( ( sizeof(PBREffectConstants) % 16 ) == 0, "CB size not padded correctly" ); + + +// Traits type describes our characteristics to the EffectBase template. +struct PBREffectTraits +{ + typedef PBREffectConstants ConstantBufferType; + + static const int VertexShaderCount = 1; + static const int PixelShaderCount = 2; + static const int ShaderPermutationCount = 2; + static const int RootSignatureCount = 1; +}; + + +// Internal PBREffect implementation class. +class ATG::PBREffect::Impl : public EffectBase +{ +public: + Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription); + void Apply(_In_ ID3D12GraphicsCommandList* commandList); + + int GetPipelineStatePermutation(bool textureEnabled) const; + + static const int MaxDirectionalLights = 3; + + int flags; + + enum RootParameterIndex + { + AlbedoTexture, + NormalTexture, + RMATexture, + RadianceTexture, + IrradianceTexture, + SurfaceSampler, + RadianceSampler, + ConstantBuffer, + RootParametersCount + }; + + D3D12_GPU_DESCRIPTOR_HANDLE descriptors[RootParametersCount]; +}; + + +const D3D12_SHADER_BYTECODE EffectBase::VertexShaderBytecode[] = +{ + { PBREffect_VSConstant, sizeof(PBREffect_VSConstant) }, + +}; + + +const int EffectBase::VertexShaderIndices[] = +{ + 0, // basic + 0, // textured +}; + + +const D3D12_SHADER_BYTECODE EffectBase::PixelShaderBytecode[] = +{ + { PBREffect_PSConstant, sizeof(PBREffect_PSConstant) }, + { PBREffect_PSTextured, sizeof(PBREffect_PSTextured) }, +}; + + +const int EffectBase::PixelShaderIndices[] = +{ + 0, // basic + 1, // textured +}; + +// Global pool of per-device PBREffect resources. Required by EffectBase<>, but not used. +SharedResourcePool::DeviceResources> EffectBase::deviceResourcesPool; + +// Constructor. +PBREffect::Impl::Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription) + : EffectBase(device), + flags(effectFlags), + descriptors{} +{ + static_assert( _countof(EffectBase::VertexShaderIndices) == PBREffectTraits::ShaderPermutationCount, "array/max mismatch" ); + static_assert( _countof(EffectBase::VertexShaderBytecode) == PBREffectTraits::VertexShaderCount, "array/max mismatch" ); + static_assert( _countof(EffectBase::PixelShaderBytecode) == PBREffectTraits::PixelShaderCount, "array/max mismatch" ); + static_assert( _countof(EffectBase::PixelShaderIndices) == PBREffectTraits::ShaderPermutationCount, "array/max mismatch" ); + + // Lighting + static const XMVECTORF32 defaultLightDirection = { 0, -1, 0, 0 }; + for (int i = 0; i < MaxDirectionalLights; i++) + { + constants.lightDirection[i] = defaultLightDirection; + constants.lightDiffuseColor[i] = g_XMZero; + } + + // Default PBR values + constants.Albedo = XMVectorSet(1, 1, 1, 1); + constants.Metallic = 0.5f; + constants.Roughness = 0.2f; + constants.numRadianceMipLevels = 1; + + // Create root signature + D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags = + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | // Only the input assembler stage needs access to the constant buffer. + D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS; + + CD3DX12_ROOT_PARAMETER rootParameters[RootParametersCount]; + CD3DX12_DESCRIPTOR_RANGE textureSRV[5] = { + CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0), + CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 1), + CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 2), + CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 3), + CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 4), + }; + + CD3DX12_DESCRIPTOR_RANGE textureSampler[2] = { + CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0), + CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 1) + }; + + for (int i = 0; i < _countof(textureSRV); i++) + { + rootParameters[i].InitAsDescriptorTable(1, &textureSRV[i]); + } + + for (int i = 0; i < _countof(textureSampler); i++) + { + rootParameters[i + SurfaceSampler].InitAsDescriptorTable(1, &textureSampler[i]); + } + + rootParameters[ConstantBuffer].InitAsConstantBufferView(0, 0, D3D12_SHADER_VISIBILITY_ALL); + + CD3DX12_ROOT_SIGNATURE_DESC rsigDesc; + rsigDesc.Init(_countof(rootParameters), rootParameters, 0, nullptr, rootSignatureFlags); + + mRootSignature = GetRootSignature(0, rsigDesc); + + // Create pipeline state + int sp = GetPipelineStatePermutation((effectFlags & EffectFlags::Texture) != 0); + int vi = EffectBase::VertexShaderIndices[sp]; + int pi = EffectBase::PixelShaderIndices[sp]; + + pipelineDescription.CreatePipelineState( + device, + mRootSignature, + EffectBase::VertexShaderBytecode[vi], + EffectBase::PixelShaderBytecode[pi], + mPipelineState.ReleaseAndGetAddressOf()); +} + + +int PBREffect::Impl::GetPipelineStatePermutation(bool textureEnabled) const +{ + int permutation = 0; + + if (textureEnabled) permutation += 1; + + return permutation; +} + + +// Sets our state onto the D3D device. +void PBREffect::Impl::Apply(_In_ ID3D12GraphicsCommandList* commandList) +{ + // Compute derived parameter values. + matrices.SetConstants(dirtyFlags, constants.worldViewProj); + + // World inverse transpose matrix. + if (dirtyFlags & EffectDirtyFlags::WorldInverseTranspose) + { + constants.world = XMMatrixTranspose(matrices.world); + + XMMATRIX worldInverse = XMMatrixInverse(nullptr, matrices.world); + + constants.worldInverseTranspose[0] = worldInverse.r[0]; + constants.worldInverseTranspose[1] = worldInverse.r[1]; + constants.worldInverseTranspose[2] = worldInverse.r[2]; + + dirtyFlags &= ~EffectDirtyFlags::WorldInverseTranspose; + dirtyFlags |= EffectDirtyFlags::ConstantBuffer; + } + + // Eye position vector. + if (dirtyFlags & EffectDirtyFlags::EyePosition) + { + XMMATRIX viewInverse = XMMatrixInverse(nullptr, matrices.view); + + constants.eyePosition = viewInverse.r[3]; + + dirtyFlags &= ~EffectDirtyFlags::EyePosition; + dirtyFlags |= EffectDirtyFlags::ConstantBuffer; + } + + // Set constants to GPU + UpdateConstants(); + + // Set the root signature + commandList->SetGraphicsRootSignature(mRootSignature); + + // Set the root parameters + if ((flags & EffectFlags::Texture) == 0) + { + // only update radiance texture and samples + commandList->SetGraphicsRootDescriptorTable(RadianceTexture, descriptors[RadianceTexture]); + commandList->SetGraphicsRootDescriptorTable(IrradianceTexture, descriptors[IrradianceTexture]); + commandList->SetGraphicsRootDescriptorTable(RadianceSampler, descriptors[RadianceSampler]); + } + else + { + // Update everything + for (int i = 0; i < ConstantBuffer; i++) + { + commandList->SetGraphicsRootDescriptorTable(i, descriptors[i]); + } + } + + // Set constants + commandList->SetGraphicsRootConstantBufferView(ConstantBuffer, GetConstantBufferGpuAddress()); + + // Set the pipeline state + commandList->SetPipelineState(EffectBase::mPipelineState.Get()); +} + +// Public constructor. +PBREffect::PBREffect(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription) + : pImpl(new Impl(device, effectFlags, pipelineDescription)) +{ +} + + +// Move constructor. +PBREffect::PBREffect(PBREffect&& moveFrom) + : pImpl(std::move(moveFrom.pImpl)) +{ +} + + +// Move assignment. +PBREffect& PBREffect::operator= (PBREffect&& moveFrom) +{ + pImpl = std::move(moveFrom.pImpl); + return *this; +} + + +// Public destructor. +PBREffect::~PBREffect() +{ +} + +// IEffect methods. +void PBREffect::Apply(_In_ ID3D12GraphicsCommandList* commandList) +{ + pImpl->Apply(commandList); +} + +// Camera settings. +void XM_CALLCONV PBREffect::SetWorld(FXMMATRIX value) +{ + pImpl->matrices.world = value; + + pImpl->dirtyFlags |= EffectDirtyFlags::WorldViewProj | EffectDirtyFlags::WorldInverseTranspose | EffectDirtyFlags::FogVector; +} + + +void XM_CALLCONV PBREffect::SetView(FXMMATRIX value) +{ + pImpl->matrices.view = value; + + pImpl->dirtyFlags |= EffectDirtyFlags::WorldViewProj | EffectDirtyFlags::EyePosition | EffectDirtyFlags::FogVector; +} + + +void XM_CALLCONV PBREffect::SetProjection(FXMMATRIX value) +{ + pImpl->matrices.projection = value; + + pImpl->dirtyFlags |= EffectDirtyFlags::WorldViewProj; +} + + +void XM_CALLCONV PBREffect::SetMatrices(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection) +{ + pImpl->matrices.world = world; + pImpl->matrices.view = view; + pImpl->matrices.projection = projection; + + pImpl->dirtyFlags |= EffectDirtyFlags::WorldViewProj | EffectDirtyFlags::WorldInverseTranspose | EffectDirtyFlags::EyePosition | EffectDirtyFlags::FogVector; +} + +void XM_CALLCONV PBREffect::SetLightDirection(int whichLight, FXMVECTOR value) +{ + pImpl->constants.lightDirection[whichLight] = value; + + pImpl->dirtyFlags |= EffectDirtyFlags::ConstantBuffer; +} + + +void XM_CALLCONV PBREffect::SetLightColorAndIntensity(int whichLight, FXMVECTOR value) +{ + pImpl->constants.lightDiffuseColor[whichLight] = value; + + pImpl->dirtyFlags |= EffectDirtyFlags::ConstantBuffer; +} + + +void PBREffect::EnableDefaultLighting() +{ + static const XMVECTORF32 defaultDirections[Impl::MaxDirectionalLights] = + { + { -0.5265408f, -0.5735765f, -0.6275069f }, + { 0.7198464f, 0.3420201f, 0.6040227f }, + { 0.4545195f, -0.7660444f, 0.4545195f }, + }; + + static const XMVECTORF32 defaultDiffuse[Impl::MaxDirectionalLights] = + { + { 1.0000000f, 0.9607844f, 0.8078432f }, + { 0.9647059f, 0.7607844f, 0.4078432f }, + { 0.3231373f, 0.3607844f, 0.3937255f }, + }; + + for (int i = 0; i < Impl::MaxDirectionalLights; i++) + { + SetLightDirection(i, defaultDirections[i]); + SetLightColorAndIntensity(i, defaultDiffuse[i]); + } +} + + +// PBR Settings +void PBREffect::SetConstantAlbedo(FXMVECTOR value) +{ + pImpl->constants.Albedo = value; + + pImpl->dirtyFlags |= EffectDirtyFlags::ConstantBuffer; +} + +void PBREffect::SetConstantMetallic(float value) +{ + pImpl->constants.Metallic = value; + + pImpl->dirtyFlags |= EffectDirtyFlags::ConstantBuffer; +} + +void PBREffect::SetConstantRoughness(float value) +{ + pImpl->constants.Roughness = value; + + pImpl->dirtyFlags |= EffectDirtyFlags::ConstantBuffer; +} + +#ifdef DEBUG +void PBREffect::SetDebugFlags(bool diffuse, bool D, bool F, bool G) +{ + pImpl->constants.enable_Diffuse = diffuse; + pImpl->constants.enable_Specular_D = D; + pImpl->constants.enable_Specular_F = F; + pImpl->constants.enable_Specular_G = G; + + pImpl->dirtyFlags |= EffectDirtyFlags::ConstantBuffer; +} +#endif + +void PBREffect::SetSurfaceTextures(_In_ D3D12_GPU_DESCRIPTOR_HANDLE albedo, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE normal, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE RMA, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE sampler) +{ + pImpl->descriptors[Impl::RootParameterIndex::AlbedoTexture] = albedo; + pImpl->descriptors[Impl::RootParameterIndex::NormalTexture] = normal; + pImpl->descriptors[Impl::RootParameterIndex::RMATexture] = RMA; + pImpl->descriptors[Impl::RootParameterIndex::SurfaceSampler] = sampler; +} + +void PBREffect::SetIBLTextures(_In_ D3D12_GPU_DESCRIPTOR_HANDLE radiance, + int numRadianceMips, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE irradiance, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE sampler) +{ + pImpl->descriptors[Impl::RootParameterIndex::RadianceTexture] = radiance; + pImpl->descriptors[Impl::RootParameterIndex::RadianceSampler] = sampler; + pImpl->constants.numRadianceMipLevels = numRadianceMips; + + pImpl->descriptors[Impl::RootParameterIndex::IrradianceTexture] = irradiance; + + pImpl->dirtyFlags |= EffectDirtyFlags::ConstantBuffer; +} + +//-------------------------------------------------------------------------------------- +// PBR +const D3D12_INPUT_ELEMENT_DESC VertexPositionNormalTextureTangent::InputElements[] = +{ + { "SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, +}; + +static_assert(sizeof(VertexPositionNormalTextureTangent) == 48, "Vertex struct/layout mismatch"); + +const D3D12_INPUT_LAYOUT_DESC VertexPositionNormalTextureTangent::InputLayout = +{ + VertexPositionNormalTextureTangent::InputElements, + VertexPositionNormalTextureTangent::InputElementCount +}; \ No newline at end of file diff --git a/Kits/ATGTK/PBREffect/PBREffect.h b/Kits/ATGTK/PBREffect/PBREffect.h new file mode 100644 index 00000000..4bcf7c89 --- /dev/null +++ b/Kits/ATGTK/PBREffect/PBREffect.h @@ -0,0 +1,110 @@ +//-------------------------------------------------------------------------------------- +// PBREffect.h +// +// A physically based shader for forward rendering on DirectX 12. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#pragma once + +#include + +namespace ATG +{ + class PBREffect : public DirectX::IEffect + { + public: + explicit PBREffect(_In_ ID3D12Device* device, int effectFlags, + const DirectX::EffectPipelineStateDescription& pipelineDescription); + PBREffect(PBREffect&& moveFrom); + PBREffect& operator= (PBREffect&& moveFrom); + + PBREffect(PBREffect const&) = delete; + PBREffect& operator= (PBREffect const&) = delete; + + virtual ~PBREffect(); + + // IEffect methods. + void __cdecl Apply(_In_ ID3D12GraphicsCommandList* commandList) override; + + // Camera settings. + void XM_CALLCONV SetWorld(DirectX::FXMMATRIX value); + void XM_CALLCONV SetView(DirectX::FXMMATRIX value); + void XM_CALLCONV SetProjection(DirectX::FXMMATRIX value); + void XM_CALLCONV SetMatrices(DirectX::FXMMATRIX world, DirectX::CXMMATRIX view, DirectX::CXMMATRIX projection); + + // Light settings. + void __cdecl SetLightEnabled(int whichLight, bool value); + void XM_CALLCONV SetLightDirection(int whichLight, DirectX::FXMVECTOR value); + void XM_CALLCONV SetLightColorAndIntensity(int whichLight, DirectX::FXMVECTOR value); + + // Set up a default light rig + void __cdecl EnableDefaultLighting(); + + // PBR Settings + void XM_CALLCONV SetConstantAlbedo(DirectX::FXMVECTOR value); + void __cdecl SetConstantMetallic(float value); + void __cdecl SetConstantRoughness(float value); +#ifdef DEBUG + void __cdecl SetDebugFlags(bool diffuse, bool D, bool F, bool G); +#endif + // Texture settings. + void __cdecl SetSurfaceTextures( + _In_ D3D12_GPU_DESCRIPTOR_HANDLE albedo, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE normal, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE RoughnessMetallicAmbientOcclusion, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE sampler); + + void __cdecl SetIBLTextures( + _In_ D3D12_GPU_DESCRIPTOR_HANDLE radiance, + int numRadianceMips, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE irradiance, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE sampler); + + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; + + // For PBR effects + struct VertexPositionNormalTextureTangent + { + VertexPositionNormalTextureTangent() = default; + + DirectX::XMFLOAT3 position; + DirectX::XMFLOAT3 normal; + DirectX::XMFLOAT2 textureCoordinate; + DirectX::XMFLOAT4 tangent; + + VertexPositionNormalTextureTangent(DirectX::XMFLOAT3 const& position, + DirectX::XMFLOAT3 const& normal, + DirectX::XMFLOAT2 const& textureCoordinate, + DirectX::XMFLOAT4 const& tangent) + : position(position), + normal(normal), + textureCoordinate(textureCoordinate), + tangent(tangent) + { + } + + VertexPositionNormalTextureTangent(DirectX::FXMVECTOR position, + DirectX::FXMVECTOR normal, + DirectX::CXMVECTOR textureCoordinate, + DirectX::FXMVECTOR tangent) + { + XMStoreFloat3(&this->position, position); + XMStoreFloat3(&this->normal, normal); + XMStoreFloat2(&this->textureCoordinate, textureCoordinate); + XMStoreFloat4(&this->tangent, tangent); + } + + static const D3D12_INPUT_LAYOUT_DESC InputLayout; + + private: + static const int InputElementCount = 4; + static const D3D12_INPUT_ELEMENT_DESC InputElements[InputElementCount]; + }; +} \ No newline at end of file diff --git a/Kits/ATGTK/PBREffect/PBREffect_Common.hlsli b/Kits/ATGTK/PBREffect/PBREffect_Common.hlsli new file mode 100644 index 00000000..05fd77b5 --- /dev/null +++ b/Kits/ATGTK/PBREffect/PBREffect_Common.hlsli @@ -0,0 +1,165 @@ +//-------------------------------------------------------------------------------------- +// PBREffect_Header.hslsi +// +// A physically based shader for forward rendering on DirectX 12. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#ifndef __PBREFFECT_HEADER_HLSLI__ +#define __PBREFFECT_HEADER_HLSLI__ + +#define PBREffectRS \ +"RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ +" DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ +" DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ +" DENY_HULL_SHADER_ROOT_ACCESS )," \ +"DescriptorTable ( SRV(t0) ),"\ +"DescriptorTable ( SRV(t1) ),"\ +"DescriptorTable ( SRV(t2) ),"\ +"DescriptorTable ( SRV(t3) ),"\ +"DescriptorTable ( SRV(t4) ),"\ +"DescriptorTable ( Sampler(s0) ),"\ +"DescriptorTable ( Sampler(s1) ),"\ +"CBV(b0)" + +Texture2D PBR_AlbedoTexture : register(t0); +Texture2D PBR_NormalTexture : register(t1); +Texture2D PBR_RMATexture : register(t2); +Texture2D PBR_RadianceTexture : register(t3); +Texture2D PBR_IrradianceTexture : register(t4); + +sampler PBR_SurfaceSampler : register(s0); +sampler PBR_IBLSampler : register(s1); + +cbuffer PBR_Constants : register(b0) +{ + float3 PBR_EyePosition : packoffset(c0); + float4x4 PBR_World : packoffset(c1); + float3x3 PBR_WorldInverseTranspose : packoffset(c5); + float4x4 PBR_WorldViewProj : packoffset(c8); + + float3 PBR_LightDirection[3] : packoffset(c12); + float3 PBR_LightColor[3] : packoffset(c15); // "Specular and diffuse light" in PBR + + float3 PBR_ConstantAlbedo : packoffset(c18); // Constant values if not a textured effect + float PBR_ConstantMetallic : packoffset(c19.x); + float PBR_ConstantRoughness : packoffset(c19.y); + + int PBR_NumRadianceMipLevels : packoffset(c19.z); +}; + +// Vertex formats +struct VSInputNmTxTangent +{ + float4 Position : SV_Position; + float3 Normal : NORMAL; + float4 Tangent : TANGENT; + float2 TexCoord : TEXCOORD0; +}; + +struct VSOutputPixelLightingTxTangent +{ + float2 TexCoord : TEXCOORD0; + float4 PositionWS : TEXCOORD1; + float3 NormalWS : TEXCOORD2; + float3 TangentWS : TEXCOORD3; + float4 Diffuse : COLOR0; + float4 PositionPS : SV_Position; +}; + +struct PSInputPixelLightingTxTangent +{ + float2 TexCoord : TEXCOORD0; + float4 PositionWS : TEXCOORD1; + float3 NormalWS : TEXCOORD2; + float3 TangentWS : TEXCOORD3; + float4 Diffuse : COLOR0; +}; + +// Common vertex shader code +struct CommonVSOutputPixelLighting +{ + float4 Pos_ps; + float3 Pos_ws; + float3 Normal_ws; +}; + +CommonVSOutputPixelLighting ComputeCommonVSOutputPixelLighting(float4 position, float3 normal, float4x4 world, float4x4 worldViewProj, float3x3 worldInverseT) +{ + CommonVSOutputPixelLighting vout; + + vout.Pos_ps = mul(position, worldViewProj); + vout.Pos_ws = mul(position, world).xyz; + vout.Normal_ws = normalize(mul(normal, worldInverseT)); + + return vout; +} + +// Common math code +#include "PBREffect_Math.hlsli" + +// Apply Disney-style physically based rendering to a surface with: +// +// V, N: Eye and surface normals +// +// numLights: Number of directional lights. +// +// lightColor[]: Color and intensity of directional light. +// +// lightDirection[]: Light direction. +float3 PBR_LightSurface( + in float3 V, in float3 N, + in int numLights, in float3 lightColor[3], in float3 lightDirection[3], + in float3 albedo, in float roughness, in float metallic, in float ambientOcclusion) +{ + // Specular coefficiant - fixed reflectance value for non-metals + static const float kSpecularCoefficient = 0.04; + + const float NdotV = saturate(dot(N, V)); + + // Burley roughness bias + const float alpha = roughness * roughness; + + // Blend base colors + const float3 c_diff = lerp(albedo, float3(0, 0, 0), metallic) * ambientOcclusion; + const float3 c_spec = lerp(kSpecularCoefficient, albedo, metallic) * ambientOcclusion; + + // Output color + float3 acc_color = 0; + + // Accumulate light values + for (int i = 0; i < numLights; i++) + { + // light vector (to light) + const float3 L = normalize(-lightDirection[i]); + + // Half vector + const float3 H = normalize(L + V); + + // products + const float NdotL = saturate(dot(N, L)); + const float LdotH = saturate(dot(L, H)); + const float NdotH = saturate(dot(N, H)); + + // Diffuse & specular factors + float diffuse_factor = Diffuse_Burley(NdotL, NdotV, LdotH, roughness); + float3 specular = Specular_BRDF(alpha, c_spec, NdotV, NdotL, LdotH, NdotH); + + // Directional light + acc_color += NdotL * lightColor[i] * (((c_diff * diffuse_factor) + specular)); + } + + // Add diffuse irradiance + float3 diffuse_env = Diffuse_IBL(N); + acc_color += c_diff * diffuse_env; + + // Add specular radiance + float3 specular_env = Specular_IBL(N, V, roughness); + acc_color += c_spec * specular_env; + + return acc_color; +} + +#endif // __PBREFFECT_HEADER_HLSLI__ diff --git a/Kits/ATGTK/PBREffect/PBREffect_Math.hlsli b/Kits/ATGTK/PBREffect/PBREffect_Math.hlsli new file mode 100644 index 00000000..ea92ae55 --- /dev/null +++ b/Kits/ATGTK/PBREffect/PBREffect_Math.hlsli @@ -0,0 +1,114 @@ +//-------------------------------------------------------------------------------------- +// PBREffect_Lighting.hslsi +// +// A physically based shader for forward rendering on DirectX 12. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#ifndef __PBR_MATH_HLSLI__ +#define __PBR_MATH_HLSLI__ + +static const float PI = 3.14159265f; + +// Given a local normal, transform it into a tangent space given by surface normal and tangent +float3 PeturbNormal(float3 localNormal, float3 surfaceNormalWS, float3 surfaceTangentWS) +{ + float3 normal = normalize(surfaceNormalWS); + float3 tangent = normalize(surfaceTangentWS); + float3 binormal = cross(normal, tangent); // reconstructed from normal & tangent + float3x3 TBN = { tangent, binormal, normal }; // world "frame" for local normal + + return mul(localNormal, TBN); // transform to local to world (tangent space) +} + +// Shlick's approximation of Fresnel +float3 Fresnel_Shlick(in float3 f0, in float3 f90, in float x) +{ + return f0 + (f90 - f0) * pow(1.f - x, 5.f); +} + +// No frills Lambert shading. +float Diffuse_Lambert(in float NdotL) +{ + return NdotL; +} + +// Burley's diffuse BRDF +float Diffuse_Burley(in float NdotL, in float NdotV, in float LdotH, in float roughness) +{ + float fd90 = 0.5f + 2.f * roughness * LdotH * LdotH; + return Fresnel_Shlick(1, fd90, NdotL).x * Fresnel_Shlick(1, fd90, NdotV).x; +} + +// GGX specular D (normal distribution) +float Specular_D_GGX(in float alpha, in float NdotH) +{ + const float alpha2 = alpha * alpha; + const float lower = (NdotH * NdotH * (alpha2 - 1)) + 1; + const float result = alpha2 / (PI * lower * lower); + + return result; +} + +// Schlick-Smith specular G (visibility) with Hable's LdotH optimization +float G_Shlick_Smith_Hable(float alpha, float LdotH) +{ + const float k = alpha / 2.0; + const float k2 = k * 2; + const float invk2 = 1 - k2; + return rcp(LdotH * LdotH * invk2 + k2); +} + +// Map a normal on unit sphere to UV coordinates +float2 SphereMap(float3 N) +{ + return float2(atan2(N.x, N.z) / (PI * 2) + 0.5, 0.5 - (asin(N.y) / PI)); +} + +// A microfacet based BRDF. +// +// alpha: This is roughness * roughness as in the "Disney" PBR model by Burley et al. +// +// specularColor: The F0 reflectance value - 0.04 for non-metals, or RGB for metals. This follows model +// used by Unreal Engine 4. +// +// NdotV, NdotL, LdotH, NdotH: vector relationships between, +// N - surface normal +// V - eye normal +// L - light normal +// H - half vector between L & V. +float3 Specular_BRDF(in float alpha, in float3 specularColor, in float NdotV, in float NdotL, in float LdotH, in float NdotH) +{ + // Specular D (microfacet normal distribution) component + float specular_D = Specular_D_GGX(alpha, NdotH); + + // Specular Fresnel + float3 specular_F = Fresnel_Shlick(specularColor, 1, LdotH); + + // Specular G (visibility) component + float specular_G = G_Shlick_Smith_Hable(alpha, LdotH); + + return specular_D * specular_F * specular_G; +} + +// Diffuse irradiance +float3 Diffuse_IBL(in float3 N) +{ + float2 uv = SphereMap(N); + return PBR_IrradianceTexture.Sample(PBR_IBLSampler, uv); +} + +// Approximate specular image based lighting by sampling radiance map at lower mips +// according to roughness, then modulating by Fresnel term. +float3 Specular_IBL(in float3 N, in float3 V, in float lodBias) +{ + float mip = lodBias * PBR_NumRadianceMipLevels; + float2 uv = SphereMap(reflect(-V, N)); + float3 envColor = PBR_RadianceTexture.SampleLevel(PBR_IBLSampler, uv, mip); + + return envColor; +} + +#endif \ No newline at end of file diff --git a/Kits/ATGTK/PBREffect/PBREffect_PSConstant.hlsl b/Kits/ATGTK/PBREffect/PBREffect_PSConstant.hlsl new file mode 100644 index 00000000..dd8ddf40 --- /dev/null +++ b/Kits/ATGTK/PBREffect/PBREffect_PSConstant.hlsl @@ -0,0 +1,25 @@ +//-------------------------------------------------------------------------------------- +// PBREffect_PSConstant.hslsi +// +// A physically based shader for forward rendering on DirectX 12. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "PBREffect_Common.hlsli" + +// Pixel shader: pixel lighting + texture. +[RootSignature(PBREffectRS)] +float4 PSConstant(PSInputPixelLightingTxTangent pin) : SV_Target0 +{ + // vectors + const float3 V = normalize(PBR_EyePosition - pin.PositionWS.xyz); // view vector + const float3 N = normalize(pin.NormalWS); // surface normal + const float AO = 1; // ambient term + + float3 output = PBR_LightSurface(V, N, 3, PBR_LightColor, PBR_LightDirection, + PBR_ConstantAlbedo, PBR_ConstantRoughness, PBR_ConstantMetallic, AO); + + return float4(output,1); +} diff --git a/Kits/ATGTK/PBREffect/PBREffect_PSTextured.hlsl b/Kits/ATGTK/PBREffect/PBREffect_PSTextured.hlsl new file mode 100644 index 00000000..96804836 --- /dev/null +++ b/Kits/ATGTK/PBREffect/PBREffect_PSTextured.hlsl @@ -0,0 +1,33 @@ +//-------------------------------------------------------------------------------------- +// PBREffect_PSTextured.hslsi +// +// A physically based shader for forward rendering on DirectX 12. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "PBREffect_Common.hlsli" + +// Pixel shader: pixel lighting + texture. +[RootSignature(PBREffectRS)] +float4 PSTextured(PSInputPixelLightingTxTangent pin) : SV_Target0 +{ + // vectors + const float3 V = normalize(PBR_EyePosition - pin.PositionWS.xyz); // view vector + const float3 L = normalize(-PBR_LightDirection[0]); // light vector ("to light" oppositve of light's direction) + + // Before lighting, peturb the surface's normal by the one given in normal map. + float3 localNormal = (PBR_NormalTexture.Sample(PBR_SurfaceSampler, pin.TexCoord).xyz * 2) - 1; + + float3 N = PeturbNormal( localNormal, pin.NormalWS, pin.TangentWS); + + // Get albedo, then roughness, metallic and ambient occlusion + float3 albedo = PBR_AlbedoTexture.Sample(PBR_SurfaceSampler, pin.TexCoord).rgb; + float3 RMA = PBR_RMATexture.Sample(PBR_SurfaceSampler, pin.TexCoord); + + // Shade surface + float3 output = PBR_LightSurface(V, N, 3, PBR_LightColor, PBR_LightDirection, albedo, RMA.x, RMA.y, RMA.z); + + return float4(output, 1); +} diff --git a/Kits/ATGTK/PBREffect/PBREffect_VSConstant.hlsl b/Kits/ATGTK/PBREffect/PBREffect_VSConstant.hlsl new file mode 100644 index 00000000..e1596f1e --- /dev/null +++ b/Kits/ATGTK/PBREffect/PBREffect_VSConstant.hlsl @@ -0,0 +1,28 @@ +//-------------------------------------------------------------------------------------- +// PBREffect_VSConstant.hslsi +// +// A physically based shader for forward rendering on DirectX 12. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "PBREffect_Common.hlsli" + +// Shared vertex shader for constant (debugging) and textured variants +[RootSignature(PBREffectRS)] +VSOutputPixelLightingTxTangent VSConstant(VSInputNmTxTangent vin) +{ + VSOutputPixelLightingTxTangent vout; + + CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal, PBR_World, PBR_WorldViewProj, PBR_WorldInverseTranspose); + + vout.PositionPS = cout.Pos_ps; + vout.PositionWS = float4(cout.Pos_ws, 1); + vout.NormalWS = cout.Normal_ws; + vout.Diffuse = float4(PBR_ConstantAlbedo,1); + vout.TexCoord = vin.TexCoord; + vout.TangentWS = normalize(mul(vin.Tangent.xyz, PBR_WorldInverseTranspose)); + + return vout; +} diff --git a/Kits/ATGTK/ToneMapEffect/ToneMapEffect.cpp b/Kits/ATGTK/ToneMapEffect/ToneMapEffect.cpp new file mode 100644 index 00000000..a4e7eeed --- /dev/null +++ b/Kits/ATGTK/ToneMapEffect/ToneMapEffect.cpp @@ -0,0 +1,204 @@ +//-------------------------------------------------------------------------------------- +// ToneMapEffect.cpp +// +// A simple flimic tonemapping effect for DirectX 12. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "pch.h" +#include "ToneMapEffect.h" + +#include <..\Src\EffectCommon.h> + +using namespace DirectX; +using namespace ATG; + +// Include the precompiled shader code. +namespace +{ +#if defined(_XBOX_ONE) && defined(_TITLE) +#include "Compiled/XboxOneToneMapEffect_VS.inc" +#include "Compiled/XboxOneToneMapEffect_PS.inc" +#else +#include "Compiled/ToneMapEffect_VS.inc" +#include "Compiled/ToneMapEffect_PS.inc" +#endif +} + +struct __declspec(align(16)) ToneMapEffectConstants +{ +// no constants + XMVECTOR _dummy; +}; + +// Traits type describes our characteristics to the EffectBase template. +struct ToneMapEffectTraits +{ + typedef ToneMapEffectConstants ConstantBufferType; + + static const int VertexShaderCount = 1; + static const int PixelShaderCount = 1; + static const int ShaderPermutationCount = 1; + static const int RootSignatureCount = 1; +}; + + +class ATG::ToneMapEffect::Impl : public EffectBase +{ +public: + + Impl(_In_ ID3D12Device* device, DXGI_FORMAT outputTargetFormat); + void Apply(_In_ ID3D12GraphicsCommandList* commandList); + + int GetPipelineStatePermutation() const; + + enum Descriptors + { + InputSRV, + InputSampler, + DescriptorsCount + }; + + D3D12_GPU_DESCRIPTOR_HANDLE descriptors[DescriptorsCount]; +}; + +const D3D12_SHADER_BYTECODE EffectBase::VertexShaderBytecode[] = +{ + { ToneMapEffect_VS, sizeof(ToneMapEffect_VS) }, +}; + + +const int EffectBase::VertexShaderIndices[] = +{ + 0, // basic +}; + + +const D3D12_SHADER_BYTECODE EffectBase::PixelShaderBytecode[] = +{ + { ToneMapEffect_PS, sizeof(ToneMapEffect_PS) }, +}; + + +const int EffectBase::PixelShaderIndices[] = +{ + 0, // basic +}; + +// Global pool of per-device ToneMapEffect resources. +SharedResourcePool::DeviceResources> EffectBase::deviceResourcesPool; + + +ToneMapEffect::Impl::Impl(_In_ ID3D12Device* device, DXGI_FORMAT outputTargetFormat) + : EffectBase(device), + descriptors{} +{ + static_assert(_countof(EffectBase::VertexShaderIndices) == ToneMapEffectTraits::ShaderPermutationCount, "array/max mismatch"); + static_assert(_countof(EffectBase::VertexShaderBytecode) == ToneMapEffectTraits::VertexShaderCount, "array/max mismatch"); + static_assert(_countof(EffectBase::PixelShaderBytecode) == ToneMapEffectTraits::PixelShaderCount, "array/max mismatch"); + static_assert(_countof(EffectBase::PixelShaderIndices) == ToneMapEffectTraits::ShaderPermutationCount, "array/max mismatch"); + + // Create root signature + D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags = + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | // Only the input assembler stage needs access to the constant buffer. + D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS; + + CD3DX12_DESCRIPTOR_RANGE textureSRVs(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); + CD3DX12_DESCRIPTOR_RANGE textureSamplers(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); + + CD3DX12_ROOT_PARAMETER rootParameters[2]; + rootParameters[0].InitAsDescriptorTable(1, &textureSRVs); + rootParameters[1].InitAsDescriptorTable(1, &textureSamplers); + + CD3DX12_ROOT_SIGNATURE_DESC rsigDesc; + rsigDesc.Init(_countof(rootParameters), rootParameters, 0, nullptr, rootSignatureFlags); + + // Create the root signature + mRootSignature = GetRootSignature(0, rsigDesc); + + // Get shaders + int sp = GetPipelineStatePermutation(); + int vi = EffectBase::VertexShaderIndices[sp]; + int pi = EffectBase::PixelShaderIndices[sp]; + + // Create pipeline state + RenderTargetState rtState(outputTargetFormat, DXGI_FORMAT_UNKNOWN); // no DSV + + EffectPipelineStateDescription tonemapPSD(&VertexType::InputLayout, + CommonStates::Opaque, + CommonStates::DepthNone, + CommonStates::CullNone, + rtState, + D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE); + + tonemapPSD.CreatePipelineState( + device, + mRootSignature, + EffectBase::VertexShaderBytecode[vi], + EffectBase::PixelShaderBytecode[pi], + mPipelineState.ReleaseAndGetAddressOf()); +} + +int ToneMapEffect::Impl::GetPipelineStatePermutation() const +{ + return 0; +} + + +// Sets our state onto the D3D device. +void ToneMapEffect::Impl::Apply(_In_ ID3D12GraphicsCommandList* commandList) +{ + // Set the root signature + commandList->SetGraphicsRootSignature(mRootSignature); + + // Set the root parameters + // TODO don't assume these are contiguous + commandList->SetGraphicsRootDescriptorTable(0, descriptors[InputSRV]); + commandList->SetGraphicsRootDescriptorTable(1, descriptors[InputSampler]); + + // Set the pipeline state + commandList->SetPipelineState(EffectBase::mPipelineState.Get()); +} + +// Public constructor. +ToneMapEffect::ToneMapEffect(_In_ ID3D12Device* device, DXGI_FORMAT outputTargetFormat) + : pImpl(new Impl(device, outputTargetFormat)) +{ +} + +// Move constructor. +ToneMapEffect::ToneMapEffect(ToneMapEffect&& moveFrom) + : pImpl(std::move(moveFrom.pImpl)) +{ +} + + +// Move assignment. +ToneMapEffect& ToneMapEffect::operator= (ToneMapEffect&& moveFrom) +{ + pImpl = std::move(moveFrom.pImpl); + return *this; +} + + +// Public destructor. +ToneMapEffect::~ToneMapEffect() +{ +} + +// IEffect methods. +void ToneMapEffect::Apply(_In_ ID3D12GraphicsCommandList* commandList) +{ + pImpl->Apply(commandList); +} + +// Texture settings. +void ToneMapEffect::SetTexture(_In_ D3D12_GPU_DESCRIPTOR_HANDLE srvDescriptor, _In_ D3D12_GPU_DESCRIPTOR_HANDLE samplerDescriptor) +{ + pImpl->descriptors[Impl::InputSRV] = srvDescriptor; + pImpl->descriptors[Impl::InputSampler] = samplerDescriptor; +} \ No newline at end of file diff --git a/Kits/ATGTK/ToneMapEffect/ToneMapEffect.h b/Kits/ATGTK/ToneMapEffect/ToneMapEffect.h new file mode 100644 index 00000000..ba43cce9 --- /dev/null +++ b/Kits/ATGTK/ToneMapEffect/ToneMapEffect.h @@ -0,0 +1,40 @@ +//-------------------------------------------------------------------------------------- +// ToneMapEffect.h +// +// A simple flimic tonemapping effect for DirectX 12. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#pragma once + +#include + +namespace ATG +{ + class ToneMapEffect : public DirectX::IEffect + { + public: + // Use this to render tonemap quad (defined here so PSO can use it). + using VertexType = DirectX::VertexPositionTexture; + + explicit ToneMapEffect(_In_ ID3D12Device* device, DXGI_FORMAT outputBufferFormat); + ToneMapEffect(ToneMapEffect&& moveFrom); + ToneMapEffect& operator= (ToneMapEffect&& moveFrom); + + ToneMapEffect(ToneMapEffect const&) = delete; + ToneMapEffect& operator= (ToneMapEffect const&) = delete; + + virtual ~ToneMapEffect(); + + void SetTexture(_In_ D3D12_GPU_DESCRIPTOR_HANDLE srvDescriptor, _In_ D3D12_GPU_DESCRIPTOR_HANDLE samplerDescriptor); + + void __cdecl Apply(_In_ ID3D12GraphicsCommandList* commandList) override; + private: + // Private implementation. + class Impl; + + std::unique_ptr pImpl; + }; +} \ No newline at end of file diff --git a/Kits/ATGTK/ToneMapEffect/ToneMapEffect_Common.hlsli b/Kits/ATGTK/ToneMapEffect/ToneMapEffect_Common.hlsli new file mode 100644 index 00000000..2ea9dff4 --- /dev/null +++ b/Kits/ATGTK/ToneMapEffect/ToneMapEffect_Common.hlsli @@ -0,0 +1,21 @@ +//-------------------------------------------------------------------------------------- +// ToneMapEffect_Common.hlsli +// +// A simple flimic tonemapping effect for DirectX 12. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#ifndef __TONEMAPEFFECT_COMMON_HLSLI__ +#define __TONEMAPEFFECT_COMMON_HLSLI__ + +#define ToneMapRS \ +"RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ +" DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ +" DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ +" DENY_HULL_SHADER_ROOT_ACCESS )," \ +"DescriptorTable ( SRV(t0) ),"\ +"DescriptorTable ( Sampler(s0) )" + +#endif \ No newline at end of file diff --git a/Kits/ATGTK/ToneMapEffect/ToneMapEffect_PS.hlsl b/Kits/ATGTK/ToneMapEffect/ToneMapEffect_PS.hlsl new file mode 100644 index 00000000..1b86f53e --- /dev/null +++ b/Kits/ATGTK/ToneMapEffect/ToneMapEffect_PS.hlsl @@ -0,0 +1,35 @@ +//-------------------------------------------------------------------------------------- +// ToneMapEffect_PS.hlsl +// +// A simple flimic tonemapping effect for DirectX 12. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "ToneMapEffect_Common.hlsli" + +Texture2D HDRTexture : register(t0); +SamplerState PointSampler : register(s0); // Point sample the HDR scene + +// HDR to SDR tone mapping using a simple Reinhard operator +float3 TonemapReinhard(float3 HDRSceneValue) +{ + return HDRSceneValue / (1.0f + HDRSceneValue); +} + +// HDR to SDR tone mapping using a simple Filmic operator +float3 TonemapFilmic(float3 HDRSceneValue) +{ + float3 x = max(0.0f, HDRSceneValue - 0.004f); + return pow((x * (6.2f * x + 0.5f)) / (x * (6.2f * x + 1.7f) + 0.06f), 2.2f); +} + +[RootSignature(ToneMapRS)] +float4 main(float2 texCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 hdr = HDRTexture.Sample(PointSampler, texCoord); + float4 sdr = float4(TonemapReinhard(hdr.xyz),1); + + return sdr; +} \ No newline at end of file diff --git a/Kits/ATGTK/ToneMapEffect/ToneMapEffect_VS.hlsl b/Kits/ATGTK/ToneMapEffect/ToneMapEffect_VS.hlsl new file mode 100644 index 00000000..acf63da3 --- /dev/null +++ b/Kits/ATGTK/ToneMapEffect/ToneMapEffect_VS.hlsl @@ -0,0 +1,16 @@ +//-------------------------------------------------------------------------------------- +// ToneMapEffect_VS.hlsl +// +// A simple flimic tonemapping effect for DirectX 12. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "ToneMapEffect_Common.hlsli" + +[RootSignature(ToneMapRS)] +void main(inout float2 texCoord : TEXCOORD0, + inout float4 position : SV_Position) +{ +} \ No newline at end of file diff --git a/Media/HDR/Stonewall_Ref_irradiance.dds b/Media/HDR/Stonewall_Ref_irradiance.dds new file mode 100644 index 00000000..5ab89e6c Binary files /dev/null and b/Media/HDR/Stonewall_Ref_irradiance.dds differ diff --git a/Media/HDR/Stonewall_Ref_radiance.dds b/Media/HDR/Stonewall_Ref_radiance.dds new file mode 100644 index 00000000..1daa8e35 Binary files /dev/null and b/Media/HDR/Stonewall_Ref_radiance.dds differ diff --git a/Samples/Audio/SimplePlay3DSoundUWP/SimplePlay3DSound.h b/Samples/Audio/SimplePlay3DSoundUWP/SimplePlay3DSound.h index 02b014cb..6480b1a7 100644 --- a/Samples/Audio/SimplePlay3DSoundUWP/SimplePlay3DSound.h +++ b/Samples/Audio/SimplePlay3DSoundUWP/SimplePlay3DSound.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -58,6 +54,9 @@ class Sample : public DX::IDeviceNotify void XM_CALLCONV DrawListener(X3DAUDIO_VECTOR position, DirectX::FXMVECTOR color); void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/Audio/SimplePlaySoundUWP/SimplePlaySound.h b/Samples/Audio/SimplePlaySoundUWP/SimplePlaySound.h index aba973a3..28fc10a6 100644 --- a/Samples/Audio/SimplePlaySoundUWP/SimplePlaySound.h +++ b/Samples/Audio/SimplePlaySoundUWP/SimplePlaySound.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -47,6 +43,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/Audio/SimpleWASAPICaptureUWP/SimpleWASAPICaptureUWP.h b/Samples/Audio/SimpleWASAPICaptureUWP/SimpleWASAPICaptureUWP.h index 10d15731..a7699c2b 100644 --- a/Samples/Audio/SimpleWASAPICaptureUWP/SimpleWASAPICaptureUWP.h +++ b/Samples/Audio/SimpleWASAPICaptureUWP/SimpleWASAPICaptureUWP.h @@ -26,10 +26,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -48,6 +44,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/Audio/SimpleWASAPIPlaySoundUWP/SimpleWASAPIPlaySound.h b/Samples/Audio/SimpleWASAPIPlaySoundUWP/SimpleWASAPIPlaySound.h index d5db66b7..2170ddd0 100644 --- a/Samples/Audio/SimpleWASAPIPlaySoundUWP/SimpleWASAPIPlaySound.h +++ b/Samples/Audio/SimpleWASAPIPlaySoundUWP/SimpleWASAPIPlaySound.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -47,6 +43,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/Graphics/SimplePBR12/Assets/LogoUWP.png b/Samples/Graphics/SimplePBR12/Assets/LogoUWP.png new file mode 100644 index 00000000..6e7e704a Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/LogoUWP.png differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/Floor/Floor.sdkmesh b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/Floor/Floor.sdkmesh new file mode 100644 index 00000000..a2f0ae1b Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/Floor/Floor.sdkmesh differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/Floor/Floor_BaseColor.dds b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/Floor/Floor_BaseColor.dds new file mode 100644 index 00000000..1b42d49b Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/Floor/Floor_BaseColor.dds differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/Floor/Floor_Normal.png b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/Floor/Floor_Normal.png new file mode 100644 index 00000000..aba9a737 Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/Floor/Floor_Normal.png differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/Floor/Floor_RMA.png b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/Floor/Floor_RMA.png new file mode 100644 index 00000000..ecb4f1fa Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/Floor/Floor_RMA.png differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/ToyRobot/ToyRobot.sdkmesh b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/ToyRobot/ToyRobot.sdkmesh new file mode 100644 index 00000000..6f2d32fd Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/ToyRobot/ToyRobot.sdkmesh differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/ToyRobot/ToyRobot_BaseColor.dds b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/ToyRobot/ToyRobot_BaseColor.dds new file mode 100644 index 00000000..7a668706 Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/ToyRobot/ToyRobot_BaseColor.dds differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/ToyRobot/ToyRobot_Normal.png b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/ToyRobot/ToyRobot_Normal.png new file mode 100644 index 00000000..fb7ff764 Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/ToyRobot/ToyRobot_Normal.png differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/ToyRobot/ToyRobot_RMA.png b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/ToyRobot/ToyRobot_RMA.png new file mode 100644 index 00000000..250f140d Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/ToyRobot/ToyRobot_RMA.png differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/WoodBlocks/WoodBlocks.sdkmesh b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/WoodBlocks/WoodBlocks.sdkmesh new file mode 100644 index 00000000..ca277d3f Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/WoodBlocks/WoodBlocks.sdkmesh differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/WoodBlocks/WoodBlocks_BaseColor.dds b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/WoodBlocks/WoodBlocks_BaseColor.dds new file mode 100644 index 00000000..360d18f6 Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/WoodBlocks/WoodBlocks_BaseColor.dds differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/WoodBlocks/WoodBlocks_Normal.png b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/WoodBlocks/WoodBlocks_Normal.png new file mode 100644 index 00000000..75d6af9c Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/WoodBlocks/WoodBlocks_Normal.png differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/WoodBlocks/WoodBlocks_RMA.png b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/WoodBlocks/WoodBlocks_RMA.png new file mode 100644 index 00000000..9259bfba Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/ToyRobot/WoodBlocks/WoodBlocks_RMA.png differ diff --git a/Samples/Graphics/SimplePBR12/Assets/Models/XboxOrb/XboxOrb.sdkmesh b/Samples/Graphics/SimplePBR12/Assets/Models/XboxOrb/XboxOrb.sdkmesh new file mode 100644 index 00000000..103b8c1c Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/Models/XboxOrb/XboxOrb.sdkmesh differ diff --git a/Samples/Graphics/SimplePBR12/Assets/SmallLogoUWP.png b/Samples/Graphics/SimplePBR12/Assets/SmallLogoUWP.png new file mode 100644 index 00000000..98b09d91 Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/SmallLogoUWP.png differ diff --git a/Samples/Graphics/SimplePBR12/Assets/SplashScreenUWP.png b/Samples/Graphics/SimplePBR12/Assets/SplashScreenUWP.png new file mode 100644 index 00000000..c352b156 Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/SplashScreenUWP.png differ diff --git a/Samples/Graphics/SimplePBR12/Assets/StoreLogoUWP.png b/Samples/Graphics/SimplePBR12/Assets/StoreLogoUWP.png new file mode 100644 index 00000000..315472e1 Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/StoreLogoUWP.png differ diff --git a/Samples/Graphics/SimplePBR12/Assets/WideLogoUWP.png b/Samples/Graphics/SimplePBR12/Assets/WideLogoUWP.png new file mode 100644 index 00000000..c70f68e2 Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Assets/WideLogoUWP.png differ diff --git a/Samples/Graphics/SimplePBR12/Readme.docx b/Samples/Graphics/SimplePBR12/Readme.docx new file mode 100644 index 00000000..6701ace8 Binary files /dev/null and b/Samples/Graphics/SimplePBR12/Readme.docx differ diff --git a/Samples/Graphics/SimplePBR12/Shared/DescriptorPile.h b/Samples/Graphics/SimplePBR12/Shared/DescriptorPile.h new file mode 100644 index 00000000..ce9431d9 --- /dev/null +++ b/Samples/Graphics/SimplePBR12/Shared/DescriptorPile.h @@ -0,0 +1,82 @@ +//-------------------------------------------------------------------------------------- +// DescriptorPile.h +// +// A wrapper to help sharing a descriptor heap. This class removes the need for a +// global enumeration of all SRVs used in a sample. The pile is statically sized and will +// throw an exception if it becomes full. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#pragma once +#include +#include + +namespace ATG +{ + class DescriptorPile + { + public: + using IndexType = size_t; + static const IndexType INVALID_INDEX = size_t(-1); + + DescriptorPile( + _In_ ID3D12Device* device, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE type, + _In_ D3D12_DESCRIPTOR_HEAP_FLAGS flags, + size_t initialSize) + : m_top(0) + { + m_heap = std::make_unique(device, type, flags, initialSize); + } + + // Return the start of a batch of descriptors, throws exception if no room + IndexType Allocate() + { + IndexType start, end; + AllocateRange(1, start, end); + + return start; + } + + // Return the start of a batch of descriptors, throws exception if no room + void AllocateRange(size_t numDescriptors, _Out_ IndexType& start, _Out_ IndexType& end) + { + // make sure we didn't allocate zero + if (numDescriptors == 0) + { + throw std::out_of_range("Can't allocate zero slots on DescriptorPile"); + } + + // get the current top + start = m_top; + + // increment top with new request + m_top += numDescriptors; + end = m_top; + + // make sure we have enough room + if (m_top >= m_heap->Count()) + { + throw std::out_of_range("DescriptorPile can't allocate more descriptors"); + } + } + + D3D12_GPU_DESCRIPTOR_HANDLE GetGpuHandle(_In_ size_t index) const + { + return m_heap->GetGpuHandle(index); + } + + D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(_In_ size_t index) const + { + return m_heap->GetCpuHandle(index); + } + + ID3D12DescriptorHeap* Heap() const { return m_heap->Heap(); } + + private: + std::unique_ptr m_heap; + IndexType m_top; + }; +} \ No newline at end of file diff --git a/Samples/Graphics/SimplePBR12/Shared/PBRModel.h b/Samples/Graphics/SimplePBR12/Shared/PBRModel.h new file mode 100644 index 00000000..0b970d50 --- /dev/null +++ b/Samples/Graphics/SimplePBR12/Shared/PBRModel.h @@ -0,0 +1,121 @@ +//-------------------------------------------------------------------------------------- +// PBRModel.h +// +// A wrapper for SDKMesh models that use PBR materials. +// +// This implies the follwing folder structure and naming convention for source assets: +// +// modelPath\modelName.sdkmesh +// modelPath\materalName\modelname_BaseColor.png +// modelPath\materalName\modelname_Normal.png +// modelPath\materalName\modelname_Roughness.png +// modelPath\materalName\modelname_Metallic.png +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +#pragma once + +#include +#include "DescriptorPile.h" +#include "PBREffect\PBREffect.h" + +namespace ATG +{ + class PBRModel + { + public: + PBRModel(const wchar_t* modelPath) + : m_modelFullPath(modelPath) + { + // Remove extension and path + auto lastSlash = m_modelFullPath.find_last_of(L"\\"); + m_modelBasePath = m_modelFullPath.substr(0, lastSlash); + + auto lastDot = m_modelFullPath.find_last_of(L"."); + m_modelName = m_modelFullPath.substr( lastSlash + 1, lastDot - lastSlash - 1); + } + + void Create( + ID3D12Device* device, + const DirectX::RenderTargetState& rtState, + const DirectX::CommonStates* commonStates, + DirectX::ResourceUploadBatch& resourceUpload, + ATG::DescriptorPile* pile) + { + using namespace DirectX; + using namespace DirectX::SimpleMath; + + // Generate paths for resources + enum Textures + { + Albedo = 0, + Normal, + RMA, + MaxTextures + }; + + wchar_t fullTexturePath[MaxTextures][_MAX_PATH] = {}; + + swprintf_s(fullTexturePath[Albedo], L"%s\\%s_BaseColor.dds", m_modelBasePath.c_str(), m_modelName.c_str()); + swprintf_s(fullTexturePath[Normal], L"%s\\%s_Normal.png", m_modelBasePath.c_str(), m_modelName.c_str()); + swprintf_s(fullTexturePath[RMA], L"%s\\%s_RMA.png", m_modelBasePath.c_str(), m_modelName.c_str()); + + // PBR Model + m_model = Model::CreateFromSDKMESH(m_modelFullPath.c_str()); + + // PBR Textures + // Force SRGB on albedo texture + DX::ThrowIfFailed( + CreateDDSTextureFromFileEx(device, resourceUpload, fullTexturePath[Albedo], 0, + D3D12_RESOURCE_FLAG_NONE, WIC_LOADER_FORCE_SRGB, + m_textureResources[Albedo].ReleaseAndGetAddressOf())); + + // Load others as linear + for (size_t i = Normal; i < MaxTextures; i++) + { + DX::ThrowIfFailed( + CreateWICTextureFromFile(device, resourceUpload, fullTexturePath[i], + m_textureResources[i].ReleaseAndGetAddressOf())); + } + + // Allocate a range of descriptors from pile + DescriptorPile::IndexType start, end; + pile->AllocateRange(MaxTextures, start, end); + + for (size_t i = 0; i < MaxTextures; i++) + { + CreateShaderResourceView(device, m_textureResources[i].Get(), pile->GetCpuHandle(start + i)); + } + + // Create PBR Effect + EffectPipelineStateDescription pbrEffectPipelineState( + &ATG::VertexPositionNormalTextureTangent::InputLayout, + CommonStates::Opaque, + CommonStates::DepthDefault, + CommonStates::CullClockwise, + rtState, + D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE); + m_effect = std::make_unique(device, EffectFlags::Texture, pbrEffectPipelineState); + + // Set surface textures + m_effect->SetSurfaceTextures(pile->GetGpuHandle(start + Albedo), + pile->GetGpuHandle(start + Normal), + pile->GetGpuHandle(start + RMA), + commonStates->AnisotropicClamp()); + m_effect->EnableDefaultLighting(); + } + + const DirectX::Model* GetModel() const { return m_model.get(); } + ATG::PBREffect* GetEffect() const { return m_effect.get(); } + + private: + std::wstring m_modelFullPath; + std::wstring m_modelBasePath; + std::wstring m_modelName; + + std::unique_ptr m_model; + std::unique_ptr m_effect; + Microsoft::WRL::ComPtr m_textureResources[4]; + }; +} \ No newline at end of file diff --git a/Samples/Graphics/SimplePBR12/Shared/SharedSimplePBR.cpp b/Samples/Graphics/SimplePBR12/Shared/SharedSimplePBR.cpp new file mode 100644 index 00000000..58ad03e9 --- /dev/null +++ b/Samples/Graphics/SimplePBR12/Shared/SharedSimplePBR.cpp @@ -0,0 +1,461 @@ +//-------------------------------------------------------------------------------------- +// SharedSimplePBR.h +// +// Shared sample class to demonstrate PBRModel and PBREffect in DirectX 12 on Xbox ERA +// and PC UWP. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "pch.h" +#include "SharedSimplePBR.h" + +#include "ControllerFont.h" +#include "DDSTextureLoader.h" +#include "GeometricPrimitive.h" + +#if defined(_XBOX_ONE) && defined(_TITLE) +#include "../Xbox/SimplePBRXbox12.h" // get sample definition +#else +#include "../UWP/SimplePBRUWP12.h" // get sample definition +#endif + + +using namespace DirectX; +using namespace DirectX::SimpleMath; +using Microsoft::WRL::ComPtr; + +namespace +{ + // PBR Assest paths. + const wchar_t* s_modelPaths[] = + { + L"Assets\\Models\\ToyRobot\\Floor\\Floor.sdkmesh", + L"Assets\\Models\\ToyRobot\\ToyRobot\\ToyRobot.sdkmesh", + L"Assets\\Models\\ToyRobot\\WoodBlocks\\WoodBlocks.sdkmesh" + }; + + // A simple test scene for material parameters + struct TestScene + { + std::unique_ptr m_model; + std::unique_ptr m_sphere; + std::unique_ptr m_effect; + + void Init(ID3D12Device* device, + D3D12_GPU_DESCRIPTOR_HANDLE radianceTex, int numMips, + D3D12_GPU_DESCRIPTOR_HANDLE irradianceTex, + D3D12_GPU_DESCRIPTOR_HANDLE sampler) + { + RenderTargetState hdrBufferRts(Sample::GetHDRRenderFormat(), Sample::GetDepthFormat()); + + m_sphere = DirectX::GeometricPrimitive::CreateSphere(1.5); + + // Create PBR Effect + EffectPipelineStateDescription pbrEffectPipelineState( + &ATG::VertexPositionNormalTextureTangent::InputLayout, + CommonStates::Opaque, + CommonStates::DepthDefault, + CommonStates::CullClockwise, + hdrBufferRts, + D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE); + m_effect = std::make_unique(device, EffectFlags::None, pbrEffectPipelineState); + + // Lighting + m_effect->SetIBLTextures( + radianceTex, + numMips, + irradianceTex, + sampler); + + // Model + m_model = Model::CreateFromSDKMESH(L"Assets\\Models\\XboxOrb\\XboxOrb.sdkmesh"); + } + + void XM_CALLCONV Render(ID3D12GraphicsCommandList* commandList, FXMMATRIX camView, CXMMATRIX camProj) + { + const size_t numSpheres = 3; + const float step = 15.f; + + Vector3 modelPos((-step * (numSpheres- 1)) / 2.f, 0, 0); + + m_effect->SetConstantAlbedo(Vector3(1, 1, 1)); + m_effect->SetConstantMetallic(1); + + for (size_t i = 0; i < numSpheres; i++) + { + m_effect->SetView(camView); + m_effect->SetProjection(camProj); + m_effect->SetWorld(Matrix::CreateTranslation(modelPos)); + + modelPos += Vector3(step, 0, 0); + + m_effect->SetConstantRoughness(float(i) / float(numSpheres-1)); + + m_effect->Apply(commandList); + m_model->DrawOpaque(commandList); + } + + modelPos = Vector3((-step * (numSpheres - 1)) / 2.f, 0, 0); + modelPos += Vector3(0, step, 0); + + m_effect->SetConstantMetallic(0); + + for (size_t i = 0; i < numSpheres; i++) + { + m_effect->SetView(camView); + m_effect->SetProjection(camProj); + m_effect->SetWorld(Matrix::CreateTranslation(modelPos)); + + modelPos += Vector3(step, 0, 0); + + m_effect->SetConstantRoughness(float(i) / float(numSpheres-1)); + + m_effect->Apply(commandList); + m_model->DrawOpaque(commandList); + } + } + }; + + std::unique_ptr s_testScene; +} + +SharedSimplePBR::SharedSimplePBR(Sample* sample) : + m_sample(sample), + m_radTexDescIndex(ATG::DescriptorPile::INVALID_INDEX), + m_HDRBufferDescIndex(ATG::DescriptorPile::INVALID_INDEX) +{ + m_gamePad = std::make_unique(); +} + +void SharedSimplePBR::Update(DX::StepTimer const& timer) +{ + const float elapsedSeconds = static_cast(timer.GetElapsedSeconds()); + + // Update camera via game pad + auto pad = m_gamePad->GetState(0); + if (pad.IsConnected()) + { + m_gamePadButtons.Update(pad); + + if (pad.IsViewPressed()) + { + Windows::ApplicationModel::Core::CoreApplication::Exit(); + } + } + else + { + m_gamePadButtons.Reset(); + } + m_camera->Update(elapsedSeconds, pad); + +#if !defined(_XBOX_ONE) || !defined(_TITLE) + // KB/Mouse currently only PC + m_camera->Update(elapsedSeconds, *(m_sample->m_mouse.get()), *(m_sample->m_keyboard.get())); +#endif + + // Update model effects + for (auto& m : m_pbrModels) + { + auto effect = m->GetEffect(); + effect->SetView(m_camera->GetView()); + effect->SetProjection(m_camera->GetProjection()); + effect->SetWorld(Matrix::CreateRotationY(XM_PI)); + } +} + +void SharedSimplePBR::Render() +{ + // Resources and dimensions for this render + DX::DeviceResources* deviceResources = m_sample->m_deviceResources.get(); + auto commandList = deviceResources->GetCommandList(); + auto size = deviceResources->GetOutputSize(); + auto safe = SimpleMath::Viewport::ComputeTitleSafeArea(size.right, size.bottom); + + // Set descriptor heaps + ID3D12DescriptorHeap* heaps[] = { m_srvPile->Heap(), m_commonStates->Heap() }; + commandList->SetDescriptorHeaps(_countof(heaps), heaps); + + PIXBeginEvent(commandList, PIX_COLOR_DEFAULT, L"Render"); + + // Draw to HDR buffer + PIXBeginEvent(commandList, PIX_COLOR_DEFAULT, L"Render HDR"); + + // Sky + { + auto depthStencilDescriptor = deviceResources->GetDepthStencilView(); + auto toneMapRTVDescriptor = m_rtvHeap->GetFirstCpuHandle(); + commandList->OMSetRenderTargets(1, &toneMapRTVDescriptor, FALSE, &depthStencilDescriptor); + + // input texture size + auto texSize = XMUINT2((uint32_t)m_radianceTexture->GetDesc().Width, + (uint32_t)m_radianceTexture->GetDesc().Width); + + // Render spherical background + auto view = deviceResources->GetScreenViewport(); + RECT position = { 0, 0, (LONG)view.Width, (LONG)view.Height }; + + m_spriteBatch->SetViewport(view); + m_spriteBatch->Begin(commandList, SpriteSortMode_Immediate); + m_spriteBatch->Draw(m_srvPile->GetGpuHandle(m_radTexDescIndex), texSize, position); + m_spriteBatch->End(); + } + + PIXBeginEvent(commandList, PIX_COLOR_DEFAULT, L"Model Draw"); +#ifndef TEST_SCENE + for (auto& m : m_pbrModels) + { + m->GetEffect()->Apply(commandList); + m->GetModel()->DrawOpaque(commandList); + } +#else + s_testScene->Render(commandList, m_camera->GetView(), m_camera->GetProjection()); +#endif + PIXEndEvent(commandList); // Model Draw + + PIXEndEvent(commandList); // Render HDR + + PIXBeginEvent(commandList, PIX_COLOR_DEFAULT, L"Tonemap HDR to SDR backbuffer"); + { + auto rtv = static_cast(deviceResources->GetRenderTargetView()); + commandList->OMSetRenderTargets(1, &rtv, FALSE, NULL); + + D3D12_RESOURCE_BARRIER b1 = CD3DX12_RESOURCE_BARRIER::Transition(m_rtvHDRBuffer.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + commandList->ResourceBarrier(1, &b1); + + // Set up tonemap effect + m_toneMapEffect->SetTexture(m_srvPile->GetGpuHandle(m_HDRBufferDescIndex), m_commonStates->LinearClamp()); + m_toneMapEffect->Apply(commandList); + + // Draw quad + m_toneMapBatch->Begin(commandList); + m_toneMapBatch->DrawQuad(ToneMapVert(Vector3(-1, 1, 0), Vector2(0, 0)), + ToneMapVert(Vector3(1, 1, 0), Vector2(1, 0)), + ToneMapVert(Vector3(1, -1, 0), Vector2(1, 1)), + ToneMapVert(Vector3(-1, -1, 0), Vector2(0, 1))); + m_toneMapBatch->End(); + + D3D12_RESOURCE_BARRIER b2 = CD3DX12_RESOURCE_BARRIER::Transition(m_rtvHDRBuffer.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); + commandList->ResourceBarrier(1, &b2); + } + PIXEndEvent(commandList); // Tonemap + + PIXBeginEvent(commandList, PIX_COLOR_DEFAULT, L"Render HUD"); + { + m_hudBatch->Begin(commandList); + + m_smallFont->DrawString(m_hudBatch.get(), L"SimplePBR Sample", + XMFLOAT2(float(safe.left), float(safe.top)), ATG::Colors::LightGrey); + + DX::DrawControllerString(m_hudBatch.get(), + m_smallFont.get(), m_ctrlFont.get(), + L"[RThumb] [LThumb] Mouse, W,A,S,D : Move Camera [View] Exit ", + XMFLOAT2(float(safe.left), + float(safe.bottom) - m_smallFont->GetLineSpacing()), + ATG::Colors::LightGrey); + + m_hudBatch->End(); + } + PIXEndEvent(commandList); // HUD + + PIXEndEvent(commandList); // Render +} + +void SharedSimplePBR::CreateDeviceDependentResources() +{ + auto device = m_sample->m_deviceResources->GetD3DDevice(); + + // State objects + m_commonStates = std::make_unique(device); + + // create heaps + m_srvPile = std::make_unique(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, 128); + m_rtvHeap = std::make_unique(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, D3D12_DESCRIPTOR_HEAP_FLAG_NONE, 1); + + // Begin uploading texture resources + ResourceUploadBatch resourceUpload(device); + resourceUpload.Begin(); + + // Pipeline state - for rendering direct to back buffer + { + RenderTargetState backBufferRts(Sample::GetBackBufferFormat(), Sample::GetDepthFormat()); + + // HUD + DirectX::SpriteBatchPipelineStateDescription hudpd( + backBufferRts, + &CommonStates::AlphaBlend); + + m_hudBatch = std::make_unique(device, resourceUpload, hudpd); + + auto segoeDescIndex = m_srvPile->Allocate(); + m_smallFont = std::make_unique(device, resourceUpload, + L"SegoeUI_18.spritefont", + m_srvPile->GetCpuHandle(segoeDescIndex), + m_srvPile->GetGpuHandle(segoeDescIndex)); + + auto legendDescInex = m_srvPile->Allocate(); + m_ctrlFont = std::make_unique(device, resourceUpload, + L"XboxOneControllerLegendSmall.spritefont", + m_srvPile->GetCpuHandle(legendDescInex), + m_srvPile->GetGpuHandle(legendDescInex)); + + // Create tone mapping effect + m_toneMapEffect = std::make_unique(device, Sample::GetBackBufferFormat()); + + // Tone map batch + m_toneMapBatch = std::make_unique>(device); + } + + // Pipeline state - for rendering to HDR buffer + { + RenderTargetState hdrBufferRts(Sample::GetHDRRenderFormat(), Sample::GetDepthFormat()); + + // Sky rendering batch + m_spriteBatch = std::make_unique(device, resourceUpload, SpriteBatchPipelineStateDescription(hdrBufferRts, &CommonStates::Opaque)); + + // PBR Model + const auto numModels = _countof(s_modelPaths); + m_pbrModels.resize(numModels); + + for (auto i = 0; i < numModels; i++) + { + m_pbrModels[i] = std::make_unique(s_modelPaths[i]); + m_pbrModels[i]->Create(device, hdrBufferRts, m_commonStates.get(), resourceUpload, m_srvPile.get()); + } + } + + // Radiance (specular environment) texture + DX::ThrowIfFailed( + DirectX::CreateDDSTextureFromFile( + device, + resourceUpload, + L"Stonewall_Ref_radiance.dds", + m_radianceTexture.ReleaseAndGetAddressOf(), + false + )); + + m_radTexDescIndex = m_srvPile->Allocate(); + DirectX::CreateShaderResourceView(device, m_radianceTexture.Get(), m_srvPile->GetCpuHandle(m_radTexDescIndex)); + + // Irradiance (diffuse environment) texture + DX::ThrowIfFailed( + DirectX::CreateDDSTextureFromFile( + device, + resourceUpload, + L"Stonewall_Ref_irradiance.dds", + m_irradianceTexture.ReleaseAndGetAddressOf(), + false + )); + + m_irrTexDescIndex = m_srvPile->Allocate(); + DirectX::CreateShaderResourceView(device, m_irradianceTexture.Get(), m_srvPile->GetCpuHandle(m_irrTexDescIndex)); + + // The current map has too much detail removed at last mips, scale back down to + // match reference. + const int numMips = m_radianceTexture->GetDesc().MipLevels - 2; + + // Set lighting textures for each model + for (auto& m : m_pbrModels) + { + m->GetEffect()->SetIBLTextures( + m_srvPile->GetGpuHandle(m_radTexDescIndex), + numMips, + m_srvPile->GetGpuHandle(m_irrTexDescIndex), + m_commonStates->LinearClamp()); + } + + s_testScene = std::make_unique(); + s_testScene->Init(device, m_srvPile->GetGpuHandle(m_radTexDescIndex), + numMips, + m_srvPile->GetGpuHandle(m_irrTexDescIndex), + m_commonStates->LinearClamp()); + + auto finished = resourceUpload.End(m_sample->m_deviceResources->GetCommandQueue()); + finished.wait(); +} + +void SharedSimplePBR::CreateWindowSizeDependentResources() +{ + auto device = m_sample->m_deviceResources->GetD3DDevice(); + const auto size = m_sample->m_deviceResources->GetOutputSize(); + + // Set hud sprite viewport + m_hudBatch->SetViewport(m_sample->m_deviceResources->GetScreenViewport()); + + // set camera + { + const float fovAngleY = 70.0f * XM_PI / 180.0f; + + m_camera = std::make_unique(); + m_camera->SetWindow(size.right, size.bottom); + m_camera->SetProjectionParameters(fovAngleY, 0.1f, 1000.f, false); + m_camera->SetRadius(25.f); + m_camera->SetRadiusRate(5.f); + m_camera->SetFocus(Vector3(0, 4, -5)); + // Rotate to face front + m_camera->SetRotation(Vector3(0, XM_PI, XM_PI / 10)); + } + + // HDR render target resource + { + D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Tex2D( + Sample::GetHDRRenderFormat(), + size.right, + size.bottom, + 1, + 1 // Use a single mipmap level. + ); + desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + + // create resource + CD3DX12_HEAP_PROPERTIES rtvHeapProperties(D3D12_HEAP_TYPE_DEFAULT); + DX::ThrowIfFailed(device->CreateCommittedResource( + &rtvHeapProperties, + D3D12_HEAP_FLAG_NONE, + &desc, + D3D12_RESOURCE_STATE_RENDER_TARGET, + nullptr, // &depthOptimizedClearValue, + IID_GRAPHICS_PPV_ARGS(m_rtvHDRBuffer.ReleaseAndGetAddressOf()) + )); + m_rtvHDRBuffer->SetName(L"HDR buffer"); + } + + // HDR render target view + { + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {}; + rtvDesc.Format = Sample::GetHDRRenderFormat(); + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + device->CreateRenderTargetView(m_rtvHDRBuffer.Get(), &rtvDesc, m_rtvHeap->GetFirstCpuHandle()); + + // create SR view and put in heap + if (m_HDRBufferDescIndex == ATG::DescriptorPile::INVALID_INDEX) m_HDRBufferDescIndex = m_srvPile->Allocate(); + + DirectX::CreateShaderResourceView(device, m_rtvHDRBuffer.Get(), m_srvPile->GetCpuHandle(m_HDRBufferDescIndex)); + } +} + +// For UWP only +void SharedSimplePBR::OnDeviceLost() +{ + m_hudBatch.reset(); + m_smallFont.reset(); + m_ctrlFont.reset(); + + m_gamePad.reset(); + m_camera.reset(); + m_commonStates.reset(); + + m_srvPile.reset(); + + m_spriteBatch.reset(); + m_toneMapEffect.reset(); + m_toneMapBatch.reset(); + + m_rtvHeap.reset(); + + for (auto& m : m_pbrModels) + { + m.reset(); + } +} \ No newline at end of file diff --git a/Samples/Graphics/SimplePBR12/Shared/SharedSimplePBR.h b/Samples/Graphics/SimplePBR12/Shared/SharedSimplePBR.h new file mode 100644 index 00000000..923665f9 --- /dev/null +++ b/Samples/Graphics/SimplePBR12/Shared/SharedSimplePBR.h @@ -0,0 +1,78 @@ +//-------------------------------------------------------------------------------------- +// SharedSimplePBR.h +// +// Shared sample class to demonstrate PBRModel and PBREffect in DirectX 12 on Xbox ERA +// and PC UWP. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#pragma once + +#include "StepTimer.h" + +#include "PBREffect/PBREffect.h" +#include "ToneMapEffect/ToneMapEffect.h" +#include "PBRModel.h" +#include "DescriptorPile.h" + +class Sample; + +class SharedSimplePBR +{ +public: + SharedSimplePBR(Sample* sample); + ~SharedSimplePBR() {} + + void Update(DX::StepTimer const& timer); + void Render(); + void CreateDeviceDependentResources(); + void CreateWindowSizeDependentResources(); + void OnDeviceLost(); + +private: + Sample* m_sample; + + // Hud + std::unique_ptr m_hudBatch; + std::unique_ptr m_smallFont; + std::unique_ptr m_ctrlFont; + + // Input and Camera + std::unique_ptr m_gamePad; + DirectX::GamePad::ButtonStateTracker m_gamePadButtons; + std::unique_ptr m_camera; + + // Render states + std::unique_ptr m_commonStates; + + // All SRV descriptors for sample + std::unique_ptr m_srvPile; + + // Drawing + using DebugVert = DirectX::VertexPositionColor; + using ToneMapVert = ATG::ToneMapEffect::VertexType; + + std::unique_ptr m_spriteBatch; + std::unique_ptr m_toneMapEffect; + std::unique_ptr> m_toneMapBatch; + + // Render target view for tonemapping + std::unique_ptr m_rtvHeap; + Microsoft::WRL::ComPtr m_rtvHDRBuffer; + + // Shader resource view for tonemapping + ATG::DescriptorPile::IndexType m_HDRBufferDescIndex; + + // Sky/Environment textures + ATG::DescriptorPile::IndexType m_radTexDescIndex; + Microsoft::WRL::ComPtr m_radianceTexture; + + // Irradiance texture + ATG::DescriptorPile::IndexType m_irrTexDescIndex; + Microsoft::WRL::ComPtr m_irradianceTexture; + + // Model + std::vector< std::unique_ptr> m_pbrModels; +}; \ No newline at end of file diff --git a/Samples/Graphics/SimplePBR12/Shared/StepTimer.h b/Samples/Graphics/SimplePBR12/Shared/StepTimer.h new file mode 100644 index 00000000..f55db2f8 --- /dev/null +++ b/Samples/Graphics/SimplePBR12/Shared/StepTimer.h @@ -0,0 +1,188 @@ +// +// StepTimer.h - A simple timer that provides elapsed time information +// + +#pragma once + +#include +#include + +namespace DX +{ + // Helper class for animation and simulation timing. + class StepTimer + { + public: + StepTimer() : + m_elapsedTicks(0), + m_totalTicks(0), + m_leftOverTicks(0), + m_frameCount(0), + m_framesPerSecond(0), + m_framesThisSecond(0), + m_qpcSecondCounter(0), + m_isFixedTimeStep(false), + m_targetElapsedTicks(TicksPerSecond / 60) + { + if (!QueryPerformanceFrequency(&m_qpcFrequency)) + { + throw std::exception( "QueryPerformanceFrequency" ); + } + + if (!QueryPerformanceCounter(&m_qpcLastTime)) + { + throw std::exception( "QueryPerformanceCounter" ); + } + + // Initialize max delta to 1/10 of a second. + m_qpcMaxDelta = m_qpcFrequency.QuadPart / 10; + } + + // Get elapsed time since the previous Update call. + uint64_t GetElapsedTicks() const { return m_elapsedTicks; } + double GetElapsedSeconds() const { return TicksToSeconds(m_elapsedTicks); } + + // Get total time since the start of the program. + uint64_t GetTotalTicks() const { return m_totalTicks; } + double GetTotalSeconds() const { return TicksToSeconds(m_totalTicks); } + + // Get total number of updates since start of the program. + uint32_t GetFrameCount() const { return m_frameCount; } + + // Get the current framerate. + uint32_t GetFramesPerSecond() const { return m_framesPerSecond; } + + // Set whether to use fixed or variable timestep mode. + void SetFixedTimeStep(bool isFixedTimestep) { m_isFixedTimeStep = isFixedTimestep; } + + // Set how often to call Update when in fixed timestep mode. + void SetTargetElapsedTicks(uint64_t targetElapsed) { m_targetElapsedTicks = targetElapsed; } + void SetTargetElapsedSeconds(double targetElapsed) { m_targetElapsedTicks = SecondsToTicks(targetElapsed); } + + // Integer format represents time using 10,000,000 ticks per second. + static const uint64_t TicksPerSecond = 10000000; + + static double TicksToSeconds(uint64_t ticks) { return static_cast(ticks) / TicksPerSecond; } + static uint64_t SecondsToTicks(double seconds) { return static_cast(seconds * TicksPerSecond); } + + // After an intentional timing discontinuity (for instance a blocking IO operation) + // call this to avoid having the fixed timestep logic attempt a set of catch-up + // Update calls. + + void ResetElapsedTime() + { + if (!QueryPerformanceCounter(&m_qpcLastTime)) + { + throw std::exception("QueryPerformanceCounter"); + } + + m_leftOverTicks = 0; + m_framesPerSecond = 0; + m_framesThisSecond = 0; + m_qpcSecondCounter = 0; + } + + // Update timer state, calling the specified Update function the appropriate number of times. + template + void Tick(const TUpdate& update) + { + // Query the current time. + LARGE_INTEGER currentTime; + + if (!QueryPerformanceCounter(¤tTime)) + { + throw std::exception( "QueryPerformanceCounter" ); + } + + uint64_t timeDelta = currentTime.QuadPart - m_qpcLastTime.QuadPart; + + m_qpcLastTime = currentTime; + m_qpcSecondCounter += timeDelta; + + // Clamp excessively large time deltas (e.g. after paused in the debugger). + if (timeDelta > m_qpcMaxDelta) + { + timeDelta = m_qpcMaxDelta; + } + + // Convert QPC units into a canonical tick format. This cannot overflow due to the previous clamp. + timeDelta *= TicksPerSecond; + timeDelta /= m_qpcFrequency.QuadPart; + + uint32_t lastFrameCount = m_frameCount; + + if (m_isFixedTimeStep) + { + // Fixed timestep update logic + + // If the app is running very close to the target elapsed time (within 1/4 of a millisecond) just clamp + // the clock to exactly match the target value. This prevents tiny and irrelevant errors + // from accumulating over time. Without this clamping, a game that requested a 60 fps + // fixed update, running with vsync enabled on a 59.94 NTSC display, would eventually + // accumulate enough tiny errors that it would drop a frame. It is better to just round + // small deviations down to zero to leave things running smoothly. + + if (abs(static_cast(timeDelta - m_targetElapsedTicks)) < TicksPerSecond / 4000) + { + timeDelta = m_targetElapsedTicks; + } + + m_leftOverTicks += timeDelta; + + while (m_leftOverTicks >= m_targetElapsedTicks) + { + m_elapsedTicks = m_targetElapsedTicks; + m_totalTicks += m_targetElapsedTicks; + m_leftOverTicks -= m_targetElapsedTicks; + m_frameCount++; + + update(); + } + } + else + { + // Variable timestep update logic. + m_elapsedTicks = timeDelta; + m_totalTicks += timeDelta; + m_leftOverTicks = 0; + m_frameCount++; + + update(); + } + + // Track the current framerate. + if (m_frameCount != lastFrameCount) + { + m_framesThisSecond++; + } + + if (m_qpcSecondCounter >= static_cast(m_qpcFrequency.QuadPart)) + { + m_framesPerSecond = m_framesThisSecond; + m_framesThisSecond = 0; + m_qpcSecondCounter %= m_qpcFrequency.QuadPart; + } + } + + private: + // Source timing data uses QPC units. + LARGE_INTEGER m_qpcFrequency; + LARGE_INTEGER m_qpcLastTime; + uint64_t m_qpcMaxDelta; + + // Derived timing data uses a canonical tick format. + uint64_t m_elapsedTicks; + uint64_t m_totalTicks; + uint64_t m_leftOverTicks; + + // Members for tracking the framerate. + uint32_t m_frameCount; + uint32_t m_framesPerSecond; + uint32_t m_framesThisSecond; + uint64_t m_qpcSecondCounter; + + // Members for configuring fixed timestep mode. + bool m_isFixedTimeStep; + uint64_t m_targetElapsedTicks; + }; +} diff --git a/Samples/Graphics/SimplePBR12/Shared/pch.cpp b/Samples/Graphics/SimplePBR12/Shared/pch.cpp new file mode 100644 index 00000000..373fab97 --- /dev/null +++ b/Samples/Graphics/SimplePBR12/Shared/pch.cpp @@ -0,0 +1,10 @@ +//-------------------------------------------------------------------------------------- +// pch.cpp +// +// Include the standard header and generate the precompiled header. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "pch.h" diff --git a/Samples/Graphics/SimplePBR12/Shared/pch.h b/Samples/Graphics/SimplePBR12/Shared/pch.h new file mode 100644 index 00000000..6ad5f4de --- /dev/null +++ b/Samples/Graphics/SimplePBR12/Shared/pch.h @@ -0,0 +1,92 @@ +//-------------------------------------------------------------------------------------- +// pch.h +// +// Header for standard system include files. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#pragma once + +// Use the C++ standard templated min/max +#define NOMINMAX + +#include + +#if defined(_XBOX_ONE) && defined(_TITLE) + +#include +#include + +#else + +#include +#include "..\UWP\d3dx12.h" +#include + +#ifdef _DEBUG +#include +#endif + +#endif + +#include +#include + + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DX +{ + // Helper class for COM exceptions + class com_exception : public std::exception + { + public: + com_exception(HRESULT hr) : result(hr) {} + + virtual const char* what() const override + { + static char s_str[64] = { 0 }; + sprintf_s(s_str, "Failure with HRESULT of %08X", result); + return s_str; + } + + private: + HRESULT result; + }; + + // Helper utility converts D3D API failures into exceptions. + inline void ThrowIfFailed(HRESULT hr) + { + if (FAILED(hr)) + { + throw com_exception(hr); + } + } +} \ No newline at end of file diff --git a/Samples/Graphics/SimplePBR12/SimplePBRUWP12.sln b/Samples/Graphics/SimplePBR12/SimplePBRUWP12.sln new file mode 100644 index 00000000..a1802000 --- /dev/null +++ b/Samples/Graphics/SimplePBR12/SimplePBRUWP12.sln @@ -0,0 +1,54 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimplePBRUWP12", "SimplePBRUWP12.vcxproj", "{7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTK12", "..\..\..\Kits\DirectXTK12\DirectXTK_Windows10.vcxproj", "{945B8F0E-AE5F-447C-933A-9D069532D3E4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Debug|ARM.ActiveCfg = Debug|ARM + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Debug|ARM.Build.0 = Debug|ARM + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Debug|ARM.Deploy.0 = Debug|ARM + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Debug|x64.ActiveCfg = Debug|x64 + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Debug|x64.Build.0 = Debug|x64 + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Debug|x64.Deploy.0 = Debug|x64 + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Debug|x86.ActiveCfg = Debug|Win32 + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Debug|x86.Build.0 = Debug|Win32 + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Debug|x86.Deploy.0 = Debug|Win32 + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Release|ARM.ActiveCfg = Release|ARM + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Release|ARM.Build.0 = Release|ARM + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Release|ARM.Deploy.0 = Release|ARM + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Release|x64.ActiveCfg = Release|x64 + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Release|x64.Build.0 = Release|x64 + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Release|x64.Deploy.0 = Release|x64 + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Release|x86.ActiveCfg = Release|Win32 + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Release|x86.Build.0 = Release|Win32 + {7B1C60AF-47EE-486D-AC6E-7CC25C8AA8BF}.Release|x86.Deploy.0 = Release|Win32 + {945B8F0E-AE5F-447C-933A-9D069532D3E4}.Debug|ARM.ActiveCfg = Debug|ARM + {945B8F0E-AE5F-447C-933A-9D069532D3E4}.Debug|ARM.Build.0 = Debug|ARM + {945B8F0E-AE5F-447C-933A-9D069532D3E4}.Debug|x64.ActiveCfg = Debug|x64 + {945B8F0E-AE5F-447C-933A-9D069532D3E4}.Debug|x64.Build.0 = Debug|x64 + {945B8F0E-AE5F-447C-933A-9D069532D3E4}.Debug|x86.ActiveCfg = Debug|Win32 + {945B8F0E-AE5F-447C-933A-9D069532D3E4}.Debug|x86.Build.0 = Debug|Win32 + {945B8F0E-AE5F-447C-933A-9D069532D3E4}.Release|ARM.ActiveCfg = Release|ARM + {945B8F0E-AE5F-447C-933A-9D069532D3E4}.Release|ARM.Build.0 = Release|ARM + {945B8F0E-AE5F-447C-933A-9D069532D3E4}.Release|x64.ActiveCfg = Release|x64 + {945B8F0E-AE5F-447C-933A-9D069532D3E4}.Release|x64.Build.0 = Release|x64 + {945B8F0E-AE5F-447C-933A-9D069532D3E4}.Release|x86.ActiveCfg = Release|Win32 + {945B8F0E-AE5F-447C-933A-9D069532D3E4}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/Graphics/SimplePBR12/SimplePBRUWP12.vcxproj b/Samples/Graphics/SimplePBR12/SimplePBRUWP12.vcxproj new file mode 100644 index 00000000..e8464197 --- /dev/null +++ b/Samples/Graphics/SimplePBR12/SimplePBRUWP12.vcxproj @@ -0,0 +1,568 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM + + + Release + ARM + + + + {7b1c60af-47ee-486d-ac6e-7cc25c8aa8bf} + DirectXApp + SimplePBRUWP12 + en-US + 14.0 + true + Windows Store + 10.0.14393.0 + 10.0.10240.0 + 10.0 + true + + + + Application + true + v140 + + + Application + true + v140 + + + Application + true + v140 + + + Application + false + true + v140 + + + Application + false + true + v140 + + + Application + false + true + v140 + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + d2d1.lib; d3d12.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm + + + Shared\pch.h + $(IntDir)pch.pch + $(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK12\Inc;..\..\..\Kits\ATGTK;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + Level4 + _DEBUG;%(PreprocessorDefinitions) + Fast + + + 5.1 + + + + + d2d1.lib; d3d12.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm + + + Shared\pch.h + $(IntDir)pch.pch + $(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK12\Inc;..\..\..\Kits\ATGTK;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + Level4 + NDEBUG;%(PreprocessorDefinitions) + Fast + + + 5.1 + + + + + d2d1.lib; d3d12.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib + + + Shared\pch.h + $(IntDir)pch.pch + $(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK12\Inc;..\..\..\Kits\ATGTK;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + Level4 + _DEBUG;%(PreprocessorDefinitions) + Fast + StreamingSIMDExtensions2 + + + 5.1 + + + + + d2d1.lib; d3d12.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib + + + Shared\pch.h + $(IntDir)pch.pch + $(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK12\Inc;..\..\..\Kits\ATGTK;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + Level4 + NDEBUG;%(PreprocessorDefinitions) + Fast + StreamingSIMDExtensions2 + + + 5.1 + + + + + d2d1.lib; d3d12.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64 + + + Shared\pch.h + $(IntDir)pch.pch + $(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK12\Inc;..\..\..\Kits\ATGTK;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + Level4 + _DEBUG;%(PreprocessorDefinitions) + Fast + + + 5.1 + + + + + d2d1.lib; d3d12.lib; dxgi.lib; dxguid.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + %(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64 + + + Shared\pch.h + $(IntDir)pch.pch + $(ProjectDir);$(IntermediateOutputPath);..\..\..\Kits\DirectXTK12\Inc;..\..\..\Kits\ATGTK;%(AdditionalIncludeDirectories) + /bigobj %(AdditionalOptions) + Level4 + NDEBUG;%(PreprocessorDefinitions) + Fast + + + 5.1 + + + + + + + + + + + + + + + + + + + + pch.h + pch.h + pch.h + pch.h + pch.h + pch.h + + + pch.h + pch.h + pch.h + pch.h + pch.h + pch.h + + + pch.h + pch.h + pch.h + pch.h + pch.h + pch.h + + + pch.h + pch.h + pch.h + pch.h + pch.h + pch.h + + + pch.h + pch.h + pch.h + pch.h + pch.h + pch.h + + + pch.h + pch.h + pch.h + pch.h + pch.h + pch.h + + + pch.h + pch.h + pch.h + pch.h + pch.h + pch.h + + + Create + Create + Create + Create + Create + Create + pch.h + pch.h + pch.h + pch.h + pch.h + pch.h + + + + + + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + {945b8f0e-ae5f-447c-933a-9d069532d3e4} + + + + + Designer + + + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + PSConstant + Pixel + PSConstant + Pixel + PSConstant + Pixel + PSConstant + Pixel + PSConstant + Pixel + PSConstant + Pixel + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + PSTextured + PSTextured + PSTextured + PSTextured + PSTextured + PSTextured + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + VSConstant + Vertex + VSConstant + Vertex + VSConstant + Vertex + VSConstant + Vertex + VSConstant + Vertex + VSConstant + Vertex + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + Pixel + Pixel + Pixel + Pixel + Pixel + Pixel + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + %(Filename) + %(ProjectDir)Compiled\%(Filename).inc + + + Vertex + Vertex + Vertex + Vertex + Vertex + Vertex + + + + + + + + + \ No newline at end of file diff --git a/Samples/Graphics/SimplePBR12/SimplePBRUWP12.vcxproj.filters b/Samples/Graphics/SimplePBR12/SimplePBRUWP12.vcxproj.filters new file mode 100644 index 00000000..bcf1c7de --- /dev/null +++ b/Samples/Graphics/SimplePBR12/SimplePBRUWP12.vcxproj.filters @@ -0,0 +1,220 @@ + + + + + 18c8d9a1-ff3d-41f9-9a89-3fa69ad5ce37 + bmp;dds;fbx;gif;jpg;jpeg;tga;tiff;tif;png + + + {ddbbf8d0-ce55-45af-a9b0-345b08d48cac} + + + {d011644b-b755-4c53-b901-861f5ded6206} + + + {3193fbea-fdac-47bc-ab74-c54874871e18} + + + {94e88a15-d53e-44c6-9190-7bd0c744a50c} + + + {ef97e544-5a3b-4af0-857a-3512e7d7b99a} + + + {f22afe59-0487-4316-94b6-38a911af033c} + + + {08afbad8-cf4a-4ce2-8605-2d011c3d7f52} + + + {a8d8dfff-b806-4fd1-a936-d06c0e1c4584} + + + {72dc149d-78d0-4a74-9107-eff7ac649ab3} + + + {475e1100-2c53-4f97-a0c3-edd7af1b1bde} + + + {0d2f37da-d7b1-4588-b30f-e61450aff6f6} + + + {44404798-9b36-41d2-89a6-3722eab0a693} + + + {a32c56f4-3a70-4d3b-be69-cd22347913df} + + + {13ff252a-7fb4-45f0-a9e1-db019f8db4fb} + + + + + Shared + + + UWP + + + UWP + + + UWP + + + Shared + + + Shared + + + ATG Tool Kit + + + ATG Tool Kit + + + Shared + + + Shared + + + ATG Tool Kit + + + ATG Tool Kit\PBREffect + + + ATG Tool Kit\ToneMapEffect + + + + + Shared + + + UWP + + + UWP + + + UWP + + + Shared + + + ATG Tool Kit + + + ATG Tool Kit\PBREffect + + + ATG Tool Kit\ToneMapEffect + + + + + Assets\Logo + + + Assets\Logo + + + Assets\Logo + + + Assets\Logo + + + Assets\Logo + + + Assets\Models\ToyRobot\Floor + + + Assets\Models\ToyRobot\Floor + + + Assets\Models\ToyRobot\ToyRobot + + + Assets\Models\ToyRobot\ToyRobot + + + Assets\Models\ToyRobot\WoodBlocks + + + Assets\Models\ToyRobot\WoodBlocks + + + Assets\Models\ToyRobot\WoodBlocks + + + Assets\Models\ToyRobot\ToyRobot + + + Assets\Models\ToyRobot\Floor + + + Assets\Backgrounds + + + Assets\Backgrounds + + + + + Assets\Models\XboxOrb + + + + ATG Tool Kit\PBREffect + + + ATG Tool Kit\PBREffect + + + ATG Tool Kit\ToneMapEffect + + + Assets\Models\ToyRobot\Floor + + + Assets\Models\ToyRobot\ToyRobot + + + Assets\Models\ToyRobot\WoodBlocks + + + Assets\Fonts + + + Assets\Fonts + + + + + UWP + + + + + ATG Tool Kit\PBREffect + + + ATG Tool Kit\PBREffect + + + ATG Tool Kit\PBREffect + + + ATG Tool Kit\ToneMapEffect + + + ATG Tool Kit\ToneMapEffect + + + \ No newline at end of file diff --git a/Samples/Graphics/SimplePBR12/UWP/DeviceResources.cpp b/Samples/Graphics/SimplePBR12/UWP/DeviceResources.cpp new file mode 100644 index 00000000..a77ccff2 --- /dev/null +++ b/Samples/Graphics/SimplePBR12/UWP/DeviceResources.cpp @@ -0,0 +1,671 @@ +// +// DeviceResources.cpp - A wrapper for the Direct3D 12 device and swapchain +// + +#include "pch.h" +#include "DeviceResources.h" + +using namespace DirectX; + +using Microsoft::WRL::ComPtr; + +// Constants used to calculate screen rotations +namespace ScreenRotation +{ + // 0-degree Z-rotation + static const XMFLOAT4X4 Rotation0( + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + ); + + // 90-degree Z-rotation + static const XMFLOAT4X4 Rotation90( + 0.0f, 1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + ); + + // 180-degree Z-rotation + static const XMFLOAT4X4 Rotation180( + -1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + ); + + // 270-degree Z-rotation + static const XMFLOAT4X4 Rotation270( + 0.0f, -1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + ); +}; + +namespace +{ + inline DXGI_FORMAT NoSRGB(DXGI_FORMAT fmt) + { + switch (fmt) + { + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM; + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM; + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_UNORM; + default: return fmt; + } + } +}; + +// Constructor for DeviceResources. +DX::DeviceResources::DeviceResources(DXGI_FORMAT backBufferFormat, DXGI_FORMAT depthBufferFormat, UINT backBufferCount, D3D_FEATURE_LEVEL minFeatureLevel) : + m_backBufferIndex(0), + m_fenceValues{}, + m_rtvDescriptorSize(0), + m_screenViewport{}, + m_scissorRect{}, + m_backBufferFormat(backBufferFormat), + m_depthBufferFormat(depthBufferFormat), + m_backBufferCount(backBufferCount), + m_d3dMinFeatureLevel(minFeatureLevel), + m_window(0), + m_d3dFeatureLevel(D3D_FEATURE_LEVEL_11_0), + m_rotation(DXGI_MODE_ROTATION_IDENTITY), + m_outputSize{0, 0, 1, 1}, + m_orientationTransform3D(ScreenRotation::Rotation0), + m_deviceNotify(nullptr) +{ + if (backBufferCount > MAX_BACK_BUFFER_COUNT) + { + throw std::out_of_range("backBufferCount too large"); + } + + if (minFeatureLevel < D3D_FEATURE_LEVEL_11_0) + { + throw std::out_of_range("minFeatureLevel too low"); + } +} + +// Destructor for DeviceResources. +DX::DeviceResources::~DeviceResources() +{ + // Ensure that the GPU is no longer referencing resources that are about to be destroyed. + WaitForGpu(); +} + +// Configures the Direct3D device, and stores handles to it and the device context. +void DX::DeviceResources::CreateDeviceResources() +{ +#if defined(_DEBUG) + // Enable the debug layer (only available if the Graphics Tools feature-on-demand is enabled). + bool debugDXGI = false; + { + ComPtr debugController; + if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(debugController.GetAddressOf())))) + { + debugController->EnableDebugLayer(); + } + else + { + OutputDebugStringA("WARNING: Direct3D Debug Device is not available\n"); + } + + ComPtr dxgiInfoQueue; + if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(dxgiInfoQueue.GetAddressOf())))) + { + debugDXGI = true; + + DX::ThrowIfFailed(CreateDXGIFactory2(DXGI_CREATE_FACTORY_DEBUG, IID_PPV_ARGS(m_dxgiFactory.ReleaseAndGetAddressOf()))); + + dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, true); + dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, true); + } + } + + if (!debugDXGI) +#endif + + DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(m_dxgiFactory.ReleaseAndGetAddressOf()))); + + ComPtr adapter; + GetAdapter(adapter.GetAddressOf()); + + // Create the DX12 API device object. + DX::ThrowIfFailed(D3D12CreateDevice( + adapter.Get(), + m_d3dMinFeatureLevel, + IID_PPV_ARGS(m_d3dDevice.ReleaseAndGetAddressOf()) + )); + +#ifndef NDEBUG + // Configure debug device (if active). + ComPtr d3dInfoQueue; + if (SUCCEEDED(m_d3dDevice.As(&d3dInfoQueue))) + { +#ifdef _DEBUG + d3dInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true); + d3dInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true); +#endif + D3D12_MESSAGE_ID hide[] = + { + D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE, + D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE + }; + D3D12_INFO_QUEUE_FILTER filter = {}; + filter.DenyList.NumIDs = _countof(hide); + filter.DenyList.pIDList = hide; + d3dInfoQueue->AddStorageFilterEntries(&filter); + } +#endif + + // Determine maximum supported feature level for this device + static const D3D_FEATURE_LEVEL s_featureLevels[] = + { + D3D_FEATURE_LEVEL_12_1, + D3D_FEATURE_LEVEL_12_0, + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + }; + + D3D12_FEATURE_DATA_FEATURE_LEVELS featLevels = + { + _countof(s_featureLevels), s_featureLevels, D3D_FEATURE_LEVEL_11_0 + }; + + HRESULT hr = m_d3dDevice->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &featLevels, sizeof(featLevels)); + if (SUCCEEDED(hr)) + { + m_d3dFeatureLevel = featLevels.MaxSupportedFeatureLevel; + } + else + { + m_d3dFeatureLevel = m_d3dMinFeatureLevel; + } + + // Create the command queue. + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + + DX::ThrowIfFailed(m_d3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(m_commandQueue.ReleaseAndGetAddressOf()))); + + // Create descriptor heaps for render target views and depth stencil views. + D3D12_DESCRIPTOR_HEAP_DESC rtvDescriptorHeapDesc = {}; + rtvDescriptorHeapDesc.NumDescriptors = m_backBufferCount; + rtvDescriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + + DX::ThrowIfFailed(m_d3dDevice->CreateDescriptorHeap(&rtvDescriptorHeapDesc, IID_PPV_ARGS(m_rtvDescriptorHeap.ReleaseAndGetAddressOf()))); + + m_rtvDescriptorSize = m_d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + + if (m_depthBufferFormat != DXGI_FORMAT_UNKNOWN) + { + D3D12_DESCRIPTOR_HEAP_DESC dsvDescriptorHeapDesc = {}; + dsvDescriptorHeapDesc.NumDescriptors = 1; + dsvDescriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; + + DX::ThrowIfFailed(m_d3dDevice->CreateDescriptorHeap(&dsvDescriptorHeapDesc, IID_PPV_ARGS(m_dsvDescriptorHeap.ReleaseAndGetAddressOf()))); + } + + // Create a command allocator for each back buffer that will be rendered to. + for (UINT n = 0; n < m_backBufferCount; n++) + { + DX::ThrowIfFailed(m_d3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(m_commandAllocators[n].ReleaseAndGetAddressOf()))); + } + + // Create a command list for recording graphics commands. + DX::ThrowIfFailed(m_d3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocators[0].Get(), nullptr, IID_PPV_ARGS(m_commandList.ReleaseAndGetAddressOf()))); + DX::ThrowIfFailed(m_commandList->Close()); + + // Create a fence for tracking GPU execution progress. + DX::ThrowIfFailed(m_d3dDevice->CreateFence(m_fenceValues[m_backBufferIndex], D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(m_fence.ReleaseAndGetAddressOf()))); + m_fenceValues[m_backBufferIndex]++; + + m_fenceEvent.Attach(CreateEvent(nullptr, FALSE, FALSE, nullptr)); + if (!m_fenceEvent.IsValid()) + { + throw std::exception("CreateEvent"); + } +} + +// These resources need to be recreated every time the window size is changed. +void DX::DeviceResources::CreateWindowSizeDependentResources() +{ + if (!m_window) + { + throw std::exception("Call SetWindow with a valid CoreWindow pointer"); + } + + // Wait until all previous GPU work is complete. + WaitForGpu(); + + // Release resources that are tied to the swap chain and update fence values. + for (UINT n = 0; n < m_backBufferCount; n++) + { + m_renderTargets[n].Reset(); + m_fenceValues[n] = m_fenceValues[m_backBufferIndex]; + } + + // Determine the render target size in pixels. + UINT backBufferWidth = std::max(m_outputSize.right - m_outputSize.left, 1); + UINT backBufferHeight = std::max(m_outputSize.bottom - m_outputSize.top, 1); + DXGI_FORMAT backBufferFormat = NoSRGB(m_backBufferFormat); + + // If the swap chain already exists, resize it, otherwise create one. + if (m_swapChain) + { + // If the swap chain already exists, resize it. + HRESULT hr = m_swapChain->ResizeBuffers( + m_backBufferCount, + backBufferWidth, + backBufferHeight, + backBufferFormat, + 0 + ); + + if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) + { +#ifdef _DEBUG + char buff[64] = {}; + sprintf_s(buff, "Device Lost on ResizeBuffers: Reason code 0x%08X\n", (hr == DXGI_ERROR_DEVICE_REMOVED) ? m_d3dDevice->GetDeviceRemovedReason() : hr); + OutputDebugStringA(buff); +#endif + // If the device was removed for any reason, a new device and swap chain will need to be created. + HandleDeviceLost(); + + // Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method + // and correctly set up the new device. + return; + } + else + { + DX::ThrowIfFailed(hr); + } + } + else + { + // Create a descriptor for the swap chain. + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; + swapChainDesc.Width = backBufferWidth; + swapChainDesc.Height = backBufferHeight; + swapChainDesc.Format = backBufferFormat; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = m_backBufferCount; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.Scaling = DXGI_SCALING_ASPECT_RATIO_STRETCH; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; + + // Create a swap chain for the window. + ComPtr swapChain; + DX::ThrowIfFailed(m_dxgiFactory->CreateSwapChainForCoreWindow( + m_commandQueue.Get(), + m_window, + &swapChainDesc, + nullptr, + swapChain.GetAddressOf() + )); + + DX::ThrowIfFailed(swapChain.As(&m_swapChain)); + } + + // Set the proper orientation for the swap chain, and generate + // matrix transformations for rendering to the rotated swap chain. + switch (m_rotation) + { + default: + case DXGI_MODE_ROTATION_IDENTITY: + m_orientationTransform3D = ScreenRotation::Rotation0; + break; + + case DXGI_MODE_ROTATION_ROTATE90: + m_orientationTransform3D = ScreenRotation::Rotation270; + break; + + case DXGI_MODE_ROTATION_ROTATE180: + m_orientationTransform3D = ScreenRotation::Rotation180; + break; + + case DXGI_MODE_ROTATION_ROTATE270: + m_orientationTransform3D = ScreenRotation::Rotation90; + break; + } + + DX::ThrowIfFailed(m_swapChain->SetRotation(m_rotation)); + + // Obtain the back buffers for this window which will be the final render targets + // and create render target views for each of them. + for (UINT n = 0; n < m_backBufferCount; n++) + { + DX::ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(m_renderTargets[n].GetAddressOf()))); + + wchar_t name[25] = {}; + swprintf_s(name, L"Render target %u", n); + m_renderTargets[n]->SetName(name); + + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {}; + rtvDesc.Format = m_backBufferFormat; + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + + CD3DX12_CPU_DESCRIPTOR_HANDLE rtvDescriptor(m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), n, m_rtvDescriptorSize); + m_d3dDevice->CreateRenderTargetView(m_renderTargets[n].Get(), &rtvDesc, rtvDescriptor); + } + + // Reset the index to the current back buffer. + m_backBufferIndex = m_swapChain->GetCurrentBackBufferIndex(); + + if (m_depthBufferFormat != DXGI_FORMAT_UNKNOWN) + { + // Allocate a 2-D surface as the depth/stencil buffer and create a depth/stencil view + // on this surface. + CD3DX12_HEAP_PROPERTIES depthHeapProperties(D3D12_HEAP_TYPE_DEFAULT); + + D3D12_RESOURCE_DESC depthStencilDesc = CD3DX12_RESOURCE_DESC::Tex2D( + m_depthBufferFormat, + backBufferWidth, + backBufferHeight, + 1, // This depth stencil view has only one texture. + 1 // Use a single mipmap level. + ); + depthStencilDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + + D3D12_CLEAR_VALUE depthOptimizedClearValue = {}; + depthOptimizedClearValue.Format = m_depthBufferFormat; + depthOptimizedClearValue.DepthStencil.Depth = 1.0f; + depthOptimizedClearValue.DepthStencil.Stencil = 0; + + DX::ThrowIfFailed(m_d3dDevice->CreateCommittedResource( + &depthHeapProperties, + D3D12_HEAP_FLAG_NONE, + &depthStencilDesc, + D3D12_RESOURCE_STATE_DEPTH_WRITE, + &depthOptimizedClearValue, + IID_PPV_ARGS(m_depthStencil.ReleaseAndGetAddressOf()) + )); + + m_depthStencil->SetName(L"Depth stencil"); + + D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {}; + dsvDesc.Format = m_depthBufferFormat; + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; + + m_d3dDevice->CreateDepthStencilView(m_depthStencil.Get(), &dsvDesc, m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart()); + } + + // Set the 3D rendering viewport and scissor rectangle to target the entire window. + m_screenViewport.TopLeftX = m_screenViewport.TopLeftY = 0.f; + m_screenViewport.Width = static_cast(backBufferWidth); + m_screenViewport.Height = static_cast(backBufferHeight); + m_screenViewport.MinDepth = D3D12_MIN_DEPTH; + m_screenViewport.MaxDepth = D3D12_MAX_DEPTH; + + m_scissorRect.left = m_scissorRect.top = 0; + m_scissorRect.right = backBufferWidth; + m_scissorRect.bottom = backBufferHeight; +} + +// This method is called when the CoreWindow is created (or re-created). +void DX::DeviceResources::SetWindow(IUnknown* window, int width, int height, DXGI_MODE_ROTATION rotation) +{ + m_window = window; + + m_outputSize.left = m_outputSize.top = 0; + m_outputSize.right = width; + m_outputSize.bottom = height; + + m_rotation = rotation; +} + +// This method is called when the window changes size. +bool DX::DeviceResources::WindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation) +{ + RECT newRc; + newRc.left = newRc.top = 0; + newRc.right = width; + newRc.bottom = height; + if (newRc.left == m_outputSize.left + && newRc.top == m_outputSize.top + && newRc.right == m_outputSize.right + && newRc.bottom == m_outputSize.bottom + && rotation == m_rotation) + { + return false; + } + + m_outputSize = newRc; + m_rotation = rotation; + CreateWindowSizeDependentResources(); + return true; +} + +// This method is called in the event handler for the DisplayContentsInvalidated event. +void DX::DeviceResources::ValidateDevice() +{ + // The D3D Device is no longer valid if the default adapter changed since the device + // was created or if the device has been removed. + + DXGI_ADAPTER_DESC previousDesc; + { + ComPtr previousDefaultAdapter; + DX::ThrowIfFailed(m_dxgiFactory->EnumAdapters1(0, previousDefaultAdapter.GetAddressOf())); + + DX::ThrowIfFailed(previousDefaultAdapter->GetDesc(&previousDesc)); + } + + DXGI_ADAPTER_DESC currentDesc; + { + ComPtr currentFactory; + DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(currentFactory.GetAddressOf()))); + + ComPtr currentDefaultAdapter; + DX::ThrowIfFailed(currentFactory->EnumAdapters1(0, currentDefaultAdapter.GetAddressOf())); + + DX::ThrowIfFailed(currentDefaultAdapter->GetDesc(¤tDesc)); + } + + // If the adapter LUIDs don't match, or if the device reports that it has been removed, + // a new D3D device must be created. + + if (previousDesc.AdapterLuid.LowPart != currentDesc.AdapterLuid.LowPart + || previousDesc.AdapterLuid.HighPart != currentDesc.AdapterLuid.HighPart + || FAILED(m_d3dDevice->GetDeviceRemovedReason())) + { +#ifdef _DEBUG + OutputDebugStringA("Device Lost on ValidateDevice\n"); +#endif + + // Create a new device and swap chain. + HandleDeviceLost(); + } +} + +// Recreate all device resources and set them back to the current state. +void DX::DeviceResources::HandleDeviceLost() +{ + if (m_deviceNotify) + { + m_deviceNotify->OnDeviceLost(); + } + + for (UINT n = 0; n < m_backBufferCount; n++) + { + m_commandAllocators[n].Reset(); + m_renderTargets[n].Reset(); + } + + m_depthStencil.Reset(); + m_commandQueue.Reset(); + m_commandList.Reset(); + m_fence.Reset(); + m_rtvDescriptorHeap.Reset(); + m_dsvDescriptorHeap.Reset(); + m_swapChain.Reset(); + m_d3dDevice.Reset(); + m_dxgiFactory.Reset(); + +#ifdef _DEBUG + { + ComPtr dxgiDebug; + if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug)))) + { + dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_IGNORE_INTERNAL)); + } + } +#endif + + CreateDeviceResources(); + CreateWindowSizeDependentResources(); + + if (m_deviceNotify) + { + m_deviceNotify->OnDeviceRestored(); + } +} + +// Prepare the command list and render target for rendering. +void DX::DeviceResources::Prepare(D3D12_RESOURCE_STATES beforeState) +{ + // Reset command list and allocator. + DX::ThrowIfFailed(m_commandAllocators[m_backBufferIndex]->Reset()); + DX::ThrowIfFailed(m_commandList->Reset(m_commandAllocators[m_backBufferIndex].Get(), nullptr)); + + if (beforeState != D3D12_RESOURCE_STATE_RENDER_TARGET) + { + // Transition the render target into the correct state to allow for drawing into it. + D3D12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_backBufferIndex].Get(), beforeState, D3D12_RESOURCE_STATE_RENDER_TARGET); + m_commandList->ResourceBarrier(1, &barrier); + } +} + +// Present the contents of the swap chain to the screen. +void DX::DeviceResources::Present(D3D12_RESOURCE_STATES beforeState) +{ + if (beforeState != D3D12_RESOURCE_STATE_PRESENT) + { + // Transition the render target to the state that allows it to be presented to the display. + D3D12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_backBufferIndex].Get(), beforeState, D3D12_RESOURCE_STATE_PRESENT); + m_commandList->ResourceBarrier(1, &barrier); + } + + // Send the command list off to the GPU for processing. + DX::ThrowIfFailed(m_commandList->Close()); + m_commandQueue->ExecuteCommandLists(1, CommandListCast(m_commandList.GetAddressOf())); + + // The first argument instructs DXGI to block until VSync, putting the application + // to sleep until the next VSync. This ensures we don't waste any cycles rendering + // frames that will never be displayed to the screen. + HRESULT hr = m_swapChain->Present(1, 0); + + // If the device was reset we must completely reinitialize the renderer. + if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) + { +#ifdef _DEBUG + char buff[64] = {}; + sprintf_s(buff, "Device Lost on Present: Reason code 0x%08X\n", (hr == DXGI_ERROR_DEVICE_REMOVED) ? m_d3dDevice->GetDeviceRemovedReason() : hr); + OutputDebugStringA(buff); +#endif + HandleDeviceLost(); + } + else + { + DX::ThrowIfFailed(hr); + + MoveToNextFrame(); + } +} + +// Wait for pending GPU work to complete. +void DX::DeviceResources::WaitForGpu() noexcept +{ + if (m_commandQueue && m_fence && m_fenceEvent.IsValid()) + { + // Schedule a Signal command in the GPU queue. + UINT64 fenceValue = m_fenceValues[m_backBufferIndex]; + if (SUCCEEDED(m_commandQueue->Signal(m_fence.Get(), fenceValue))) + { + // Wait until the Signal has been processed. + if (SUCCEEDED(m_fence->SetEventOnCompletion(fenceValue, m_fenceEvent.Get()))) + { + WaitForSingleObjectEx(m_fenceEvent.Get(), INFINITE, FALSE); + + // Increment the fence value for the current frame. + m_fenceValues[m_backBufferIndex]++; + } + } + } +} + +// Prepare to render the next frame. +void DX::DeviceResources::MoveToNextFrame() +{ + // Schedule a Signal command in the queue. + const UINT64 currentFenceValue = m_fenceValues[m_backBufferIndex]; + DX::ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), currentFenceValue)); + + // Update the back buffer index. + m_backBufferIndex = m_swapChain->GetCurrentBackBufferIndex(); + + // If the next frame is not ready to be rendered yet, wait until it is ready. + if (m_fence->GetCompletedValue() < m_fenceValues[m_backBufferIndex]) + { + DX::ThrowIfFailed(m_fence->SetEventOnCompletion(m_fenceValues[m_backBufferIndex], m_fenceEvent.Get())); + WaitForSingleObjectEx(m_fenceEvent.Get(), INFINITE, FALSE); + } + + // Set the fence value for the next frame. + m_fenceValues[m_backBufferIndex] = currentFenceValue + 1; +} + +// This method acquires the first available hardware adapter that supports Direct3D 12. +// If no such adapter can be found, try WARP. Otherwise throw an exception. +void DX::DeviceResources::GetAdapter(IDXGIAdapter1** ppAdapter) +{ + *ppAdapter = nullptr; + + ComPtr adapter; + for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != m_dxgiFactory->EnumAdapters1(adapterIndex, adapter.ReleaseAndGetAddressOf()); ++adapterIndex) + { + DXGI_ADAPTER_DESC1 desc; + DX::ThrowIfFailed(adapter->GetDesc1(&desc)); + + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + // Don't select the Basic Render Driver adapter. + continue; + } + + // Check to see if the adapter supports Direct3D 12, but don't create the actual device yet. + if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), m_d3dMinFeatureLevel, _uuidof(ID3D12Device), nullptr))) + { +#ifdef _DEBUG + wchar_t buff[256] = {}; + swprintf_s(buff, L"Direct3D Adapter (%u): VID:%04X, PID:%04X - %ls\n", adapterIndex, desc.VendorId, desc.DeviceId, desc.Description); + OutputDebugStringW(buff); +#endif + break; + } + } + +#if !defined(NDEBUG) + if (!adapter) + { + // Try WARP12 instead + if (FAILED(m_dxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(adapter.ReleaseAndGetAddressOf())))) + { + throw std::exception("WARP12 not available. Enable the 'Graphics Tools' feature-on-demand"); + } + + OutputDebugStringA("Direct3D Adapter - WARP12\n"); + } +#endif + + if (!adapter) + { + throw std::exception("No Direct3D 12 device found"); + } + + *ppAdapter = adapter.Detach(); +} diff --git a/Samples/Graphics/SimplePBR12/UWP/DeviceResources.h b/Samples/Graphics/SimplePBR12/UWP/DeviceResources.h new file mode 100644 index 00000000..5eaa373a --- /dev/null +++ b/Samples/Graphics/SimplePBR12/UWP/DeviceResources.h @@ -0,0 +1,117 @@ +// +// DeviceResources.h - A wrapper for the Direct3D 12 device and swapchain +// + +#pragma once + +namespace DX +{ + // Provides an interface for an application that owns DeviceResources to be notified of the device being lost or created. + interface IDeviceNotify + { + virtual void OnDeviceLost() = 0; + virtual void OnDeviceRestored() = 0; + }; + + // Controls all the DirectX device resources. + class DeviceResources + { + public: + DeviceResources(DXGI_FORMAT backBufferFormat = DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT depthBufferFormat = DXGI_FORMAT_D32_FLOAT, + UINT backBufferCount = 2, + D3D_FEATURE_LEVEL minFeatureLevel = D3D_FEATURE_LEVEL_11_0); + ~DeviceResources(); + + void CreateDeviceResources(); + void CreateWindowSizeDependentResources(); + void SetWindow(IUnknown* window, int width, int height, DXGI_MODE_ROTATION rotation); + bool WindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation); + void ValidateDevice(); + void HandleDeviceLost(); + void RegisterDeviceNotify(IDeviceNotify* deviceNotify) { m_deviceNotify = deviceNotify; } + void Prepare(D3D12_RESOURCE_STATES beforeState = D3D12_RESOURCE_STATE_PRESENT); + void Present(D3D12_RESOURCE_STATES beforeState = D3D12_RESOURCE_STATE_RENDER_TARGET); + void WaitForGpu() noexcept; + + // Device Accessors. + RECT GetOutputSize() const { return m_outputSize; } + DXGI_MODE_ROTATION GetRotation() const { return m_rotation; } + + // Direct3D Accessors. + ID3D12Device* GetD3DDevice() const { return m_d3dDevice.Get(); } + IDXGISwapChain3* GetSwapChain() const { return m_swapChain.Get(); } + D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const { return m_d3dFeatureLevel; } + ID3D12Resource* GetRenderTarget() const { return m_renderTargets[m_backBufferIndex].Get(); } + ID3D12Resource* GetDepthStencil() const { return m_depthStencil.Get(); } + ID3D12CommandQueue* GetCommandQueue() const { return m_commandQueue.Get(); } + ID3D12CommandAllocator* GetCommandAllocator() const { return m_commandAllocators[m_backBufferIndex].Get(); } + ID3D12GraphicsCommandList* GetCommandList() const { return m_commandList.Get(); } + DXGI_FORMAT GetBackBufferFormat() const { return m_backBufferFormat; } + DXGI_FORMAT GetDepthBufferFormat() const { return m_depthBufferFormat; } + D3D12_VIEWPORT GetScreenViewport() const { return m_screenViewport; } + D3D12_RECT GetScissorRect() const { return m_scissorRect; } + UINT GetCurrentFrameIndex() const { return m_backBufferIndex; } + UINT GetBackBufferCount() const { return m_backBufferCount; } + DirectX::XMFLOAT4X4 GetOrientationTransform3D() const { return m_orientationTransform3D; } + + CD3DX12_CPU_DESCRIPTOR_HANDLE GetRenderTargetView() const + { + return CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), m_backBufferIndex, m_rtvDescriptorSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE GetDepthStencilView() const + { + return CD3DX12_CPU_DESCRIPTOR_HANDLE(m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart()); + } + + private: + void MoveToNextFrame(); + void GetAdapter(IDXGIAdapter1** ppAdapter); + + const static size_t MAX_BACK_BUFFER_COUNT = 3; + + UINT m_backBufferIndex; + + // Direct3D objects. + Microsoft::WRL::ComPtr m_d3dDevice; + Microsoft::WRL::ComPtr m_commandQueue; + Microsoft::WRL::ComPtr m_commandList; + Microsoft::WRL::ComPtr m_commandAllocators[MAX_BACK_BUFFER_COUNT]; + + // Swap chain objects. + Microsoft::WRL::ComPtr m_dxgiFactory; + Microsoft::WRL::ComPtr m_swapChain; + Microsoft::WRL::ComPtr m_renderTargets[MAX_BACK_BUFFER_COUNT]; + Microsoft::WRL::ComPtr m_depthStencil; + + // Presentation fence objects. + Microsoft::WRL::ComPtr m_fence; + UINT64 m_fenceValues[MAX_BACK_BUFFER_COUNT]; + Microsoft::WRL::Wrappers::Event m_fenceEvent; + + // Direct3D rendering objects. + Microsoft::WRL::ComPtr m_rtvDescriptorHeap; + Microsoft::WRL::ComPtr m_dsvDescriptorHeap; + UINT m_rtvDescriptorSize; + D3D12_VIEWPORT m_screenViewport; + D3D12_RECT m_scissorRect; + + // Direct3D properties. + DXGI_FORMAT m_backBufferFormat; + DXGI_FORMAT m_depthBufferFormat; + UINT m_backBufferCount; + D3D_FEATURE_LEVEL m_d3dMinFeatureLevel; + + // Cached device properties. + IUnknown* m_window; + D3D_FEATURE_LEVEL m_d3dFeatureLevel; + DXGI_MODE_ROTATION m_rotation; + RECT m_outputSize; + + // Transforms used for display orientation. + DirectX::XMFLOAT4X4 m_orientationTransform3D; + + // The IDeviceNotify can be held directly as it owns the DeviceResources. + IDeviceNotify* m_deviceNotify; + }; +} diff --git a/Samples/Graphics/SimplePBR12/UWP/Main.cpp b/Samples/Graphics/SimplePBR12/UWP/Main.cpp new file mode 100644 index 00000000..dbfb6c8f --- /dev/null +++ b/Samples/Graphics/SimplePBR12/UWP/Main.cpp @@ -0,0 +1,357 @@ +//-------------------------------------------------------------------------------------- +// Main.cpp +// +// Entry point for Universal Windows Platform (UWP) app. +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "pch.h" +#include "SimplePBRUWP12.h" + +#include + +using namespace concurrency; +using namespace Windows::ApplicationModel; +using namespace Windows::ApplicationModel::Core; +using namespace Windows::ApplicationModel::Activation; +using namespace Windows::UI::Core; +using namespace Windows::UI::Input; +using namespace Windows::UI::ViewManagement; +using namespace Windows::System; +using namespace Windows::Foundation; +using namespace Windows::Graphics::Display; +using namespace DirectX; + +ref class ViewProvider sealed : public IFrameworkView +{ +public: + ViewProvider() : + m_exit(false), + m_visible(true), + m_DPI(96.f), + m_logicalWidth(800.f), + m_logicalHeight(600.f), + m_nativeOrientation(DisplayOrientations::None), + m_currentOrientation(DisplayOrientations::None) + { + } + + // IFrameworkView methods + virtual void Initialize(CoreApplicationView^ applicationView) + { + applicationView->Activated += ref new + TypedEventHandler(this, &ViewProvider::OnActivated); + + CoreApplication::Suspending += + ref new EventHandler(this, &ViewProvider::OnSuspending); + + CoreApplication::Resuming += + ref new EventHandler(this, &ViewProvider::OnResuming); + + m_sample = std::make_unique(); + } + + virtual void Uninitialize() + { + m_sample.reset(); + } + + virtual void SetWindow(CoreWindow^ window) + { + window->SizeChanged += + ref new TypedEventHandler(this, &ViewProvider::OnWindowSizeChanged); + + window->VisibilityChanged += + ref new TypedEventHandler(this, &ViewProvider::OnVisibilityChanged); + + window->Closed += + ref new TypedEventHandler(this, &ViewProvider::OnWindowClosed); + + auto dispatcher = CoreWindow::GetForCurrentThread()->Dispatcher; + + dispatcher->AcceleratorKeyActivated += + ref new TypedEventHandler(this, &ViewProvider::OnAcceleratorKeyActivated); + + auto currentDisplayInformation = DisplayInformation::GetForCurrentView(); + + currentDisplayInformation->DpiChanged += + ref new TypedEventHandler(this, &ViewProvider::OnDpiChanged); + + currentDisplayInformation->OrientationChanged += + ref new TypedEventHandler(this, &ViewProvider::OnOrientationChanged); + + DisplayInformation::DisplayContentsInvalidated += + ref new TypedEventHandler(this, &ViewProvider::OnDisplayContentsInvalidated); + + m_DPI = currentDisplayInformation->LogicalDpi; + + m_logicalWidth = window->Bounds.Width; + m_logicalHeight = window->Bounds.Height; + + m_nativeOrientation = currentDisplayInformation->NativeOrientation; + m_currentOrientation = currentDisplayInformation->CurrentOrientation; + + int outputWidth = ConvertDipsToPixels(m_logicalWidth); + int outputHeight = ConvertDipsToPixels(m_logicalHeight); + + DXGI_MODE_ROTATION rotation = ComputeDisplayRotation(); + + if (rotation == DXGI_MODE_ROTATION_ROTATE90 || rotation == DXGI_MODE_ROTATION_ROTATE270) + { + std::swap(outputWidth, outputHeight); + } + + m_sample->Initialize(reinterpret_cast(window), + outputWidth, outputHeight, rotation ); + } + + virtual void Load(Platform::String^ entryPoint) + { + } + + virtual void Run() + { + while (!m_exit) + { + if (m_visible) + { + m_sample->Tick(); + + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); + } + else + { + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); + } + } + } + +protected: + // Event handlers + void OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) + { + if (args->Kind == ActivationKind::Launch) + { + auto launchArgs = static_cast(args); + + if (launchArgs->PrelaunchActivated) + { + // Opt-out of Prelaunch + CoreApplication::Exit(); + return; + } + } + + int w, h; + m_sample->GetDefaultSize(w, h); + + m_DPI = DisplayInformation::GetForCurrentView()->LogicalDpi; + + ApplicationView::PreferredLaunchWindowingMode = ApplicationViewWindowingMode::PreferredLaunchViewSize; + // Change to ApplicationViewWindowingMode::FullScreen to default to full screen + + auto desiredSize = Size(ConvertPixelsToDips(w), ConvertPixelsToDips(h)); + + ApplicationView::PreferredLaunchViewSize = desiredSize; + + auto view = ApplicationView::GetForCurrentView(); + + auto minSize = Size(ConvertPixelsToDips(320), ConvertPixelsToDips(200)); + + view->SetPreferredMinSize(minSize); + + CoreWindow::GetForCurrentThread()->Activate(); + + view->FullScreenSystemOverlayMode = FullScreenSystemOverlayMode::Minimal; + + view->TryResizeView(desiredSize); + } + + void OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args) + { + SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral(); + + create_task([this, deferral]() + { + m_sample->OnSuspending(); + + deferral->Complete(); + }); + } + + void OnResuming(Platform::Object^ sender, Platform::Object^ args) + { + m_sample->OnResuming(); + } + + void OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) + { + m_logicalWidth = sender->Bounds.Width; + m_logicalHeight = sender->Bounds.Height; + + HandleWindowSizeChanged(); + } + + void OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) + { + m_visible = args->Visible; + if (m_visible) + m_sample->OnActivated(); + else + m_sample->OnDeactivated(); + } + + void OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) + { + m_exit = true; + } + + void OnAcceleratorKeyActivated(CoreDispatcher^, AcceleratorKeyEventArgs^ args) + { + if (args->EventType == CoreAcceleratorKeyEventType::SystemKeyDown + && args->VirtualKey == VirtualKey::Enter + && args->KeyStatus.IsMenuKeyDown + && !args->KeyStatus.WasKeyDown) + { + // Implements the classic ALT+ENTER fullscreen toggle + auto view = ApplicationView::GetForCurrentView(); + + if (view->IsFullScreenMode) + view->ExitFullScreenMode(); + else + view->TryEnterFullScreenMode(); + + args->Handled = true; + } + } + + void OnDpiChanged(DisplayInformation^ sender, Object^ args) + { + m_DPI = sender->LogicalDpi; + + HandleWindowSizeChanged(); + } + + void OnOrientationChanged(DisplayInformation^ sender, Object^ args) + { + m_currentOrientation = sender->CurrentOrientation; + + HandleWindowSizeChanged(); + } + + void OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args) + { + m_sample->ValidateDevice(); + } + +private: + bool m_exit; + bool m_visible; + float m_DPI; + float m_logicalWidth; + float m_logicalHeight; + std::unique_ptr m_sample; + + Windows::Graphics::Display::DisplayOrientations m_nativeOrientation; + Windows::Graphics::Display::DisplayOrientations m_currentOrientation; + + inline int ConvertDipsToPixels(float dips) const + { + return int(dips * m_DPI / 96.f + 0.5f); + } + + inline float ConvertPixelsToDips(int pixels) const + { + return (float(pixels) * 96.f / m_DPI); + } + + DXGI_MODE_ROTATION ComputeDisplayRotation() const + { + DXGI_MODE_ROTATION rotation = DXGI_MODE_ROTATION_UNSPECIFIED; + + switch (m_nativeOrientation) + { + case DisplayOrientations::Landscape: + switch (m_currentOrientation) + { + case DisplayOrientations::Landscape: + rotation = DXGI_MODE_ROTATION_IDENTITY; + break; + + case DisplayOrientations::Portrait: + rotation = DXGI_MODE_ROTATION_ROTATE270; + break; + + case DisplayOrientations::LandscapeFlipped: + rotation = DXGI_MODE_ROTATION_ROTATE180; + break; + + case DisplayOrientations::PortraitFlipped: + rotation = DXGI_MODE_ROTATION_ROTATE90; + break; + } + break; + + case DisplayOrientations::Portrait: + switch (m_currentOrientation) + { + case DisplayOrientations::Landscape: + rotation = DXGI_MODE_ROTATION_ROTATE90; + break; + + case DisplayOrientations::Portrait: + rotation = DXGI_MODE_ROTATION_IDENTITY; + break; + + case DisplayOrientations::LandscapeFlipped: + rotation = DXGI_MODE_ROTATION_ROTATE270; + break; + + case DisplayOrientations::PortraitFlipped: + rotation = DXGI_MODE_ROTATION_ROTATE180; + break; + } + break; + } + + return rotation; + } + + void HandleWindowSizeChanged() + { + int outputWidth = ConvertDipsToPixels(m_logicalWidth); + int outputHeight = ConvertDipsToPixels(m_logicalHeight); + + DXGI_MODE_ROTATION rotation = ComputeDisplayRotation(); + + if (rotation == DXGI_MODE_ROTATION_ROTATE90 || rotation == DXGI_MODE_ROTATION_ROTATE270) + { + std::swap(outputWidth, outputHeight); + } + + m_sample->OnWindowSizeChanged(outputWidth, outputHeight, rotation); + } +}; + +ref class ViewProviderFactory : IFrameworkViewSource +{ +public: + virtual IFrameworkView^ CreateView() + { + return ref new ViewProvider(); + } +}; + + +// Entry point +[Platform::MTAThread] +int main(Platform::Array^ argv) +{ + UNREFERENCED_PARAMETER(argv); + + auto viewProviderFactory = ref new ViewProviderFactory(); + CoreApplication::Run(viewProviderFactory); + return 0; +} diff --git a/Samples/Graphics/SimplePBR12/UWP/Package.appxmanifest b/Samples/Graphics/SimplePBR12/UWP/Package.appxmanifest new file mode 100644 index 00000000..f6da96c5 --- /dev/null +++ b/Samples/Graphics/SimplePBR12/UWP/Package.appxmanifest @@ -0,0 +1,49 @@ + + + + + + + + + + SimplePBRUWP12 + Xbox Advanced Technology Group + Assets\StoreLogoUWP.png + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/Graphics/SimplePBR12/UWP/SimplePBRUWP12.cpp b/Samples/Graphics/SimplePBR12/UWP/SimplePBRUWP12.cpp new file mode 100644 index 00000000..7aaa5ee5 --- /dev/null +++ b/Samples/Graphics/SimplePBR12/UWP/SimplePBRUWP12.cpp @@ -0,0 +1,191 @@ +//-------------------------------------------------------------------------------------- +// SimplePBRUWP12.cpp +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#include "pch.h" +#include "SimplePBRUWP12.h" + +#include "ATGColors.h" + +using namespace DirectX; + +using Microsoft::WRL::ComPtr; + +Sample::Sample() +{ + m_deviceResources = std::make_unique(GetBackBufferFormat(), GetDepthFormat()); + m_deviceResources->RegisterDeviceNotify(this); + m_sharedSimplePBR = std::make_unique(this); +} + +// Initialize the Direct3D resources required to run. +void Sample::Initialize(IUnknown* window, int width, int height, DXGI_MODE_ROTATION rotation) +{ + m_deviceResources->SetWindow(window, width, height, rotation); + + m_deviceResources->CreateDeviceResources(); + CreateDeviceDependentResources(); + + m_deviceResources->CreateWindowSizeDependentResources(); + CreateWindowSizeDependentResources(); + + // KB/Mouse should be in + m_keyboard = std::make_unique(); + m_mouse = std::make_unique(); + + m_keyboard->SetWindow(reinterpret_cast(window)); + m_mouse->SetWindow(reinterpret_cast(window)); +} + +#pragma region Frame Update +// Executes basic render loop. +void Sample::Tick() +{ + m_timer.Tick([&]() + { + Update(m_timer); + }); + + Render(); +} + +// Updates the world. +void Sample::Update(DX::StepTimer const& timer) +{ + PIXBeginEvent(PIX_COLOR_DEFAULT, L"Update"); + + // Update mouse/keyboard + auto kb = m_keyboard->GetState(); + m_keyboardButtons.Update(kb); + + if (kb.Escape) + { + Windows::ApplicationModel::Core::CoreApplication::Exit(); + } + + // Update core sample + m_sharedSimplePBR->Update(timer); + + PIXEndEvent(); +} +#pragma endregion + +#pragma region Frame Render +// Draws the scene. +void Sample::Render() +{ + // Don't try to render anything before the f8irst Update. + if (m_timer.GetFrameCount() == 0) + { + return; + } + + // Prepare the command list to render a new frame. + m_deviceResources->Prepare(); + Clear(); + + m_sharedSimplePBR->Render(); + + // Show the new frame. + PIXBeginEvent(m_deviceResources->GetCommandQueue(), PIX_COLOR_DEFAULT, L"Present"); + m_deviceResources->Present(); + m_graphicsMemory->Commit(m_deviceResources->GetCommandQueue()); + PIXEndEvent(m_deviceResources->GetCommandQueue()); +} + +// Helper method to clear the back buffers. +void Sample::Clear() +{ + auto commandList = m_deviceResources->GetCommandList(); + PIXBeginEvent(commandList, PIX_COLOR_DEFAULT, L"Clear"); + + // Clear the views. + auto rtvDescriptor = m_deviceResources->GetRenderTargetView(); + auto dsvDescriptor = m_deviceResources->GetDepthStencilView(); + + commandList->OMSetRenderTargets(1, &rtvDescriptor, FALSE, &dsvDescriptor); + commandList->ClearRenderTargetView(rtvDescriptor, ATG::Colors::Background, 0, nullptr); + commandList->ClearDepthStencilView(dsvDescriptor, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); + + // Set the viewport and scissor rect. + auto viewport = m_deviceResources->GetScreenViewport(); + auto scissorRect = m_deviceResources->GetScissorRect(); + commandList->RSSetViewports(1, &viewport); + commandList->RSSetScissorRects(1, &scissorRect); + + PIXEndEvent(commandList); +} +#pragma endregion + +#pragma region Message Handlers +// Message handlers +void Sample::OnActivated() +{ +} + +void Sample::OnDeactivated() +{ +} + +void Sample::OnSuspending() +{ +} + +void Sample::OnResuming() +{ + m_timer.ResetElapsedTime(); +} + +void Sample::OnWindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation) +{ + if (!m_deviceResources->WindowSizeChanged(width, height, rotation)) + return; + + CreateWindowSizeDependentResources(); +} + +void Sample::ValidateDevice() +{ + m_deviceResources->ValidateDevice(); +} + +// Properties +void Sample::GetDefaultSize(int& width, int& height) const +{ + width = 1280; + height = 720; +} +#pragma endregion + +#pragma region Direct3D Resources +// These are the resources that depend on the device. +void Sample::CreateDeviceDependentResources() +{ + auto device = m_deviceResources->GetD3DDevice(); + m_graphicsMemory = std::make_unique(device); + + m_sharedSimplePBR->CreateDeviceDependentResources(); +} + +// Allocate all memory resources that change on a window SizeChanged event. +void Sample::CreateWindowSizeDependentResources() +{ + m_sharedSimplePBR->CreateWindowSizeDependentResources(); +} + +void Sample::OnDeviceLost() +{ + m_sharedSimplePBR->OnDeviceLost(); + m_graphicsMemory.reset(); +} + +void Sample::OnDeviceRestored() +{ + CreateDeviceDependentResources(); + + CreateWindowSizeDependentResources(); +} +#pragma endregion diff --git a/Samples/Graphics/SimplePBR12/UWP/SimplePBRUWP12.h b/Samples/Graphics/SimplePBR12/UWP/SimplePBRUWP12.h new file mode 100644 index 00000000..25dd8ea8 --- /dev/null +++ b/Samples/Graphics/SimplePBR12/UWP/SimplePBRUWP12.h @@ -0,0 +1,74 @@ +//-------------------------------------------------------------------------------------- +// SimplePBRUWP12.h +// +// Advanced Technology Group (ATG) +// Copyright (C) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#pragma once + +#include "DeviceResources.h" +#include "../Shared/StepTimer.h" +#include "../Shared/SharedSimplePBR.h" + +// A basic sample implementation that creates a D3D12 device and +// provides a render loop. +class Sample : public DX::IDeviceNotify +{ +public: + friend class SharedSimplePBR; + + Sample(); + + // Initialization and management + void Initialize(IUnknown* window, int width, int height, DXGI_MODE_ROTATION rotation); + + // Basic render loop + void Tick(); + + // IDeviceNotify + virtual void OnDeviceLost() override; + virtual void OnDeviceRestored() override; + + // Messages + void OnActivated(); + void OnDeactivated(); + void OnSuspending(); + void OnResuming(); + void OnWindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation); + void ValidateDevice(); + + // Properties + void GetDefaultSize( int& width, int& height ) const; + + inline static DXGI_FORMAT GetHDRRenderFormat() { return DXGI_FORMAT_R16G16B16A16_FLOAT; } + inline static DXGI_FORMAT GetBackBufferFormat() { return DXGI_FORMAT_R16G16B16A16_FLOAT; } + inline static DXGI_FORMAT GetDepthFormat() { return DXGI_FORMAT_D32_FLOAT; } + +private: + + void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); + + void CreateDeviceDependentResources(); + void CreateWindowSizeDependentResources(); + + // Device resources. + std::unique_ptr m_deviceResources; + + // Rendering loop timer. + DX::StepTimer m_timer; + + // Input + std::unique_ptr m_keyboard; + DirectX::Keyboard::KeyboardStateTracker m_keyboardButtons; + std::unique_ptr m_mouse; + + // DirectXTK objects. + std::unique_ptr m_graphicsMemory; + + // Core shared sample object + std::unique_ptr m_sharedSimplePBR; +}; \ No newline at end of file diff --git a/Samples/Graphics/SimplePBR12/UWP/d3dx12.h b/Samples/Graphics/SimplePBR12/UWP/d3dx12.h new file mode 100644 index 00000000..6538b82b --- /dev/null +++ b/Samples/Graphics/SimplePBR12/UWP/d3dx12.h @@ -0,0 +1,1946 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#ifndef __D3DX12_H__ +#define __D3DX12_H__ + +#include "d3d12.h" + +#if defined( __cplusplus ) + +struct CD3DX12_DEFAULT {}; +extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT; + +//------------------------------------------------------------------------------------------------ +inline bool operator==( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) +{ + return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width && + l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth; +} + +//------------------------------------------------------------------------------------------------ +inline bool operator!=( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RECT : public D3D12_RECT +{ + CD3DX12_RECT() + {} + explicit CD3DX12_RECT( const D3D12_RECT& o ) : + D3D12_RECT( o ) + {} + explicit CD3DX12_RECT( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = Left; + top = Top; + right = Right; + bottom = Bottom; + } + ~CD3DX12_RECT() {} + operator const D3D12_RECT&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BOX : public D3D12_BOX +{ + CD3DX12_BOX() + {} + explicit CD3DX12_BOX( const D3D12_BOX& o ) : + D3D12_BOX( o ) + {} + explicit CD3DX12_BOX( + LONG Left, + LONG Right ) + { + left = Left; + top = 0; + front = 0; + right = Right; + bottom = 1; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = Left; + top = Top; + front = 0; + right = Right; + bottom = Bottom; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Front, + LONG Right, + LONG Bottom, + LONG Back ) + { + left = Left; + top = Top; + front = Front; + right = Right; + bottom = Bottom; + back = Back; + } + ~CD3DX12_BOX() {} + operator const D3D12_BOX&() const { return *this; } +}; +inline bool operator==( const D3D12_BOX& l, const D3D12_BOX& r ) +{ + return l.left == r.left && l.top == r.top && l.front == r.front && + l.right == r.right && l.bottom == r.bottom && l.back == r.back; +} +inline bool operator!=( const D3D12_BOX& l, const D3D12_BOX& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC +{ + CD3DX12_DEPTH_STENCIL_DESC() + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( const D3D12_DEPTH_STENCIL_DESC& o ) : + D3D12_DEPTH_STENCIL_DESC( o ) + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( CD3DX12_DEFAULT ) + { + DepthEnable = TRUE; + DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D12_COMPARISON_FUNC_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + } + explicit CD3DX12_DEPTH_STENCIL_DESC( + BOOL depthEnable, + D3D12_DEPTH_WRITE_MASK depthWriteMask, + D3D12_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D12_STENCIL_OP frontStencilFailOp, + D3D12_STENCIL_OP frontStencilDepthFailOp, + D3D12_STENCIL_OP frontStencilPassOp, + D3D12_COMPARISON_FUNC frontStencilFunc, + D3D12_STENCIL_OP backStencilFailOp, + D3D12_STENCIL_OP backStencilDepthFailOp, + D3D12_STENCIL_OP backStencilPassOp, + D3D12_COMPARISON_FUNC backStencilFunc ) + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + } + ~CD3DX12_DEPTH_STENCIL_DESC() {} + operator const D3D12_DEPTH_STENCIL_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC +{ + CD3DX12_BLEND_DESC() + {} + explicit CD3DX12_BLEND_DESC( const D3D12_BLEND_DESC& o ) : + D3D12_BLEND_DESC( o ) + {} + explicit CD3DX12_BLEND_DESC( CD3DX12_DEFAULT ) + { + AlphaToCoverageEnable = FALSE; + IndependentBlendEnable = FALSE; + const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = + { + FALSE,FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL, + }; + for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + RenderTarget[ i ] = defaultRenderTargetBlendDesc; + } + ~CD3DX12_BLEND_DESC() {} + operator const D3D12_BLEND_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC +{ + CD3DX12_RASTERIZER_DESC() + {} + explicit CD3DX12_RASTERIZER_DESC( const D3D12_RASTERIZER_DESC& o ) : + D3D12_RASTERIZER_DESC( o ) + {} + explicit CD3DX12_RASTERIZER_DESC( CD3DX12_DEFAULT ) + { + FillMode = D3D12_FILL_MODE_SOLID; + CullMode = D3D12_CULL_MODE_BACK; + FrontCounterClockwise = FALSE; + DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = TRUE; + MultisampleEnable = FALSE; + AntialiasedLineEnable = FALSE; + ForcedSampleCount = 0; + ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + } + explicit CD3DX12_RASTERIZER_DESC( + D3D12_FILL_MODE fillMode, + D3D12_CULL_MODE cullMode, + BOOL frontCounterClockwise, + INT depthBias, + FLOAT depthBiasClamp, + FLOAT slopeScaledDepthBias, + BOOL depthClipEnable, + BOOL multisampleEnable, + BOOL antialiasedLineEnable, + UINT forcedSampleCount, + D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster) + { + FillMode = fillMode; + CullMode = cullMode; + FrontCounterClockwise = frontCounterClockwise; + DepthBias = depthBias; + DepthBiasClamp = depthBiasClamp; + SlopeScaledDepthBias = slopeScaledDepthBias; + DepthClipEnable = depthClipEnable; + MultisampleEnable = multisampleEnable; + AntialiasedLineEnable = antialiasedLineEnable; + ForcedSampleCount = forcedSampleCount; + ConservativeRaster = conservativeRaster; + } + ~CD3DX12_RASTERIZER_DESC() {} + operator const D3D12_RASTERIZER_DESC&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO +{ + CD3DX12_RESOURCE_ALLOCATION_INFO() + {} + explicit CD3DX12_RESOURCE_ALLOCATION_INFO( const D3D12_RESOURCE_ALLOCATION_INFO& o ) : + D3D12_RESOURCE_ALLOCATION_INFO( o ) + {} + CD3DX12_RESOURCE_ALLOCATION_INFO( + UINT64 size, + UINT64 alignment ) + { + SizeInBytes = size; + Alignment = alignment; + } + operator const D3D12_RESOURCE_ALLOCATION_INFO&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES +{ + CD3DX12_HEAP_PROPERTIES() + {} + explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) : + D3D12_HEAP_PROPERTIES(o) + {} + CD3DX12_HEAP_PROPERTIES( + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) + { + Type = D3D12_HEAP_TYPE_CUSTOM; + CPUPageProperty = cpuPageProperty; + MemoryPoolPreference = memoryPoolPreference; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + explicit CD3DX12_HEAP_PROPERTIES( + D3D12_HEAP_TYPE type, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) + { + Type = type; + CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + operator const D3D12_HEAP_PROPERTIES&() const { return *this; } + bool IsCPUAccessible() const + { + return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM && + (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)); + } +}; +inline bool operator==( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) +{ + return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty && + l.MemoryPoolPreference == r.MemoryPoolPreference && + l.CreationNodeMask == r.CreationNodeMask && + l.VisibleNodeMask == r.VisibleNodeMask; +} +inline bool operator!=( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC +{ + CD3DX12_HEAP_DESC() + {} + explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) : + D3D12_HEAP_DESC(o) + {} + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_PROPERTIES properties, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = properties; + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_TYPE type, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_PROPERTIES properties, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = properties; + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_TYPE type, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + operator const D3D12_HEAP_DESC&() const { return *this; } + bool IsCPUAccessible() const + { return static_cast< const CD3DX12_HEAP_PROPERTIES* >( &Properties )->IsCPUAccessible(); } +}; +inline bool operator==( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) +{ + return l.SizeInBytes == r.SizeInBytes && + l.Properties == r.Properties && + l.Alignment == r.Alignment && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE +{ + CD3DX12_CLEAR_VALUE() + {} + explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) : + D3D12_CLEAR_VALUE(o) + {} + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + const FLOAT color[4] ) + { + Format = format; + memcpy( Color, color, sizeof( Color ) ); + } + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + FLOAT depth, + UINT8 stencil ) + { + Format = format; + /* Use memcpy to preserve NAN values */ + memcpy( &DepthStencil.Depth, &depth, sizeof( depth ) ); + DepthStencil.Stencil = stencil; + } + operator const D3D12_CLEAR_VALUE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RANGE : public D3D12_RANGE +{ + CD3DX12_RANGE() + {} + explicit CD3DX12_RANGE(const D3D12_RANGE &o) : + D3D12_RANGE(o) + {} + CD3DX12_RANGE( + SIZE_T begin, + SIZE_T end ) + { + Begin = begin; + End = end; + } + operator const D3D12_RANGE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SHADER_BYTECODE : public D3D12_SHADER_BYTECODE +{ + CD3DX12_SHADER_BYTECODE() + {} + explicit CD3DX12_SHADER_BYTECODE(const D3D12_SHADER_BYTECODE &o) : + D3D12_SHADER_BYTECODE(o) + {} + CD3DX12_SHADER_BYTECODE( + ID3DBlob* pShaderBlob ) + { + pShaderBytecode = pShaderBlob->GetBufferPointer(); + BytecodeLength = pShaderBlob->GetBufferSize(); + } + CD3DX12_SHADER_BYTECODE( + void* _pShaderBytecode, + SIZE_T bytecodeLength ) + { + pShaderBytecode = _pShaderBytecode; + BytecodeLength = bytecodeLength; + } + operator const D3D12_SHADER_BYTECODE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE +{ + CD3DX12_TILED_RESOURCE_COORDINATE() + {} + explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE &o) : + D3D12_TILED_RESOURCE_COORDINATE(o) + {} + CD3DX12_TILED_RESOURCE_COORDINATE( + UINT x, + UINT y, + UINT z, + UINT subresource ) + { + X = x; + Y = y; + Z = z; + Subresource = subresource; + } + operator const D3D12_TILED_RESOURCE_COORDINATE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE +{ + CD3DX12_TILE_REGION_SIZE() + {} + explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE &o) : + D3D12_TILE_REGION_SIZE(o) + {} + CD3DX12_TILE_REGION_SIZE( + UINT numTiles, + BOOL useBox, + UINT width, + UINT16 height, + UINT16 depth ) + { + NumTiles = numTiles; + UseBox = useBox; + Width = width; + Height = height; + Depth = depth; + } + operator const D3D12_TILE_REGION_SIZE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING +{ + CD3DX12_SUBRESOURCE_TILING() + {} + explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) : + D3D12_SUBRESOURCE_TILING(o) + {} + CD3DX12_SUBRESOURCE_TILING( + UINT widthInTiles, + UINT16 heightInTiles, + UINT16 depthInTiles, + UINT startTileIndexInOverallResource ) + { + WidthInTiles = widthInTiles; + HeightInTiles = heightInTiles; + DepthInTiles = depthInTiles; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } + operator const D3D12_SUBRESOURCE_TILING&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE +{ + CD3DX12_TILE_SHAPE() + {} + explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE &o) : + D3D12_TILE_SHAPE(o) + {} + CD3DX12_TILE_SHAPE( + UINT widthInTexels, + UINT heightInTexels, + UINT depthInTexels ) + { + WidthInTexels = widthInTexels; + HeightInTexels = heightInTexels; + DepthInTexels = depthInTexels; + } + operator const D3D12_TILE_SHAPE&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER +{ + CD3DX12_RESOURCE_BARRIER() + {} + explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) : + D3D12_RESOURCE_BARRIER(o) + {} + static inline CD3DX12_RESOURCE_BARRIER Transition( + _In_ ID3D12Resource* pResource, + D3D12_RESOURCE_STATES stateBefore, + D3D12_RESOURCE_STATES stateAfter, + UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, + D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + result.Flags = flags; + barrier.Transition.pResource = pResource; + barrier.Transition.StateBefore = stateBefore; + barrier.Transition.StateAfter = stateAfter; + barrier.Transition.Subresource = subresource; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER Aliasing( + _In_ ID3D12Resource* pResourceBefore, + _In_ ID3D12Resource* pResourceAfter) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; + barrier.Aliasing.pResourceBefore = pResourceBefore; + barrier.Aliasing.pResourceAfter = pResourceAfter; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER UAV( + _In_ ID3D12Resource* pResource) + { + CD3DX12_RESOURCE_BARRIER result; + ZeroMemory(&result, sizeof(result)); + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.UAV.pResource = pResource; + return result; + } + operator const D3D12_RESOURCE_BARRIER&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO +{ + CD3DX12_PACKED_MIP_INFO() + {} + explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) : + D3D12_PACKED_MIP_INFO(o) + {} + CD3DX12_PACKED_MIP_INFO( + UINT8 numStandardMips, + UINT8 numPackedMips, + UINT numTilesForPackedMips, + UINT startTileIndexInOverallResource ) + { + NumStandardMips = numStandardMips; + NumPackedMips = numPackedMips; + NumTilesForPackedMips = numTilesForPackedMips; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } + operator const D3D12_PACKED_MIP_INFO&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT +{ + CD3DX12_SUBRESOURCE_FOOTPRINT() + {} + explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT &o) : + D3D12_SUBRESOURCE_FOOTPRINT(o) + {} + CD3DX12_SUBRESOURCE_FOOTPRINT( + DXGI_FORMAT format, + UINT width, + UINT height, + UINT depth, + UINT rowPitch ) + { + Format = format; + Width = width; + Height = height; + Depth = depth; + RowPitch = rowPitch; + } + explicit CD3DX12_SUBRESOURCE_FOOTPRINT( + const D3D12_RESOURCE_DESC& resDesc, + UINT rowPitch ) + { + Format = resDesc.Format; + Width = UINT( resDesc.Width ); + Height = resDesc.Height; + Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1); + RowPitch = rowPitch; + } + operator const D3D12_SUBRESOURCE_FOOTPRINT&() const { return *this; } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION +{ + CD3DX12_TEXTURE_COPY_LOCATION() + {} + explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) : + D3D12_TEXTURE_COPY_LOCATION(o) + {} + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes) { pResource = pRes; } + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + PlacedFootprint = Footprint; + } + CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, UINT Sub) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + SubresourceIndex = Sub; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE +{ + CD3DX12_DESCRIPTOR_RANGE() { } + explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE &o) : + D3D12_DESCRIPTOR_RANGE(o) + {} + CD3DX12_DESCRIPTOR_RANGE( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + inline void Init( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + static inline void Init( + _Out_ D3D12_DESCRIPTOR_RANGE &range, + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + range.RangeType = rangeType; + range.NumDescriptors = numDescriptors; + range.BaseShaderRegister = baseShaderRegister; + range.RegisterSpace = registerSpace; + range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE +{ + CD3DX12_ROOT_DESCRIPTOR_TABLE() {} + explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE &o) : + D3D12_ROOT_DESCRIPTOR_TABLE(o) + {} + CD3DX12_ROOT_DESCRIPTOR_TABLE( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(numDescriptorRanges, _pDescriptorRanges); + } + + inline void Init( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(*this, numDescriptorRanges, _pDescriptorRanges); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR_TABLE &rootDescriptorTable, + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; + rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS +{ + CD3DX12_ROOT_CONSTANTS() {} + explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS &o) : + D3D12_ROOT_CONSTANTS(o) + {} + CD3DX12_ROOT_CONSTANTS( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(num32BitValues, shaderRegister, registerSpace); + } + + inline void Init( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, num32BitValues, shaderRegister, registerSpace); + } + + static inline void Init( + _Out_ D3D12_ROOT_CONSTANTS &rootConstants, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + rootConstants.Num32BitValues = num32BitValues; + rootConstants.ShaderRegister = shaderRegister; + rootConstants.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR +{ + CD3DX12_ROOT_DESCRIPTOR() {} + explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR &o) : + D3D12_ROOT_DESCRIPTOR(o) + {} + CD3DX12_ROOT_DESCRIPTOR( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(shaderRegister, registerSpace); + } + + inline void Init( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, shaderRegister, registerSpace); + } + + static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR &table, UINT shaderRegister, UINT registerSpace = 0) + { + table.ShaderRegister = shaderRegister; + table.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER +{ + CD3DX12_ROOT_PARAMETER() {} + explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER &o) : + D3D12_ROOT_PARAMETER(o) + {} + + static inline void InitAsDescriptorTable( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); + } + + static inline void InitAsConstants( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); + } + + static inline void InitAsConstantBufferView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsShaderResourceView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsUnorderedAccessView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + inline void InitAsDescriptorTable( + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); + } + + inline void InitAsConstants( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); + } + + inline void InitAsConstantBufferView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsShaderResourceView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsUnorderedAccessView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC +{ + CD3DX12_STATIC_SAMPLER_DESC() {} + explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC &o) : + D3D12_STATIC_SAMPLER_DESC(o) + {} + CD3DX12_STATIC_SAMPLER_DESC( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + + static inline void Init( + _Out_ D3D12_STATIC_SAMPLER_DESC &samplerDesc, + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + samplerDesc.ShaderRegister = shaderRegister; + samplerDesc.Filter = filter; + samplerDesc.AddressU = addressU; + samplerDesc.AddressV = addressV; + samplerDesc.AddressW = addressW; + samplerDesc.MipLODBias = mipLODBias; + samplerDesc.MaxAnisotropy = maxAnisotropy; + samplerDesc.ComparisonFunc = comparisonFunc; + samplerDesc.BorderColor = borderColor; + samplerDesc.MinLOD = minLOD; + samplerDesc.MaxLOD = maxLOD; + samplerDesc.ShaderVisibility = shaderVisibility; + samplerDesc.RegisterSpace = registerSpace; + } + inline void Init( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + *this, + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC +{ + CD3DX12_ROOT_SIGNATURE_DESC() {} + explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) : + D3D12_ROOT_SIGNATURE_DESC(o) + {} + CD3DX12_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) + { + Init(0, NULL, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_NONE); + } + + inline void Init( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init( + _Out_ D3D12_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + desc.NumParameters = numParameters; + desc.pParameters = _pParameters; + desc.NumStaticSamplers = numStaticSamplers; + desc.pStaticSamplers = _pStaticSamplers; + desc.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DESCRIPTOR_RANGE1 : public D3D12_DESCRIPTOR_RANGE1 +{ + CD3DX12_DESCRIPTOR_RANGE1() { } + explicit CD3DX12_DESCRIPTOR_RANGE1(const D3D12_DESCRIPTOR_RANGE1 &o) : + D3D12_DESCRIPTOR_RANGE1(o) + {} + CD3DX12_DESCRIPTOR_RANGE1( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + D3D12_DESCRIPTOR_RANGE_FLAGS flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, flags, offsetInDescriptorsFromTableStart); + } + + inline void Init( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + D3D12_DESCRIPTOR_RANGE_FLAGS flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, flags, offsetInDescriptorsFromTableStart); + } + + static inline void Init( + _Out_ D3D12_DESCRIPTOR_RANGE1 &range, + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + D3D12_DESCRIPTOR_RANGE_FLAGS flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + range.RangeType = rangeType; + range.NumDescriptors = numDescriptors; + range.BaseShaderRegister = baseShaderRegister; + range.RegisterSpace = registerSpace; + range.Flags = flags; + range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR_TABLE1 : public D3D12_ROOT_DESCRIPTOR_TABLE1 +{ + CD3DX12_ROOT_DESCRIPTOR_TABLE1() {} + explicit CD3DX12_ROOT_DESCRIPTOR_TABLE1(const D3D12_ROOT_DESCRIPTOR_TABLE1 &o) : + D3D12_ROOT_DESCRIPTOR_TABLE1(o) + {} + CD3DX12_ROOT_DESCRIPTOR_TABLE1( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* _pDescriptorRanges) + { + Init(numDescriptorRanges, _pDescriptorRanges); + } + + inline void Init( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* _pDescriptorRanges) + { + Init(*this, numDescriptorRanges, _pDescriptorRanges); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR_TABLE1 &rootDescriptorTable, + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* _pDescriptorRanges) + { + rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; + rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR1 : public D3D12_ROOT_DESCRIPTOR1 +{ + CD3DX12_ROOT_DESCRIPTOR1() {} + explicit CD3DX12_ROOT_DESCRIPTOR1(const D3D12_ROOT_DESCRIPTOR1 &o) : + D3D12_ROOT_DESCRIPTOR1(o) + {} + CD3DX12_ROOT_DESCRIPTOR1( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE) + { + Init(shaderRegister, registerSpace, flags); + } + + inline void Init( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE) + { + Init(*this, shaderRegister, registerSpace, flags); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR1 &table, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE) + { + table.ShaderRegister = shaderRegister; + table.RegisterSpace = registerSpace; + table.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_PARAMETER1 : public D3D12_ROOT_PARAMETER1 +{ + CD3DX12_ROOT_PARAMETER1() {} + explicit CD3DX12_ROOT_PARAMETER1(const D3D12_ROOT_PARAMETER1 &o) : + D3D12_ROOT_PARAMETER1(o) + {} + + static inline void InitAsDescriptorTable( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR_TABLE1::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); + } + + static inline void InitAsConstants( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); + } + + static inline void InitAsConstantBufferView( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR1::Init(rootParam.Descriptor, shaderRegister, registerSpace, flags); + } + + static inline void InitAsShaderResourceView( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR1::Init(rootParam.Descriptor, shaderRegister, registerSpace, flags); + } + + static inline void InitAsUnorderedAccessView( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR1::Init(rootParam.Descriptor, shaderRegister, registerSpace, flags); + } + + inline void InitAsDescriptorTable( + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); + } + + inline void InitAsConstants( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); + } + + inline void InitAsConstantBufferView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstantBufferView(*this, shaderRegister, registerSpace, flags, visibility); + } + + inline void InitAsShaderResourceView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsShaderResourceView(*this, shaderRegister, registerSpace, flags, visibility); + } + + inline void InitAsUnorderedAccessView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, flags, visibility); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC : public D3D12_VERSIONED_ROOT_SIGNATURE_DESC +{ + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC() {} + explicit CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC &o) : + D3D12_VERSIONED_ROOT_SIGNATURE_DESC(o) + {} + explicit CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) + { + Version = D3D_ROOT_SIGNATURE_VERSION_1_0; + Desc_1_0 = o; + } + explicit CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC1 &o) + { + Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + Desc_1_1 = o; + } + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init_1_0(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER1* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init_1_1(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) + { + Init_1_1(0, NULL, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_NONE); + } + + inline void Init_1_0( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init_1_0(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init_1_0( + _Out_ D3D12_VERSIONED_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + desc.Version = D3D_ROOT_SIGNATURE_VERSION_1_0; + desc.Desc_1_0.NumParameters = numParameters; + desc.Desc_1_0.pParameters = _pParameters; + desc.Desc_1_0.NumStaticSamplers = numStaticSamplers; + desc.Desc_1_0.pStaticSamplers = _pStaticSamplers; + desc.Desc_1_0.Flags = flags; + } + + inline void Init_1_1( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER1* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init_1_1(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init_1_1( + _Out_ D3D12_VERSIONED_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER1* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + desc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + desc.Desc_1_1.NumParameters = numParameters; + desc.Desc_1_1.pParameters = _pParameters; + desc.Desc_1_1.NumStaticSamplers = numStaticSamplers; + desc.Desc_1_1.pStaticSamplers = _pStaticSamplers; + desc.Desc_1_1.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE +{ + CD3DX12_CPU_DESCRIPTOR_HANDLE() {} + explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) : + D3D12_CPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr += offsetInDescriptors * descriptorIncrementSize; + return *this; + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr += offsetScaledByIncrementSize; + return *this; + } + bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) const + { + return (ptr == other.ptr); + } + bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) const + { + return (ptr != other.ptr); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = base.ptr + offsetScaledByIncrementSize; + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE +{ + CD3DX12_GPU_DESCRIPTOR_HANDLE() {} + explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE &o) : + D3D12_GPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr += offsetInDescriptors * descriptorIncrementSize; + return *this; + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr += offsetScaledByIncrementSize; + return *this; + } + inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) const + { + return (ptr == other.ptr); + } + inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) const + { + return (ptr != other.ptr); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE &operator=(const D3D12_GPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = base.ptr + offsetScaledByIncrementSize; + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize; + } +}; + +//------------------------------------------------------------------------------------------------ +inline UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize ) +{ + return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; +} + +//------------------------------------------------------------------------------------------------ +template +inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) +{ + MipSlice = static_cast(Subresource % MipLevels); + ArraySlice = static_cast((Subresource / MipLevels) % ArraySize); + PlaneSlice = static_cast(Subresource / (MipLevels * ArraySize)); +} + +//------------------------------------------------------------------------------------------------ +inline UINT8 D3D12GetFormatPlaneCount( + _In_ ID3D12Device* pDevice, + DXGI_FORMAT Format + ) +{ + D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = {Format}; + if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)))) + { + return 0; + } + return formatInfo.PlaneCount; +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC +{ + CD3DX12_RESOURCE_DESC() + {} + explicit CD3DX12_RESOURCE_DESC( const D3D12_RESOURCE_DESC& o ) : + D3D12_RESOURCE_DESC( o ) + {} + CD3DX12_RESOURCE_DESC( + D3D12_RESOURCE_DIMENSION dimension, + UINT64 alignment, + UINT64 width, + UINT height, + UINT16 depthOrArraySize, + UINT16 mipLevels, + DXGI_FORMAT format, + UINT sampleCount, + UINT sampleQuality, + D3D12_TEXTURE_LAYOUT layout, + D3D12_RESOURCE_FLAGS flags ) + { + Dimension = dimension; + Alignment = alignment; + Width = width; + Height = height; + DepthOrArraySize = depthOrArraySize; + MipLevels = mipLevels; + Format = format; + SampleDesc.Count = sampleCount; + SampleDesc.Quality = sampleQuality; + Layout = layout; + Flags = flags; + } + static inline CD3DX12_RESOURCE_DESC Buffer( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes, + 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Buffer( + UINT64 width, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1, + DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex1D( + DXGI_FORMAT format, + UINT64 width, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize, + mipLevels, format, 1, 0, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex2D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + UINT sampleCount = 1, + UINT sampleQuality = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize, + mipLevels, format, sampleCount, sampleQuality, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex3D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 depth, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth, + mipLevels, format, 1, 0, layout, flags ); + } + inline UINT16 Depth() const + { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT16 ArraySize() const + { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const + { return D3D12GetFormatPlaneCount(pDevice, Format); } + inline UINT Subresources(_In_ ID3D12Device* pDevice) const + { return MipLevels * ArraySize() * PlaneCount(pDevice); } + inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) + { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); } + operator const D3D12_RESOURCE_DESC&() const { return *this; } +}; +inline bool operator==( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) +{ + return l.Dimension == r.Dimension && + l.Alignment == r.Alignment && + l.Width == r.Width && + l.Height == r.Height && + l.DepthOrArraySize == r.DepthOrArraySize && + l.MipLevels == r.MipLevels && + l.Format == r.Format && + l.SampleDesc.Count == r.SampleDesc.Count && + l.SampleDesc.Quality == r.SampleDesc.Quality && + l.Layout == r.Layout && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +// Row-by-row memcpy +inline void MemcpySubresource( + _In_ const D3D12_MEMCPY_DEST* pDest, + _In_ const D3D12_SUBRESOURCE_DATA* pSrc, + SIZE_T RowSizeInBytes, + UINT NumRows, + UINT NumSlices) +{ + for (UINT z = 0; z < NumSlices; ++z) + { + BYTE* pDestSlice = reinterpret_cast(pDest->pData) + pDest->SlicePitch * z; + const BYTE* pSrcSlice = reinterpret_cast(pSrc->pData) + pSrc->SlicePitch * z; + for (UINT y = 0; y < NumRows; ++y) + { + memcpy(pDestSlice + pDest->RowPitch * y, + pSrcSlice + pSrc->RowPitch * y, + RowSizeInBytes); + } + } +} + +//------------------------------------------------------------------------------------------------ +// Returns required size of a buffer to be used for data upload +inline UINT64 GetRequiredIntermediateSize( + _In_ ID3D12Resource* pDestinationResource, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources) +{ + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + UINT64 RequiredSize = 0; + + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize); + pDevice->Release(); + + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// All arrays must be populated (e.g. by calling GetCopyableFootprints) +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 RequiredSize, + _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, + _In_reads_(NumSubresources) const UINT* pNumRows, + _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes, + _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) +{ + // Minor validation + D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc(); + D3D12_RESOURCE_DESC DestinationDesc = pDestinationResource->GetDesc(); + if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || + IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || + RequiredSize > (SIZE_T)-1 || + (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && + (FirstSubresource != 0 || NumSubresources != 1))) + { + return 0; + } + + BYTE* pData; + HRESULT hr = pIntermediate->Map(0, NULL, reinterpret_cast(&pData)); + if (FAILED(hr)) + { + return 0; + } + + for (UINT i = 0; i < NumSubresources; ++i) + { + if (pRowSizesInBytes[i] > (SIZE_T)-1) return 0; + D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, pLayouts[i].Footprint.RowPitch * pNumRows[i] }; + MemcpySubresource(&DestData, &pSrcData[i], (SIZE_T)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth); + } + pIntermediate->Unmap(0, NULL); + + if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + CD3DX12_BOX SrcBox( UINT( pLayouts[0].Offset ), UINT( pLayouts[0].Offset + pLayouts[0].Footprint.Width ) ); + pCmdList->CopyBufferRegion( + pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (UINT i = 0; i < NumSubresources; ++i) + { + CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource); + CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]); + pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr); + } + } + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// Heap-allocating UpdateSubresources implementation +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + UINT64 MemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources; + if (MemToAlloc > SIZE_MAX) + { + return 0; + } + void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast(MemToAlloc)); + if (pMem == NULL) + { + return 0; + } + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + NumSubresources); + UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + NumSubresources); + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); + pDevice->Release(); + + UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); + HeapFree(GetProcessHeap(), 0, pMem); + return Result; +} + +//------------------------------------------------------------------------------------------------ +// Stack-allocating UpdateSubresources implementation +template +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0, MaxSubresources) UINT FirstSubresource, + _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources]; + UINT NumRows[MaxSubresources]; + UINT64 RowSizesInBytes[MaxSubresources]; + + D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice; + pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); + pDevice->Release(); + + return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); +} + +//------------------------------------------------------------------------------------------------ +inline bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) +{ return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; } + +//------------------------------------------------------------------------------------------------ +inline ID3D12CommandList * const * CommandListCast(ID3D12GraphicsCommandList * const * pp) +{ + // This cast is useful for passing strongly typed command list pointers into + // ExecuteCommandLists. + // This cast is valid as long as the const-ness is respected. D3D12 APIs do + // respect the const-ness of their arguments. + return reinterpret_cast(pp); +} + +//------------------------------------------------------------------------------------------------ +// D3D12 exports a new method for serializing root signatures in the Windows 10 Anniversary Update. +// To help enable root signature 1.1 features when they are available and not require maintaining +// two code paths for building root signatures, this helper method reconstructs a 1.0 signature when +// 1.1 is not supported. +inline HRESULT D3DX12SerializeVersionedRootSignature( + _In_ const D3D12_VERSIONED_ROOT_SIGNATURE_DESC* pRootSignatureDesc, + D3D_ROOT_SIGNATURE_VERSION MaxVersion, + _Outptr_ ID3DBlob** ppBlob, + _Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob) +{ + switch (MaxVersion) + { + case D3D_ROOT_SIGNATURE_VERSION_1_0: + switch (pRootSignatureDesc->Version) + { + case D3D_ROOT_SIGNATURE_VERSION_1_0: + return D3D12SerializeRootSignature(&pRootSignatureDesc->Desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); + + case D3D_ROOT_SIGNATURE_VERSION_1_1: + { + const D3D12_ROOT_SIGNATURE_DESC1& desc_1_1 = pRootSignatureDesc->Desc_1_1; + + SIZE_T ParametersSize = sizeof(D3D12_ROOT_PARAMETER) * desc_1_1.NumParameters; + void* pParameters = (ParametersSize > 0) ? HeapAlloc(GetProcessHeap(), 0, ParametersSize) : NULL; + D3D12_ROOT_PARAMETER* pParameters_1_0 = reinterpret_cast(pParameters); + + for (UINT n = 0; n < desc_1_1.NumParameters; n++) + { + pParameters_1_0[n].ParameterType = desc_1_1.pParameters[n].ParameterType; + pParameters_1_0[n].ShaderVisibility = desc_1_1.pParameters[n].ShaderVisibility; + + switch (desc_1_1.pParameters[n].ParameterType) + { + case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: + pParameters_1_0[n].Constants.Num32BitValues = desc_1_1.pParameters[n].Constants.Num32BitValues; + pParameters_1_0[n].Constants.RegisterSpace = desc_1_1.pParameters[n].Constants.RegisterSpace; + pParameters_1_0[n].Constants.ShaderRegister = desc_1_1.pParameters[n].Constants.ShaderRegister; + break; + + case D3D12_ROOT_PARAMETER_TYPE_CBV: + case D3D12_ROOT_PARAMETER_TYPE_SRV: + case D3D12_ROOT_PARAMETER_TYPE_UAV: + pParameters_1_0[n].Descriptor.RegisterSpace = desc_1_1.pParameters[n].Descriptor.RegisterSpace; + pParameters_1_0[n].Descriptor.ShaderRegister = desc_1_1.pParameters[n].Descriptor.ShaderRegister; + break; + + case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: + const D3D12_ROOT_DESCRIPTOR_TABLE1& table_1_1 = desc_1_1.pParameters[n].DescriptorTable; + + SIZE_T DescriptorRangesSize = sizeof(D3D12_DESCRIPTOR_RANGE) * table_1_1.NumDescriptorRanges; + void* pDescriptorRanges = (DescriptorRangesSize > 0) ? HeapAlloc(GetProcessHeap(), 0, DescriptorRangesSize) : NULL; + D3D12_DESCRIPTOR_RANGE* pDescriptorRanges_1_0 = reinterpret_cast(pDescriptorRanges); + + for (UINT x = 0; x < table_1_1.NumDescriptorRanges; x++) + { + pDescriptorRanges_1_0[x].BaseShaderRegister = table_1_1.pDescriptorRanges[x].BaseShaderRegister; + pDescriptorRanges_1_0[x].NumDescriptors = table_1_1.pDescriptorRanges[x].NumDescriptors; + pDescriptorRanges_1_0[x].OffsetInDescriptorsFromTableStart = table_1_1.pDescriptorRanges[x].OffsetInDescriptorsFromTableStart; + pDescriptorRanges_1_0[x].RangeType = table_1_1.pDescriptorRanges[x].RangeType; + pDescriptorRanges_1_0[x].RegisterSpace = table_1_1.pDescriptorRanges[x].RegisterSpace; + } + + D3D12_ROOT_DESCRIPTOR_TABLE& table_1_0 = pParameters_1_0[n].DescriptorTable; + table_1_0.NumDescriptorRanges = table_1_1.NumDescriptorRanges; + table_1_0.pDescriptorRanges = pDescriptorRanges_1_0; + } + } + + CD3DX12_ROOT_SIGNATURE_DESC desc_1_0(desc_1_1.NumParameters, pParameters_1_0, desc_1_1.NumStaticSamplers, desc_1_1.pStaticSamplers, desc_1_1.Flags); + HRESULT hr = D3D12SerializeRootSignature(&desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); + + for (UINT n = 0; n < desc_1_0.NumParameters; n++) + { + if (desc_1_0.pParameters[n].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) + { + HeapFree(GetProcessHeap(), 0, reinterpret_cast(const_cast(pParameters_1_0[n].DescriptorTable.pDescriptorRanges))); + } + } + HeapFree(GetProcessHeap(), 0, pParameters); + return hr; + } + } + break; + + case D3D_ROOT_SIGNATURE_VERSION_1_1: + return D3D12SerializeVersionedRootSignature(pRootSignatureDesc, ppBlob, ppErrorBlob); + } + + return E_INVALIDARG; +} + +#endif // defined( __cplusplus ) + +#endif //__D3DX12_H__ + + + diff --git a/Samples/IntroGraphics/DirectXTKSimpleSampleUWP/DirectXTKSimpleSample.h b/Samples/IntroGraphics/DirectXTKSimpleSampleUWP/DirectXTKSimpleSample.h index f96f6247..3325c532 100644 --- a/Samples/IntroGraphics/DirectXTKSimpleSampleUWP/DirectXTKSimpleSample.h +++ b/Samples/IntroGraphics/DirectXTKSimpleSampleUWP/DirectXTKSimpleSample.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -48,6 +44,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/IntroGraphics/DirectXTKSimpleSampleUWP12/DirectXTKSimpleSample12.cpp b/Samples/IntroGraphics/DirectXTKSimpleSampleUWP12/DirectXTKSimpleSample12.cpp index 841de6f6..b8a2ade9 100644 --- a/Samples/IntroGraphics/DirectXTKSimpleSampleUWP12/DirectXTKSimpleSample12.cpp +++ b/Samples/IntroGraphics/DirectXTKSimpleSampleUWP12/DirectXTKSimpleSample12.cpp @@ -433,9 +433,6 @@ void Sample::CreateDeviceDependentResources() // Upload the resources to the GPU. auto uploadResourcesFinished = resourceUpload.End(m_deviceResources->GetCommandQueue()); - // Wait for the command list to finish executing - m_deviceResources->WaitForGpu(); - // Wait for the upload thread to terminate uploadResourcesFinished.wait(); } diff --git a/Samples/IntroGraphics/DirectXTKSimpleSampleUWP12/DirectXTKSimpleSample12.h b/Samples/IntroGraphics/DirectXTKSimpleSampleUWP12/DirectXTKSimpleSample12.h index 290d9094..93cfbc90 100644 --- a/Samples/IntroGraphics/DirectXTKSimpleSampleUWP12/DirectXTKSimpleSample12.h +++ b/Samples/IntroGraphics/DirectXTKSimpleSampleUWP12/DirectXTKSimpleSample12.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -48,6 +44,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/IntroGraphics/SimpleBezierUWP/SimpleBezier.h b/Samples/IntroGraphics/SimpleBezierUWP/SimpleBezier.h index a0af9196..6d871b77 100644 --- a/Samples/IntroGraphics/SimpleBezierUWP/SimpleBezier.h +++ b/Samples/IntroGraphics/SimpleBezierUWP/SimpleBezier.h @@ -25,10 +25,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -48,6 +44,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateShaders(); diff --git a/Samples/IntroGraphics/SimpleBezierUWP12/SimpleBezier.cpp b/Samples/IntroGraphics/SimpleBezierUWP12/SimpleBezier.cpp index 0e6a6c39..ace6c4ef 100644 --- a/Samples/IntroGraphics/SimpleBezierUWP12/SimpleBezier.cpp +++ b/Samples/IntroGraphics/SimpleBezierUWP12/SimpleBezier.cpp @@ -413,9 +413,6 @@ void Sample::CreateDeviceDependentResources() m_help->RestoreDevice(device, uploadBatch, rtState); auto finish = uploadBatch.End(m_deviceResources->GetCommandQueue()); - - m_deviceResources->WaitForGpu(); - finish.wait(); } diff --git a/Samples/IntroGraphics/SimpleBezierUWP12/SimpleBezier.h b/Samples/IntroGraphics/SimpleBezierUWP12/SimpleBezier.h index f6a01b0d..d8ea8c6e 100644 --- a/Samples/IntroGraphics/SimpleBezierUWP12/SimpleBezier.h +++ b/Samples/IntroGraphics/SimpleBezierUWP12/SimpleBezier.h @@ -25,10 +25,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -48,6 +44,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateShaders(); diff --git a/Samples/IntroGraphics/SimpleInstancingUWP/SimpleInstancing.h b/Samples/IntroGraphics/SimpleInstancingUWP/SimpleInstancing.h index 7eeb2e32..4fc6bae8 100644 --- a/Samples/IntroGraphics/SimpleInstancingUWP/SimpleInstancing.h +++ b/Samples/IntroGraphics/SimpleInstancingUWP/SimpleInstancing.h @@ -26,10 +26,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -49,6 +45,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/IntroGraphics/SimpleInstancingUWP12/SimpleInstancing12.cpp b/Samples/IntroGraphics/SimpleInstancingUWP12/SimpleInstancing12.cpp index 5abda8d5..f462839c 100644 --- a/Samples/IntroGraphics/SimpleInstancingUWP12/SimpleInstancing12.cpp +++ b/Samples/IntroGraphics/SimpleInstancingUWP12/SimpleInstancing12.cpp @@ -724,11 +724,8 @@ void Sample::CreateDeviceDependentResources() // Initialize the positions/state of all the cubes in the scene. ResetSimulation(); - auto uploadResourcesFinished = resourceUpload.End(m_deviceResources->GetCommandQueue()); - // Wait until assets have been uploaded to the GPU. - m_deviceResources->WaitForGpu(); - + auto uploadResourcesFinished = resourceUpload.End(m_deviceResources->GetCommandQueue()); uploadResourcesFinished.wait(); // Create a fence for synchronizing between the CPU and the GPU diff --git a/Samples/IntroGraphics/SimpleInstancingUWP12/SimpleInstancing12.h b/Samples/IntroGraphics/SimpleInstancingUWP12/SimpleInstancing12.h index 2b551e87..0ad9e7c9 100644 --- a/Samples/IntroGraphics/SimpleInstancingUWP12/SimpleInstancing12.h +++ b/Samples/IntroGraphics/SimpleInstancingUWP12/SimpleInstancing12.h @@ -25,10 +25,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -48,6 +44,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/IntroGraphics/SimpleLightingUWP/SimpleLightingUWP.h b/Samples/IntroGraphics/SimpleLightingUWP/SimpleLightingUWP.h index 23f8b222..5fd17af6 100644 --- a/Samples/IntroGraphics/SimpleLightingUWP/SimpleLightingUWP.h +++ b/Samples/IntroGraphics/SimpleLightingUWP/SimpleLightingUWP.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -47,6 +43,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/IntroGraphics/SimpleLightingUWP12/SimpleLightingUWP12.h b/Samples/IntroGraphics/SimpleLightingUWP12/SimpleLightingUWP12.h index a797bdce..519a8556 100644 --- a/Samples/IntroGraphics/SimpleLightingUWP12/SimpleLightingUWP12.h +++ b/Samples/IntroGraphics/SimpleLightingUWP12/SimpleLightingUWP12.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -71,6 +67,9 @@ class Sample : public DX::IDeviceNotify static_assert(sizeof(PaddedConstantBuffer) == 2 * D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, "PaddedConstantBuffer is not aligned properly"); void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/IntroGraphics/SimpleTextureUWP/SimpleTextureUWP.h b/Samples/IntroGraphics/SimpleTextureUWP/SimpleTextureUWP.h index 79f912f8..224ddce6 100644 --- a/Samples/IntroGraphics/SimpleTextureUWP/SimpleTextureUWP.h +++ b/Samples/IntroGraphics/SimpleTextureUWP/SimpleTextureUWP.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -47,6 +43,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/IntroGraphics/SimpleTextureUWP12/SimpleTextureUWP12.h b/Samples/IntroGraphics/SimpleTextureUWP12/SimpleTextureUWP12.h index 528fcf13..eb2eaae9 100644 --- a/Samples/IntroGraphics/SimpleTextureUWP12/SimpleTextureUWP12.h +++ b/Samples/IntroGraphics/SimpleTextureUWP12/SimpleTextureUWP12.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -47,6 +43,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/IntroGraphics/SimpleTriangleUWP/SimpleTriangleUWP.h b/Samples/IntroGraphics/SimpleTriangleUWP/SimpleTriangleUWP.h index 208bc756..93261267 100644 --- a/Samples/IntroGraphics/SimpleTriangleUWP/SimpleTriangleUWP.h +++ b/Samples/IntroGraphics/SimpleTriangleUWP/SimpleTriangleUWP.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -47,6 +43,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/IntroGraphics/SimpleTriangleUWP12/SimpleTriangleUWP12.h b/Samples/IntroGraphics/SimpleTriangleUWP12/SimpleTriangleUWP12.h index b80b27e4..b8b67001 100644 --- a/Samples/IntroGraphics/SimpleTriangleUWP12/SimpleTriangleUWP12.h +++ b/Samples/IntroGraphics/SimpleTriangleUWP12/SimpleTriangleUWP12.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -47,6 +43,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/CPUSets/CPUSets.h b/Samples/System/CPUSets/CPUSets.h index a36cf134..53f981dd 100644 --- a/Samples/System/CPUSets/CPUSets.h +++ b/Samples/System/CPUSets/CPUSets.h @@ -23,10 +23,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -60,6 +56,9 @@ class Sample : public DX::IDeviceNotify }; void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/CollisionUWP/Collision.h b/Samples/System/CollisionUWP/Collision.h index 42b21c4f..57082ce8 100644 --- a/Samples/System/CollisionUWP/Collision.h +++ b/Samples/System/CollisionUWP/Collision.h @@ -26,10 +26,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -49,6 +45,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/ExtendedExecutionUWP/ExtendedExecutionOnSuspend/ExtendedExecutionOnSuspend.h b/Samples/System/ExtendedExecutionUWP/ExtendedExecutionOnSuspend/ExtendedExecutionOnSuspend.h index dc875b73..8164c5d4 100644 --- a/Samples/System/ExtendedExecutionUWP/ExtendedExecutionOnSuspend/ExtendedExecutionOnSuspend.h +++ b/Samples/System/ExtendedExecutionUWP/ExtendedExecutionOnSuspend/ExtendedExecutionOnSuspend.h @@ -26,10 +26,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -54,6 +50,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/ExtendedExecutionUWP/PreemptiveExtendedExecution/PreemptiveExtendedExecution.h b/Samples/System/ExtendedExecutionUWP/PreemptiveExtendedExecution/PreemptiveExtendedExecution.h index 0f40a524..ff31fc5d 100644 --- a/Samples/System/ExtendedExecutionUWP/PreemptiveExtendedExecution/PreemptiveExtendedExecution.h +++ b/Samples/System/ExtendedExecutionUWP/PreemptiveExtendedExecution/PreemptiveExtendedExecution.h @@ -26,10 +26,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -54,6 +50,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/GamepadUWP/GamepadUWP.h b/Samples/System/GamepadUWP/GamepadUWP.h index 55f0f149..6720294c 100644 --- a/Samples/System/GamepadUWP/GamepadUWP.h +++ b/Samples/System/GamepadUWP/GamepadUWP.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -47,6 +43,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/GamepadVibrationUWP/GamepadVibrationUWP.h b/Samples/System/GamepadVibrationUWP/GamepadVibrationUWP.h index aa479e0c..c558efb4 100644 --- a/Samples/System/GamepadVibrationUWP/GamepadVibrationUWP.h +++ b/Samples/System/GamepadVibrationUWP/GamepadVibrationUWP.h @@ -34,10 +34,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -62,6 +58,9 @@ class Sample : public DX::IDeviceNotify static const int MAX_PLAYER_COUNT = 8; void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/InputInterfacingUWP/InputInterfacingUWP.h b/Samples/System/InputInterfacingUWP/InputInterfacingUWP.h index c47378bd..08076fdd 100644 --- a/Samples/System/InputInterfacingUWP/InputInterfacingUWP.h +++ b/Samples/System/InputInterfacingUWP/InputInterfacingUWP.h @@ -31,10 +31,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -57,6 +53,9 @@ class Sample : public DX::IDeviceNotify void DrawWheel(DirectX::XMFLOAT2 startPosition); void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/MemoryStatisticsUWP/MemoryStatistics.h b/Samples/System/MemoryStatisticsUWP/MemoryStatistics.h index d9be4174..a14b1796 100644 --- a/Samples/System/MemoryStatisticsUWP/MemoryStatistics.h +++ b/Samples/System/MemoryStatisticsUWP/MemoryStatistics.h @@ -23,10 +23,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -64,6 +60,9 @@ class Sample : public DX::IDeviceNotify float m_temporaryTextTime; void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/MouseCursor/MouseCursor.h b/Samples/System/MouseCursor/MouseCursor.h index 97cba4dd..c20146a1 100644 --- a/Samples/System/MouseCursor/MouseCursor.h +++ b/Samples/System/MouseCursor/MouseCursor.h @@ -28,10 +28,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); //IDeviceNotify virtual void OnDeviceLost() override; @@ -61,6 +57,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/MouseCursor/MouseCursor.vcxproj b/Samples/System/MouseCursor/MouseCursor.vcxproj index 209da439..07a52419 100644 --- a/Samples/System/MouseCursor/MouseCursor.vcxproj +++ b/Samples/System/MouseCursor/MouseCursor.vcxproj @@ -38,6 +38,7 @@ 10.0.14393.0 10.0.10586.0 100 + Never diff --git a/Samples/System/NLSAndLocalizationUWP/NLSAndLocalizationUWP.h b/Samples/System/NLSAndLocalizationUWP/NLSAndLocalizationUWP.h index f225bd38..22431b28 100644 --- a/Samples/System/NLSAndLocalizationUWP/NLSAndLocalizationUWP.h +++ b/Samples/System/NLSAndLocalizationUWP/NLSAndLocalizationUWP.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -49,6 +45,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/NLSAndLocalizationUWP/NLSAndLocalizationUWP.vcxproj b/Samples/System/NLSAndLocalizationUWP/NLSAndLocalizationUWP.vcxproj index a3fc053e..f1a71f56 100644 --- a/Samples/System/NLSAndLocalizationUWP/NLSAndLocalizationUWP.vcxproj +++ b/Samples/System/NLSAndLocalizationUWP/NLSAndLocalizationUWP.vcxproj @@ -37,6 +37,7 @@ 10.0.14393.0 10.0.10586.0 10.0 + Never diff --git a/Samples/System/SimplePLM_UWP/SimplePLM.h b/Samples/System/SimplePLM_UWP/SimplePLM.h index 4e9cd64a..c77d548f 100644 --- a/Samples/System/SimplePLM_UWP/SimplePLM.h +++ b/Samples/System/SimplePLM_UWP/SimplePLM.h @@ -26,10 +26,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -54,6 +50,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/SystemInfoUWP/SystemInfo.h b/Samples/System/SystemInfoUWP/SystemInfo.h index c6618bb5..1a297400 100644 --- a/Samples/System/SystemInfoUWP/SystemInfo.h +++ b/Samples/System/SystemInfoUWP/SystemInfo.h @@ -24,10 +24,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -47,6 +43,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources(); diff --git a/Samples/System/UserGamepadPairingUWP/UserGamepadPairingUWP.h b/Samples/System/UserGamepadPairingUWP/UserGamepadPairingUWP.h index b7ef9a04..bb9e6861 100644 --- a/Samples/System/UserGamepadPairingUWP/UserGamepadPairingUWP.h +++ b/Samples/System/UserGamepadPairingUWP/UserGamepadPairingUWP.h @@ -23,10 +23,6 @@ class Sample : public DX::IDeviceNotify // Basic render loop void Tick(); - void Render(); - - // Rendering helpers - void Clear(); // IDeviceNotify virtual void OnDeviceLost() override; @@ -46,6 +42,9 @@ class Sample : public DX::IDeviceNotify private: void Update(DX::StepTimer const& timer); + void Render(); + + void Clear(); void CreateDeviceDependentResources(); void CreateWindowSizeDependentResources();