#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mfxvideo.h" #include using namespace DirectX; using Microsoft::WRL::ComPtr; struct CD3DX12_DEFAULT {}; extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT; // Assign a name to the object to aid with debugging. inline void SetName(ID3D12Object* pObject, LPCWSTR name) { pObject->SetName(name); } inline void SetNameIndexed(ID3D12Object* pObject, LPCWSTR name, UINT index) { WCHAR fullName[50]; if (swprintf_s(fullName, L"%s[%u]", name, index) > 0) { pObject->SetName(fullName); } } // Naming helper for ComPtr. // Assigns the name of the variable as the name of the object. // The indexed variant will include the index in the name of the object. #define NAME_D3D12_OBJECT(x) SetName((x).Get(), L#x) #define NAME_D3D12_OBJECT_INDEXED(x, n) SetNameIndexed((x)[n].Get(), L#x, n) //------------------------------------------------------------------------------------------------ struct CD3DX12_RECT : public D3D12_RECT { CD3DX12_RECT() = default; explicit CD3DX12_RECT(const D3D12_RECT& o) noexcept : D3D12_RECT(o) {} explicit CD3DX12_RECT( LONG Left, LONG Top, LONG Right, LONG Bottom) noexcept { left = Left; top = Top; right = Right; bottom = Bottom; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_VIEWPORT : public D3D12_VIEWPORT { CD3DX12_VIEWPORT() = default; explicit CD3DX12_VIEWPORT(const D3D12_VIEWPORT& o) noexcept : D3D12_VIEWPORT(o) {} explicit CD3DX12_VIEWPORT( FLOAT topLeftX, FLOAT topLeftY, FLOAT width, FLOAT height, FLOAT minDepth = D3D12_MIN_DEPTH, FLOAT maxDepth = D3D12_MAX_DEPTH) noexcept { TopLeftX = topLeftX; TopLeftY = topLeftY; Width = width; Height = height; MinDepth = minDepth; MaxDepth = maxDepth; } explicit CD3DX12_VIEWPORT( _In_ ID3D12Resource* pResource, UINT mipSlice = 0, FLOAT topLeftX = 0.0f, FLOAT topLeftY = 0.0f, FLOAT minDepth = D3D12_MIN_DEPTH, FLOAT maxDepth = D3D12_MAX_DEPTH) noexcept { auto Desc = pResource->GetDesc(); const UINT64 SubresourceWidth = Desc.Width >> mipSlice; const UINT64 SubresourceHeight = Desc.Height >> mipSlice; switch (Desc.Dimension) { case D3D12_RESOURCE_DIMENSION_BUFFER: TopLeftX = topLeftX; TopLeftY = 0.0f; Width = float(Desc.Width) - topLeftX; Height = 1.0f; break; case D3D12_RESOURCE_DIMENSION_TEXTURE1D: TopLeftX = topLeftX; TopLeftY = 0.0f; Width = (SubresourceWidth ? float(SubresourceWidth) : 1.0f) - topLeftX; Height = 1.0f; break; case D3D12_RESOURCE_DIMENSION_TEXTURE2D: case D3D12_RESOURCE_DIMENSION_TEXTURE3D: TopLeftX = topLeftX; TopLeftY = topLeftY; Width = (SubresourceWidth ? float(SubresourceWidth) : 1.0f) - topLeftX; Height = (SubresourceHeight ? float(SubresourceHeight) : 1.0f) - topLeftY; break; default: break; } MinDepth = minDepth; MaxDepth = maxDepth; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC { CD3DX12_ROOT_SIGNATURE_DESC() = default; explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) noexcept : 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 = nullptr, D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) noexcept { Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); } CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) noexcept { Init(0, nullptr, 0, nullptr, 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 = nullptr, D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) noexcept { 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 = nullptr, D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) noexcept { desc.NumParameters = numParameters; desc.pParameters = _pParameters; desc.NumStaticSamplers = numStaticSamplers; desc.pStaticSamplers = _pStaticSamplers; desc.Flags = flags; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC { CD3DX12_RASTERIZER_DESC() = default; explicit CD3DX12_RASTERIZER_DESC(const D3D12_RASTERIZER_DESC& o) noexcept : D3D12_RASTERIZER_DESC(o) {} explicit CD3DX12_RASTERIZER_DESC(CD3DX12_DEFAULT) noexcept { 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) noexcept { FillMode = fillMode; CullMode = cullMode; FrontCounterClockwise = frontCounterClockwise; DepthBias = depthBias; DepthBiasClamp = depthBiasClamp; SlopeScaledDepthBias = slopeScaledDepthBias; DepthClipEnable = depthClipEnable; MultisampleEnable = multisampleEnable; AntialiasedLineEnable = antialiasedLineEnable; ForcedSampleCount = forcedSampleCount; ConservativeRaster = conservativeRaster; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC { CD3DX12_BLEND_DESC() = default; explicit CD3DX12_BLEND_DESC(const D3D12_BLEND_DESC& o) noexcept : D3D12_BLEND_DESC(o) {} explicit CD3DX12_BLEND_DESC(CD3DX12_DEFAULT) noexcept { 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; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_SHADER_BYTECODE : public D3D12_SHADER_BYTECODE { CD3DX12_SHADER_BYTECODE() = default; explicit CD3DX12_SHADER_BYTECODE(const D3D12_SHADER_BYTECODE &o) noexcept : D3D12_SHADER_BYTECODE(o) {} CD3DX12_SHADER_BYTECODE( _In_ ID3DBlob* pShaderBlob) noexcept { pShaderBytecode = pShaderBlob->GetBufferPointer(); BytecodeLength = pShaderBlob->GetBufferSize(); } CD3DX12_SHADER_BYTECODE( const void* _pShaderBytecode, SIZE_T bytecodeLength) noexcept { pShaderBytecode = _pShaderBytecode; BytecodeLength = bytecodeLength; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER { CD3DX12_RESOURCE_BARRIER() = default; explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) noexcept : 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) noexcept { CD3DX12_RESOURCE_BARRIER 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) noexcept { CD3DX12_RESOURCE_BARRIER 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) noexcept { CD3DX12_RESOURCE_BARRIER result = {}; D3D12_RESOURCE_BARRIER &barrier = result; result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; barrier.UAV.pResource = pResource; return result; } }; //------------------------------------------------------------------------------------------------ struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE { CD3DX12_CPU_DESCRIPTOR_HANDLE() = default; explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) noexcept : D3D12_CPU_DESCRIPTOR_HANDLE(o) {} CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) noexcept { ptr = 0; } CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) noexcept { InitOffsetted(other, offsetScaledByIncrementSize); } CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) noexcept { InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); } CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) noexcept { ptr = SIZE_T(INT64(ptr) + INT64(offsetInDescriptors) * INT64(descriptorIncrementSize)); return *this; } CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) noexcept { ptr = SIZE_T(INT64(ptr) + INT64(offsetScaledByIncrementSize)); return *this; } bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) const noexcept { return (ptr == other.ptr); } bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) const noexcept { return (ptr != other.ptr); } CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other) noexcept { ptr = other.ptr; return *this; } inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) noexcept { InitOffsetted(*this, base, offsetScaledByIncrementSize); } inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) noexcept { InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); } static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) noexcept { handle.ptr = SIZE_T(INT64(base.ptr) + INT64(offsetScaledByIncrementSize)); } static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) noexcept { handle.ptr = SIZE_T(INT64(base.ptr) + INT64(offsetInDescriptors) * INT64(descriptorIncrementSize)); } }; class ExD3D12_Device { public: ExD3D12_Device(); ~ExD3D12_Device(); void CreateDevice(HWND hwind); void RenderUI(); void LoadPipeline(); mfxStatus RenderFrame(mfxFrameSurface1 * pSrf, mfxFrameAllocator * pAlloc); protected: std::wstring GetAssetFullPath(LPCWSTR assetName); void GetHardwareAdapter( _In_ IDXGIFactory1* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter, bool requestHighPerformanceAdapter = false); // Viewport dimensions. UINT m_width; UINT m_height; float m_aspectRatio; // Whether or not tearing is available for fullscreen borderless windowed mode. bool m_tearingSupport = false; mfxStatus Dx11CreateVideoProcessor(mfxFrameSurface1 * pSrf); mfxStatus Dx12CreateVideoProcessor(mfxFrameSurface1 * pSrf); void LoadAssets(); private: HWND m_MyWind = NULL; struct Vertex { XMFLOAT3 position; XMFLOAT4 color; }; static const UINT FrameCount = 3; // Pipeline objects. CD3DX12_VIEWPORT m_viewport; CD3DX12_RECT m_scissorRect; ComPtr m_swapChain; ComPtr m_d3d11DeviceContext; ComPtr m_d3d11On12Device; ComPtr m_d3d12Device; ComPtr m_dWriteFactory; ComPtr m_d2dFactory; ComPtr m_d2dDevice; ComPtr m_renderTargets[FrameCount]; ComPtr m_wrappedBackBuffers[FrameCount]; ComPtr m_d2dDeviceContext; ComPtr m_d2dRenderTargets[FrameCount]; ComPtr m_commandQueue; ComPtr m_commandList; ComPtr m_commandAllocators[FrameCount]; ComPtr m_pipelineState; ComPtr m_rootSignature; ComPtr m_rtvHeap; ComPtr m_pVideoBackBuffers[FrameCount]; ComPtr m_pVideoRenderTargets[FrameCount]; /*CComQIPtr m_pDX11VideoDevice; CComQIPtr m_pVideoContext;*/ ComPtr m_pDX12VideoDevice; ComPtr m_pVideoCommandAllocators[FrameCount]; ComPtr m_pVideoCommandQueue; ComPtr m_pVideoProcessor; ComPtr m_pDX12VideoProcessor; CComPtr m_VideoProcessorEnum; ComPtr m_pID3D12VideoProcessCommandList1; CComPtr m_pDX12GIBackBuffer; // App resources. UINT m_rtvDescriptorSize; ComPtr m_textBrush; ComPtr m_textFormat; ComPtr m_vertexBuffer; D3D12_VERTEX_BUFFER_VIEW m_vertexBufferView; // Synchronization objects. UINT m_frameIndex; HANDLE m_fenceEvent; ComPtr m_fence; UINT64 m_fenceValues[FrameCount]; // Root assets path. std::wstring m_assetsPath; // Window title. std::wstring m_title; };