• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/gpu/dawn/GrDawnCaps.h"
9 
10 #include "src/gpu/GrProgramDesc.h"
11 #include "src/gpu/GrProgramInfo.h"
12 #include "src/gpu/GrRenderTarget.h"
13 #include "src/gpu/GrStencilSettings.h"
14 
GrDawnCaps(const GrContextOptions & contextOptions)15 GrDawnCaps::GrDawnCaps(const GrContextOptions& contextOptions) : INHERITED(contextOptions) {
16     fMipmapSupport = true;
17     fBufferMapThreshold = SK_MaxS32;  // FIXME: get this from Dawn?
18     fShaderCaps = std::make_unique<GrShaderCaps>();
19     fMaxTextureSize = fMaxRenderTargetSize = 8192; // FIXME
20     fMaxVertexAttributes = 16; // FIXME
21     fClampToBorderSupport = false;
22     fPerformPartialClearsAsDraws = true;
23     fDynamicStateArrayGeometryProcessorTextureSupport = true;
24 
25     fShaderCaps->fFlatInterpolationSupport = true;
26     fShaderCaps->fIntegerSupport = true;
27     // FIXME: each fragment sampler takes two binding slots in Dawn (sampler + texture). Limit to
28     // 6 * 2 = 12, since kMaxBindingsPerGroup is 16 in Dawn, and we need to keep a few for
29     // non-texture bindings. Eventually, we may be able to increase kMaxBindingsPerGroup in Dawn.
30     fShaderCaps->fMaxFragmentSamplers = 6;
31     fShaderCaps->fShaderDerivativeSupport = true;
32 
33     this->finishInitialization(contextOptions);
34 }
35 
isFormatSRGB(const GrBackendFormat & format) const36 bool GrDawnCaps::isFormatSRGB(const GrBackendFormat& format) const {
37     return false;
38 }
39 
isFormatTexturable(const GrBackendFormat & format,GrTextureType) const40 bool GrDawnCaps::isFormatTexturable(const GrBackendFormat& format, GrTextureType) const {
41     // Currently, all the formats in GrDawnFormatToPixelConfig are texturable.
42     wgpu::TextureFormat dawnFormat;
43     return format.asDawnFormat(&dawnFormat);
44 }
45 
get_swizzle(const GrBackendFormat & format,GrColorType colorType,bool forOutput)46 static GrSwizzle get_swizzle(const GrBackendFormat& format, GrColorType colorType,
47                              bool forOutput) {
48     switch (colorType) {
49         case GrColorType::kAlpha_8: // fall through
50         case GrColorType::kAlpha_F16:
51             if (forOutput) {
52                 return GrSwizzle("a000");
53             } else {
54                 return GrSwizzle("000r");
55             }
56         case GrColorType::kGray_8:
57             if (!forOutput) {
58                 return GrSwizzle::RRRA();
59             }
60             break;
61         case GrColorType::kRGB_888x:
62             if (!forOutput) {
63                 return GrSwizzle::RGB1();
64             }
65             break;
66         default:
67             return GrSwizzle::RGBA();
68     }
69     return GrSwizzle::RGBA();
70 }
71 
isFormatRenderable(const GrBackendFormat & format,int sampleCount) const72 bool GrDawnCaps::isFormatRenderable(const GrBackendFormat& format,
73                                     int sampleCount) const {
74     wgpu::TextureFormat dawnFormat;
75     if (!format.isValid() || sampleCount > 1 || !format.asDawnFormat(&dawnFormat)) {
76         return false;
77     }
78 
79     return GrDawnFormatIsRenderable(dawnFormat);
80 }
81 
isFormatAsColorTypeRenderable(GrColorType ct,const GrBackendFormat & format,int sampleCount) const82 bool GrDawnCaps::isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
83                                                int sampleCount) const {
84     return isFormatRenderable(format, sampleCount);
85 }
86 
surfaceSupportsReadPixels(const GrSurface * surface) const87 GrCaps::SurfaceReadPixelsSupport GrDawnCaps::surfaceSupportsReadPixels(
88       const GrSurface* surface) const {
89     // We currently support readbacks only from Textures and TextureRenderTargets.
90     return surface->asTexture() ? SurfaceReadPixelsSupport::kSupported
91                                 : SurfaceReadPixelsSupport::kUnsupported;
92 }
93 
onSurfaceSupportsWritePixels(const GrSurface * surface) const94 bool GrDawnCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {
95     // We currently support writePixels only to Textures and TextureRenderTargets.
96     return surface->asTexture() != nullptr;
97 }
98 
getRenderTargetSampleCount(int requestedCount,const GrBackendFormat & backendFormat) const99 int GrDawnCaps::getRenderTargetSampleCount(int requestedCount,
100                                            const GrBackendFormat& backendFormat) const {
101     wgpu::TextureFormat dawnFormat;
102     if (!backendFormat.asDawnFormat(&dawnFormat)) {
103         return 0;
104     }
105     return GrDawnFormatIsRenderable(dawnFormat) ? 1 : 0;
106 }
107 
maxRenderTargetSampleCount(const GrBackendFormat & format) const108 int GrDawnCaps::maxRenderTargetSampleCount(const GrBackendFormat& format) const {
109     return format.isValid() ? 1 : 0;
110 }
111 
onGetDefaultBackendFormat(GrColorType ct) const112 GrBackendFormat GrDawnCaps::onGetDefaultBackendFormat(GrColorType ct) const {
113     wgpu::TextureFormat format;
114     if (!GrColorTypeToDawnFormat(ct, &format)) {
115         return {};
116     }
117     return GrBackendFormat::MakeDawn(format);
118 }
119 
getBackendFormatFromCompressionType(SkImage::CompressionType type) const120 GrBackendFormat GrDawnCaps::getBackendFormatFromCompressionType(SkImage::CompressionType type) const
121 {
122     return GrBackendFormat();
123 }
124 
onGetReadSwizzle(const GrBackendFormat & format,GrColorType colorType) const125 GrSwizzle GrDawnCaps::onGetReadSwizzle(const GrBackendFormat& format, GrColorType colorType) const
126 {
127     return get_swizzle(format, colorType, false);
128 }
129 
getWriteSwizzle(const GrBackendFormat & format,GrColorType colorType) const130 GrSwizzle GrDawnCaps::getWriteSwizzle(const GrBackendFormat& format, GrColorType colorType) const {
131     return get_swizzle(format, colorType, true);
132 }
133 
computeFormatKey(const GrBackendFormat & format) const134 uint64_t GrDawnCaps::computeFormatKey(const GrBackendFormat& format) const {
135     wgpu::TextureFormat dawnFormat;
136     SkAssertResult(format.asDawnFormat(&dawnFormat));
137 
138     // Dawn max enum value should always fit in 32 bits.
139 
140     // disabled: no member named 'WGPUTextureFormat_Force32' in namespace 'wgpu'
141     //SkASSERT(dawnFormat <= wgpu::WGPUTextureFormat_Force32);
142     return (uint64_t)dawnFormat;
143 }
144 
onAreColorTypeAndFormatCompatible(GrColorType ct,const GrBackendFormat & format) const145 bool GrDawnCaps::onAreColorTypeAndFormatCompatible(GrColorType ct,
146                                                    const GrBackendFormat& format) const {
147     return true;
148 }
149 
150 // FIXME: taken from GrVkPipelineState; refactor.
get_blend_info_key(const GrPipeline & pipeline)151 static uint32_t get_blend_info_key(const GrPipeline& pipeline) {
152     GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
153 
154     static const uint32_t kBlendWriteShift = 1;
155     static const uint32_t kBlendCoeffShift = 5;
156     static_assert(kLast_GrBlendCoeff < (1 << kBlendCoeffShift));
157     static_assert(kFirstAdvancedGrBlendEquation - 1 < 4);
158 
159     uint32_t key = blendInfo.fWriteColor;
160     key |= (blendInfo.fSrcBlend << kBlendWriteShift);
161     key |= (blendInfo.fDstBlend << (kBlendWriteShift + kBlendCoeffShift));
162     key |= (blendInfo.fEquation << (kBlendWriteShift + 2 * kBlendCoeffShift));
163 
164     return key;
165 }
166 
makeDesc(GrRenderTarget * rt,const GrProgramInfo & programInfo,ProgramDescOverrideFlags overrideFlags) const167 GrProgramDesc GrDawnCaps::makeDesc(GrRenderTarget* rt,
168                                    const GrProgramInfo& programInfo,
169                                    ProgramDescOverrideFlags overrideFlags) const {
170     SkASSERT(overrideFlags == ProgramDescOverrideFlags::kNone);
171     GrProgramDesc desc;
172     GrProgramDesc::Build(&desc, programInfo, *this);
173 
174     wgpu::TextureFormat format;
175     if (!programInfo.backendFormat().asDawnFormat(&format)) {
176         desc.reset();
177         SkASSERT(!desc.isValid());
178         return desc;
179     }
180 
181     GrProcessorKeyBuilder b(desc.key());
182     GrStencilSettings stencil = programInfo.nonGLStencilSettings();
183     stencil.genKey(&b, true);
184 
185     // TODO: remove this reliance on the renderTarget
186     bool hasDepthStencil = rt->getStencilAttachment() != nullptr;
187 
188     b.add32(static_cast<uint32_t>(format));
189     b.add32(static_cast<int32_t>(hasDepthStencil));
190     b.add32(get_blend_info_key(programInfo.pipeline()));
191     b.add32(programInfo.primitiveTypeKey());
192 
193     b.flush();
194     return desc;
195 }
196 
197 #if GR_TEST_UTILS
getTestingCombinations() const198 std::vector<GrCaps::TestFormatColorTypeCombination> GrDawnCaps::getTestingCombinations() const {
199     std::vector<GrCaps::TestFormatColorTypeCombination> combos = {
200         { GrColorType::kAlpha_8,   GrBackendFormat::MakeDawn(wgpu::TextureFormat::R8Unorm)    },
201         { GrColorType::kRGBA_8888, GrBackendFormat::MakeDawn(wgpu::TextureFormat::RGBA8Unorm) },
202         { GrColorType::kRGBA_8888, GrBackendFormat::MakeDawn(wgpu::TextureFormat::BGRA8Unorm) },
203         { GrColorType::kRGB_888x,  GrBackendFormat::MakeDawn(wgpu::TextureFormat::RGBA8Unorm) },
204         { GrColorType::kRGB_888x,  GrBackendFormat::MakeDawn(wgpu::TextureFormat::BGRA8Unorm) },
205         { GrColorType::kBGRA_8888, GrBackendFormat::MakeDawn(wgpu::TextureFormat::BGRA8Unorm) },
206         { GrColorType::kBGRA_8888, GrBackendFormat::MakeDawn(wgpu::TextureFormat::RGBA8Unorm) },
207     };
208 
209 #ifdef SK_DEBUG
210     for (const GrCaps::TestFormatColorTypeCombination& combo : combos) {
211         SkASSERT(this->onAreColorTypeAndFormatCompatible(combo.fColorType, combo.fFormat));
212     }
213 #endif
214     return combos;
215 }
216 #endif
217