1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/libGLESv2/renderer/Renderer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,228 @@ 1.4 +#include "precompiled.h" 1.5 +// 1.6 +// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. 1.7 +// Use of this source code is governed by a BSD-style license that can be 1.8 +// found in the LICENSE file. 1.9 +// 1.10 + 1.11 +// Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances. 1.12 + 1.13 +#include <EGL/eglext.h> 1.14 +#include "libGLESv2/main.h" 1.15 +#include "libGLESv2/Program.h" 1.16 +#include "libGLESv2/renderer/Renderer.h" 1.17 +#include "libGLESv2/renderer/Renderer9.h" 1.18 +#include "libGLESv2/renderer/Renderer11.h" 1.19 +#include "libGLESv2/utilities.h" 1.20 + 1.21 +#if !defined(ANGLE_ENABLE_D3D11) 1.22 +// Enables use of the Direct3D 11 API for a default display, when available 1.23 +#define ANGLE_ENABLE_D3D11 0 1.24 +#endif 1.25 + 1.26 +#define ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES \ 1.27 + { \ 1.28 + TEXT("d3dcompiler_47.dll"), \ 1.29 + TEXT("d3dcompiler_46.dll"), \ 1.30 + TEXT("d3dcompiler_43.dll") \ 1.31 + } 1.32 + 1.33 + 1.34 +namespace rx 1.35 +{ 1.36 + 1.37 +Renderer::Renderer(egl::Display *display) : mDisplay(display) 1.38 +{ 1.39 + mD3dCompilerModule = NULL; 1.40 + mD3DCompileFunc = NULL; 1.41 +} 1.42 + 1.43 +Renderer::~Renderer() 1.44 +{ 1.45 + if (mD3dCompilerModule) 1.46 + { 1.47 + FreeLibrary(mD3dCompilerModule); 1.48 + mD3dCompilerModule = NULL; 1.49 + } 1.50 +} 1.51 + 1.52 +bool Renderer::initializeCompiler() 1.53 +{ 1.54 +#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) 1.55 + // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. 1.56 + static TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; 1.57 + 1.58 + for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i) 1.59 + { 1.60 + if (GetModuleHandleEx(0, d3dCompilerNames[i], &mD3dCompilerModule)) 1.61 + { 1.62 + break; 1.63 + } 1.64 + } 1.65 +#else 1.66 + // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. 1.67 + mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL); 1.68 +#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES 1.69 + 1.70 + if (!mD3dCompilerModule) 1.71 + { 1.72 + ERR("No D3D compiler module found - aborting!\n"); 1.73 + return false; 1.74 + } 1.75 + 1.76 + mD3DCompileFunc = reinterpret_cast<pCompileFunc>(GetProcAddress(mD3dCompilerModule, "D3DCompile")); 1.77 + ASSERT(mD3DCompileFunc); 1.78 + 1.79 + return mD3DCompileFunc != NULL; 1.80 +} 1.81 + 1.82 +// Compiles HLSL code into executable binaries 1.83 +ShaderBlob *Renderer::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, UINT optimizationFlags, bool alternateFlags) 1.84 +{ 1.85 + if (!hlsl) 1.86 + { 1.87 + return NULL; 1.88 + } 1.89 + 1.90 + HRESULT result = S_OK; 1.91 + UINT flags = 0; 1.92 + std::string sourceText; 1.93 + if (gl::perfActive()) 1.94 + { 1.95 + flags |= D3DCOMPILE_DEBUG; 1.96 + 1.97 +#ifdef NDEBUG 1.98 + flags |= optimizationFlags; 1.99 +#else 1.100 + flags |= D3DCOMPILE_SKIP_OPTIMIZATION; 1.101 +#endif 1.102 + 1.103 + std::string sourcePath = getTempPath(); 1.104 + sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl); 1.105 + writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); 1.106 + } 1.107 + else 1.108 + { 1.109 + flags |= optimizationFlags; 1.110 + sourceText = hlsl; 1.111 + } 1.112 + 1.113 + // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. 1.114 + // Try the default flags first and if compilation fails, try some alternatives. 1.115 + const static UINT extraFlags[] = 1.116 + { 1.117 + 0, 1.118 + D3DCOMPILE_AVOID_FLOW_CONTROL, 1.119 + D3DCOMPILE_PREFER_FLOW_CONTROL 1.120 + }; 1.121 + 1.122 + const static char * const extraFlagNames[] = 1.123 + { 1.124 + "default", 1.125 + "avoid flow control", 1.126 + "prefer flow control" 1.127 + }; 1.128 + 1.129 + int attempts = alternateFlags ? ArraySize(extraFlags) : 1; 1.130 + pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc); 1.131 + for (int i = 0; i < attempts; ++i) 1.132 + { 1.133 + ID3DBlob *errorMessage = NULL; 1.134 + ID3DBlob *binary = NULL; 1.135 + 1.136 + result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, 1.137 + "main", profile, flags | extraFlags[i], 0, &binary, &errorMessage); 1.138 + if (errorMessage) 1.139 + { 1.140 + const char *message = (const char*)errorMessage->GetBufferPointer(); 1.141 + 1.142 + infoLog.appendSanitized(message); 1.143 + TRACE("\n%s", hlsl); 1.144 + TRACE("\n%s", message); 1.145 + 1.146 + errorMessage->Release(); 1.147 + errorMessage = NULL; 1.148 + } 1.149 + 1.150 + if (SUCCEEDED(result)) 1.151 + { 1.152 + return (ShaderBlob*)binary; 1.153 + } 1.154 + else 1.155 + { 1.156 + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) 1.157 + { 1.158 + return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*) NULL); 1.159 + } 1.160 + 1.161 + infoLog.append("Warning: D3D shader compilation failed with "); 1.162 + infoLog.append(extraFlagNames[i]); 1.163 + infoLog.append(" flags."); 1.164 + if (i + 1 < attempts) 1.165 + { 1.166 + infoLog.append(" Retrying with "); 1.167 + infoLog.append(extraFlagNames[i + 1]); 1.168 + infoLog.append(".\n"); 1.169 + } 1.170 + } 1.171 + } 1.172 + 1.173 + return NULL; 1.174 +} 1.175 + 1.176 +} 1.177 + 1.178 +extern "C" 1.179 +{ 1.180 + 1.181 +rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, EGLNativeDisplayType displayId) 1.182 +{ 1.183 + rx::Renderer *renderer = NULL; 1.184 + EGLint status = EGL_BAD_ALLOC; 1.185 + 1.186 + if (ANGLE_ENABLE_D3D11 || 1.187 + displayId == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || 1.188 + displayId == EGL_D3D11_ONLY_DISPLAY_ANGLE) 1.189 + { 1.190 + renderer = new rx::Renderer11(display, hDc); 1.191 + 1.192 + if (renderer) 1.193 + { 1.194 + status = renderer->initialize(); 1.195 + } 1.196 + 1.197 + if (status == EGL_SUCCESS) 1.198 + { 1.199 + return renderer; 1.200 + } 1.201 + else if (displayId == EGL_D3D11_ONLY_DISPLAY_ANGLE) 1.202 + { 1.203 + return NULL; 1.204 + } 1.205 + 1.206 + // Failed to create a D3D11 renderer, try creating a D3D9 renderer 1.207 + delete renderer; 1.208 + } 1.209 + 1.210 + bool softwareDevice = (displayId == EGL_SOFTWARE_DISPLAY_ANGLE); 1.211 + renderer = new rx::Renderer9(display, hDc, softwareDevice); 1.212 + 1.213 + if (renderer) 1.214 + { 1.215 + status = renderer->initialize(); 1.216 + } 1.217 + 1.218 + if (status == EGL_SUCCESS) 1.219 + { 1.220 + return renderer; 1.221 + } 1.222 + 1.223 + return NULL; 1.224 +} 1.225 + 1.226 +void glDestroyRenderer(rx::Renderer *renderer) 1.227 +{ 1.228 + delete renderer; 1.229 +} 1.230 + 1.231 +}