Files
renderdoc/renderdoc/driver/d3d11/d3d11_common.cpp
T
baldurk 0b187934de Track bytes written for hidden SO counters. Closes #2662
* The D3D11 spec is unclear but checking sources including D3D11On12 it looks
  like the defined behaviour for SO counters is to calculate the number of bytes
  written and divide that by the VB stride on draw.
* Old captures can't be updated to work with this because the stride is unknown,
  but new captures will work correctly as well as any data that is stream'd out
  mid-capture.
2022-07-22 16:10:59 +01:00

826 lines
24 KiB
C++

/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2019-2022 Baldur Karlsson
* Copyright (c) 2014 Crytek
*
* 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 "d3d11_common.h"
#include "core/core.h"
#include "serialise/serialiser.h"
#include "strings/string_utils.h"
#include "d3d11_renderstate.h"
#include "d3d11_resources.h"
WrappedID3D11Device *D3D11MarkerRegion::device;
D3D11MarkerRegion::D3D11MarkerRegion(const rdcstr &marker)
{
D3D11MarkerRegion::Begin(marker);
}
D3D11MarkerRegion::~D3D11MarkerRegion()
{
D3D11MarkerRegion::End();
}
void D3D11MarkerRegion::Set(const rdcstr &marker)
{
if(device == NULL)
return;
ID3DUserDefinedAnnotation *annot = device->GetAnnotations();
if(annot)
annot->SetMarker(StringFormat::UTF82Wide(marker).c_str());
}
void D3D11MarkerRegion::Begin(const rdcstr &marker)
{
if(device == NULL)
return;
ID3DUserDefinedAnnotation *annot = device->GetAnnotations();
if(annot)
annot->BeginEvent(StringFormat::UTF82Wide(marker).c_str());
}
void D3D11MarkerRegion::End()
{
if(device == NULL)
return;
ID3DUserDefinedAnnotation *annot = device->GetAnnotations();
if(annot)
annot->EndEvent();
}
ResourceRange ResourceRange::Null = ResourceRange(ResourceRange::empty);
ResourceRange::ResourceRange(ID3D11ShaderResourceView *srv)
{
minMip = minSlice = 0;
depthReadOnly = false;
stencilReadOnly = false;
if(srv == NULL)
{
resource = NULL;
maxMip = allMip;
maxSlice = allSlice;
fullRange = true;
return;
}
// in non-release make sure we always consistently check wrapped resources/views. Otherwise we could
// end up in a situation where we're comparing two resource ranges that do overlap, but one was
// constructed with the wrapped view and one wasn't - so they compare differently
#if ENABLED(RDOC_DEVEL)
RDCASSERT(WrappedID3D11ShaderResourceView1::IsAlloc(srv));
#endif
ID3D11Resource *res = NULL;
srv->GetResource(&res);
res->Release();
resource = res;
UINT numMips = allMip, numSlices = allSlice;
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
srv->GetDesc(&srvd);
// extract depth/stencil read only flags if appropriate
{
D3D11_RESOURCE_DIMENSION dim;
DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN;
fmt = srvd.Format;
res->GetType(&dim);
if(fmt == DXGI_FORMAT_UNKNOWN)
{
if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D)
{
D3D11_TEXTURE1D_DESC d;
((ID3D11Texture1D *)res)->GetDesc(&d);
fmt = d.Format;
}
else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D)
{
D3D11_TEXTURE2D_DESC d;
((ID3D11Texture2D *)res)->GetDesc(&d);
fmt = d.Format;
}
}
if(fmt == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || fmt == DXGI_FORMAT_X24_TYPELESS_G8_UINT)
{
stencilReadOnly = true;
}
else if(fmt == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || fmt == DXGI_FORMAT_R24_UNORM_X8_TYPELESS)
{
depthReadOnly = true;
}
else
{
fmt = GetTypelessFormat(fmt);
// any format that could be depth-only, treat it as reading depth only.
// this only applies for conflicts detected with the depth target.
if(fmt == DXGI_FORMAT_R32_TYPELESS || fmt == DXGI_FORMAT_R16_TYPELESS)
{
depthReadOnly = true;
}
}
}
switch(srvd.ViewDimension)
{
case D3D11_SRV_DIMENSION_TEXTURE1D:
minMip = srvd.Texture1D.MostDetailedMip;
numMips = srvd.Texture1D.MipLevels;
minSlice = 0;
numSlices = 1;
break;
case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
minMip = srvd.Texture1DArray.MostDetailedMip;
numMips = srvd.Texture1DArray.MipLevels;
minSlice = srvd.Texture1DArray.FirstArraySlice;
numSlices = srvd.Texture1DArray.ArraySize;
break;
case D3D11_SRV_DIMENSION_TEXTURE2D:
minMip = srvd.Texture2D.MostDetailedMip;
numMips = srvd.Texture2D.MipLevels;
minSlice = 0;
numSlices = 1;
break;
case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
minMip = srvd.Texture2DArray.MostDetailedMip;
numMips = srvd.Texture2DArray.MipLevels;
minSlice = srvd.Texture2DArray.FirstArraySlice;
numSlices = srvd.Texture2DArray.ArraySize;
break;
case D3D11_SRV_DIMENSION_TEXTURE2DMS:
minMip = 0;
numMips = 1;
minSlice = 0;
numSlices = 1;
break;
case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
minMip = 0;
numMips = 1;
minSlice = srvd.Texture2DMSArray.FirstArraySlice;
numSlices = srvd.Texture2DMSArray.ArraySize;
break;
case D3D11_SRV_DIMENSION_TEXTURE3D:
minMip = srvd.Texture3D.MostDetailedMip;
numMips = srvd.Texture3D.MipLevels;
minSlice = 0;
numSlices = 1;
break;
case D3D11_SRV_DIMENSION_TEXTURECUBE:
minMip = srvd.TextureCube.MostDetailedMip;
numMips = srvd.TextureCube.MipLevels;
minSlice = 0;
numSlices = 1;
break;
case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY:
minMip = srvd.TextureCubeArray.MostDetailedMip;
numMips = srvd.TextureCubeArray.MipLevels;
minSlice = srvd.TextureCubeArray.First2DArrayFace;
numSlices = srvd.TextureCubeArray.NumCubes * 6;
break;
case D3D11_SRV_DIMENSION_UNKNOWN:
case D3D11_SRV_DIMENSION_BUFFER:
case D3D11_SRV_DIMENSION_BUFFEREX:
minMip = minSlice = 0;
numMips = numSlices = 1;
break;
}
SetMaxes(numMips, numSlices);
}
ResourceRange::ResourceRange(ID3D11UnorderedAccessView *uav)
{
minMip = minSlice = 0;
depthReadOnly = false;
stencilReadOnly = false;
if(uav == NULL)
{
resource = NULL;
maxMip = allMip;
maxSlice = allSlice;
fullRange = true;
return;
}
#if ENABLED(RDOC_DEVEL)
RDCASSERT(WrappedID3D11UnorderedAccessView1::IsAlloc(uav));
#endif
ID3D11Resource *res = NULL;
uav->GetResource(&res);
res->Release();
resource = res;
UINT numMips = allMip, numSlices = allSlice;
D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
uav->GetDesc(&desc);
switch(desc.ViewDimension)
{
case D3D11_UAV_DIMENSION_TEXTURE1D:
minMip = desc.Texture1D.MipSlice;
numMips = 1;
minSlice = 0;
numSlices = 1;
break;
case D3D11_UAV_DIMENSION_TEXTURE1DARRAY:
minMip = desc.Texture1DArray.MipSlice;
numMips = 1;
minSlice = desc.Texture1DArray.FirstArraySlice;
numSlices = desc.Texture1DArray.ArraySize;
break;
case D3D11_UAV_DIMENSION_TEXTURE2D:
minMip = desc.Texture2D.MipSlice;
numMips = 1;
minSlice = 0;
numSlices = 1;
break;
case D3D11_UAV_DIMENSION_TEXTURE2DARRAY:
minMip = desc.Texture2DArray.MipSlice;
numMips = 1;
minSlice = desc.Texture2DArray.FirstArraySlice;
numSlices = desc.Texture2DArray.ArraySize;
break;
case D3D11_UAV_DIMENSION_TEXTURE3D:
minMip = desc.Texture3D.MipSlice;
numMips = 1;
minSlice = desc.Texture3D.FirstWSlice;
numSlices = desc.Texture3D.WSize;
break;
case D3D11_UAV_DIMENSION_UNKNOWN:
case D3D11_UAV_DIMENSION_BUFFER:
minMip = minSlice = 0;
numMips = numSlices = 1;
break;
}
SetMaxes(numMips, numSlices);
}
ResourceRange::ResourceRange(ID3D11RenderTargetView *rtv)
{
minMip = minSlice = 0;
depthReadOnly = false;
stencilReadOnly = false;
if(rtv == NULL)
{
resource = NULL;
maxMip = allMip;
maxSlice = allSlice;
fullRange = true;
return;
}
#if ENABLED(RDOC_DEVEL)
RDCASSERT(WrappedID3D11RenderTargetView1::IsAlloc(rtv));
#endif
ID3D11Resource *res = NULL;
rtv->GetResource(&res);
res->Release();
resource = res;
UINT numMips = allMip, numSlices = allSlice;
D3D11_RENDER_TARGET_VIEW_DESC desc;
rtv->GetDesc(&desc);
switch(desc.ViewDimension)
{
case D3D11_RTV_DIMENSION_TEXTURE1D:
minMip = desc.Texture1D.MipSlice;
numMips = 1;
minSlice = 0;
numSlices = 1;
break;
case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
minMip = desc.Texture1DArray.MipSlice;
numMips = 1;
minSlice = desc.Texture1DArray.FirstArraySlice;
numSlices = desc.Texture1DArray.ArraySize;
break;
case D3D11_RTV_DIMENSION_TEXTURE2D:
minMip = desc.Texture2D.MipSlice;
numMips = 1;
minSlice = 0;
numSlices = 1;
break;
case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
minMip = desc.Texture2DArray.MipSlice;
numMips = 1;
minSlice = desc.Texture2DArray.FirstArraySlice;
numSlices = desc.Texture2DArray.ArraySize;
break;
case D3D11_RTV_DIMENSION_TEXTURE2DMS:
minMip = 0;
numMips = 1;
minSlice = 0;
numSlices = 1;
break;
case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
minMip = 0;
numMips = 1;
minSlice = desc.Texture2DMSArray.FirstArraySlice;
numSlices = desc.Texture2DMSArray.ArraySize;
break;
case D3D11_RTV_DIMENSION_TEXTURE3D:
minMip = desc.Texture3D.MipSlice;
numMips = 1;
minSlice = desc.Texture3D.FirstWSlice;
numSlices = desc.Texture3D.WSize;
break;
case D3D11_RTV_DIMENSION_UNKNOWN:
case D3D11_RTV_DIMENSION_BUFFER:
minMip = minSlice = 0;
numMips = numSlices = 1;
break;
}
SetMaxes(numMips, numSlices);
}
ResourceRange::ResourceRange(ID3D11DepthStencilView *dsv)
{
minMip = minSlice = 0;
depthReadOnly = false;
stencilReadOnly = false;
if(dsv == NULL)
{
resource = NULL;
maxMip = allMip;
maxSlice = allSlice;
fullRange = true;
return;
}
#if ENABLED(RDOC_DEVEL)
RDCASSERT(WrappedID3D11DepthStencilView::IsAlloc(dsv));
#endif
ID3D11Resource *res = NULL;
dsv->GetResource(&res);
res->Release();
resource = res;
UINT numMips = allMip, numSlices = allSlice;
D3D11_DEPTH_STENCIL_VIEW_DESC desc;
dsv->GetDesc(&desc);
if(desc.Flags & D3D11_DSV_READ_ONLY_DEPTH)
depthReadOnly = true;
if(desc.Flags & D3D11_DSV_READ_ONLY_STENCIL)
stencilReadOnly = true;
switch(desc.ViewDimension)
{
case D3D11_DSV_DIMENSION_TEXTURE1D:
minMip = desc.Texture1D.MipSlice;
numMips = 1;
minSlice = 0;
numSlices = 1;
break;
case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
minMip = desc.Texture1DArray.MipSlice;
numMips = 1;
minSlice = desc.Texture1DArray.FirstArraySlice;
numSlices = desc.Texture1DArray.ArraySize;
break;
case D3D11_DSV_DIMENSION_TEXTURE2D:
minMip = desc.Texture2D.MipSlice;
numMips = 1;
minSlice = 0;
numSlices = 1;
break;
case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
minMip = desc.Texture2DArray.MipSlice;
numMips = 1;
minSlice = desc.Texture2DArray.FirstArraySlice;
numSlices = desc.Texture2DArray.ArraySize;
break;
case D3D11_DSV_DIMENSION_TEXTURE2DMS:
minMip = 0;
numMips = 1;
minSlice = 0;
numSlices = 1;
break;
case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
minMip = 0;
numMips = 1;
minSlice = desc.Texture2DMSArray.FirstArraySlice;
numSlices = desc.Texture2DMSArray.ArraySize;
break;
case D3D11_DSV_DIMENSION_UNKNOWN:
minMip = minSlice = 0;
numMips = numSlices = 1;
break;
}
SetMaxes(numMips, numSlices);
}
ResourceRange::ResourceRange(ID3D11Buffer *res)
{
#if ENABLED(RDOC_DEVEL)
RDCASSERT(!res || WrappedID3D11Buffer::IsAlloc(res));
#endif
resource = res;
minMip = minSlice = 0;
maxMip = 0;
maxSlice = 0;
fullRange = true;
depthReadOnly = false;
stencilReadOnly = false;
}
ResourceRange::ResourceRange(ID3D11Texture2D *res)
{
#if ENABLED(RDOC_DEVEL)
RDCASSERT(!res || WrappedID3D11Texture2D1::IsAlloc(res));
#endif
resource = res;
minMip = minSlice = 0;
maxMip = allMip;
maxSlice = allSlice;
fullRange = true;
depthReadOnly = false;
stencilReadOnly = false;
}
ResourceRange::ResourceRange(ID3D11Resource *res, UINT mip, UINT slice)
{
#if ENABLED(RDOC_DEVEL)
RDCASSERT(!res || WrappedID3D11Texture1D::IsAlloc(res) || WrappedID3D11Texture2D1::IsAlloc(res) ||
WrappedID3D11Texture3D1::IsAlloc(res) || WrappedID3D11Buffer::IsAlloc(res));
#endif
resource = res;
minMip = mip;
maxMip = mip;
minSlice = slice;
maxSlice = slice;
fullRange = false;
depthReadOnly = false;
stencilReadOnly = false;
}
bool D3D11InitParams::IsSupportedVersion(uint64_t ver)
{
if(ver == CurrentVersion)
return true;
// 0x0F -> 0x10 - serialised the number of subresources in resource initial states after
// multiplying on sample count rather than before
if(ver == 0x0F)
return true;
// 0x10 -> 0x11 - added serialisation of adapter descriptor in D3D11InitParams
if(ver == 0x10)
return true;
// 0x11 -> 0x12 - added serialisation of vendor extension use in D3D11InitParams
if(ver == 0x11)
return true;
// 0x12 -> 0x13 - added stride from stream-out to hidden counter data
if(ver == 0x12)
return true;
return false;
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, D3D11InitParams &el)
{
SERIALISE_MEMBER(DriverType);
SERIALISE_MEMBER(Flags);
SERIALISE_MEMBER(SDKVersion);
SERIALISE_MEMBER(NumFeatureLevels);
SERIALISE_MEMBER(FeatureLevels);
if(ser.VersionAtLeast(0x11))
{
SERIALISE_MEMBER(AdapterDesc);
}
else
{
RDCEraseEl(el.AdapterDesc);
}
if(ser.VersionAtLeast(0x12))
{
SERIALISE_MEMBER(VendorExtensions);
SERIALISE_MEMBER(VendorUAV);
}
else
{
el.VendorExtensions = GPUVendor::Unknown;
el.VendorUAV = ~0U;
}
}
INSTANTIATE_SERIALISE_TYPE(D3D11InitParams);
TextureType MakeTextureDim(D3D11_SRV_DIMENSION dim)
{
switch(dim)
{
case D3D11_SRV_DIMENSION_UNKNOWN: return TextureType::Unknown;
case D3D11_SRV_DIMENSION_BUFFER:
case D3D11_SRV_DIMENSION_BUFFEREX: return TextureType::Buffer;
case D3D11_SRV_DIMENSION_TEXTURE1D: return TextureType::Texture1D;
case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: return TextureType::Texture1DArray;
case D3D11_SRV_DIMENSION_TEXTURE2D: return TextureType::Texture2D;
case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: return TextureType::Texture2DArray;
case D3D11_SRV_DIMENSION_TEXTURE2DMS: return TextureType::Texture2DMS;
case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: return TextureType::Texture2DMSArray;
case D3D11_SRV_DIMENSION_TEXTURE3D: return TextureType::Texture3D;
case D3D11_SRV_DIMENSION_TEXTURECUBE: return TextureType::TextureCube;
case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: return TextureType::TextureCubeArray;
}
return TextureType::Unknown;
}
TextureType MakeTextureDim(D3D11_RTV_DIMENSION dim)
{
switch(dim)
{
case D3D11_RTV_DIMENSION_UNKNOWN: return TextureType::Unknown;
case D3D11_RTV_DIMENSION_BUFFER: return TextureType::Buffer;
case D3D11_RTV_DIMENSION_TEXTURE1D: return TextureType::Texture1D;
case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: return TextureType::Texture1DArray;
case D3D11_RTV_DIMENSION_TEXTURE2D: return TextureType::Texture2D;
case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: return TextureType::Texture2DArray;
case D3D11_RTV_DIMENSION_TEXTURE2DMS: return TextureType::Texture2DMS;
case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: return TextureType::Texture2DMSArray;
case D3D11_RTV_DIMENSION_TEXTURE3D: return TextureType::Texture3D;
}
return TextureType::Unknown;
}
TextureType MakeTextureDim(D3D11_DSV_DIMENSION dim)
{
switch(dim)
{
case D3D11_DSV_DIMENSION_UNKNOWN: return TextureType::Unknown;
case D3D11_DSV_DIMENSION_TEXTURE1D: return TextureType::Texture1D;
case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: return TextureType::Texture1DArray;
case D3D11_DSV_DIMENSION_TEXTURE2D: return TextureType::Texture2D;
case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: return TextureType::Texture2DArray;
case D3D11_DSV_DIMENSION_TEXTURE2DMS: return TextureType::Texture2DMS;
case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: return TextureType::Texture2DMSArray;
}
return TextureType::Unknown;
}
TextureType MakeTextureDim(D3D11_UAV_DIMENSION dim)
{
switch(dim)
{
case D3D11_UAV_DIMENSION_UNKNOWN: return TextureType::Unknown;
case D3D11_UAV_DIMENSION_BUFFER: return TextureType::Buffer;
case D3D11_UAV_DIMENSION_TEXTURE1D: return TextureType::Texture1D;
case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: return TextureType::Texture1DArray;
case D3D11_UAV_DIMENSION_TEXTURE2D: return TextureType::Texture2D;
case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: return TextureType::Texture2DArray;
case D3D11_UAV_DIMENSION_TEXTURE3D: return TextureType::Texture3D;
}
return TextureType::Unknown;
}
AddressMode MakeAddressMode(D3D11_TEXTURE_ADDRESS_MODE addr)
{
switch(addr)
{
case D3D11_TEXTURE_ADDRESS_WRAP: return AddressMode::Wrap;
case D3D11_TEXTURE_ADDRESS_MIRROR: return AddressMode::Mirror;
case D3D11_TEXTURE_ADDRESS_CLAMP: return AddressMode::ClampEdge;
case D3D11_TEXTURE_ADDRESS_BORDER: return AddressMode::ClampBorder;
case D3D11_TEXTURE_ADDRESS_MIRROR_ONCE: return AddressMode::MirrorOnce;
default: break;
}
return AddressMode::Wrap;
}
CompareFunction MakeCompareFunc(D3D11_COMPARISON_FUNC func)
{
switch(func)
{
case D3D11_COMPARISON_NEVER: return CompareFunction::Never;
case D3D11_COMPARISON_LESS: return CompareFunction::Less;
case D3D11_COMPARISON_EQUAL: return CompareFunction::Equal;
case D3D11_COMPARISON_LESS_EQUAL: return CompareFunction::LessEqual;
case D3D11_COMPARISON_GREATER: return CompareFunction::Greater;
case D3D11_COMPARISON_NOT_EQUAL: return CompareFunction::NotEqual;
case D3D11_COMPARISON_GREATER_EQUAL: return CompareFunction::GreaterEqual;
case D3D11_COMPARISON_ALWAYS: return CompareFunction::AlwaysTrue;
default: break;
}
return CompareFunction::AlwaysTrue;
}
TextureFilter MakeFilter(D3D11_FILTER filter)
{
TextureFilter ret;
ret.filter = FilterFunction::Normal;
if(filter >= D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT &&
filter < D3D11_FILTER_COMPARISON_ANISOTROPIC)
{
ret.filter = FilterFunction::Comparison;
// the first 0x7f is the min/mag/mip filtering
filter = D3D11_FILTER(filter & 0x7f);
}
else if(filter >= D3D11_FILTER_MINIMUM_MIN_MAG_MIP_POINT &&
filter < D3D11_FILTER_MINIMUM_ANISOTROPIC)
{
ret.filter = FilterFunction::Minimum;
// the first 0x7f is the min/mag/mip filtering
filter = D3D11_FILTER(filter & 0x7f);
}
else if(filter >= D3D11_FILTER_MAXIMUM_MIN_MAG_MIP_POINT &&
filter < D3D11_FILTER_MAXIMUM_ANISOTROPIC)
{
ret.filter = FilterFunction::Maximum;
// the first 0x7f is the min/mag/mip filtering
filter = D3D11_FILTER(filter & 0x7f);
}
switch(filter)
{
case D3D11_FILTER_ANISOTROPIC:
ret.minify = ret.magnify = ret.mip = FilterMode::Anisotropic;
break;
case D3D11_FILTER_MIN_MAG_MIP_POINT:
ret.minify = ret.magnify = ret.mip = FilterMode::Point;
break;
case D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR:
ret.minify = ret.magnify = FilterMode::Point;
ret.mip = FilterMode::Linear;
break;
case D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT:
ret.minify = FilterMode::Point;
ret.magnify = FilterMode::Linear;
ret.mip = FilterMode::Point;
break;
case D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR:
ret.minify = FilterMode::Point;
ret.magnify = ret.mip = FilterMode::Linear;
break;
case D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT:
ret.minify = FilterMode::Linear;
ret.magnify = ret.mip = FilterMode::Point;
break;
case D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR:
ret.minify = FilterMode::Linear;
ret.magnify = FilterMode::Point;
ret.mip = FilterMode::Linear;
break;
case D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT:
ret.minify = ret.magnify = FilterMode::Linear;
ret.mip = FilterMode::Point;
break;
case D3D11_FILTER_MIN_MAG_MIP_LINEAR:
ret.minify = ret.magnify = ret.mip = FilterMode::Linear;
break;
default: break;
}
return ret;
}
LogicOperation MakeLogicOp(D3D11_LOGIC_OP op)
{
switch(op)
{
case D3D11_LOGIC_OP_CLEAR: return LogicOperation::Clear;
case D3D11_LOGIC_OP_AND: return LogicOperation::And;
case D3D11_LOGIC_OP_AND_REVERSE: return LogicOperation::AndReverse;
case D3D11_LOGIC_OP_COPY: return LogicOperation::Copy;
case D3D11_LOGIC_OP_AND_INVERTED: return LogicOperation::AndInverted;
case D3D11_LOGIC_OP_NOOP: return LogicOperation::NoOp;
case D3D11_LOGIC_OP_XOR: return LogicOperation::Xor;
case D3D11_LOGIC_OP_OR: return LogicOperation::Or;
case D3D11_LOGIC_OP_NOR: return LogicOperation::Nor;
case D3D11_LOGIC_OP_EQUIV: return LogicOperation::Equivalent;
case D3D11_LOGIC_OP_INVERT: return LogicOperation::Invert;
case D3D11_LOGIC_OP_OR_REVERSE: return LogicOperation::OrReverse;
case D3D11_LOGIC_OP_COPY_INVERTED: return LogicOperation::CopyInverted;
case D3D11_LOGIC_OP_OR_INVERTED: return LogicOperation::OrInverted;
case D3D11_LOGIC_OP_NAND: return LogicOperation::Nand;
case D3D11_LOGIC_OP_SET: return LogicOperation::Set;
default: break;
}
return LogicOperation::NoOp;
}
BlendMultiplier MakeBlendMultiplier(D3D11_BLEND blend, bool alpha)
{
switch(blend)
{
case D3D11_BLEND_ZERO: return BlendMultiplier::Zero;
case D3D11_BLEND_ONE: return BlendMultiplier::One;
case D3D11_BLEND_SRC_COLOR: return BlendMultiplier::SrcCol;
case D3D11_BLEND_INV_SRC_COLOR: return BlendMultiplier::InvSrcCol;
case D3D11_BLEND_DEST_COLOR: return BlendMultiplier::DstCol;
case D3D11_BLEND_INV_DEST_COLOR: return BlendMultiplier::InvDstCol;
case D3D11_BLEND_SRC_ALPHA: return BlendMultiplier::SrcAlpha;
case D3D11_BLEND_INV_SRC_ALPHA: return BlendMultiplier::InvSrcAlpha;
case D3D11_BLEND_DEST_ALPHA: return BlendMultiplier::DstAlpha;
case D3D11_BLEND_INV_DEST_ALPHA: return BlendMultiplier::InvDstAlpha;
case D3D11_BLEND_BLEND_FACTOR:
return alpha ? BlendMultiplier::FactorAlpha : BlendMultiplier::FactorRGB;
case D3D11_BLEND_INV_BLEND_FACTOR:
return alpha ? BlendMultiplier::InvFactorAlpha : BlendMultiplier::InvFactorRGB;
case D3D11_BLEND_SRC_ALPHA_SAT: return BlendMultiplier::SrcAlphaSat;
case D3D11_BLEND_SRC1_COLOR: return BlendMultiplier::Src1Col;
case D3D11_BLEND_INV_SRC1_COLOR: return BlendMultiplier::InvSrc1Col;
case D3D11_BLEND_SRC1_ALPHA: return BlendMultiplier::Src1Alpha;
case D3D11_BLEND_INV_SRC1_ALPHA: return BlendMultiplier::InvSrc1Alpha;
default: break;
}
return BlendMultiplier::One;
}
BlendOperation MakeBlendOp(D3D11_BLEND_OP op)
{
switch(op)
{
case D3D11_BLEND_OP_ADD: return BlendOperation::Add;
case D3D11_BLEND_OP_SUBTRACT: return BlendOperation::Subtract;
case D3D11_BLEND_OP_REV_SUBTRACT: return BlendOperation::ReversedSubtract;
case D3D11_BLEND_OP_MIN: return BlendOperation::Minimum;
case D3D11_BLEND_OP_MAX: return BlendOperation::Maximum;
default: break;
}
return BlendOperation::Add;
}
StencilOperation MakeStencilOp(D3D11_STENCIL_OP op)
{
switch(op)
{
case D3D11_STENCIL_OP_KEEP: return StencilOperation::Keep;
case D3D11_STENCIL_OP_ZERO: return StencilOperation::Zero;
case D3D11_STENCIL_OP_REPLACE: return StencilOperation::Replace;
case D3D11_STENCIL_OP_INCR_SAT: return StencilOperation::IncSat;
case D3D11_STENCIL_OP_DECR_SAT: return StencilOperation::DecSat;
case D3D11_STENCIL_OP_INVERT: return StencilOperation::Invert;
case D3D11_STENCIL_OP_INCR: return StencilOperation::IncWrap;
case D3D11_STENCIL_OP_DECR: return StencilOperation::DecWrap;
default: break;
}
return StencilOperation::Keep;
}