mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-14 09:23:53 +01:00
304 lines
8.6 KiB
C++
304 lines
8.6 KiB
C++
#pragma once
|
|
|
|
#include "d3d9_include.h"
|
|
|
|
#include "d3d9_format.h"
|
|
|
|
#include "../dxso/dxso_common.h"
|
|
#include "../dxvk/dxvk_device.h"
|
|
|
|
#include "../util/util_matrix.h"
|
|
|
|
#include <d3dcommon.h>
|
|
|
|
namespace dxvk {
|
|
|
|
struct D3D9ShaderMasks {
|
|
uint32_t samplerMask;
|
|
uint32_t rtMask;
|
|
};
|
|
|
|
static constexpr D3D9ShaderMasks FixedFunctionMask =
|
|
{ 0b1111111, 0b1 };
|
|
|
|
struct D3D9MipFilter {
|
|
bool MipsEnabled;
|
|
VkSamplerMipmapMode MipFilter;
|
|
};
|
|
|
|
struct D3D9BlendState {
|
|
D3DBLEND Src;
|
|
D3DBLEND Dst;
|
|
D3DBLENDOP Op;
|
|
};
|
|
|
|
inline void FixupBlendState(D3D9BlendState& State) {
|
|
// Old DirectX 6 HW feature that still exists...
|
|
// Yuck!
|
|
if (unlikely(State.Src == D3DBLEND_BOTHSRCALPHA)) {
|
|
State.Src = D3DBLEND_SRCALPHA;
|
|
State.Dst = D3DBLEND_INVSRCALPHA;
|
|
}
|
|
else if (unlikely(State.Src == D3DBLEND_BOTHINVSRCALPHA)) {
|
|
State.Src = D3DBLEND_INVSRCALPHA;
|
|
State.Dst = D3DBLEND_SRCALPHA;
|
|
}
|
|
}
|
|
|
|
inline bool InvalidSampler(DWORD Sampler) {
|
|
if (Sampler > 15 && Sampler < D3DDMAPSAMPLER)
|
|
return true;
|
|
|
|
if (Sampler > D3DVERTEXTEXTURESAMPLER3)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
inline DWORD RemapSamplerState(DWORD Sampler) {
|
|
if (Sampler >= D3DDMAPSAMPLER)
|
|
Sampler = 16 + (Sampler - D3DDMAPSAMPLER);
|
|
|
|
return Sampler;
|
|
}
|
|
|
|
inline std::pair<DxsoProgramType, DWORD> RemapStateSamplerShader(DWORD Sampler) {
|
|
if (Sampler >= 17)
|
|
return std::make_pair(DxsoProgramTypes::VertexShader, Sampler - 17);
|
|
|
|
return std::make_pair(DxsoProgramTypes::PixelShader, Sampler);
|
|
}
|
|
|
|
inline std::pair<DxsoProgramType, DWORD> RemapSamplerShader(DWORD Sampler) {
|
|
Sampler = RemapSamplerState(Sampler);
|
|
|
|
return RemapStateSamplerShader(Sampler);
|
|
}
|
|
|
|
template <typename T, typename J>
|
|
void CastRefPrivate(J* ptr, bool AddRef) {
|
|
if (ptr == nullptr)
|
|
return;
|
|
|
|
T* castedPtr = reinterpret_cast<T*>(ptr);
|
|
AddRef ? castedPtr->AddRefPrivate() : castedPtr->ReleasePrivate();
|
|
}
|
|
|
|
HRESULT DisassembleShader(
|
|
const void* pShader,
|
|
BOOL EnableColorCode,
|
|
char* pComments,
|
|
ID3DBlob** ppDisassembly);
|
|
|
|
HRESULT DecodeMultiSampleType(
|
|
D3DMULTISAMPLE_TYPE MultiSample,
|
|
DWORD MultisampleQuality,
|
|
VkSampleCountFlagBits* pCount);
|
|
|
|
VkFormat GetPackedDepthStencilFormat(D3D9Format Format);
|
|
|
|
VkFormatFeatureFlags GetImageFormatFeatures(DWORD Usage);
|
|
|
|
VkImageUsageFlags GetImageUsageFlags(DWORD Usage);
|
|
|
|
inline void DecodeD3DCOLOR(D3DCOLOR color, float* rgba) {
|
|
// Encoded in D3DCOLOR as argb
|
|
rgba[3] = (float)((color & 0xff000000) >> 24) / 255.0f;
|
|
rgba[0] = (float)((color & 0x00ff0000) >> 16) / 255.0f;
|
|
rgba[1] = (float)((color & 0x0000ff00) >> 8) / 255.0f;
|
|
rgba[2] = (float)((color & 0x000000ff)) / 255.0f;
|
|
}
|
|
|
|
inline VkFormat PickSRGB(VkFormat format, VkFormat srgbFormat, bool srgb) {
|
|
return srgb ? srgbFormat : format;
|
|
}
|
|
|
|
inline VkShaderStageFlagBits GetShaderStage(DxsoProgramType ProgramType) {
|
|
switch (ProgramType) {
|
|
case DxsoProgramTypes::VertexShader: return VK_SHADER_STAGE_VERTEX_BIT;
|
|
case DxsoProgramTypes::PixelShader: return VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
default: return VkShaderStageFlagBits(0);
|
|
}
|
|
}
|
|
|
|
inline uint32_t GetTransformIndex(D3DTRANSFORMSTATETYPE Type) {
|
|
if (Type == D3DTS_VIEW)
|
|
return 0;
|
|
|
|
if (Type == D3DTS_PROJECTION)
|
|
return 1;
|
|
|
|
if (Type >= D3DTS_TEXTURE0 && Type <= D3DTS_TEXTURE7)
|
|
return 2 + (Type - D3DTS_TEXTURE0);
|
|
|
|
return 10 + (Type - D3DTS_WORLD);
|
|
}
|
|
|
|
inline Matrix4 ConvertMatrix(const D3DMATRIX* Matrix) {
|
|
if (Matrix == nullptr) // Identity.
|
|
return Matrix4();
|
|
|
|
return Matrix4(Matrix->m);
|
|
}
|
|
|
|
uint32_t GetVertexCount(D3DPRIMITIVETYPE type, UINT count);
|
|
|
|
DxvkInputAssemblyState DecodeInputAssemblyState(D3DPRIMITIVETYPE type);
|
|
|
|
VkBlendFactor DecodeBlendFactor(D3DBLEND BlendFactor, bool IsAlpha);
|
|
|
|
VkBlendOp DecodeBlendOp(D3DBLENDOP BlendOp);
|
|
|
|
VkFilter DecodeFilter(D3DTEXTUREFILTERTYPE Filter);
|
|
|
|
D3D9MipFilter DecodeMipFilter(D3DTEXTUREFILTERTYPE Filter);
|
|
|
|
bool IsAnisotropic(D3DTEXTUREFILTERTYPE Filter);
|
|
|
|
VkSamplerAddressMode DecodeAddressMode(D3DTEXTUREADDRESS Mode);
|
|
|
|
VkCompareOp DecodeCompareOp(D3DCMPFUNC Func);
|
|
|
|
VkStencilOp DecodeStencilOp(D3DSTENCILOP Op);
|
|
|
|
VkCullModeFlags DecodeCullMode(D3DCULL Mode);
|
|
|
|
VkPolygonMode DecodeFillMode(D3DFILLMODE Mode);
|
|
|
|
VkIndexType DecodeIndexType(D3D9Format Format);
|
|
|
|
VkFormat DecodeDecltype(D3DDECLTYPE Type);
|
|
|
|
uint32_t GetDecltypeSize(D3DDECLTYPE Type);
|
|
|
|
uint32_t GetDecltypeCount(D3DDECLTYPE Type);
|
|
|
|
void ConvertBox(D3DBOX box, VkOffset3D& offset, VkExtent3D& extent);
|
|
|
|
void ConvertRect(RECT rect, VkOffset3D& offset, VkExtent3D& extent);
|
|
|
|
void ConvertRect(RECT rect, VkOffset2D& offset, VkExtent2D& extent);
|
|
|
|
inline float GetDepthBufferRValue(VkFormat Format) {
|
|
switch (Format) {
|
|
case VK_FORMAT_D16_UNORM_S8_UINT:
|
|
case VK_FORMAT_D16_UNORM:
|
|
return float(1 << 16);
|
|
|
|
case VK_FORMAT_D24_UNORM_S8_UINT:
|
|
return float(1 << 24);
|
|
|
|
default:
|
|
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
|
case VK_FORMAT_D32_SFLOAT:
|
|
return float(1 << 23);
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
UINT CompactSparseList(T* pData, UINT Mask) {
|
|
uint32_t count = 0;
|
|
|
|
while (Mask != 0) {
|
|
uint32_t id = bit::tzcnt(Mask);
|
|
pData[count++] = pData[id];
|
|
Mask &= Mask - 1;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
bool IsDepthFormat(D3D9Format Format);
|
|
|
|
inline bool operator == (const D3DVIEWPORT9& a, const D3DVIEWPORT9& b) {
|
|
return a.X == b.X &&
|
|
a.Y == b.Y &&
|
|
a.Width == b.Width &&
|
|
a.Height == b.Height &&
|
|
a.MinZ == b.MinZ &&
|
|
a.MaxZ == b.MaxZ;
|
|
}
|
|
|
|
inline bool operator != (const D3DVIEWPORT9& a, const D3DVIEWPORT9& b) {
|
|
return !(a == b);
|
|
}
|
|
|
|
inline bool operator == (const RECT& a, const RECT& b) {
|
|
return a.left == b.left &&
|
|
a.right == b.right &&
|
|
a.top == b.top &&
|
|
a.bottom == b.bottom;
|
|
}
|
|
|
|
inline bool operator != (const RECT& a, const RECT& b) {
|
|
return !(a == b);
|
|
}
|
|
|
|
inline bool operator == (const POINT& a, const POINT& b) {
|
|
return a.x == b.x && a.y == b.y;
|
|
}
|
|
|
|
inline bool operator != (const POINT& a, const POINT& b) {
|
|
return !(a == b);
|
|
}
|
|
|
|
inline bool IsPoolManaged(D3DPOOL Pool) {
|
|
return Pool == D3DPOOL_MANAGED || Pool == D3DPOOL_MANAGED_EX;
|
|
}
|
|
|
|
inline D3DRENDERSTATETYPE ColorWriteIndex(uint32_t i) {
|
|
return D3DRENDERSTATETYPE(i ? D3DRS_COLORWRITEENABLE1 + i - 1 : D3DRS_COLORWRITEENABLE);
|
|
}
|
|
|
|
inline bool AreFormatsSimilar(D3D9Format srcFormat, D3D9Format dstFormat) {
|
|
return (srcFormat == dstFormat)
|
|
|| (srcFormat == D3D9Format::A8B8G8R8 && dstFormat == D3D9Format::X8B8G8R8)
|
|
|| (srcFormat == D3D9Format::A8R8G8B8 && dstFormat == D3D9Format::X8R8G8B8)
|
|
|| (srcFormat == D3D9Format::A1R5G5B5 && dstFormat == D3D9Format::X1R5G5B5)
|
|
|| (srcFormat == D3D9Format::A4R4G4B4 && dstFormat == D3D9Format::X4R4G4B4);
|
|
}
|
|
|
|
inline bool IsBlitRegionInvalid(VkOffset3D offsets[2], VkExtent3D extent) {
|
|
// Only bother checking x, y as we don't have 3D blits.
|
|
return offsets[1].x < offsets[0].x ||
|
|
offsets[1].y < offsets[0].y ||
|
|
offsets[0].x < 0 ||
|
|
offsets[0].y < 0 ||
|
|
uint32_t(offsets[1].x) > extent.width ||
|
|
uint32_t(offsets[1].y) > extent.height;
|
|
}
|
|
|
|
enum D3D9TextureStageStateTypes : uint32_t
|
|
{
|
|
DXVK_TSS_COLOROP = 0,
|
|
DXVK_TSS_COLORARG1 = 1,
|
|
DXVK_TSS_COLORARG2 = 2,
|
|
DXVK_TSS_ALPHAOP = 3,
|
|
DXVK_TSS_ALPHAARG1 = 4,
|
|
DXVK_TSS_ALPHAARG2 = 5,
|
|
DXVK_TSS_BUMPENVMAT00 = 6,
|
|
DXVK_TSS_BUMPENVMAT01 = 7,
|
|
DXVK_TSS_BUMPENVMAT10 = 8,
|
|
DXVK_TSS_BUMPENVMAT11 = 9,
|
|
DXVK_TSS_TEXCOORDINDEX = 10,
|
|
DXVK_TSS_BUMPENVLSCALE = 21,
|
|
DXVK_TSS_BUMPENVLOFFSET = 22,
|
|
DXVK_TSS_TEXTURETRANSFORMFLAGS = 23,
|
|
DXVK_TSS_COLORARG0 = 25,
|
|
DXVK_TSS_ALPHAARG0 = 26,
|
|
DXVK_TSS_RESULTARG = 27,
|
|
DXVK_TSS_CONSTANT = 31,
|
|
DXVK_TSS_COUNT = 32
|
|
};
|
|
|
|
constexpr uint32_t DXVK_TSS_TCI_PASSTHRU = 0x00000000;
|
|
constexpr uint32_t DXVK_TSS_TCI_CAMERASPACENORMAL = 0x00010000;
|
|
constexpr uint32_t DXVK_TSS_TCI_CAMERASPACEPOSITION = 0x00020000;
|
|
constexpr uint32_t DXVK_TSS_TCI_CAMERASPACEREFLECTIONVECTOR = 0x00030000;
|
|
constexpr uint32_t DXVK_TSS_TCI_SPHEREMAP = 0x00040000;
|
|
|
|
inline D3D9TextureStageStateTypes RemapTextureStageStateType(D3DTEXTURESTAGESTATETYPE Type) {
|
|
return D3D9TextureStageStateTypes(Type - 1);
|
|
}
|
|
|
|
} |