@@ -27,7 +27,7 @@ class ISwapchain : public IBackendObject
2727 if (!physDev || !surface || !surface->getSurfaceCapabilitiesForPhysicalDevice (physDev,caps))
2828 return false ;
2929
30- if (!caps.supportedUsageFlags .hasFlags (imageUsage))
30+ if (!imageUsage. value || ! caps.supportedUsageFlags .hasFlags (imageUsage))
3131 return false ;
3232 if (minImageCount<caps.minImageCount )
3333 return false ;
@@ -46,6 +46,18 @@ class ISwapchain : public IBackendObject
4646 return false ;
4747 if (hlsl::bitCount (preTransform.value )!=1 || !caps.supportedTransforms .hasFlags (preTransform))
4848 return false ;
49+ {
50+ const auto & formatUsages = physDev->getImageFormatUsagesOptimalTiling ();
51+ core::bitflag<IGPUImage::E_USAGE_FLAGS> possibleUsages = IGPUImage::E_USAGE_FLAGS::EUF_NONE;
52+ for (auto f=0u ; f<asset::EF_COUNT; f++)
53+ {
54+ const auto format = static_cast <asset::E_FORMAT>(f);
55+ if (viewFormats.test (format))
56+ possibleUsages |= core::bitflag<IGPUImage::E_USAGE_FLAGS>(formatUsages[format]);
57+ }
58+ if (!possibleUsages.hasFlags (imageUsage))
59+ return false ;
60+ }
4961 return true ;
5062 }
5163
@@ -76,21 +88,7 @@ class ISwapchain : public IBackendObject
7688 if (!physDev || !surface || !surface->getSurfaceCapabilitiesForPhysicalDevice (physDev,caps))
7789 return false ;
7890
79- if (!imageUsage)
80- {
81- const auto formatUsages = physDev->getImageFormatUsagesOptimalTiling ();
82- // we must be able to at least render to an image with a Graphics Pipeline
83- core::bitflag<IGPUImage::E_USAGE_FLAGS> extendedUsages = IGPUImage::E_USAGE_FLAGS::EUF_RENDER_ATTACHMENT_BIT;
84- for (auto f=0u ; f<asset::EF_COUNT; f++)
85- {
86- const auto format = static_cast <asset::E_FORMAT>(f);
87- if (viewFormats.test (format))
88- extendedUsages |= core::bitflag<IGPUImage::E_USAGE_FLAGS>(formatUsages[format]);
89- }
90- // usages need to be trimmed
91- imageUsage = caps.supportedUsageFlags & extendedUsages;
92- }
93- else if (!caps.supportedUsageFlags .hasFlags (imageUsage))
91+ if (!imageUsage || !caps.supportedUsageFlags .hasFlags (imageUsage))
9492 return false ;
9593
9694 caps.maxImageCount = core::min<uint32_t >(caps.maxImageCount ,MaxImages);
@@ -155,8 +153,20 @@ class ISwapchain : public IBackendObject
155153 return true ;
156154 }
157155
158- // default means "all supported"
159- core::bitflag<IGPUImage::E_USAGE_FLAGS> imageUsage = IGPUImage::E_USAGE_FLAGS::EUF_NONE;
156+ //
157+ static inline core::vector<ISurface::SFormat> obtainAvailableSurfaceFormats (const IPhysicalDevice* physDev, const ISurface* surface)
158+ {
159+ uint32_t availableFormatCount = 0 ;
160+ surface->getAvailableFormatsForPhysicalDevice (physDev,availableFormatCount,nullptr );
161+
162+ core::vector<ISurface::SFormat> availableFormats (availableFormatCount);
163+ surface->getAvailableFormatsForPhysicalDevice (physDev,availableFormatCount,availableFormats.data ());
164+
165+ return availableFormats;
166+ }
167+
168+ // Required to be not NONE, default to Transfer Dst cause thats the easiest way to copy (blit)
169+ core::bitflag<IGPUImage::E_USAGE_FLAGS> imageUsage = IGPUImage::E_USAGE_FLAGS::EUF_TRANSFER_DST_BIT|IGPUImage::E_USAGE_FLAGS::EUF_RENDER_ATTACHMENT_BIT;
160170 // can also treat as them as bitflags of valid transforms
161171 uint8_t minImageCount = 0u ;
162172 core::bitflag<ISurface::E_PRESENT_MODE> presentMode = ISurface::EPM_ALL_BITS;
@@ -178,13 +188,7 @@ class ISwapchain : public IBackendObject
178188 if (!sharedParams.valid (physDev,surface.get ()))
179189 return false ;
180190
181- core::vector<ISurface::SFormat> availableFormats;
182- {
183- uint32_t availableFormatCount = 0 ;
184- surface->getAvailableFormatsForPhysicalDevice (physDev,availableFormatCount,nullptr );
185- availableFormats.resize (availableFormatCount);
186- surface->getAvailableFormatsForPhysicalDevice (physDev,availableFormatCount,availableFormats.data ());
187- }
191+ auto availableFormats = SSharedCreationParams::obtainAvailableSurfaceFormats (physDev,surface.get ());
188192 return std::find (availableFormats.begin (),availableFormats.end (),surfaceFormat)!=availableFormats.end ();
189193 }
190194
@@ -216,13 +220,7 @@ class ISwapchain : public IBackendObject
216220 std::span<const asset::E_COLOR_PRIMARIES> preferredColorPrimaries=DefaultColorPrimaries
217221 )
218222 {
219- core::vector<ISurface::SFormat> availableFormats;
220- {
221- uint32_t availableFormatCount = 0 ;
222- surface->getAvailableFormatsForPhysicalDevice (physDev,availableFormatCount,nullptr );
223- availableFormats.resize (availableFormatCount);
224- surface->getAvailableFormatsForPhysicalDevice (physDev,availableFormatCount,availableFormats.data ());
225- }
223+ auto availableFormats = SSharedCreationParams::obtainAvailableSurfaceFormats (physDev,surface.get ());
226224
227225 // override preferred if set to known value already
228226 if (surfaceFormat.format !=asset::EF_UNKNOWN)
@@ -270,6 +268,8 @@ class ISwapchain : public IBackendObject
270268 val.format = format;
271269 if (std::binary_search (formatBegin,formatEnd,val,fullComparator))
272270 {
271+ // trim usage
272+
273273 // Check compatibility against all `viewFormats`
274274 bool incompatible = false ;
275275 const auto formatClass = asset::getFormatClass (format);
0 commit comments