Files
renderdoc/renderdoc/driver/d3d12/d3d12_common.cpp
T

1248 lines
40 KiB
C++

/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2019-2021 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "d3d12_common.h"
#include "driver/dxgi/dxgi_common.h"
#include "driver/dxgi/dxgi_wrapped.h"
#include "d3d12_manager.h"
#include "d3d12_resources.h"
D3D12MarkerRegion::D3D12MarkerRegion(ID3D12GraphicsCommandList *l, const rdcstr &marker)
{
list = l;
queue = NULL;
D3D12MarkerRegion::Begin(list, marker);
}
D3D12MarkerRegion::D3D12MarkerRegion(ID3D12CommandQueue *q, const rdcstr &marker)
{
list = NULL;
queue = q;
D3D12MarkerRegion::Begin(queue, marker);
}
D3D12MarkerRegion::~D3D12MarkerRegion()
{
if(list)
D3D12MarkerRegion::End(list);
if(queue)
D3D12MarkerRegion::End(queue);
}
void D3D12MarkerRegion::Begin(ID3D12GraphicsCommandList *list, const rdcstr &marker)
{
if(list)
{
// Some debuggers (but not all) will assume the event string is null-terminated, and
// display one less character than specified by the size. Append a space to pad the
// output without visibly changing the event marker for other debuggers.
rdcwstr text = StringFormat::UTF82Wide(marker + " ");
UINT size = UINT(text.length() * sizeof(wchar_t));
list->BeginEvent(0, text.c_str(), size);
}
}
void D3D12MarkerRegion::Begin(ID3D12CommandQueue *queue, const rdcstr &marker)
{
if(queue)
{
rdcwstr text = StringFormat::UTF82Wide(marker + " ");
UINT size = UINT(text.length() * sizeof(wchar_t));
queue->BeginEvent(0, text.c_str(), size);
}
}
void D3D12MarkerRegion::Set(ID3D12GraphicsCommandList *list, const rdcstr &marker)
{
if(list)
{
rdcwstr text = StringFormat::UTF82Wide(marker + " ");
UINT size = UINT(text.length() * sizeof(wchar_t));
list->SetMarker(0, text.c_str(), size);
}
}
void D3D12MarkerRegion::Set(ID3D12CommandQueue *queue, const rdcstr &marker)
{
if(queue)
{
rdcwstr text = StringFormat::UTF82Wide(marker + " ");
UINT size = UINT(text.length() * sizeof(wchar_t));
queue->SetMarker(0, text.c_str(), size);
}
}
void D3D12MarkerRegion::End(ID3D12GraphicsCommandList *list)
{
list->EndEvent();
}
void D3D12MarkerRegion::End(ID3D12CommandQueue *queue)
{
queue->EndEvent();
}
bool EnableD3D12DebugLayer(PFN_D3D12_GET_DEBUG_INTERFACE getDebugInterface)
{
if(!getDebugInterface)
getDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)GetProcAddress(GetModuleHandleA("d3d12.dll"),
"D3D12GetDebugInterface");
if(!getDebugInterface)
{
RDCERR("Couldn't find D3D12GetDebugInterface!");
return false;
}
ID3D12Debug *debug = NULL;
HRESULT hr = getDebugInterface(__uuidof(ID3D12Debug), (void **)&debug);
if(SUCCEEDED(hr) && debug)
{
debug->EnableDebugLayer();
RDCDEBUG("Enabling debug layer");
// enable this to get GPU-based validation, where available, whenever we enable API validation
#if 0
ID3D12Debug1 *debug1 = NULL;
hr = debug->QueryInterface(__uuidof(ID3D12Debug1), (void **)&debug1);
if(SUCCEEDED(hr) && debug1)
{
RDCDEBUG("Enabling GPU-based validation");
debug1->SetEnableGPUBasedValidation(true);
SAFE_RELEASE(debug1);
}
else
{
RDCDEBUG("GPU-based validation not available");
}
#endif
SAFE_RELEASE(debug);
return true;
}
else if(hr == DXGI_ERROR_SDK_COMPONENT_MISSING)
{
RDCWARN("Debug layer not available: DXGI_ERROR_SDK_COMPONENT_MISSING");
}
else
{
RDCERR("Couldn't enable debug layer: %x", hr);
}
return false;
}
HRESULT EnumAdapterByLuid(IDXGIFactory1 *factory, LUID luid, IDXGIAdapter **pAdapter)
{
HRESULT hr = S_OK;
*pAdapter = NULL;
for(UINT i = 0; i < 10; i++)
{
IDXGIAdapter *adapter = NULL;
hr = factory->EnumAdapters(i, &adapter);
if(hr == S_OK && adapter)
{
DXGI_ADAPTER_DESC desc;
adapter->GetDesc(&desc);
if(desc.AdapterLuid.LowPart == luid.LowPart && desc.AdapterLuid.HighPart == luid.HighPart)
{
*pAdapter = adapter;
return S_OK;
}
adapter->Release();
}
else
{
break;
}
}
return E_FAIL;
}
bool D3D12InitParams::IsSupportedVersion(uint64_t ver)
{
if(ver == CurrentVersion)
return true;
// 0x4 -> 0x5 - CPU_DESCRIPTOR_HANDLE serialised inline as D3D12Descriptor in appropriate
// list-recording functions
if(ver == 0x4)
return true;
// 0x5 -> 0x6 - Multiply by number of planes in format when serialising initial states -
// i.e. stencil is saved with depth in initial states.
if(ver == 0x5)
return true;
// 0x6 -> 0x7 - Fixed serialisation of D3D12_WRITEBUFFERIMMEDIATE_PARAMETER to properly replay the
// GPU address
if(ver == 0x6)
return true;
// 0x7 -> 0x8 - Added serialisation of adapter descriptor in D3D12InitParams
if(ver == 0x7)
return true;
// 0x8 -> 0x9 - Added serialisation of usedDXIL in D3D12InitParams
if(ver == 0x8)
return true;
// 0x9 -> 0xA - Added serialisation of vendor extension use in D3D12InitParams
if(ver == 0x9)
return true;
// 0xA -> 0xB - Added support for sparse/reserved/tiled resources
if(ver == 0x9)
return true;
return false;
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, D3D12InitParams &el)
{
SERIALISE_MEMBER(MinimumFeatureLevel);
if(ser.VersionAtLeast(0x8))
{
SERIALISE_MEMBER(AdapterDesc);
}
else
{
RDCEraseEl(el.AdapterDesc);
}
if(ser.VersionAtLeast(0x9))
{
SERIALISE_MEMBER(usedDXIL);
}
if(ser.VersionAtLeast(0xA))
{
SERIALISE_MEMBER(VendorExtensions);
SERIALISE_MEMBER(VendorUAV);
SERIALISE_MEMBER(VendorUAVSpace);
}
else
{
el.VendorExtensions = GPUVendor::Unknown;
el.VendorUAV = ~0U;
el.VendorUAVSpace = ~0U;
}
}
INSTANTIATE_SERIALISE_TYPE(D3D12InitParams);
TextureType MakeTextureDim(D3D12_SRV_DIMENSION dim)
{
switch(dim)
{
case D3D12_SRV_DIMENSION_UNKNOWN: return TextureType::Unknown;
case D3D12_SRV_DIMENSION_BUFFER: return TextureType::Buffer;
case D3D12_SRV_DIMENSION_TEXTURE1D: return TextureType::Texture1D;
case D3D12_SRV_DIMENSION_TEXTURE1DARRAY: return TextureType::Texture1DArray;
case D3D12_SRV_DIMENSION_TEXTURE2D: return TextureType::Texture2D;
case D3D12_SRV_DIMENSION_TEXTURE2DARRAY: return TextureType::Texture2DArray;
case D3D12_SRV_DIMENSION_TEXTURE2DMS: return TextureType::Texture2DMS;
case D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY: return TextureType::Texture2DMSArray;
case D3D12_SRV_DIMENSION_TEXTURE3D: return TextureType::Texture3D;
case D3D12_SRV_DIMENSION_TEXTURECUBE: return TextureType::TextureCube;
case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY: return TextureType::TextureCubeArray;
default: break;
}
return TextureType::Unknown;
}
TextureType MakeTextureDim(D3D12_RTV_DIMENSION dim)
{
switch(dim)
{
case D3D12_RTV_DIMENSION_UNKNOWN: return TextureType::Unknown;
case D3D12_RTV_DIMENSION_BUFFER: return TextureType::Buffer;
case D3D12_RTV_DIMENSION_TEXTURE1D: return TextureType::Texture1D;
case D3D12_RTV_DIMENSION_TEXTURE1DARRAY: return TextureType::Texture1DArray;
case D3D12_RTV_DIMENSION_TEXTURE2D: return TextureType::Texture2D;
case D3D12_RTV_DIMENSION_TEXTURE2DARRAY: return TextureType::Texture2DArray;
case D3D12_RTV_DIMENSION_TEXTURE2DMS: return TextureType::Texture2DMS;
case D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY: return TextureType::Texture2DMSArray;
case D3D12_RTV_DIMENSION_TEXTURE3D: return TextureType::Texture3D;
default: break;
}
return TextureType::Unknown;
}
TextureType MakeTextureDim(D3D12_DSV_DIMENSION dim)
{
switch(dim)
{
case D3D12_DSV_DIMENSION_UNKNOWN: return TextureType::Unknown;
case D3D12_DSV_DIMENSION_TEXTURE1D: return TextureType::Texture1D;
case D3D12_DSV_DIMENSION_TEXTURE1DARRAY: return TextureType::Texture1DArray;
case D3D12_DSV_DIMENSION_TEXTURE2D: return TextureType::Texture2D;
case D3D12_DSV_DIMENSION_TEXTURE2DARRAY: return TextureType::Texture2DArray;
case D3D12_DSV_DIMENSION_TEXTURE2DMS: return TextureType::Texture2DMS;
case D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY: return TextureType::Texture2DMSArray;
default: break;
}
return TextureType::Unknown;
}
TextureType MakeTextureDim(D3D12_UAV_DIMENSION dim)
{
switch(dim)
{
case D3D12_UAV_DIMENSION_UNKNOWN: return TextureType::Unknown;
case D3D12_UAV_DIMENSION_BUFFER: return TextureType::Buffer;
case D3D12_UAV_DIMENSION_TEXTURE1D: return TextureType::Texture1D;
case D3D12_UAV_DIMENSION_TEXTURE1DARRAY: return TextureType::Texture1DArray;
case D3D12_UAV_DIMENSION_TEXTURE2D: return TextureType::Texture2D;
case D3D12_UAV_DIMENSION_TEXTURE2DARRAY: return TextureType::Texture2DArray;
case D3D12_UAV_DIMENSION_TEXTURE3D: return TextureType::Texture3D;
default: break;
}
return TextureType::Unknown;
}
AddressMode MakeAddressMode(D3D12_TEXTURE_ADDRESS_MODE addr)
{
switch(addr)
{
case D3D12_TEXTURE_ADDRESS_MODE_WRAP: return AddressMode::Wrap;
case D3D12_TEXTURE_ADDRESS_MODE_MIRROR: return AddressMode::Mirror;
case D3D12_TEXTURE_ADDRESS_MODE_CLAMP: return AddressMode::ClampEdge;
case D3D12_TEXTURE_ADDRESS_MODE_BORDER: return AddressMode::ClampBorder;
case D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE: return AddressMode::MirrorOnce;
default: break;
}
return AddressMode::Wrap;
}
CompareFunction MakeCompareFunc(D3D12_COMPARISON_FUNC func)
{
switch(func)
{
case D3D12_COMPARISON_FUNC_NEVER: return CompareFunction::Never;
case D3D12_COMPARISON_FUNC_LESS: return CompareFunction::Less;
case D3D12_COMPARISON_FUNC_EQUAL: return CompareFunction::Equal;
case D3D12_COMPARISON_FUNC_LESS_EQUAL: return CompareFunction::LessEqual;
case D3D12_COMPARISON_FUNC_GREATER: return CompareFunction::Greater;
case D3D12_COMPARISON_FUNC_NOT_EQUAL: return CompareFunction::NotEqual;
case D3D12_COMPARISON_FUNC_GREATER_EQUAL: return CompareFunction::GreaterEqual;
case D3D12_COMPARISON_FUNC_ALWAYS: return CompareFunction::AlwaysTrue;
default: break;
}
return CompareFunction::AlwaysTrue;
}
TextureFilter MakeFilter(D3D12_FILTER filter)
{
TextureFilter ret;
ret.filter = FilterFunction::Normal;
if(filter >= D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT &&
filter <= D3D12_FILTER_COMPARISON_ANISOTROPIC)
{
ret.filter = FilterFunction::Comparison;
// the first 0x7f is the min/mag/mip filtering
filter = D3D12_FILTER(filter & 0x7f);
}
else if(filter >= D3D12_FILTER_MINIMUM_MIN_MAG_MIP_POINT &&
filter <= D3D12_FILTER_MINIMUM_ANISOTROPIC)
{
ret.filter = FilterFunction::Minimum;
// the first 0x7f is the min/mag/mip filtering
filter = D3D12_FILTER(filter & 0x7f);
}
else if(filter >= D3D12_FILTER_MAXIMUM_MIN_MAG_MIP_POINT &&
filter <= D3D12_FILTER_MAXIMUM_ANISOTROPIC)
{
ret.filter = FilterFunction::Maximum;
// the first 0x7f is the min/mag/mip filtering
filter = D3D12_FILTER(filter & 0x7f);
}
switch(filter)
{
case D3D12_FILTER_ANISOTROPIC:
ret.minify = ret.magnify = ret.mip = FilterMode::Anisotropic;
break;
case D3D12_FILTER_MIN_MAG_MIP_POINT:
ret.minify = ret.magnify = ret.mip = FilterMode::Point;
break;
case D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR:
ret.minify = ret.magnify = FilterMode::Point;
ret.mip = FilterMode::Linear;
break;
case D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT:
ret.minify = FilterMode::Point;
ret.magnify = FilterMode::Linear;
ret.mip = FilterMode::Point;
break;
case D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR:
ret.minify = FilterMode::Point;
ret.magnify = ret.mip = FilterMode::Linear;
break;
case D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT:
ret.minify = FilterMode::Linear;
ret.magnify = ret.mip = FilterMode::Point;
break;
case D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR:
ret.minify = FilterMode::Linear;
ret.magnify = FilterMode::Point;
ret.mip = FilterMode::Linear;
break;
case D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT:
ret.minify = ret.magnify = FilterMode::Linear;
ret.mip = FilterMode::Point;
break;
case D3D12_FILTER_MIN_MAG_MIP_LINEAR:
ret.minify = ret.magnify = ret.mip = FilterMode::Linear;
break;
default: break;
}
return ret;
}
D3DBufferViewFlags MakeBufferFlags(D3D12_BUFFER_SRV_FLAGS flags)
{
D3DBufferViewFlags ret = D3DBufferViewFlags::NoFlags;
if(flags & D3D12_BUFFER_SRV_FLAG_RAW)
ret |= D3DBufferViewFlags::Raw;
return ret;
}
D3DBufferViewFlags MakeBufferFlags(D3D12_BUFFER_UAV_FLAGS flags)
{
D3DBufferViewFlags ret = D3DBufferViewFlags::NoFlags;
if(flags & D3D12_BUFFER_UAV_FLAG_RAW)
ret |= D3DBufferViewFlags::Raw;
return ret;
}
LogicOperation MakeLogicOp(D3D12_LOGIC_OP op)
{
switch(op)
{
case D3D12_LOGIC_OP_CLEAR: return LogicOperation::Clear;
case D3D12_LOGIC_OP_AND: return LogicOperation::And;
case D3D12_LOGIC_OP_AND_REVERSE: return LogicOperation::AndReverse;
case D3D12_LOGIC_OP_COPY: return LogicOperation::Copy;
case D3D12_LOGIC_OP_AND_INVERTED: return LogicOperation::AndInverted;
case D3D12_LOGIC_OP_NOOP: return LogicOperation::NoOp;
case D3D12_LOGIC_OP_XOR: return LogicOperation::Xor;
case D3D12_LOGIC_OP_OR: return LogicOperation::Or;
case D3D12_LOGIC_OP_NOR: return LogicOperation::Nor;
case D3D12_LOGIC_OP_EQUIV: return LogicOperation::Equivalent;
case D3D12_LOGIC_OP_INVERT: return LogicOperation::Invert;
case D3D12_LOGIC_OP_OR_REVERSE: return LogicOperation::OrReverse;
case D3D12_LOGIC_OP_COPY_INVERTED: return LogicOperation::CopyInverted;
case D3D12_LOGIC_OP_OR_INVERTED: return LogicOperation::OrInverted;
case D3D12_LOGIC_OP_NAND: return LogicOperation::Nand;
case D3D12_LOGIC_OP_SET: return LogicOperation::Set;
default: break;
}
return LogicOperation::NoOp;
}
BlendMultiplier MakeBlendMultiplier(D3D12_BLEND blend, bool alpha)
{
switch(blend)
{
case D3D12_BLEND_ZERO: return BlendMultiplier::Zero;
case D3D12_BLEND_ONE: return BlendMultiplier::One;
case D3D12_BLEND_SRC_COLOR: return BlendMultiplier::SrcCol;
case D3D12_BLEND_INV_SRC_COLOR: return BlendMultiplier::InvSrcCol;
case D3D12_BLEND_DEST_COLOR: return BlendMultiplier::DstCol;
case D3D12_BLEND_INV_DEST_COLOR: return BlendMultiplier::InvDstCol;
case D3D12_BLEND_SRC_ALPHA: return BlendMultiplier::SrcAlpha;
case D3D12_BLEND_INV_SRC_ALPHA: return BlendMultiplier::InvSrcAlpha;
case D3D12_BLEND_DEST_ALPHA: return BlendMultiplier::DstAlpha;
case D3D12_BLEND_INV_DEST_ALPHA: return BlendMultiplier::InvDstAlpha;
case D3D12_BLEND_BLEND_FACTOR:
return alpha ? BlendMultiplier::FactorAlpha : BlendMultiplier::FactorRGB;
case D3D12_BLEND_INV_BLEND_FACTOR:
return alpha ? BlendMultiplier::InvFactorAlpha : BlendMultiplier::InvFactorRGB;
case D3D12_BLEND_SRC_ALPHA_SAT: return BlendMultiplier::SrcAlphaSat;
case D3D12_BLEND_SRC1_COLOR: return BlendMultiplier::Src1Col;
case D3D12_BLEND_INV_SRC1_COLOR: return BlendMultiplier::InvSrc1Col;
case D3D12_BLEND_SRC1_ALPHA: return BlendMultiplier::Src1Alpha;
case D3D12_BLEND_INV_SRC1_ALPHA: return BlendMultiplier::InvSrc1Alpha;
default: break;
}
return BlendMultiplier::One;
}
BlendOperation MakeBlendOp(D3D12_BLEND_OP op)
{
switch(op)
{
case D3D12_BLEND_OP_ADD: return BlendOperation::Add;
case D3D12_BLEND_OP_SUBTRACT: return BlendOperation::Subtract;
case D3D12_BLEND_OP_REV_SUBTRACT: return BlendOperation::ReversedSubtract;
case D3D12_BLEND_OP_MIN: return BlendOperation::Minimum;
case D3D12_BLEND_OP_MAX: return BlendOperation::Maximum;
default: break;
}
return BlendOperation::Add;
}
StencilOperation MakeStencilOp(D3D12_STENCIL_OP op)
{
switch(op)
{
case D3D12_STENCIL_OP_KEEP: return StencilOperation::Keep;
case D3D12_STENCIL_OP_ZERO: return StencilOperation::Zero;
case D3D12_STENCIL_OP_REPLACE: return StencilOperation::Replace;
case D3D12_STENCIL_OP_INCR_SAT: return StencilOperation::IncSat;
case D3D12_STENCIL_OP_DECR_SAT: return StencilOperation::DecSat;
case D3D12_STENCIL_OP_INVERT: return StencilOperation::Invert;
case D3D12_STENCIL_OP_INCR: return StencilOperation::IncWrap;
case D3D12_STENCIL_OP_DECR: return StencilOperation::DecWrap;
default: break;
}
return StencilOperation::Keep;
}
UINT GetResourceNumMipLevels(const D3D12_RESOURCE_DESC *desc)
{
switch(desc->Dimension)
{
default:
case D3D12_RESOURCE_DIMENSION_UNKNOWN:
RDCERR("Unexpected resource dimension! %d", desc->Dimension);
break;
case D3D12_RESOURCE_DIMENSION_BUFFER: return 1;
case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
{
if(desc->MipLevels)
return desc->MipLevels;
UINT w = RDCMAX(1U, UINT(desc->Width));
UINT count = 1;
while(w > 1)
{
++count;
w = RDCMAX(1U, w >> 1U);
}
return count;
}
case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
{
if(desc->MipLevels)
return desc->MipLevels;
UINT w = RDCMAX(1U, UINT(desc->Width));
UINT h = RDCMAX(1U, desc->Height);
UINT count = 1;
while(w > 1 || h > 1)
{
++count;
w = RDCMAX(1U, w >> 1U);
h = RDCMAX(1U, h >> 1U);
}
return count;
}
case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
{
if(desc->MipLevels)
return desc->MipLevels;
UINT w = RDCMAX(1U, UINT(desc->Width));
UINT h = RDCMAX(1U, desc->Height);
UINT d = RDCMAX(1U, UINT(desc->DepthOrArraySize));
UINT count = 1;
while(w > 1 || h > 1 || d > 1)
{
++count;
w = RDCMAX(1U, w >> 1U);
h = RDCMAX(1U, h >> 1U);
d = RDCMAX(1U, d >> 1U);
}
return count;
}
}
return 1;
}
UINT GetNumSubresources(ID3D12Device *dev, const D3D12_RESOURCE_DESC *desc)
{
D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = {};
formatInfo.Format = desc->Format;
dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo));
UINT planes = RDCMAX((UINT8)1, formatInfo.PlaneCount);
switch(desc->Dimension)
{
default:
case D3D12_RESOURCE_DIMENSION_UNKNOWN:
RDCERR("Unexpected resource dimension! %d", desc->Dimension);
break;
case D3D12_RESOURCE_DIMENSION_BUFFER: return planes;
case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
return RDCMAX((UINT16)1, desc->DepthOrArraySize) * GetResourceNumMipLevels(desc) * planes;
case D3D12_RESOURCE_DIMENSION_TEXTURE3D: return GetResourceNumMipLevels(desc) * planes;
}
return 1;
}
ShaderStageMask ConvertVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility)
{
switch(ShaderVisibility)
{
case D3D12_SHADER_VISIBILITY_ALL: return ShaderStageMask::All;
case D3D12_SHADER_VISIBILITY_VERTEX: return ShaderStageMask::Vertex;
case D3D12_SHADER_VISIBILITY_HULL: return ShaderStageMask::Hull;
case D3D12_SHADER_VISIBILITY_DOMAIN: return ShaderStageMask::Domain;
case D3D12_SHADER_VISIBILITY_GEOMETRY: return ShaderStageMask::Geometry;
case D3D12_SHADER_VISIBILITY_PIXEL: return ShaderStageMask::Pixel;
case D3D12_SHADER_VISIBILITY_AMPLIFICATION:
case D3D12_SHADER_VISIBILITY_MESH:
default: RDCERR("Unexpected visibility %u", ShaderVisibility); break;
}
return ShaderStageMask::Unknown;
}
// from PIXEventsCommon.h of winpixeventruntime
enum PIXEventType
{
ePIXEvent_EndEvent = 0x000,
ePIXEvent_BeginEvent_VarArgs = 0x001,
ePIXEvent_BeginEvent_NoArgs = 0x002,
ePIXEvent_SetMarker_VarArgs = 0x007,
ePIXEvent_SetMarker_NoArgs = 0x008,
ePIXEvent_EndEvent_OnContext = 0x010,
ePIXEvent_BeginEvent_OnContext_VarArgs = 0x011,
ePIXEvent_BeginEvent_OnContext_NoArgs = 0x012,
ePIXEvent_SetMarker_OnContext_VarArgs = 0x017,
ePIXEvent_SetMarker_OnContext_NoArgs = 0x018,
};
inline void PIX3DecodeEventInfo(const UINT64 BlobData, UINT64 &Timestamp, PIXEventType &EventType)
{
static const UINT64 PIXEventsBlockEndMarker = 0x00000000000FFF80;
static const UINT64 PIXEventsTypeReadMask = 0x00000000000FFC00;
static const UINT64 PIXEventsTypeWriteMask = 0x00000000000003FF;
static const UINT64 PIXEventsTypeBitShift = 10;
static const UINT64 PIXEventsTimestampReadMask = 0xFFFFFFFFFFF00000;
static const UINT64 PIXEventsTimestampWriteMask = 0x00000FFFFFFFFFFF;
static const UINT64 PIXEventsTimestampBitShift = 20;
Timestamp = (BlobData >> PIXEventsTimestampBitShift) & PIXEventsTimestampWriteMask;
EventType = PIXEventType((BlobData >> PIXEventsTypeBitShift) & PIXEventsTypeWriteMask);
}
inline void PIX3DecodeStringInfo(const UINT64 BlobData, UINT64 &Alignment, UINT64 &CopyChunkSize,
bool &IsANSI, bool &IsShortcut)
{
static const UINT64 PIXEventsStringAlignmentWriteMask = 0x000000000000000F;
static const UINT64 PIXEventsStringAlignmentReadMask = 0xF000000000000000;
static const UINT64 PIXEventsStringAlignmentBitShift = 60;
static const UINT64 PIXEventsStringCopyChunkSizeWriteMask = 0x000000000000001F;
static const UINT64 PIXEventsStringCopyChunkSizeReadMask = 0x0F80000000000000;
static const UINT64 PIXEventsStringCopyChunkSizeBitShift = 55;
static const UINT64 PIXEventsStringIsANSIWriteMask = 0x0000000000000001;
static const UINT64 PIXEventsStringIsANSIReadMask = 0x0040000000000000;
static const UINT64 PIXEventsStringIsANSIBitShift = 54;
static const UINT64 PIXEventsStringIsShortcutWriteMask = 0x0000000000000001;
static const UINT64 PIXEventsStringIsShortcutReadMask = 0x0020000000000000;
static const UINT64 PIXEventsStringIsShortcutBitShift = 53;
Alignment = (BlobData >> PIXEventsStringAlignmentBitShift) & PIXEventsStringAlignmentWriteMask;
CopyChunkSize =
(BlobData >> PIXEventsStringCopyChunkSizeBitShift) & PIXEventsStringCopyChunkSizeWriteMask;
IsANSI = (BlobData >> PIXEventsStringIsANSIBitShift) & PIXEventsStringIsANSIWriteMask;
IsShortcut = (BlobData >> PIXEventsStringIsShortcutBitShift) & PIXEventsStringIsShortcutWriteMask;
}
const UINT64 *PIX3DecodeStringParam(const UINT64 *pData, rdcstr &DecodedString)
{
UINT64 alignment;
UINT64 copyChunkSize;
bool isANSI;
bool isShortcut;
PIX3DecodeStringInfo(*pData, alignment, copyChunkSize, isANSI, isShortcut);
++pData;
UINT totalStringBytes = 0;
if(isANSI)
{
const char *c = (const char *)pData;
UINT formatStringCharCount = UINT(strlen((const char *)pData));
DecodedString = rdcstr(c, formatStringCharCount);
totalStringBytes = formatStringCharCount + 1;
}
else
{
const wchar_t *w = (const wchar_t *)pData;
UINT formatStringCharCount = UINT(wcslen((const wchar_t *)pData));
DecodedString = StringFormat::Wide2UTF8(rdcwstr(w, formatStringCharCount));
totalStringBytes = (formatStringCharCount + 1) * sizeof(wchar_t);
}
UINT64 byteChunks = ((totalStringBytes + copyChunkSize - 1) / copyChunkSize) * copyChunkSize;
UINT64 stringQWordCount = (byteChunks + 7) / 8;
pData += stringQWordCount;
return pData;
}
rdcstr PIX3SprintfParams(const rdcstr &Format, const UINT64 *pData)
{
rdcstr finalString;
rdcstr formatPart;
int32_t lastFind = 0;
for(int32_t found = Format.indexOf('%'); found >= 0;)
{
finalString += Format.substr(lastFind, found - lastFind);
int32_t endOfFormat = Format.find_first_of("%diufFeEgGxXoscpaAn", found + 1);
if(endOfFormat < 0)
{
finalString += "<FORMAT_ERROR>";
break;
}
formatPart = Format.substr(found, (endOfFormat - found) + 1);
// strings
if(formatPart.back() == 's')
{
rdcstr stringParam;
pData = PIX3DecodeStringParam(pData, stringParam);
finalString += stringParam;
}
// numerical values
else
{
finalString += StringFormat::Fmt(formatPart.c_str(), *pData);
++pData;
}
lastFind = endOfFormat + 1;
found = Format.indexOf('%', lastFind);
}
finalString += Format.substr(lastFind);
return finalString;
}
rdcstr PIX3DecodeEventString(const UINT64 *pData)
{
// event header
UINT64 timestamp;
PIXEventType eventType;
PIX3DecodeEventInfo(*pData, timestamp, eventType);
++pData;
// convert setmarker event types to beginevent event types because they're identical and it makes
// for easier processing.
if(eventType == ePIXEvent_SetMarker_NoArgs)
eventType = ePIXEvent_BeginEvent_NoArgs;
if(eventType == ePIXEvent_SetMarker_VarArgs)
eventType = ePIXEvent_BeginEvent_VarArgs;
if(eventType != ePIXEvent_BeginEvent_NoArgs && eventType != ePIXEvent_BeginEvent_VarArgs)
{
RDCERR("Unexpected/unsupported PIX3Event %u type in PIXDecodeMarkerEventString", eventType);
return "";
}
// color
// UINT64 color = *pData;
++pData;
// format string
rdcstr formatString;
pData = PIX3DecodeStringParam(pData, formatString);
if(eventType == ePIXEvent_BeginEvent_NoArgs)
return formatString;
// sprintf remaining args
formatString = PIX3SprintfParams(formatString, pData);
return formatString;
}
D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC(
const D3D12_GRAPHICS_PIPELINE_STATE_DESC &graphics)
{
pRootSignature = graphics.pRootSignature;
VS = graphics.VS;
PS = graphics.PS;
DS = graphics.DS;
HS = graphics.HS;
GS = graphics.GS;
StreamOutput = graphics.StreamOutput;
BlendState = graphics.BlendState;
SampleMask = graphics.SampleMask;
RasterizerState = graphics.RasterizerState;
{
DepthStencilState.DepthEnable = graphics.DepthStencilState.DepthEnable;
DepthStencilState.DepthWriteMask = graphics.DepthStencilState.DepthWriteMask;
DepthStencilState.DepthFunc = graphics.DepthStencilState.DepthFunc;
DepthStencilState.StencilEnable = graphics.DepthStencilState.StencilEnable;
DepthStencilState.StencilReadMask = graphics.DepthStencilState.StencilReadMask;
DepthStencilState.StencilWriteMask = graphics.DepthStencilState.StencilWriteMask;
DepthStencilState.FrontFace = graphics.DepthStencilState.FrontFace;
DepthStencilState.BackFace = graphics.DepthStencilState.BackFace;
// DepthBounds defaults to disabled
DepthStencilState.DepthBoundsTestEnable = FALSE;
}
InputLayout = graphics.InputLayout;
IBStripCutValue = graphics.IBStripCutValue;
PrimitiveTopologyType = graphics.PrimitiveTopologyType;
RTVFormats.NumRenderTargets = graphics.NumRenderTargets;
memcpy(RTVFormats.RTFormats, graphics.RTVFormats, 8 * sizeof(DXGI_FORMAT));
DSVFormat = graphics.DSVFormat;
SampleDesc = graphics.SampleDesc;
NodeMask = graphics.NodeMask;
CachedPSO = graphics.CachedPSO;
Flags = graphics.Flags;
// default state
ViewInstancing.Flags = D3D12_VIEW_INSTANCING_FLAG_NONE;
ViewInstancing.pViewInstanceLocations = NULL;
ViewInstancing.ViewInstanceCount = 0;
}
D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC(
const D3D12_COMPUTE_PIPELINE_STATE_DESC &compute)
{
pRootSignature = compute.pRootSignature;
CS = compute.CS;
NodeMask = compute.NodeMask;
CachedPSO = compute.CachedPSO;
Flags = compute.Flags;
}
// this awkward construction is to account for UINT and pointer aligned data on both 32-bit and
// 64-bit.
struct D3D12_PSO_SUBOBJECT
{
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE type;
};
struct D3D12_U32_PSO_SUBOBJECT
{
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE type;
union U32Data
{
UINT SampleMask;
DXGI_FORMAT DSVFormat;
UINT NodeMask;
D3D12_BLEND_DESC BlendState;
D3D12_RASTERIZER_DESC RasterizerState;
D3D12_DEPTH_STENCIL_DESC DepthStencilState;
D3D12_DEPTH_STENCIL_DESC1 DepthStencilState1;
D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue;
D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType;
D3D12_RT_FORMAT_ARRAY RTVFormats;
DXGI_SAMPLE_DESC SampleDesc;
D3D12_PIPELINE_STATE_FLAGS Flags;
} data;
};
struct D3D12_PTR_PSO_SUBOBJECT
{
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE type;
#if ENABLED(RDOC_X64)
UINT padding;
#endif
union PTRData
{
ID3D12RootSignature *pRootSignature;
D3D12_SHADER_BYTECODE shader;
D3D12_STREAM_OUTPUT_DESC StreamOutput;
D3D12_INPUT_LAYOUT_DESC InputLayout;
D3D12_CACHED_PIPELINE_STATE CachedPSO;
D3D12_VIEW_INSTANCING_DESC ViewInstancing;
} data;
};
D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC(
const D3D12_PIPELINE_STATE_STREAM_DESC &stream)
{
// ensure data is naturally aligned.
RDCCOMPILE_ASSERT(offsetof(D3D12_U32_PSO_SUBOBJECT, data.SampleMask) == 4,
"D3D12_U32_PSO_SUBOBJECT UINT data is misaligned");
RDCCOMPILE_ASSERT(offsetof(D3D12_PTR_PSO_SUBOBJECT, data.pRootSignature) == sizeof(void *),
"D3D12_PTR_PSO_SUBOBJECT Pointer data is misaligned");
RDCCOMPILE_ASSERT(offsetof(D3D12_PSO_SUBOBJECT, type) == 0,
"D3D12_PSO_SUBOBJECT type member is misaligned");
RDCCOMPILE_ASSERT(offsetof(D3D12_U32_PSO_SUBOBJECT, type) == 0,
"D3D12_U32_PSO_SUBOBJECT type member is misaligned");
RDCCOMPILE_ASSERT(offsetof(D3D12_PTR_PSO_SUBOBJECT, type) == 0,
"D3D12_PTR_PSO_SUBOBJECT type member is misaligned");
// first set default state
pRootSignature = NULL;
RDCEraseEl(VS);
RDCEraseEl(HS);
RDCEraseEl(DS);
RDCEraseEl(GS);
RDCEraseEl(PS);
RDCEraseEl(CS);
NodeMask = 0;
RDCEraseEl(CachedPSO);
Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
SampleMask = ~0U;
RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
RasterizerState.CullMode = D3D12_CULL_MODE_BACK;
RasterizerState.FrontCounterClockwise = FALSE;
RasterizerState.DepthBias = 0;
RasterizerState.DepthBiasClamp = 0.0f;
RasterizerState.SlopeScaledDepthBias = 0.0f;
RasterizerState.DepthClipEnable = TRUE;
RasterizerState.MultisampleEnable = FALSE;
RasterizerState.AntialiasedLineEnable = FALSE;
RasterizerState.ForcedSampleCount = 0;
RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
RDCEraseEl(StreamOutput);
BlendState.AlphaToCoverageEnable = FALSE;
BlendState.IndependentBlendEnable = FALSE;
for(int i = 0; i < 8; i++)
{
BlendState.RenderTarget[i].BlendEnable = FALSE;
BlendState.RenderTarget[i].LogicOpEnable = FALSE;
BlendState.RenderTarget[i].SrcBlend = D3D12_BLEND_ONE;
BlendState.RenderTarget[i].DestBlend = D3D12_BLEND_ZERO;
BlendState.RenderTarget[i].BlendOp = D3D12_BLEND_OP_ADD;
BlendState.RenderTarget[i].SrcBlendAlpha = D3D12_BLEND_ONE;
BlendState.RenderTarget[i].DestBlendAlpha = D3D12_BLEND_ZERO;
BlendState.RenderTarget[i].LogicOp = D3D12_LOGIC_OP_NOOP;
BlendState.RenderTarget[i].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
}
{
DepthStencilState.DepthEnable = TRUE;
DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
DepthStencilState.StencilEnable = FALSE;
DepthStencilState.StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK;
DepthStencilState.StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK;
DepthStencilState.FrontFace.StencilFunc = DepthStencilState.BackFace.StencilFunc =
D3D12_COMPARISON_FUNC_ALWAYS;
DepthStencilState.FrontFace.StencilDepthFailOp = DepthStencilState.BackFace.StencilDepthFailOp =
D3D12_STENCIL_OP_KEEP;
DepthStencilState.FrontFace.StencilPassOp = DepthStencilState.BackFace.StencilPassOp =
D3D12_STENCIL_OP_KEEP;
DepthStencilState.FrontFace.StencilFailOp = DepthStencilState.BackFace.StencilFailOp =
D3D12_STENCIL_OP_KEEP;
// DepthBounds defaults to disabled
DepthStencilState.DepthBoundsTestEnable = FALSE;
}
RDCEraseEl(InputLayout);
IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED;
RDCEraseEl(RTVFormats);
DSVFormat = DXGI_FORMAT_UNKNOWN;
SampleDesc.Count = 1;
SampleDesc.Quality = 0;
ViewInstancing.Flags = D3D12_VIEW_INSTANCING_FLAG_NONE;
ViewInstancing.pViewInstanceLocations = NULL;
ViewInstancing.ViewInstanceCount = 0;
#define ITER_ADV(objtype) \
iter = iter + sizeof(obj->type); \
iter = AlignUpPtr(iter, alignof(objtype)); \
iter += sizeof(objtype);
byte *iter = (byte *)stream.pPipelineStateSubobjectStream;
byte *end = iter + stream.SizeInBytes;
while(iter < end)
{
D3D12_PSO_SUBOBJECT *obj = (D3D12_PSO_SUBOBJECT *)iter;
D3D12_U32_PSO_SUBOBJECT *u32 = (D3D12_U32_PSO_SUBOBJECT *)obj;
D3D12_PTR_PSO_SUBOBJECT *ptr = (D3D12_PTR_PSO_SUBOBJECT *)obj;
switch(obj->type)
{
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE:
{
pRootSignature = ptr->data.pRootSignature;
ITER_ADV(ID3D12RootSignature *);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS:
{
VS = ptr->data.shader;
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS:
{
PS = ptr->data.shader;
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS:
{
HS = ptr->data.shader;
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS:
{
DS = ptr->data.shader;
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS:
{
GS = ptr->data.shader;
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CS:
{
CS = ptr->data.shader;
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT:
{
StreamOutput = ptr->data.StreamOutput;
ITER_ADV(D3D12_STREAM_OUTPUT_DESC);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND:
{
BlendState = u32->data.BlendState;
ITER_ADV(D3D12_BLEND_DESC);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK:
{
SampleMask = u32->data.SampleMask;
ITER_ADV(UINT);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER:
{
RasterizerState = u32->data.RasterizerState;
ITER_ADV(D3D12_RASTERIZER_DESC);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL:
{
const D3D12_DEPTH_STENCIL_DESC &dsdesc = u32->data.DepthStencilState;
DepthStencilState.DepthEnable = dsdesc.DepthEnable;
DepthStencilState.DepthWriteMask = dsdesc.DepthWriteMask;
DepthStencilState.DepthFunc = dsdesc.DepthFunc;
DepthStencilState.StencilEnable = dsdesc.StencilEnable;
DepthStencilState.StencilReadMask = dsdesc.StencilReadMask;
DepthStencilState.StencilWriteMask = dsdesc.StencilWriteMask;
DepthStencilState.FrontFace = dsdesc.FrontFace;
DepthStencilState.BackFace = dsdesc.BackFace;
ITER_ADV(D3D12_DEPTH_STENCIL_DESC);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT:
{
InputLayout = ptr->data.InputLayout;
ITER_ADV(D3D12_INPUT_LAYOUT_DESC);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE:
{
IBStripCutValue = u32->data.IBStripCutValue;
ITER_ADV(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY:
{
PrimitiveTopologyType = u32->data.PrimitiveTopologyType;
ITER_ADV(D3D12_PRIMITIVE_TOPOLOGY_TYPE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS:
{
RTVFormats = u32->data.RTVFormats;
ITER_ADV(D3D12_RT_FORMAT_ARRAY);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT:
{
DSVFormat = u32->data.DSVFormat;
ITER_ADV(DXGI_FORMAT);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC:
{
SampleDesc = u32->data.SampleDesc;
ITER_ADV(DXGI_SAMPLE_DESC);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK:
{
NodeMask = u32->data.NodeMask;
ITER_ADV(UINT);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO:
{
CachedPSO = ptr->data.CachedPSO;
ITER_ADV(D3D12_CACHED_PIPELINE_STATE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS:
{
Flags = u32->data.Flags;
ITER_ADV(D3D12_PIPELINE_STATE_FLAGS);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1:
{
DepthStencilState = u32->data.DepthStencilState1;
ITER_ADV(D3D12_DEPTH_STENCIL_DESC1);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING:
{
ViewInstancing = ptr->data.ViewInstancing;
ITER_ADV(D3D12_VIEW_INSTANCING_DESC);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS:
{
if(ptr->data.shader.BytecodeLength > 0)
{
RDCERR("AS passed to D3D12_PIPELINE_STATE_STREAM_DESC but mesh shaders not supported");
errored = true;
}
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS:
{
if(ptr->data.shader.BytecodeLength > 0)
{
RDCERR("MS passed to D3D12_PIPELINE_STATE_STREAM_DESC but mesh shaders not supported");
errored = true;
}
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
default:
{
RDCERR("Unknown subobject type %d", obj->type);
break;
}
}
iter = AlignUpPtr(iter, sizeof(void *));
}
}
void D3D12_PACKED_PIPELINE_STATE_STREAM_DESC::Unwrap()
{
m_GraphicsStreamData.pRootSignature = ::Unwrap(m_GraphicsStreamData.pRootSignature);
m_ComputeStreamData.pRootSignature = ::Unwrap(m_ComputeStreamData.pRootSignature);
}
D3D12_PACKED_PIPELINE_STATE_STREAM_DESC &D3D12_PACKED_PIPELINE_STATE_STREAM_DESC::operator=(
const D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC &expanded)
{
if(expanded.CS.BytecodeLength > 0)
{
m_ComputeStreamData.pRootSignature = expanded.pRootSignature;
m_ComputeStreamData.CS = expanded.CS;
m_ComputeStreamData.NodeMask = expanded.NodeMask;
m_ComputeStreamData.CachedPSO = expanded.CachedPSO;
m_ComputeStreamData.Flags = expanded.Flags;
}
else
{
m_GraphicsStreamData.pRootSignature = expanded.pRootSignature;
m_GraphicsStreamData.VS = expanded.VS;
m_GraphicsStreamData.PS = expanded.PS;
m_GraphicsStreamData.DS = expanded.DS;
m_GraphicsStreamData.HS = expanded.HS;
m_GraphicsStreamData.GS = expanded.GS;
m_GraphicsStreamData.StreamOutput = expanded.StreamOutput;
m_GraphicsStreamData.BlendState = expanded.BlendState;
m_GraphicsStreamData.SampleMask = expanded.SampleMask;
m_GraphicsStreamData.RasterizerState = expanded.RasterizerState;
m_GraphicsStreamData.DepthStencilState = expanded.DepthStencilState;
m_GraphicsStreamData.InputLayout = expanded.InputLayout;
m_GraphicsStreamData.IBStripCutValue = expanded.IBStripCutValue;
m_GraphicsStreamData.PrimitiveTopologyType = expanded.PrimitiveTopologyType;
m_GraphicsStreamData.RTVFormats = expanded.RTVFormats;
m_GraphicsStreamData.DSVFormat = expanded.DSVFormat;
m_GraphicsStreamData.SampleDesc = expanded.SampleDesc;
m_GraphicsStreamData.NodeMask = expanded.NodeMask;
m_GraphicsStreamData.CachedPSO = expanded.CachedPSO;
m_GraphicsStreamData.Flags = expanded.Flags;
m_GraphicsStreamData.ViewInstancing = expanded.ViewInstancing;
}
return *this;
}