Check device features (only build non solid pipelines if feature available)
This commit is contained in:
parent
4cc7b204df
commit
e3c93c5b7f
2 changed files with 53 additions and 26 deletions
|
|
@ -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);
|
||||||
vkDestroyPipeline(device, pipelines.wireframe, nullptr);
|
if (pipelines.wireframe != VK_NULL_HANDLE) {
|
||||||
|
vkDestroyPipeline(device, pipelines.wireframe, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
vkDestroyPipeline(device, pipelines.wire, nullptr);
|
if (pipelines.wire != VK_NULL_HANDLE) {
|
||||||
|
vkDestroyPipeline(device, pipelines.wire, nullptr);
|
||||||
|
};
|
||||||
vkDestroyPipeline(device, pipelines.solidPassThrough, 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);
|
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
|
||||||
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
|
if (deviceFeatures.fillModeNonSolid) {
|
||||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wire));
|
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
|
||||||
|
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,8 +448,10 @@ 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
|
||||||
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
|
if (deviceFeatures.fillModeNonSolid) {
|
||||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wirePassThrough));
|
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
|
// Prepare and initialize uniform buffer containing shader uniforms
|
||||||
|
|
@ -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:
|
||||||
togglePipelines();
|
if (deviceFeatures.fillModeNonSolid) {
|
||||||
|
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);
|
||||||
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
|
#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);
|
||||||
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue