aboutsummaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2015-03-21 21:19:34 +0100
committerSven Gothel <[email protected]>2015-03-21 21:19:34 +0100
commite490c3c7f7bb5461cfa78a214827aa534fb43a3e (patch)
treeb86b0291ef529ec6b75cc548d73599fa9c283cd6 /LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp
parent05bb4364bfd9930fb1902efec86446ef035ee07a (diff)
Bump OculusVR RIFT SDK to 0.4.4
Diffstat (limited to 'LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp')
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp1012
1 files changed, 811 insertions, 201 deletions
diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp
index 60e2c88..04cfd07 100644
--- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp
+++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp
@@ -3,18 +3,18 @@
Filename : CAPI_D3D1X_DistortionRenderer.cpp
Content : Experimental distortion renderer
Created : November 11, 2013
-Authors : Volga Aksoy, Michael Antonov
+Authors : Volga Aksoy, Michael Antonov, Shariq Hashme
-Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
-Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
+Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
you may not use the Oculus VR Rift SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
-http://www.oculusvr.com/licenses/LICENSE-3.1
+http://www.oculusvr.com/licenses/LICENSE-3.2
Unless required by applicable law or agreed to in writing, the Oculus VR SDK
distributed under the License is distributed on an "AS IS" BASIS,
@@ -27,26 +27,33 @@ limitations under the License.
#include "CAPI_D3D1X_DistortionRenderer.h"
#include "../../OVR_CAPI_D3D.h"
+#include "../CAPI_HMDState.h"
+#include "../../Kernel/OVR_Color.h"
namespace OVR { namespace CAPI { namespace D3D_NS {
-#include "../Shaders/Distortion_vs.h"
-#include "../Shaders/Distortion_vs_refl.h"
-#include "../Shaders/Distortion_ps.h"
-#include "../Shaders/Distortion_ps_refl.h"
-#include "../Shaders/DistortionChroma_vs.h"
-#include "../Shaders/DistortionChroma_vs_refl.h"
-#include "../Shaders/DistortionChroma_ps.h"
-#include "../Shaders/DistortionChroma_ps_refl.h"
-#include "../Shaders/DistortionTimewarp_vs.h"
-#include "../Shaders/DistortionTimewarp_vs_refl.h"
-#include "../Shaders/DistortionTimewarpChroma_vs.h"
-#include "../Shaders/DistortionTimewarpChroma_vs_refl.h"
-
-#include "../Shaders/SimpleQuad_vs.h"
-#include "../Shaders/SimpleQuad_vs_refl.h"
-#include "../Shaders/SimpleQuad_ps.h"
-#include "../Shaders/SimpleQuad_ps_refl.h"
+#include "Shaders/Distortion_vs.h"
+#include "Shaders/Distortion_vs_refl.h"
+#include "Shaders/Distortion_ps.h"
+#include "Shaders/Distortion_ps_refl.h"
+#include "Shaders/DistortionChroma_vs.h"
+#include "Shaders/DistortionChroma_vs_refl.h"
+#include "Shaders/DistortionChroma_ps.h"
+#include "Shaders/DistortionChroma_ps_refl.h"
+#include "Shaders/DistortionTimewarp_vs.h"
+#include "Shaders/DistortionTimewarp_vs_refl.h"
+#include "Shaders/DistortionTimewarpChroma_vs.h"
+#include "Shaders/DistortionTimewarpChroma_vs_refl.h"
+#include "Shaders/DistortionCS2x2.h"
+#include "Shaders/DistortionCS2x2_refl.h"
+
+#include "Shaders/SimpleQuad_vs.h"
+#include "Shaders/SimpleQuad_vs_refl.h"
+#include "Shaders/SimpleQuad_ps.h"
+#include "Shaders/SimpleQuad_ps_refl.h"
+
+#include <initguid.h>
+DEFINE_GUID(IID_OVRDXGISwapchain, 0x868f9b4f, 0xe427, 0x46ed, 0xb0, 0x94, 0x66, 0xd1, 0x3b, 0xb, 0x48, 0xf7);
// Distortion pixel shader lookup.
// Bit 0: Chroma Correction
@@ -56,7 +63,7 @@ enum {
DistortionVertexShaderBitMask = 3,
DistortionVertexShaderCount = DistortionVertexShaderBitMask + 1,
DistortionPixelShaderBitMask = 1,
- DistortionPixelShaderCount = DistortionPixelShaderBitMask + 1
+ DistortionPixelShaderCount = DistortionPixelShaderBitMask + 1,
};
struct PrecompiledShader
@@ -83,8 +90,21 @@ static PrecompiledShader DistortionVertexShaderLookup[DistortionVertexShaderCoun
static PrecompiledShader DistortionPixelShaderLookup[DistortionPixelShaderCount] =
{
PCS_NOREFL(Distortion_ps),
- PCS_NOREFL(DistortionChroma_ps)
+ PCS_REFL__(DistortionChroma_ps)
+};
+
+enum
+{
+ DistortionComputeShader2x2 = 0,
+ DistortionComputeShader2x2Pentile,
+ DistortionComputeShaderCount
};
+static PrecompiledShader DistortionComputeShaderLookup[DistortionComputeShaderCount] =
+{
+ PCS_REFL__(DistortionCS2x2)
+};
+
+
void DistortionShaderBitIndexCheck()
{
@@ -94,15 +114,24 @@ void DistortionShaderBitIndexCheck()
-struct DistortionVertex
+struct DistortionVertex // Must match the VB description DistortionMeshVertexDesc
{
- Vector2f Pos;
- Vector2f TexR;
- Vector2f TexG;
- Vector2f TexB;
+ Vector2f ScreenPosNDC;
+ Vector2f TanEyeAnglesR;
+ Vector2f TanEyeAnglesG;
+ Vector2f TanEyeAnglesB;
Color Col;
};
+struct DistortionComputePin // Must match the ones declared in DistortionCS*.csh
+{
+ Vector2f TanEyeAnglesR;
+ Vector2f TanEyeAnglesG;
+ Vector2f TanEyeAnglesB;
+ Color Col;
+ int padding[1]; // Aligns to power-of-two boundary, increases performance significantly.
+};
+
// Vertex type; same format is used for all shapes for simplicity.
// Shapes are built by adding vertices to Model.
@@ -135,6 +164,8 @@ DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager
const HMDRenderState& renderState)
: CAPI::DistortionRenderer(ovrRenderAPI_D3D11, hmd, timeManager, renderState)
{
+ SrgbBackBuffer = false;
+
EyeTextureSize[0] = Sizei(0);
EyeRenderViewport[0] = Recti();
EyeTextureSize[1] = Sizei(0);
@@ -155,8 +186,7 @@ CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd,
}
-bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig,
- unsigned distortionCaps)
+bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig)
{
const ovrD3D1X(Config)* config = (const ovrD3D1X(Config)*)apiConfig;
@@ -171,24 +201,48 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig,
if (!config->D3D_NS.pDevice || !config->D3D_NS.pBackBufferRT)
return false;
-
+
+ if (System::DirectDisplayEnabled())
+ {
+ Ptr<IUnknown> ovrSwapChain;
+ if (config->D3D_NS.pSwapChain->QueryInterface(IID_OVRDXGISwapchain, (void**)&ovrSwapChain.GetRawRef()) == E_NOINTERFACE)
+ {
+ OVR_DEBUG_LOG_TEXT(("ovr_Initialize() or ovr_InitializeRenderingShim() wasn't called before DXGISwapChain was created."));
+ }
+ }
+
RParams.pDevice = config->D3D_NS.pDevice;
RParams.pContext = D3DSELECT_10_11(config->D3D_NS.pDevice, config->D3D_NS.pDeviceContext);
RParams.pBackBufferRT = config->D3D_NS.pBackBufferRT;
+#if (OVR_D3D_VERSION>=11)
+ RParams.pBackBufferUAV = config->D3D_NS.pBackBufferUAV;
+#else
+ RParams.pBackBufferUAV = NULL;
+#endif
RParams.pSwapChain = config->D3D_NS.pSwapChain;
- RParams.RTSize = config->D3D_NS.Header.RTSize;
+ RParams.BackBufferSize = config->D3D_NS.Header.BackBufferSize;
RParams.Multisample = config->D3D_NS.Header.Multisample;
GfxState = *new GraphicsState(RParams.pContext);
- DistortionCaps = distortionCaps;
+ D3D1X_(RENDER_TARGET_VIEW_DESC) backBufferDesc;
+ RParams.pBackBufferRT->GetDesc(&backBufferDesc);
+ SrgbBackBuffer = (backBufferDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) ||
+ (backBufferDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB) ||
+ (backBufferDesc.Format == DXGI_FORMAT_B8G8R8X8_UNORM_SRGB);
- //DistortionWarper.SetVsync((hmdCaps & ovrHmdCap_NoVSync) ? false : true);
+
+#if 0 // enable related section in DistortionChroma.psh shader
+ // aniso requires proper sRGB sampling
+ SampleMode hqFilter = (RState.DistortionCaps & ovrDistortionCap_HqDistortion) ? Sample_Anisotropic : Sample_Linear;
+#else
+ SampleMode hqFilter = Sample_Linear;
+#endif
pEyeTextures[0] = *new Texture(&RParams, Texture_RGBA, Sizei(0),
- getSamplerState(Sample_Linear|Sample_ClampBorder));
+ getSamplerState(hqFilter|Sample_ClampBorder));
pEyeTextures[1] = *new Texture(&RParams, Texture_RGBA, Sizei(0),
- getSamplerState(Sample_Linear|Sample_ClampBorder));
+ getSamplerState(hqFilter|Sample_ClampBorder));
initBuffersAndShaders();
@@ -199,8 +253,11 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig,
rs.CullMode = D3D1X_(CULL_BACK);
rs.DepthClipEnable = true;
rs.FillMode = D3D1X_(FILL_SOLID);
+ Rasterizer = NULL;
RParams.pDevice->CreateRasterizerState(&rs, &Rasterizer.GetRawRef());
+ initOverdrive();
+
// TBD: Blend state.. not used?
// We'll want to turn off blending
@@ -211,8 +268,53 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig,
return true;
}
+void DistortionRenderer::initOverdrive()
+{
+ if(RState.DistortionCaps & ovrDistortionCap_Overdrive)
+ {
+ LastUsedOverdriveTextureIndex = 0;
+
+ D3D1X_(RENDER_TARGET_VIEW_DESC) backBufferDesc;
+ RParams.pBackBufferRT->GetDesc(&backBufferDesc);
+
+ for (int i = 0; i < NumOverdriveTextures; i++)
+ {
+ pOverdriveTextures[i] = *new Texture(&RParams, Texture_RGBA, RParams.BackBufferSize,
+ getSamplerState(Sample_Linear|Sample_ClampBorder));
+
+ D3D1X_(TEXTURE2D_DESC) dsDesc;
+ dsDesc.Width = RParams.BackBufferSize.w;
+ dsDesc.Height = RParams.BackBufferSize.h;
+ dsDesc.MipLevels = 1;
+ dsDesc.ArraySize = 1;
+ dsDesc.Format = backBufferDesc.Format;
+ dsDesc.SampleDesc.Count = 1;
+ dsDesc.SampleDesc.Quality = 0;
+ dsDesc.Usage = D3D1X_(USAGE_DEFAULT);
+ dsDesc.BindFlags = D3D1X_(BIND_SHADER_RESOURCE) | D3D1X_(BIND_RENDER_TARGET);
+ dsDesc.CPUAccessFlags = 0;
+ dsDesc.MiscFlags = 0;
+
+ HRESULT hr = RParams.pDevice->CreateTexture2D(&dsDesc, NULL, &pOverdriveTextures[i]->Tex.GetRawRef());
+ if (FAILED(hr))
+ {
+ OVR_DEBUG_LOG_TEXT(("Failed to create overdrive texture."));
+ // Remove overdrive flag since we failed to create the texture
+ LastUsedOverdriveTextureIndex = -1; // disables feature
+ break;
+ }
+
+ RParams.pDevice->CreateShaderResourceView(pOverdriveTextures[i]->Tex, NULL, &pOverdriveTextures[i]->TexSv.GetRawRef());
+ RParams.pDevice->CreateRenderTargetView(pOverdriveTextures[i]->Tex, NULL, &pOverdriveTextures[i]->TexRtv.GetRawRef());
+ }
+ }
+ else
+ {
+ LastUsedOverdriveTextureIndex = -1;
+ }
+}
-void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture)
+void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture)
{
const ovrD3D1X(Texture)* tex = (const ovrD3D1X(Texture)*)eyeTexture;
@@ -229,44 +331,64 @@ void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture)
EyeTextureSize[eyeId], EyeRenderViewport[eyeId],
UVScaleOffset[eyeId]);
+ if (RState.DistortionCaps & ovrDistortionCap_FlipInput)
+ {
+ UVScaleOffset[eyeId][0].y = -UVScaleOffset[eyeId][0].y;
+ UVScaleOffset[eyeId][1].y = 1.0f - UVScaleOffset[eyeId][1].y;
+ }
+
pEyeTextures[eyeId]->UpdatePlaceholderTexture(tex->D3D_NS.pTexture, tex->D3D_NS.pSRView,
tex->D3D_NS.Header.TextureSize);
}
}
-void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor,
- unsigned char* latencyTester2DrawColor)
+void DistortionRenderer::renderEndFrame()
{
- if (!TimeManager.NeedDistortionTimeMeasurement())
- {
- if (RState.DistortionCaps & ovrDistortionCap_TimeWarp)
- {
- // Wait for timewarp distortion if it is time and Gpu idle
- FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime);
- }
+ renderDistortion(pEyeTextures[0], pEyeTextures[1]);
+
+ if(RegisteredPostDistortionCallback)
+ RegisteredPostDistortionCallback(RParams.pContext);
- renderDistortion(pEyeTextures[0], pEyeTextures[1]);
+ if(LatencyTest2Active)
+ {
+ renderLatencyPixel(LatencyTest2DrawColor);
}
- else
+}
+
+void DistortionRenderer::EndFrame(bool swapBuffers)
+{
+ // Don't spin if we are explicitly asked not to
+ if ((RState.DistortionCaps & ovrDistortionCap_TimeWarp) &&
+ !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits))
{
- // If needed, measure distortion time so that TimeManager can better estimate
- // latency-reducing time-warp wait timing.
- WaitUntilGpuIdle();
- double distortionStartTime = ovr_GetTimeInSeconds();
+ if (!TimeManager.NeedDistortionTimeMeasurement())
+ {
+ // Wait for timewarp distortion if it is time and Gpu idle
+ FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime);
+
+ renderEndFrame();
+ }
+ else
+ {
+ // If needed, measure distortion time so that TimeManager can better estimate
+ // latency-reducing time-warp wait timing.
+ WaitUntilGpuIdle();
+ double distortionStartTime = ovr_GetTimeInSeconds();
- renderDistortion(pEyeTextures[0], pEyeTextures[1]);
+ renderEndFrame();
- WaitUntilGpuIdle();
- TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime);
+ WaitUntilGpuIdle();
+ TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime);
+ }
}
-
- if(latencyTesterDrawColor)
+ else
{
- renderLatencyQuad(latencyTesterDrawColor);
+ renderEndFrame();
}
- else if(latencyTester2DrawColor)
+
+ if(LatencyTestActive)
{
- renderLatencyPixel(latencyTester2DrawColor);
+ renderLatencyQuad(LatencyTestDrawColor);
}
if (swapBuffers)
@@ -278,7 +400,12 @@ void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTester
// Force GPU to flush the scene, resulting in the lowest possible latency.
// It's critical that this flush is *after* present.
- WaitUntilGpuIdle();
+ // With the display driver this flush is obsolete and theoretically should
+ // be a no-op.
+ // Doesn't need to be done if running through the Oculus driver.
+ if (RState.OurHMDInfo.InCompatibilityMode &&
+ !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits))
+ WaitUntilGpuIdle();
}
else
{
@@ -312,99 +439,180 @@ void DistortionRenderer::WaitUntilGpuIdle()
double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime)
{
- double initialTime = ovr_GetTimeInSeconds();
- if (initialTime >= absTime)
- return 0.0;
-
- // Flush and Stall CPU while waiting for GPU to complete rendering all of the queued draw calls
- D3D1x_QUERY_DESC queryDesc = { D3D1X_(QUERY_EVENT), 0 };
- Ptr<ID3D1xQuery> query;
- BOOL done = FALSE;
- bool callGetData = false;
-
- if (RParams.pDevice->CreateQuery(&queryDesc, &query.GetRawRef()) == S_OK)
- {
- D3DSELECT_10_11(query->End(),
- RParams.pContext->End(query));
- callGetData = true;
- }
-
- double newTime = initialTime;
- volatile int i;
-
- while (newTime < absTime)
- {
- if (callGetData)
- {
- // GetData will returns S_OK for both done == TRUE or FALSE.
- // Stop calling GetData on failure.
- callGetData = !FAILED(D3DSELECT_10_11(query->GetData(&done, sizeof(BOOL), 0),
- RParams.pContext->GetData(query, &done, sizeof(BOOL), 0))) && !done;
- }
- else
- {
- for (int j = 0; j < 50; j++)
- i = 0;
- }
- newTime = ovr_GetTimeInSeconds();
- }
-
- // How long we waited
- return newTime - initialTime;
+ RParams.pContext->Flush();
+ return WaitTillTime(absTime);
}
void DistortionRenderer::initBuffersAndShaders()
{
- for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ if ( RState.DistortionCaps & ovrDistortionCap_ComputeShader )
{
- // Allocate & generate distortion mesh vertices.
- ovrDistortionMesh meshData;
-
-// double startT = ovr_GetTimeInSeconds();
-
- if (!ovrHmd_CreateDistortionMesh( HMD,
- RState.EyeRenderDesc[eyeNum].Eye,
- RState.EyeRenderDesc[eyeNum].Fov,
- RState.DistortionCaps,
- &meshData) )
- {
- OVR_ASSERT(false);
- continue;
+ // Compute shader distortion grid.
+ // TODO - only do this if the CS is actually enabled?
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ // Compute shader setup of regular grid.
+ DistortionMeshVBs[eyeNum] = NULL;
+ DistortionMeshIBs[eyeNum] = NULL;
+
+ // These constants need to match those declared in the shader in DistortionCS*.csh
+ const int gridSizeInPixels = 16;
+ const int pinsPerEdge = 128;
+
+
+ // TODO: clean up this mess!
+ HMDState* hmds = (HMDState*)HMD->Handle;
+ ovrEyeType eyeType = RState.EyeRenderDesc[eyeNum].Eye;
+ ovrFovPort fov = RState.EyeRenderDesc[eyeNum].Fov;
+
+ const HmdRenderInfo& hmdri = hmds->RenderState.RenderInfo;
+ DistortionRenderDesc& distortion = hmds->RenderState.Distortion[eyeType];
+
+
+ // Find the mapping from TanAngle space to target NDC space.
+ ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(fov);
+
+ //const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight;
+ OVR_ASSERT ( gridSizeInPixels * (pinsPerEdge-1) > hmdri.ResolutionInPixels.w/2 );
+ OVR_ASSERT ( gridSizeInPixels * (pinsPerEdge-1) > hmdri.ResolutionInPixels.h );
+ DistortionComputePin Verts[pinsPerEdge*pinsPerEdge];
+ // Vertices are laid out in a vertical scanline pattern,
+ // scanning right to left, then within each scan going top to bottom, like DK2.
+ // If we move to a different panel orientation, we may need to flip this around.
+ int vertexNum = 0;
+ for ( int x = 0; x < pinsPerEdge; x++ )
+ {
+ for ( int y = 0; y < pinsPerEdge; y++ )
+ {
+ int pixX = x * gridSizeInPixels;
+ int pixY = y * gridSizeInPixels;
+ #if 0
+ // Simple version, ignoring pentile offsets
+ Vector2f screenPosNdc;
+ screenPosNdc.x = 2.0f * ( 0.5f - ( (float)pixX / (hmdri.ResolutionInPixels.w/2) ) ); // Note signs!
+ screenPosNdc.y = 2.0f * ( -0.5f + ( (float)pixY / hmdri.ResolutionInPixels.h ) ); // Note signs!
+
+ DistortionMeshVertexData vertex = DistortionMeshMakeVertex ( screenPosNdc,
+ ( eyeNum == 1 ),
+ hmdri,
+ distortion,
+ eyeToSourceNDC );
+ DistortionComputePin *pCurVert = &(Verts[vertexNum]);
+ pCurVert->TanEyeAnglesR = vertex.TanEyeAnglesR;
+ pCurVert->TanEyeAnglesG = vertex.TanEyeAnglesG;
+ pCurVert->TanEyeAnglesB = vertex.TanEyeAnglesB;
+ #else
+ // Pentile offsets are messy.
+ Vector2f screenPos[3]; // R=0, G=1, B=2
+ DistortionMeshVertexData vertexRGB[3];
+ screenPos[1] = Vector2f ( (float)pixX, (float)pixY );
+ screenPos[0] = screenPos[1];
+ screenPos[2] = screenPos[1];
+
+ if ( ( hmds->RenderState.EnabledHmdCaps & ovrHmdCap_DirectPentile ) != 0 )
+ {
+ // Doing direct display, so enable the pentile offsets.
+ screenPos[0] = screenPos[1] + hmdri.PelOffsetR;
+ screenPos[2] = screenPos[1] + hmdri.PelOffsetB;
+ }
+
+ for ( int i = 0; i < 3; i++ )
+ {
+ Vector2f screenPosNdc;
+ screenPosNdc.x = 2.0f * ( 0.5f - ( screenPos[i].x / (hmdri.ResolutionInPixels.w/2) ) ); // Note signs!
+ screenPosNdc.y = 2.0f * ( -0.5f + ( screenPos[i].y / hmdri.ResolutionInPixels.h ) ); // Note signs!
+ vertexRGB[i] = DistortionMeshMakeVertex ( screenPosNdc,
+ ( eyeNum == 1 ),
+ hmdri,
+ distortion,
+ eyeToSourceNDC );
+ }
+ // Most data (fade, TW interpolate, etc) comes from the green channel.
+ DistortionMeshVertexData vertex = vertexRGB[1];
+ DistortionComputePin *pCurVert = &(Verts[vertexNum]);
+ pCurVert->TanEyeAnglesR = vertexRGB[0].TanEyeAnglesR;
+ pCurVert->TanEyeAnglesG = vertexRGB[1].TanEyeAnglesG;
+ pCurVert->TanEyeAnglesB = vertexRGB[2].TanEyeAnglesB;
+ #endif
+
+ // vertex.Shade will go negative beyond the edges to produce correct intercept with the 0.0 plane.
+ // We want to preserve this, so bias and offset to fit [-1,+1] in a byte.
+ // The reverse wll be done in the shader.
+ float shade = Alg::Clamp ( vertex.Shade * 0.5f + 0.5f, 0.0f, 1.0f );
+ pCurVert->Col.R = (OVR::UByte)( floorf ( shade * 255.999f ) );
+ pCurVert->Col.G = pCurVert->Col.R;
+ pCurVert->Col.B = pCurVert->Col.R;
+ pCurVert->Col.A = (OVR::UByte)( floorf ( vertex.TimewarpLerp * 255.999f ) );
+
+ vertexNum++;
+ }
+ }
+ DistortionPinBuffer[eyeNum] = *new Buffer(&RParams);
+ DistortionPinBuffer[eyeNum]->Data ( Buffer_Compute, Verts, vertexNum * sizeof(Verts[0]), sizeof(Verts[0]) );
}
-// double deltaT = ovr_GetTimeInSeconds() - startT;
-// LogText("GenerateDistortion time = %f\n", deltaT);
-
- // Now parse the vertex data and create a render ready vertex buffer from it
- DistortionVertex * pVBVerts = (DistortionVertex*)OVR_ALLOC ( sizeof(DistortionVertex) * meshData.VertexCount );
- DistortionVertex * pCurVBVert = pVBVerts;
- ovrDistortionVertex* pCurOvrVert = meshData.pVertexData;
-
- for ( unsigned vertNum = 0; vertNum < meshData.VertexCount; vertNum++ )
+ }
+ else
+ {
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
{
- pCurVBVert->Pos.x = pCurOvrVert->Pos.x;
- pCurVBVert->Pos.y = pCurOvrVert->Pos.y;
- pCurVBVert->TexR = (*(Vector2f*)&pCurOvrVert->TexR);
- pCurVBVert->TexG = (*(Vector2f*)&pCurOvrVert->TexG);
- pCurVBVert->TexB = (*(Vector2f*)&pCurOvrVert->TexB);
- // Convert [0.0f,1.0f] to [0,255]
- pCurVBVert->Col.R = (OVR::UByte)( pCurOvrVert->VignetteFactor * 255.99f );
- pCurVBVert->Col.G = pCurVBVert->Col.R;
- pCurVBVert->Col.B = pCurVBVert->Col.R;
- pCurVBVert->Col.A = (OVR::UByte)( pCurOvrVert->TimeWarpFactor * 255.99f );;
- pCurOvrVert++;
- pCurVBVert++;
+ // Allocate & generate distortion mesh vertices.
+ DistortionPinBuffer[eyeNum] = NULL;
+
+ ovrDistortionMesh meshData;
+
+ // double startT = ovr_GetTimeInSeconds();
+
+ if (!ovrHmd_CreateDistortionMesh( HMD,
+ RState.EyeRenderDesc[eyeNum].Eye,
+ RState.EyeRenderDesc[eyeNum].Fov,
+ RState.DistortionCaps,
+ &meshData) )
+ {
+ OVR_ASSERT(false);
+ continue;
+ }
+
+ // double deltaT = ovr_GetTimeInSeconds() - startT;
+ // LogText("GenerateDistortion time = %f\n", deltaT);
+
+ // Now parse the vertex data and create a render ready vertex buffer from it
+ DistortionVertex * pVBVerts = (DistortionVertex*)OVR_ALLOC ( sizeof(DistortionVertex) * meshData.VertexCount );
+ DistortionVertex * pCurVBVert = pVBVerts;
+ ovrDistortionVertex* pCurOvrVert = meshData.pVertexData;
+
+ for ( unsigned vertNum = 0; vertNum < meshData.VertexCount; vertNum++ )
+ {
+ pCurVBVert->ScreenPosNDC.x = pCurOvrVert->ScreenPosNDC.x;
+ pCurVBVert->ScreenPosNDC.y = pCurOvrVert->ScreenPosNDC.y;
+ pCurVBVert->TanEyeAnglesR = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesR);
+ pCurVBVert->TanEyeAnglesG = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesG);
+ pCurVBVert->TanEyeAnglesB = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesB);
+
+ // Convert [0.0f,1.0f] to [0,255]
+ if (RState.DistortionCaps & ovrDistortionCap_Vignette)
+ pCurVBVert->Col.R = (uint8_t)( Alg::Max ( pCurOvrVert->VignetteFactor, 0.0f ) * 255.99f );
+ else
+ pCurVBVert->Col.R = 255;
+
+ pCurVBVert->Col.G = pCurVBVert->Col.R;
+ pCurVBVert->Col.B = pCurVBVert->Col.R;
+ pCurVBVert->Col.A = (uint8_t)( pCurOvrVert->TimeWarpFactor * 255.99f );
+ pCurOvrVert++;
+ pCurVBVert++;
+ }
+
+ DistortionMeshVBs[eyeNum] = *new Buffer(&RParams);
+ DistortionMeshVBs[eyeNum]->Data(Buffer_Vertex | Buffer_ReadOnly, pVBVerts, sizeof(DistortionVertex)* meshData.VertexCount);
+ DistortionMeshIBs[eyeNum] = *new Buffer(&RParams);
+ DistortionMeshIBs[eyeNum]->Data(Buffer_Index | Buffer_ReadOnly, meshData.pIndexData, (sizeof(INT16)* meshData.IndexCount));
+
+ OVR_FREE ( pVBVerts );
+ ovrHmd_DestroyDistortionMesh( &meshData );
}
-
- DistortionMeshVBs[eyeNum] = *new Buffer(&RParams);
- DistortionMeshVBs[eyeNum]->Data(Buffer_Vertex | Buffer_ReadOnly, pVBVerts, sizeof(DistortionVertex)* meshData.VertexCount);
- DistortionMeshIBs[eyeNum] = *new Buffer(&RParams);
- DistortionMeshIBs[eyeNum]->Data(Buffer_Index | Buffer_ReadOnly, meshData.pIndexData, (sizeof(INT16)* meshData.IndexCount));
-
- OVR_FREE ( pVBVerts );
- ovrHmd_DestroyDistortionMesh( &meshData );
}
+
// Uniform buffers
for(int i = 0; i < Shader_Count; i++)
{
@@ -417,43 +625,166 @@ void DistortionRenderer::initBuffersAndShaders()
void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* rightEyeTexture)
{
+
+#if (OVR_D3D_VERSION == 10)
+ RParams.pContext->GSSetShader(NULL);
+#else // d3d 11
+ RParams.pContext->HSSetShader(NULL, NULL, 0);
+ RParams.pContext->DSSetShader(NULL, NULL, 0);
+ RParams.pContext->GSSetShader(NULL, NULL, 0);
+#endif
+
RParams.pContext->RSSetState(Rasterizer);
- RParams.pContext->OMSetRenderTargets(1, &RParams.pBackBufferRT, 0);
-
- setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h));
-
+ bool overdriveActive = IsOverdriveActive();
+ int currOverdriveTextureIndex = -1;
+
+ if(overdriveActive)
+ {
+ currOverdriveTextureIndex = (LastUsedOverdriveTextureIndex + 1) % NumOverdriveTextures;
+ ID3D1xRenderTargetView* distortionRtv = pOverdriveTextures[currOverdriveTextureIndex]->TexRtv.GetRawRef();
+ ID3D1xRenderTargetView* mrtRtv[2] = {distortionRtv, RParams.pBackBufferRT};
+ RParams.pContext->OMSetRenderTargets(2, mrtRtv, 0);
+
+ RParams.pContext->ClearRenderTargetView(distortionRtv, RState.ClearColor);
+ }
+ else
+ {
+ RParams.pContext->OMSetRenderTargets(1, &RParams.pBackBufferRT, 0);
+ }
+
// Not affected by viewport.
RParams.pContext->ClearRenderTargetView(RParams.pBackBufferRT, RState.ClearColor);
+ setViewport(Recti(0,0, RParams.BackBufferSize.w, RParams.BackBufferSize.h));
+
+
for(int eyeNum = 0; eyeNum < 2; eyeNum++)
- {
+ {
ShaderFill distortionShaderFill(DistortionShader);
- distortionShaderFill.SetTexture(0, eyeNum == 0 ? leftEyeTexture : rightEyeTexture);
+ distortionShaderFill.SetTexture(0, eyeNum == 0 ? leftEyeTexture : rightEyeTexture, Shader_Pixel);
+
+ if(RState.DistortionCaps & ovrDistortionCap_HqDistortion)
+ {
+ static float aaDerivMult = 1.0f;
+ DistortionShader->SetUniform1f("AaDerivativeMult", aaDerivMult);
+ }
+ else
+ {
+ // 0.0 disables high quality anti-aliasing
+ DistortionShader->SetUniform1f("AaDerivativeMult", -1.0f);
+ }
+
+ if(overdriveActive)
+ {
+ distortionShaderFill.SetTexture(1, pOverdriveTextures[LastUsedOverdriveTextureIndex], Shader_Pixel);
+
+ float overdriveScaleRegularRise;
+ float overdriveScaleRegularFall;
+ GetOverdriveScales(overdriveScaleRegularRise, overdriveScaleRegularFall);
+ DistortionShader->SetUniform2f("OverdriveScales", overdriveScaleRegularRise, overdriveScaleRegularFall);
+ }
+ else
+ {
+ // -1.0f disables PLO
+ DistortionShader->SetUniform2f("OverdriveScales", -1.0f, -1.0f);
+ }
+
distortionShaderFill.SetInputLayout(DistortionVertexIL);
DistortionShader->SetUniform2f("EyeToSourceUVScale", UVScaleOffset[eyeNum][0].x, UVScaleOffset[eyeNum][0].y);
DistortionShader->SetUniform2f("EyeToSourceUVOffset", UVScaleOffset[eyeNum][1].x, UVScaleOffset[eyeNum][1].y);
- if (DistortionCaps & ovrDistortionCap_TimeWarp)
+
+ if (RState.DistortionCaps & ovrDistortionCap_TimeWarp)
{
- ovrMatrix4f timeWarpMatrices[2];
+ ovrMatrix4f timeWarpMatrices[2];
ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum,
RState.EyeRenderPoses[eyeNum], timeWarpMatrices);
- // Feed identity like matrices in until we get proper timewarp calculation going on
- DistortionShader->SetUniform4x4f("EyeRotationStart", Matrix4f(timeWarpMatrices[0]));
- DistortionShader->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1]));
-
- renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum],
- NULL, 0, (int)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles);
+ if (RState.DistortionCaps & ovrDistortionCap_ComputeShader)
+ {
+ DistortionShader->SetUniform3x3f("EyeRotationStart", Matrix4f(timeWarpMatrices[0]));
+ DistortionShader->SetUniform3x3f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1]));
+ }
+ else
+ {
+ // Can feed identity like matrices incase of concern over timewarp calculations
+ DistortionShader->SetUniform4x4f("EyeRotationStart", Matrix4f(timeWarpMatrices[0]));
+ DistortionShader->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1]));
+ }
}
+
+
+ if (RState.DistortionCaps & ovrDistortionCap_ComputeShader)
+ {
+#if (OVR_D3D_VERSION >= 11)
+ //RParams.pContext->CSCSSetShaderResources
+ //RParams.pContext->CSSetUnorderedAccessViews
+ //RParams.pContext->CSSetShader
+ //RParams.pContext->CSSetSamplers
+ //RParams.pContext->CSSetConstantBuffers
+
+
+ // These need to match the values used in the compiled shader
+ //const int gridSizeInPixels = 16; // GRID_SIZE_IN_PIXELS
+ //const int pinsPerEdge = 128; // PINS_PER_EDGE
+ const int nxnBlockSizeInPixels = 2; // NXN_BLOCK_SIZE_PIXELS
+ const int simdSquareSize = 16; // SIMD_SQUARE_SIZE
+
+ const int invocationSizeInPixels = nxnBlockSizeInPixels * simdSquareSize;
+
+ distortionShaderFill.SetTexture(0, eyeNum == 0 ? leftEyeTexture : rightEyeTexture, Shader_Compute);
+
+ DistortionShader->SetUniform1f("RightEye", (float)eyeNum);
+ DistortionShader->SetUniform1f("UseOverlay", 0.0f); // No overlay supported here.
+ DistortionShader->SetUniform1f("FbSizePixelsX", (float)RParams.BackBufferSize.w);
+
+ ShaderSet* shaders = distortionShaderFill.GetShaders();
+ ShaderBase* cshader = ((ShaderBase*)shaders->GetShader(Shader_Compute));
+
+ ID3D1xUnorderedAccessView *uavRendertarget = RParams.pBackBufferUAV;
+ int SizeX = RParams.BackBufferSize.w/2;
+ int SizeY = RParams.BackBufferSize.h;
+
+ int TileNumX = ( SizeX + (invocationSizeInPixels-1) ) / invocationSizeInPixels;
+ int TileNumY = ( SizeY + (invocationSizeInPixels-1) ) / invocationSizeInPixels;
+
+ RParams.pContext->CSSetUnorderedAccessViews ( 0, 1, &uavRendertarget, NULL );
+
+
+ // Incoming eye-buffer textures start at t0 onwards, so set this in slot #4
+ // Subtlety - can't put this in slot 0 because fill->Set stops at the first NULL texture.
+ ID3D1xShaderResourceView *d3dSrv = DistortionPinBuffer[eyeNum]->GetSrv();
+ RParams.pContext->CSSetShaderResources ( 4, 1, &d3dSrv );
+
+ // TODO: uniform/constant buffers
+ cshader->UpdateBuffer(UniformBuffers[Shader_Compute]);
+ cshader->SetUniformBuffer(UniformBuffers[Shader_Compute]);
+
+ // Primitive type is ignored for CS.
+ // This call actually sets the textures and does pContext->CSSetShader(). Primitive type is ignored.
+ distortionShaderFill.Set ( Prim_Unknown );
+
+ RParams.pContext->Dispatch ( TileNumX, TileNumY, 1 );
+#else
+ OVR_ASSERT ( !"No compute shaders on DX10" );
+#endif
+ }
else
{
renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum],
- NULL, 0, (int)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles);
+ NULL, 0, (int)DistortionMeshIBs[eyeNum]->GetSize()/2, Prim_Triangles);
}
}
+
+ LastUsedOverdriveTextureIndex = currOverdriveTextureIndex;
+
+ // Re-activate to only draw on back buffer
+ if(overdriveActive)
+ {
+ RParams.pContext->OMSetRenderTargets(1, &RParams.pBackBufferRT, 0);
+ }
}
void DistortionRenderer::createDrawQuad()
@@ -498,17 +829,20 @@ void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor
ShaderFill quadFill(SimpleQuadShader);
quadFill.SetInputLayout(SimpleQuadVertexIL);
- setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h));
+ setViewport(Recti(0,0, RParams.BackBufferSize.w, RParams.BackBufferSize.h));
+
+ float testerLuminance = (float)latencyTesterDrawColor[0] / 255.99f;
+ if(SrgbBackBuffer)
+ {
+ testerLuminance = pow(testerLuminance, 2.2f);
+ }
- SimpleQuadShader->SetUniform2f("Scale", 0.2f, 0.2f);
- SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterDrawColor[0] / 255.99f,
- (float)latencyTesterDrawColor[0] / 255.99f,
- (float)latencyTesterDrawColor[0] / 255.99f,
- 1.0f);
+ SimpleQuadShader->SetUniform2f("Scale", 0.3f, 0.3f);
+ SimpleQuadShader->SetUniform4f("Color", testerLuminance, testerLuminance, testerLuminance, 1.0f);
for(int eyeNum = 0; eyeNum < 2; eyeNum++)
{
- SimpleQuadShader->SetUniform2f("PositionOffset", eyeNum == 0 ? -0.4f : 0.4f, 0.0f);
+ SimpleQuadShader->SetUniform2f("PositionOffset", eyeNum == 0 ? -0.5f : 0.5f, 0.0f);
renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, NULL, 0, numQuadVerts, Prim_TriangleStrip);
}
}
@@ -521,20 +855,35 @@ void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelCol
{
createDrawQuad();
}
-
+
ShaderFill quadFill(SimpleQuadShader);
quadFill.SetInputLayout(SimpleQuadVertexIL);
- setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h));
+ setViewport(Recti(0,0, RParams.BackBufferSize.w, RParams.BackBufferSize.h));
+
+ Vector3f testerColor = Vector3f((float)latencyTesterPixelColor[0] / 255.99f,
+ (float)latencyTesterPixelColor[1] / 255.99f,
+ (float)latencyTesterPixelColor[2] / 255.99f);
+ if(SrgbBackBuffer)
+ {
+ // 2.2 gamma is close enough for our purposes of matching sRGB
+ testerColor.x = pow(testerColor.x, 2.2f);
+ testerColor.y = pow(testerColor.y, 2.2f);
+ testerColor.z = pow(testerColor.z, 2.2f);
+ }
- SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterPixelColor[0] / 255.99f,
- (float)latencyTesterPixelColor[0] / 255.99f,
- (float)latencyTesterPixelColor[0] / 255.99f,
- 1.0f);
+#ifdef OVR_BUILD_DEBUG
+ SimpleQuadShader->SetUniform4f("Color", testerColor.x, testerColor.y, testerColor.z, 1.0f);
- Vector2f scale(2.0f / RParams.RTSize.w, 2.0f / RParams.RTSize.h);
+ Vector2f scale(20.0f / RParams.BackBufferSize.w, 20.0f / RParams.BackBufferSize.h);
+#else
+ // sending in as gray scale
+ SimpleQuadShader->SetUniform4f("Color", testerColor.x, testerColor.x, testerColor.x, 1.0f);
+
+ Vector2f scale(1.0f / RParams.BackBufferSize.w, 1.0f / RParams.BackBufferSize.h);
+#endif
SimpleQuadShader->SetUniform2f("Scale", scale.x, scale.y);
- SimpleQuadShader->SetUniform2f("PositionOffset", 1.0f, 1.0f);
+ SimpleQuadShader->SetUniform2f("PositionOffset", 1.0f-scale.x, 1.0f-scale.y);
renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, NULL, 0, numQuadVerts, Prim_TriangleStrip);
}
@@ -628,7 +977,7 @@ void DistortionRenderer::setViewport(const Recti& vp)
-
+// Must match struct DistortionVertex
static D3D1X_(INPUT_ELEMENT_DESC) DistortionMeshVertexDesc[] =
{
{"Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D1X_(INPUT_PER_VERTEX_DATA), 0},
@@ -643,17 +992,43 @@ static D3D1X_(INPUT_ELEMENT_DESC) SimpleQuadMeshVertexDesc[] =
{"Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D1X_(INPUT_PER_VERTEX_DATA), 0},
};
+
+
// TODO: this is D3D specific
void DistortionRenderer::initShaders()
-{
+{
+#if OVR_D3D_VERSION>=11
+ if ( ( RState.DistortionCaps & ovrDistortionCap_ComputeShader ) != 0 )
{
- PrecompiledShader vsShaderByteCode = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & DistortionCaps];
+ // Compute shader
+ DistortionShader = *new ShaderSet;
+
+ int shaderNum = DistortionComputeShader2x2;
+ if ( ( RState.EnabledHmdCaps & ovrHmdCap_DirectPentile ) != 0 )
+ {
+ shaderNum = DistortionComputeShader2x2Pentile;
+ }
+
+ PrecompiledShader psShaderByteCode = DistortionComputeShaderLookup[shaderNum];
+ Ptr<D3D_NS::ComputeShader> cs = *new D3D_NS::ComputeShader(
+ &RParams,
+ (void*)psShaderByteCode.ShaderData, psShaderByteCode.ShaderSize,
+ psShaderByteCode.ReflectionData, psShaderByteCode.ReflectionSize);
+
+ DistortionShader->SetShader(cs);
+ }
+ else
+#endif
+ {
+ // Vertex + pixel distortion shader.
+ PrecompiledShader vsShaderByteCode = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & RState.DistortionCaps];
Ptr<D3D_NS::VertexShader> vtxShader = *new D3D_NS::VertexShader(
&RParams,
(void*)vsShaderByteCode.ShaderData, vsShaderByteCode.ShaderSize,
vsShaderByteCode.ReflectionData, vsShaderByteCode.ReflectionSize);
- ID3D1xInputLayout** objRef = &DistortionVertexIL.GetRawRef();
+ DistortionVertexIL = NULL;
+ ID3D1xInputLayout** objRef = &DistortionVertexIL.GetRawRef();
HRESULT validate = RParams.pDevice->CreateInputLayout(
DistortionMeshVertexDesc, sizeof(DistortionMeshVertexDesc) / sizeof(DistortionMeshVertexDesc[0]),
@@ -663,7 +1038,7 @@ void DistortionRenderer::initShaders()
DistortionShader = *new ShaderSet;
DistortionShader->SetShader(vtxShader);
- PrecompiledShader psShaderByteCode = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & DistortionCaps];
+ PrecompiledShader psShaderByteCode = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & RState.DistortionCaps];
Ptr<D3D_NS::PixelShader> ps = *new D3D_NS::PixelShader(
&RParams,
@@ -680,6 +1055,7 @@ void DistortionRenderer::initShaders()
SimpleQuad_vs_refl, sizeof(SimpleQuad_vs_refl) / sizeof(SimpleQuad_vs_refl[0]));
//NULL, 0);
+ SimpleQuadVertexIL = NULL;
ID3D1xInputLayout** objRef = &SimpleQuadVertexIL.GetRawRef();
HRESULT validate = RParams.pDevice->CreateInputLayout(
@@ -722,7 +1098,7 @@ ID3D1xSamplerState* DistortionRenderer::getSamplerState(int sm)
else if (sm & Sample_Anisotropic)
{
ss.Filter = D3D1X_(FILTER_ANISOTROPIC);
- ss.MaxAnisotropy = 8;
+ ss.MaxAnisotropy = 4;
}
else
{
@@ -740,6 +1116,7 @@ void DistortionRenderer::destroy()
{
DistortionMeshVBs[eyeNum].Clear();
DistortionMeshIBs[eyeNum].Clear();
+ DistortionPinBuffer[eyeNum].Clear();
}
DistortionVertexIL.Clear();
@@ -748,6 +1125,7 @@ void DistortionRenderer::destroy()
{
DistortionShader->UnsetShader(Shader_Vertex);
DistortionShader->UnsetShader(Shader_Pixel);
+ DistortionShader->UnsetShader(Shader_Compute);
DistortionShader.Clear();
}
@@ -757,48 +1135,280 @@ void DistortionRenderer::destroy()
DistortionRenderer::GraphicsState::GraphicsState(ID3D1xDeviceContext* c)
: context(c)
+, memoryCleared(TRUE)
, rasterizerState(NULL)
+//samplerStates[]
+, inputLayoutState(NULL)
+//psShaderResourceState[]
+//vsShaderResourceState[]
+//psConstantBuffersState[]
+//vsConstantBuffersState[]
+//renderTargetViewState[]
+, depthStencilViewState(NULL)
+, omBlendState(NULL)
+//omBlendFactorState[]
+, omSampleMaskState(0xffffffff)
+, primitiveTopologyState(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED)
+, iaIndexBufferPointerState(NULL)
+, iaIndexBufferFormatState(DXGI_FORMAT_UNKNOWN)
+, iaIndexBufferOffsetState(0)
+//iaVertexBufferPointersState[]
+//iaVertexBufferStridesState[]
+//iaVertexBufferOffsetsState[]
+, currentPixelShader(NULL)
+, currentVertexShader(NULL)
+, currentGeometryShader(NULL)
+#if (OVR_D3D_VERSION == 11)
+, currentHullShader(NULL)
+, currentDomainShader(NULL)
+, currentComputeShader(NULL)
+#endif
{
- for (int i = 0; i < 8; ++i)
- samplerStates[i] = NULL;
+ for (int i = 0; i < D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i)
+ {
+ psSamplerStates[i] = NULL;
+ vsSamplerStates[i] = NULL;
+#if (OVR_D3D_VERSION == 11)
+ csSamplerStates[i] = NULL;
+#endif
+ }
+
+ for (int i = 0; i < D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++)
+ {
+ psShaderResourceState[i] = NULL;
+ vsShaderResourceState[i] = NULL;
+#if (OVR_D3D_VERSION == 11)
+ csShaderResourceState[i] = NULL;
+#endif
+ }
+
+ for (int i = 0; i < D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++)
+ {
+ psConstantBuffersState[i] = NULL;
+ vsConstantBuffersState[i] = NULL;
+#if (OVR_D3D_VERSION == 11)
+ csConstantBuffersState[i] = NULL;
+#endif
+ }
+
+ for (int i = 0; i < D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
+ {
+ renderTargetViewState[i] = NULL;
+#if (OVR_D3D_VERSION == 11)
+ csUnorderedAccessViewState[i] = NULL;
+#endif
+ }
+
+ for (int i = 0; i < 4; i++)
+ omBlendFactorState[i] = NULL;
+
+ for (int i = 0; i < D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++)
+ {
+ iaVertexBufferPointersState[i] = NULL;
+ iaVertexBufferStridesState[i] = NULL;
+ iaVertexBufferOffsetsState[i] = NULL;
+ }
}
+#define SAFE_RELEASE(x) if ( (x) != NULL ) { (x)->Release(); (x)=NULL; }
-void DistortionRenderer::GraphicsState::Save()
+void DistortionRenderer::GraphicsState::clearMemory()
{
- if (rasterizerState != NULL)
- rasterizerState->Release();
+ SAFE_RELEASE ( rasterizerState );
- context->RSGetState(&rasterizerState);
+ for (int i = 0; i < D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i)
+ {
+ SAFE_RELEASE ( psSamplerStates[i] );
+ SAFE_RELEASE ( vsSamplerStates[i] );
+#if (OVR_D3D_VERSION == 11)
+ SAFE_RELEASE ( csSamplerStates[i] );
+#endif
+ }
+
+ SAFE_RELEASE ( inputLayoutState );
+
+ for (int i = 0; i < D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++)
+ {
+ SAFE_RELEASE ( psShaderResourceState[i] );
+ SAFE_RELEASE ( vsShaderResourceState[i] );
+#if (OVR_D3D_VERSION == 11)
+ SAFE_RELEASE ( csShaderResourceState[i] );
+#endif
+ }
+
+ for (int i = 0; i < D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++)
+ {
+ SAFE_RELEASE ( psConstantBuffersState[i] );
+ SAFE_RELEASE ( vsConstantBuffersState[i] );
+#if (OVR_D3D_VERSION == 11)
+ SAFE_RELEASE ( csConstantBuffersState[i] );
+#endif
+ }
- for (int i = 0; i < 8; ++i)
+ for (int i = 0; i < D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
{
- if (samplerStates[i] != NULL)
- samplerStates[i]->Release();
+ SAFE_RELEASE ( renderTargetViewState[i] );
+#if (OVR_D3D_VERSION == 11)
+ SAFE_RELEASE ( csUnorderedAccessViewState[i] );
+#endif
+ }
+
+ SAFE_RELEASE ( depthStencilViewState );
+ SAFE_RELEASE ( omBlendState );
+ SAFE_RELEASE ( iaIndexBufferPointerState );
+
+ for (int i = 0; i < D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++)
+ {
+ SAFE_RELEASE ( iaVertexBufferPointersState[i] );
}
- context->PSGetSamplers(0, 8, samplerStates);
+ SAFE_RELEASE ( currentPixelShader );
+ SAFE_RELEASE ( currentVertexShader );
+ SAFE_RELEASE ( currentGeometryShader );
+
+#if (OVR_D3D_VERSION == 11)
+ SAFE_RELEASE ( currentHullShader );
+ SAFE_RELEASE ( currentDomainShader );
+ SAFE_RELEASE ( currentComputeShader );
+#endif
+
+ memoryCleared = TRUE;
+}
+
+#undef SAFE_RELEASE
+
+DistortionRenderer::GraphicsState::~GraphicsState()
+{
+ clearMemory();
+}
+
+
+void DistortionRenderer::GraphicsState::Save()
+{
+ if (!memoryCleared)
+ clearMemory();
+
+ memoryCleared = FALSE;
+
+ context->RSGetState(&rasterizerState);
+ context->IAGetInputLayout(&inputLayoutState);
+
+ context->PSGetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, psShaderResourceState);
+ context->PSGetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, psSamplerStates);
+ context->PSGetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, psConstantBuffersState);
+
+ context->VSGetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, vsShaderResourceState);
+ context->VSGetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, vsSamplerStates);
+ context->VSGetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, vsConstantBuffersState);
+
+#if (OVR_D3D_VERSION == 11)
+ context->CSGetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, csShaderResourceState);
+ context->CSGetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, csSamplerStates);
+ context->CSGetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, csConstantBuffersState);
+ context->CSGetUnorderedAccessViews(0, D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT, csUnorderedAccessViewState);
+#endif
+
+ context->OMGetRenderTargets(D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT, renderTargetViewState, &depthStencilViewState);
+
+ context->OMGetBlendState(&omBlendState, omBlendFactorState, &omSampleMaskState);
+
+ context->IAGetPrimitiveTopology(&primitiveTopologyState);
+
+ context->IAGetIndexBuffer(&iaIndexBufferPointerState, &iaIndexBufferFormatState, &iaIndexBufferOffsetState);
+
+ context->IAGetVertexBuffers(0, D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, iaVertexBufferPointersState, iaVertexBufferStridesState, iaVertexBufferOffsetsState);
+
+#if (OVR_D3D_VERSION == 10)
+ context->PSGetShader(&currentPixelShader);
+ context->VSGetShader(&currentVertexShader);
+ context->GSGetShader(&currentGeometryShader);
+#else // Volga says class instance interfaces are very new and almost no one uses them
+ context->PSGetShader(&currentPixelShader, NULL, NULL);
+ context->VSGetShader(&currentVertexShader, NULL, NULL);
+ context->GSGetShader(&currentGeometryShader, NULL, NULL);
+ context->HSGetShader(&currentHullShader, NULL, NULL);
+ context->DSGetShader(&currentDomainShader, NULL, NULL);
+ context->CSGetShader(&currentComputeShader, NULL, NULL);
+ /* maybe above doesn't work; then do something with this (must test on dx11)
+ ID3D11ClassInstance* blank_array[0];
+ UINT blank_uint = 0;
+ context->PSGetShader(&currentPixelShader, blank_array, blank_uint);
+ context->VSGetShader(&currentVertexShader, blank_array, blank_uint);
+ context->GSGetShader(&currentGeometryShader, blank_array, blank_uint);
+ context->HSGetShader(&currentHullShader, blank_array, blank_uint);
+ context->DSGetShader(&currentDomainShader, blank_array, blank_uint);
+ context->CSGetShader(&currentComputeShader, blank_array, blank_uint);
+ */
+#endif
}
void DistortionRenderer::GraphicsState::Restore()
{
if (rasterizerState != NULL)
- {
context->RSSetState(rasterizerState);
- rasterizerState->Release();
- rasterizerState = NULL;
- }
- for (int i = 0; i < 8; ++i)
- {
- if (samplerStates[i] == NULL)
- continue;
+ if (inputLayoutState != NULL)
+ context->IASetInputLayout(inputLayoutState);
- context->PSSetSamplers(0, 1, &samplerStates[i]);
- samplerStates[i]->Release();
- samplerStates[i] = NULL;
- }
+ context->PSSetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, psSamplerStates);
+ if (psShaderResourceState != NULL)
+ context->PSSetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, psShaderResourceState);
+ if (psConstantBuffersState != NULL)
+ context->PSSetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, psConstantBuffersState);
+
+ context->VSSetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, vsSamplerStates);
+ if (vsShaderResourceState != NULL)
+ context->VSSetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, vsShaderResourceState);
+ if (vsConstantBuffersState != NULL)
+ context->VSSetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, vsConstantBuffersState);
+
+#if (OVR_D3D_VERSION == 11)
+ context->CSSetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, csSamplerStates);
+ if (csShaderResourceState != NULL)
+ context->CSSetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, csShaderResourceState);
+ if (csConstantBuffersState != NULL)
+ context->CSSetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, csConstantBuffersState);
+ if (csUnorderedAccessViewState != NULL)
+ context->CSSetUnorderedAccessViews(0, D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT, csUnorderedAccessViewState, NULL);
+#endif
+
+ if (depthStencilViewState != NULL || renderTargetViewState != NULL)
+ context->OMSetRenderTargets(D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT, renderTargetViewState, depthStencilViewState);
+
+ if (omBlendState != NULL)
+ context->OMSetBlendState(omBlendState, omBlendFactorState, omSampleMaskState);
+
+ context->IASetPrimitiveTopology(primitiveTopologyState);
+
+ if (iaIndexBufferPointerState != NULL)
+ context->IASetIndexBuffer(iaIndexBufferPointerState, iaIndexBufferFormatState, iaIndexBufferOffsetState);
+
+ if (iaVertexBufferPointersState != NULL)
+ context->IASetVertexBuffers(0, D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, iaVertexBufferPointersState, iaVertexBufferStridesState, iaVertexBufferOffsetsState);
+
+#if (OVR_D3D_VERSION == 10)
+ if (currentPixelShader != NULL)
+ context->PSSetShader(currentPixelShader);
+ if (currentVertexShader != NULL)
+ context->VSSetShader(currentVertexShader);
+ if (currentGeometryShader != NULL)
+ context->GSSetShader(currentGeometryShader);
+#else
+ if (currentPixelShader != NULL)
+ context->PSSetShader(currentPixelShader, NULL, 0);
+ if (currentVertexShader != NULL)
+ context->VSSetShader(currentVertexShader, NULL, 0);
+ if (currentGeometryShader != NULL)
+ context->GSSetShader(currentGeometryShader, NULL, 0);
+ if (currentHullShader != NULL)
+ context->HSSetShader(currentHullShader, NULL, 0);
+ if (currentDomainShader != NULL)
+ context->DSSetShader(currentDomainShader, NULL, 0);
+ if (currentComputeShader != NULL)
+ context->CSSetShader(currentComputeShader, NULL, 0);
+#endif
+ clearMemory();
}
}}} // OVR::CAPI::D3D1X