diff options
author | Brad Davis <[email protected]> | 2014-07-24 16:47:31 -0700 |
---|---|---|
committer | Brad Davis <[email protected]> | 2014-07-24 16:47:31 -0700 |
commit | 0f49ce8fc6aa54224e4c0d6fda8c4527ad39cce1 (patch) | |
tree | da07ebc6a7f75185bda857dd5f1c34710b416a93 /LibOVR/Src/CAPI/D3D1X | |
parent | ca79271759ff7eecd22ec5c4db438370fe51d687 (diff) |
0.4 Win-Beta0.4.0
Diffstat (limited to 'LibOVR/Src/CAPI/D3D1X')
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp | 35 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.h | 41 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp | 35 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h | 41 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp | 554 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h | 52 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp | 592 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.h | 84 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp | 1 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h | 7 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp | 113 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h | 11 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_HSWDisplay.cpp | 433 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_HSWDisplay.h | 82 | ||||
-rw-r--r-- | LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp | 26 |
15 files changed, 1934 insertions, 173 deletions
diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp new file mode 100644 index 0000000..4a66ba5 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp @@ -0,0 +1,35 @@ +/************************************************************************************ + +Filename : CAPI_D3D10_HSWDisplay.cpp +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.1 (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 + +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, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#define OVR_D3D_VERSION 10 +#include "CAPI_D3D1X_HSWDisplay.cpp" +#undef OVR_D3D_VERSION + + + + + + diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.h new file mode 100644 index 0000000..2d78b8c --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.h @@ -0,0 +1,41 @@ +/************************************************************************************ + +Filename : CAPI_D3D10_HSWDisplay.h +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.1 (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 + +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, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CAPI_D3D10_HSWDisplay_h +#define OVR_CAPI_D3D10_HSWDisplay_h + +#if !defined(OVR_D3D_VERSION) || ((OVR_D3D_VERSION != 10) && (OVR_D3D_VERSION != 11)) + #error This header expects OVR_D3D_VERSION to be defined, to 10 or 11. +#endif + +// Due to the similarities between DX10 and DX11, there is a shared implementation of the headers and source +// which is differentiated only by the OVR_D3D_VERSION define. This define causes D3D_NS (D3D namespace) to +// be defined to either D3D10 or D3D11, as well as other similar effects. +#include "CAPI_D3D1X_HSWDisplay.h" + + +#endif // OVR_CAPI_D3D10_HSWDisplay_h + diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp new file mode 100644 index 0000000..02e5c01 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp @@ -0,0 +1,35 @@ +/************************************************************************************ + +Filename : CAPI_D3D11_HSWDisplay.cpp +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.1 (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 + +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, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#define OVR_D3D_VERSION 11 +#include "CAPI_D3D1X_HSWDisplay.cpp" +#undef OVR_D3D_VERSION + + + + + + diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h new file mode 100644 index 0000000..b5739fb --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h @@ -0,0 +1,41 @@ +/************************************************************************************ + +Filename : CAPI_D3D11_HSWDisplay.h +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.1 (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 + +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, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CAPI_D3D11_HSWDisplay_h +#define OVR_CAPI_D3D11_HSWDisplay_h + +#if !defined(OVR_D3D_VERSION) || ((OVR_D3D_VERSION != 10) && (OVR_D3D_VERSION != 11)) + #error This header expects OVR_D3D_VERSION to be defined, to 10 or 11. +#endif + +// Due to the similarities between DX10 and DX11, there is a shared implementation of the headers and source +// which is differentiated only by the OVR_D3D_VERSION define. This define causes D3D_NS (D3D namespace) to +// be defined to either D3D10 or D3D11, as well as other similar effects. +#include "CAPI_D3D1X_HSWDisplay.h" + + +#endif // OVR_CAPI_D3D11_HSWDisplay_h + diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp index 878d777..18ad298 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp @@ -3,7 +3,7 @@ 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. @@ -27,6 +27,7 @@ limitations under the License. #include "CAPI_D3D1X_DistortionRenderer.h" #include "../../OVR_CAPI_D3D.h" +#include "../../Kernel/OVR_Color.h" namespace OVR { namespace CAPI { namespace D3D_NS { @@ -83,7 +84,7 @@ static PrecompiledShader DistortionVertexShaderLookup[DistortionVertexShaderCoun static PrecompiledShader DistortionPixelShaderLookup[DistortionPixelShaderCount] = { PCS_NOREFL(Distortion_ps), - PCS_NOREFL(DistortionChroma_ps) + PCS_REFL__(DistortionChroma_ps) }; void DistortionShaderBitIndexCheck() @@ -96,10 +97,10 @@ void DistortionShaderBitIndexCheck() struct DistortionVertex { - Vector2f Pos; - Vector2f TexR; - Vector2f TexG; - Vector2f TexB; + Vector2f ScreenPosNDC; + Vector2f TanEyeAnglesR; + Vector2f TanEyeAnglesG; + Vector2f TanEyeAnglesB; Color Col; }; @@ -171,7 +172,7 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, if (!config->D3D_NS.pDevice || !config->D3D_NS.pBackBufferRT) return false; - + 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; @@ -199,8 +200,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 +215,50 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, return true; } +void DistortionRenderer::initOverdrive() +{ + if(RState.DistortionCaps & ovrDistortionCap_Overdrive) + { + LastUsedOverdriveTextureIndex = 0; -void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture) + for (int i = 0; i < NumOverdriveTextures; i++) + { + pOverdriveTextures[i] = *new Texture(&RParams, Texture_RGBA, RParams.RTSize, + getSamplerState(Sample_Linear|Sample_ClampBorder)); + + D3D1X_(TEXTURE2D_DESC) dsDesc; + dsDesc.Width = RParams.RTSize.w; + dsDesc.Height = RParams.RTSize.h; + dsDesc.MipLevels = 1; + dsDesc.ArraySize = 1; + dsDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + 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, const ovrTexture* eyeTexture) { const ovrD3D1X(Texture)* tex = (const ovrD3D1X(Texture)*)eyeTexture; @@ -229,44 +275,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); - renderDistortion(pEyeTextures[0], pEyeTextures[1]); + renderEndFrame(); + } + else + { + // If needed, measure distortion time so that TimeManager can better estimate + // latency-reducing time-warp wait timing. + WaitUntilGpuIdle(); + double distortionStartTime = ovr_GetTimeInSeconds(); - WaitUntilGpuIdle(); - TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); - } + renderEndFrame(); - if(latencyTesterDrawColor) + WaitUntilGpuIdle(); + TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); + } + } + else { - renderLatencyQuad(latencyTesterDrawColor); + renderEndFrame(); } - else if(latencyTester2DrawColor) + + if(LatencyTestActive) { - renderLatencyPixel(latencyTester2DrawColor); + renderLatencyQuad(LatencyTestDrawColor); } if (swapBuffers) @@ -278,7 +344,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,45 +383,8 @@ 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() @@ -382,16 +416,21 @@ void DistortionRenderer::initBuffersAndShaders() for ( unsigned vertNum = 0; vertNum < meshData.VertexCount; vertNum++ ) { - 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); + 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] - pCurVBVert->Col.R = (OVR::UByte)( pCurOvrVert->VignetteFactor * 255.99f ); + if (DistortionCaps & ovrDistortionCap_Vignette) + pCurVBVert->Col.R = (uint8_t)( pCurOvrVert->VignetteFactor * 255.99f ); + else + pCurVBVert->Col.R = 255; + pCurVBVert->Col.G = pCurVBVert->Col.R; pCurVBVert->Col.B = pCurVBVert->Col.R; - pCurVBVert->Col.A = (OVR::UByte)( pCurOvrVert->TimeWarpFactor * 255.99f );; + pCurVBVert->Col.A = (uint8_t)( pCurOvrVert->TimeWarpFactor * 255.99f );; pCurOvrVert++; pCurVBVert++; } @@ -417,19 +456,63 @@ 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.RTSize.w, RParams.RTSize.h)); + + for(int eyeNum = 0; eyeNum < 2; eyeNum++) { ShaderFill distortionShaderFill(DistortionShader); distortionShaderFill.SetTexture(0, eyeNum == 0 ? leftEyeTexture : rightEyeTexture); + + if(overdriveActive) + { + distortionShaderFill.SetTexture(1, pOverdriveTextures[LastUsedOverdriveTextureIndex]); + + float invRtWidth = 1.0f / (float)RParams.RTSize.w; + float invRtHeight = 1.0f / (float)RParams.RTSize.h; + DistortionShader->SetUniform2f("OverdriveInvRTSize", invRtWidth, invRtHeight); + + static float overdriveScaleRegularRise = 0.1f; + static float overdriveScaleRegularFall = 0.05f; // falling issues are hardly visible + DistortionShader->SetUniform2f("OverdriveScales", overdriveScaleRegularRise, overdriveScaleRegularFall); + } + else + { + // -1.0f disables PLO + DistortionShader->SetUniform2f("OverdriveInvRTSize", -1.0f, -1.0f); + } + distortionShaderFill.SetInputLayout(DistortionVertexIL); DistortionShader->SetUniform2f("EyeToSourceUVScale", UVScaleOffset[eyeNum][0].x, UVScaleOffset[eyeNum][0].y); @@ -437,7 +520,7 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ if (DistortionCaps & ovrDistortionCap_TimeWarp) { - ovrMatrix4f timeWarpMatrices[2]; + ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, RState.EyeRenderPoses[eyeNum], timeWarpMatrices); @@ -446,14 +529,22 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ DistortionShader->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1])); renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum], - NULL, 0, (int)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles); + NULL, 0, (int)DistortionMeshIBs[eyeNum]->GetSize()/2, Prim_Triangles); } 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() @@ -500,7 +591,7 @@ void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h)); - SimpleQuadShader->SetUniform2f("Scale", 0.2f, 0.2f); + SimpleQuadShader->SetUniform2f("Scale", 0.3f, 0.3f); SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterDrawColor[0] / 255.99f, (float)latencyTesterDrawColor[0] / 255.99f, (float)latencyTesterDrawColor[0] / 255.99f, @@ -508,7 +599,7 @@ void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor 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 +612,29 @@ void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelCol { createDrawQuad(); } - + ShaderFill quadFill(SimpleQuadShader); quadFill.SetInputLayout(SimpleQuadVertexIL); setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h)); +#ifdef OVR_BUILD_DEBUG + SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterPixelColor[0] / 255.99f, + (float)latencyTesterPixelColor[1] / 255.99f, + (float)latencyTesterPixelColor[2] / 255.99f, + 1.0f); + + Vector2f scale(20.0f / RParams.RTSize.w, 20.0f / RParams.RTSize.h); +#else SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterPixelColor[0] / 255.99f, (float)latencyTesterPixelColor[0] / 255.99f, (float)latencyTesterPixelColor[0] / 255.99f, 1.0f); - Vector2f scale(2.0f / RParams.RTSize.w, 2.0f / RParams.RTSize.h); + Vector2f scale(1.0f / RParams.RTSize.w, 1.0f / RParams.RTSize.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); } @@ -653,7 +753,8 @@ void DistortionRenderer::initShaders() (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]), @@ -680,6 +781,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( @@ -758,47 +860,279 @@ void DistortionRenderer::destroy() DistortionRenderer::GraphicsState::GraphicsState(ID3D1xDeviceContext* c) : context(c) , rasterizerState(NULL) +, inputLayoutState(NULL) +, depthStencilViewState(NULL) +, omBlendState(NULL) +, omSampleMaskState(0xffffffff) +, iaIndexBufferPointerState(NULL) +, memoryCleared(TRUE) +, currentPixelShader(NULL) +, currentVertexShader(NULL) +, currentGeometryShader(NULL) +#if (OVR_D3D_VERSION == 11) +, currentHullShader(NULL) +, currentDomainShader(NULL) +#endif { - for (int i = 0; i < 8; ++i) + for (int i = 0; i < D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) samplerStates[i] = NULL; -} - - -void DistortionRenderer::GraphicsState::Save() -{ - if (rasterizerState != NULL) - rasterizerState->Release(); - context->RSGetState(&rasterizerState); + for (int i = 0; i < D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) + { + psShaderResourceState[i] = NULL; + vsShaderResourceState[i] = NULL; + } - for (int i = 0; i < 8; ++i) + for (int i = 0; i < D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) { - if (samplerStates[i] != NULL) - samplerStates[i]->Release(); + psConstantBuffersState[i] = NULL; + vsConstantBuffersState[i] = NULL; } - context->PSGetSamplers(0, 8, samplerStates); -} + for (int i = 0; i < D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + renderTargetViewState[i] = NULL; + for (int i = 0; i < 4; i++) + omBlendFactorState[i] = NULL; -void DistortionRenderer::GraphicsState::Restore() + for (int i = 0; i < D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) + iaVertexBufferPointersState[i] = NULL; +} + +void DistortionRenderer::GraphicsState::clearMemory() { if (rasterizerState != NULL) { - context->RSSetState(rasterizerState); rasterizerState->Release(); rasterizerState = NULL; } - for (int i = 0; i < 8; ++i) + for (int i = 0; i < D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) { if (samplerStates[i] == NULL) continue; - - context->PSSetSamplers(0, 1, &samplerStates[i]); samplerStates[i]->Release(); samplerStates[i] = NULL; } + + if (inputLayoutState != NULL) + { + inputLayoutState->Release(); + inputLayoutState = NULL; + } + + for (int i = 0; i < D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) + { + if (psShaderResourceState[i] != NULL) + { + psShaderResourceState[i]->Release(); + psShaderResourceState[i] = NULL; + } + if (vsShaderResourceState[i] != NULL) + { + vsShaderResourceState[i]->Release(); + vsShaderResourceState[i] = NULL; + } + } + + for (int i = 0; i < D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + { + if (psConstantBuffersState[i] != NULL) + { + psConstantBuffersState[i]->Release(); + psConstantBuffersState[i] = NULL; + } + if (vsConstantBuffersState[i] != NULL) + { + vsConstantBuffersState[i]->Release(); + vsConstantBuffersState[i] = NULL; + } + } + + for (int i = 0; i < D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + if (renderTargetViewState[i] != NULL) + { + renderTargetViewState[i]->Release(); + renderTargetViewState[i] = NULL; + } + } + + if (depthStencilViewState != NULL) + { + depthStencilViewState->Release(); + depthStencilViewState = NULL; + } + + if (omBlendState != NULL) + { + omBlendState->Release(); + omBlendState = NULL; + } + + if (iaIndexBufferPointerState != NULL) + { + iaIndexBufferPointerState->Release(); + iaIndexBufferPointerState = NULL; + } + + for (int i = 0; i < D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) + { + if (iaVertexBufferPointersState[i] == NULL) + continue; + iaVertexBufferPointersState[i]->Release(); + iaVertexBufferPointersState[i] = NULL; + } + + if (currentPixelShader != NULL) + { + currentPixelShader->Release(); + currentPixelShader = NULL; + } + + if (currentVertexShader != NULL) + { + currentVertexShader->Release(); + currentVertexShader = NULL; + } + + if (currentGeometryShader != NULL) + { + currentGeometryShader->Release(); + currentGeometryShader = NULL; + } + +#if (OVR_D3D_VERSION == 11) + + if (currentHullShader != NULL) + { + currentHullShader->Release(); + currentHullShader = NULL; + } + + if (currentDomainShader != NULL) + { + currentDomainShader->Release(); + currentDomainShader = NULL; + } + +#endif + + memoryCleared = TRUE; +} + +DistortionRenderer::GraphicsState::~GraphicsState() +{ + clearMemory(); +} + + +void DistortionRenderer::GraphicsState::Save() +{ + if (!memoryCleared) + clearMemory(); + + memoryCleared = FALSE; + + context->RSGetState(&rasterizerState); + context->PSGetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, samplerStates); + context->IAGetInputLayout(&inputLayoutState); + + context->PSGetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, psShaderResourceState); + context->VSGetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, vsShaderResourceState); + + context->PSGetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, psConstantBuffersState); + context->VSGetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, vsConstantBuffersState); + + 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(¤tPixelShader); + context->VSGetShader(¤tVertexShader); + context->GSGetShader(¤tGeometryShader); +#else // Volga says class instance interfaces are very new and almost no one uses them + context->PSGetShader(¤tPixelShader, NULL, NULL); + context->VSGetShader(¤tVertexShader, NULL, NULL); + context->GSGetShader(¤tGeometryShader, NULL, NULL); + context->HSGetShader(¤tHullShader, NULL, NULL); + context->DSGetShader(¤tDomainShader, 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(¤tPixelShader, blank_array, blank_uint); + context->VSGetShader(¤tVertexShader, blank_array, blank_uint); + context->GSGetShader(¤tGeometryShader, blank_array, blank_uint); + context->HSGetShader(¤tHullShader, blank_array, blank_uint); + context->DSGetShader(¤tDomainShader, blank_array, blank_uint); + */ +#endif +} + + +void DistortionRenderer::GraphicsState::Restore() +{ + if (rasterizerState != NULL) + context->RSSetState(rasterizerState); + + context->PSSetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, samplerStates); + + if (inputLayoutState != NULL) + context->IASetInputLayout(inputLayoutState); + + if (psShaderResourceState != NULL) + context->PSSetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, psShaderResourceState); + + if (vsShaderResourceState != NULL) + context->VSSetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, vsShaderResourceState); + + if (psConstantBuffersState != NULL) + context->PSSetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, psConstantBuffersState); + + if (vsConstantBuffersState != NULL) + context->VSSetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, vsConstantBuffersState); + + 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); +#endif + clearMemory(); } }}} // OVR::CAPI::D3D1X diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h index c4d2619..8543b4a 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h @@ -59,9 +59,9 @@ public: virtual bool Initialize(const ovrRenderAPIConfig* apiConfig, unsigned distortionCaps); - virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture); + virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture); - virtual void EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor); + virtual void EndFrame(bool swapBuffers); // TBD: Make public? void WaitUntilGpuIdle(); @@ -76,13 +76,50 @@ protected: { public: GraphicsState(ID3D1xDeviceContext* context); + virtual ~GraphicsState(); + virtual void clearMemory(); virtual void Save(); virtual void Restore(); protected: - ID3D1xRasterizerState* rasterizerState; - ID3D1xSamplerState* samplerStates[8]; ID3D1xDeviceContext* context; + BOOL memoryCleared; + + ID3D1xRasterizerState* rasterizerState; + ID3D1xSamplerState* samplerStates[D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT]; + ID3D1xInputLayout* inputLayoutState; + + ID3D1xShaderResourceView* psShaderResourceState[D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D1xShaderResourceView* vsShaderResourceState[D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + + ID3D1xBuffer* psConstantBuffersState[D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D1xBuffer* vsConstantBuffersState[D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + + ID3D1xRenderTargetView* renderTargetViewState[D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT]; + ID3D1xDepthStencilView* depthStencilViewState; + + ID3D1xBlendState* omBlendState; + FLOAT omBlendFactorState[4]; + UINT omSampleMaskState; + + D3D1x_PRIMITIVE_TOPOLOGY primitiveTopologyState; + + ID3D1xBuffer* iaIndexBufferPointerState; + DXGI_FORMAT iaIndexBufferFormatState; + UINT iaIndexBufferOffsetState; + + ID3D1xBuffer* iaVertexBufferPointersState[D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + UINT iaVertexBufferStridesState[D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + UINT iaVertexBufferOffsetsState[D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + + ID3D1xPixelShader* currentPixelShader; + ID3D1xVertexShader* currentVertexShader; + ID3D1xGeometryShader* currentGeometryShader; +#if (OVR_D3D_VERSION == 11) + ID3D11HullShader* currentHullShader; + ID3D11DomainShader* currentDomainShader; +#endif + }; private: @@ -90,6 +127,7 @@ private: void initBuffersAndShaders(); void initShaders(); void initFullscreenQuad(); + void initOverdrive(); void destroy(); void setViewport(const Recti& vp); @@ -100,6 +138,8 @@ private: Matrix4f* viewMatrix, int offset, int count, PrimitiveType rprim); + void renderEndFrame(); + void createDrawQuad(); void renderLatencyQuad(unsigned char* latencyTesterDrawColor); void renderLatencyPixel(unsigned char* latencyTesterPixelColor); @@ -114,12 +154,14 @@ private: // D3DX device and utility variables. RenderParams RParams; Ptr<Texture> pEyeTextures[2]; - + // U,V scale and offset needed for timewarp. ovrVector2f UVScaleOffset[2][2]; ovrSizei EyeTextureSize[2]; ovrRecti EyeRenderViewport[2]; + Ptr<Texture> pOverdriveTextures[NumOverdriveTextures]; + //Ptr<Buffer> mpFullScreenVertexBuffer; Ptr<Buffer> DistortionMeshVBs[2]; // one per-eye diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp new file mode 100644 index 0000000..1e4b11a --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp @@ -0,0 +1,592 @@ +/************************************************************************************ + +Filename : CAPI_D3D1X_HSWDisplay.cpp +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.1 (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 + +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, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +// This file is intended to be #included by CAPI_D3D10_HSWDisplay.cpp or CAPI_D3D11_HSWDisplay.cpp, +// which define OVR_D3D_VERSION to 10 or 11 respectively. +#if defined(OVR_D3D_VERSION) && ((OVR_D3D_VERSION == 10) || (OVR_D3D_VERSION == 11)) + +#define _WINSOCKAPI_ // Prevents <Windows.h> from #including <Winsock.h>, as we need the app to use <Winsock2.h> instead. +#include "../../OVR_CAPI_D3D.h" // OVR_D3D_VERSION will have been defined by who included us. +#include "CAPI_D3D1X_HSWDisplay.h" +#include "../../Kernel/OVR_File.h" +#include "../../Kernel/OVR_SysFile.h" +#include "../../Kernel/OVR_Math.h" +#include "../../Kernel/OVR_Allocator.h" +#include "../../Kernel/OVR_Color.h" + + +#include "../Textures/healthAndSafety.tga.h" + +// We currently borrow the SimpleQuad shaders +#include "../Shaders/SimpleTexturedQuad_vs.h" +#include "../Shaders/SimpleTexturedQuad_vs_refl.h" +#include "../Shaders/SimpleTexturedQuad_ps.h" +#include "../Shaders/SimpleTexturedQuad_ps_refl.h" + + +/* +#include <d3dcompiler.h> + +ID3D10Blob* CompileShader(const char* profile, const char* src, const char* mainName = "main") +{ + ID3D10Blob* shader = NULL; + ID3D10Blob* errors = NULL; + HRESULT hr = D3DCompile(src, strlen(src), NULL, NULL, NULL, mainName, profile, 0, 0, &shader, &errors); + + OVR_ASSERT(SUCCEEDED(hr)); + if (FAILED(hr)) + { + shader = NULL; + OVR_DEBUG_LOG(("Compiling D3D shader for %s failed\n%s\n\n%s", profile, src, errors->GetBufferPointer())); + } + + if (errors) + errors->Release(); + + return shader; +} +*/ + + + +// For a given DXGI format: if the format is a typeless one then this function returns a +// suitable typed one. If the format is a typed one then this function returns it as-is. +static DXGI_FORMAT GetFullyTypedDXGIFormat(DXGI_FORMAT textureFormat) +{ + // http://msdn.microsoft.com/en-us/library/windows/desktop/bb173059%28v=vs.85%29.aspx + + DXGI_FORMAT fullyTypedFormat = textureFormat; + + switch(textureFormat) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + return DXGI_FORMAT_R32G32B32A32_FLOAT; // or DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_SINT + + case DXGI_FORMAT_R32G32B32_TYPELESS: + return DXGI_FORMAT_R32G32B32_FLOAT; // or DXGI_FORMAT_R32G32B32_UINT, DXGI_FORMAT_R32G32B32_SINT + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + return DXGI_FORMAT_R16G16B16A16_UNORM; // or DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_SINT + + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + return DXGI_FORMAT_R8G8B8A8_UNORM; // or DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SINT + + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + + // Others which we don't currently support: + //case DXGI_FORMAT_R32G32_TYPELESS: + //case DXGI_FORMAT_R32G8X24_TYPELESS: + //case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + //case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + //case DXGI_FORMAT_R10G10B10A2_TYPELESS: + //case DXGI_FORMAT_R16G16_TYPELESS: + //case DXGI_FORMAT_R32_TYPELESS: + //case DXGI_FORMAT_R24G8_TYPELESS: + //case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + //case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + //case DXGI_FORMAT_R8G8_TYPELESS: + //case DXGI_FORMAT_R16_TYPELESS: + //case DXGI_FORMAT_R8_TYPELESS: + //case DXGI_FORMAT_BC1_TYPELESS: + //case DXGI_FORMAT_BC2_TYPELESS: + //case DXGI_FORMAT_BC3_TYPELESS: + //case DXGI_FORMAT_BC4_TYPELESS: + //case DXGI_FORMAT_BC5_TYPELESS: + //case DXGI_FORMAT_BC6H_TYPELESS: + //case DXGI_FORMAT_BC7_TYPELESS: + } + + return fullyTypedFormat; +} + + + +namespace OVR { namespace CAPI { + +// To do Need to move LoadTextureTgaData to a shared location. +uint8_t* LoadTextureTgaData(OVR::File* f, uint8_t alpha, int& width, int& height); + + +namespace D3D_NS { + +// This is a temporary function implementation, and it functionality needs to be implemented in a more generic way. +Texture* LoadTextureTga(RenderParams& rParams, ID3D1xSamplerState* pSamplerState, OVR::File* f, uint8_t alpha) +{ + OVR::CAPI::D3D_NS::Texture* pTexture = NULL; + + int width, height; + const uint8_t* pRGBA = LoadTextureTgaData(f, alpha, width, height); + + if (pRGBA) + { + pTexture = new OVR::CAPI::D3D_NS::Texture(&rParams, OVR::CAPI::D3D_NS::Texture_RGBA, OVR::Sizei(0,0), pSamplerState, 1); + + // Create the D3D texture + D3D1X_(TEXTURE2D_DESC) dsDesc; + dsDesc.Width = width; + dsDesc.Height = height; + dsDesc.MipLevels = 1; + dsDesc.ArraySize = 1; + dsDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + dsDesc.SampleDesc.Count = 1; + dsDesc.SampleDesc.Quality = 0; + dsDesc.Usage = D3D1X_(USAGE_DEFAULT); + dsDesc.BindFlags = D3D1X_(BIND_SHADER_RESOURCE); + dsDesc.CPUAccessFlags = 0; + dsDesc.MiscFlags = 0; + + HRESULT hr = rParams.pDevice->CreateTexture2D(&dsDesc, NULL, &pTexture->Tex.GetRawRef()); + + if (SUCCEEDED(hr)) + { + if (dsDesc.BindFlags & D3D1X_(BIND_SHADER_RESOURCE)) + rParams.pDevice->CreateShaderResourceView(pTexture->Tex, NULL, &pTexture->TexSv.GetRawRef()); + + rParams.pContext->UpdateSubresource(pTexture->Tex, 0, NULL, pRGBA, width * 4, width * height * 4); + } + else + { + OVR_DEBUG_LOG_TEXT(("[LoadTextureTga] CreateTexture2D failed")); + pTexture->Release(); + } + + OVR_FREE(const_cast<uint8_t*>(pRGBA)); + } + + return pTexture; +} + + +// Loads a texture from a memory image of a TGA file. +Texture* LoadTextureTga(RenderParams& rParams, ID3D1xSamplerState* pSamplerState, const uint8_t* pData, int dataSize, uint8_t alpha) +{ + MemoryFile memoryFile("", pData, dataSize); + + return LoadTextureTga(rParams, pSamplerState, &memoryFile, alpha); +} + + +// Loads a texture from a disk TGA file. +Texture* LoadTextureTga(RenderParams& rParams, ID3D1xSamplerState* pSamplerState, const char* pFilePath, uint8_t alpha) +{ + SysFile sysFile; + + if(sysFile.Open(pFilePath, FileConstants::Open_Read | FileConstants::Open_Buffered)) + return LoadTextureTga(rParams, pSamplerState, &sysFile, alpha); + + return NULL; +} + + + +// To do: This needs to be promoted to a central version, possibly in CAPI_HSWDisplay.h +struct HASWVertex +{ + Vector3f Pos; + Color C; + float U, V; + + HASWVertex(const Vector3f& p, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) + : Pos(p), C(c), U(u), V(v) + {} + + HASWVertex(float x, float y, float z, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) + : Pos(x,y,z), C(c), U(u), V(v) + {} + + bool operator==(const HASWVertex& b) const + { + return (Pos == b.Pos) && (C == b.C) && (U == b.U) && (V == b.V); + } +}; + + + +// The texture below may conceivably be shared between HSWDisplay instances. However, +// beware that sharing may not be possible if two HMDs are using different locales +// simultaneously. As of this writing it's not clear if that can occur in practice. + +HSWDisplay::HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState) + : OVR::CAPI::HSWDisplay(api, hmd, renderState), + RenderParams() +{ +} + +bool HSWDisplay::Initialize(const ovrRenderAPIConfig* apiConfig) +{ + #if (OVR_D3D_VERSION == 10) + const ovrD3D10Config* config = reinterpret_cast<const ovrD3D10Config*>(apiConfig); + #else + const ovrD3D11Config* config = reinterpret_cast<const ovrD3D11Config*>(apiConfig); + #endif + + if(config) + { + RenderParams.pDevice = config->D3D_NS.pDevice; + #if (OVR_D3D_VERSION == 10) + RenderParams.pContext = config->D3D10.pDevice; + #else + RenderParams.pContext = config->D3D11.pDeviceContext; + #endif + RenderParams.pBackBufferRT = config->D3D_NS.pBackBufferRT; + RenderParams.pSwapChain = config->D3D_NS.pSwapChain; + RenderParams.RTSize = config->D3D_NS.Header.RTSize; + RenderParams.Multisample = config->D3D_NS.Header.Multisample; + + // We may want to create RasterizerState, or alternatively let the DistortionRenderer handle it. + } + // else do any necessary cleanup + + return true; +} + +void HSWDisplay::Shutdown() +{ + UnloadGraphics(); +} + + +void HSWDisplay::DisplayInternal() +{ + HSWDISPLAY_LOG(("[HSWDisplay D3D1x] DisplayInternal()")); + // We may want to call LoadGraphics here instead of within Render. +} + + +void HSWDisplay::DismissInternal() +{ + HSWDISPLAY_LOG(("[HSWDisplay D3D1x] DismissInternal()")); + UnloadGraphics(); +} + + +void HSWDisplay::UnloadGraphics() +{ + //RenderParams: nothing to do. + pSamplerState.Clear(); + pTexture.Clear(); + pVB.Clear(); + for(size_t i = 0; i < OVR_ARRAY_COUNT(UniformBufferArray); i++) + UniformBufferArray[i].Clear(); + pShaderSet.Clear(); + pVertexInputLayout.Clear(); + pBlendState.Clear(); + pRasterizerState.Clear(); + // OrthoProjection: No need to clear. +} + +void HSWDisplay::LoadGraphics() +{ + // Load the graphics if not loaded already. + if(!pSamplerState) + { + D3D1X_(SAMPLER_DESC) sDesc; + + memset(&sDesc, 0, sizeof(sDesc)); + sDesc.Filter = D3D1X_(FILTER_MIN_MAG_MIP_LINEAR); + sDesc.AddressU = D3D1X_(TEXTURE_ADDRESS_CLAMP); + sDesc.AddressV = D3D1X_(TEXTURE_ADDRESS_CLAMP); + sDesc.AddressW = D3D1X_(TEXTURE_ADDRESS_CLAMP); + + RenderParams.pDevice->CreateSamplerState(&sDesc, &pSamplerState.GetRawRef()); + } + + #if defined(OVR_BUILD_DEBUG) + if(!pTexture) + pTexture = *LoadTextureTga(RenderParams, pSamplerState, "C:\\TestPath\\TestFile.tga", 255); + #endif + + if(!pTexture) // To do: Add support for .dds files, which would be significantly smaller than the size of the tga. + pTexture = *LoadTextureTga(RenderParams, pSamplerState, healthAndSafety_tga, (int)sizeof(healthAndSafety_tga), 255); + + if(!UniformBufferArray[0]) + { + for(size_t i = 0; i < OVR_ARRAY_COUNT(UniformBufferArray); i++) + UniformBufferArray[i] = *new Buffer(&RenderParams); + } + + if(!pShaderSet) + { + pShaderSet = *new ShaderSet; + + // Setup the vertex shader + const D3D1X_(INPUT_ELEMENT_DESC) VertexDescription[] = { + { "Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(HASWVertex, Pos), D3D1X_(INPUT_PER_VERTEX_DATA), 0 }, + { "Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(HASWVertex, C), D3D1X_(INPUT_PER_VERTEX_DATA), 0 }, + { "TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(HASWVertex, U), D3D1X_(INPUT_PER_VERTEX_DATA), 0 } + }; + + Ptr<D3D_NS::VertexShader> vs = *new D3D_NS::VertexShader(&RenderParams, (void*)SimpleTexturedQuad_vs, sizeof(SimpleTexturedQuad_vs), SimpleTexturedQuad_vs_refl, OVR_ARRAY_COUNT(SimpleTexturedQuad_vs_refl)); + pVertexInputLayout = NULL; // Make sure it's cleared in case it wasn't. + ID3D1xInputLayout** ppD3DInputLayout = &pVertexInputLayout.GetRawRef(); + HRESULT hResult = RenderParams.pDevice->CreateInputLayout(VertexDescription, OVR_ARRAY_COUNT(VertexDescription), SimpleTexturedQuad_vs, sizeof(SimpleTexturedQuad_vs), ppD3DInputLayout); + OVR_ASSERT(SUCCEEDED(hResult)); + if(SUCCEEDED(hResult)) + pShaderSet->SetShader(vs); + + // Setup the pixel shader + Ptr<D3D_NS::PixelShader> ps = *new D3D_NS::PixelShader(&RenderParams, (void*)SimpleTexturedQuad_ps, sizeof(SimpleTexturedQuad_ps), SimpleTexturedQuad_ps_refl, OVR_ARRAY_COUNT(SimpleTexturedQuad_ps_refl)); + pShaderSet->SetShader(ps); + + if(!pBlendState) + { + D3D1X_(BLEND_DESC) bm; + memset(&bm, 0, sizeof(bm)); + #if (OVR_D3D_VERSION == 10) + bm.BlendEnable[0] = TRUE; + bm.BlendOp = bm.BlendOpAlpha = D3D1X_(BLEND_OP_ADD); + bm.SrcBlend = bm.SrcBlendAlpha = D3D1X_(BLEND_SRC_ALPHA); + bm.DestBlend = bm.DestBlendAlpha = D3D1X_(BLEND_INV_SRC_ALPHA); + bm.RenderTargetWriteMask[0] = D3D1X_(COLOR_WRITE_ENABLE_ALL); + #else + bm.RenderTarget[0].BlendEnable = TRUE; + bm.RenderTarget[0].BlendOp = bm.RenderTarget[0].BlendOpAlpha = D3D1X_(BLEND_OP_ADD); + bm.RenderTarget[0].SrcBlend = bm.RenderTarget[0].SrcBlendAlpha = D3D1X_(BLEND_SRC_ALPHA); + bm.RenderTarget[0].DestBlend = bm.RenderTarget[0].DestBlendAlpha = D3D1X_(BLEND_INV_SRC_ALPHA); + bm.RenderTarget[0].RenderTargetWriteMask = D3D1X_(COLOR_WRITE_ENABLE_ALL); + #endif + + RenderParams.pDevice->CreateBlendState(&bm, &pBlendState.GetRawRef()); + } + + if(!pRasterizerState) + { + D3D1X_(RASTERIZER_DESC) rs; + memset(&rs, 0, sizeof(rs)); + rs.AntialiasedLineEnable = true; + rs.CullMode = D3D1X_(CULL_BACK); + rs.DepthClipEnable = true; + rs.FillMode = D3D1X_(FILL_SOLID); + + RenderParams.pDevice->CreateRasterizerState(&rs, &pRasterizerState.GetRawRef()); + } + } + + if(!pVB) + { + pVB = *new Buffer(&RenderParams); + + if(pVB) + { + const size_t vertexCount = 4; + + pVB->Data(Buffer_Vertex, NULL, vertexCount * sizeof(HASWVertex)); + HASWVertex* pVertices = (HASWVertex*)pVB->Map(0, vertexCount * sizeof(HASWVertex), Map_Discard); + OVR_ASSERT(pVertices); + + if(pVertices) + { + const bool flip = ((RenderState.DistortionCaps & ovrDistortionCap_FlipInput) != 0); + const float left = -1.0f; // We currently draw this in normalized device coordinates with an stereo translation + const float top = -1.1f; // applied as a vertex shader uniform. In the future when we have a more formal graphics + const float right = 1.0f; // API abstraction we may move this draw to an overlay layer or to a more formal + const float bottom = 0.9f; // model/mesh scheme with a perspective projection. + + pVertices[0] = HASWVertex(left, top, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 1.f : 0.f); + pVertices[1] = HASWVertex(left, bottom, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 0.f : 1.f); + pVertices[2] = HASWVertex(right, top, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 1.f : 0.f); + pVertices[3] = HASWVertex(right, bottom, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 0.f : 1.f); + + pVB->Unmap(pVertices); + } + } + } + + // Calculate ortho projection. + GetOrthoProjection(RenderState, OrthoProjection); +} + + +// Note: If we are drawing this warning onto the eye texture before distortion, the "time warp" functionality +// will cause the warning to shake on the screen when the user moves their head. One solution is to disable +// time warping while the warning or any screen-static GUI elements are present. + +void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) +{ + if(RenderEnabled && eyeTexture) + { + // We need to render to the eyeTexture with the texture viewport. + // Setup rendering to the texture. + ovrD3D1X(Texture)* eyeTextureD3D = const_cast<ovrD3D1X(Texture)*>(reinterpret_cast<const ovrD3D1X(Texture)*>(eyeTexture)); + OVR_ASSERT(eyeTextureD3D->Texture.Header.API == ((OVR_D3D_VERSION == 10) ? ovrRenderAPI_D3D10 : ovrRenderAPI_D3D11)); + + // D3D10 is currently disabled while we track down a bug that results in a black screen. + //if(eyeTextureD3D->Texture.Header.API == ovrRenderAPI_D3D10) + // return; + + // Load the graphics if not loaded already. + if(!pVB) + LoadGraphics(); + + + // Save settings + // To do: Merge this saved state with that done by DistortionRenderer::GraphicsState::Save(), and put them in a shared location. + Ptr<ID3D1xBlendState> pBlendStateSaved; + FLOAT blendFactorSaved[4]; + UINT blendSampleMaskSaved; + RenderParams.pContext->OMGetBlendState(&pBlendStateSaved.GetRawRef(), blendFactorSaved, &blendSampleMaskSaved); + + Ptr<ID3D1xRasterizerState> pRasterizerStateSaved; + RenderParams.pContext->RSGetState(&pRasterizerStateSaved.GetRawRef()); + + Ptr<ID3D1xRenderTargetView> pTextureRenderTargetViewSaved; + Ptr<ID3D1xDepthStencilView> pDepthStencilViewSaved; + RenderParams.pContext->OMGetRenderTargets(1, &pTextureRenderTargetViewSaved.GetRawRef(), &pDepthStencilViewSaved.GetRawRef()); + + #ifndef D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE // D3D10 doesn't define this, so we pretend that it does. + #define D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE 4 + #endif + D3D1x_VIEWPORT d3dViewportSaved[D3D1X_(VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE)]; + UINT viewportCountSaved = OVR_ARRAY_COUNT(d3dViewportSaved); + RenderParams.pContext->RSGetViewports(&viewportCountSaved, d3dViewportSaved); + + UINT stencilRefSaved; + Ptr<ID3D1xDepthStencilState> pDepthStencilStateSaved; + RenderParams.pContext->OMGetDepthStencilState(&pDepthStencilStateSaved.GetRawRef(), &stencilRefSaved); + + Ptr<ID3D1xInputLayout> pInputLayoutSaved; + RenderParams.pContext->IAGetInputLayout(&pInputLayoutSaved.GetRawRef()); + + Ptr<ID3D1xBuffer> pVertexBufferSaved; + UINT vertexStrideSaved[1]; + UINT vertexOffsetSaved[1]; + RenderParams.pContext->IAGetVertexBuffers(0, 1, &pVertexBufferSaved.GetRawRef(), vertexStrideSaved, vertexOffsetSaved); + + D3D1X_(PRIMITIVE_TOPOLOGY) topologySaved; + RenderParams.pContext->IAGetPrimitiveTopology(&topologySaved); + + + // Set our settings + RenderParams.pContext->OMSetBlendState(pBlendState, NULL, 0xffffffff); + RenderParams.pContext->RSSetState(pRasterizerState); + + // We can't necessarily use a NULL D3D11_RENDER_TARGET_VIEW_DESC argument to CreateRenderTargetView, because we are rendering to + // a texture that somebody else created and which may have been created in a typeless format (e.g. DXGI_FORMAT_R8G8B8A8_TYPELESS). + // So what we do is check to see if the texture format is a typeless format and if see we pass a suitable D3D11_RENDER_TARGET_VIEW_DESC + // to CreateRenderTargetView instead of NULL. + D3D1X_(TEXTURE2D_DESC) texture2DDesc; + eyeTextureD3D->D3D_NS.pTexture->GetDesc(&texture2DDesc); + + D3D1X_(RENDER_TARGET_VIEW_DESC) renderTargetViewDesc; + memset(&renderTargetViewDesc, 0, sizeof(renderTargetViewDesc)); + renderTargetViewDesc.Format = GetFullyTypedDXGIFormat(texture2DDesc.Format); // DXGI_FORMAT. If this is a typeless format then GetFullyTypedFormat converts it to a fully typed format. + renderTargetViewDesc.ViewDimension = (texture2DDesc.SampleDesc.Count > 1) ? D3D1X_(RTV_DIMENSION_TEXTURE2DMS) : D3D1X_(RTV_DIMENSION_TEXTURE2D); + renderTargetViewDesc.Texture2D.MipSlice = 0; + Ptr<ID3D1xRenderTargetView> pTextureRenderTargetView; + HRESULT hResult = RenderParams.pDevice->CreateRenderTargetView(eyeTextureD3D->D3D_NS.pTexture, (renderTargetViewDesc.Format == texture2DDesc.Format) ? NULL : &renderTargetViewDesc, &pTextureRenderTargetView.GetRawRef()); + + if(SUCCEEDED(hResult)) + { + RenderParams.pContext->OMSetRenderTargets(1, &pTextureRenderTargetView.GetRawRef(), NULL); // We currently don't bind a depth buffer. + + D3D1x_VIEWPORT D3DViewport; + + OVR_DISABLE_MSVC_WARNING(4244) // conversion from int to float + D3DViewport.TopLeftX = eyeTextureD3D->Texture.Header.RenderViewport.Pos.x; + D3DViewport.TopLeftY = eyeTextureD3D->Texture.Header.RenderViewport.Pos.y; + D3DViewport.Width = eyeTextureD3D->Texture.Header.RenderViewport.Size.w; + D3DViewport.Height = eyeTextureD3D->Texture.Header.RenderViewport.Size.h; + D3DViewport.MinDepth = 0; + D3DViewport.MaxDepth = 1; + RenderParams.pContext->RSSetViewports(1, &D3DViewport); + OVR_RESTORE_MSVC_WARNING() + + // We don't set up a world/view/projection matrix because we are using + // normalized device coordinates below. + + // We don't set the depth state because we aren't using it. + // RenderParams.pContext->OMSetDepthStencilState(<depth state>, 0); + + ShaderFill fill(pShaderSet); + fill.SetInputLayout(pVertexInputLayout); + if(pTexture) + fill.SetTexture(0, pTexture); + + const float scale = HSWDISPLAY_SCALE * ((RenderState.OurHMDInfo.HmdType == HmdType_DK1) ? 0.70f : 1.f); + pShaderSet->SetUniform2f("Scale", scale, scale / 2.f); // X and Y scale. Y is a fixed proportion to X in order to give a certain aspect ratio. + pShaderSet->SetUniform4f("Color", 1.f, 1.f, 1.f, 1.f); + pShaderSet->SetUniform2f("PositionOffset", OrthoProjection[eye].GetTranslation().x, 0.0f); + + RenderParams.pContext->IASetInputLayout((ID3D1xInputLayout*)fill.GetInputLayout()); + + ID3D1xBuffer* vertexBuffer = pVB->GetBuffer(); + UINT vertexStride = sizeof(HASWVertex); + UINT vertexOffset = 0; + RenderParams.pContext->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset); + + ShaderBase* vShaderBase = (ShaderBase*)pShaderSet->GetShader(OVR::CAPI::D3D_NS::Shader_Vertex); + unsigned char* vertexData = vShaderBase->UniformData; + + if (vertexData) + { + UniformBufferArray[OVR::CAPI::D3D_NS::Shader_Vertex]->Data(OVR::CAPI::D3D_NS::Buffer_Uniform, vertexData, vShaderBase->UniformsSize); + vShaderBase->SetUniformBuffer(UniformBufferArray[OVR::CAPI::D3D_NS::Shader_Vertex]); + } + + for (int i = (OVR::CAPI::D3D_NS::Shader_Vertex + 1); i < OVR::CAPI::D3D_NS::Shader_Count; i++) + { + if (pShaderSet->GetShader(i)) + { + ((ShaderBase*)pShaderSet->GetShader(i))->UpdateBuffer(UniformBufferArray[i]); + ((ShaderBase*)pShaderSet->GetShader(i))->SetUniformBuffer(UniformBufferArray[i]); + } + } + + RenderParams.pContext->IASetPrimitiveTopology(D3D1X_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP)); + fill.Set(Prim_TriangleStrip); + + RenderParams.pContext->Draw(4, 0); + } + else + { + HSWDISPLAY_LOG(("[HSWDisplay D3D1x] CreateRenderTargetView() failed")); + } + + + // Restore settings + RenderParams.pContext->IASetPrimitiveTopology(topologySaved); + RenderParams.pContext->IASetVertexBuffers(0, 1, &pVertexBufferSaved.GetRawRef(), &vertexStrideSaved[0], &vertexOffsetSaved[0]); + RenderParams.pContext->IASetInputLayout(pInputLayoutSaved); + RenderParams.pContext->OMSetDepthStencilState(pDepthStencilStateSaved, stencilRefSaved); + RenderParams.pContext->RSSetViewports(viewportCountSaved, d3dViewportSaved); + RenderParams.pContext->OMSetRenderTargets(1, &pTextureRenderTargetViewSaved.GetRawRef(), pDepthStencilViewSaved); + RenderParams.pContext->RSSetState(pRasterizerStateSaved); + RenderParams.pContext->OMSetBlendState(pBlendStateSaved, blendFactorSaved, blendSampleMaskSaved); + } +} + +}}} // namespace OVR::CAPI::D3D_NS + + +#endif // OVR_D3D_VERSION + + + + diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.h new file mode 100644 index 0000000..16391c6 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.h @@ -0,0 +1,84 @@ +/************************************************************************************ + +Filename : CAPI_D3D1X_HSWDisplay.h +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.1 (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 + +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, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +// Do not use include guards, as this file is #included separately by both +// CAPI_D3D10_HSWDisplay.h and CAPI_D3D11_HSWDisplay.h with OVR_D3D_VERSION defined +// to either 10 or 11. Only those two headers should #include this one. +//#ifndef OVR_CAPI_D3D1X_HSWDisplay_h +//#define OVR_CAPI_D3D1X_HSWDisplay_h + +//#if !defined(OVR_CAPI_D3D10_HSWDisplay_h) && !defined(OVR_CAPI_D3D11_HSWDisplay_h) +// #error This header is expected to be compiled only by these two headers. +//#endif +#if !defined(OVR_D3D_VERSION) || ((OVR_D3D_VERSION != 10) && (OVR_D3D_VERSION != 11)) + #error This header expects OVR_D3D_VERSION to be defined, to 10 or 11. +#endif + +#include "../CAPI_HSWDisplay.h" +#include "CAPI_D3D1X_Util.h" + + +namespace OVR { namespace CAPI { namespace D3D_NS { + + class HSWDisplay : public CAPI::HSWDisplay + { + public: + HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState); + + // Must be called before use. apiConfig is such that: + // const ovrD3D11Config* config = (const ovrD3D11Config*)apiConfig; or + bool Initialize(const ovrRenderAPIConfig* apiConfig); + void Shutdown(); + void DisplayInternal(); + void DismissInternal(); + + // Draws the warning to the eye texture(s). This must be done at the end of a + // frame but prior to executing the distortion rendering of the eye textures. + void RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture); + + protected: + void LoadGraphics(); + void UnloadGraphics(); + + OVR::CAPI::D3D_NS::RenderParams RenderParams; + Ptr<ID3D1xSamplerState> pSamplerState; + Ptr<OVR::CAPI::D3D_NS::Texture> pTexture; + Ptr<Buffer> pVB; + Ptr<Buffer> UniformBufferArray[OVR::CAPI::D3D_NS::Shader_Count]; + Ptr<ShaderSet> pShaderSet; + Ptr<ID3D1xInputLayout> pVertexInputLayout; + Ptr<ID3D1xBlendState> pBlendState; + Ptr<ID3D1xRasterizerState> pRasterizerState; + Matrix4f OrthoProjection[ovrEye_Count]; + + private: + OVR_NON_COPYABLE(HSWDisplay) + }; + +}}} // namespace OVR::CAPI::D3D_NS + + + diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp index 501a8e3..e3b438f 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp @@ -116,6 +116,7 @@ bool Buffer::Data(int use, const void *buffer, size_t size) sr.SysMemPitch = 0; sr.SysMemSlicePitch = 0; + D3DBuffer = NULL; HRESULT hr = pParams->pDevice->CreateBuffer(&desc, buffer ? &sr : NULL, &D3DBuffer.GetRawRef()); if (SUCCEEDED(hr)) { diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h index 7bbc685..9aa5e43 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h @@ -42,6 +42,7 @@ limitations under the License. #include "../../Kernel/OVR_Math.h" #if defined(OVR_OS_WIN32) +#define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <comdef.h> // for _COM_SMARTPTR_TYPEDEF() @@ -107,6 +108,12 @@ typedef D3D1X_(VIEWPORT) D3D1x_VIEWPORT; typedef D3D1X_(QUERY_DESC) D3D1x_QUERY_DESC; typedef D3D1X_(SHADER_BUFFER_DESC) D3D1x_SHADER_BUFFER_DESC; typedef D3D1X_(SHADER_VARIABLE_DESC) D3D1x_SHADER_VARIABLE_DESC; +typedef D3D1X_(PRIMITIVE_TOPOLOGY) D3D1x_PRIMITIVE_TOPOLOGY; +static const int D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT = D3D1X_(COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT); +static const int D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT = D3D1X_(COMMONSHADER_SAMPLER_SLOT_COUNT); +static const int D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT = D3D1X_(SIMULTANEOUS_RENDER_TARGET_COUNT); +static const int D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = D3D1X_(IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT); +static const int D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT = D3D1X_(COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); // Blob is the same typedef ID3D10Blob ID3D1xBlob; diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp index e8cf767..a685191 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp @@ -70,7 +70,7 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, screenSize = config->D3D9.Header.RTSize; distortionCaps = arg_distortionCaps; - GfxState = *new GraphicsState(device); + GfxState = *new GraphicsState(device, distortionCaps); CreateVertexDeclaration(); CreateDistortionShaders(); @@ -81,7 +81,7 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, /**************************************************************/ -void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture) +void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture) { //Doesn't do a lot in here?? const ovrD3D9Texture* tex = (const ovrD3D9Texture*)eyeTexture; @@ -99,51 +99,70 @@ void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture) ovrHmd_GetRenderScaleAndOffset( erd.Fov, eachEye[eyeId].TextureSize, eachEye[eyeId].RenderViewport, eachEye[eyeId].UVScaleOffset ); -} + if (RState.DistortionCaps & ovrDistortionCap_FlipInput) + { + eachEye[eyeId].UVScaleOffset[0].y = -eachEye[eyeId].UVScaleOffset[0].y; + eachEye[eyeId].UVScaleOffset[1].y = 1.0f - eachEye[eyeId].UVScaleOffset[1].y; + } +} -/******************************************************************/ -void DistortionRenderer::EndFrame(bool swapBuffers, - unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor) +void DistortionRenderer::renderEndFrame() { - OVR_UNUSED(swapBuffers); - OVR_UNUSED(latencyTesterDrawColor); + RenderBothDistortionMeshes(); - ///QUESTION : Should I be clearing the screen? - ///QUESTION : Should I be ensuring the screen is the render target + if(RegisteredPostDistortionCallback) + RegisteredPostDistortionCallback(device); - if (!TimeManager.NeedDistortionTimeMeasurement()) + if(LatencyTest2Active) { - if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) - { - // Wait for timewarp distortion if it is time and Gpu idle - WaitTillTimeAndFlushGpu(TimeManager.GetFrameTiming().TimewarpPointTime); - } - - RenderBothDistortionMeshes(); + // TODO: + //renderLatencyPixel(LatencyTest2DrawColor); } - else +} + +/******************************************************************/ +void DistortionRenderer::EndFrame(bool swapBuffers) +{ + ///QUESTION : Clear the screen? + ///QUESTION : Ensure the screen is the render target + + // 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); - RenderBothDistortionMeshes(); - WaitUntilGpuIdle(); + renderEndFrame(); + } + else + { + // If needed, measure distortion time so that TimeManager can better estimate + // latency-reducing time-warp wait timing. + WaitUntilGpuIdle(); + double distortionStartTime = ovr_GetTimeInSeconds(); - TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); - } + renderEndFrame(); - if(latencyTesterDrawColor) + WaitUntilGpuIdle(); + TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); + } + } + else { - ///QUESTION : Is this still to be supported? - ///renderLatencyQuad(latencyTesterDrawColor); + renderEndFrame(); } - if(latencyTester2DrawColor) + if(RegisteredPostDistortionCallback) + RegisteredPostDistortionCallback(device); + + if(LatencyTestDrawColor) { - // TODO: + // TODO: Support latency tester quad + ///renderLatencyQuad(latencyTesterDrawColor); } if (swapBuffers) @@ -159,7 +178,10 @@ void DistortionRenderer::EndFrame(bool swapBuffers, // Force GPU to flush the scene, resulting in the lowest possible latency. // It's critical that this flush is *after* present. - WaitUntilGpuIdle(); + // Doesn't need to be done if running through the Oculus driver. + if (RState.OurHMDInfo.InCompatibilityMode && + !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits)) + WaitUntilGpuIdle(); } } @@ -174,38 +196,29 @@ void DistortionRenderer::WaitUntilGpuIdle() if(pEventQuery!=NULL) { pEventQuery->Issue(D3DISSUE_END) ; - while(S_FALSE == pEventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH)) ; + while(S_FALSE == pEventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH)){} + pEventQuery->Release(); } } } -double DistortionRenderer::WaitTillTimeAndFlushGpu(double absTime) +double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) { - double initialTime = ovr_GetTimeInSeconds(); + double initialTime = ovr_GetTimeInSeconds(); if (initialTime >= absTime) return 0.0; WaitUntilGpuIdle(); - double newTime = initialTime; - volatile int i; - - while (newTime < absTime) - { - for (int j = 0; j < 50; j++) - i = 0; - newTime = ovr_GetTimeInSeconds(); - } - - // How long we waited - return newTime - initialTime; + return WaitTillTime(absTime); } -DistortionRenderer::GraphicsState::GraphicsState(IDirect3DDevice9* d) +DistortionRenderer::GraphicsState::GraphicsState(IDirect3DDevice9* d, unsigned arg_distortionCaps) : device(d) , numSavedStates(0) +, distortionCaps(arg_distortionCaps) { } @@ -238,6 +251,7 @@ void DistortionRenderer::GraphicsState::Save() RecordAndSetState(0, D3DSAMP_BORDERCOLOR, 0x000000 ); RecordAndSetState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER ); RecordAndSetState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER ); + RecordAndSetState(0, D3DSAMP_SRGBTEXTURE, (distortionCaps & ovrDistortionCap_SRGB) ? TRUE : FALSE ); RecordAndSetState(1, D3DRS_MULTISAMPLEANTIALIAS, FALSE ); RecordAndSetState(1, D3DRS_DITHERENABLE, FALSE ); @@ -254,6 +268,7 @@ void DistortionRenderer::GraphicsState::Save() RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); RecordAndSetState(1, D3DRS_LIGHTING, FALSE ); RecordAndSetState(1, D3DRS_FOGENABLE, FALSE ); + RecordAndSetState(1, D3DRS_SRGBWRITEENABLE, (distortionCaps & ovrDistortionCap_SRGB) ? TRUE : FALSE ); } diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h index f24eb31..be5aa5f 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h @@ -29,6 +29,7 @@ limitations under the License. #undef new #if defined (OVR_OS_WIN32) +#define WIN32_LEAN_AND_MEAN #if _MSC_VER < 1700 #include <d3dx9.h> #else @@ -63,23 +64,23 @@ public: virtual bool Initialize(const ovrRenderAPIConfig* apiConfig, unsigned distortionCaps); - virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture); + virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture); - virtual void EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor); + virtual void EndFrame(bool swapBuffers); // TBD: Make public? void WaitUntilGpuIdle(); // Similar to ovr_WaitTillTime but it also flushes GPU. // Note, it exits when time expires, even if GPU is not in idle state yet. - double WaitTillTimeAndFlushGpu(double absTime); + double FlushGpuAndWaitTillTime(double absTime); protected: class GraphicsState : public CAPI::DistortionRenderer::GraphicsState { public: - GraphicsState(IDirect3DDevice9* d); + GraphicsState(IDirect3DDevice9* d, unsigned arg_distortionCaps); virtual void Save(); virtual void Restore(); @@ -98,6 +99,7 @@ protected: //Keep track of how many we've done, for reverting int numSavedStates; IDirect3DDevice9* device; + unsigned distortionCaps; }; private: @@ -110,6 +112,7 @@ private: void RecordAndSetState(int which, int type, DWORD newValue); void RevertAllStates(void); + void renderEndFrame(); //Data, structures and pointers IDirect3DDevice9 * device; diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_HSWDisplay.cpp new file mode 100644 index 0000000..3daad5d --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_HSWDisplay.cpp @@ -0,0 +1,433 @@ +/************************************************************************************ + +Filename : CAPI_D3D9_HSWDisplay.cpp +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.1 (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 + +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, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#define OVR_D3D_VERSION 9 +#include "CAPI_D3D9_HSWDisplay.h" +#include "../../OVR_CAPI_D3D.h" +#undef OVR_D3D_VERSION + +#include <d3d9.h> +#include "../../Kernel/OVR_File.h" +#include "../../Kernel/OVR_SysFile.h" +#include "../../Kernel/OVR_Math.h" +#include "../../Kernel/OVR_Allocator.h" +#include "../../Kernel/OVR_Color.h" + +#include "../Textures/healthAndSafety.tga.h" + + + +namespace OVR { namespace CAPI { + + +// To do Need to move LoadTextureTgaData to a shared location. +uint8_t* LoadTextureTgaData(OVR::File* f, uint8_t alpha, int& width, int& height); + + +namespace D3D9 { + +// This is a temporary function implementation, and it functionality needs to be implemented in a more generic way. +IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, OVR::File* f, uint8_t alpha) +{ + IDirect3DTexture9* pTexture = NULL; + + int width, height; + const uint8_t* pRGBA = LoadTextureTgaData(f, alpha, width, height); + + if (pRGBA) + { + // We don't have access to D3DX9 and so we currently have to do this manually instead of calling a D3DX9 utility function. + Ptr<IDirect3DTexture9> pTextureSysmem; + HRESULT hResult = rParams.Device->CreateTexture((UINT)width, (UINT)height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pTextureSysmem.GetRawRef(), NULL); + + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("CreateTexture(D3DPOOL_SYSTEMMEM) failed. %d (%x)", hResult, hResult)); } + else + { + // Lock the texture so we can write this frame's texel data + D3DLOCKED_RECT lock; + hResult = pTextureSysmem->LockRect(0, &lock, NULL, D3DLOCK_NOSYSLOCK | D3DLOCK_NO_DIRTY_UPDATE); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("LockRect failed. %d (%x)", hResult, hResult)); } + else + { + // Four bytes per pixel. Pitch bytes per row (will be >= w * 4). + uint8_t* pRow = (uint8_t*)lock.pBits; + const uint8_t* pSource = pRGBA; + + for(int y = 0; y < height; y++, pRow += lock.Pitch, pSource += (width * 4)) + { + uint8_t* pDest = pRow; + + for(int x = 0, xEnd = width * 4; x < xEnd; x += 4) + { + pDest[x + 0] = pSource[x + 2]; + pDest[x + 1] = pSource[x + 1]; + pDest[x + 2] = pSource[x + 0]; + pDest[x + 3] = pSource[x + 3]; + } + } + + pTextureSysmem->UnlockRect(0); + + hResult = rParams.Device->CreateTexture((UINT)width, (UINT)height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("CreateTexture(D3DPOOL_DEFAULT) failed. %d (%x)", hResult, hResult)); } + else + { + hResult = rParams.Device->UpdateTexture(pTextureSysmem, pTexture); + if(FAILED(hResult)) + { + HSWDISPLAY_LOG(("UpdateTexture failed. %d (%x)", hResult, hResult)); + pTexture->Release(); + pTexture = NULL; + } + } + } + } + + OVR_FREE(const_cast<uint8_t*>(pRGBA)); + } + + return pTexture; +} + + +// Loads a texture from a memory image of a TGA file. +IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, const uint8_t* pData, int dataSize, uint8_t alpha) +{ + MemoryFile memoryFile("", pData, dataSize); + + return LoadTextureTga(rParams, &memoryFile, alpha); +} + + +// Loads a texture from a disk TGA file. +IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, const char* pFilePath, uint8_t alpha) +{ + SysFile sysFile; + + if(sysFile.Open(pFilePath, FileConstants::Open_Read | FileConstants::Open_Buffered)) + return LoadTextureTga(rParams, &sysFile, alpha); + + return NULL; +} + + + +// To do: This needs to be promoted to a central version, possibly in CAPI_HSWDisplay.h +struct HASWVertex +{ + Vector3f Pos; + Color C; + float U, V; + + HASWVertex(const Vector3f& p, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) + : Pos(p), C(c), U(u), V(v) + {} + + HASWVertex(float x, float y, float z, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) + : Pos(x,y,z), C(c), U(u), V(v) + {} + + bool operator==(const HASWVertex& b) const + { + return (Pos == b.Pos) && (C == b.C) && (U == b.U) && (V == b.V); + } +}; + +#define HASWVertexD3D9Format (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) + + +// The texture below may conceivably be shared between HSWDisplay instances. However, +// beware that sharing may not be possible if two HMDs are using different locales +// simultaneously. As of this writing it's not clear if that can occur in practice. + +HSWDisplay::HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState) + : OVR::CAPI::HSWDisplay(api, hmd, renderState) + , RenderParams() +{ +} + +bool HSWDisplay::Initialize(const ovrRenderAPIConfig* apiConfig) +{ + const ovrD3D9Config* config = reinterpret_cast<const ovrD3D9Config*>(apiConfig); + + if(config) + { + RenderParams.Device = config->D3D9.pDevice; + RenderParams.SwapChain = config->D3D9.pSwapChain; + RenderParams.ScreenSize = config->D3D9.Header.RTSize; + } + else + { + UnloadGraphics(); + } + + return true; +} + +void HSWDisplay::Shutdown() +{ + UnloadGraphics(); +} + +void HSWDisplay::DisplayInternal() +{ + HSWDISPLAY_LOG(("[HSWDisplay D3D9] DisplayInternal()")); + // We may want to call LoadGraphics here instead of within Render. +} + +void HSWDisplay::DismissInternal() +{ + HSWDISPLAY_LOG(("[HSWDisplay D3D9] DismissInternal()")); + UnloadGraphics(); +} + + +void HSWDisplay::UnloadGraphics() +{ + // RenderParams: No need to clear. + pTexture.Clear(); + pVB.Clear(); + // OrthoProjection: No need to clear. +} + + +void HSWDisplay::LoadGraphics() +{ + // As of this writing, we don't yet have an abstraction for Textures, Buffers, and Shaders like we do for D3D11, D3D11, and OpenGL. + #if defined(OVR_BUILD_DEBUG) + if(!pTexture) + pTexture = *LoadTextureTga(RenderParams, "C:\\TestPath\\TestFile.tga", 255); + #endif + + if(!pTexture) + { + D3DCAPS9 caps; + RenderParams.Device->GetDeviceCaps(&caps); + + if(caps.TextureCaps & (D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_POW2)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] Square textures allowed only.")); } + + pTexture = *LoadTextureTga(RenderParams, healthAndSafety_tga, (int)sizeof(healthAndSafety_tga), 255); + OVR_ASSERT(pTexture); + } + + if(!pVB) + { + HRESULT hResult = RenderParams.Device->CreateVertexBuffer(4 * sizeof(HASWVertex), NULL, HASWVertexD3D9Format, D3DPOOL_MANAGED, &pVB.GetRawRef(), NULL); + + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] CreateVertexBuffer failed. %d (%x)", hResult, hResult)); } + else + { + void* pVerticesVoid; + hResult = pVB->Lock(0, 0, (void**)&pVerticesVoid, 0); + + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] Lock failed. %d (%x)", hResult, hResult)); } + else + { + HASWVertex* pVertices = reinterpret_cast<HASWVertex*>(pVerticesVoid); + + const bool flip = ((RenderState.DistortionCaps & ovrDistortionCap_FlipInput) != 0); + const float left = -1.0f; + const float top = -1.1f; + const float right = +1.0f; + const float bottom = +0.9f; + + pVertices[0] = HASWVertex(left, top, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 1.f : 0.f); // To do: Make this branchless + pVertices[1] = HASWVertex(left, bottom, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 0.f : 1.f); + pVertices[2] = HASWVertex(right, top, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 1.f : 0.f); + pVertices[3] = HASWVertex(right, bottom, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 0.f : 1.f); + + pVB->Unlock(); + } + } + } + + // Calculate ortho projection. + GetOrthoProjection(RenderState, OrthoProjection); +} + + +void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) +{ + if(RenderEnabled && eyeTexture) + { + // Note: The D3D9 implementation below is entirely fixed-function and isn't yet using shaders. + // For the time being this is sufficient, but future designs will likely necessitate moving + // to a system that uses programmable shaders. + + // We need to render to the eyeTexture with the texture viewport. + // Setup rendering to the texture. + ovrD3D9Texture* eyeTextureD3D9 = const_cast<ovrD3D9Texture*>(reinterpret_cast<const ovrD3D9Texture*>(eyeTexture)); + OVR_ASSERT(eyeTextureD3D9->Texture.Header.API == ovrRenderAPI_D3D9); + + + // Save previous state. + // To do: Merge this saved state with that done by DistortionRenderer::GraphicsState::Save(), and put them in a shared location. + DWORD fvfSaved; + RenderParams.Device->GetFVF(&fvfSaved); + + Ptr<IDirect3DVertexBuffer9> pVBDSaved; + UINT vbOffsetSaved; + UINT vbStrideSaved; + RenderParams.Device->GetStreamSource(0, &pVBDSaved.GetRawRef(), &vbOffsetSaved, &vbStrideSaved); + + Ptr<IDirect3DBaseTexture9> pTexture0Saved; + RenderParams.Device->GetTexture(0, &pTexture0Saved.GetRawRef()); + Ptr<IDirect3DBaseTexture9> pTexture1Saved; + RenderParams.Device->GetTexture(1, &pTexture1Saved.GetRawRef()); + + D3DMATRIX worldMatrixSaved, viewMatrixSaved, projectionMatrixSaved, texture0MatrixSaved; + RenderParams.Device->GetTransform(D3DTS_WORLD, &worldMatrixSaved); + RenderParams.Device->GetTransform(D3DTS_VIEW, &viewMatrixSaved); + RenderParams.Device->GetTransform(D3DTS_PROJECTION, &projectionMatrixSaved); + RenderParams.Device->GetTransform(D3DTS_TEXTURE0, &texture0MatrixSaved); + + Ptr<IDirect3DVertexShader9> pVertexShaderSaved; + RenderParams.Device->GetVertexShader(&pVertexShaderSaved.GetRawRef()); + + Ptr<IDirect3DPixelShader9> pPixelShaderSaved; + RenderParams.Device->GetPixelShader(&pPixelShaderSaved.GetRawRef()); + + D3DVIEWPORT9 viewportSaved; + RenderParams.Device->GetViewport(&viewportSaved); + + Ptr<IDirect3DSurface9> pRenderTargetSaved; + RenderParams.Device->GetRenderTarget(0, &pRenderTargetSaved.GetRawRef()); + + + // Load the graphics if not loaded already. + if(!pTexture) + LoadGraphics(); + + HRESULT hResult; + + hResult = RenderParams.Device->BeginScene(); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] BeginScene failed. %d (%x)", hResult, hResult)); } + + Ptr<IDirect3DSurface9> pDestSurface; + hResult = eyeTextureD3D9->D3D9.pTexture->GetSurfaceLevel(0, &pDestSurface.GetRawRef()); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] GetSurfaceLevel failed. %d (%x)", hResult, hResult)); } + + hResult = RenderParams.Device->SetRenderTarget(0, pDestSurface); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetRenderTarget failed. %d (%x)", hResult, hResult)); } + + D3DVIEWPORT9 D3DViewport; + D3DViewport.X = eyeTextureD3D9->Texture.Header.RenderViewport.Pos.x; + D3DViewport.Y = eyeTextureD3D9->Texture.Header.RenderViewport.Pos.y; + D3DViewport.Width = eyeTextureD3D9->Texture.Header.RenderViewport.Size.w; + D3DViewport.Height = eyeTextureD3D9->Texture.Header.RenderViewport.Size.h; + D3DViewport.MinZ = 0; + D3DViewport.MaxZ = 1; + hResult = RenderParams.Device->SetViewport(&D3DViewport); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetViewport failed. %d (%x)", hResult, hResult)); } + + hResult = RenderParams.Device->SetTexture(0, pTexture); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetTexture failed. %d (%x)", hResult, hResult)); } + + RenderParams.Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + RenderParams.Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + RenderParams.Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + + RenderParams.Device->SetVertexShader(NULL); + RenderParams.Device->SetPixelShader(NULL); + + hResult = RenderParams.Device->SetStreamSource(0, pVB, 0, sizeof(HASWVertex)); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetStreamSource failed. %d (%x)", hResult, hResult)); } + + RenderParams.Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + RenderParams.Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + RenderParams.Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + RenderParams.Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + RenderParams.Device->SetRenderState(D3DRS_LIGHTING, FALSE); + RenderParams.Device->SetRenderState(D3DRS_ZENABLE, FALSE); + RenderParams.Device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + RenderParams.Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + RenderParams.Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + RenderParams.Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + const float scale = HSWDISPLAY_SCALE * ((RenderState.OurHMDInfo.HmdType == HmdType_DK1) ? 0.70f : 1.f); + Matrix4f identityMatrix = Matrix4f::Identity(); + Vector3f translation = OrthoProjection[eye].GetTranslation(); + Matrix4f orthoStereoMatrix( + scale, 0, 0, 0, + 0, scale / 2, 0, 0, + 0, 0, HSWDISPLAY_DISTANCE, 0, + translation.x, translation.y, translation.z, 1 + ); + RenderParams.Device->SetTransform(D3DTS_WORLD, reinterpret_cast<const D3DMATRIX*>(&identityMatrix)); + RenderParams.Device->SetTransform(D3DTS_VIEW, reinterpret_cast<const D3DMATRIX*>(&identityMatrix)); + RenderParams.Device->SetTransform(D3DTS_PROJECTION, reinterpret_cast<const D3DMATRIX*>(&orthoStereoMatrix)); + RenderParams.Device->SetTransform(D3DTS_TEXTURE0, reinterpret_cast<const D3DMATRIX*>(&identityMatrix)); + + hResult = RenderParams.Device->SetFVF(HASWVertexD3D9Format); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetFVF failed. %d (%x)", hResult, hResult)); } + + hResult = RenderParams.Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] DrawPrimitive failed. %d (%x)", hResult, hResult)); } + + hResult = RenderParams.Device->EndScene(); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] EndScene failed. %d (%x)", hResult, hResult)); } + + + // Restore previous state. + RenderParams.Device->SetRenderTarget(0, pRenderTargetSaved); + RenderParams.Device->SetViewport(&viewportSaved); + RenderParams.Device->SetPixelShader(pPixelShaderSaved); + RenderParams.Device->SetVertexShader(pVertexShaderSaved); + RenderParams.Device->SetTransform(D3DTS_TEXTURE0, &texture0MatrixSaved); + RenderParams.Device->SetTransform(D3DTS_PROJECTION, &projectionMatrixSaved); + RenderParams.Device->SetTransform(D3DTS_VIEW, &viewMatrixSaved); + RenderParams.Device->SetTransform(D3DTS_WORLD, &worldMatrixSaved); + RenderParams.Device->SetTexture(0, pTexture0Saved); + RenderParams.Device->SetTexture(1, pTexture1Saved); + RenderParams.Device->SetStreamSource(0, pVBDSaved, vbOffsetSaved, vbStrideSaved); + RenderParams.Device->SetFVF(fvfSaved); + } +} + + +}}} // namespace OVR::CAPI::D3D9 + + + + + + + diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_HSWDisplay.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_HSWDisplay.h new file mode 100644 index 0000000..6fbd58f --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_HSWDisplay.h @@ -0,0 +1,82 @@ +/************************************************************************************ + +Filename : CAPI_D3D9_HSWDisplay.h +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.1 (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 + +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, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CAPI_D3D9_HSWDisplay_h +#define OVR_CAPI_D3D9_HSWDisplay_h + +#if !defined(OVR_D3D_VERSION) || (OVR_D3D_VERSION != 9) + #error This header expects OVR_D3D_VERSION to be defined, to 9. +#endif + +#include "../CAPI_HSWDisplay.h" +#include "CAPI_D3D1X_Util.h" +#include <d3d9.h> + + +namespace OVR { namespace CAPI { namespace D3D9 { + + // There currently isn't a D3D9::RenderParams, as D3D9 support is currently only very basic. + struct HSWRenderParams + { + IDirect3DDevice9* Device; + IDirect3DSwapChain9* SwapChain; + ovrSizei ScreenSize; + }; + + class HSWDisplay : public CAPI::HSWDisplay + { + public: + HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState); + + // Must be called before use. apiConfig is such that: + // const ovrD3D9Config* config = (const ovrD3D9Config*)apiConfig; or + bool Initialize(const ovrRenderAPIConfig* apiConfig); + void Shutdown(); + void DisplayInternal(); + void DismissInternal(); + + // Draws the warning to the eye texture(s). This must be done at the end of a + // frame but prior to executing the distortion rendering of the eye textures. + void RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture); + + protected: + void LoadGraphics(); + void UnloadGraphics(); + + D3D9::HSWRenderParams RenderParams; + Ptr<IDirect3DTexture9> pTexture; + Ptr<IDirect3DVertexBuffer9> pVB; + Matrix4f OrthoProjection[2]; // Projection for 2D. + + private: + OVR_NON_COPYABLE(HSWDisplay) + }; + +}}} // namespace OVR::CAPI::D3D9 + + +#endif // OVR_CAPI_D3D9_HSWDisplay_h + diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp index e6bdcb6..cc164df 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp @@ -32,17 +32,18 @@ limitations under the License. namespace OVR { namespace CAPI { namespace D3D9 { -#define PRECOMPILE_FLAG 0 +#define PRECOMPILE_FLAG 0 #if !PRECOMPILE_FLAG //To make these, you need to run it with PRECOMPILE_FLAG, which also uses them, so good for debugging. //Then cut and paste these from the output window. //Then turn off the flag. -DWORD precompiledVertexShaderSrc[95] = {4294836736,3014654,1111577667,28,127,4294836736,2,28,33024,120,68,131074,655361,88,0,104,2,131073,88,0,1415936325,1668436847,1716475477,1952805734,2880154368,196609,131073,1,0,1415936325,1668436847,1666405973,6646881,845116278,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147614720,2416902145,33554463,2147483653,2416902146,33554463,2147549189,2416902147,33554463,2147614725,2416902148,33554433,2147680256,2699296768,67108868,3758292992,2162425856,2430861314,2699296770,67108868,3758292993,2162425856,2430861315,2699296770,67108868,3758292994,2162425856,2430861316,2699296770,67108868,3222208512,2416181248,2689597441,2686779393,33554433,3758161923,2415919105,65535,}; -DWORD precompiledVertexShaderTimewarpSrc[293] = {4294836736,4456446,1111577667,28,215,4294836736,4,28,33024,208,108,1310722,5373956,124,0,140,262146,1179652,124,0,157,131074,655361,176,0,192,2,131073,176,0,1382381893,1952543855,1164865385,2868929646,196611,262148,1,0,1382381893,1952543855,1399746409,1953653108,1702446336,1918070612,1331058019,1702061670,2880110708,196609,131073,1,0,1415936325,1668436847,1666405973,6646881,845116278,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147549184,2416902145,33554463,2147614720,2416902146,33554463,2147483653,2416902147,33554463,2147549189,2416902148,33554463,2147614725,2416902149,33554433,2147549184,2695495684,50331650,2147549185,2164260864,2695495700,33554433,2147614720,2695495685,50331650,2147614721,2169831424,2695495701,33554433,2147745792,2695495686,50331650,2147745793,2175401984,2695495702,33554433,2148007936,2695495687,50331650,2148007937,2180972544,2695495703,67108868,2148466688,2415919105,2162425857,2162425856,67108868,2148466689,2416181251,2689597441,2684682241,50331657,2147549186,2162425856,2162425857,33554438,2147549186,2147483650,33554433,2147680259,2699296772,50331650,2147876866,2177892355,2697986068,67108868,2147549187,2415919105,2158624770,2689925124,67108868,2147549188,2415919105,2153054210,2684354564,33554433,2147680261,2699296773,50331650,2147876866,2177105925,2697199637,67108868,2147614723,2415919105,2153054210,2689925125,67108868,2147614724,2415919105,2158624770,2684354565,33554433,2147680261,2699296774,50331650,2147811333,2177171461,2697265174,67108868,2147745795,2415919105,2147483653,2689925126,67108868,2147745796,2415919105,2158624773,2684354566,33554433,2147680261,2699296775,50331650,2148073477,2166685701,2686779415,67108868,2148007939,2415919105,2147483653,2689925127,67108868,2148007940,2415919105,2164195333,2684354567,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331653,2147680257,2147483650,2162425861,33554433,2147680258,2699296768,67108868,3758292992,2162425858,2162425857,2699296770,67108868,2148466689,2416181252,2689597441,2684682241,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331657,2147549185,2162425856,2162425857,33554438,2147549185,2147483649,50331653,2147680257,2147483649,2162425861,67108868,3758292993,2162425858,2162425857,2699296770,67108868,2148466689,2416181253,2689597441,2684682241,50331657,2147549188,2162425860,2162425857,50331657,2147614724,2162425859,2162425857,50331657,2147549184,2162425856,2162425857,33554438,2147549184,2147483648,50331653,2147680256,2147483648,2162425860,67108868,3758292994,2162425858,2162425856,2699296770,67108868,3222208512,2416181248,2689597441,2686779393,33554433,3758161923,2415919106,65535,}; -DWORD precompiledPixelShaderSrc[84] = {4294902528,2228222,1111577667,28,79,4294902528,1,28,33024,72,48,3,131073,56,0,1954047316,6648437,786436,65537,1,0,861893488,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,83886161,2685337600,1065353216,0,0,0,33554463,2147483653,2416115712,33554463,2147549189,2416115713,33554463,2147614725,2416115714,33554463,2147680261,2415984643,33554463,2415919104,2685339648,50331714,2148466688,2430861312,2699298816,67108868,2148073472,2147483648,2690908160,2686779392,50331714,2148466689,2430861313,2699298816,33554433,2147614720,2153054209,50331714,2148466689,2430861314,2699298816,33554433,2147745792,2158624769,50331653,2148468736,2162425856,2415919107,65535,}; +DWORD precompiledVertexShaderSrc[96] = {4294836736,3080190,1111577667,28,130,4294836736,2,28,33024,123,68,131074,655361,88,0,104,2,131073,88,0,1415936325,1970230127,1432707954,1717981014,7628147,196609,131073,1,0,1415936325,1970230127,1432707954,1633899350,1979737452,1597136755,1766654000,1936683619,544499311,539578920,1280527432,1634226976,544367972,1886220099,1919249513,841890080,892939833,825437746,2868916529,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147614720,2416902145,33554463,2147483653,2416902146,33554463,2147549189,2416902147,33554463,2147614725,2416902148,33554433,2147680256,2699296768,67108868,3758292992,2162425856,2430861314,2699296770,67108868,3758292993,2162425856,2430861315,2699296770,67108868,3758292994,2162425856,2430861316,2699296770,67108868,3222208512,2416181248,2689597441,2686779393,33554433,3758161923,2415919105,65535,}; +DWORD precompiledVertexShaderTimewarpSrc[310] = {4294836992,4587518,1111577667,28,222,4294836992,4,28,33024,215,108,1310722,5373956,124,0,140,262146,1179652,124,0,157,131074,655361,180,0,196,2,131073,180,0,1382381893,1952543855,1164865385,2868929646,196611,262148,1,0,1382381893,1952543855,1399746409,1953653108,1702446336,1867738964,1701016181,1716475477,1952805734,2880154368,196609,131073,1,0,1415936325,1970230127,1432707954,1633899350,1979737452,1597202291,1766654000,1936683619,544499311,539578920,1280527432,1634226976,544367972,1886220099,1919249513,841890080,892939833,825437746,2868916529,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147549184,2416902145,33554463,2147614720,2416902146,33554463,2147483653,2416902147,33554463,2147549189,2416902148,33554463,2147614725,2416902149,33554463,2147483648,3759079424,33554463,2147483653,3758292993,33554463,2147549189,3758292994,33554463,2147614725,3758292995,33554463,2147680261,3758161924,33554433,2147549184,2695495684,50331650,2147549185,2164260864,2695495700,33554433,2147614720,2695495685,50331650,2147614721,2169831424,2695495701,33554433,2147745792,2695495686,50331650,2147745793,2175401984,2695495702,33554433,2148007936,2695495687,50331650,2148007937,2180972544,2695495703,67108868,2148466688,2415919105,2162425857,2162425856,67108868,2148466689,2416181251,2689597441,2684682241,50331657,2147549186,2162425856,2162425857,33554438,2147549186,2147483650,33554433,2147680259,2699296772,50331650,2147876866,2177892355,2697986068,67108868,2147549187,2415919105,2158624770,2689925124,67108868,2147549188,2415919105,2153054210,2684354564,33554433,2147680261,2699296773,50331650,2147876866,2177105925,2697199637,67108868,2147614723,2415919105,2153054210,2689925125,67108868,2147614724,2415919105,2158624770,2684354565,33554433,2147680261,2699296774,50331650,2147811333,2177171461,2697265174,67108868,2147745795,2415919105,2147483653,2689925126,67108868,2147745796,2415919105,2158624773,2684354566,33554433,2147680261,2699296775,50331650,2148073477,2166685701,2686779415,67108868,2148007939,2415919105,2147483653,2689925127,67108868,2148007940,2415919105,2164195333,2684354567,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331653,2147680257,2147483650,2162425861,33554433,2147680258,2699296768,67108868,3758292993,2162425858,2162425857,2699296770,67108868,2148466689,2416181252,2689597441,2684682241,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331657,2147549185,2162425856,2162425857,33554438,2147549185,2147483649,50331653,2147680257,2147483649,2162425861,67108868,3758292994,2162425858,2162425857,2699296770,67108868,2148466689,2416181253,2689597441,2684682241,50331657,2147549188,2162425860,2162425857,50331657,2147614724,2162425859,2162425857,50331657,2147549184,2162425856,2162425857,33554438,2147549184,2147483648,50331653,2147680256,2147483648,2162425860,67108868,3758292995,2162425858,2162425856,2699296770,67108868,3759079424,2416181248,2689597441,2686779393,33554433,3758161924,2415919106,65535,}; +DWORD precompiledPixelShaderSrc[84] = {4294902528,2228222,1111577667,28,79,4294902528,1,28,33024,72,48,3,131073,56,0,1954047316,6648437,786436,65537,1,0,861893488,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,83886161,2685337600,1065353216,0,0,0,33554463,2147483653,2416115712,33554463,2147549189,2416115713,33554463,2147614725,2416115714,33554463,2147680261,2415984643,33554463,2415919104,2685339648,50331714,2148466688,2430861312,2699298816,67108868,2148073472,2147483648,2690908160,2686779392,50331714,2148466689,2430861313,2699298816,33554433,2147614720,2153054209,50331714,2148466689,2430861314,2699298816,33554433,2147745792,2158624769,50331653,2148468736,2162425856,2415919107,65535,}; #else #include "d3dcompiler.h" +#pragma comment(lib, "C:\\Program Files (x86)\\Microsoft DirectX SDK (June 2010)\\Lib\\x86\\D3DCompiler.lib") /***************************************************************************/ const char* VertexShaderSrc = @@ -146,7 +147,7 @@ void DistortionRenderer::CreateDistortionShaders(void) device->CreateVertexShader( ( DWORD* )pShaderCode->GetBufferPointer(), &vertexShader ); pShaderCode->Release(); - pShaderCode = ShaderCompile("precompiledVertexShaderTimewarpSrc",VertexShaderTimewarpSrc,"vs_2_0"); + pShaderCode = ShaderCompile("precompiledVertexShaderTimewarpSrc",VertexShaderTimewarpSrc,"vs_3_0"); device->CreateVertexShader( ( DWORD* )pShaderCode->GetBufferPointer(), &vertexShaderTimewarp ); pShaderCode->Release(); @@ -197,11 +198,13 @@ void DistortionRenderer::Create_Distortion_Models(void) D3DPOOL_MANAGED, &e->dxVerts, NULL ); ovrDistortionVertex * dxv; e->dxVerts->Lock( 0, 0, (void**)&dxv, 0 ); for (int v=0;v<e->numVerts;v++) dxv[v] = meshData.pVertexData[v]; + e->dxVerts->Unlock(); device->CreateIndexBuffer( (e->numIndices)*sizeof(u_short),0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &e->dxIndices, NULL ); unsigned short* dxi; e->dxIndices->Lock( 0, 0, (void**)&dxi, 0 ); for (int i=0;i<e->numIndices;i++) dxi[i] = meshData.pIndexData[i]; + e->dxIndices->Unlock(); ovrHmd_DestroyDistortionMesh( &meshData ); } @@ -210,10 +213,21 @@ void DistortionRenderer::Create_Distortion_Models(void) /**********************************************************/ void DistortionRenderer::RenderBothDistortionMeshes(void) { + device->BeginScene(); + + D3DCOLOR clearColor = D3DCOLOR_RGBA( + (int)(RState.ClearColor[0] * 255.0f), + (int)(RState.ClearColor[1] * 255.0f), + (int)(RState.ClearColor[2] * 255.0f), + (int)(RState.ClearColor[3] * 255.0f)); + + device->Clear(1, NULL, D3DCLEAR_TARGET, clearColor, 0, 0); + for (int eye=0; eye<2; eye++) { FOR_EACH_EYE * e = &eachEye[eye]; D3DVIEWPORT9 vp; vp.X=0; vp.Y=0; vp.Width=screenSize.w; vp.Height=screenSize.h; vp.MinZ=0; vp.MaxZ = 1; + device->SetViewport(&vp); device->SetStreamSource( 0, e->dxVerts,0, sizeof(ovrDistortionVertex) ); device->SetVertexDeclaration( vertexDecl ); @@ -249,6 +263,8 @@ void DistortionRenderer::RenderBothDistortionMeshes(void) device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0,0,e->numVerts,0,e->numIndices/3); } + + device->EndScene(); } }}}
\ No newline at end of file |