aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrDrawTargetCaps.h
blob: ae6a9ed7492db5eddda716d5ef77abf308c505f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#ifndef GrDrawTargetCaps_DEFINED
#define GrDrawTargetCaps_DEFINED

#include "GrTypes.h"
#include "GrTypesPriv.h"
#include "GrShaderVar.h"
#include "SkRefCnt.h"
#include "SkString.h"

/**
 * Represents the draw target capabilities.
 */
class GrDrawTargetCaps : public SkRefCnt {
public:
    SK_DECLARE_INST_COUNT(GrDrawTargetCaps)

    /** Info about shader variable precision within a given shader stage. That is, this info
        is relevant to a float (or vecNf) variable declared with a GrShaderVar::Precision 
        in a given GrShaderType. The info here is hoisted from the OpenGL spec. */
    struct PrecisionInfo {
        PrecisionInfo() {
            fLogRangeLow = 0;
            fLogRangeHigh = 0;
            fBits = 0;
        }

        /** Is this precision level allowed in the shader stage? */
        bool supported() const { return 0 != fBits; }

        bool operator==(const PrecisionInfo& that) const {
            return fLogRangeLow == that.fLogRangeLow && fLogRangeHigh == that.fLogRangeHigh &&
                   fBits == that.fBits;
        }
        bool operator!=(const PrecisionInfo& that) const { return !(*this == that); }

        /** floor(log2(|min_value|)) */
        int fLogRangeLow;
        /** floor(log2(|max_value|)) */
        int fLogRangeHigh;
        /** Number of bits of precision. As defined in OpenGL (with names modified to reflect this 
            struct) :
            """
                If the smallest representable value greater than 1 is 1 + e, then fBits will
                contain floor(log2(e)), and every value in the range [2^fLogRangeLow,
                2^fLogRangeHigh] can be represented to at least one part in 2^fBits.
            """  
          */
        int fBits;
    };


    GrDrawTargetCaps() : fUniqueID(CreateUniqueID()) {
        this->reset();
    }
    GrDrawTargetCaps(const GrDrawTargetCaps& other) : INHERITED(), fUniqueID(CreateUniqueID()) {
        *this = other;
    }
    GrDrawTargetCaps& operator= (const GrDrawTargetCaps&);

    virtual void reset();
    virtual SkString dump() const;

    bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
    /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g.
        only for POT textures) */
    bool mipMapSupport() const { return fMipMapSupport; }
    bool twoSidedStencilSupport() const { return fTwoSidedStencilSupport; }
    bool stencilWrapOpsSupport() const { return  fStencilWrapOpsSupport; }
    bool hwAALineSupport() const { return fHWAALineSupport; }
    bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; }
    bool geometryShaderSupport() const { return fGeometryShaderSupport; }
    bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
    bool pathRenderingSupport() const { return fPathRenderingSupport; }
    bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
    bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; }
    bool gpuTracingSupport() const { return fGpuTracingSupport; }
    bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; }

    bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; }

    /**
     * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and
     * textures allows partial mappings or full mappings.
     */
    enum MapFlags {
        kNone_MapFlags   = 0x0,       //<! Cannot map the resource.

        kCanMap_MapFlag  = 0x1,       //<! The resource can be mapped. Must be set for any of
                                      //   the other flags to have meaning.k
        kSubset_MapFlag  = 0x2,       //<! The resource can be partially mapped.
    };

    uint32_t mapBufferFlags() const { return fMapBufferFlags; }

    // Scratch textures not being reused means that those scratch textures
    // that we upload to (i.e., don't have a render target) will not be
    // recycled in the texture cache. This is to prevent ghosting by drivers
    // (in particular for deferred architectures).
    bool reuseScratchTextures() const { return fReuseScratchTextures; }

    int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
    int maxTextureSize() const { return fMaxTextureSize; }
    // Will be 0 if MSAA is not supported
    int maxSampleCount() const { return fMaxSampleCount; }

    bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const {
        SkASSERT(kGrPixelConfigCnt > config);
        return fConfigRenderSupport[config][withMSAA];
    }

    bool isConfigTexturable(GrPixelConfig config) const {
        SkASSERT(kGrPixelConfigCnt > config);
        return fConfigTextureSupport[config];
    }

    /**
     * Get the precision info for a variable of type kFloat_GrSLType, kVec2f_GrSLType, etc in a
     * given shader type. If the shader type is not supported or the precision level is not
     * supported in that shader type then the returned struct will report false when supported() is
     * called.
     */
    const PrecisionInfo& getFloatShaderPrecisionInfo(GrShaderType shaderType,
                                                     GrShaderVar::Precision precision) const {
        return fFloatPrecisions[shaderType][precision];
    };

    /**
     * Is there any difference between the float shader variable precision types? If this is true
     * then unless the shader type is not supported, any call to getFloatShaderPrecisionInfo() would
     * report the same info for all precisions in all shader types.
     */
    bool floatPrecisionVaries() const { return fShaderPrecisionVaries; }

    /**
     * Gets an id that is unique for this GrDrawTargetCaps object. It is static in that it does
     * not change when the content of the GrDrawTargetCaps object changes. This will never return
     * 0.
     */
    uint32_t getUniqueID() const { return fUniqueID; }

protected:
    bool fNPOTTextureTileSupport    : 1;
    bool fMipMapSupport             : 1;
    bool fTwoSidedStencilSupport    : 1;
    bool fStencilWrapOpsSupport     : 1;
    bool fHWAALineSupport           : 1;
    bool fShaderDerivativeSupport   : 1;
    bool fGeometryShaderSupport     : 1;
    bool fDualSourceBlendingSupport : 1;
    bool fPathRenderingSupport      : 1;
    bool fDstReadInShaderSupport    : 1;
    bool fDiscardRenderTargetSupport: 1;
    bool fReuseScratchTextures      : 1;
    bool fGpuTracingSupport         : 1;
    bool fCompressedTexSubImageSupport : 1;

    // Driver workaround
    bool fUseDrawInsteadOfClear     : 1;

    uint32_t fMapBufferFlags;

    int fMaxRenderTargetSize;
    int fMaxTextureSize;
    int fMaxSampleCount;

    // The first entry for each config is without msaa and the second is with.
    bool fConfigRenderSupport[kGrPixelConfigCnt][2];
    bool fConfigTextureSupport[kGrPixelConfigCnt];

    bool fShaderPrecisionVaries;
    PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][GrShaderVar::kPrecisionCount];

private:
    static uint32_t CreateUniqueID();

    const uint32_t          fUniqueID;

    typedef SkRefCnt INHERITED;
};

#endif