1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © Microsoft Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci * IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#ifndef D3D12_UTIL_H
25bf215546Sopenharmony_ci#define D3D12_UTIL_H
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci//------------------------------------------------------------------------------------------------
28bf215546Sopenharmony_citemplate <typename T, typename U, typename V>
29bf215546Sopenharmony_ciinline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) noexcept
30bf215546Sopenharmony_ci{
31bf215546Sopenharmony_ci    MipSlice = static_cast<T>(Subresource % MipLevels);
32bf215546Sopenharmony_ci    ArraySlice = static_cast<U>((Subresource / MipLevels) % ArraySize);
33bf215546Sopenharmony_ci    PlaneSlice = static_cast<V>(Subresource / (MipLevels * ArraySize));
34bf215546Sopenharmony_ci}
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_ci//------------------------------------------------------------------------------------------------
37bf215546Sopenharmony_ciconstexpr UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize ) noexcept
38bf215546Sopenharmony_ci{
39bf215546Sopenharmony_ci    return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize;
40bf215546Sopenharmony_ci}
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci//------------------------------------------------------------------------------------------------
43bf215546Sopenharmony_cistruct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER
44bf215546Sopenharmony_ci{
45bf215546Sopenharmony_ci    CD3DX12_RESOURCE_BARRIER() = default;
46bf215546Sopenharmony_ci    explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) noexcept :
47bf215546Sopenharmony_ci        D3D12_RESOURCE_BARRIER(o)
48bf215546Sopenharmony_ci    {}
49bf215546Sopenharmony_ci    static inline CD3DX12_RESOURCE_BARRIER Transition(
50bf215546Sopenharmony_ci        _In_ ID3D12Resource* pResource,
51bf215546Sopenharmony_ci        D3D12_RESOURCE_STATES stateBefore,
52bf215546Sopenharmony_ci        D3D12_RESOURCE_STATES stateAfter,
53bf215546Sopenharmony_ci        UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
54bf215546Sopenharmony_ci        D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) noexcept
55bf215546Sopenharmony_ci    {
56bf215546Sopenharmony_ci        CD3DX12_RESOURCE_BARRIER result = {};
57bf215546Sopenharmony_ci        D3D12_RESOURCE_BARRIER &barrier = result;
58bf215546Sopenharmony_ci        result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
59bf215546Sopenharmony_ci        result.Flags = flags;
60bf215546Sopenharmony_ci        barrier.Transition.pResource = pResource;
61bf215546Sopenharmony_ci        barrier.Transition.StateBefore = stateBefore;
62bf215546Sopenharmony_ci        barrier.Transition.StateAfter = stateAfter;
63bf215546Sopenharmony_ci        barrier.Transition.Subresource = subresource;
64bf215546Sopenharmony_ci        return result;
65bf215546Sopenharmony_ci    }
66bf215546Sopenharmony_ci    static inline CD3DX12_RESOURCE_BARRIER Aliasing(
67bf215546Sopenharmony_ci        _In_ ID3D12Resource* pResourceBefore,
68bf215546Sopenharmony_ci        _In_ ID3D12Resource* pResourceAfter) noexcept
69bf215546Sopenharmony_ci    {
70bf215546Sopenharmony_ci        CD3DX12_RESOURCE_BARRIER result = {};
71bf215546Sopenharmony_ci        D3D12_RESOURCE_BARRIER &barrier = result;
72bf215546Sopenharmony_ci        result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING;
73bf215546Sopenharmony_ci        barrier.Aliasing.pResourceBefore = pResourceBefore;
74bf215546Sopenharmony_ci        barrier.Aliasing.pResourceAfter = pResourceAfter;
75bf215546Sopenharmony_ci        return result;
76bf215546Sopenharmony_ci    }
77bf215546Sopenharmony_ci    static inline CD3DX12_RESOURCE_BARRIER UAV(
78bf215546Sopenharmony_ci        _In_ ID3D12Resource* pResource) noexcept
79bf215546Sopenharmony_ci    {
80bf215546Sopenharmony_ci        CD3DX12_RESOURCE_BARRIER result = {};
81bf215546Sopenharmony_ci        D3D12_RESOURCE_BARRIER &barrier = result;
82bf215546Sopenharmony_ci        result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
83bf215546Sopenharmony_ci        barrier.UAV.pResource = pResource;
84bf215546Sopenharmony_ci        return result;
85bf215546Sopenharmony_ci    }
86bf215546Sopenharmony_ci};
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci//------------------------------------------------------------------------------------------------
89bf215546Sopenharmony_cistruct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC
90bf215546Sopenharmony_ci{
91bf215546Sopenharmony_ci    CD3DX12_RESOURCE_DESC() = default;
92bf215546Sopenharmony_ci    explicit CD3DX12_RESOURCE_DESC( const D3D12_RESOURCE_DESC& o ) noexcept :
93bf215546Sopenharmony_ci        D3D12_RESOURCE_DESC( o )
94bf215546Sopenharmony_ci    {}
95bf215546Sopenharmony_ci    CD3DX12_RESOURCE_DESC(
96bf215546Sopenharmony_ci        D3D12_RESOURCE_DIMENSION dimension,
97bf215546Sopenharmony_ci        UINT64 alignment,
98bf215546Sopenharmony_ci        UINT64 width,
99bf215546Sopenharmony_ci        UINT height,
100bf215546Sopenharmony_ci        UINT16 depthOrArraySize,
101bf215546Sopenharmony_ci        UINT16 mipLevels,
102bf215546Sopenharmony_ci        DXGI_FORMAT format,
103bf215546Sopenharmony_ci        UINT sampleCount,
104bf215546Sopenharmony_ci        UINT sampleQuality,
105bf215546Sopenharmony_ci        D3D12_TEXTURE_LAYOUT layout,
106bf215546Sopenharmony_ci        D3D12_RESOURCE_FLAGS flags ) noexcept
107bf215546Sopenharmony_ci    {
108bf215546Sopenharmony_ci        Dimension = dimension;
109bf215546Sopenharmony_ci        Alignment = alignment;
110bf215546Sopenharmony_ci        Width = width;
111bf215546Sopenharmony_ci        Height = height;
112bf215546Sopenharmony_ci        DepthOrArraySize = depthOrArraySize;
113bf215546Sopenharmony_ci        MipLevels = mipLevels;
114bf215546Sopenharmony_ci        Format = format;
115bf215546Sopenharmony_ci        SampleDesc.Count = sampleCount;
116bf215546Sopenharmony_ci        SampleDesc.Quality = sampleQuality;
117bf215546Sopenharmony_ci        Layout = layout;
118bf215546Sopenharmony_ci        Flags = flags;
119bf215546Sopenharmony_ci    }
120bf215546Sopenharmony_ci    static inline CD3DX12_RESOURCE_DESC Buffer(
121bf215546Sopenharmony_ci        const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
122bf215546Sopenharmony_ci        D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE ) noexcept
123bf215546Sopenharmony_ci    {
124bf215546Sopenharmony_ci        return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes,
125bf215546Sopenharmony_ci            1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags );
126bf215546Sopenharmony_ci    }
127bf215546Sopenharmony_ci    static inline CD3DX12_RESOURCE_DESC Buffer(
128bf215546Sopenharmony_ci        UINT64 width,
129bf215546Sopenharmony_ci        D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
130bf215546Sopenharmony_ci        UINT64 alignment = 0 ) noexcept
131bf215546Sopenharmony_ci    {
132bf215546Sopenharmony_ci        return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1,
133bf215546Sopenharmony_ci            DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags );
134bf215546Sopenharmony_ci    }
135bf215546Sopenharmony_ci    static inline CD3DX12_RESOURCE_DESC Tex1D(
136bf215546Sopenharmony_ci        DXGI_FORMAT format,
137bf215546Sopenharmony_ci        UINT64 width,
138bf215546Sopenharmony_ci        UINT16 arraySize = 1,
139bf215546Sopenharmony_ci        UINT16 mipLevels = 0,
140bf215546Sopenharmony_ci        D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
141bf215546Sopenharmony_ci        D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
142bf215546Sopenharmony_ci        UINT64 alignment = 0 ) noexcept
143bf215546Sopenharmony_ci    {
144bf215546Sopenharmony_ci        return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize,
145bf215546Sopenharmony_ci            mipLevels, format, 1, 0, layout, flags );
146bf215546Sopenharmony_ci    }
147bf215546Sopenharmony_ci    static inline CD3DX12_RESOURCE_DESC Tex2D(
148bf215546Sopenharmony_ci        DXGI_FORMAT format,
149bf215546Sopenharmony_ci        UINT64 width,
150bf215546Sopenharmony_ci        UINT height,
151bf215546Sopenharmony_ci        UINT16 arraySize = 1,
152bf215546Sopenharmony_ci        UINT16 mipLevels = 0,
153bf215546Sopenharmony_ci        UINT sampleCount = 1,
154bf215546Sopenharmony_ci        UINT sampleQuality = 0,
155bf215546Sopenharmony_ci        D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
156bf215546Sopenharmony_ci        D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
157bf215546Sopenharmony_ci        UINT64 alignment = 0 ) noexcept
158bf215546Sopenharmony_ci    {
159bf215546Sopenharmony_ci        return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize,
160bf215546Sopenharmony_ci            mipLevels, format, sampleCount, sampleQuality, layout, flags );
161bf215546Sopenharmony_ci    }
162bf215546Sopenharmony_ci    static inline CD3DX12_RESOURCE_DESC Tex3D(
163bf215546Sopenharmony_ci        DXGI_FORMAT format,
164bf215546Sopenharmony_ci        UINT64 width,
165bf215546Sopenharmony_ci        UINT height,
166bf215546Sopenharmony_ci        UINT16 depth,
167bf215546Sopenharmony_ci        UINT16 mipLevels = 0,
168bf215546Sopenharmony_ci        D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
169bf215546Sopenharmony_ci        D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
170bf215546Sopenharmony_ci        UINT64 alignment = 0 ) noexcept
171bf215546Sopenharmony_ci    {
172bf215546Sopenharmony_ci        return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth,
173bf215546Sopenharmony_ci            mipLevels, format, 1, 0, layout, flags );
174bf215546Sopenharmony_ci    }
175bf215546Sopenharmony_ci    inline UINT16 Depth() const noexcept
176bf215546Sopenharmony_ci    { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1u); }
177bf215546Sopenharmony_ci    inline UINT16 ArraySize() const noexcept
178bf215546Sopenharmony_ci    { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1u); }
179bf215546Sopenharmony_ci    inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) noexcept
180bf215546Sopenharmony_ci    { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); }
181bf215546Sopenharmony_ci};
182bf215546Sopenharmony_ciinline bool operator==( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) noexcept
183bf215546Sopenharmony_ci{
184bf215546Sopenharmony_ci    return l.Dimension == r.Dimension &&
185bf215546Sopenharmony_ci        l.Alignment == r.Alignment &&
186bf215546Sopenharmony_ci        l.Width == r.Width &&
187bf215546Sopenharmony_ci        l.Height == r.Height &&
188bf215546Sopenharmony_ci        l.DepthOrArraySize == r.DepthOrArraySize &&
189bf215546Sopenharmony_ci        l.MipLevels == r.MipLevels &&
190bf215546Sopenharmony_ci        l.Format == r.Format &&
191bf215546Sopenharmony_ci        l.SampleDesc.Count == r.SampleDesc.Count &&
192bf215546Sopenharmony_ci        l.SampleDesc.Quality == r.SampleDesc.Quality &&
193bf215546Sopenharmony_ci        l.Layout == r.Layout &&
194bf215546Sopenharmony_ci        l.Flags == r.Flags;
195bf215546Sopenharmony_ci}
196bf215546Sopenharmony_ciinline bool operator!=( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) noexcept
197bf215546Sopenharmony_ci{ return !( l == r ); }
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_ci//------------------------------------------------------------------------------------------------
201bf215546Sopenharmony_cistruct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES
202bf215546Sopenharmony_ci{
203bf215546Sopenharmony_ci    CD3DX12_HEAP_PROPERTIES() = default;
204bf215546Sopenharmony_ci    explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) noexcept :
205bf215546Sopenharmony_ci        D3D12_HEAP_PROPERTIES(o)
206bf215546Sopenharmony_ci    {}
207bf215546Sopenharmony_ci    CD3DX12_HEAP_PROPERTIES(
208bf215546Sopenharmony_ci        D3D12_CPU_PAGE_PROPERTY cpuPageProperty,
209bf215546Sopenharmony_ci        D3D12_MEMORY_POOL memoryPoolPreference,
210bf215546Sopenharmony_ci        UINT creationNodeMask = 1,
211bf215546Sopenharmony_ci        UINT nodeMask = 1 ) noexcept
212bf215546Sopenharmony_ci    {
213bf215546Sopenharmony_ci        Type = D3D12_HEAP_TYPE_CUSTOM;
214bf215546Sopenharmony_ci        CPUPageProperty = cpuPageProperty;
215bf215546Sopenharmony_ci        MemoryPoolPreference = memoryPoolPreference;
216bf215546Sopenharmony_ci        CreationNodeMask = creationNodeMask;
217bf215546Sopenharmony_ci        VisibleNodeMask = nodeMask;
218bf215546Sopenharmony_ci    }
219bf215546Sopenharmony_ci    explicit CD3DX12_HEAP_PROPERTIES(
220bf215546Sopenharmony_ci        D3D12_HEAP_TYPE type,
221bf215546Sopenharmony_ci        UINT creationNodeMask = 1,
222bf215546Sopenharmony_ci        UINT nodeMask = 1 ) noexcept
223bf215546Sopenharmony_ci    {
224bf215546Sopenharmony_ci        Type = type;
225bf215546Sopenharmony_ci        CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
226bf215546Sopenharmony_ci        MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
227bf215546Sopenharmony_ci        CreationNodeMask = creationNodeMask;
228bf215546Sopenharmony_ci        VisibleNodeMask = nodeMask;
229bf215546Sopenharmony_ci    }
230bf215546Sopenharmony_ci    bool IsCPUAccessible() const noexcept
231bf215546Sopenharmony_ci    {
232bf215546Sopenharmony_ci        return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM &&
233bf215546Sopenharmony_ci            (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK));
234bf215546Sopenharmony_ci    }
235bf215546Sopenharmony_ci};
236bf215546Sopenharmony_ciinline bool operator==( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) noexcept
237bf215546Sopenharmony_ci{
238bf215546Sopenharmony_ci    return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty &&
239bf215546Sopenharmony_ci        l.MemoryPoolPreference == r.MemoryPoolPreference &&
240bf215546Sopenharmony_ci        l.CreationNodeMask == r.CreationNodeMask &&
241bf215546Sopenharmony_ci        l.VisibleNodeMask == r.VisibleNodeMask;
242bf215546Sopenharmony_ci}
243bf215546Sopenharmony_ciinline bool operator!=( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) noexcept
244bf215546Sopenharmony_ci{ return !( l == r ); }
245bf215546Sopenharmony_ci
246bf215546Sopenharmony_ci#endif