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);
} uboVS;
struct {
struct Pipelines {
VkPipeline solid;
VkPipeline wireframe;
VkPipeline wireframe = VK_NULL_HANDLE;
} pipelines;
VkPipelineLayout pipelineLayout;
@ -111,7 +111,9 @@ public:
// Clean up used Vulkan resources
// Note : Inherited destructor cleans up resources stored in base class
vkDestroyPipeline(device, pipelines.solid, nullptr);
vkDestroyPipeline(device, pipelines.wireframe, nullptr);
if (pipelines.wireframe != VK_NULL_HANDLE) {
vkDestroyPipeline(device, pipelines.wireframe, nullptr);
}
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);

View file

@ -69,11 +69,11 @@ public:
float tessAlpha = 1.0f;
} uboTessEval;
struct {
struct Pipelines {
VkPipeline solid;
VkPipeline wire;
VkPipeline wire = VK_NULL_HANDLE;
VkPipeline solidPassThrough;
VkPipeline wirePassThrough;
VkPipeline wirePassThrough = VK_NULL_HANDLE;
} pipelines;
VkPipeline *pipelineLeft = &pipelines.wirePassThrough;
VkPipeline *pipelineRight = &pipelines.wire;
@ -89,11 +89,6 @@ public:
cameraPos = glm::vec3(-3.0f, 2.3f, 0.0f);
title = "Vulkan Example - Tessellation shader (PN Triangles)";
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()
@ -101,9 +96,13 @@ public:
// Clean up used Vulkan resources
// Note : Inherited destructor cleans up resources stored in base class
vkDestroyPipeline(device, pipelines.solid, nullptr);
vkDestroyPipeline(device, pipelines.wire, nullptr);
if (pipelines.wire != VK_NULL_HANDLE) {
vkDestroyPipeline(device, pipelines.wire, nullptr);
};
vkDestroyPipeline(device, pipelines.solidPassThrough, nullptr);
vkDestroyPipeline(device, pipelines.wirePassThrough, nullptr);
if (pipelines.wirePassThrough != VK_NULL_HANDLE) {
vkDestroyPipeline(device, pipelines.wirePassThrough, nullptr);
};
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
@ -114,6 +113,28 @@ public:
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()
{
if (!checkCommandBuffers())
@ -413,8 +434,10 @@ public:
// Solid
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solid));
// Wireframe
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wire));
if (deviceFeatures.fillModeNonSolid) {
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wire));
}
// Pass through pipelines
// Load pass through tessellation shaders (Vert and frag are reused)
@ -425,8 +448,10 @@ public:
rasterizationState.polygonMode = VK_POLYGON_MODE_FILL;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solidPassThrough));
// Wireframe
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wirePassThrough));
if (deviceFeatures.fillModeNonSolid) {
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wirePassThrough));
}
}
// Prepare and initialize uniform buffer containing shader uniforms
@ -486,12 +511,6 @@ public:
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();
loadAssets();
setupVertexDescriptions();
@ -532,7 +551,9 @@ public:
break;
case KEY_W:
case GAMEPAD_BUTTON_A:
togglePipelines();
if (deviceFeatures.fillModeNonSolid) {
togglePipelines();
}
break;
case KEY_S:
case GAMEPAD_BUTTON_X:
@ -547,10 +568,14 @@ public:
ss << std::setprecision(2) << std::fixed << uboTessControl.tessLevel;
#if defined(__ANDROID__)
textOverlay->addText("Tessellation level: " + ss.str() + " (Buttons L1/R1 to change)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
textOverlay->addText("Press \"Button X\" to toggle splitscreen", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
if (deviceFeatures.fillModeNonSolid) {
textOverlay->addText("Press \"Button X\" to toggle splitscreen", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
}
#else
textOverlay->addText("Tessellation level: " + ss.str() + " (NUMPAD +/- to change)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
textOverlay->addText("Press \"s\" to toggle splitscreen", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
if (deviceFeatures.fillModeNonSolid) {
textOverlay->addText("Press \"s\" to toggle splitscreen", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
}
#endif
}