-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathREV_CAPI_D3D.cpp
More file actions
202 lines (182 loc) · 7.7 KB
/
REV_CAPI_D3D.cpp
File metadata and controls
202 lines (182 loc) · 7.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#include "OVR_CAPI_D3D.h"
#include "openvr.h"
#include <d3d11.h>
#include "REV_Assert.h"
#include "REV_Common.h"
DXGI_FORMAT ovr_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_D16_UNORM: return DXGI_FORMAT_R16_TYPELESS;
case OVR_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
case OVR_FORMAT_D32_FLOAT: return DXGI_FORMAT_R32_TYPELESS;
case OVR_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
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;
case OVR_FORMAT_D16_UNORM: return DXGI_FORMAT_R16_TYPELESS;
case OVR_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
case OVR_FORMAT_D32_FLOAT: return DXGI_FORMAT_R32_TYPELESS;
case OVR_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
default: return DXGI_FORMAT_UNKNOWN;
}
}
}
UINT ovr_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;
}
OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateTextureSwapChainDX(ovrSession session,
IUnknown* d3dPtr,
const ovrTextureSwapChainDesc* desc,
ovrTextureSwapChain* out_TextureSwapChain)
{
// TODO: DX12 support.
ID3D11Device* pDevice;
HRESULT hr = d3dPtr->QueryInterface(&pDevice);
if (FAILED(hr))
return ovrError_RuntimeException;
D3D11_TEXTURE2D_DESC tdesc;
tdesc.Width = desc->Width;
tdesc.Height = desc->Height;
tdesc.MipLevels = desc->MipLevels;
tdesc.ArraySize = desc->ArraySize;
tdesc.SampleDesc.Count = 1;
tdesc.SampleDesc.Quality = 0;
tdesc.Format = ovr_TextureFormatToDXGIFormat(desc->Format, desc->MiscFlags);
tdesc.Usage = D3D11_USAGE_DEFAULT;
tdesc.BindFlags = ovr_BindFlagsToD3DBindFlags(desc->BindFlags);
tdesc.CPUAccessFlags = 0;
tdesc.MiscFlags = 0;
ovrTextureSwapChain swapChain = new ovrTextureSwapChainData();
swapChain->length = 2;
swapChain->index = 0;
swapChain->desc = *desc;
for (int i = 0; i < swapChain->length; i++)
{
swapChain->texture[i].eType = vr::API_DirectX;
swapChain->texture[i].eColorSpace = vr::ColorSpace_Auto; // TODO: Set this from the texture format.
hr = pDevice->CreateTexture2D(&tdesc, nullptr, (ID3D11Texture2D**)&swapChain->texture[i].handle);
if (FAILED(hr))
return ovrError_RuntimeException;
}
swapChain->current = swapChain->texture[swapChain->index];
// Clean up and return
pDevice->Release();
*out_TextureSwapChain = swapChain;
return ovrSuccess;
}
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferDX(ovrSession session,
ovrTextureSwapChain chain,
int index,
IID iid,
void** out_Buffer)
{
ID3D11Texture2D* texturePtr = (ID3D11Texture2D*)chain->texture[index].handle;
HRESULT hr = texturePtr->QueryInterface(iid, out_Buffer);
if (FAILED(hr))
return ovrError_RuntimeException;
return ovrSuccess;
}
OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateMirrorTextureDX(ovrSession session,
IUnknown* d3dPtr,
const ovrMirrorTextureDesc* desc,
ovrMirrorTexture* out_MirrorTexture)
{
// TODO: DX12 support.
ID3D11Device* pDevice;
HRESULT hr = d3dPtr->QueryInterface(&pDevice);
if (FAILED(hr))
return ovrError_RuntimeException;
// TODO: Implement support for texture flags.
ID3D11Texture2D* texture;
D3D11_TEXTURE2D_DESC tdesc;
tdesc.Width = desc->Width;
tdesc.Height = desc->Height;
tdesc.MipLevels = 1;
tdesc.ArraySize = 1;
tdesc.SampleDesc.Count = 1;
tdesc.SampleDesc.Quality = 0;
tdesc.Format = ovr_TextureFormatToDXGIFormat(desc->Format, desc->MiscFlags);
tdesc.Usage = D3D11_USAGE_DEFAULT;
tdesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
tdesc.CPUAccessFlags = 0;
tdesc.MiscFlags = 0;
hr = pDevice->CreateTexture2D(&tdesc, nullptr, &texture);
if (FAILED(hr))
return ovrError_RuntimeException;
// TODO: Should add multiple buffers to swapchain?
ovrMirrorTexture mirrorTexture = new ovrMirrorTextureData();
mirrorTexture->desc = *desc;
mirrorTexture->texture.handle = texture;
mirrorTexture->texture.eType = vr::API_DirectX;
mirrorTexture->texture.eColorSpace = vr::ColorSpace_Auto; // TODO: Set this from the texture format.
// Clean up and return
pDevice->Release();
*out_MirrorTexture = mirrorTexture;
return ovrSuccess;
}
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetMirrorTextureBufferDX(ovrSession session,
ovrMirrorTexture mirrorTexture,
IID iid,
void** out_Buffer)
{
ID3D11Texture2D* texture = (ID3D11Texture2D*)mirrorTexture->texture.handle;
ID3D11Device* pDevice;
texture->GetDevice(&pDevice);
ID3D11DeviceContext* pContext;
pDevice->GetImmediateContext(&pContext);
int perEyeWidth = mirrorTexture->desc.Width / 2;
for (int i = 0; i < ovrEye_Count; i++)
{
ovrTextureSwapChain chain = session->ColorTexture[i];
if (chain)
{
// TODO: Support texture bounds.
ID3D11Texture2D* eyeTexture = (ID3D11Texture2D*)chain->current.handle;
pContext->CopySubresourceRegion(texture, 0, perEyeWidth * i, 0, 0, eyeTexture, 0, nullptr);
}
}
HRESULT hr = texture->QueryInterface(iid, out_Buffer);
if (FAILED(hr))
return ovrError_RuntimeException;
// Clean up and return
pDevice->Release();
pContext->Release();
return ovrSuccess;
}