og-revive/Revive/TextureD3D.cpp

267 lines
9.5 KiB
C++
Raw Permalink Normal View History

#include "TextureD3D.h"
#include "OVR_CAPI.h"
#include <openvr.h>
#include <d3d11.h>
TextureD3D::TextureD3D(ID3D11Device* pDevice)
: m_pDevice(pDevice)
2017-08-20 22:21:50 +02:00
, m_data()
, m_pDevice12()
, m_pQueue()
{
}
2017-08-20 22:21:50 +02:00
TextureD3D::TextureD3D(ID3D12CommandQueue* pQueue)
: m_pDevice()
, m_data()
, m_pDevice12()
, m_pQueue(pQueue)
{
m_pQueue->GetDevice(IID_PPV_ARGS(&m_pDevice12));
m_data.m_pCommandQueue = m_pQueue.Get();
}
TextureD3D::~TextureD3D()
{
}
vr::VRTextureWithPose_t TextureD3D::ToVRTexture()
{
2017-08-19 14:42:56 +02:00
vr::VRTextureWithPose_t texture = {};
texture.eColorSpace = vr::ColorSpace_Auto; // TODO: Set this from the texture format
2017-08-20 22:21:50 +02:00
if (m_pDevice12)
{
texture.eType = vr::TextureType_DirectX12;
texture.handle = &m_data;
}
else
{
texture.eType = vr::TextureType_DirectX;
texture.handle = m_pTexture.Get();
}
return texture;
}
DXGI_FORMAT TextureD3D::TextureFormatToDXGIFormat(ovrTextureFormat format, unsigned int flags)
{
if (flags & ovrTextureMisc_DX_Typeless)
{
switch (format)
{
case OVR_FORMAT_UNKNOWN: return DXGI_FORMAT_UNKNOWN;
//case OVR_FORMAT_B5G6R5_UNORM: return DXGI_FORMAT_B5G6R5_TYPELESS;
//case OVR_FORMAT_B5G5R5A1_UNORM: return DXGI_FORMAT_B5G5R5A1_TYPELESS;
//case OVR_FORMAT_B4G4R4A4_UNORM: return DXGI_FORMAT_B4G4R4A4_TYPELESS;
case OVR_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_TYPELESS;
case OVR_FORMAT_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_TYPELESS;
case OVR_FORMAT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_TYPELESS;
case OVR_FORMAT_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_TYPELESS;
case OVR_FORMAT_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_TYPELESS;
case OVR_FORMAT_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_TYPELESS;
case OVR_FORMAT_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_TYPELESS;
case OVR_FORMAT_R11G11B10_FLOAT: return DXGI_FORMAT_R10G10B10A2_TYPELESS; // TODO: OpenVR doesn't support R11G11B10
2017-08-19 14:42:56 +02:00
// Depth formats
case OVR_FORMAT_D16_UNORM: return DXGI_FORMAT_R16_TYPELESS;
2017-08-20 22:21:50 +02:00
case OVR_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_R24G8_TYPELESS;
case OVR_FORMAT_D32_FLOAT: return DXGI_FORMAT_R32_TYPELESS;
2017-08-20 22:21:50 +02:00
case OVR_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32G32_TYPELESS;
// Added in 1.5 compressed formats can be used for static layers
case OVR_FORMAT_BC1_UNORM: return DXGI_FORMAT_BC1_TYPELESS;
case OVR_FORMAT_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_TYPELESS;
case OVR_FORMAT_BC2_UNORM: return DXGI_FORMAT_BC2_TYPELESS;
case OVR_FORMAT_BC2_UNORM_SRGB: return DXGI_FORMAT_BC2_TYPELESS;
case OVR_FORMAT_BC3_UNORM: return DXGI_FORMAT_BC3_TYPELESS;
case OVR_FORMAT_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_TYPELESS;
case OVR_FORMAT_BC6H_UF16: return DXGI_FORMAT_BC6H_TYPELESS;
case OVR_FORMAT_BC6H_SF16: return DXGI_FORMAT_BC6H_TYPELESS;
case OVR_FORMAT_BC7_UNORM: return DXGI_FORMAT_BC7_TYPELESS;
case OVR_FORMAT_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_TYPELESS;
default: return DXGI_FORMAT_UNKNOWN;
}
}
else
{
switch (format)
{
case OVR_FORMAT_UNKNOWN: return DXGI_FORMAT_UNKNOWN;
case OVR_FORMAT_B5G6R5_UNORM: return DXGI_FORMAT_B5G6R5_UNORM;
case OVR_FORMAT_B5G5R5A1_UNORM: return DXGI_FORMAT_B5G5R5A1_UNORM;
case OVR_FORMAT_B4G4R4A4_UNORM: return DXGI_FORMAT_B4G4R4A4_UNORM;
case OVR_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM;
case OVR_FORMAT_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
case OVR_FORMAT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM;
case OVR_FORMAT_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
case OVR_FORMAT_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM;
case OVR_FORMAT_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
case OVR_FORMAT_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT;
2017-08-19 14:42:56 +02:00
case OVR_FORMAT_R11G11B10_FLOAT: return DXGI_FORMAT_R10G10B10A2_UNORM; // TODO: OpenVR doesn't support R11G11B10
// Depth formats
2017-08-20 22:21:50 +02:00
case OVR_FORMAT_D16_UNORM: return DXGI_FORMAT_D16_UNORM;
case OVR_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_D24_UNORM_S8_UINT;
case OVR_FORMAT_D32_FLOAT: return DXGI_FORMAT_D32_FLOAT;
case OVR_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
// Added in 1.5 compressed formats can be used for static layers
case OVR_FORMAT_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM;
case OVR_FORMAT_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_UNORM_SRGB;
case OVR_FORMAT_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM;
case OVR_FORMAT_BC2_UNORM_SRGB: return DXGI_FORMAT_BC2_UNORM_SRGB;
case OVR_FORMAT_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM;
case OVR_FORMAT_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_UNORM_SRGB;
case OVR_FORMAT_BC6H_UF16: return DXGI_FORMAT_BC6H_UF16;
case OVR_FORMAT_BC6H_SF16: return DXGI_FORMAT_BC6H_SF16;
case OVR_FORMAT_BC7_UNORM: return DXGI_FORMAT_BC7_UNORM;
case OVR_FORMAT_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_UNORM_SRGB;
default: return DXGI_FORMAT_UNKNOWN;
}
}
}
2017-08-20 22:21:50 +02:00
ovrTextureFormat TextureD3D::ToLinearFormat(ovrTextureFormat format)
{
switch (format)
{
case OVR_FORMAT_R8G8B8A8_UNORM_SRGB: return OVR_FORMAT_R8G8B8A8_UNORM;
case OVR_FORMAT_B8G8R8A8_UNORM_SRGB: return OVR_FORMAT_B8G8R8A8_UNORM;
case OVR_FORMAT_B8G8R8X8_UNORM_SRGB: return OVR_FORMAT_B8G8R8X8_UNORM;
// Added in 1.5 compressed formats can be used for static layers
case OVR_FORMAT_BC1_UNORM_SRGB: return OVR_FORMAT_BC1_UNORM;
case OVR_FORMAT_BC2_UNORM_SRGB: return OVR_FORMAT_BC2_UNORM;
case OVR_FORMAT_BC3_UNORM_SRGB: return OVR_FORMAT_BC3_UNORM;
case OVR_FORMAT_BC7_UNORM_SRGB: return OVR_FORMAT_BC7_UNORM;
default: return format;
}
}
UINT TextureD3D::BindFlagsToD3DBindFlags(unsigned int flags)
{
UINT result = D3D11_BIND_SHADER_RESOURCE;
if (flags & ovrTextureBind_DX_RenderTarget)
result |= D3D11_BIND_RENDER_TARGET;
if (flags & ovrTextureBind_DX_UnorderedAccess)
result |= D3D11_BIND_UNORDERED_ACCESS;
if (flags & ovrTextureBind_DX_DepthStencil)
result |= D3D11_BIND_DEPTH_STENCIL;
return result;
}
UINT TextureD3D::MiscFlagsToD3DMiscFlags(unsigned int flags)
{
2017-12-02 14:11:40 -08:00
// TODO: Support ovrTextureMisc_AutoGenerateMips
UINT result = 0;
if (flags & ovrTextureMisc_AllowGenerateMips)
result |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
return result;
}
2017-08-20 22:21:50 +02:00
D3D12_RESOURCE_FLAGS TextureD3D::BindFlagsToD3DResourceFlags(unsigned int flags)
{
D3D12_RESOURCE_FLAGS result = D3D12_RESOURCE_FLAG_NONE;
if (flags & ovrTextureBind_DX_RenderTarget)
result |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
if (flags & ovrTextureBind_DX_UnorderedAccess)
result |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
if (flags & ovrTextureBind_DX_DepthStencil)
result |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
return result;
}
bool TextureD3D::Init(ovrTextureType type, int Width, int Height, int MipLevels, int ArraySize,
ovrTextureFormat Format, unsigned int MiscFlags, unsigned int BindFlags)
{
2017-08-20 22:21:50 +02:00
if (m_pDevice12)
{
D3D12_RESOURCE_DESC desc = {};
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
desc.Width = Width;
desc.Height = Height;
desc.DepthOrArraySize = ArraySize;
desc.MipLevels = MipLevels;
desc.Format = TextureFormatToDXGIFormat(Format, MiscFlags);
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Flags = BindFlagsToD3DResourceFlags(BindFlags);
D3D12_HEAP_PROPERTIES heap = {};
heap.Type = D3D12_HEAP_TYPE_DEFAULT;
heap.CreationNodeMask = 1;
heap.VisibleNodeMask = 1;
D3D12_CLEAR_VALUE clear = {};
clear.Format = TextureFormatToDXGIFormat(ToLinearFormat(Format));
if (BindFlags & ovrTextureBind_DX_DepthStencil)
{
clear.DepthStencil.Depth = 1.0f;
clear.DepthStencil.Stencil = 0;
}
else
{
clear.Color[3] = 1.0f;
}
HRESULT hr = m_pDevice12->CreateCommittedResource(&heap,
D3D12_HEAP_FLAG_NONE,
&desc,
D3D12_RESOURCE_STATE_COMMON,
&clear,
IID_PPV_ARGS(&m_pResource12));
if (FAILED(hr))
return false;
m_data.m_pResource = m_pResource12.Get();
}
else
{
2017-08-20 22:21:50 +02:00
D3D11_TEXTURE2D_DESC desc = {};
desc.Width = Width;
desc.Height = Height;
desc.MipLevels = MipLevels;
desc.ArraySize = ArraySize;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Format = TextureFormatToDXGIFormat(Format, MiscFlags);
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = BindFlagsToD3DBindFlags(BindFlags);
desc.CPUAccessFlags = 0;
desc.MiscFlags = MiscFlagsToD3DMiscFlags(MiscFlags);
HRESULT hr = m_pDevice->CreateTexture2D(&desc, nullptr, m_pTexture.GetAddressOf());
if (FAILED(hr))
return false;
}
2017-08-20 22:21:50 +02:00
if (m_pDevice)
{
2017-08-20 22:21:50 +02:00
D3D11_SHADER_RESOURCE_VIEW_DESC desc = {};
desc.Format = TextureFormatToDXGIFormat(Format, 0);
desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
desc.Texture2D.MipLevels = -1;
desc.Texture2D.MostDetailedMip = 0;
2017-08-20 22:21:50 +02:00
HRESULT hr = m_pDevice->CreateShaderResourceView(m_pTexture.Get(), &desc, m_pSRV.GetAddressOf());
if (FAILED(hr))
return false;
}
2017-08-20 22:21:50 +02:00
if (m_pDevice && BindFlags & ovrTextureBind_DX_RenderTarget)
{
2017-08-20 22:21:50 +02:00
D3D11_RENDER_TARGET_VIEW_DESC target_desc = {};
target_desc.Format = TextureFormatToDXGIFormat(Format, 0);
target_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
target_desc.Texture2D.MipSlice = 0;
2017-08-20 22:21:50 +02:00
HRESULT hr = m_pDevice->CreateRenderTargetView(m_pTexture.Get(), &target_desc, m_pRTV.GetAddressOf());
if (FAILED(hr))
return false;
}
return true;
}