00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "Kernel/OVR_Log.h"
00025 #include "Kernel/OVR_Std.h"
00026
00027 #include "Render_D3D1X_Device.h"
00028
00029 #include <d3dcompiler.h>
00030
00031 #if (OVR_D3D_VERSION == 10)
00032 namespace OVR { namespace Render { namespace D3D10 {
00033 #else
00034 namespace OVR { namespace Render { namespace D3D11 {
00035 #endif
00036
00037 static D3D1x_(INPUT_ELEMENT_DESC) ModelVertexDesc[] =
00038 {
00039 {"Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, Pos), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
00040 {"Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(Vertex, C), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
00041 {"TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(Vertex, U), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
00042 {"TexCoord", 1, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(Vertex, U2), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
00043 {"Normal", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, Norm), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
00044 };
00045
00046
00047 static const char* StdVertexShaderSrc =
00048 "float4x4 Proj;\n"
00049 "float4x4 View;\n"
00050 "struct Varyings\n"
00051 "{\n"
00052 " float4 Position : SV_Position;\n"
00053 " float4 Color : COLOR0;\n"
00054 " float2 TexCoord : TEXCOORD0;\n"
00055 " float2 TexCoord1 : TEXCOORD1;\n"
00056 " float3 Normal : NORMAL;\n"
00057 " float3 VPos : TEXCOORD4;\n"
00058 "};\n"
00059 "void main(in float4 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, in float3 Normal : NORMAL,\n"
00060 " out Varyings ov)\n"
00061 "{\n"
00062 " ov.Position = mul(Proj, mul(View, Position));\n"
00063 " ov.Normal = mul(View, Normal);\n"
00064 " ov.VPos = mul(View, Position);\n"
00065 " ov.TexCoord = TexCoord;\n"
00066 " ov.TexCoord1 = TexCoord1;\n"
00067 " ov.Color = Color;\n"
00068 "}\n";
00069
00070 static const char* DirectVertexShaderSrc =
00071 "float4x4 View : register(c4);\n"
00072 "void main(in float4 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, in float3 Normal : NORMAL,\n"
00073 " out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float2 oTexCoord : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, out float3 oNormal : NORMAL)\n"
00074 "{\n"
00075 " oPosition = mul(View, Position);\n"
00076 " oTexCoord = TexCoord;\n"
00077 " oTexCoord1 = TexCoord1;\n"
00078 " oColor = Color;\n"
00079 " oNormal = mul(View, Normal);\n"
00080 "}\n";
00081
00082 static const char* SolidPixelShaderSrc =
00083 "float4 Color;\n"
00084 "struct Varyings\n"
00085 "{\n"
00086 " float4 Position : SV_Position;\n"
00087 " float4 Color : COLOR0;\n"
00088 " float2 TexCoord : TEXCOORD0;\n"
00089 "};\n"
00090 "float4 main(in Varyings ov) : SV_Target\n"
00091 "{\n"
00092 " return Color;\n"
00093 "}\n";
00094
00095 static const char* GouraudPixelShaderSrc =
00096 "struct Varyings\n"
00097 "{\n"
00098 " float4 Position : SV_Position;\n"
00099 " float4 Color : COLOR0;\n"
00100 " float2 TexCoord : TEXCOORD0;\n"
00101 "};\n"
00102 "float4 main(in Varyings ov) : SV_Target\n"
00103 "{\n"
00104 " return ov.Color;\n"
00105 "}\n";
00106
00107 static const char* TexturePixelShaderSrc =
00108 "Texture2D Texture : register(t0);\n"
00109 "SamplerState Linear : register(s0);\n"
00110 "struct Varyings\n"
00111 "{\n"
00112 " float4 Position : SV_Position;\n"
00113 " float4 Color : COLOR0;\n"
00114 " float2 TexCoord : TEXCOORD0;\n"
00115 "};\n"
00116 "float4 main(in Varyings ov) : SV_Target\n"
00117 "{\n"
00118 " float4 color2 = ov.Color * Texture.Sample(Linear, ov.TexCoord);\n"
00119 " if (color2.a <= 0.4)\n"
00120 " discard;\n"
00121 " return color2;\n"
00122 "}\n";
00123
00124 static const char* MultiTexturePixelShaderSrc =
00125 "Texture2D Texture[2] : register(t0);\n"
00126 "SamplerState Linear : register(s0);\n"
00127 "struct Varyings\n"
00128 "{\n"
00129 " float4 Position : SV_Position;\n"
00130 " float4 Color : COLOR0;\n"
00131 " float2 TexCoord : TEXCOORD0;\n"
00132 " float2 TexCoord1 : TEXCOORD1;\n"
00133 "};\n"
00134 "float4 main(in Varyings ov) : SV_Target\n"
00135 "{\n"
00136 "float4 color1;\n"
00137 "float4 color2;\n"
00138 " color1 = Texture[0].Sample(Linear, ov.TexCoord);\n"
00139 " color2 = Texture[1].Sample(Linear, ov.TexCoord1);\n"
00140 " color2.rgb = color2.rgb * lerp(1.2, 1.9, saturate(length(color2.rgb)));\n"
00141 " color2 = color1 * color2;\n"
00142 " if (color2.a <= 0.4)\n"
00143 " discard;\n"
00144 " return color2;\n"
00145 "}\n";
00146
00147 #define LIGHTING_COMMON \
00148 "cbuffer Lighting : register(b1)\n" \
00149 "{\n" \
00150 " float3 Ambient;\n" \
00151 " float3 LightPos[8];\n" \
00152 " float4 LightColor[8];\n" \
00153 " float LightCount;\n" \
00154 "};\n" \
00155 "struct Varyings\n" \
00156 "{\n" \
00157 " float4 Position : SV_Position;\n" \
00158 " float4 Color : COLOR0;\n" \
00159 " float2 TexCoord : TEXCOORD0;\n" \
00160 " float3 Normal : NORMAL;\n" \
00161 " float3 VPos : TEXCOORD4;\n" \
00162 "};\n" \
00163 "float4 DoLight(Varyings v)\n" \
00164 "{\n" \
00165 " float3 norm = normalize(v.Normal);\n" \
00166 " float3 light = Ambient;\n" \
00167 " for (uint i = 0; i < LightCount; i++)\n"\
00168 " {\n" \
00169 " float3 ltp = (LightPos[i] - v.VPos);\n" \
00170 " float ldist = dot(ltp,ltp);\n" \
00171 " ltp = normalize(ltp);\n" \
00172 " light += saturate(LightColor[i] * v.Color.rgb * dot(norm, ltp) / sqrt(ldist));\n"\
00173 " }\n" \
00174 " return float4(light, v.Color.a);\n" \
00175 "}\n"
00176
00177 static const char* LitSolidPixelShaderSrc =
00178 LIGHTING_COMMON
00179 "float4 main(in Varyings ov) : SV_Target\n"
00180 "{\n"
00181 " return DoLight(ov) * ov.Color;\n"
00182 "}\n";
00183
00184 static const char* LitTexturePixelShaderSrc =
00185 "Texture2D Texture : register(t0);\n"
00186 "SamplerState Linear : register(s0);\n"
00187 LIGHTING_COMMON
00188 "float4 main(in Varyings ov) : SV_Target\n"
00189 "{\n"
00190 " return DoLight(ov) * Texture.Sample(Linear, ov.TexCoord);\n"
00191 "}\n";
00192
00193 static const char* AlphaTexturePixelShaderSrc =
00194 "Texture2D Texture : register(t0);\n"
00195 "SamplerState Linear : register(s0);\n"
00196 "struct Varyings\n"
00197 "{\n"
00198 " float4 Position : SV_Position;\n"
00199 " float4 Color : COLOR0;\n"
00200 " float2 TexCoord : TEXCOORD0;\n"
00201 "};\n"
00202 "float4 main(in Varyings ov) : SV_Target\n"
00203 "{\n"
00204 " return ov.Color * float4(1,1,1,Texture.Sample(Linear, ov.TexCoord).r);\n"
00205 "}\n";
00206
00207
00208
00209
00210 static const char* PostProcessVertexShaderSrc =
00211 "float4x4 View : register(c4);\n"
00212 "float4x4 Texm : register(c8);\n"
00213 "void main(in float4 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1,\n"
00214 " out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float2 oTexCoord : TEXCOORD0)\n"
00215 "{\n"
00216 " oPosition = mul(View, Position);\n"
00217 " oTexCoord = mul(Texm, float4(TexCoord,0,1));\n"
00218 " oColor = Color;\n"
00219 "}\n";
00220
00221
00222 static const char* PostProcessPixelShaderSrc =
00223 "Texture2D Texture : register(t0);\n"
00224 "SamplerState Linear : register(s0);\n"
00225 "float2 LensCenter;\n"
00226 "float2 ScreenCenter;\n"
00227 "float2 Scale;\n"
00228 "float2 ScaleIn;\n"
00229 "float4 HmdWarpParam;\n"
00230 "\n"
00231
00232
00233
00234
00235 "float2 HmdWarp(float2 in01)\n"
00236 "{\n"
00237 " float2 theta = (in01 - LensCenter) * ScaleIn;\n"
00238 " float rSq = theta.x * theta.x + theta.y * theta.y;\n"
00239 " float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
00240 " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
00241 " return LensCenter + Scale * theta1;\n"
00242 "}\n"
00243
00244 "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n"
00245 " in float2 oTexCoord : TEXCOORD0) : SV_Target\n"
00246 "{\n"
00247 " float2 tc = HmdWarp(oTexCoord);\n"
00248 " if (any(clamp(tc, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tc))\n"
00249 " return 0;\n"
00250 " return Texture.Sample(Linear, tc);\n"
00251 "}\n";
00252
00253
00254 static const char* PostProcessPixelShaderWithChromAbSrc =
00255 "Texture2D Texture : register(t0);\n"
00256 "SamplerState Linear : register(s0);\n"
00257 "float2 LensCenter;\n"
00258 "float2 ScreenCenter;\n"
00259 "float2 Scale;\n"
00260 "float2 ScaleIn;\n"
00261 "float4 HmdWarpParam;\n"
00262 "float4 ChromAbParam;\n"
00263 "\n"
00264
00265
00266
00267
00268 "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n"
00269 " in float2 oTexCoord : TEXCOORD0) : SV_Target\n"
00270 "{\n"
00271 " float2 theta = (oTexCoord - LensCenter) * ScaleIn;\n"
00272 " float rSq = theta.x * theta.x + theta.y * theta.y;\n"
00273 " float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
00274 " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
00275 " \n"
00276 " // Detect whether blue texture coordinates are out of range since these will scaled out the furthest.\n"
00277 " float2 thetaBlue = theta1 * (ChromAbParam.z + ChromAbParam.w * rSq);\n"
00278 " float2 tcBlue = LensCenter + Scale * thetaBlue;\n"
00279 " if (any(clamp(tcBlue, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tcBlue))\n"
00280 " return 0;\n"
00281 " \n"
00282 " // Now do blue texture lookup.\n"
00283 " float blue = Texture.Sample(Linear, tcBlue).b;\n"
00284 " \n"
00285 " // Do green lookup (no scaling).\n"
00286 " float2 tcGreen = LensCenter + Scale * theta1;\n"
00287 " float4 greenColor = Texture.Sample(Linear, tcGreen);\n"
00288 " float green = greenColor.g;\n"
00289 " float alpha = greenColor.a;\n"
00290 " \n"
00291 " // Do red scale and lookup.\n"
00292 " float2 thetaRed = theta1 * (ChromAbParam.x + ChromAbParam.y * rSq);\n"
00293 " float2 tcRed = LensCenter + Scale * thetaRed;\n"
00294 " float red = Texture.Sample(Linear, tcRed).r;\n"
00295 " \n"
00296 " return float4(red, green, blue, alpha);\n"
00297 "}\n";
00298
00299
00300 static const char* VShaderSrcs[VShader_Count] =
00301 {
00302 DirectVertexShaderSrc,
00303 StdVertexShaderSrc,
00304 PostProcessVertexShaderSrc
00305 };
00306 static const char* FShaderSrcs[FShader_Count] =
00307 {
00308 SolidPixelShaderSrc,
00309 GouraudPixelShaderSrc,
00310 TexturePixelShaderSrc,
00311 AlphaTexturePixelShaderSrc,
00312 PostProcessPixelShaderSrc,
00313 PostProcessPixelShaderWithChromAbSrc,
00314 LitSolidPixelShaderSrc,
00315 LitTexturePixelShaderSrc,
00316 MultiTexturePixelShaderSrc
00317 };
00318
00319 RenderDevice::RenderDevice(const RendererParams& p, HWND window)
00320 {
00321 RECT rc;
00322 GetClientRect(window, &rc);
00323 UINT width = rc.right - rc.left;
00324 UINT height = rc.bottom - rc.top;
00325 WindowWidth = width;
00326 WindowHeight = height;
00327 Window = window;
00328
00329 Params = p;
00330 HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&DXGIFactory.GetRawRef()));
00331 if (FAILED(hr))
00332 return;
00333
00334
00335 if (Params.Display.MonitorName.GetLength() > 0)
00336 {
00337 for(UINT AdapterIndex = 0; ; AdapterIndex++)
00338 {
00339 HRESULT hr = DXGIFactory->EnumAdapters(AdapterIndex, &Adapter.GetRawRef());
00340 if (hr == DXGI_ERROR_NOT_FOUND)
00341 break;
00342
00343 DXGI_ADAPTER_DESC Desc;
00344 Adapter->GetDesc(&Desc);
00345
00346 UpdateMonitorOutputs();
00347
00348 if (FullscreenOutput)
00349 break;
00350 }
00351
00352 if (!FullscreenOutput)
00353 Adapter = NULL;
00354 }
00355
00356 if (!Adapter)
00357 {
00358 DXGIFactory->EnumAdapters(0, &Adapter.GetRawRef());
00359 UpdateMonitorOutputs();
00360 }
00361
00362 int flags = 0;
00363
00364 #if (OVR_D3D_VERSION == 10)
00365 hr = D3D10CreateDevice(Adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D1x_(SDK_VERSION),
00366 &Device.GetRawRef());
00367 Context = Device;
00368 Context->AddRef();
00369 #else //11
00370 hr = D3D11CreateDevice(Adapter, Adapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE,
00371 NULL, flags, NULL, 0, D3D1x_(SDK_VERSION),
00372 &Device.GetRawRef(), NULL, &Context.GetRawRef());
00373 #endif
00374 if (FAILED(hr))
00375 return;
00376
00377 if (!RecreateSwapChain())
00378 return;
00379
00380 if (Params.Fullscreen)
00381 SwapChain->SetFullscreenState(1, FullscreenOutput);
00382
00383 CurRenderTarget = NULL;
00384 for(int i = 0; i < Shader_Count; i++)
00385 {
00386 UniformBuffers[i] = *CreateBuffer();
00387 MaxTextureSet[i] = 0;
00388 }
00389
00390 ID3D10Blob* vsData = CompileShader("vs_4_0", DirectVertexShaderSrc);
00391 VertexShaders[VShader_MV] = *new VertexShader(this, vsData);
00392 for(int i = 1; i < VShader_Count; i++)
00393 {
00394 VertexShaders[i] = *new VertexShader(this, CompileShader("vs_4_0", VShaderSrcs[i]));
00395 }
00396
00397 for(int i = 0; i < FShader_Count; i++)
00398 {
00399 PixelShaders[i] = *new PixelShader(this, CompileShader("ps_4_0", FShaderSrcs[i]));
00400 }
00401
00402 SPInt bufferSize = vsData->GetBufferSize();
00403 const void* buffer = vsData->GetBufferPointer();
00404 ID3D1xInputLayout** objRef = &ModelVertexIL.GetRawRef();
00405
00406 HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, 5, buffer, bufferSize, objRef);
00407 OVR_UNUSED(validate);
00408
00409 Ptr<ShaderSet> gouraudShaders = *new ShaderSet();
00410 gouraudShaders->SetShader(VertexShaders[VShader_MVP]);
00411 gouraudShaders->SetShader(PixelShaders[FShader_Gouraud]);
00412 DefaultFill = *new ShaderFill(gouraudShaders);
00413
00414 #if (OVR_D3D_VERSION == 10)
00415 D3D1x_(BLEND_DESC) bm;
00416 memset(&bm, 0, sizeof(bm));
00417 bm.BlendEnable[0] = true;
00418 bm.BlendOp = bm.BlendOpAlpha = D3D1x_(BLEND_OP_ADD);
00419 bm.SrcBlend = bm.SrcBlendAlpha = D3D1x_(BLEND_SRC_ALPHA);
00420 bm.DestBlend = bm.DestBlendAlpha = D3D1x_(BLEND_INV_SRC_ALPHA);
00421 bm.RenderTargetWriteMask[0] = D3D1x_(COLOR_WRITE_ENABLE_ALL);
00422 Device->CreateBlendState(&bm, &BlendState.GetRawRef());
00423 #else
00424 D3D1x_(BLEND_DESC) bm;
00425 memset(&bm, 0, sizeof(bm));
00426 bm.RenderTarget[0].BlendEnable = true;
00427 bm.RenderTarget[0].BlendOp = bm.RenderTarget[0].BlendOpAlpha = D3D1x_(BLEND_OP_ADD);
00428 bm.RenderTarget[0].SrcBlend = bm.RenderTarget[0].SrcBlendAlpha = D3D1x_(BLEND_SRC_ALPHA);
00429 bm.RenderTarget[0].DestBlend = bm.RenderTarget[0].DestBlendAlpha = D3D1x_(BLEND_INV_SRC_ALPHA);
00430 bm.RenderTarget[0].RenderTargetWriteMask = D3D1x_(COLOR_WRITE_ENABLE_ALL);
00431 Device->CreateBlendState(&bm, &BlendState.GetRawRef());
00432 #endif
00433
00434 D3D1x_(RASTERIZER_DESC) rs;
00435 memset(&rs, 0, sizeof(rs));
00436 rs.AntialiasedLineEnable = true;
00437 rs.CullMode = D3D1x_(CULL_BACK);
00438
00439 rs.DepthClipEnable = true;
00440 rs.FillMode = D3D1x_(FILL_SOLID);
00441 Device->CreateRasterizerState(&rs, &Rasterizer.GetRawRef());
00442
00443 QuadVertexBuffer = *CreateBuffer();
00444 const Render::Vertex QuadVertices[] =
00445 { Vertex(Vector3f(0, 1, 0)), Vertex(Vector3f(1, 1, 0)),
00446 Vertex(Vector3f(0, 0, 0)), Vertex(Vector3f(1, 0, 0)) };
00447 QuadVertexBuffer->Data(Buffer_Vertex, QuadVertices, sizeof(QuadVertices));
00448
00449 SetDepthMode(0, 0);
00450 }
00451
00452 RenderDevice::~RenderDevice()
00453 {
00454 if (SwapChain && Params.Fullscreen)
00455 {
00456 SwapChain->SetFullscreenState(false, NULL);
00457 }
00458 }
00459
00460
00461
00462 Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd)
00463 {
00464 return new RenderDevice(rp, (HWND)oswnd);
00465 }
00466
00467
00468
00469
00470
00471
00472
00473 BOOL CALLBACK MonitorEnumFunc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData)
00474 {
00475 RenderDevice* renderer = (RenderDevice*)dwData;
00476
00477 MONITORINFOEX monitor;
00478 monitor.cbSize = sizeof(monitor);
00479
00480 if (::GetMonitorInfo(hMonitor, &monitor) && monitor.szDevice[0])
00481 {
00482 DISPLAY_DEVICE dispDev;
00483 memset(&dispDev, 0, sizeof(dispDev));
00484 dispDev.cb = sizeof(dispDev);
00485
00486 if (::EnumDisplayDevices(monitor.szDevice, 0, &dispDev, 0))
00487 {
00488 if (strstr(String(dispDev.DeviceName).ToCStr(), renderer->GetParams().Display.MonitorName.ToCStr()))
00489 {
00490 renderer->FSDesktopX = monitor.rcMonitor.left;
00491 renderer->FSDesktopY = monitor.rcMonitor.top;
00492 return FALSE;
00493 }
00494 }
00495 }
00496
00497 return TRUE;
00498 }
00499
00500
00501 void RenderDevice::UpdateMonitorOutputs(bool needRecreate)
00502 {
00503 HRESULT hr;
00504
00505 if (needRecreate)
00506 {
00507
00508
00509 if (SwapChain)
00510 {
00511 SwapChain->SetFullscreenState(FALSE, NULL);
00512 SwapChain->Release();
00513 SwapChain = NULL;
00514 }
00515
00516 DXGIFactory = NULL;
00517 Adapter = NULL;
00518 hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&DXGIFactory.GetRawRef()));
00519 if (FAILED(hr))
00520 return;
00521 DXGIFactory->EnumAdapters(0, &Adapter.GetRawRef());
00522 }
00523
00524 bool deviceNameFound = false;
00525
00526 for(UINT OutputIndex = 0; ; OutputIndex++)
00527 {
00528 Ptr<IDXGIOutput> Output;
00529 hr = Adapter->EnumOutputs(OutputIndex, &Output.GetRawRef());
00530 if (hr == DXGI_ERROR_NOT_FOUND)
00531 {
00532 break;
00533 }
00534
00535 DXGI_OUTPUT_DESC OutDesc;
00536 Output->GetDesc(&OutDesc);
00537
00538 MONITORINFOEX monitor;
00539 monitor.cbSize = sizeof(monitor);
00540 if (::GetMonitorInfo(OutDesc.Monitor, &monitor) && monitor.szDevice[0])
00541 {
00542 DISPLAY_DEVICE dispDev;
00543 memset(&dispDev, 0, sizeof(dispDev));
00544 dispDev.cb = sizeof(dispDev);
00545
00546 if (::EnumDisplayDevices(monitor.szDevice, 0, &dispDev, 0))
00547 {
00548 if (strstr(String(dispDev.DeviceName).ToCStr(), Params.Display.MonitorName.ToCStr()))
00549 {
00550 deviceNameFound = true;
00551 FullscreenOutput = Output;
00552 FSDesktopX = monitor.rcMonitor.left;
00553 FSDesktopY = monitor.rcMonitor.top;
00554 break;
00555 }
00556 }
00557 }
00558 }
00559
00560 if (!deviceNameFound && !Params.Display.MonitorName.IsEmpty())
00561 {
00562 EnumDisplayMonitors(0, 0, MonitorEnumFunc, (LPARAM)this);
00563 }
00564 }
00565
00566 bool RenderDevice::RecreateSwapChain()
00567 {
00568 DXGI_SWAP_CHAIN_DESC scDesc;
00569 memset(&scDesc, 0, sizeof(scDesc));
00570 scDesc.BufferCount = 1;
00571 scDesc.BufferDesc.Width = WindowWidth;
00572 scDesc.BufferDesc.Height = WindowHeight;
00573 scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
00574 scDesc.BufferDesc.RefreshRate.Numerator = 60;
00575 scDesc.BufferDesc.RefreshRate.Denominator = 1;
00576 scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
00577 scDesc.OutputWindow = Window;
00578 scDesc.SampleDesc.Count = Params.Multisample;
00579 scDesc.SampleDesc.Quality = 0;
00580 scDesc.Windowed = Params.Fullscreen != Display_Fullscreen;
00581 scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
00582
00583 if (SwapChain)
00584 {
00585 SwapChain->SetFullscreenState(FALSE, NULL);
00586 SwapChain->Release();
00587 SwapChain = NULL;
00588 }
00589
00590 Ptr<IDXGISwapChain> newSC;
00591 if (FAILED(DXGIFactory->CreateSwapChain(Device, &scDesc, &newSC.GetRawRef())))
00592 return false;
00593 SwapChain = newSC;
00594
00595 BackBuffer = NULL;
00596 BackBufferRT = NULL;
00597 HRESULT hr = SwapChain->GetBuffer(0, __uuidof(ID3D1xTexture2D), (void**)&BackBuffer.GetRawRef());
00598 if (FAILED(hr))
00599 return false;
00600
00601 hr = Device->CreateRenderTargetView(BackBuffer, NULL, &BackBufferRT.GetRawRef());
00602 if (FAILED(hr))
00603 return false;
00604
00605 Texture* depthBuffer = GetDepthBuffer(WindowWidth, WindowHeight, Params.Multisample);
00606 CurDepthBuffer = depthBuffer;
00607 if (CurRenderTarget == NULL)
00608 {
00609 Context->OMSetRenderTargets(1, &BackBufferRT.GetRawRef(), depthBuffer->TexDsv);
00610 }
00611 return true;
00612 }
00613
00614 bool RenderDevice::SetParams(const RendererParams& newParams)
00615 {
00616 String oldMonitor = Params.Display.MonitorName;
00617
00618 Params = newParams;
00619 if (newParams.Display.MonitorName != oldMonitor)
00620 {
00621 UpdateMonitorOutputs(true);
00622 }
00623
00624
00625 pSceneColorTex = NULL;
00626 return RecreateSwapChain();
00627 }
00628
00629 void RenderDevice::SetWindowSize(int w, int h)
00630 {
00631 if (w == WindowWidth && h == WindowHeight)
00632 return;
00633
00634 WindowWidth = w;
00635 WindowHeight = h;
00636 Context->OMSetRenderTargets(0, NULL, NULL);
00637 BackBuffer = NULL;
00638 BackBufferRT = NULL;
00639 if (SwapChain)
00640 {
00641 SwapChain->ResizeBuffers(2, WindowWidth, WindowHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
00642 SwapChain->GetBuffer(0, __uuidof(ID3D1xTexture2D), (void**)&BackBuffer.GetRawRef());
00643 }
00644 Device->CreateRenderTargetView(BackBuffer, NULL, &BackBufferRT.GetRawRef());
00645 }
00646
00647 bool RenderDevice::SetFullscreen(DisplayMode fullscreen)
00648 {
00649 if (fullscreen == Params.Fullscreen)
00650 {
00651 return true;
00652 }
00653
00654 if (Params.Fullscreen == Display_FakeFullscreen)
00655 {
00656 SetWindowLong(Window, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS);
00657 SetWindowPos(Window, NULL, PreFullscreenX, PreFullscreenY,
00658 PreFullscreenW, PreFullscreenH, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
00659 }
00660
00661 if (fullscreen == Display_FakeFullscreen)
00662 {
00663
00664
00665 WINDOWPLACEMENT wp;
00666 wp.length = sizeof(wp);
00667 GetWindowPlacement(Window, &wp);
00668 PreFullscreenW = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
00669 PreFullscreenH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
00670 PreFullscreenX = wp.rcNormalPosition.left;
00671 PreFullscreenY = wp.rcNormalPosition.top;
00672
00673
00674 SetWindowLong(Window, GWL_STYLE, WS_OVERLAPPED | WS_VISIBLE | WS_CLIPSIBLINGS);
00675 SetWindowPos(Window, NULL, FSDesktopX, FSDesktopY, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED);
00676
00677
00678 POINT oldCursor;
00679 if (GetCursorPos(&oldCursor) &&
00680 ((oldCursor.x < FSDesktopX) || (oldCursor.x > (FSDesktopX + PreFullscreenW)) ||
00681 (oldCursor.y < FSDesktopY) || (oldCursor.x > (FSDesktopY + PreFullscreenH))))
00682 {
00683
00684
00685 ::SetCursorPos(FSDesktopX, FSDesktopY);
00686 }
00687 }
00688 else
00689 {
00690 HRESULT hr = SwapChain->SetFullscreenState(fullscreen, fullscreen ? FullscreenOutput : NULL);
00691 if (FAILED(hr))
00692 {
00693 return false;
00694 }
00695 }
00696
00697 Params.Fullscreen = fullscreen;
00698 return true;
00699 }
00700
00701 void RenderDevice::SetMultipleViewports(int n, const Viewport* vps)
00702 {
00703 if (n > 2)
00704 {
00705 n = 2;
00706 }
00707 for(int i = 0; i < n; i++)
00708 {
00709 #if (OVR_D3D_VERSION == 10)
00710 Viewports[i].Width = vps[i].w;
00711 Viewports[i].Height = vps[i].h;
00712 Viewports[i].MinDepth = 0;
00713 Viewports[i].MaxDepth = 1;
00714 Viewports[i].TopLeftX = vps[i].x;
00715 Viewports[i].TopLeftY = vps[i].y;
00716 #else
00717 Viewports[i].Width = (float)vps[i].w;
00718 Viewports[i].Height = (float)vps[i].h;
00719 Viewports[i].MinDepth = 0;
00720 Viewports[i].MaxDepth = 1;
00721 Viewports[i].TopLeftX = (float)vps[i].x;
00722 Viewports[i].TopLeftY = (float)vps[i].y;
00723 #endif
00724 }
00725 NumViewports = n;
00726 Context->RSSetViewports(n, Viewports);
00727 }
00728
00729 static int GetDepthStateIndex(bool enable, bool write, RenderDevice::CompareFunc func)
00730 {
00731 if (!enable)
00732 {
00733 return 0;
00734 }
00735 return 1 + int(func) * 2 + write;
00736 }
00737
00738 void RenderDevice::SetDepthMode(bool enable, bool write, CompareFunc func)
00739 {
00740 int index = GetDepthStateIndex(enable, write, func);
00741 if (DepthStates[index])
00742 {
00743 CurDepthState = DepthStates[index];
00744 Context->OMSetDepthStencilState(DepthStates[index], 0);
00745 return;
00746 }
00747
00748 D3D1x_(DEPTH_STENCIL_DESC) dss;
00749 memset(&dss, 0, sizeof(dss));
00750 dss.DepthEnable = enable;
00751 switch(func)
00752 {
00753 case Compare_Always: dss.DepthFunc = D3D1x_(COMPARISON_ALWAYS); break;
00754 case Compare_Less: dss.DepthFunc = D3D1x_(COMPARISON_LESS); break;
00755 case Compare_Greater: dss.DepthFunc = D3D1x_(COMPARISON_GREATER); break;
00756 default:
00757 assert(0);
00758 }
00759 dss.DepthWriteMask = write ? D3D1x_(DEPTH_WRITE_MASK_ALL) : D3D1x_(DEPTH_WRITE_MASK_ZERO);
00760 Device->CreateDepthStencilState(&dss, &DepthStates[index].GetRawRef());
00761 Context->OMSetDepthStencilState(DepthStates[index], 0);
00762 CurDepthState = DepthStates[index];
00763 }
00764
00765 Texture* RenderDevice::GetDepthBuffer(int w, int h, int ms)
00766 {
00767 for(unsigned i = 0; i < DepthBuffers.GetSize(); i++)
00768 {
00769 if (w == DepthBuffers[i]->Width && h == DepthBuffers[i]->Height &&
00770 ms == DepthBuffers[i]->Samples)
00771 return DepthBuffers[i];
00772 }
00773
00774 Ptr<Texture> newDepth = *CreateTexture(Texture_Depth | Texture_RenderTarget | ms, w, h, NULL);
00775 if (newDepth == NULL)
00776 {
00777 OVR_DEBUG_LOG(("Failed to get depth buffer."));
00778 return NULL;
00779 }
00780
00781 DepthBuffers.PushBack(newDepth);
00782 return newDepth.GetPtr();
00783 }
00784
00785 void RenderDevice::Clear(float r, float g, float b, float a, float depth)
00786 {
00787 const float color[] = {r, g, b, a};
00788
00789
00790 ID3D1xDepthStencilState* oldDepthState = CurDepthState;
00791 StandardUniformData clearUniforms;
00792
00793 SetDepthMode(true, true, Compare_Always);
00794
00795 Context->IASetInputLayout(ModelVertexIL);
00796 #if (OVR_D3D_VERSION == 10)
00797 Context->GSSetShader(NULL);
00798 #else
00799 Context->GSSetShader(NULL, NULL, 0);
00800 #endif
00801
00802
00803
00804 ID3D1xShaderResourceView* sv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
00805 if (MaxTextureSet[Shader_Fragment])
00806 {
00807 Context->PSSetShaderResources(0, MaxTextureSet[Shader_Fragment], sv);
00808 }
00809
00810 ID3D1xBuffer* vertexBuffer = QuadVertexBuffer->GetBuffer();
00811 UINT vertexStride = sizeof(Vertex);
00812 UINT vertexOffset = 0;
00813 Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
00814
00815 clearUniforms.View = Matrix4f(2, 0, 0, 0,
00816 0, 2, 0, 0,
00817 0, 0, 0, 0,
00818 -1, -1, depth, 1);
00819 UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, &clearUniforms, sizeof(clearUniforms));
00820
00821 ID3D1xBuffer* vertexConstants = UniformBuffers[Shader_Vertex]->GetBuffer();
00822 Context->VSSetConstantBuffers(0, 1, &vertexConstants);
00823 Context->IASetPrimitiveTopology(D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP));
00824 VertexShaders[VShader_MV]->Set(Prim_TriangleStrip);
00825 PixelShaders[FShader_Solid]->Set(Prim_TriangleStrip);
00826
00827 UniformBuffers[Shader_Pixel]->Data(Buffer_Uniform, color, sizeof(color));
00828 PixelShaders[FShader_Solid]->SetUniformBuffer(UniformBuffers[Shader_Pixel]);
00829
00830 if (NumViewports > 1)
00831 {
00832 for(int i = 0; i < NumViewports; i++)
00833 {
00834 Context->RSSetViewports(1, &Viewports[i]);
00835 Context->OMSetBlendState(NULL, NULL, 0xffffffff);
00836 Context->Draw(4, 0);
00837 }
00838 Context->RSSetViewports(NumViewports, Viewports);
00839 }
00840 else
00841 {
00842 Context->OMSetBlendState(NULL, NULL, 0xffffffff);
00843 Context->Draw(4, 0);
00844 }
00845
00846
00847 CurDepthState = oldDepthState;
00848 Context->OMSetDepthStencilState(CurDepthState, 0);
00849 }
00850
00851
00852
00853 Buffer* RenderDevice::CreateBuffer()
00854 {
00855 return new Buffer(this);
00856 }
00857
00858 Buffer::~Buffer()
00859 {
00860 }
00861
00862 bool Buffer::Data(int use, const void *buffer, size_t size)
00863 {
00864 if (D3DBuffer && Size >= size)
00865 {
00866 if (Dynamic)
00867 {
00868 if (!buffer)
00869 return true;
00870
00871 void* v = Map(0, size, Map_Discard);
00872 if (v)
00873 {
00874 memcpy(v, buffer, size);
00875 Unmap(v);
00876 return true;
00877 }
00878 }
00879 else
00880 {
00881 Ren->Context->UpdateSubresource(D3DBuffer, 0, NULL, buffer, 0, 0);
00882 return true;
00883 }
00884 }
00885 if (D3DBuffer)
00886 {
00887 D3DBuffer = NULL;
00888 Size = 0;
00889 Use = 0;
00890 Dynamic = 0;
00891 }
00892
00893 D3D1x_(BUFFER_DESC) desc;
00894 memset(&desc, 0, sizeof(desc));
00895 if (use & Buffer_ReadOnly)
00896 {
00897 desc.Usage = D3D1x_(USAGE_IMMUTABLE);
00898 desc.CPUAccessFlags = 0;
00899 }
00900 else
00901 {
00902 desc.Usage = D3D1x_(USAGE_DYNAMIC);
00903 desc.CPUAccessFlags = D3D1x_(CPU_ACCESS_WRITE);
00904 Dynamic = 1;
00905 }
00906
00907 switch(use & Buffer_TypeMask)
00908 {
00909 case Buffer_Vertex: desc.BindFlags = D3D1x_(BIND_VERTEX_BUFFER); break;
00910 case Buffer_Index: desc.BindFlags = D3D1x_(BIND_INDEX_BUFFER); break;
00911 case Buffer_Uniform:
00912 desc.BindFlags = D3D1x_(BIND_CONSTANT_BUFFER);
00913 size += ((size + 15) & ~15) - size;
00914 break;
00915 case Buffer_Feedback:
00916 desc.BindFlags = D3D1x_(BIND_STREAM_OUTPUT);
00917 desc.Usage = D3D1x_(USAGE_DEFAULT);
00918 desc.CPUAccessFlags = 0;
00919 size += ((size + 15) & ~15) - size;
00920 break;
00921 }
00922
00923 desc.ByteWidth = (unsigned)size;
00924
00925 D3D1x_(SUBRESOURCE_DATA) sr;
00926 sr.pSysMem = buffer;
00927 sr.SysMemPitch = 0;
00928 sr.SysMemSlicePitch = 0;
00929
00930 HRESULT hr = Ren->Device->CreateBuffer(&desc, buffer ? &sr : NULL, &D3DBuffer.GetRawRef());
00931 if (SUCCEEDED(hr))
00932 {
00933 Use = use;
00934 Size = desc.ByteWidth;
00935 return 1;
00936 }
00937 return 0;
00938 }
00939
00940 void* Buffer::Map(size_t start, size_t size, int flags)
00941 {
00942 OVR_UNUSED(size);
00943
00944 D3D1x_(MAP) mapFlags = D3D1x_(MAP_WRITE);
00945 if (flags & Map_Discard)
00946 mapFlags = D3D1x_(MAP_WRITE_DISCARD);
00947 if (flags & Map_Unsynchronized)
00948 mapFlags = D3D1x_(MAP_WRITE_NO_OVERWRITE);
00949
00950 #if (OVR_D3D_VERSION == 10)
00951 void* map;
00952 if (SUCCEEDED(D3DBuffer->Map(mapFlags, 0, &map)))
00953 return ((char*)map) + start;
00954 else
00955 return NULL;
00956 #else
00957 D3D1x_(MAPPED_SUBRESOURCE) map;
00958 if (SUCCEEDED(Ren->Context->Map(D3DBuffer, 0, mapFlags, 0, &map)))
00959 return ((char*)map.pData) + start;
00960 else
00961 return NULL;
00962 #endif
00963 }
00964
00965 bool Buffer::Unmap(void *m)
00966 {
00967 OVR_UNUSED(m);
00968
00969 #if (OVR_D3D_VERSION == 10)
00970 D3DBuffer->Unmap();
00971 #else
00972 Ren->Context->Unmap(D3DBuffer, 0);
00973 #endif
00974 return true;
00975 }
00976
00977
00978
00979
00980 #if (OVR_D3D_VERSION == 10)
00981 template<> bool Shader<Render::Shader_Vertex, ID3D10VertexShader>::Load(void* shader, size_t size)
00982 {
00983 return SUCCEEDED(Ren->Device->CreateVertexShader(shader, size, &D3DShader));
00984 }
00985 template<> bool Shader<Render::Shader_Pixel, ID3D10PixelShader>::Load(void* shader, size_t size)
00986 {
00987 return SUCCEEDED(Ren->Device->CreatePixelShader(shader, size, &D3DShader));
00988 }
00989 template<> bool Shader<Render::Shader_Geometry, ID3D10GeometryShader>::Load(void* shader, size_t size)
00990 {
00991 return SUCCEEDED(Ren->Device->CreateGeometryShader(shader, size, &D3DShader));
00992 }
00993
00994 template<> void Shader<Render::Shader_Vertex, ID3D10VertexShader>::Set(PrimitiveType) const
00995 {
00996 Ren->Context->VSSetShader(D3DShader);
00997 }
00998 template<> void Shader<Render::Shader_Pixel, ID3D10PixelShader>::Set(PrimitiveType) const
00999 {
01000 Ren->Context->PSSetShader(D3DShader);
01001 }
01002 template<> void Shader<Render::Shader_Geometry, ID3D10GeometryShader>::Set(PrimitiveType) const
01003 {
01004 Ren->Context->GSSetShader(D3DShader);
01005 }
01006
01007 #else // 11
01008 template<> bool Shader<Render::Shader_Vertex, ID3D11VertexShader>::Load(void* shader, size_t size)
01009 {
01010 return SUCCEEDED(Ren->Device->CreateVertexShader(shader, size, NULL, &D3DShader));
01011 }
01012 template<> bool Shader<Render::Shader_Pixel, ID3D11PixelShader>::Load(void* shader, size_t size)
01013 {
01014 return SUCCEEDED(Ren->Device->CreatePixelShader(shader, size, NULL, &D3DShader));
01015 }
01016 template<> bool Shader<Render::Shader_Geometry, ID3D11GeometryShader>::Load(void* shader, size_t size)
01017 {
01018 return SUCCEEDED(Ren->Device->CreateGeometryShader(shader, size, NULL, &D3DShader));
01019 }
01020
01021 template<> void Shader<Render::Shader_Vertex, ID3D11VertexShader>::Set(PrimitiveType) const
01022 {
01023 Ren->Context->VSSetShader(D3DShader, NULL, 0);
01024 }
01025 template<> void Shader<Render::Shader_Pixel, ID3D11PixelShader>::Set(PrimitiveType) const
01026 {
01027 Ren->Context->PSSetShader(D3DShader, NULL, 0);
01028 }
01029 template<> void Shader<Render::Shader_Geometry, ID3D11GeometryShader>::Set(PrimitiveType) const
01030 {
01031 Ren->Context->GSSetShader(D3DShader, NULL, 0);
01032 }
01033 #endif
01034
01035 template<> void Shader<Render::Shader_Vertex, ID3D1xVertexShader>::SetUniformBuffer(Render::Buffer* buffer, int i)
01036 {
01037 Ren->Context->VSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef());
01038 }
01039 template<> void Shader<Render::Shader_Pixel, ID3D1xPixelShader>::SetUniformBuffer(Render::Buffer* buffer, int i)
01040 {
01041 Ren->Context->PSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef());
01042 }
01043 template<> void Shader<Render::Shader_Geometry, ID3D1xGeometryShader>::SetUniformBuffer(Render::Buffer* buffer, int i)
01044 {
01045 Ren->Context->GSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef());
01046 }
01047
01048 ID3D10Blob* RenderDevice::CompileShader(const char* profile, const char* src, const char* mainName)
01049 {
01050 ID3D10Blob* shader;
01051 ID3D10Blob* errors;
01052 HRESULT hr = D3DCompile(src, strlen(src), NULL, NULL, NULL, mainName, profile,
01053 0, 0, &shader, &errors);
01054 if (FAILED(hr))
01055 {
01056 OVR_DEBUG_LOG(("Compiling D3D shader for %s failed\n%s\n\n%s",
01057 profile, src, errors->GetBufferPointer()));
01058 OutputDebugStringA((char*)errors->GetBufferPointer());
01059 return NULL;
01060 }
01061 if (errors)
01062 {
01063 errors->Release();
01064 }
01065 return shader;
01066 }
01067
01068
01069 ShaderBase::ShaderBase(RenderDevice* r, ShaderStage stage)
01070 : Render::Shader(stage), Ren(r), UniformData(0)
01071 {
01072 }
01073 ShaderBase::~ShaderBase()
01074 {
01075 if (UniformData)
01076 {
01077 OVR_FREE(UniformData);
01078 }
01079 }
01080
01081 bool ShaderBase::SetUniform(const char* name, int n, const float* v)
01082 {
01083 for(unsigned i = 0; i < UniformInfo.GetSize(); i++)
01084 if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
01085 {
01086 memcpy(UniformData + UniformInfo[i].Offset, v, n * sizeof(float));
01087 return 1;
01088 }
01089 return 0;
01090 }
01091
01092 void ShaderBase::InitUniforms(ID3D10Blob* s)
01093 {
01094 ID3D10ShaderReflection* ref = NULL;
01095 D3D10ReflectShader(s->GetBufferPointer(), s->GetBufferSize(), &ref);
01096 ID3D10ShaderReflectionConstantBuffer* buf = ref->GetConstantBufferByIndex(0);
01097 D3D10_SHADER_BUFFER_DESC bufd;
01098 if (FAILED(buf->GetDesc(&bufd)))
01099 {
01100 UniformsSize = 0;
01101 if (UniformData)
01102 {
01103 OVR_FREE(UniformData);
01104 UniformData = 0;
01105 }
01106 return;
01107 }
01108
01109 for(unsigned i = 0; i < bufd.Variables; i++)
01110 {
01111 ID3D10ShaderReflectionVariable* var = buf->GetVariableByIndex(i);
01112 if (var)
01113 {
01114 D3D10_SHADER_VARIABLE_DESC vd;
01115 if (SUCCEEDED(var->GetDesc(&vd)))
01116 {
01117 Uniform u;
01118 u.Name = vd.Name;
01119 u.Offset = vd.StartOffset;
01120 u.Size = vd.Size;
01121 UniformInfo.PushBack(u);
01122 }
01123 }
01124 }
01125
01126 UniformsSize = bufd.Size;
01127 UniformData = (unsigned char*)OVR_ALLOC(bufd.Size);
01128 }
01129
01130 void ShaderBase::UpdateBuffer(Buffer* buf)
01131 {
01132 if (UniformsSize)
01133 {
01134 buf->Data(Buffer_Uniform, UniformData, UniformsSize);
01135 }
01136 }
01137
01138 void RenderDevice::SetCommonUniformBuffer(int i, Render::Buffer* buffer)
01139 {
01140 CommonUniforms[i] = (Buffer*)buffer;
01141
01142 Context->PSSetConstantBuffers(1, 1, &CommonUniforms[1]->D3DBuffer.GetRawRef());
01143 Context->VSSetConstantBuffers(1, 1, &CommonUniforms[1]->D3DBuffer.GetRawRef());
01144 }
01145
01146 Render::Shader *RenderDevice::LoadBuiltinShader(ShaderStage stage, int shader)
01147 {
01148 switch(stage)
01149 {
01150 case Shader_Vertex:
01151 return VertexShaders[shader];
01152 case Shader_Pixel:
01153 return PixelShaders[shader];
01154 default:
01155 return NULL;
01156 }
01157 }
01158
01159 ShaderBase* RenderDevice::CreateStereoShader(PrimitiveType prim, Render::Shader* vs)
01160 {
01161 if (pStereoShaders[prim])
01162 {
01163 return pStereoShaders[prim];
01164 }
01165
01166 OVR_UNUSED(vs);
01167 const char* varyings =
01168 " float4 Position : SV_Position;\n"
01169 " float4 Color : COLOR0;\n"
01170 " float2 TexCoord : TEXCOORD0;\n"
01171 " float3 Normal : NORMAL;\n";
01172 const char* copyVaryings =
01173 " o.Color = iv[i].Color;\n"
01174 " o.Normal = iv[i].Normal;\n"
01175 " o.TexCoord = iv[i].TexCoord;\n";
01176
01177 StringBuffer src =
01178 "float4x4 Proj[2] : register(c0);\n"
01179 "float4 ViewOffset : register(c8);\n"
01180 "struct Varyings\n"
01181 "{\n";
01182 src += varyings;
01183 src += "};\n"
01184 "struct OutVaryings\n"
01185 "{\n";
01186 src += varyings;
01187 src +=
01188 " float3 VPos : TEXCOORD4;\n"
01189 " uint Viewport : SV_ViewportArrayIndex;\n"
01190 "};\n";
01191
01192 if (prim == Prim_Lines)
01193 src +=
01194 "[maxvertexcount(4)]\n"
01195 "void main(line Varyings iv[2], inout LineStream<OutVaryings> v)\n";
01196 else
01197 src +=
01198 "[maxvertexcount(6)]\n"
01199 "void main(triangle Varyings iv[3], inout TriangleStream<OutVaryings> v)\n";
01200
01201 char ivsize[6];
01202 OVR_sprintf(ivsize, 6, "%d", (prim == Prim_Lines) ? 2 : 3);
01203
01204 src +=
01205 "{\n"
01206 " OutVaryings o;\n"
01207 " for (uint i = 0; i < ";
01208 src += ivsize;
01209 src += "; i++)\n"
01210 " {\n"
01211 " o.Position = mul(Proj[0], iv[i].Position - ViewOffset);\n"
01212 " o.VPos = iv[i].Position;\n"
01213 " o.Viewport = 0;\n";
01214 src += copyVaryings;
01215 src +=
01216 " v.Append(o);\n"
01217 " }\n"
01218 " v.RestartStrip();\n"
01219 " for (uint i = 0; i < ";
01220 src += ivsize;
01221 src += "; i++)\n"
01222 " {\n"
01223 " o.Position = mul(Proj[1], iv[i].Position + ViewOffset);\n"
01224 " o.VPos = iv[i].Position;\n"
01225 " o.Viewport = 1;\n";
01226 src += copyVaryings;
01227 src +=
01228 " v.Append(o);\n"
01229 " }\n"
01230 " v.RestartStrip();\n"
01231 "}\n";
01232
01233 pStereoShaders[prim] = *new GeomShader(this, CompileShader("gs_4_0", src.ToCStr()));
01234 return pStereoShaders[prim];
01235 }
01236
01237 Fill* RenderDevice::CreateSimpleFill(int flags)
01238 {
01239 OVR_UNUSED(flags);
01240 return DefaultFill;
01241 }
01242
01243
01244
01245 ID3D1xSamplerState* RenderDevice::GetSamplerState(int sm)
01246 {
01247 if (SamplerStates[sm])
01248 return SamplerStates[sm];
01249
01250 D3D1x_(SAMPLER_DESC) ss;
01251 memset(&ss, 0, sizeof(ss));
01252 if (sm & Sample_Clamp)
01253 ss.AddressU = ss.AddressV = ss.AddressW = D3D1x_(TEXTURE_ADDRESS_CLAMP);
01254 else if (sm & Sample_ClampBorder)
01255 ss.AddressU = ss.AddressV = ss.AddressW = D3D1x_(TEXTURE_ADDRESS_BORDER);
01256 else
01257 ss.AddressU = ss.AddressV = ss.AddressW = D3D1x_(TEXTURE_ADDRESS_WRAP);
01258
01259 if (sm & Sample_Nearest)
01260 {
01261 ss.Filter = D3D1x_(FILTER_MIN_MAG_MIP_POINT);
01262 }
01263 else if (sm & Sample_Anisotropic)
01264 {
01265 ss.Filter = D3D1x_(FILTER_ANISOTROPIC);
01266 ss.MaxAnisotropy = 8;
01267 }
01268 else
01269 {
01270 ss.Filter = D3D1x_(FILTER_MIN_MAG_MIP_LINEAR);
01271 }
01272 ss.MaxLOD = 15;
01273 Device->CreateSamplerState(&ss, &SamplerStates[sm].GetRawRef());
01274 return SamplerStates[sm];
01275 }
01276
01277 Texture::Texture(RenderDevice* ren, int fmt, int w, int h) : Ren(ren), Tex(NULL), TexSv(NULL), TexRtv(NULL), TexDsv(NULL), Width(w), Height(h)
01278 {
01279 OVR_UNUSED(fmt);
01280 Sampler = Ren->GetSamplerState(0);
01281 }
01282
01283 Texture::~Texture()
01284 {
01285 }
01286
01287 void Texture::Set(int slot, Render::ShaderStage stage) const
01288 {
01289 Ren->SetTexture(stage, slot, this);
01290 }
01291
01292 void Texture::SetSampleMode(int sm)
01293 {
01294 Sampler = Ren->GetSamplerState(sm);
01295 }
01296
01297 void RenderDevice::SetTexture(Render::ShaderStage stage, int slot, const Texture* t)
01298 {
01299 if (MaxTextureSet[stage] <= slot)
01300 MaxTextureSet[stage] = slot + 1;
01301
01302 ID3D1xShaderResourceView* sv = t ? t->TexSv : NULL;
01303 switch(stage)
01304 {
01305 case Shader_Fragment:
01306 Context->PSSetShaderResources(slot, 1, &sv);
01307 if (t)
01308 {
01309 Context->PSSetSamplers(slot, 1, &t->Sampler.GetRawRef());
01310 }
01311 break;
01312
01313 case Shader_Vertex:
01314 Context->VSSetShaderResources(slot, 1, &sv);
01315 break;
01316 }
01317 }
01318
01319 void RenderDevice::GenerateSubresourceData(
01320 unsigned imageWidth, unsigned imageHeight, int format, unsigned imageDimUpperLimit,
01321 const void* rawBytes, D3D1x_(SUBRESOURCE_DATA)* subresData,
01322 unsigned& largestMipWidth, unsigned& largestMipHeight, unsigned& byteSize, unsigned& effectiveMipCount)
01323 {
01324 largestMipWidth = 0;
01325 largestMipHeight = 0;
01326
01327 unsigned sliceLen = 0;
01328 unsigned rowLen = 0;
01329 unsigned numRows = 0;
01330 const byte* mipBytes = static_cast<const byte*>(rawBytes);
01331
01332 unsigned index = 0;
01333 unsigned subresWidth = imageWidth;
01334 unsigned subresHeight = imageHeight;
01335 unsigned numMips = effectiveMipCount;
01336
01337 for(unsigned i = 0; i < numMips; i++)
01338 {
01339 unsigned bytesPerBlock = 0;
01340 if (format == DXGI_FORMAT_BC1_UNORM)
01341 {
01342 bytesPerBlock = 8;
01343 }
01344 else if (format == DXGI_FORMAT_BC3_UNORM)
01345 {
01346 bytesPerBlock = 16;
01347 }
01348
01349 unsigned blockWidth = 0;
01350 blockWidth = (subresWidth + 3) / 4;
01351 if (blockWidth < 1)
01352 {
01353 blockWidth = 1;
01354 }
01355
01356 unsigned blockHeight = 0;
01357 blockHeight = (subresHeight + 3) / 4;
01358 if (blockHeight < 1)
01359 {
01360 blockHeight = 1;
01361 }
01362
01363 rowLen = blockWidth * bytesPerBlock;
01364 numRows = blockHeight;
01365 sliceLen = rowLen * numRows;
01366
01367 if (imageDimUpperLimit == 0 || (effectiveMipCount == 1) ||
01368 (subresWidth <= imageDimUpperLimit && subresHeight <= imageDimUpperLimit))
01369 {
01370 if(!largestMipWidth)
01371 {
01372 largestMipWidth = subresWidth;
01373 largestMipHeight = subresHeight;
01374 }
01375
01376 subresData[index].pSysMem = (const void*)mipBytes;
01377 subresData[index].SysMemPitch = static_cast<UINT>(rowLen);
01378 subresData[index].SysMemSlicePitch = static_cast<UINT>(sliceLen);
01379 byteSize += sliceLen;
01380 ++index;
01381 }
01382 else
01383 {
01384 effectiveMipCount--;
01385 }
01386
01387 mipBytes += sliceLen;
01388
01389 subresWidth = subresWidth >> 1;
01390 subresHeight = subresHeight >> 1;
01391 if (subresWidth <= 0)
01392 {
01393 subresWidth = 1;
01394 }
01395 if (subresHeight <= 0)
01396 {
01397 subresHeight = 1;
01398 }
01399 }
01400 }
01401
01402 #define _256Megabytes 268435456
01403 #define _512Megabytes 536870912
01404
01405 Texture* RenderDevice::CreateTexture(int format, int width, int height, const void* data, int mipcount)
01406 {
01407 UPInt gpuMemorySize = 0;
01408 {
01409 IDXGIDevice* pDXGIDevice;
01410 Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice);
01411 IDXGIAdapter * pDXGIAdapter;
01412 pDXGIDevice->GetAdapter(&pDXGIAdapter);
01413 DXGI_ADAPTER_DESC adapterDesc;
01414 pDXGIAdapter->GetDesc(&adapterDesc);
01415 gpuMemorySize = adapterDesc.DedicatedVideoMemory;
01416 pDXGIAdapter->Release();
01417 pDXGIDevice->Release();
01418 }
01419
01420 unsigned imageDimUpperLimit = 0;
01421 if (gpuMemorySize <= _256Megabytes)
01422 {
01423 imageDimUpperLimit = 512;
01424 }
01425 else if (gpuMemorySize <= _512Megabytes)
01426 {
01427 imageDimUpperLimit = 1024;
01428 }
01429
01430 if (format == Texture_DXT1 || format == Texture_DXT5)
01431 {
01432 int convertedFormat = (format == Texture_DXT1) ? DXGI_FORMAT_BC1_UNORM : DXGI_FORMAT_BC3_UNORM;
01433 unsigned largestMipWidth = 0;
01434 unsigned largestMipHeight = 0;
01435 unsigned effectiveMipCount = mipcount;
01436 unsigned textureSize = 0;
01437
01438 #ifdef OVR_DEFINE_NEW
01439 #undef new
01440 #endif
01441
01442 D3D1x_(SUBRESOURCE_DATA)* subresData = (D3D1x_(SUBRESOURCE_DATA)*)
01443 OVR_ALLOC(sizeof(D3D1x_(SUBRESOURCE_DATA)) * mipcount);
01444 GenerateSubresourceData(width, height, convertedFormat, imageDimUpperLimit, data, subresData, largestMipWidth,
01445 largestMipHeight, textureSize, effectiveMipCount);
01446 TotalTextureMemoryUsage += textureSize;
01447
01448 #ifdef OVR_DEFINE_NEW
01449 #define new OVR_DEFINE_NEW
01450 #endif
01451
01452 if (!Device || !subresData)
01453 {
01454 return NULL;
01455 }
01456 int samples = (Texture_RGBA & Texture_SamplesMask);
01457 if (samples < 1)
01458 {
01459 samples = 1;
01460 }
01461
01462 Texture* NewTex = new Texture(this, format, largestMipWidth, largestMipHeight);
01463 NewTex->Samples = samples;
01464
01465 D3D1x_(TEXTURE2D_DESC) desc;
01466 desc.Width = largestMipWidth;
01467 desc.Height = largestMipHeight;
01468 desc.MipLevels = effectiveMipCount;
01469 desc.ArraySize = 1;
01470 desc.Format = static_cast<DXGI_FORMAT>(convertedFormat);
01471 desc.SampleDesc.Count = samples;
01472 desc.SampleDesc.Quality = 0;
01473 desc.Usage = D3D1x_(USAGE_DEFAULT);
01474 desc.BindFlags = D3D1x_(BIND_SHADER_RESOURCE);
01475 desc.CPUAccessFlags = 0;
01476 desc.MiscFlags = 0;
01477
01478 HRESULT hr = Device->CreateTexture2D(&desc, static_cast<D3D1x_(SUBRESOURCE_DATA)*>(subresData),
01479 &NewTex->Tex.GetRawRef());
01480 OVR_FREE(subresData);
01481
01482 if (SUCCEEDED(hr) && NewTex != 0)
01483 {
01484 D3D1x_(SHADER_RESOURCE_VIEW_DESC) SRVDesc;
01485 memset(&SRVDesc, 0, sizeof(SRVDesc));
01486 SRVDesc.Format = static_cast<DXGI_FORMAT>(format);
01487 SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D;
01488 SRVDesc.Texture2D.MipLevels = desc.MipLevels;
01489
01490 hr = Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef());
01491
01492 if (FAILED(hr))
01493 {
01494 NewTex->Release();
01495 return NULL;
01496 }
01497 return NewTex;
01498 }
01499
01500 return NULL;
01501 }
01502 else
01503 {
01504 DXGI_FORMAT d3dformat;
01505 int bpp;
01506 switch(format & Texture_TypeMask)
01507 {
01508 case Texture_RGBA:
01509 bpp = 4;
01510 d3dformat = DXGI_FORMAT_R8G8B8A8_UNORM;
01511 break;
01512 case Texture_R:
01513 bpp = 1;
01514 d3dformat = DXGI_FORMAT_R8_UNORM;
01515 break;
01516 case Texture_Depth:
01517 bpp = 0;
01518 d3dformat = DXGI_FORMAT_D32_FLOAT;
01519 break;
01520 default:
01521 return NULL;
01522 }
01523
01524 int samples = (format & Texture_SamplesMask);
01525 if (samples < 1)
01526 {
01527 samples = 1;
01528 }
01529
01530 Texture* NewTex = new Texture(this, format, width, height);
01531 NewTex->Samples = samples;
01532
01533 D3D1x_(TEXTURE2D_DESC) dsDesc;
01534 dsDesc.Width = width;
01535 dsDesc.Height = height;
01536 dsDesc.MipLevels = (format == (Texture_RGBA | Texture_GenMipmaps) && data) ? GetNumMipLevels(width, height) : 1;
01537 dsDesc.ArraySize = 1;
01538 dsDesc.Format = d3dformat;
01539 dsDesc.SampleDesc.Count = samples;
01540 dsDesc.SampleDesc.Quality = 0;
01541 dsDesc.Usage = D3D1x_(USAGE_DEFAULT);
01542 dsDesc.BindFlags = D3D1x_(BIND_SHADER_RESOURCE);
01543 dsDesc.CPUAccessFlags = 0;
01544 dsDesc.MiscFlags = 0;
01545
01546 if (format & Texture_RenderTarget)
01547 {
01548 if ((format & Texture_TypeMask) == Texture_Depth)
01549
01550 {
01551 dsDesc.BindFlags = D3D1x_(BIND_DEPTH_STENCIL);
01552 }
01553 else
01554 {
01555 dsDesc.BindFlags |= D3D1x_(BIND_RENDER_TARGET);
01556 }
01557 }
01558
01559 HRESULT hr = Device->CreateTexture2D(&dsDesc, NULL, &NewTex->Tex.GetRawRef());
01560 if (FAILED(hr))
01561 {
01562 OVR_DEBUG_LOG_TEXT(("Failed to create 2D D3D texture."));
01563 NewTex->Release();
01564 return NULL;
01565 }
01566 if (dsDesc.BindFlags & D3D1x_(BIND_SHADER_RESOURCE))
01567 {
01568 Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef());
01569 }
01570
01571 if (data)
01572 {
01573 Context->UpdateSubresource(NewTex->Tex, 0, NULL, data, width * bpp, width * height * bpp);
01574 if (format == (Texture_RGBA | Texture_GenMipmaps))
01575 {
01576 int srcw = width, srch = height;
01577 int level = 0;
01578 UByte* mipmaps = NULL;
01579 do
01580 {
01581 level++;
01582 int mipw = srcw >> 1;
01583 if (mipw < 1)
01584 {
01585 mipw = 1;
01586 }
01587 int miph = srch >> 1;
01588 if (miph < 1)
01589 {
01590 miph = 1;
01591 }
01592 if (mipmaps == NULL)
01593 {
01594 mipmaps = (UByte*)OVR_ALLOC(mipw * miph * 4);
01595 }
01596 FilterRgba2x2(level == 1 ? (const UByte*)data : mipmaps, srcw, srch, mipmaps);
01597 Context->UpdateSubresource(NewTex->Tex, level, NULL, mipmaps, mipw * bpp, miph * bpp);
01598 srcw = mipw;
01599 srch = miph;
01600 }
01601 while(srcw > 1 || srch > 1);
01602
01603 if (mipmaps != NULL)
01604 {
01605 OVR_FREE(mipmaps);
01606 }
01607 }
01608 }
01609
01610 if (format & Texture_RenderTarget)
01611 {
01612 if ((format & Texture_TypeMask) == Texture_Depth)
01613 {
01614 Device->CreateDepthStencilView(NewTex->Tex, NULL, &NewTex->TexDsv.GetRawRef());
01615 }
01616 else
01617 {
01618 Device->CreateRenderTargetView(NewTex->Tex, NULL, &NewTex->TexRtv.GetRawRef());
01619 }
01620 }
01621
01622 return NewTex;
01623 }
01624 }
01625
01626
01627
01628 void RenderDevice::BeginRendering()
01629 {
01630 Context->RSSetState(Rasterizer);
01631 }
01632
01633 void RenderDevice::SetRenderTarget(Render::Texture* color, Render::Texture* depth, Render::Texture* stencil)
01634 {
01635 OVR_UNUSED(stencil);
01636
01637 CurRenderTarget = (Texture*)color;
01638 if (color == NULL)
01639 {
01640 Texture* newDepthBuffer = GetDepthBuffer(WindowWidth, WindowHeight, Params.Multisample);
01641 if (newDepthBuffer == NULL)
01642 {
01643 OVR_DEBUG_LOG(("New depth buffer creation failed."));
01644 }
01645 if (newDepthBuffer != NULL)
01646 {
01647 CurDepthBuffer = GetDepthBuffer(WindowWidth, WindowHeight, Params.Multisample);
01648 Context->OMSetRenderTargets(1, &BackBufferRT.GetRawRef(), CurDepthBuffer->TexDsv);
01649 }
01650 return;
01651 }
01652 if (depth == NULL)
01653 {
01654 depth = GetDepthBuffer(color->GetWidth(), color->GetHeight(), CurRenderTarget->Samples);
01655 }
01656
01657 ID3D1xShaderResourceView* sv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
01658 if (MaxTextureSet[Shader_Fragment])
01659 {
01660 Context->PSSetShaderResources(0, MaxTextureSet[Shader_Fragment], sv);
01661 }
01662 memset(MaxTextureSet, 0, sizeof(MaxTextureSet));
01663
01664 CurDepthBuffer = (Texture*)depth;
01665 Context->OMSetRenderTargets(1, &((Texture*)color)->TexRtv.GetRawRef(), ((Texture*)depth)->TexDsv);
01666 }
01667
01668
01669 void RenderDevice::SetWorldUniforms(const Matrix4f& proj)
01670 {
01671 StdUniforms.Proj = proj.Transposed();
01672
01673 }
01674
01675
01676 void RenderDevice::Render(const Matrix4f& matrix, Model* model)
01677 {
01678
01679 if (!model->VertexBuffer)
01680 {
01681 Ptr<Buffer> vb = *CreateBuffer();
01682 vb->Data(Buffer_Vertex, &model->Vertices[0], model->Vertices.GetSize() * sizeof(Vertex));
01683 model->VertexBuffer = vb;
01684 }
01685 if (!model->IndexBuffer)
01686 {
01687 Ptr<Buffer> ib = *CreateBuffer();
01688 ib->Data(Buffer_Index, &model->Indices[0], model->Indices.GetSize() * 2);
01689 model->IndexBuffer = ib;
01690 }
01691
01692 Render(model->Fill ? model->Fill : DefaultFill,
01693 model->VertexBuffer, model->IndexBuffer,
01694 matrix, 0, (unsigned)model->Indices.GetSize(), model->GetPrimType());
01695 }
01696
01697 void RenderDevice::RenderWithAlpha( const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
01698 const Matrix4f& matrix, int offset, int count, PrimitiveType rprim)
01699 {
01700 Context->OMSetBlendState(BlendState, NULL, 0xffffffff);
01701 Render(fill, vertices, indices, matrix, offset, count, rprim);
01702 Context->OMSetBlendState(NULL, NULL, 0xffffffff);
01703 }
01704
01705 void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
01706 const Matrix4f& matrix, int offset, int count, PrimitiveType rprim)
01707 {
01708 Context->IASetInputLayout(ModelVertexIL);
01709 if (indices)
01710 {
01711 Context->IASetIndexBuffer(((Buffer*)indices)->GetBuffer(), DXGI_FORMAT_R16_UINT, 0);
01712 }
01713
01714 ID3D1xBuffer* vertexBuffer = ((Buffer*)vertices)->GetBuffer();
01715 UINT vertexStride = sizeof(Vertex);
01716 UINT vertexOffset = offset;
01717 Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
01718
01719 ShaderSet* shaders = ((ShaderFill*)fill)->GetShaders();
01720
01721 ShaderBase* vshader = ((ShaderBase*)shaders->GetShader(Shader_Vertex));
01722 unsigned char* vertexData = vshader->UniformData;
01723 if (vertexData)
01724 {
01725 StandardUniformData* stdUniforms = (StandardUniformData*) vertexData;
01726 stdUniforms->View = matrix.Transposed();
01727 stdUniforms->Proj = StdUniforms.Proj;
01728 UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, vertexData, vshader->UniformsSize);
01729 vshader->SetUniformBuffer(UniformBuffers[Shader_Vertex]);
01730 }
01731
01732 for(int i = Shader_Vertex + 1; i < Shader_Count; i++)
01733 if (shaders->GetShader(i))
01734 {
01735 ((ShaderBase*)shaders->GetShader(i))->UpdateBuffer(UniformBuffers[i]);
01736 ((ShaderBase*)shaders->GetShader(i))->SetUniformBuffer(UniformBuffers[i]);
01737 }
01738
01739 D3D1x_(PRIMITIVE_TOPOLOGY) prim;
01740 switch(rprim)
01741 {
01742 case Prim_Triangles:
01743 prim = D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLELIST);
01744 break;
01745 case Prim_Lines:
01746 prim = D3D1x_(PRIMITIVE_TOPOLOGY_LINELIST);
01747 break;
01748 case Prim_TriangleStrip:
01749 prim = D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
01750 break;
01751 default:
01752 assert(0);
01753 return;
01754 }
01755 Context->IASetPrimitiveTopology(prim);
01756
01757 fill->Set(rprim);
01758 if (ExtraShaders)
01759 {
01760 ExtraShaders->Set(rprim);
01761 }
01762
01763 if (indices)
01764 {
01765 Context->DrawIndexed(count, 0, 0);
01766 }
01767 else
01768 {
01769 Context->Draw(count, 0);
01770 }
01771 }
01772
01773 UPInt RenderDevice::QueryGPUMemorySize()
01774 {
01775 IDXGIDevice* pDXGIDevice;
01776 Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice);
01777 IDXGIAdapter * pDXGIAdapter;
01778 pDXGIDevice->GetAdapter(&pDXGIAdapter);
01779 DXGI_ADAPTER_DESC adapterDesc;
01780 pDXGIAdapter->GetDesc(&adapterDesc);
01781 return adapterDesc.DedicatedVideoMemory;
01782 }
01783
01784
01785 void RenderDevice::Present()
01786 {
01787 SwapChain->Present(0, 0);
01788 }
01789
01790 void RenderDevice::ForceFlushGPU()
01791 {
01792 D3D1x_QUERY_DESC queryDesc = { D3D1x_(QUERY_EVENT), 0 };
01793 Ptr<ID3D1xQuery> query;
01794 BOOL done = FALSE;
01795
01796 if (Device->CreateQuery(&queryDesc, &query.GetRawRef()) == S_OK)
01797 {
01798
01799 #if (OVR_D3D_VERSION == 10)
01800
01801 query->End();
01802
01803
01804 do { }
01805 while(!done && !FAILED(query->GetData(&done, sizeof(BOOL), 0)));
01806 #else
01807 Context->End(query);
01808 do { }
01809 while(!done && !FAILED(Context->GetData(query, &done, sizeof(BOOL), 0)));
01810 #endif
01811
01812 }
01813 }
01814
01815
01816 void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c)
01817 {
01818 Context->OMSetBlendState(BlendState, NULL, 0xffffffff);
01819 OVR::Render::RenderDevice::FillRect(left, top, right, bottom, c);
01820 Context->OMSetBlendState(NULL, NULL, 0xffffffff);
01821 }
01822
01823 void RenderDevice::FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm)
01824 {
01825 Context->OMSetBlendState(BlendState, NULL, 0xffffffff);
01826 OVR::Render::RenderDevice::FillGradientRect(left, top, right, bottom, col_top, col_btm);
01827 Context->OMSetBlendState(NULL, NULL, 0xffffffff);
01828 }
01829
01830 void RenderDevice::RenderText(const struct Font* font, const char* str, float x, float y, float size, Color c)
01831 {
01832 Context->OMSetBlendState(BlendState, NULL, 0xffffffff);
01833 OVR::Render::RenderDevice::RenderText(font, str, x, y, size, c);
01834 Context->OMSetBlendState(NULL, NULL, 0xffffffff);
01835 }
01836
01837 void RenderDevice::RenderImage(float left, float top, float right, float bottom, ShaderFill* image)
01838 {
01839 Context->OMSetBlendState(BlendState, NULL, 0xffffffff);
01840 OVR::Render::RenderDevice::RenderImage(left, top, right, bottom, image);
01841 Context->OMSetBlendState(NULL, NULL, 0xffffffff);
01842 }
01843
01844 }}}
01845