tor-browser

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

renderer11_utils.h (14521B)


      1 //
      2 // Copyright 2012 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 // renderer11_utils.h: Conversion functions and other utility routines
      8 // specific to the D3D11 renderer.
      9 
     10 #ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
     11 #define LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
     12 
     13 #include <array>
     14 #include <functional>
     15 #include <vector>
     16 
     17 #include "common/Color.h"
     18 
     19 #include "libANGLE/Caps.h"
     20 #include "libANGLE/Error.h"
     21 #include "libANGLE/renderer/d3d/RendererD3D.h"
     22 #include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
     23 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
     24 
     25 namespace gl
     26 {
     27 class FramebufferAttachment;
     28 }
     29 
     30 namespace rx
     31 {
     32 class Context11;
     33 class Renderer11;
     34 class RenderTarget11;
     35 struct Renderer11DeviceCaps;
     36 
     37 using RTVArray = std::array<ID3D11RenderTargetView *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
     38 
     39 namespace gl_d3d11
     40 {
     41 
     42 D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha);
     43 D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp);
     44 UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha);
     45 
     46 D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode);
     47 
     48 D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison);
     49 D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled);
     50 UINT8 ConvertStencilMask(GLuint stencilmask);
     51 D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp);
     52 
     53 D3D11_FILTER ConvertFilter(GLenum minFilter,
     54                           GLenum magFilter,
     55                           float maxAnisotropy,
     56                           GLenum comparisonMode);
     57 D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap);
     58 UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel);
     59 
     60 D3D11_QUERY ConvertQueryType(gl::QueryType type);
     61 
     62 UINT8 GetColorMask(const gl::InternalFormat &formatInfo);
     63 
     64 }  // namespace gl_d3d11
     65 
     66 namespace d3d11_gl
     67 {
     68 
     69 unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel);
     70 
     71 unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel);
     72 
     73 gl::Version GetMaximumClientVersion(const Renderer11DeviceCaps &caps);
     74 void GenerateCaps(ID3D11Device *device,
     75                  ID3D11DeviceContext *deviceContext,
     76                  const Renderer11DeviceCaps &renderer11DeviceCaps,
     77                  const angle::FeaturesD3D &features,
     78                  const char *description,
     79                  gl::Caps *caps,
     80                  gl::TextureCapsMap *textureCapsMap,
     81                  gl::Extensions *extensions,
     82                  gl::Limitations *limitations);
     83 
     84 D3D_FEATURE_LEVEL GetMinimumFeatureLevelForES31();
     85 
     86 }  // namespace d3d11_gl
     87 
     88 namespace d3d11
     89 {
     90 
     91 enum ANGLED3D11DeviceType
     92 {
     93    ANGLE_D3D11_DEVICE_TYPE_UNKNOWN,
     94    ANGLE_D3D11_DEVICE_TYPE_HARDWARE,
     95    ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL,
     96    ANGLE_D3D11_DEVICE_TYPE_WARP,
     97 };
     98 
     99 ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device);
    100 
    101 void MakeValidSize(bool isImage,
    102                   DXGI_FORMAT format,
    103                   GLsizei *requestWidth,
    104                   GLsizei *requestHeight,
    105                   int *levelOffset);
    106 
    107 angle::Result GenerateInitialTextureData(
    108    const gl::Context *context,
    109    GLint internalFormat,
    110    const Renderer11DeviceCaps &renderer11DeviceCaps,
    111    GLuint width,
    112    GLuint height,
    113    GLuint depth,
    114    GLuint mipLevels,
    115    gl::TexLevelArray<D3D11_SUBRESOURCE_DATA> *outSubresourceData);
    116 
    117 UINT GetPrimitiveRestartIndex();
    118 
    119 struct PositionTexCoordVertex
    120 {
    121    float x, y;
    122    float u, v;
    123 };
    124 void SetPositionTexCoordVertex(PositionTexCoordVertex *vertex, float x, float y, float u, float v);
    125 
    126 struct PositionLayerTexCoord3DVertex
    127 {
    128    float x, y;
    129    unsigned int l;
    130    float u, v, s;
    131 };
    132 void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex *vertex,
    133                                      float x,
    134                                      float y,
    135                                      unsigned int layer,
    136                                      float u,
    137                                      float v,
    138                                      float s);
    139 
    140 struct PositionVertex
    141 {
    142    float x, y, z, w;
    143 };
    144 
    145 struct BlendStateKey final
    146 {
    147    // This will zero-initialize the struct, including padding.
    148    BlendStateKey();
    149    BlendStateKey(const BlendStateKey &other);
    150 
    151    gl::BlendStateExt blendStateExt;
    152 
    153    // Use two 16-bit ints to round the struct nicely.
    154    uint16_t rtvMax;
    155    uint16_t sampleAlphaToCoverage;
    156 };
    157 
    158 bool operator==(const BlendStateKey &a, const BlendStateKey &b);
    159 bool operator!=(const BlendStateKey &a, const BlendStateKey &b);
    160 
    161 struct RasterizerStateKey final
    162 {
    163    // This will zero-initialize the struct, including padding.
    164    RasterizerStateKey();
    165 
    166    gl::RasterizerState rasterizerState;
    167 
    168    // Use a 32-bit int to round the struct nicely.
    169    uint32_t scissorEnabled;
    170 };
    171 
    172 bool operator==(const RasterizerStateKey &a, const RasterizerStateKey &b);
    173 bool operator!=(const RasterizerStateKey &a, const RasterizerStateKey &b);
    174 
    175 template <typename outType>
    176 outType *DynamicCastComObject(IUnknown *object)
    177 {
    178    outType *outObject = nullptr;
    179    HRESULT result =
    180        object->QueryInterface(__uuidof(outType), reinterpret_cast<void **>(&outObject));
    181    if (SUCCEEDED(result))
    182    {
    183        return outObject;
    184    }
    185    else
    186    {
    187        SafeRelease(outObject);
    188        return nullptr;
    189    }
    190 }
    191 
    192 template <typename outType>
    193 angle::ComPtr<outType> DynamicCastComObjectToComPtr(IUnknown *object)
    194 {
    195    angle::ComPtr<outType> outObject;
    196    const HRESULT hr = object->QueryInterface(IID_PPV_ARGS(&outObject));
    197    if (SUCCEEDED(hr))
    198    {
    199        return outObject;
    200    }
    201    else
    202    {
    203        return nullptr;
    204    }
    205 }
    206 
    207 inline bool isDeviceLostError(HRESULT errorCode)
    208 {
    209    switch (errorCode)
    210    {
    211        case DXGI_ERROR_DEVICE_HUNG:
    212        case DXGI_ERROR_DEVICE_REMOVED:
    213        case DXGI_ERROR_DEVICE_RESET:
    214        case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
    215        case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
    216            return true;
    217        default:
    218            return false;
    219    }
    220 }
    221 
    222 template <ResourceType ResourceT>
    223 class LazyResource : angle::NonCopyable
    224 {
    225  public:
    226    constexpr LazyResource() : mResource() {}
    227    virtual ~LazyResource() {}
    228 
    229    virtual angle::Result resolve(d3d::Context *context, Renderer11 *renderer) = 0;
    230    void reset() { mResource.reset(); }
    231    GetD3D11Type<ResourceT> *get() const
    232    {
    233        ASSERT(mResource.valid());
    234        return mResource.get();
    235    }
    236 
    237    const Resource11<GetD3D11Type<ResourceT>> &getObj() const { return mResource; }
    238 
    239  protected:
    240    LazyResource(LazyResource &&other) : mResource(std::move(other.mResource)) {}
    241 
    242    // Specialized in the cpp file to avoid MSVS/Clang specific code.
    243    angle::Result resolveImpl(d3d::Context *context,
    244                              Renderer11 *renderer,
    245                              const GetDescType<ResourceT> &desc,
    246                              GetInitDataType<ResourceT> *initData,
    247                              const char *name);
    248 
    249    Resource11<GetD3D11Type<ResourceT>> mResource;
    250 };
    251 
    252 template <typename D3D11ShaderType>
    253 class LazyShader final : public LazyResource<GetResourceTypeFromD3D11<D3D11ShaderType>()>
    254 {
    255  public:
    256    // All parameters must be constexpr. Not supported in VS2013.
    257    constexpr LazyShader(const BYTE *byteCode, size_t byteCodeSize, const char *name)
    258        : mByteCode(byteCode, byteCodeSize), mName(name)
    259    {}
    260 
    261    constexpr LazyShader(LazyShader &&shader)
    262        : LazyResource<GetResourceTypeFromD3D11<D3D11ShaderType>()>(std::move(shader)),
    263          mByteCode(std::move(shader.mByteCode)),
    264          mName(shader.mName)
    265    {}
    266 
    267    angle::Result resolve(d3d::Context *context, Renderer11 *renderer) override
    268    {
    269        return this->resolveImpl(context, renderer, mByteCode, nullptr, mName);
    270    }
    271 
    272  private:
    273    ShaderData mByteCode;
    274    const char *mName;
    275 };
    276 
    277 class LazyInputLayout final : public LazyResource<ResourceType::InputLayout>
    278 {
    279  public:
    280    LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc,
    281                    size_t inputDescLen,
    282                    const BYTE *byteCode,
    283                    size_t byteCodeLen,
    284                    const char *debugName);
    285    ~LazyInputLayout() override;
    286 
    287    angle::Result resolve(d3d::Context *context, Renderer11 *renderer) override;
    288 
    289  private:
    290    InputElementArray mInputDesc;
    291    ShaderData mByteCode;
    292    const char *mDebugName;
    293 };
    294 
    295 class LazyBlendState final : public LazyResource<ResourceType::BlendState>
    296 {
    297  public:
    298    LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName);
    299 
    300    angle::Result resolve(d3d::Context *context, Renderer11 *renderer) override;
    301 
    302  private:
    303    D3D11_BLEND_DESC mDesc;
    304    const char *mDebugName;
    305 };
    306 
    307 // Copy data to small D3D11 buffers, such as for small constant buffers, which use one struct to
    308 // represent an entire buffer.
    309 template <class T>
    310 void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, const T &value)
    311 {
    312    D3D11_MAPPED_SUBRESOURCE mappedResource = {};
    313    HRESULT result = context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
    314    ASSERT(SUCCEEDED(result));
    315    if (SUCCEEDED(result))
    316    {
    317        memcpy(mappedResource.pData, &value, sizeof(T));
    318        context->Unmap(constantBuffer, 0);
    319    }
    320 }
    321 
    322 void InitializeFeatures(const Renderer11DeviceCaps &deviceCaps,
    323                        const DXGI_ADAPTER_DESC &adapterDesc,
    324                        angle::FeaturesD3D *features);
    325 
    326 void InitializeFrontendFeatures(const DXGI_ADAPTER_DESC &adapterDesc,
    327                                angle::FrontendFeatures *features);
    328 
    329 enum ReservedConstantBufferSlot
    330 {
    331    RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK = 0,
    332    RESERVED_CONSTANT_BUFFER_SLOT_DRIVER                = 1,
    333 
    334    RESERVED_CONSTANT_BUFFER_SLOT_COUNT = 2
    335 };
    336 
    337 void InitConstantBufferDesc(D3D11_BUFFER_DESC *constantBufferDescription, size_t byteWidth);
    338 
    339 // Helper class for RAII patterning.
    340 template <typename T>
    341 class [[nodiscard]] ScopedUnmapper final : angle::NonCopyable
    342 {
    343  public:
    344    ScopedUnmapper(T *object) : mObject(object) {}
    345    ~ScopedUnmapper() { mObject->unmap(); }
    346 
    347  private:
    348    T *mObject;
    349 };
    350 }  // namespace d3d11
    351 
    352 struct GenericData
    353 {
    354    GenericData() {}
    355    ~GenericData()
    356    {
    357        if (object)
    358        {
    359            // We can have a nullptr factory when holding passed-in resources.
    360            if (manager)
    361            {
    362                manager->onReleaseGeneric(resourceType, object);
    363                manager = nullptr;
    364            }
    365            object->Release();
    366            object = nullptr;
    367        }
    368    }
    369 
    370    ResourceType resourceType  = ResourceType::Last;
    371    ID3D11Resource *object     = nullptr;
    372    ResourceManager11 *manager = nullptr;
    373 };
    374 
    375 // A helper class which wraps a 2D or 3D texture.
    376 class TextureHelper11 : public Resource11Base<ID3D11Resource, std::shared_ptr, GenericData>
    377 {
    378  public:
    379    TextureHelper11();
    380    TextureHelper11(TextureHelper11 &&other);
    381    TextureHelper11(const TextureHelper11 &other);
    382    ~TextureHelper11() override;
    383    TextureHelper11 &operator=(TextureHelper11 &&other);
    384    TextureHelper11 &operator=(const TextureHelper11 &other);
    385 
    386    bool isBuffer() const { return mData->resourceType == ResourceType::Buffer; }
    387    bool is2D() const { return mData->resourceType == ResourceType::Texture2D; }
    388    bool is3D() const { return mData->resourceType == ResourceType::Texture3D; }
    389    ResourceType getTextureType() const { return mData->resourceType; }
    390    gl::Extents getExtents() const { return mExtents; }
    391    DXGI_FORMAT getFormat() const { return mFormatSet->texFormat; }
    392    const d3d11::Format &getFormatSet() const { return *mFormatSet; }
    393    int getSampleCount() const { return mSampleCount; }
    394 
    395    template <typename DescT, typename ResourceT>
    396    void init(Resource11<ResourceT> &&texture, const DescT &desc, const d3d11::Format &format)
    397    {
    398        std::swap(mData->manager, texture.mData->manager);
    399 
    400        // Can't use std::swap because texture is typed, and here we use ID3D11Resource.
    401        ID3D11Resource *temp  = mData->object;
    402        mData->object         = texture.mData->object;
    403        texture.mData->object = static_cast<ResourceT *>(temp);
    404 
    405        mFormatSet = &format;
    406        initDesc(desc);
    407    }
    408 
    409    template <typename ResourceT>
    410    void set(ResourceT *object, const d3d11::Format &format)
    411    {
    412        ASSERT(!valid());
    413 
    414        mFormatSet     = &format;
    415        mData->object  = object;
    416        mData->manager = nullptr;
    417 
    418        GetDescFromD3D11<ResourceT> desc;
    419        getDesc(&desc);
    420        initDesc(desc);
    421    }
    422 
    423    bool operator==(const TextureHelper11 &other) const;
    424    bool operator!=(const TextureHelper11 &other) const;
    425 
    426    void getDesc(D3D11_TEXTURE2D_DESC *desc) const;
    427    void getDesc(D3D11_TEXTURE3D_DESC *desc) const;
    428    void getDesc(D3D11_BUFFER_DESC *desc) const;
    429 
    430  private:
    431    void initDesc(const D3D11_TEXTURE2D_DESC &desc2D);
    432    void initDesc(const D3D11_TEXTURE3D_DESC &desc3D);
    433    void initDesc(const D3D11_BUFFER_DESC &descBuffer);
    434 
    435    const d3d11::Format *mFormatSet;
    436    gl::Extents mExtents;
    437    int mSampleCount;
    438 };
    439 
    440 enum class StagingAccess
    441 {
    442    READ,
    443    READ_WRITE,
    444 };
    445 
    446 bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachment *colorbuffer);
    447 bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled,
    448                                   gl::DrawElementsType type);
    449 
    450 enum class IndexStorageType
    451 {
    452    // Dynamic indexes are re-streamed every frame. They come from a client data pointer or
    453    // from buffers that are updated frequently.
    454    Dynamic,
    455 
    456    // Static indexes are translated from the original storage once, and re-used multiple times.
    457    Static,
    458 
    459    // Direct indexes are never transated and are used directly from the source buffer. They are
    460    // the fastest available path.
    461    Direct,
    462 
    463    // Not a real storage type.
    464    Invalid,
    465 };
    466 
    467 IndexStorageType ClassifyIndexStorage(const gl::State &glState,
    468                                      const gl::Buffer *elementArrayBuffer,
    469                                      gl::DrawElementsType elementType,
    470                                      gl::DrawElementsType destElementType,
    471                                      unsigned int offset);
    472 
    473 bool SwizzleRequired(const gl::TextureState &textureState);
    474 gl::SwizzleState GetEffectiveSwizzle(const gl::TextureState &textureState);
    475 
    476 }  // namespace rx
    477 
    478 #endif  // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_