init
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
////
|
||||
- Copyright (c) 2023, Mobica Limited
|
||||
-
|
||||
- SPDX-License-Identifier: Apache-2.0
|
||||
-
|
||||
- Licensed under the Apache License, Version 2.0 the "License";
|
||||
- you may not use this file except in compliance with the License.
|
||||
- You may obtain a copy of the License at
|
||||
-
|
||||
- http://www.apache.org/licenses/LICENSE-2.0
|
||||
-
|
||||
- Unless required by applicable law or agreed to in writing, software
|
||||
- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
- See the License for the specific language governing permissions and
|
||||
- limitations under the License.
|
||||
-
|
||||
////
|
||||
= Logic operations dynamic state
|
||||
|
||||
ifdef::site-gen-antora[]
|
||||
TIP: The source for this sample can be found in the https://github.com/KhronosGroup/Vulkan-Samples/tree/main/samples/extensions/logic_op_dynamic_state[Khronos Vulkan samples github repository].
|
||||
endif::[]
|
||||
|
||||
|
||||
image::./images/logic_op_dynamic_state_screenshot.png[Sample]
|
||||
|
||||
== Overview
|
||||
|
||||
The https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_extended_dynamic_state2.html[VK_EXT_extended_dynamic_state2] extension allows to use dynamic states e.g.
|
||||
the VK_DYNAMIC_STATE_LOGIC_OP_EXT.
|
||||
This may help an application to change a logical operation used without creating a new pipeline.
|
||||
|
||||
The sample demonstrates usage of this extension with dynamically changed logical operations applied to blending.
|
||||
|
||||
== Surface format setting
|
||||
|
||||
Logical operations are applied only for https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#framebuffer-logicop[signed and unsigned integer and normalized integer framebuffers].
|
||||
|
||||
In the sample the surface format is changed to `VK_FORMAT_B8G8R8A8_UNORM` by overriding the virtual method `create_render_context` (derived from `ApiVulkanSample` class).
|
||||
|
||||
[,C++]
|
||||
----
|
||||
auto surface_priority_list = std::vector<VkSurfaceFormatKHR>{
|
||||
{VK_FORMAT_B8G8R8A8_UNORM, VK_COLORSPACE_SRGB_NONLINEAR_KHR},
|
||||
};
|
||||
render_context = platform.create_render_context(*device.get(), surface, surface_priority_list);
|
||||
----
|
||||
|
||||
== Enabling logical operations in pipeline creation
|
||||
|
||||
In the sample two pipelines are created:
|
||||
|
||||
* a pipeline for a background model (the background pipeline);
|
||||
* a pipeline for a cube model (the baseline pipeline).
|
||||
|
||||
The cube model is used to present blending effect achieved using the dynamic logical operations.
|
||||
|
||||
The `logicOpEnable` member of the `VkPipelineColorBlendStateCreateInfo` structure https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineColorBlendStateCreateInfo.html[controls if logical operations should be applied].
|
||||
|
||||
The `logicOpEnable` member is set to `VK_TRUE` during creation of the baseline pipeline in the `create_pipeline` method.
|
||||
|
||||
[,C++]
|
||||
----
|
||||
VkPipelineColorBlendStateCreateInfo color_blend_state =
|
||||
vkb::initializers::pipeline_color_blend_state_create_info(1, &blend_attachment_state);
|
||||
|
||||
/* Enable logic operations */
|
||||
color_blend_state.logicOpEnable = VK_TRUE;
|
||||
----
|
||||
|
||||
In the same method `VK_DYNAMIC_STATE_LOGIC_OP_EXT` is added to the vector of `VkDynamicState` (used to define pipeline dynamic state in https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineDynamicStateCreateInfo.html[`VkPipelineDynamicStateCreateInfo`]).
|
||||
|
||||
[,C++]
|
||||
----
|
||||
std::vector<VkDynamicState> dynamic_state_enables = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT,
|
||||
VK_DYNAMIC_STATE_SCISSOR,
|
||||
VK_DYNAMIC_STATE_LOGIC_OP_EXT,
|
||||
};
|
||||
VkPipelineDynamicStateCreateInfo dynamic_state =
|
||||
vkb::initializers::pipeline_dynamic_state_create_info(
|
||||
dynamic_state_enables.data(),
|
||||
static_cast<uint32_t>(dynamic_state_enables.size()),
|
||||
0);
|
||||
----
|
||||
|
||||
Both structures: `color_blend_state` and `dynamic_state` are used to define https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkGraphicsPipelineCreateInfo.html[`VkGraphicsPipelineCreateInfo`] needed to create the graphics pipeline.
|
||||
|
||||
[,C++]
|
||||
----
|
||||
VkGraphicsPipelineCreateInfo graphics_create{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO};
|
||||
graphics_create.pColorBlendState = &color_blend_state;
|
||||
graphics_create.pDynamicState = &dynamic_state;
|
||||
...
|
||||
|
||||
VK_CHECK(vkCreateGraphicsPipelines(get_device().get_handle(), pipeline_cache, 1, &graphics_create, VK_NULL_HANDLE, &pipeline.baseline));
|
||||
----
|
||||
|
||||
Logical operations are not enabled in the background pipeline.
|
||||
|
||||
[,C++]
|
||||
----
|
||||
std::vector<VkDynamicState> dynamic_state_enables_background = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT,
|
||||
VK_DYNAMIC_STATE_SCISSOR,
|
||||
};
|
||||
|
||||
/* Disable logic operations in background pipeline */
|
||||
color_blend_state.logicOpEnable = VK_FALSE;
|
||||
----
|
||||
|
||||
== Logical operation dynamic setting in command buffer creation
|
||||
|
||||
Calling https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdSetLogicOpEXT.html[`vkCmdSetLogicOpEXT`] allows to set the logic operation dynamically.
|
||||
In the sample it is called before drawing the model in the `build_command_buffers` method using a value provided by the GUI.
|
||||
Available logical operations are defined by the `VkLogicOp` enumeration (check the Vulkan specification for details of https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VkLogicOp[the logical operations]).
|
||||
The background model is drawn before the cube model (with logical operations enabled) to observe blending results on the cube model.
|
||||
|
||||
[,C++]
|
||||
----
|
||||
VK_CHECK(vkBeginCommandBuffer(draw_cmd_buffer, &command_begin));
|
||||
...
|
||||
|
||||
/* Drawing background */
|
||||
draw_model(background_model, draw_cmd_buffer);
|
||||
...
|
||||
|
||||
/* Set logic operation chosen in GUI for the cube model */
|
||||
vkCmdSetLogicOpEXT(draw_cmd_buffer, static_cast<VkLogicOp>(gui_settings.selected_operation));
|
||||
|
||||
/* Draw model */
|
||||
draw_created_model(draw_cmd_buffer);
|
||||
...
|
||||
|
||||
VK_CHECK(vkEndCommandBuffer(draw_cmd_buffer));
|
||||
----
|
||||
|
||||
== Enabling the required extensions
|
||||
|
||||
The extended dynamic state 2 API requires Vulkan 1.0 and the appropriate headers / SDK is required.
|
||||
This extension has been https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_extended_dynamic_state2.html#_promotion_to_vulkan_1_3[partially] promoted to Vulkan 1.3.
|
||||
|
||||
The device extension `VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME` requires `VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME` instance extension to be enabled.
|
||||
|
||||
[,C++]
|
||||
----
|
||||
add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
||||
add_device_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
|
||||
----
|
||||
|
||||
Enabling extension features is done using `VkPhysicalDeviceExtendedDynamicState2FeaturesEXT` and `VkPhysicalDeviceExtendedDynamicStateFeaturesEXT` structures.
|
||||
|
||||
[,C++]
|
||||
----
|
||||
typedef struct VkPhysicalDeviceExtendedDynamicState2FeaturesEXT {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkBool32 extendedDynamicState2;
|
||||
VkBool32 extendedDynamicState2LogicOp;
|
||||
VkBool32 extendedDynamicState2PatchControlPoints;
|
||||
} VkPhysicalD
|
||||
|
||||
typedef struct VkPhysicalDeviceExtendedDynamicStateFeaturesEXT {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkBool32 extendedDynamicState;
|
||||
} VkPhysicalDeviceExtendedDynamicStateFeaturesEXT;
|
||||
----
|
||||
|
||||
In the sample it is implemented in the `request_gpu_features` method.
|
||||
|
||||
[,C++]
|
||||
----
|
||||
auto &requested_extended_dynamic_state2_features =
|
||||
gpu.request_extension_features<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT);
|
||||
requested_extended_dynamic_state2_features.extendedDynamicState2 = VK_TRUE;
|
||||
requested_extended_dynamic_state2_features.extendedDynamicState2LogicOp = VK_TRUE;
|
||||
|
||||
auto &requested_extended_dynamic_state_feature =
|
||||
gpu.request_extension_features<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT>(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT);
|
||||
requested_extended_dynamic_state_feature.extendedDynamicState = VK_TRUE;
|
||||
----
|
||||
Reference in New Issue
Block a user