• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 "GrVkCaps.h"
9 
10 #include "GrVkUtil.h"
11 #include "glsl/GrGLSLCaps.h"
12 #include "vk/GrVkInterface.h"
13 
GrVkCaps(const GrContextOptions & contextOptions,const GrVkInterface * vkInterface,VkPhysicalDevice physDev)14 GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
15                    VkPhysicalDevice physDev) : INHERITED(contextOptions) {
16     /**************************************************************************
17     * GrDrawTargetCaps fields
18     **************************************************************************/
19     fMipMapSupport = false; //TODO: figure this out
20     fNPOTTextureTileSupport = false; //TODO: figure this out
21     fTwoSidedStencilSupport = false; //TODO: figure this out
22     fStencilWrapOpsSupport = false; //TODO: figure this out
23     fDiscardRenderTargetSupport = false; //TODO: figure this out
24     fReuseScratchTextures = true; //TODO: figure this out
25     fGpuTracingSupport = false; //TODO: figure this out
26     fCompressedTexSubImageSupport = false; //TODO: figure this out
27     fOversizedStencilSupport = false; //TODO: figure this out
28 
29     fUseDrawInsteadOfClear = false; //TODO: figure this out
30 
31     fMapBufferFlags = kNone_MapFlags; //TODO: figure this out
32     fGeometryBufferMapThreshold = SK_MaxS32;  //TODO: figure this out
33 
34     fMaxRenderTargetSize = 4096; // minimum required by spec
35     fMaxTextureSize = 4096; // minimum required by spec
36     fMaxColorSampleCount = 4; // minimum required by spec
37     fMaxStencilSampleCount = 4; // minimum required by spec
38 
39 
40     fShaderCaps.reset(new GrGLSLCaps(contextOptions));
41 
42     /**************************************************************************
43     * GrVkCaps fields
44     **************************************************************************/
45     fMaxSampledTextures = 16; // Spec requires a minimum of 16 sampled textures per stage
46 
47     this->init(contextOptions, vkInterface, physDev);
48 }
49 
init(const GrContextOptions & contextOptions,const GrVkInterface * vkInterface,VkPhysicalDevice physDev)50 void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
51                     VkPhysicalDevice physDev) {
52 
53     this->initGLSLCaps(vkInterface, physDev);
54     this->initConfigTexturableTable(vkInterface, physDev);
55     this->initConfigRenderableTable(vkInterface, physDev);
56     this->initStencilFormats(vkInterface, physDev);
57 
58     VkPhysicalDeviceProperties properties;
59     GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties));
60 
61     // We could actually querey and get a max size for each config, however maxImageDimension2D will
62     // give the minimum max size across all configs. So for simplicity we will use that for now.
63     fMaxRenderTargetSize = properties.limits.maxImageDimension2D;
64     fMaxTextureSize = properties.limits.maxImageDimension2D;
65 
66     this->initSampleCount(properties);
67 
68     fMaxSampledTextures = SkTMin(properties.limits.maxPerStageDescriptorSampledImages,
69                                  properties.limits.maxPerStageDescriptorSamplers);
70 
71     this->applyOptionsOverrides(contextOptions);
72     // need to friend GrVkCaps in GrGLSLCaps.h
73     // GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
74     // glslCaps->applyOptionsOverrides(contextOptions);
75 }
76 
get_max_sample_count(VkSampleCountFlags flags)77 int get_max_sample_count(VkSampleCountFlags flags) {
78     SkASSERT(flags & VK_SAMPLE_COUNT_1_BIT);
79     if (!(flags & VK_SAMPLE_COUNT_2_BIT)) {
80         return 0;
81     }
82     if (!(flags & VK_SAMPLE_COUNT_4_BIT)) {
83         return 2;
84     }
85     if (!(flags & VK_SAMPLE_COUNT_8_BIT)) {
86         return 4;
87     }
88     if (!(flags & VK_SAMPLE_COUNT_16_BIT)) {
89         return 8;
90     }
91     if (!(flags & VK_SAMPLE_COUNT_32_BIT)) {
92         return 16;
93     }
94     if (!(flags & VK_SAMPLE_COUNT_64_BIT)) {
95         return 32;
96     }
97     return 64;
98 }
99 
initSampleCount(const VkPhysicalDeviceProperties & properties)100 void GrVkCaps::initSampleCount(const VkPhysicalDeviceProperties& properties) {
101     VkSampleCountFlags colorSamples = properties.limits.framebufferColorSampleCounts;
102     VkSampleCountFlags stencilSamples = properties.limits.framebufferStencilSampleCounts;
103 
104     fMaxColorSampleCount = get_max_sample_count(colorSamples);
105     fMaxStencilSampleCount = get_max_sample_count(stencilSamples);
106 }
107 
initGLSLCaps(const GrVkInterface * interface,VkPhysicalDevice physDev)108 void GrVkCaps::initGLSLCaps(const GrVkInterface* interface, VkPhysicalDevice physDev) {
109     GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get());
110     // TODO: actually figure out a correct version here
111     glslCaps->fVersionDeclString = "#version 140\n";
112 
113     // fConfigOutputSwizzle will default to RGBA so we only need to set it for alpha only config.
114     for (int i = 0; i < kGrPixelConfigCnt; ++i) {
115         GrPixelConfig config = static_cast<GrPixelConfig>(i);
116         if (GrPixelConfigIsAlphaOnly(config)) {
117             glslCaps->fConfigTextureSwizzle[i] = GrSwizzle::RRRR();
118             glslCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
119         } else {
120             glslCaps->fConfigTextureSwizzle[i] = GrSwizzle::RGBA();
121         }
122     }
123 }
124 
format_supported_for_feature(const GrVkInterface * interface,VkPhysicalDevice physDev,VkFormat format,VkFormatFeatureFlagBits featureBit,bool * linearSupport,bool * optimalSupport)125 static void format_supported_for_feature(const GrVkInterface* interface,
126                                          VkPhysicalDevice physDev,
127                                          VkFormat format,
128                                          VkFormatFeatureFlagBits featureBit,
129                                          bool* linearSupport,
130                                          bool* optimalSupport) {
131     VkFormatProperties props;
132     memset(&props, 0, sizeof(VkFormatProperties));
133     GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props));
134     *linearSupport = SkToBool(props.linearTilingFeatures & featureBit);
135     *optimalSupport = SkToBool(props.optimalTilingFeatures & featureBit);
136 }
137 
config_supported_for_feature(const GrVkInterface * interface,VkPhysicalDevice physDev,GrPixelConfig config,VkFormatFeatureFlagBits featureBit,bool * linearSupport,bool * optimalSupport)138 static void config_supported_for_feature(const GrVkInterface* interface,
139                                          VkPhysicalDevice physDev,
140                                          GrPixelConfig config,
141                                          VkFormatFeatureFlagBits featureBit,
142                                          bool* linearSupport,
143                                          bool* optimalSupport) {
144     VkFormat format;
145     if (!GrPixelConfigToVkFormat(config, &format)) {
146         *linearSupport = false;
147         *optimalSupport = false;
148         return;
149     }
150     format_supported_for_feature(interface, physDev, format, featureBit,
151                                  linearSupport, optimalSupport);
152 }
153 
154 // Currently just assumeing if something can be rendered to without MSAA it also works for MSAAA
155 #define SET_CONFIG_IS_RENDERABLE(config)                                                          \
156     config_supported_for_feature(interface,                                                       \
157                                  physDev,                                                         \
158                                  config,                                    \
159                                  VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT,                    \
160                                  &fConfigLinearRenderSupport[config][kNo_MSAA],                   \
161                                  &fConfigRenderSupport[config][kNo_MSAA] );                       \
162     fConfigRenderSupport[config][kYes_MSAA] = fConfigRenderSupport[config][kNo_MSAA];             \
163     fConfigLinearRenderSupport[config][kYes_MSAA] = fConfigLinearRenderSupport[config][kNo_MSAA];
164 
165 
initConfigRenderableTable(const GrVkInterface * interface,VkPhysicalDevice physDev)166 void GrVkCaps::initConfigRenderableTable(const GrVkInterface* interface, VkPhysicalDevice physDev) {
167     enum {
168         kNo_MSAA = 0,
169         kYes_MSAA = 1,
170     };
171 
172     // Base render support
173     SET_CONFIG_IS_RENDERABLE(kAlpha_8_GrPixelConfig);
174     SET_CONFIG_IS_RENDERABLE(kRGB_565_GrPixelConfig);
175     SET_CONFIG_IS_RENDERABLE(kRGBA_4444_GrPixelConfig);
176     SET_CONFIG_IS_RENDERABLE(kRGBA_8888_GrPixelConfig);
177     SET_CONFIG_IS_RENDERABLE(kBGRA_8888_GrPixelConfig);
178 
179     SET_CONFIG_IS_RENDERABLE(kSRGBA_8888_GrPixelConfig);
180 
181     // Float render support
182     SET_CONFIG_IS_RENDERABLE(kRGBA_float_GrPixelConfig);
183     SET_CONFIG_IS_RENDERABLE(kRGBA_half_GrPixelConfig);
184     SET_CONFIG_IS_RENDERABLE(kAlpha_half_GrPixelConfig);
185 }
186 
187 #define SET_CONFIG_IS_TEXTURABLE(config)                                 \
188     config_supported_for_feature(interface,                              \
189                                  physDev,                                \
190                                  config,                                 \
191                                  VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT,    \
192                                  &fConfigLinearTextureSupport[config],   \
193                                  &fConfigTextureSupport[config]);
194 
initConfigTexturableTable(const GrVkInterface * interface,VkPhysicalDevice physDev)195 void GrVkCaps::initConfigTexturableTable(const GrVkInterface* interface, VkPhysicalDevice physDev) {
196     // Base texture support
197     SET_CONFIG_IS_TEXTURABLE(kAlpha_8_GrPixelConfig);
198     SET_CONFIG_IS_TEXTURABLE(kRGB_565_GrPixelConfig);
199     SET_CONFIG_IS_TEXTURABLE(kRGBA_4444_GrPixelConfig);
200     SET_CONFIG_IS_TEXTURABLE(kRGBA_8888_GrPixelConfig);
201     SET_CONFIG_IS_TEXTURABLE(kBGRA_8888_GrPixelConfig);
202 
203     SET_CONFIG_IS_TEXTURABLE(kIndex_8_GrPixelConfig);
204     SET_CONFIG_IS_TEXTURABLE(kSRGBA_8888_GrPixelConfig);
205 
206     // Compressed texture support
207     SET_CONFIG_IS_TEXTURABLE(kETC1_GrPixelConfig);
208     SET_CONFIG_IS_TEXTURABLE(kLATC_GrPixelConfig);
209     SET_CONFIG_IS_TEXTURABLE(kR11_EAC_GrPixelConfig);
210     SET_CONFIG_IS_TEXTURABLE(kASTC_12x12_GrPixelConfig);
211 
212     // Float texture support
213     SET_CONFIG_IS_TEXTURABLE(kRGBA_float_GrPixelConfig);
214     SET_CONFIG_IS_TEXTURABLE(kRGBA_half_GrPixelConfig);
215     SET_CONFIG_IS_TEXTURABLE(kAlpha_half_GrPixelConfig);
216 }
217 
218 #define SET_CONFIG_CAN_STENCIL(config)                                                    \
219     bool SK_MACRO_APPEND_LINE(linearSupported);                                           \
220     bool SK_MACRO_APPEND_LINE(optimalSupported);                                          \
221     format_supported_for_feature(interface,                                               \
222                                  physDev,                                                 \
223                                  config.fInternalFormat,                                  \
224                                  VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT,          \
225                                  &SK_MACRO_APPEND_LINE(linearSupported),                  \
226                                  &SK_MACRO_APPEND_LINE(optimalSupported));                \
227     if (SK_MACRO_APPEND_LINE(linearSupported)) fLinearStencilFormats.push_back(config);   \
228     if (SK_MACRO_APPEND_LINE(optimalSupported)) fStencilFormats.push_back(config);
229 
initStencilFormats(const GrVkInterface * interface,VkPhysicalDevice physDev)230 void GrVkCaps::initStencilFormats(const GrVkInterface* interface, VkPhysicalDevice physDev) {
231     // Build up list of legal stencil formats (though perhaps not supported on
232     // the particular gpu/driver) from most preferred to least.
233 
234     static const StencilFormat
235                   // internal Format             stencil bits      total bits        packed?
236         gS8    = { VK_FORMAT_S8_UINT,            8,                 8,               false },
237         gD24S8 = { VK_FORMAT_D24_UNORM_S8_UINT,  8,                32,               true };
238 
239     // I'm simply assuming that these two will be supported since they are used in example code.
240     // TODO: Actaully figure this out
241     SET_CONFIG_CAN_STENCIL(gS8);
242     SET_CONFIG_CAN_STENCIL(gD24S8);
243 }
244 
245