+ void scaleDimensionsToMemory(int& width, int& height, int devLayers, int sysLayers, int devBPP, int sysBPP)
+ {
+ vk::PlatformMemoryLimits memoryLimits;
+ m_context.getTestContext().getPlatform().getVulkanPlatform().getMemoryLimits(memoryLimits);
+ GLsizeiptr sysSpace = memoryLimits.totalSystemMemory;
+ GLsizeiptr devSpace = memoryLimits.totalDeviceLocalMemory;
+ int devInSysLayers = 0;
+
+ if (devSpace == 0)
+ {
+ devInSysLayers = devLayers;
+ devLayers = 0;
+ }
+
+ // Check if available memory is enough
+ GLsizeiptr pixelsPerLayer = width * height;
+ GLsizeiptr sysRequired = pixelsPerLayer * ((sysBPP * sysLayers) + (devBPP * devInSysLayers));
+ GLsizeiptr devRequired = pixelsPerLayer * devBPP * devLayers;
+ if ((sysRequired <= sysSpace) && (devRequired <= devSpace))
+ {
+ return;
+ }
+
+ // Scales the width and height such that the overall texture fits into
+ // the available space for both system and device.
+ GLdouble scale = sqrt(sysSpace / GLdouble(sysRequired));
+ if (devSpace != 0)
+ {
+ GLdouble devScale = sqrt(devSpace / GLdouble(devRequired));
+ scale = de::min(devScale, scale);
+ }
+ int newWidth = int(width * scale);
+ int newHeight = int(height * scale);
+
+ m_context.getTestContext().getLog()
+ << tcu::TestLog::Message << "Reducing surface dimensions to fit in memory, from " << width << "x" << height
+ << " to " << newWidth << "x" << newHeight << "." << tcu::TestLog::EndMessage;
+
+ width = newWidth;
+ height = newHeight;
+ }
+