Check device features (only build non solid pipelines if feature available)

This commit is contained in:
saschawillems 2017-03-08 22:06:17 +01:00
parent 4cc7b204df
commit e3c93c5b7f
2 changed files with 53 additions and 26 deletions

View file

@ -86,9 +86,9 @@ public:
glm::vec4 lightPos = glm::vec4(25.0f, 5.0f, 5.0f, 1.0f); glm::vec4 lightPos = glm::vec4(25.0f, 5.0f, 5.0f, 1.0f);
} uboVS; } uboVS;
struct { struct Pipelines {
VkPipeline solid; VkPipeline solid;
VkPipeline wireframe; VkPipeline wireframe = VK_NULL_HANDLE;
} pipelines; } pipelines;
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
@ -111,7 +111,9 @@ public:
// Clean up used Vulkan resources // Clean up used Vulkan resources
// Note : Inherited destructor cleans up resources stored in base class // Note : Inherited destructor cleans up resources stored in base class
vkDestroyPipeline(device, pipelines.solid, nullptr); vkDestroyPipeline(device, pipelines.solid, nullptr);
if (pipelines.wireframe != VK_NULL_HANDLE) {
vkDestroyPipeline(device, pipelines.wireframe, nullptr); vkDestroyPipeline(device, pipelines.wireframe, nullptr);
}
vkDestroyPipelineLayout(device, pipelineLayout, nullptr); vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);

View file

@ -69,11 +69,11 @@ public:
float tessAlpha = 1.0f; float tessAlpha = 1.0f;
} uboTessEval; } uboTessEval;
struct { struct Pipelines {
VkPipeline solid; VkPipeline solid;
VkPipeline wire; VkPipeline wire = VK_NULL_HANDLE;
VkPipeline solidPassThrough; VkPipeline solidPassThrough;
VkPipeline wirePassThrough; VkPipeline wirePassThrough = VK_NULL_HANDLE;
} pipelines; } pipelines;
VkPipeline *pipelineLeft = &pipelines.wirePassThrough; VkPipeline *pipelineLeft = &pipelines.wirePassThrough;
VkPipeline *pipelineRight = &pipelines.wire; VkPipeline *pipelineRight = &pipelines.wire;
@ -89,11 +89,6 @@ public:
cameraPos = glm::vec3(-3.0f, 2.3f, 0.0f); cameraPos = glm::vec3(-3.0f, 2.3f, 0.0f);
title = "Vulkan Example - Tessellation shader (PN Triangles)"; title = "Vulkan Example - Tessellation shader (PN Triangles)";
enableTextOverlay = true; enableTextOverlay = true;
// Enable physical device features required for this example
// Tell the driver that we are going to use geometry shaders
enabledFeatures.tessellationShader = VK_TRUE;
// Example also uses a wireframe pipeline, enable non-solid fill modes
enabledFeatures.fillModeNonSolid = VK_TRUE;
} }
~VulkanExample() ~VulkanExample()
@ -101,9 +96,13 @@ public:
// Clean up used Vulkan resources // Clean up used Vulkan resources
// Note : Inherited destructor cleans up resources stored in base class // Note : Inherited destructor cleans up resources stored in base class
vkDestroyPipeline(device, pipelines.solid, nullptr); vkDestroyPipeline(device, pipelines.solid, nullptr);
if (pipelines.wire != VK_NULL_HANDLE) {
vkDestroyPipeline(device, pipelines.wire, nullptr); vkDestroyPipeline(device, pipelines.wire, nullptr);
};
vkDestroyPipeline(device, pipelines.solidPassThrough, nullptr); vkDestroyPipeline(device, pipelines.solidPassThrough, nullptr);
if (pipelines.wirePassThrough != VK_NULL_HANDLE) {
vkDestroyPipeline(device, pipelines.wirePassThrough, nullptr); vkDestroyPipeline(device, pipelines.wirePassThrough, nullptr);
};
vkDestroyPipelineLayout(device, pipelineLayout, nullptr); vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
@ -114,6 +113,28 @@ public:
textures.colorMap.destroy(); textures.colorMap.destroy();
} }
// Enable physical device features required for this example
virtual void getEnabledFeatures()
{
// Example uses tessellation shaders
if (deviceFeatures.tessellationShader) {
enabledFeatures.tessellationShader = VK_TRUE;
}
else {
vks::tools::exitFatal("Selected GPU does not support tessellation shaders!", "Feature not supported");
}
// Fill mode non solid is required for wireframe display
if (deviceFeatures.fillModeNonSolid) {
enabledFeatures.fillModeNonSolid = VK_TRUE;
}
else {
// Wireframe not supported, switch to solid pipelines
pipelineLeft = &pipelines.solidPassThrough;
pipelineRight = &pipelines.solid;
}
}
void reBuildCommandBuffers() void reBuildCommandBuffers()
{ {
if (!checkCommandBuffers()) if (!checkCommandBuffers())
@ -413,8 +434,10 @@ public:
// Solid // Solid
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solid)); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solid));
// Wireframe // Wireframe
if (deviceFeatures.fillModeNonSolid) {
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE; rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wire)); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wire));
}
// Pass through pipelines // Pass through pipelines
// Load pass through tessellation shaders (Vert and frag are reused) // Load pass through tessellation shaders (Vert and frag are reused)
@ -425,9 +448,11 @@ public:
rasterizationState.polygonMode = VK_POLYGON_MODE_FILL; rasterizationState.polygonMode = VK_POLYGON_MODE_FILL;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solidPassThrough)); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solidPassThrough));
// Wireframe // Wireframe
if (deviceFeatures.fillModeNonSolid) {
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE; rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wirePassThrough)); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wirePassThrough));
} }
}
// Prepare and initialize uniform buffer containing shader uniforms // Prepare and initialize uniform buffer containing shader uniforms
void prepareUniformBuffers() void prepareUniformBuffers()
@ -486,12 +511,6 @@ public:
void prepare() void prepare()
{ {
// Check if device supports tessellation shaders
if (!deviceFeatures.tessellationShader)
{
vks::tools::exitFatal("Selected GPU does not support tessellation shaders!", "Feature not supported");
}
VulkanExampleBase::prepare(); VulkanExampleBase::prepare();
loadAssets(); loadAssets();
setupVertexDescriptions(); setupVertexDescriptions();
@ -532,7 +551,9 @@ public:
break; break;
case KEY_W: case KEY_W:
case GAMEPAD_BUTTON_A: case GAMEPAD_BUTTON_A:
if (deviceFeatures.fillModeNonSolid) {
togglePipelines(); togglePipelines();
}
break; break;
case KEY_S: case KEY_S:
case GAMEPAD_BUTTON_X: case GAMEPAD_BUTTON_X:
@ -547,10 +568,14 @@ public:
ss << std::setprecision(2) << std::fixed << uboTessControl.tessLevel; ss << std::setprecision(2) << std::fixed << uboTessControl.tessLevel;
#if defined(__ANDROID__) #if defined(__ANDROID__)
textOverlay->addText("Tessellation level: " + ss.str() + " (Buttons L1/R1 to change)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft); textOverlay->addText("Tessellation level: " + ss.str() + " (Buttons L1/R1 to change)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
if (deviceFeatures.fillModeNonSolid) {
textOverlay->addText("Press \"Button X\" to toggle splitscreen", 5.0f, 100.0f, VulkanTextOverlay::alignLeft); textOverlay->addText("Press \"Button X\" to toggle splitscreen", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
}
#else #else
textOverlay->addText("Tessellation level: " + ss.str() + " (NUMPAD +/- to change)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft); textOverlay->addText("Tessellation level: " + ss.str() + " (NUMPAD +/- to change)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
if (deviceFeatures.fillModeNonSolid) {
textOverlay->addText("Press \"s\" to toggle splitscreen", 5.0f, 100.0f, VulkanTextOverlay::alignLeft); textOverlay->addText("Press \"s\" to toggle splitscreen", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
}
#endif #endif
} }