Create a surface to find out what formats are presentable
diff --git a/tests/vkrenderframework.cpp b/tests/vkrenderframework.cpp
index ba2cbd7..a3277c8 100644
--- a/tests/vkrenderframework.cpp
+++ b/tests/vkrenderframework.cpp
@@ -74,6 +74,8 @@
std::vector<const char*> device_layer_names;
std::vector<const char*> instance_extension_names;
std::vector<const char*> device_extension_names;
+ instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
+ device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
InitFramework(
instance_layer_names, device_layer_names,
instance_extension_names, device_extension_names);
@@ -174,44 +176,7 @@
{
VkResult err;
-// FIXME/TODO: The following code needs to be modified. It was
-// written in a broken manner, when that was easier to do. It
-// did/does not pass valid surface info to the
-// vkGetPhysicalDeviceSurfaceFormatsKHR() function. This worked for
-// the early Vulkan ICDs, and it may work for some production ICDs;
-// but it is not valid. The vkGetPhysicalDeviceSurfaceFormatsKHR()
-// function can only be called with a VkSurfaceKHR object, which means
-// that a window must have been created. Perhaps there's a
-// chicken-and-egg problem with the API, where the test framework
-// wants to find out what VkFormat(s) it can use before creating a
-// window, but a window is needed in order to call the
-// vkGetPhysicalDeviceSurfaceFormatsKHR() function. If so, let's
-// figure this out quickly!
-
- // Get the list of VkFormat's that are supported:
- PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fpGetPhysicalDeviceSurfaceFormatsKHR;
- uint32_t formatCount;
- VkSurfaceKHR surface = VK_NULL_HANDLE;
-#ifdef _WIN32
- // FIXME/TODO: Call vkCreateWin32SurfaceKHR()
-#else // _WIN32
- // FIXME/TODO: Call vkCreateXcbSurfaceKHR()
-#endif // _WIN32
- GET_DEVICE_PROC_ADDR(device(), GetPhysicalDeviceSurfaceFormatsKHR);
- err = fpGetPhysicalDeviceSurfaceFormatsKHR(
- m_device->phy().handle(),
- surface,
- &formatCount, NULL);
- ASSERT_VK_SUCCESS(err);
- VkSurfaceFormatKHR *surfFormats =
- (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
- err = fpGetPhysicalDeviceSurfaceFormatsKHR(
- m_device->phy().handle(),
- surface,
- &formatCount, surfFormats);
- ASSERT_VK_SUCCESS(err);
- m_render_target_fmt = surfFormats[0].format;
- free(surfFormats);
+ m_render_target_fmt = VkTestFramework::GetFormat(inst, m_device);
m_lineWidth = 1.0f;
diff --git a/tests/vktestframework.cpp b/tests/vktestframework.cpp
index 77fa84d..5c526ba 100644
--- a/tests/vktestframework.cpp
+++ b/tests/vktestframework.cpp
@@ -104,6 +104,8 @@
void Run();
void InitPresentFramework(std::list<VkTestImageRecord> &imagesIn, VkInstance inst);
void CreateMyWindow();
+ VkFormat GetPresentFormat();
+ void DestroyWindow();
void CreateSwapchain();
void SetImageLayout(VkImage image, VkImageAspectFlags aspectMask,
VkImageLayout old_image_layout, VkImageLayout new_image_layout);
@@ -144,6 +146,7 @@
PFN_vkGetSwapchainImagesKHR m_fpGetSwapchainImagesKHR;
PFN_vkAcquireNextImageKHR m_fpAcquireNextImageKHR;
PFN_vkQueuePresentKHR m_fpQueuePresentKHR;
+ PFN_vkDestroySurfaceKHR m_fpDestroySurfaceKHR;
uint32_t m_swapchainImageCount;
VkSwapchainKHR m_swap_chain;
SwapchainBuffers *m_buffers;
@@ -302,6 +305,46 @@
}
}
+VkFormat VkTestFramework::GetFormat(VkInstance instance, vk_testing::Device *device)
+{
+ VkFormatProperties format_props;
+ if (!m_show_images)
+ {
+ vkGetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_B8G8R8A8_UNORM, &format_props);
+ if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
+ format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)
+ {
+ return VK_FORMAT_B8G8R8A8_UNORM;
+ }
+ vkGetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, &format_props);
+ if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
+ format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)
+ {
+ return VK_FORMAT_R8G8B8A8_UNORM;
+ }
+ printf("Error - device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM - exiting\n");
+ exit(0);
+ }
+ else
+ {
+ /* To find which formats are presentable, you have to provide a surface to vkGetPhysicalDeviceSurfaceFormatsKHR */
+ /* To create a surface, you need a window. Use the present object to create a window, use that to create a */
+ /* KHR surface, and then find out what formats are presentable */
+ VkFormat presentFormat;
+ std::list<VkTestImageRecord> list;
+ VkTestImageRecord placeholder;
+ /* Use a dummy image record with non-zero area so the window will create on Windows */
+ placeholder.m_width = placeholder.m_height = 20;
+ list.push_back(placeholder);
+ TestFrameworkVkPresent vkPresent(*device);
+ vkPresent.InitPresentFramework(list, instance);
+ vkPresent.CreateMyWindow();
+ presentFormat = vkPresent.GetPresentFormat();
+ vkPresent.DestroyWindow();
+ return presentFormat;
+ }
+}
+
void VkTestFramework::WritePPM( const char *basename, VkImageObj *image )
{
string filename;
@@ -505,6 +548,40 @@
m_height = 0;
}
+VkFormat TestFrameworkVkPresent::GetPresentFormat()
+{
+ uint32_t formatCount;
+ VkResult U_ASSERT_ONLY res;
+ VkSurfaceKHR surface;
+ VkFormat returnFormat;
+
+#ifdef _WIN32
+ res = vkCreateWin32SurfaceKHR(m_instance, m_connection, m_window,
+ NULL, &surface);
+#else // _WIN32
+ res = vkCreateXcbSurfaceKHR(m_instance, m_connection, m_window,
+ NULL, &surface);
+#endif // _WIN32
+ assert(res == VK_SUCCESS);
+
+ m_fpGetPhysicalDeviceSurfaceFormatsKHR(
+ m_device.phy().handle(),
+ surface,
+ &formatCount, NULL);
+ VkSurfaceFormatKHR *surfFormats =
+ (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
+ m_fpGetPhysicalDeviceSurfaceFormatsKHR(
+ m_device.phy().handle(),
+ surface,
+ &formatCount, surfFormats);
+
+ m_fpDestroySurfaceKHR(m_instance, surface, NULL);
+
+ returnFormat = surfFormats[0].format;
+ free(surfFormats);
+ return returnFormat;
+}
+
void TestFrameworkVkPresent::Display()
{
VkResult U_ASSERT_ONLY err;
@@ -1059,6 +1136,7 @@
GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfaceCapabilitiesKHR);
GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfaceFormatsKHR);
GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfacePresentModesKHR);
+ GET_INSTANCE_PROC_ADDR(inst, DestroySurfaceKHR);
GET_DEVICE_PROC_ADDR(m_device.handle(), CreateSwapchainKHR);
GET_DEVICE_PROC_ADDR(m_device.handle(), CreateSwapchainKHR);
GET_DEVICE_PROC_ADDR(m_device.handle(), DestroySwapchainKHR);
@@ -1203,6 +1281,16 @@
#endif
}
+void TestFrameworkVkPresent::DestroyWindow()
+{
+#ifndef _WIN32
+ xcb_destroy_window(m_connection, m_window);
+ xcb_disconnect(m_connection);
+#else
+ DestroyWindow(m_window);
+#endif
+}
+
void VkTestFramework::Finish()
{
if (m_images.size() == 0) return;
diff --git a/tests/vktestframework.h b/tests/vktestframework.h
index f5747d9..05e5b82 100644
--- a/tests/vktestframework.h
+++ b/tests/vktestframework.h
@@ -85,7 +85,6 @@
static bool optionMatch(const char* option, char* optionLine);
static void InitArgs(int *argc, char *argv[]);
- static void InitWindow();
static void Finish();
void WritePPM( const char *basename, VkImageObj *image );
@@ -93,6 +92,7 @@
void Compare(const char *comment, VkImageObj *image);
void RecordImage(VkImageObj * image);
void RecordImages(vector<VkImageObj *> image);
+ VkFormat GetFormat(VkInstance instance, vk_testing::Device *device);
bool GLSLtoSPV(const VkShaderStageFlagBits shader_type,
const char *pshader,
std::vector<unsigned int> &spv);