99
1010#include " libANGLE/renderer/vulkan/vk_caps_utils.h"
1111
12+ #include < type_traits>
13+
1214#include " common/utilities.h"
1315#include " libANGLE/Caps.h"
1416#include " libANGLE/formatutils.h"
1517#include " libANGLE/renderer/vulkan/DisplayVk.h"
1618#include " libANGLE/renderer/vulkan/FeaturesVk.h"
19+ #include " libANGLE/renderer/vulkan/RendererVk.h"
1720#include " vk_format_utils.h"
1821
1922namespace
@@ -155,7 +158,38 @@ void GenerateCaps(const VkPhysicalDeviceProperties &physicalDeviceProperties,
155158
156159namespace egl_vk
157160{
158- egl::Config GenerateDefaultConfig (const gl::InternalFormat &colorFormat,
161+
162+ namespace
163+ {
164+
165+ EGLint ComputeMaximumPBufferPixels (const VkPhysicalDeviceProperties &physicalDeviceProperties)
166+ {
167+ // EGLints are signed 32-bit integers, it's fairly easy to overflow them, especially since
168+ // Vulkan's minimum guaranteed VkImageFormatProperties::maxResourceSize is 2^31 bytes.
169+ constexpr uint64_t kMaxValueForEGLint =
170+ static_cast <uint64_t >(std::numeric_limits<EGLint>::max ());
171+
172+ // TODO(geofflang): Compute the maximum size of a pbuffer by using the maxResourceSize result
173+ // from vkGetPhysicalDeviceImageFormatProperties for both the color and depth stencil format and
174+ // the exact image creation parameters that would be used to create the pbuffer. Because it is
175+ // always safe to return out-of-memory errors on pbuffer allocation, it's fine to simply return
176+ // the number of pixels in a max width by max height pbuffer for now. http://anglebug.com/2622
177+
178+ // Storing the result of squaring a 32-bit unsigned int in a 64-bit unsigned int is safe.
179+ static_assert (std::is_same<decltype (physicalDeviceProperties.limits .maxImageDimension2D ),
180+ uint32_t >::value,
181+ " physicalDeviceProperties.limits.maxImageDimension2D expected to be a uint32_t." );
182+ const uint64_t maxDimensionsSquared =
183+ static_cast <uint64_t >(physicalDeviceProperties.limits .maxImageDimension2D ) *
184+ static_cast <uint64_t >(physicalDeviceProperties.limits .maxImageDimension2D );
185+
186+ return static_cast <EGLint>(std::min (maxDimensionsSquared, kMaxValueForEGLint ));
187+ }
188+
189+ // Generates a basic config for a combination of color format, depth stencil format and sample
190+ // count.
191+ egl::Config GenerateDefaultConfig (const VkPhysicalDeviceProperties &physicalDeviceProperties,
192+ const gl::InternalFormat &colorFormat,
159193 const gl::InternalFormat &depthStencilFormat,
160194 EGLint sampleCount)
161195{
@@ -178,9 +212,9 @@ egl::Config GenerateDefaultConfig(const gl::InternalFormat &colorFormat,
178212 config.stencilSize = depthStencilFormat.stencilBits ;
179213 config.level = 0 ;
180214 config.matchNativePixmap = EGL_NONE;
181- config.maxPBufferWidth = 0 ;
182- config.maxPBufferHeight = 0 ;
183- config.maxPBufferPixels = 0 ;
215+ config.maxPBufferWidth = physicalDeviceProperties. limits . maxImageDimension2D ;
216+ config.maxPBufferHeight = physicalDeviceProperties. limits . maxImageDimension2D ;
217+ config.maxPBufferPixels = ComputeMaximumPBufferPixels (physicalDeviceProperties) ;
184218 config.maxSwapInterval = 1 ;
185219 config.minSwapInterval = 1 ;
186220 config.nativeRenderable = EGL_TRUE;
@@ -201,6 +235,8 @@ egl::Config GenerateDefaultConfig(const gl::InternalFormat &colorFormat,
201235 return config;
202236}
203237
238+ } // anonymous namespace
239+
204240egl::ConfigSet GenerateConfigs (const GLenum *colorFormats,
205241 size_t colorFormatsCount,
206242 const GLenum *depthStencilFormats,
@@ -214,6 +250,10 @@ egl::ConfigSet GenerateConfigs(const GLenum *colorFormats,
214250
215251 egl::ConfigSet configSet;
216252
253+ const RendererVk *renderer = display->getRenderer ();
254+ const VkPhysicalDeviceProperties &physicalDeviceProperties =
255+ renderer->getPhysicalDeviceProperties ();
256+
217257 for (size_t colorFormatIdx = 0 ; colorFormatIdx < colorFormatsCount; colorFormatIdx++)
218258 {
219259 const gl::InternalFormat &colorFormatInfo =
@@ -231,8 +271,9 @@ egl::ConfigSet GenerateConfigs(const GLenum *colorFormats,
231271 for (size_t sampleCountIndex = 0 ; sampleCountIndex < sampleCountsCount;
232272 sampleCountIndex++)
233273 {
234- egl::Config config = GenerateDefaultConfig (colorFormatInfo, depthStencilFormatInfo,
235- sampleCounts[sampleCountIndex]);
274+ egl::Config config =
275+ GenerateDefaultConfig (physicalDeviceProperties, colorFormatInfo,
276+ depthStencilFormatInfo, sampleCounts[sampleCountIndex]);
236277 if (display->checkConfigSupport (&config))
237278 {
238279 configSet.add (config);
0 commit comments