diff options
Diffstat (limited to 'Samples/CommonSrc/Render/Render_D3D1X_Device.cpp')
-rw-r--r-- | Samples/CommonSrc/Render/Render_D3D1X_Device.cpp | 710 |
1 files changed, 513 insertions, 197 deletions
diff --git a/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp b/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp index 6408e08..d7c606f 100644 --- a/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp +++ b/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp @@ -21,13 +21,20 @@ limitations under the License. ************************************************************************************/ +#define GPU_PROFILING 0 + #include "Kernel/OVR_Log.h" #include "Kernel/OVR_Std.h" #include "Render_D3D1X_Device.h" +#include "Util/Util_ImageWindow.h" + +#include "OVR_CAPI_D3D.h" #include <d3dcompiler.h> +#include <d3d9.h> // for GPU markers + #if (OVR_D3D_VERSION == 10) namespace OVR { namespace Render { namespace D3D10 { #else @@ -43,7 +50,6 @@ static D3D1x_(INPUT_ELEMENT_DESC) ModelVertexDesc[] = {"Normal", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, Norm), D3D1x_(INPUT_PER_VERTEX_DATA), 0}, }; - static const char* StdVertexShaderSrc = "float4x4 Proj;\n" "float4x4 View;\n" @@ -135,13 +141,18 @@ static const char* MultiTexturePixelShaderSrc = "{\n" "float4 color1;\n" "float4 color2;\n" - " color1 = Texture[0].Sample(Linear, ov.TexCoord);\n" + " color1 = Texture[0].Sample(Linear, ov.TexCoord);\n" + // go to linear space colors (assume gamma 2.0 for speed) + " color1.rgb *= color1.rgb;\n" " color2 = Texture[1].Sample(Linear, ov.TexCoord1);\n" + // go to linear space colors (assume gamma 2.0 for speed) + " color2.rgb *= color2.rgb;\n" " color2.rgb = color2.rgb * lerp(1.2, 1.9, saturate(length(color2.rgb)));\n" " color2 = color1 * color2;\n" " if (color2.a <= 0.4)\n" " discard;\n" - " return color2;\n" + // go to back to gamma space space colors (assume gamma 2.0 for speed) + " return float4(sqrt(color2.rgb), color2.a);\n" "}\n"; #define LIGHTING_COMMON \ @@ -201,7 +212,9 @@ static const char* AlphaTexturePixelShaderSrc = "};\n" "float4 main(in Varyings ov) : SV_Target\n" "{\n" - " return ov.Color * float4(1,1,1,Texture.Sample(Linear, ov.TexCoord).r);\n" + " float4 finalColor = ov.Color;\n" + " finalColor.a *= Texture.Sample(Linear, ov.TexCoord).r;\n" + " return finalColor;\n" "}\n"; @@ -211,97 +224,294 @@ static const char* PostProcessVertexShaderSrc = "float4x4 View : register(c4);\n" "float4x4 Texm : register(c8);\n" "void main(in float4 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1,\n" - " out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float2 oTexCoord : TEXCOORD0)\n" + " out float4 oPosition : SV_Position, out float2 oTexCoord : TEXCOORD0)\n" "{\n" " oPosition = mul(View, Position);\n" " oTexCoord = mul(Texm, float4(TexCoord,0,1));\n" - " oColor = Color;\n" "}\n"; -// Shader with just lens distortion correction. -static const char* PostProcessPixelShaderSrc = + +// Shader with lens distortion and chromatic aberration correction. +static const char* PostProcessPixelShaderWithChromAbSrc = "Texture2D Texture : register(t0);\n" "SamplerState Linear : register(s0);\n" - "float2 LensCenter;\n" - "float2 ScreenCenter;\n" - "float2 Scale;\n" - "float2 ScaleIn;\n" + "float3 DistortionClearColor;\n" + "float EdgeFadeScale;\n" + "float2 EyeToSourceUVScale;\n" + "float2 EyeToSourceUVOffset;\n" + "float2 EyeToSourceNDCScale;\n" + "float2 EyeToSourceNDCOffset;\n" + "float2 TanEyeAngleScale;\n" + "float2 TanEyeAngleOffset;\n" "float4 HmdWarpParam;\n" + "float4 ChromAbParam;\n" "\n" - // Scales input texture coordinates for distortion. - // ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be - // larger due to aspect ratio. - "float2 HmdWarp(float2 in01)\n" + "float4 main(in float4 oPosition : SV_Position,\n" + " in float2 oTexCoord : TEXCOORD0) : SV_Target\n" "{\n" - " float2 theta = (in01 - LensCenter) * ScaleIn;\n" // Scales to [-1, 1] - " float rSq = theta.x * theta.x + theta.y * theta.y;\n" - " float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + " - " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n" - " return LensCenter + Scale * theta1;\n" - "}\n" + // Input oTexCoord is [-1,1] across the half of the screen used for a single eye. + " float2 TanEyeAngleDistorted = oTexCoord * TanEyeAngleScale + TanEyeAngleOffset;\n" // Scales to tan(thetaX),tan(thetaY), but still distorted (i.e. only the center is correct) + " float RadiusSq = TanEyeAngleDistorted.x * TanEyeAngleDistorted.x + TanEyeAngleDistorted.y * TanEyeAngleDistorted.y;\n" + " float Distort = rcp ( 1.0 + RadiusSq * ( HmdWarpParam.y + RadiusSq * ( HmdWarpParam.z + RadiusSq * ( HmdWarpParam.w ) ) ) );\n" + " float DistortR = Distort * ( ChromAbParam.x + RadiusSq * ChromAbParam.y );\n" + " float DistortG = Distort;\n" + " float DistortB = Distort * ( ChromAbParam.z + RadiusSq * ChromAbParam.w );\n" + " float2 TanEyeAngleR = DistortR * TanEyeAngleDistorted;\n" + " float2 TanEyeAngleG = DistortG * TanEyeAngleDistorted;\n" + " float2 TanEyeAngleB = DistortB * TanEyeAngleDistorted;\n" + + // These are now in "TanEyeAngle" space. + // The vectors (TanEyeAngleRGB.x, TanEyeAngleRGB.y, 1.0) are real-world vectors pointing from the eye to where the components of the pixel appear to be. + // If you had a raytracer, you could just use them directly. + + // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) + " float2 SourceCoordR = TanEyeAngleR * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " float2 SourceCoordG = TanEyeAngleG * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " float2 SourceCoordB = TanEyeAngleB * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + + // Find the distance to the nearest edge. + " float2 NDCCoord = TanEyeAngleG * EyeToSourceNDCScale + EyeToSourceNDCOffset;\n" + " float EdgeFadeIn = EdgeFadeScale * ( 1.0 - max ( abs ( NDCCoord.x ), abs ( NDCCoord.y ) ) );\n" + " if ( EdgeFadeIn < 0.0 )\n" + " {\n" + " return float4(DistortionClearColor.r, DistortionClearColor.g, DistortionClearColor.b, 1.0);\n" + " }\n" + " EdgeFadeIn = saturate ( EdgeFadeIn );\n" + + // Actually do the lookups. + " float ResultR = Texture.Sample(Linear, SourceCoordR).r;\n" + " float ResultG = Texture.Sample(Linear, SourceCoordG).g;\n" + " float ResultB = Texture.Sample(Linear, SourceCoordB).b;\n" + + " return float4(ResultR * EdgeFadeIn, ResultG * EdgeFadeIn, ResultB * EdgeFadeIn, 1.0);\n" + "}\n"; + +//---------------------------------------------------------------------------- + +// A vertex format used for mesh-based distortion. +/* +struct DistortionVertex +{ + Vector2f Pos; + Vector2f TexR; + Vector2f TexG; + Vector2f TexB; + Color Col; +}; +*/ +static D3D1x_(INPUT_ELEMENT_DESC) DistortionVertexDesc[] = +{ + {"Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D1x_(INPUT_PER_VERTEX_DATA), 0}, + {"TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D1x_(INPUT_PER_VERTEX_DATA), 0}, + {"TexCoord", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 8+8, D3D1x_(INPUT_PER_VERTEX_DATA), 0}, + {"TexCoord", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 8+8+8, D3D1x_(INPUT_PER_VERTEX_DATA), 0}, + {"Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 8+8+8+8, D3D1x_(INPUT_PER_VERTEX_DATA), 0}, +}; + + +//---------------------------------------------------------------------------- +// Simple distortion shader that does three texture reads. +// Used for mesh-based distortion without timewarp. + +static const char* PostProcessMeshVertexShaderSrc = + "float2 EyeToSourceUVScale;\n" + "float2 EyeToSourceUVOffset;\n" + "void main(in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2,\n" + " out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float2 oTexCoord0 : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2)\n" + "{\n" + " oPosition.x = Position.x;\n" + " oPosition.y = Position.y;\n" + " oPosition.z = 0.5;\n" + " oPosition.w = 1.0;\n" + // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). + // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) + " oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oColor = Color;\n" // Used for vignette fade. + "}\n"; + +static const char* PostProcessMeshPixelShaderSrc = + "Texture2D Texture : register(t0);\n" + "SamplerState Linear : register(s0);\n" + "\n" "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n" - " in float2 oTexCoord : TEXCOORD0) : SV_Target\n" + " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2) : SV_Target\n" "{\n" - " float2 tc = HmdWarp(oTexCoord);\n" - " if (any(clamp(tc, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tc))\n" - " return 0;\n" - " return Texture.Sample(Linear, tc);\n" + " float ResultR = Texture.Sample(Linear, oTexCoord0).r;\n" + " float ResultG = Texture.Sample(Linear, oTexCoord1).g;\n" + " float ResultB = Texture.Sample(Linear, oTexCoord2).b;\n" + " return float4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n" "}\n"; -// Shader with lens distortion and chromatic aberration correction. -static const char* PostProcessPixelShaderWithChromAbSrc = + +//---------------------------------------------------------------------------- +// Pixel shader is very simple - does three texture reads. +// Vertex shader does all the hard work. +// Used for mesh-based distortion with timewarp. + +static const char* PostProcessMeshTimewarpVertexShaderSrc = + "float2 EyeToSourceUVScale;\n" + "float2 EyeToSourceUVOffset;\n" + "float3x3 EyeRotationStart;\n" + "float3x3 EyeRotationEnd;\n" + "void main(in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2,\n" + " out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float2 oTexCoord0 : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2)\n" + "{\n" + " oPosition.x = Position.x;\n" + " oPosition.y = Position.y;\n" + " oPosition.z = 0.5;\n" + " oPosition.w = 1.0;\n" + + // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). + // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. + " float3 TanEyeAngleR = float3 ( TexCoord0.x, TexCoord0.y, 1.0 );\n" + " float3 TanEyeAngleG = float3 ( TexCoord1.x, TexCoord1.y, 1.0 );\n" + " float3 TanEyeAngleB = float3 ( TexCoord2.x, TexCoord2.y, 1.0 );\n" + + // Accurate time warp lerp vs. faster +#if 1 + // Apply the two 3x3 timewarp rotations to these vectors. + " float3 TransformedRStart = mul ( TanEyeAngleR, EyeRotationStart );\n" + " float3 TransformedGStart = mul ( TanEyeAngleG, EyeRotationStart );\n" + " float3 TransformedBStart = mul ( TanEyeAngleB, EyeRotationStart );\n" + " float3 TransformedREnd = mul ( TanEyeAngleR, EyeRotationEnd );\n" + " float3 TransformedGEnd = mul ( TanEyeAngleG, EyeRotationEnd );\n" + " float3 TransformedBEnd = mul ( TanEyeAngleB, EyeRotationEnd );\n" + // And blend between them. + " float3 TransformedR = lerp ( TransformedRStart, TransformedREnd, Color.a );\n" + " float3 TransformedG = lerp ( TransformedGStart, TransformedGEnd, Color.a );\n" + " float3 TransformedB = lerp ( TransformedBStart, TransformedBEnd, Color.a );\n" +#else + " float3x3 EyeRotation = lerp ( EyeRotationStart, EyeRotationEnd, Color.a );\n" + " float3 TransformedR = mul ( TanEyeAngleR, EyeRotation );\n" + " float3 TransformedG = mul ( TanEyeAngleG, EyeRotation );\n" + " float3 TransformedB = mul ( TanEyeAngleB, EyeRotation );\n" +#endif + + // Project them back onto the Z=1 plane of the rendered images. + " float RecipZR = rcp ( TransformedR.z );\n" + " float RecipZG = rcp ( TransformedG.z );\n" + " float RecipZB = rcp ( TransformedB.z );\n" + " float2 FlattenedR = float2 ( TransformedR.x * RecipZR, TransformedR.y * RecipZR );\n" + " float2 FlattenedG = float2 ( TransformedG.x * RecipZG, TransformedG.y * RecipZG );\n" + " float2 FlattenedB = float2 ( TransformedB.x * RecipZB, TransformedB.y * RecipZB );\n" + + // These are now still in TanEyeAngle space. + // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) + " float2 SrcCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " float2 SrcCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " float2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord0 = SrcCoordR;\n" + " oTexCoord1 = SrcCoordG;\n" + " oTexCoord2 = SrcCoordB;\n" + " oColor = Color.r;\n" // Used for vignette fade. + "}\n"; + +static const char* PostProcessMeshTimewarpPixelShaderSrc = "Texture2D Texture : register(t0);\n" "SamplerState Linear : register(s0);\n" - "float2 LensCenter;\n" - "float2 ScreenCenter;\n" - "float2 Scale;\n" - "float2 ScaleIn;\n" - "float4 HmdWarpParam;\n" - "float4 ChromAbParam;\n" "\n" + "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n" + " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2) : SV_Target\n" + "{\n" + " float ResultR = Texture.Sample(Linear, oTexCoord0).r;\n" + " float ResultG = Texture.Sample(Linear, oTexCoord1).g;\n" + " float ResultB = Texture.Sample(Linear, oTexCoord2).b;\n" + " return float4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n" + "}\n"; - // Scales input texture coordinates for distortion. - // ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be - // larger due to aspect ratio. +//---------------------------------------------------------------------------- +// Pixel shader is very simple - does three texture reads. +// Vertex shader does all the hard work. +// Used for mesh-based distortion with positional timewarp. + +static const char* PostProcessMeshPositionalTimewarpVertexShaderSrc = + "Texture2DMS<float,4> DepthTexture : register(t0);\n" + // Padding because we are uploading "standard uniform buffer" constants + "float4x4 Padding1;\n" + "float4x4 Padding2;\n" + "float2 EyeToSourceUVScale;\n" + "float2 EyeToSourceUVOffset;\n" + "float2 DepthProjector;\n" + "float2 DepthDimSize;\n" + "float4x4 EyeRotationStart;\n" + "float4x4 EyeRotationEnd;\n" + + "float4 PositionFromDepth(float2 inTexCoord)\n" + "{\n" + " float2 eyeToSourceTexCoord = inTexCoord * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " float depth = DepthTexture.Load(int2(eyeToSourceTexCoord * DepthDimSize), 0).x;\n" + " float linearDepth = DepthProjector.y / (depth - DepthProjector.x);\n" + " float4 retVal = float4(inTexCoord, 1, 1);\n" + " retVal.xyz *= linearDepth;\n" + " return retVal;\n" + "}\n" + + "float2 TimewarpTexCoordToWarpedPos(float2 inTexCoord, float4x4 rotMat)\n" + "{\n" + // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). + // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. + // Apply the 4x4 timewarp rotation to these vectors. + " float4 inputPos = PositionFromDepth(inTexCoord);\n" + " float3 transformed = float3( mul ( rotMat, inputPos ).xyz);\n" + // Project them back onto the Z=1 plane of the rendered images. + " float2 flattened = transformed.xy / transformed.z;\n" + // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) + " float2 noDepthUV = flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + //" float depth = DepthTexture.SampleLevel(Linear, noDepthUV, 0).r;\n" + " return noDepthUV.xy;\n" + "}\n" + + "void main( in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0,\n" + " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2,\n" + " out float4 oPosition : SV_Position, out float4 oColor : COLOR,\n" + " out float2 oTexCoord0 : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2)\n" + "{\n" + " oPosition.x = Position.x;\n" + " oPosition.y = Position.y;\n" + " oPosition.z = 0.5;\n" + " oPosition.w = 1.0;\n" + + " float timewarpLerpFactor = Color.a;\n" + " float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, timewarpLerpFactor);\n" + //" float4x4 lerpedEyeRot = EyeRotationStart;\n" + + // warped positions are a bit more involved, hence a separate function + " oTexCoord0 = TimewarpTexCoordToWarpedPos(TexCoord0, lerpedEyeRot);\n" + " oTexCoord1 = TimewarpTexCoordToWarpedPos(TexCoord1, lerpedEyeRot);\n" + " oTexCoord2 = TimewarpTexCoordToWarpedPos(TexCoord2, lerpedEyeRot);\n" + + " oColor = Color.r; // Used for vignette fade.\n" + "}\n"; + +static const char* PostProcessMeshPositionalTimewarpPixelShaderSrc = + "Texture2D Texture : register(t0);\n" + "SamplerState Linear : register(s0);\n" + "float2 DepthDimSize;\n" + "\n" "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n" - " in float2 oTexCoord : TEXCOORD0) : SV_Target\n" + " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2) : SV_Target\n" "{\n" - " float2 theta = (oTexCoord - LensCenter) * ScaleIn;\n" // Scales to [-1, 1] - " float rSq = theta.x * theta.x + theta.y * theta.y;\n" - " float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + " - " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n" - " \n" - " // Detect whether blue texture coordinates are out of range since these will scaled out the furthest.\n" - " float2 thetaBlue = theta1 * (ChromAbParam.z + ChromAbParam.w * rSq);\n" - " float2 tcBlue = LensCenter + Scale * thetaBlue;\n" - " if (any(clamp(tcBlue, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tcBlue))\n" - " return 0;\n" - " \n" - " // Now do blue texture lookup.\n" - " float blue = Texture.Sample(Linear, tcBlue).b;\n" - " \n" - " // Do green lookup (no scaling).\n" - " float2 tcGreen = LensCenter + Scale * theta1;\n" - " float4 greenColor = Texture.Sample(Linear, tcGreen);\n" - " float green = greenColor.g;\n" - " float alpha = greenColor.a;\n" - " \n" - " // Do red scale and lookup.\n" - " float2 thetaRed = theta1 * (ChromAbParam.x + ChromAbParam.y * rSq);\n" - " float2 tcRed = LensCenter + Scale * thetaRed;\n" - " float red = Texture.Sample(Linear, tcRed).r;\n" - " \n" - " return float4(red, green, blue, alpha);\n" + " float3 result;\n" + " result.r = Texture.Sample(Linear, oTexCoord0).r;\n" + " result.g = Texture.Sample(Linear, oTexCoord1).g;\n" + " result.b = Texture.Sample(Linear, oTexCoord2).b;\n" + " return float4(result * oColor, 1.0);\n" "}\n"; +//---------------------------------------------------------------------------- static const char* VShaderSrcs[VShader_Count] = { DirectVertexShaderSrc, StdVertexShaderSrc, - PostProcessVertexShaderSrc + PostProcessVertexShaderSrc, + PostProcessMeshVertexShaderSrc, + PostProcessMeshTimewarpVertexShaderSrc, + PostProcessMeshPositionalTimewarpVertexShaderSrc }; static const char* FShaderSrcs[FShader_Count] = { @@ -309,11 +519,13 @@ static const char* FShaderSrcs[FShader_Count] = GouraudPixelShaderSrc, TexturePixelShaderSrc, AlphaTexturePixelShaderSrc, - PostProcessPixelShaderSrc, PostProcessPixelShaderWithChromAbSrc, LitSolidPixelShaderSrc, LitTexturePixelShaderSrc, - MultiTexturePixelShaderSrc + MultiTexturePixelShaderSrc, + PostProcessMeshPixelShaderSrc, + PostProcessMeshTimewarpPixelShaderSrc, + PostProcessMeshPositionalTimewarpPixelShaderSrc }; RenderDevice::RenderDevice(const RendererParams& p, HWND window) @@ -322,8 +534,8 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) GetClientRect(window, &rc); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; - WindowWidth = width; - WindowHeight = height; + ::OVR::Render::RenderDevice::SetWindowSize(width, height); + Window = window; Params = p; @@ -359,17 +571,18 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) UpdateMonitorOutputs(); } - int flags = 0; + int flags = D3D10_CREATE_DEVICE_BGRA_SUPPORT; //0; #if (OVR_D3D_VERSION == 10) - hr = D3D10CreateDevice(Adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D1x_(SDK_VERSION), + hr = D3D10CreateDevice1(Adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D10_FEATURE_LEVEL_10_1, D3D10_1_SDK_VERSION, &Device.GetRawRef()); Context = Device; Context->AddRef(); #else //11 + D3D_FEATURE_LEVEL featureLevel; // TODO: Limit certain features based on D3D feature level hr = D3D11CreateDevice(Adapter, Adapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, NULL, flags, NULL, 0, D3D1x_(SDK_VERSION), - &Device.GetRawRef(), NULL, &Context.GetRawRef()); + &Device.GetRawRef(), &featureLevel, &Context.GetRawRef()); #endif if (FAILED(hr)) return; @@ -387,25 +600,43 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) MaxTextureSet[i] = 0; } - ID3D10Blob* vsData = CompileShader("vs_4_0", DirectVertexShaderSrc); + ID3D10Blob* vsData = CompileShader("vs_4_1", DirectVertexShaderSrc); VertexShaders[VShader_MV] = *new VertexShader(this, vsData); for(int i = 1; i < VShader_Count; i++) { - VertexShaders[i] = *new VertexShader(this, CompileShader("vs_4_0", VShaderSrcs[i])); + OVR_ASSERT ( VShaderSrcs[i] != NULL ); // You forgot a shader! + ID3D10Blob *pShader = CompileShader("vs_4_1", VShaderSrcs[i]); + VertexShaders[i] = NULL; + if ( pShader != NULL ) + { + VertexShaders[i] = *new VertexShader(this, pShader); + } } for(int i = 0; i < FShader_Count; i++) { - PixelShaders[i] = *new PixelShader(this, CompileShader("ps_4_0", FShaderSrcs[i])); + OVR_ASSERT ( FShaderSrcs[i] != NULL ); // You forgot a shader! + ID3D10Blob *pShader = CompileShader("ps_4_1", FShaderSrcs[i]); + PixelShaders[i] = NULL; + if ( pShader != NULL ) + { + PixelShaders[i] = *new PixelShader(this, pShader); + } } SPInt bufferSize = vsData->GetBufferSize(); const void* buffer = vsData->GetBufferPointer(); ID3D1xInputLayout** objRef = &ModelVertexIL.GetRawRef(); - - HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, 5, buffer, bufferSize, objRef); + HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, sizeof(ModelVertexDesc)/sizeof(ModelVertexDesc[0]), buffer, bufferSize, objRef); OVR_UNUSED(validate); + ID3D10Blob* vsData2 = CompileShader("vs_4_1", PostProcessMeshVertexShaderSrc); + SPInt bufferSize2 = vsData2->GetBufferSize(); + const void* buffer2 = vsData2->GetBufferPointer(); + ID3D1xInputLayout** objRef2 = &DistortionVertexIL.GetRawRef(); + HRESULT validate2 = Device->CreateInputLayout(DistortionVertexDesc, sizeof(DistortionVertexDesc)/sizeof(DistortionVertexDesc[0]), buffer2, bufferSize2, objRef2); + OVR_UNUSED(validate2); + Ptr<ShaderSet> gouraudShaders = *new ShaderSet(); gouraudShaders->SetShader(VertexShaders[VShader_MVP]); gouraudShaders->SetShader(PixelShaders[FShader_Gouraud]); @@ -433,7 +664,7 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) D3D1x_(RASTERIZER_DESC) rs; memset(&rs, 0, sizeof(rs)); - rs.AntialiasedLineEnable = true; + rs.AntialiasedLineEnable = false; // You can't just turn this on - it needs alpha modes etc setting up and doesn't work with Z buffers. rs.CullMode = D3D1x_(CULL_BACK); // rs.CullMode = D3D1x_(CULL_NONE); rs.DepthClipEnable = true; @@ -568,10 +799,11 @@ bool RenderDevice::RecreateSwapChain() DXGI_SWAP_CHAIN_DESC scDesc; memset(&scDesc, 0, sizeof(scDesc)); scDesc.BufferCount = 1; - scDesc.BufferDesc.Width = WindowWidth; + scDesc.BufferDesc.Width = WindowWidth; scDesc.BufferDesc.Height = WindowHeight; scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - scDesc.BufferDesc.RefreshRate.Numerator = 60; + // Use default refresh rate; switching rate on CC prototype can cause screen lockup. + scDesc.BufferDesc.RefreshRate.Numerator = 0; scDesc.BufferDesc.RefreshRate.Denominator = 1; scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scDesc.OutputWindow = Window; @@ -621,18 +853,60 @@ bool RenderDevice::SetParams(const RendererParams& newParams) UpdateMonitorOutputs(true); } - // Cause this to be recreated with the new multisample mode. - pSceneColorTex = NULL; return RecreateSwapChain(); } + +ovrRenderAPIConfig RenderDevice::Get_ovrRenderAPIConfig() const +{ +#if (OVR_D3D_VERSION == 10) + static ovrD3D10Config cfg; + cfg.D3D10.Header.API = ovrRenderAPI_D3D10; + cfg.D3D10.Header.RTSize = Sizei(WindowWidth, WindowHeight); + cfg.D3D10.Header.Multisample = Params.Multisample; + cfg.D3D10.pDevice = Device; + cfg.D3D10.pBackBufferRT = BackBufferRT; + cfg.D3D10.pSwapChain = SwapChain; +#else + static ovrD3D11Config cfg; + cfg.D3D11.Header.API = ovrRenderAPI_D3D11; + cfg.D3D11.Header.RTSize = Sizei(WindowWidth, WindowHeight); + cfg.D3D11.Header.Multisample = Params.Multisample; + cfg.D3D11.pDevice = Device; + cfg.D3D11.pDeviceContext = Context; + cfg.D3D11.pBackBufferRT = BackBufferRT; + cfg.D3D11.pSwapChain = SwapChain; +#endif + return cfg.Config; +} + +ovrTexture Texture::Get_ovrTexture() +{ + ovrTexture tex; + + OVR::Sizei newRTSize(Width, Height); + +#if (OVR_D3D_VERSION == 10) + ovrD3D10TextureData* texData = (ovrD3D10TextureData*)&tex; + texData->Header.API = ovrRenderAPI_D3D10; +#else + ovrD3D11TextureData* texData = (ovrD3D11TextureData*)&tex; + texData->Header.API = ovrRenderAPI_D3D11; +#endif + texData->Header.TextureSize = newRTSize; + texData->Header.RenderViewport = Recti(newRTSize); + texData->pTexture = Tex; + texData->pSRView = TexSv; + + return tex; +} void RenderDevice::SetWindowSize(int w, int h) { if (w == WindowWidth && h == WindowHeight) return; - WindowWidth = w; - WindowHeight = h; + ::OVR::Render::RenderDevice::SetWindowSize(w, h); + Context->OMSetRenderTargets(0, NULL, NULL); BackBuffer = NULL; BackBufferRT = NULL; @@ -698,32 +972,24 @@ bool RenderDevice::SetFullscreen(DisplayMode fullscreen) return true; } -void RenderDevice::SetMultipleViewports(int n, const Viewport* vps) +void RenderDevice::SetViewport(const Recti& vp) { - if (n > 2) - { - n = 2; - } - for(int i = 0; i < n; i++) - { #if (OVR_D3D_VERSION == 10) - Viewports[i].Width = vps[i].w; - Viewports[i].Height = vps[i].h; - Viewports[i].MinDepth = 0; - Viewports[i].MaxDepth = 1; - Viewports[i].TopLeftX = vps[i].x; - Viewports[i].TopLeftY = vps[i].y; + D3DViewport.Width = vp.w; + D3DViewport.Height = vp.h; + D3DViewport.MinDepth = 0; + D3DViewport.MaxDepth = 1; + D3DViewport.TopLeftX = vp.x; + D3DViewport.TopLeftY = vp.y; #else - Viewports[i].Width = (float)vps[i].w; - Viewports[i].Height = (float)vps[i].h; - Viewports[i].MinDepth = 0; - Viewports[i].MaxDepth = 1; - Viewports[i].TopLeftX = (float)vps[i].x; - Viewports[i].TopLeftY = (float)vps[i].y; + D3DViewport.Width = (float)vp.w; + D3DViewport.Height = (float)vp.h; + D3DViewport.MinDepth = 0; + D3DViewport.MaxDepth = 1; + D3DViewport.TopLeftX = (float)vp.x; + D3DViewport.TopLeftY = (float)vp.y; #endif - } - NumViewports = n; - Context->RSSetViewports(n, Viewports); + Context->RSSetViewports(1,&D3DViewport); } static int GetDepthStateIndex(bool enable, bool write, RenderDevice::CompareFunc func) @@ -754,7 +1020,7 @@ void RenderDevice::SetDepthMode(bool enable, bool write, CompareFunc func) case Compare_Less: dss.DepthFunc = D3D1x_(COMPARISON_LESS); break; case Compare_Greater: dss.DepthFunc = D3D1x_(COMPARISON_GREATER); break; default: - assert(0); + OVR_ASSERT(0); } dss.DepthWriteMask = write ? D3D1x_(DEPTH_WRITE_MASK_ALL) : D3D1x_(DEPTH_WRITE_MASK_ZERO); Device->CreateDepthStencilState(&dss, &DepthStates[index].GetRawRef()); @@ -782,70 +1048,27 @@ Texture* RenderDevice::GetDepthBuffer(int w, int h, int ms) return newDepth.GetPtr(); } -void RenderDevice::Clear(float r, float g, float b, float a, float depth) +void RenderDevice::Clear(float r /*= 0*/, float g /*= 0*/, float b /*= 0*/, float a /*= 1*/, + float depth /*= 1*/, + bool clearColor /*= true*/, bool clearDepth /*= true*/) { - const float color[] = {r, g, b, a}; - - // save state that is affected by clearing this way - ID3D1xDepthStencilState* oldDepthState = CurDepthState; - StandardUniformData clearUniforms; - - SetDepthMode(true, true, Compare_Always); - - Context->IASetInputLayout(ModelVertexIL); -#if (OVR_D3D_VERSION == 10) - Context->GSSetShader(NULL); -#else - Context->GSSetShader(NULL, NULL, 0); -#endif - //Shader<Shader_Geometry,ID3D1xGeometryShader> NullGS(this,(ID3D1xGeometryShader*)NULL); - //NullGS.Set(Prim_TriangleStrip); - - ID3D1xShaderResourceView* sv[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - if (MaxTextureSet[Shader_Fragment]) - { - Context->PSSetShaderResources(0, MaxTextureSet[Shader_Fragment], sv); - } - - ID3D1xBuffer* vertexBuffer = QuadVertexBuffer->GetBuffer(); - UINT vertexStride = sizeof(Vertex); - UINT vertexOffset = 0; - Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset); - - clearUniforms.View = Matrix4f(2, 0, 0, 0, - 0, 2, 0, 0, - 0, 0, 0, 0, - -1, -1, depth, 1); - UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, &clearUniforms, sizeof(clearUniforms)); - - ID3D1xBuffer* vertexConstants = UniformBuffers[Shader_Vertex]->GetBuffer(); - Context->VSSetConstantBuffers(0, 1, &vertexConstants); - Context->IASetPrimitiveTopology(D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP)); - VertexShaders[VShader_MV]->Set(Prim_TriangleStrip); - PixelShaders[FShader_Solid]->Set(Prim_TriangleStrip); - - UniformBuffers[Shader_Pixel]->Data(Buffer_Uniform, color, sizeof(color)); - PixelShaders[FShader_Solid]->SetUniformBuffer(UniformBuffers[Shader_Pixel]); - - if (NumViewports > 1) + if ( clearColor ) { - for(int i = 0; i < NumViewports; i++) + const float color[] = {r, g, b, a}; + if ( CurRenderTarget == NULL ) + { + Context->ClearRenderTargetView ( BackBufferRT.GetRawRef(), color ); + } + else { - Context->RSSetViewports(1, &Viewports[i]); - Context->OMSetBlendState(NULL, NULL, 0xffffffff); - Context->Draw(4, 0); + Context->ClearRenderTargetView ( CurRenderTarget->TexRtv, color ); } - Context->RSSetViewports(NumViewports, Viewports); } - else + + if ( clearDepth ) { - Context->OMSetBlendState(NULL, NULL, 0xffffffff); - Context->Draw(4, 0); + Context->ClearDepthStencilView ( CurDepthBuffer->TexDsv, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, depth, 0 ); } - - // reset - CurDepthState = oldDepthState; - Context->OMSetDepthStencilState(CurDepthState, 0); } // Buffers @@ -1280,6 +1503,11 @@ Texture::Texture(RenderDevice* ren, int fmt, int w, int h) : Ren(ren), Tex(NULL) Sampler = Ren->GetSamplerState(0); } +void* Texture::GetInternalImplementation() +{ + return Tex; +} + Texture::~Texture() { } @@ -1312,6 +1540,10 @@ void RenderDevice::SetTexture(Render::ShaderStage stage, int slot, const Texture case Shader_Vertex: Context->VSSetShaderResources(slot, 1, &sv); + if (t) + { + Context->VSSetSamplers(slot, 1, &t->Sampler.GetRawRef()); + } break; } } @@ -1501,10 +1733,22 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo } else { + int samples = (format & Texture_SamplesMask); + if (samples < 1) + { + samples = 1; + } + + bool createDepthSrv = (format & Texture_SampleDepth) > 0; + DXGI_FORMAT d3dformat; int bpp; switch(format & Texture_TypeMask) { + case Texture_BGRA: + bpp = 4; + d3dformat = DXGI_FORMAT_B8G8R8A8_UNORM; + break; case Texture_RGBA: bpp = 4; d3dformat = DXGI_FORMAT_R8G8B8A8_UNORM; @@ -1513,30 +1757,28 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo bpp = 1; d3dformat = DXGI_FORMAT_R8_UNORM; break; + case Texture_A: + bpp = 1; + d3dformat = DXGI_FORMAT_A8_UNORM; + break; case Texture_Depth: bpp = 0; - d3dformat = DXGI_FORMAT_D32_FLOAT; + d3dformat = createDepthSrv ? DXGI_FORMAT_R32_TYPELESS : DXGI_FORMAT_D32_FLOAT; break; default: return NULL; } - int samples = (format & Texture_SamplesMask); - if (samples < 1) - { - samples = 1; - } - Texture* NewTex = new Texture(this, format, width, height); NewTex->Samples = samples; D3D1x_(TEXTURE2D_DESC) dsDesc; - dsDesc.Width = width; - dsDesc.Height = height; + dsDesc.Width = width; + dsDesc.Height = height; dsDesc.MipLevels = (format == (Texture_RGBA | Texture_GenMipmaps) && data) ? GetNumMipLevels(width, height) : 1; dsDesc.ArraySize = 1; dsDesc.Format = d3dformat; - dsDesc.SampleDesc.Count = samples; + dsDesc.SampleDesc.Count = samples; dsDesc.SampleDesc.Quality = 0; dsDesc.Usage = D3D1x_(USAGE_DEFAULT); dsDesc.BindFlags = D3D1x_(BIND_SHADER_RESOURCE); @@ -1546,9 +1788,8 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo if (format & Texture_RenderTarget) { if ((format & Texture_TypeMask) == Texture_Depth) - // We don't use depth textures, and creating them in d3d10 requires different options. { - dsDesc.BindFlags = D3D1x_(BIND_DEPTH_STENCIL); + dsDesc.BindFlags = createDepthSrv ? (dsDesc.BindFlags | D3D1x_(BIND_DEPTH_STENCIL)) : D3D1x_(BIND_DEPTH_STENCIL); } else { @@ -1565,7 +1806,19 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo } if (dsDesc.BindFlags & D3D1x_(BIND_SHADER_RESOURCE)) { - Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef()); + if((dsDesc.BindFlags & D3D1x_(BIND_DEPTH_STENCIL)) > 0 && createDepthSrv) + { + D3D1x_(SHADER_RESOURCE_VIEW_DESC) depthSrv; + depthSrv.Format = DXGI_FORMAT_R32_FLOAT; + depthSrv.ViewDimension = samples > 1 ? D3D1x_(SRV_DIMENSION_TEXTURE2DMS) : D3D1x_(SRV_DIMENSION_TEXTURE2D); + depthSrv.Texture2D.MostDetailedMip = 0; + depthSrv.Texture2D.MipLevels = dsDesc.MipLevels; + Device->CreateShaderResourceView(NewTex->Tex, &depthSrv, &NewTex->TexSv.GetRawRef()); + } + else + { + Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef()); + } } if (data) @@ -1611,7 +1864,12 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo { if ((format & Texture_TypeMask) == Texture_Depth) { - Device->CreateDepthStencilView(NewTex->Tex, NULL, &NewTex->TexDsv.GetRawRef()); + D3D1x_(DEPTH_STENCIL_VIEW_DESC) depthDsv; + ZeroMemory(&depthDsv, sizeof(depthDsv)); + depthDsv.Format = DXGI_FORMAT_D32_FLOAT; + depthDsv.ViewDimension = samples > 1 ? D3D1x_(DSV_DIMENSION_TEXTURE2DMS) : D3D1x_(DSV_DIMENSION_TEXTURE2D); + depthDsv.Texture2D.MipSlice = 0; + Device->CreateDepthStencilView(NewTex->Tex, createDepthSrv ? &depthDsv : NULL, &NewTex->TexDsv.GetRawRef()); } else { @@ -1703,38 +1961,54 @@ void RenderDevice::RenderWithAlpha( const Fill* fill, Render::Buffer* vertices, } void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices, - const Matrix4f& matrix, int offset, int count, PrimitiveType rprim) + const Matrix4f& matrix, int offset, int count, PrimitiveType rprim, bool useDistortionVertex/* = false*/) { - Context->IASetInputLayout(ModelVertexIL); + ID3D1xBuffer* vertexBuffer = ((Buffer*)vertices)->GetBuffer(); + UINT vertexOffset = offset; + UINT vertexStride = sizeof(Vertex); + if ( useDistortionVertex ) + { + Context->IASetInputLayout(DistortionVertexIL); + vertexStride = sizeof(DistortionVertex); + } + else + { + Context->IASetInputLayout(ModelVertexIL); + vertexStride = sizeof(Vertex); + } + Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset); + if (indices) { Context->IASetIndexBuffer(((Buffer*)indices)->GetBuffer(), DXGI_FORMAT_R16_UINT, 0); } - ID3D1xBuffer* vertexBuffer = ((Buffer*)vertices)->GetBuffer(); - UINT vertexStride = sizeof(Vertex); - UINT vertexOffset = offset; - Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset); - ShaderSet* shaders = ((ShaderFill*)fill)->GetShaders(); ShaderBase* vshader = ((ShaderBase*)shaders->GetShader(Shader_Vertex)); unsigned char* vertexData = vshader->UniformData; - if (vertexData) + if ( vertexData != NULL ) { - StandardUniformData* stdUniforms = (StandardUniformData*) vertexData; - stdUniforms->View = matrix.Transposed(); - stdUniforms->Proj = StdUniforms.Proj; + // TODO: some VSes don't start with StandardUniformData! + if ( vshader->UniformsSize >= sizeof(StandardUniformData) ) + { + StandardUniformData* stdUniforms = (StandardUniformData*) vertexData; + stdUniforms->View = matrix.Transposed(); + stdUniforms->Proj = StdUniforms.Proj; + } + UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, vertexData, vshader->UniformsSize); vshader->SetUniformBuffer(UniformBuffers[Shader_Vertex]); } for(int i = Shader_Vertex + 1; i < Shader_Count; i++) + { if (shaders->GetShader(i)) { ((ShaderBase*)shaders->GetShader(i))->UpdateBuffer(UniformBuffers[i]); ((ShaderBase*)shaders->GetShader(i))->SetUniformBuffer(UniformBuffers[i]); } + } D3D1x_(PRIMITIVE_TOPOLOGY) prim; switch(rprim) @@ -1749,7 +2023,7 @@ void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Bu prim = D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); break; default: - assert(0); + OVR_ASSERT(0); return; } Context->IASetPrimitiveTopology(prim); @@ -1782,20 +2056,40 @@ UPInt RenderDevice::QueryGPUMemorySize() } -void RenderDevice::Present() +void RenderDevice::Present ( bool withVsync ) { - SwapChain->Present(0, 0); + if( OVR::Util::ImageWindow::GlobalWindow() ) + { + OVR::Util::ImageWindow::GlobalWindow()->Process(); + } + + if ( withVsync ) + { + SwapChain->Present(1, 0); + } + else + { + // Immediate present + SwapChain->Present(0, 0); + } } -void RenderDevice::ForceFlushGPU() +void RenderDevice::WaitUntilGpuIdle() { +#if 0 + // If enabling this option and using an NVIDIA GPU, + // then make sure your "max pre-rendered frames" is set to 1 under the NVIDIA GPU settings. + + // Flush GPU data and don't stall CPU waiting for GPU to complete + Context->Flush(); +#else + // 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; if (Device->CreateQuery(&queryDesc, &query.GetRawRef()) == S_OK) { - #if (OVR_D3D_VERSION == 10) // Begin() not used for EVENT query. query->End(); @@ -1808,10 +2102,10 @@ void RenderDevice::ForceFlushGPU() do { } while(!done && !FAILED(Context->GetData(query, &done, sizeof(BOOL), 0))); #endif - } -} +#endif +} void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c) { @@ -1841,5 +2135,27 @@ void RenderDevice::RenderImage(float left, float top, float right, float bottom, Context->OMSetBlendState(NULL, NULL, 0xffffffff); } +void RenderDevice::BeginGpuEvent(const char* markerText, UInt32 markerColor) +{ +#if GPU_PROFILING + WCHAR wStr[255]; + size_t newStrLen = 0; + mbstowcs_s(&newStrLen, wStr, markerText, 255); + LPCWSTR pwStr = wStr; + + D3DPERF_BeginEvent(markerColor, pwStr); +#else + OVR_UNUSED(markerText); + OVR_UNUSED(markerColor); +#endif +} + +void RenderDevice::EndGpuEvent() +{ +#if GPU_PROFILING + D3DPERF_EndEvent(); +#endif +} + }}} |