tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ShaderD3D.cpp (14188B)


      1 //
      2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // ShaderD3D.cpp: Defines the rx::ShaderD3D class which implements rx::ShaderImpl.
      8 
      9 #include "libANGLE/renderer/d3d/ShaderD3D.h"
     10 
     11 #include "common/system_utils.h"
     12 #include "common/utilities.h"
     13 #include "libANGLE/Caps.h"
     14 #include "libANGLE/Compiler.h"
     15 #include "libANGLE/Context.h"
     16 #include "libANGLE/Shader.h"
     17 #include "libANGLE/features.h"
     18 #include "libANGLE/renderer/ContextImpl.h"
     19 #include "libANGLE/renderer/d3d/ProgramD3D.h"
     20 #include "libANGLE/renderer/d3d/RendererD3D.h"
     21 #include "libANGLE/trace.h"
     22 
     23 namespace rx
     24 {
     25 
     26 class TranslateTaskD3D : public angle::Closure
     27 {
     28  public:
     29    TranslateTaskD3D(ShHandle handle,
     30                     const ShCompileOptions &options,
     31                     const std::string &source,
     32                     const std::string &sourcePath)
     33        : mHandle(handle),
     34          mOptions(options),
     35          mSource(source),
     36          mSourcePath(sourcePath),
     37          mResult(false)
     38    {}
     39 
     40    void operator()() override
     41    {
     42        ANGLE_TRACE_EVENT1("gpu.angle", "TranslateTask::run", "source", mSource);
     43        std::vector<const char *> srcStrings;
     44        if (!mSourcePath.empty())
     45        {
     46            srcStrings.push_back(mSourcePath.c_str());
     47        }
     48        srcStrings.push_back(mSource.c_str());
     49 
     50        mResult = sh::Compile(mHandle, &srcStrings[0], srcStrings.size(), mOptions);
     51    }
     52 
     53    bool getResult() { return mResult; }
     54 
     55  private:
     56    ShHandle mHandle;
     57    ShCompileOptions mOptions;
     58    std::string mSource;
     59    std::string mSourcePath;
     60    bool mResult;
     61 };
     62 
     63 using PostTranslateFunctor =
     64    std::function<bool(gl::ShCompilerInstance *compiler, std::string *infoLog)>;
     65 
     66 class WaitableCompileEventD3D final : public WaitableCompileEvent
     67 {
     68  public:
     69    WaitableCompileEventD3D(std::shared_ptr<angle::WaitableEvent> waitableEvent,
     70                            gl::ShCompilerInstance *compilerInstance,
     71                            PostTranslateFunctor &&postTranslateFunctor,
     72                            std::shared_ptr<TranslateTaskD3D> translateTask)
     73        : WaitableCompileEvent(waitableEvent),
     74          mCompilerInstance(compilerInstance),
     75          mPostTranslateFunctor(std::move(postTranslateFunctor)),
     76          mTranslateTask(translateTask)
     77    {}
     78 
     79    bool getResult() override { return mTranslateTask->getResult(); }
     80 
     81    bool postTranslate(std::string *infoLog) override
     82    {
     83        return mPostTranslateFunctor(mCompilerInstance, infoLog);
     84    }
     85 
     86  private:
     87    gl::ShCompilerInstance *mCompilerInstance;
     88    PostTranslateFunctor mPostTranslateFunctor;
     89    std::shared_ptr<TranslateTaskD3D> mTranslateTask;
     90 };
     91 
     92 ShaderD3D::ShaderD3D(const gl::ShaderState &state, RendererD3D *renderer)
     93    : ShaderImpl(state), mRenderer(renderer)
     94 {
     95    uncompile();
     96 }
     97 
     98 ShaderD3D::~ShaderD3D() {}
     99 
    100 std::string ShaderD3D::getDebugInfo() const
    101 {
    102    if (mDebugInfo.empty())
    103    {
    104        return "";
    105    }
    106 
    107    return mDebugInfo + std::string("\n// ") + gl::GetShaderTypeString(mState.getShaderType()) +
    108           " SHADER END\n";
    109 }
    110 
    111 // initialize/clean up previous state
    112 void ShaderD3D::uncompile()
    113 {
    114    // set by compileToHLSL
    115    mCompilerOutputType = SH_ESSL_OUTPUT;
    116 
    117    mUsesMultipleRenderTargets   = false;
    118    mUsesFragColor               = false;
    119    mUsesFragData                = false;
    120    mUsesSecondaryColor          = false;
    121    mUsesFragCoord               = false;
    122    mUsesFrontFacing             = false;
    123    mUsesHelperInvocation        = false;
    124    mUsesPointSize               = false;
    125    mUsesPointCoord              = false;
    126    mUsesDepthRange              = false;
    127    mUsesFragDepth               = false;
    128    mHasANGLEMultiviewEnabled    = false;
    129    mUsesVertexID                = false;
    130    mUsesViewID                  = false;
    131    mUsesDiscardRewriting        = false;
    132    mUsesNestedBreak             = false;
    133    mRequiresIEEEStrictCompiling = false;
    134 
    135    mDebugInfo.clear();
    136 }
    137 
    138 void ShaderD3D::generateWorkarounds(CompilerWorkaroundsD3D *workarounds) const
    139 {
    140    if (mUsesDiscardRewriting)
    141    {
    142        // ANGLE issue 486:
    143        // Work-around a D3D9 compiler bug that presents itself when using conditional discard, by
    144        // disabling optimization
    145        workarounds->skipOptimization = true;
    146    }
    147    else if (mUsesNestedBreak)
    148    {
    149        // ANGLE issue 603:
    150        // Work-around a D3D9 compiler bug that presents itself when using break in a nested loop,
    151        // by maximizing optimization We want to keep the use of
    152        // ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION minimal to prevent hangs, so usesDiscard takes
    153        // precedence
    154        workarounds->useMaxOptimization = true;
    155    }
    156 
    157    if (mRequiresIEEEStrictCompiling)
    158    {
    159        // IEEE Strictness for D3D compiler needs to be enabled for NaNs to work.
    160        workarounds->enableIEEEStrictness = true;
    161    }
    162 }
    163 
    164 unsigned int ShaderD3D::getUniformRegister(const std::string &uniformName) const
    165 {
    166    ASSERT(mUniformRegisterMap.count(uniformName) > 0);
    167    return mUniformRegisterMap.find(uniformName)->second;
    168 }
    169 
    170 unsigned int ShaderD3D::getUniformBlockRegister(const std::string &blockName) const
    171 {
    172    ASSERT(mUniformBlockRegisterMap.count(blockName) > 0);
    173    return mUniformBlockRegisterMap.find(blockName)->second;
    174 }
    175 
    176 bool ShaderD3D::shouldUniformBlockUseStructuredBuffer(const std::string &blockName) const
    177 {
    178    ASSERT(mUniformBlockUseStructuredBufferMap.count(blockName) > 0);
    179    return mUniformBlockUseStructuredBufferMap.find(blockName)->second;
    180 }
    181 
    182 unsigned int ShaderD3D::getShaderStorageBlockRegister(const std::string &blockName) const
    183 {
    184    ASSERT(mShaderStorageBlockRegisterMap.count(blockName) > 0);
    185    return mShaderStorageBlockRegisterMap.find(blockName)->second;
    186 }
    187 
    188 ShShaderOutput ShaderD3D::getCompilerOutputType() const
    189 {
    190    return mCompilerOutputType;
    191 }
    192 
    193 bool ShaderD3D::useImage2DFunction(const std::string &functionName) const
    194 {
    195    if (mUsedImage2DFunctionNames.empty())
    196    {
    197        return false;
    198    }
    199 
    200    return mUsedImage2DFunctionNames.find(functionName) != mUsedImage2DFunctionNames.end();
    201 }
    202 
    203 const std::set<std::string> &ShaderD3D::getSlowCompilingUniformBlockSet() const
    204 {
    205    return mSlowCompilingUniformBlockSet;
    206 }
    207 
    208 const std::map<std::string, unsigned int> &GetUniformRegisterMap(
    209    const std::map<std::string, unsigned int> *uniformRegisterMap)
    210 {
    211    ASSERT(uniformRegisterMap);
    212    return *uniformRegisterMap;
    213 }
    214 
    215 const std::set<std::string> &GetSlowCompilingUniformBlockSet(
    216    const std::set<std::string> *slowCompilingUniformBlockSet)
    217 {
    218    ASSERT(slowCompilingUniformBlockSet);
    219    return *slowCompilingUniformBlockSet;
    220 }
    221 
    222 const std::set<std::string> &GetUsedImage2DFunctionNames(
    223    const std::set<std::string> *usedImage2DFunctionNames)
    224 {
    225    ASSERT(usedImage2DFunctionNames);
    226    return *usedImage2DFunctionNames;
    227 }
    228 
    229 std::shared_ptr<WaitableCompileEvent> ShaderD3D::compile(const gl::Context *context,
    230                                                         gl::ShCompilerInstance *compilerInstance,
    231                                                         ShCompileOptions *options)
    232 {
    233    std::string sourcePath;
    234    uncompile();
    235 
    236    const angle::FeaturesD3D &features = mRenderer->getFeatures();
    237    const gl::Extensions &extensions   = mRenderer->getNativeExtensions();
    238 
    239    const std::string &source = mState.getSource();
    240 
    241 #if !defined(ANGLE_ENABLE_WINDOWS_UWP)
    242    if (gl::DebugAnnotationsActive(context))
    243    {
    244        sourcePath = angle::CreateTemporaryFile().value();
    245        writeFile(sourcePath.c_str(), source.c_str(), source.length());
    246        options->lineDirectives = true;
    247        options->sourcePath     = true;
    248    }
    249 #endif
    250 
    251    if (features.expandIntegerPowExpressions.enabled)
    252    {
    253        options->expandSelectHLSLIntegerPowExpressions = true;
    254    }
    255 
    256    if (features.getDimensionsIgnoresBaseLevel.enabled)
    257    {
    258        options->HLSLGetDimensionsIgnoresBaseLevel = true;
    259    }
    260 
    261    if (features.preAddTexelFetchOffsets.enabled)
    262    {
    263        options->rewriteTexelFetchOffsetToTexelFetch = true;
    264    }
    265    if (features.rewriteUnaryMinusOperator.enabled)
    266    {
    267        options->rewriteIntegerUnaryMinusOperator = true;
    268    }
    269    if (features.emulateIsnanFloat.enabled)
    270    {
    271        options->emulateIsnanFloatFunction = true;
    272    }
    273    if (features.skipVSConstantRegisterZero.enabled &&
    274        mState.getShaderType() == gl::ShaderType::Vertex)
    275    {
    276        options->skipD3DConstantRegisterZero = true;
    277    }
    278    if (features.forceAtomicValueResolution.enabled)
    279    {
    280        options->forceAtomicValueResolution = true;
    281    }
    282    if (features.allowTranslateUniformBlockToStructuredBuffer.enabled)
    283    {
    284        options->allowTranslateUniformBlockToStructuredBuffer = true;
    285    }
    286    if (extensions.multiviewOVR || extensions.multiview2OVR)
    287    {
    288        options->initializeBuiltinsForInstancedMultiview = true;
    289    }
    290    if (extensions.shaderPixelLocalStorageANGLE)
    291    {
    292        options->pls.type = mRenderer->getNativePixelLocalStorageType();
    293        if (extensions.shaderPixelLocalStorageCoherentANGLE)
    294        {
    295            options->pls.fragmentSynchronizationType =
    296                ShFragmentSynchronizationType::RasterizerOrderViews_D3D;
    297        }
    298    }
    299 
    300    auto postTranslateFunctor = [this](gl::ShCompilerInstance *compiler, std::string *infoLog) {
    301        // TODO(jmadill): We shouldn't need to cache this.
    302        mCompilerOutputType = compiler->getShaderOutputType();
    303 
    304        const std::string &translatedSource = mState.getTranslatedSource();
    305 
    306        mUsesMultipleRenderTargets = translatedSource.find("GL_USES_MRT") != std::string::npos;
    307        mUsesFragColor      = translatedSource.find("GL_USES_FRAG_COLOR") != std::string::npos;
    308        mUsesFragData       = translatedSource.find("GL_USES_FRAG_DATA") != std::string::npos;
    309        mUsesSecondaryColor = translatedSource.find("GL_USES_SECONDARY_COLOR") != std::string::npos;
    310        mUsesFragCoord      = translatedSource.find("GL_USES_FRAG_COORD") != std::string::npos;
    311        mUsesFrontFacing    = translatedSource.find("GL_USES_FRONT_FACING") != std::string::npos;
    312        mUsesHelperInvocation =
    313            translatedSource.find("GL_USES_HELPER_INVOCATION") != std::string::npos;
    314        mUsesPointSize  = translatedSource.find("GL_USES_POINT_SIZE") != std::string::npos;
    315        mUsesPointCoord = translatedSource.find("GL_USES_POINT_COORD") != std::string::npos;
    316        mUsesDepthRange = translatedSource.find("GL_USES_DEPTH_RANGE") != std::string::npos;
    317        mUsesFragDepth  = translatedSource.find("GL_USES_FRAG_DEPTH") != std::string::npos;
    318        mHasANGLEMultiviewEnabled =
    319            translatedSource.find("GL_ANGLE_MULTIVIEW_ENABLED") != std::string::npos;
    320        mUsesVertexID = translatedSource.find("GL_USES_VERTEX_ID") != std::string::npos;
    321        mUsesViewID   = translatedSource.find("GL_USES_VIEW_ID") != std::string::npos;
    322        mUsesDiscardRewriting =
    323            translatedSource.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos;
    324        mUsesNestedBreak = translatedSource.find("ANGLE_USES_NESTED_BREAK") != std::string::npos;
    325        mRequiresIEEEStrictCompiling =
    326            translatedSource.find("ANGLE_REQUIRES_IEEE_STRICT_COMPILING") != std::string::npos;
    327 
    328        ShHandle compilerHandle = compiler->getHandle();
    329 
    330        mUniformRegisterMap = GetUniformRegisterMap(sh::GetUniformRegisterMap(compilerHandle));
    331        mReadonlyImage2DRegisterIndex = sh::GetReadonlyImage2DRegisterIndex(compilerHandle);
    332        mImage2DRegisterIndex         = sh::GetImage2DRegisterIndex(compilerHandle);
    333        mUsedImage2DFunctionNames =
    334            GetUsedImage2DFunctionNames(sh::GetUsedImage2DFunctionNames(compilerHandle));
    335 
    336        for (const sh::InterfaceBlock &interfaceBlock : mState.getUniformBlocks())
    337        {
    338            if (interfaceBlock.active)
    339            {
    340                unsigned int index = static_cast<unsigned int>(-1);
    341                bool blockRegisterResult =
    342                    sh::GetUniformBlockRegister(compilerHandle, interfaceBlock.name, &index);
    343                ASSERT(blockRegisterResult);
    344                bool useStructuredBuffer =
    345                    sh::ShouldUniformBlockUseStructuredBuffer(compilerHandle, interfaceBlock.name);
    346 
    347                mUniformBlockRegisterMap[interfaceBlock.name]            = index;
    348                mUniformBlockUseStructuredBufferMap[interfaceBlock.name] = useStructuredBuffer;
    349            }
    350        }
    351 
    352        mSlowCompilingUniformBlockSet =
    353            GetSlowCompilingUniformBlockSet(sh::GetSlowCompilingUniformBlockSet(compilerHandle));
    354 
    355        for (const sh::InterfaceBlock &interfaceBlock : mState.getShaderStorageBlocks())
    356        {
    357            if (interfaceBlock.active)
    358            {
    359                unsigned int index = static_cast<unsigned int>(-1);
    360                bool blockRegisterResult =
    361                    sh::GetShaderStorageBlockRegister(compilerHandle, interfaceBlock.name, &index);
    362                ASSERT(blockRegisterResult);
    363 
    364                mShaderStorageBlockRegisterMap[interfaceBlock.name] = index;
    365            }
    366        }
    367 
    368        mDebugInfo += std::string("// ") + gl::GetShaderTypeString(mState.getShaderType()) +
    369                      " SHADER BEGIN\n";
    370        mDebugInfo += "\n// GLSL BEGIN\n\n" + mState.getSource() + "\n\n// GLSL END\n\n\n";
    371        mDebugInfo +=
    372            "// INITIAL HLSL BEGIN\n\n" + translatedSource + "\n// INITIAL HLSL END\n\n\n";
    373        // Successive steps will append more info
    374        return true;
    375    };
    376 
    377    auto workerThreadPool = context->getWorkerThreadPool();
    378    auto translateTask = std::make_shared<TranslateTaskD3D>(compilerInstance->getHandle(), *options,
    379                                                            source, sourcePath);
    380 
    381    return std::make_shared<WaitableCompileEventD3D>(
    382        angle::WorkerThreadPool::PostWorkerTask(workerThreadPool, translateTask), compilerInstance,
    383        std::move(postTranslateFunctor), translateTask);
    384 }
    385 
    386 bool ShaderD3D::hasUniform(const std::string &name) const
    387 {
    388    return mUniformRegisterMap.find(name) != mUniformRegisterMap.end();
    389 }
    390 
    391 }  // namespace rx