void ShaderD3D::parseAttributes(ShHandle compiler) { const std::string &hlsl = getTranslatedSource(); if (!hlsl.empty()) { mActiveAttributes = *GetShaderVariables(ShGetAttributes(compiler)); FilterInactiveVariables(&mActiveAttributes); } }
bool ShaderD3D::compile(gl::Compiler *compiler, const std::string &source) { uncompile(); CompilerD3D *compilerD3D = GetImplAs<CompilerD3D>(compiler); ShHandle compilerHandle = compilerD3D->getCompilerHandle(mShaderType); mCompilerOutputType = ShGetShaderOutputType(compilerHandle); compileToHLSL(compilerHandle, source); if (mShaderType == GL_VERTEX_SHADER) { parseAttributes(compilerHandle); } parseVaryings(compilerHandle); if (mShaderType == GL_FRAGMENT_SHADER) { std::sort(mVaryings.begin(), mVaryings.end(), CompareVarying); const std::string &hlsl = getTranslatedSource(); if (!hlsl.empty()) { mActiveOutputVariables = *GetShaderVariables(ShGetOutputVariables(compilerHandle)); FilterInactiveVariables(&mActiveOutputVariables); } } #if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED mDebugInfo += std::string("// ") + GetShaderTypeString(mShaderType) + " SHADER BEGIN\n"; mDebugInfo += "\n// GLSL BEGIN\n\n" + source + "\n\n// GLSL END\n\n\n"; mDebugInfo += "// INITIAL HLSL BEGIN\n\n" + getTranslatedSource() + "\n// INITIAL HLSL END\n\n\n"; // Successive steps will append more info #else mDebugInfo += getTranslatedSource(); #endif return !getTranslatedSource().empty(); }
void ShaderD3D::compileToHLSL(ShHandle compiler, const std::string &source) { int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES); // D3D11 Feature Level 9_3 and below do not support non-constant loop indexers in fragment // shaders. // Shader compilation will fail. To provide a better error message we can instruct the // compiler to pre-validate. if (mRenderer->getRendererLimitations().shadersRequireIndexedLoopValidation) { compileOptions |= SH_VALIDATE_LOOP_INDEXING; } std::string sourcePath; #if !defined (ANGLE_ENABLE_WINDOWS_STORE) if (gl::DebugAnnotationsActive()) { sourcePath = getTempPath(); writeFile(sourcePath.c_str(), source.c_str(), source.length()); compileOptions |= SH_LINE_DIRECTIVES; } #endif int result; if (sourcePath.empty()) { const char* sourceStrings[] = { source.c_str(), }; result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions); } else { const char* sourceStrings[] = { sourcePath.c_str(), source.c_str(), }; result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH); } mShaderVersion = ShGetShaderVersion(compiler); if (result) { mTranslatedSource = ShGetObjectCode(compiler); #ifdef _DEBUG // Prefix hlsl shader with commented out glsl shader // Useful in diagnostics tools like pix which capture the hlsl shaders std::ostringstream hlslStream; hlslStream << "// GLSL\n"; hlslStream << "//\n"; size_t curPos = 0; while (curPos != std::string::npos) { size_t nextLine = source.find("\n", curPos); size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); hlslStream << "// " << source.substr(curPos, len); curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); } hlslStream << "\n\n"; hlslStream << mTranslatedSource; mTranslatedSource = hlslStream.str(); #endif mUniforms = *GetShaderVariables(ShGetUniforms(compiler)); for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) { const sh::Uniform &uniform = mUniforms[uniformIndex]; if (uniform.staticUse && !uniform.isBuiltIn()) { unsigned int index = static_cast<unsigned int>(-1); bool getUniformRegisterResult = ShGetUniformRegister(compiler, uniform.name, &index); UNUSED_ASSERTION_VARIABLE(getUniformRegisterResult); ASSERT(getUniformRegisterResult); mUniformRegisterMap[uniform.name] = index; } } mInterfaceBlocks = *GetShaderVariables(ShGetInterfaceBlocks(compiler)); for (size_t blockIndex = 0; blockIndex < mInterfaceBlocks.size(); blockIndex++) { const sh::InterfaceBlock &interfaceBlock = mInterfaceBlocks[blockIndex]; if (interfaceBlock.staticUse) { unsigned int index = static_cast<unsigned int>(-1); bool blockRegisterResult = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name, &index); UNUSED_ASSERTION_VARIABLE(blockRegisterResult); ASSERT(blockRegisterResult); mInterfaceBlockRegisterMap[interfaceBlock.name] = index; } } } else { mInfoLog = ShGetInfoLog(compiler); TRACE("\n%s", mInfoLog.c_str()); } }
void OmniMapD3D::SetupAllShaderVaribles() { int N_Channels; int TextureIds[OMNIMAP_maxChannelFaces]; D3DXMATRIX textureMats[OMNIMAP_maxChannelFaces]; GetShaderVariables(N_Channels, TextureIds); ((OmniMapShaderD3D *) shaders)->SetTextureIds(N_Channels); for (int i = 0; i < N_Channels; i++) { OmniMapChannelBase *channel = this->GetChannel(i); D3DXQUATERNION tmpQuat; D3DXMATRIX *pTextureMat = &textureMats[i]; D3DXMATRIX tmpMat; D3DXMatrixIdentity(pTextureMat); const D3DXVECTOR3 zeroVec(0.0,0.0,0.0); const D3DXVECTOR3 transVec(.5,.5,.5); D3DXMatrixAffineTransformation(pTextureMat, .5, &zeroVec, D3DXQuaternionIdentity(&tmpQuat), &transVec); D3DXMATRIX channelProj; ((OmniMapChannelD3D *) channel)->GetProjectionMatrixRH(&channelProj); D3DXMatrixMultiply(pTextureMat, &channelProj, pTextureMat); D3DXMATRIX viewMatrix; ((OmniMapChannelD3D *) channel)->GetViewMatrix2(&viewMatrix); D3DXMatrixMultiply(pTextureMat, &viewMatrix, pTextureMat); } ((OmniMapShaderD3D *) shaders)->SetTextureMatrices(textureMats, N_Channels); D3DVIEWPORT9 vp; d3dDevice->GetViewport(&vp); float yOffset1, yOffset2, yScale; if (((glViewportsettings0 + glViewportsettings2) <= vp.Width) && (glViewportsettings0 >= 0) && ((glViewportsettings1 + glViewportsettings3) <= vp.Height) && (glViewportsettings1 >= 0)) { //if image circle is inside of the viewport, use opengl approach vp.X = (DWORD) glViewportsettings0; vp.Y = (DWORD) glViewportsettings1; vp.Width = (DWORD) glViewportsettings2; vp.Height = (DWORD) glViewportsettings3; d3dDevice->SetViewport(&vp); yOffset1 = 0.0; yOffset2 = 0.0; yScale = 1.0; } else { // FIX FOR DX11 VIEWPORT if image circle is outside of the viewport if (glViewportsettings2 <1.0f) glViewportsettings2 = (float)vp.Width; // UNTESTED if(glViewportsettings3<1.0f) glViewportsettings3 = (float) vp.Height; // UNTESTED float HeightImageCircle = glViewportsettings3; // back out the offset from the lua... this float offsetSuggestedByLua = (glViewportsettings1 - .5f* vp.Height + .5f* vp.Width)/vp.Width; float aspect = vp.Width/(float)vp.Height; float offsetByDX11 =offsetSuggestedByLua*2.0f*aspect; yScale = HeightImageCircle /((float)vp.Height); yOffset1 = 0; yOffset2 = offsetByDX11; } if (yOffset1 != 0.0) yOffset2 = 0.0; ((OmniMapShaderD3D *) shaders)->omnimapFX->SetFloat( "yScale", yScale); ((OmniMapShaderD3D *) shaders)->omnimapFX->SetFloat( "yOffset1", yOffset1); ((OmniMapShaderD3D *) shaders)->omnimapFX->SetFloat( "yOffset2", yOffset2); ((OmniMapShaderD3D *) shaders)->omnimapFX->SetMatrix( "g_mProjection", &worldViewProjection ); ((OmniMapShaderD3D *) shaders)->omnimapFX->SetMatrix( "g_mWorldView", &worldView ); if(StencilMask_filename) ((OmniMapShaderD3D *) shaders)->StencilMask_Bind(6);//+1 }
void Shader::resolveCompile() { if (!mState.compilePending()) { return; } ASSERT(mBoundCompiler.get()); ShHandle compilerHandle = mBoundCompiler->getCompilerHandle(mState.mShaderType); std::vector<const char *> srcStrings; if (!mLastCompiledSourcePath.empty()) { srcStrings.push_back(mLastCompiledSourcePath.c_str()); } srcStrings.push_back(mLastCompiledSource.c_str()); if (!sh::Compile(compilerHandle, &srcStrings[0], srcStrings.size(), mLastCompileOptions)) { mInfoLog = sh::GetInfoLog(compilerHandle); WARN() << std::endl << mInfoLog; mState.mCompileStatus = CompileStatus::NOT_COMPILED; return; } mState.mTranslatedSource = sh::GetObjectCode(compilerHandle); #if !defined(NDEBUG) // Prefix translated shader with commented out un-translated shader. // Useful in diagnostics tools which capture the shader source. std::ostringstream shaderStream; shaderStream << "// GLSL\n"; shaderStream << "//\n"; std::istringstream inputSourceStream(mState.mSource); std::string line; while (std::getline(inputSourceStream, line)) { // Remove null characters from the source line line.erase(std::remove(line.begin(), line.end(), '\0'), line.end()); shaderStream << "// " << line << std::endl; } shaderStream << "\n\n"; shaderStream << mState.mTranslatedSource; mState.mTranslatedSource = shaderStream.str(); #endif // !defined(NDEBUG) // Gather the shader information mState.mShaderVersion = sh::GetShaderVersion(compilerHandle); mState.mUniforms = GetShaderVariables(sh::GetUniforms(compilerHandle)); mState.mUniformBlocks = GetShaderVariables(sh::GetUniformBlocks(compilerHandle)); mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle)); switch (mState.mShaderType) { case ShaderType::Compute: { mState.mLocalSize = sh::GetComputeShaderLocalGroupSize(compilerHandle); if (mState.mLocalSize.isDeclared()) { angle::CheckedNumeric<uint32_t> checked_local_size_product(mState.mLocalSize[0]); checked_local_size_product *= mState.mLocalSize[1]; checked_local_size_product *= mState.mLocalSize[2]; if (!checked_local_size_product.IsValid()) { WARN() << std::endl << "Integer overflow when computing the product of local_size_x, " << "local_size_y and local_size_z."; mState.mCompileStatus = CompileStatus::NOT_COMPILED; return; } if (checked_local_size_product.ValueOrDie() > mCurrentMaxComputeWorkGroupInvocations) { WARN() << std::endl << "The total number of invocations within a work group exceeds " << "MAX_COMPUTE_WORK_GROUP_INVOCATIONS."; mState.mCompileStatus = CompileStatus::NOT_COMPILED; return; } } break; } case ShaderType::Vertex: { { mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle)); mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes); mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle); } break; } case ShaderType::Fragment: { mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); // TODO(jmadill): Figure out why we only sort in the FS, and if we need to. std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar); mState.mActiveOutputVariables = GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle)); break; } case ShaderType::Geometry: { mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); if (sh::HasValidGeometryShaderInputPrimitiveType(compilerHandle)) { mState.mGeometryShaderInputPrimitiveType = FromGLenum<PrimitiveMode>( sh::GetGeometryShaderInputPrimitiveType(compilerHandle)); } if (sh::HasValidGeometryShaderOutputPrimitiveType(compilerHandle)) { mState.mGeometryShaderOutputPrimitiveType = FromGLenum<PrimitiveMode>( sh::GetGeometryShaderOutputPrimitiveType(compilerHandle)); } if (sh::HasValidGeometryShaderMaxVertices(compilerHandle)) { mState.mGeometryShaderMaxVertices = sh::GetGeometryShaderMaxVertices(compilerHandle); } mState.mGeometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle); break; } default: UNREACHABLE(); } ASSERT(!mState.mTranslatedSource.empty()); bool success = mImplementation->postTranslateCompile(mBoundCompiler.get(), &mInfoLog); mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED; }
void Shader::compile(Compiler *compiler) { mData.mTranslatedSource.clear(); mInfoLog.clear(); mData.mShaderVersion = 100; mData.mVaryings.clear(); mData.mUniforms.clear(); mData.mInterfaceBlocks.clear(); mData.mActiveAttributes.clear(); mData.mActiveOutputVariables.clear(); ShHandle compilerHandle = compiler->getCompilerHandle(mData.mShaderType); std::stringstream sourceStream; std::string sourcePath; int additionalOptions = mImplementation->prepareSourceAndReturnOptions(&sourceStream, &sourcePath); int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES | additionalOptions); // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes // in fragment shaders. Shader compilation will fail. To provide a better error message we can // instruct the compiler to pre-validate. if (mRendererLimitations.shadersRequireIndexedLoopValidation) { compileOptions |= SH_VALIDATE_LOOP_INDEXING; } std::string sourceString = sourceStream.str(); std::vector<const char *> sourceCStrings; if (!sourcePath.empty()) { sourceCStrings.push_back(sourcePath.c_str()); } sourceCStrings.push_back(sourceString.c_str()); bool result = ShCompile(compilerHandle, &sourceCStrings[0], sourceCStrings.size(), compileOptions); if (!result) { mInfoLog = ShGetInfoLog(compilerHandle); TRACE("\n%s", mInfoLog.c_str()); mCompiled = false; return; } mData.mTranslatedSource = ShGetObjectCode(compilerHandle); #ifndef NDEBUG // Prefix translated shader with commented out un-translated shader. // Useful in diagnostics tools which capture the shader source. std::ostringstream shaderStream; shaderStream << "// GLSL\n"; shaderStream << "//\n"; size_t curPos = 0; while (curPos != std::string::npos) { size_t nextLine = mData.mSource.find("\n", curPos); size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); shaderStream << "// " << mData.mSource.substr(curPos, len); curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); } shaderStream << "\n\n"; shaderStream << mData.mTranslatedSource; mData.mTranslatedSource = shaderStream.str(); #endif // Gather the shader information mData.mShaderVersion = ShGetShaderVersion(compilerHandle); mData.mVaryings = GetShaderVariables(ShGetVaryings(compilerHandle)); mData.mUniforms = GetShaderVariables(ShGetUniforms(compilerHandle)); mData.mInterfaceBlocks = GetShaderVariables(ShGetInterfaceBlocks(compilerHandle)); if (mData.mShaderType == GL_VERTEX_SHADER) { mData.mActiveAttributes = GetActiveShaderVariables(ShGetAttributes(compilerHandle)); } else { ASSERT(mData.mShaderType == GL_FRAGMENT_SHADER); // TODO(jmadill): Figure out why we only sort in the FS, and if we need to. std::sort(mData.mVaryings.begin(), mData.mVaryings.end(), CompareShaderVar); mData.mActiveOutputVariables = GetActiveShaderVariables(ShGetOutputVariables(compilerHandle)); } ASSERT(!mData.mTranslatedSource.empty()); mCompiled = mImplementation->postTranslateCompile(compiler, &mInfoLog); }
void ShaderD3D::compileToHLSL(void *compiler, const std::string &source) { // ensure the compiler is loaded initializeCompiler(); int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES); std::string sourcePath; #if !defined (ANGLE_ENABLE_WINDOWS_STORE) if (gl::perfActive()) { sourcePath = getTempPath(); writeFile(sourcePath.c_str(), source.c_str(), source.length()); compileOptions |= SH_LINE_DIRECTIVES; } #endif int result; if (sourcePath.empty()) { const char* sourceStrings[] = { source.c_str(), }; result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions); } else { const char* sourceStrings[] = { sourcePath.c_str(), source.c_str(), }; result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH); } mShaderVersion = ShGetShaderVersion(compiler); if (mShaderVersion == 300 && mRenderer->getCurrentClientVersion() < 3) { mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts"; TRACE("\n%s", mInfoLog.c_str()); } else if (result) { mHlsl = ShGetObjectCode(compiler); #ifdef _DEBUG // Prefix hlsl shader with commented out glsl shader // Useful in diagnostics tools like pix which capture the hlsl shaders std::ostringstream hlslStream; hlslStream << "// GLSL\n"; hlslStream << "//\n"; size_t curPos = 0; while (curPos != std::string::npos) { size_t nextLine = source.find("\n", curPos); size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); hlslStream << "// " << source.substr(curPos, len); curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); } hlslStream << "\n\n"; hlslStream << mHlsl; mHlsl = hlslStream.str(); #endif mUniforms = *GetShaderVariables(ShGetUniforms(compiler)); for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) { const sh::Uniform &uniform = mUniforms[uniformIndex]; if (uniform.staticUse) { unsigned int index = -1; bool result = ShGetUniformRegister(compiler, uniform.name, &index); UNUSED_ASSERTION_VARIABLE(result); ASSERT(result); mUniformRegisterMap[uniform.name] = index; } } mInterfaceBlocks = *GetShaderVariables(ShGetInterfaceBlocks(compiler)); for (size_t blockIndex = 0; blockIndex < mInterfaceBlocks.size(); blockIndex++) { const sh::InterfaceBlock &interfaceBlock = mInterfaceBlocks[blockIndex]; if (interfaceBlock.staticUse) { unsigned int index = -1; bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name, &index); UNUSED_ASSERTION_VARIABLE(result); ASSERT(result); mInterfaceBlockRegisterMap[interfaceBlock.name] = index; } } } else { mInfoLog = ShGetInfoLog(compiler); TRACE("\n%s", mInfoLog.c_str()); } }