OLD | NEW |
| (Empty) |
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 | |
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 | |
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 maxI
mageDimension2D will | |
62 // give the minimum max size across all configs. So for simplicity we will u
se that for now. | |
63 fMaxRenderTargetSize = properties.limits.maxImageDimension2D; | |
64 fMaxTextureSize = properties.limits.maxImageDimension2D; | |
65 | |
66 this->initSampleCount(properties); | |
67 | |
68 fMaxSampledTextures = SkTMin(properties.limits.maxPerStageDescriptorSampledI
mages, | |
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 | |
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 | |
100 void GrVkCaps::initSampleCount(const VkPhysicalDeviceProperties& properties) { | |
101 VkSampleCountFlags colorSamples = properties.limits.framebufferColorSampleCo
unts; | |
102 VkSampleCountFlags stencilSamples = properties.limits.framebufferStencilSamp
leCounts; | |
103 | |
104 fMaxColorSampleCount = get_max_sample_count(colorSamples); | |
105 fMaxStencilSampleCount = get_max_sample_count(stencilSamples); | |
106 } | |
107 | |
108 void GrVkCaps::initGLSLCaps(const GrVkInterface* interface, VkPhysicalDevice phy
sDev) { | |
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 a
lpha 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 | |
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, &pr
ops)); | |
134 *linearSupport = SkToBool(props.linearTilingFeatures & featureBit); | |
135 *optimalSupport = SkToBool(props.optimalTilingFeatures & featureBit); | |
136 } | |
137 | |
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_M
SAA]; \ | |
163 fConfigLinearRenderSupport[config][kYes_MSAA] = fConfigLinearRenderSupport[c
onfig][kNo_MSAA]; | |
164 | |
165 | |
166 void GrVkCaps::initConfigRenderableTable(const GrVkInterface* interface, VkPhysi
calDevice 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 | |
195 void GrVkCaps::initConfigTexturableTable(const GrVkInterface* interface, VkPhysi
calDevice 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(c
onfig); \ | |
228 if (SK_MACRO_APPEND_LINE(optimalSupported)) fStencilFormats.push_back(config
); | |
229 | |
230 void GrVkCaps::initStencilFormats(const GrVkInterface* interface, VkPhysicalDevi
ce 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 | |
OLD | NEW |