vulkan: optionally use VK_KHR_PUSH_DESCRIPTOR

This commit is contained in:
nikeinikei
2022-09-01 14:51:06 +02:00
parent 7185d7356f
commit adc02a4939
4 changed files with 103 additions and 44 deletions
+55 -34
View File
@@ -407,7 +407,7 @@ void Graphics::setFrontFaceWinding(Winding winding) {
states.back().winding = winding;
if (optionalDeviceFeatures.extendedDynamicState) {
extendedDynamicStateFunctions.vkCmdSetFrontFaceEXT(
ext.vkCmdSetFrontFaceEXT(
commandBuffers.at(currentFrame),
Vulkan::getFrontFace(winding));
}
@@ -448,7 +448,9 @@ Graphics::RendererInfo Graphics::getRendererInfo() const {
std::stringstream ss;
ss << "Vulkan( ";
if (optionalDeviceFeatures.extendedDynamicState)
ss << "VK_EXT_extended_dynamic_state2 ";
ss << VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME << " ";
if (optionalDeviceFeatures.pushDescriptor)
ss << VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME << " ";
ss << ")";
info.name = ss.str();
@@ -572,7 +574,7 @@ void Graphics::setStencilMode(StencilAction action, CompareMode compare, int val
vkCmdSetStencilReference(commandBuffers.at(currentFrame), VK_STENCIL_FACE_FRONT_AND_BACK, value);
if (optionalDeviceFeatures.extendedDynamicState) {
extendedDynamicStateFunctions.vkCmdSetStencilOpEXT(
ext.vkCmdSetStencilOpEXT(
commandBuffers.at(currentFrame),
VK_STENCIL_FACE_FRONT_AND_BACK,
VK_STENCIL_OP_KEEP, Vulkan::getStencilOp(action),
@@ -590,10 +592,10 @@ void Graphics::setDepthMode(CompareMode compare, bool write) {
flushBatchedDraws();
if (optionalDeviceFeatures.extendedDynamicState) {
extendedDynamicStateFunctions.vkCmdSetDepthCompareOpEXT(
ext.vkCmdSetDepthCompareOpEXT(
commandBuffers.at(currentFrame), Vulkan::getCompareOp(compare));
extendedDynamicStateFunctions.vkCmdSetDepthWriteEnableEXT(
ext.vkCmdSetDepthWriteEnableEXT(
commandBuffers.at(currentFrame), Vulkan::getBool(write));
}
@@ -701,19 +703,19 @@ void Graphics::initDynamicState() {
vkCmdSetStencilReference(commandBuffers.at(currentFrame), VK_STENCIL_FACE_FRONT_AND_BACK, states.back().stencil.value);
if (optionalDeviceFeatures.extendedDynamicState) {
extendedDynamicStateFunctions.vkCmdSetStencilOpEXT(
ext.vkCmdSetStencilOpEXT(
commandBuffers.at(currentFrame),
VK_STENCIL_FACE_FRONT_AND_BACK,
VK_STENCIL_OP_KEEP, Vulkan::getStencilOp(states.back().stencil.action),
VK_STENCIL_OP_KEEP, Vulkan::getCompareOp(states.back().stencil.compare));
extendedDynamicStateFunctions.vkCmdSetDepthCompareOpEXT(
ext.vkCmdSetDepthCompareOpEXT(
commandBuffers.at(currentFrame), Vulkan::getCompareOp(states.back().depthTest));
extendedDynamicStateFunctions.vkCmdSetDepthWriteEnableEXT(
ext.vkCmdSetDepthWriteEnableEXT(
commandBuffers.at(currentFrame), Vulkan::getBool(states.back().depthWrite));
extendedDynamicStateFunctions.vkCmdSetFrontFaceEXT(
ext.vkCmdSetFrontFaceEXT(
commandBuffers.at(currentFrame), Vulkan::getFrontFace(states.back().winding));
}
}
@@ -1169,6 +1171,9 @@ static void findOptionalDeviceExtensions(VkPhysicalDevice physicalDevice, Option
if (strcmp(extension.extensionName, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) == 0) {
optionalDeviceFeatures.extendedDynamicState = true;
}
if (strcmp(extension.extensionName, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME) == 0) {
optionalDeviceFeatures.pushDescriptor = true;
}
}
}
@@ -1206,9 +1211,10 @@ void Graphics::createLogicalDevice() {
std::vector<const char*> enabledExtensions(deviceExtensions.begin(), deviceExtensions.end());
if (optionalDeviceFeatures.extendedDynamicState) {
if (optionalDeviceFeatures.extendedDynamicState)
enabledExtensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
}
if (optionalDeviceFeatures.pushDescriptor)
enabledExtensions.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
createInfo.enabledExtensionCount = static_cast<uint32_t>(enabledExtensions.size());
createInfo.ppEnabledExtensionNames = enabledExtensions.data();
@@ -1241,29 +1247,36 @@ void Graphics::createLogicalDevice() {
if (optionalDeviceFeatures.extendedDynamicState) {
#ifdef LOVE_ANDROID
extendedDynamicStateFunctions.vkCmdSetCullModeEXT = vkCmdSetCullModeEXT;
extendedDynamicStateFunctions.vkCmdSetDepthBoundsTestEnableEXT = vkCmdSetDepthBoundsTestEnableEXT;
extendedDynamicStateFunctions.vkCmdSetDepthBoundsTestEnableEXT = vkCmdSetCullModeEXT;
extendedDynamicStateFunctions.vkCmdSetDepthTestEnableEXT = vkCmdSetDepthTestEnableEXT;
extendedDynamicStateFunctions.vkCmdSetDepthWriteEnableEXT = vkCmdSetDepthWriteEnableEXT;
extendedDynamicStateFunctions.vkCmdSetFrontFaceEXT = vkCmdSetFrontFaceEXT;
extendedDynamicStateFunctions.vkCmdSetPrimitiveTopologyEXT = vkCmdSetPrimitiveTopologyEXT;
extendedDynamicStateFunctions.vkCmdSetScissorWithCountEXT = vkCmdSetScissorWithCountEXT;
extendedDynamicStateFunctions.vkCmdSetStencilOpEXT = vkCmdSetStencilOpEXT;
extendedDynamicStateFunctions.vkCmdSetStencilTestEnableEXT = vkCmdSetStencilTestEnableEXT;
extendedDynamicStateFunctions.vkCmdSetViewportWithCountEXT = vkCmdSetViewportWithCountEXT;
ext.vkCmdSetCullModeEXT = vkCmdSetCullModeEXT;
ext.vkCmdSetDepthBoundsTestEnableEXT = vkCmdSetDepthBoundsTestEnableEXT;
ext.vkCmdSetDepthBoundsTestEnableEXT = vkCmdSetCullModeEXT;
ext.vkCmdSetDepthTestEnableEXT = vkCmdSetDepthTestEnableEXT;
ext.vkCmdSetDepthWriteEnableEXT = vkCmdSetDepthWriteEnableEXT;
ext.vkCmdSetFrontFaceEXT = vkCmdSetFrontFaceEXT;
ext.vkCmdSetPrimitiveTopologyEXT = vkCmdSetPrimitiveTopologyEXT;
ext.vkCmdSetScissorWithCountEXT = vkCmdSetScissorWithCountEXT;
ext.vkCmdSetStencilOpEXT = vkCmdSetStencilOpEXT;
ext.vkCmdSetStencilTestEnableEXT = vkCmdSetStencilTestEnableEXT;
ext.vkCmdSetViewportWithCountEXT = vkCmdSetViewportWithCountEXT;
#else
extendedDynamicStateFunctions.vkCmdSetCullModeEXT = (PFN_vkCmdSetCullModeEXT)vkGetDeviceProcAddr(device, "vkCmdSetCullModeEXT");
extendedDynamicStateFunctions.vkCmdSetDepthBoundsTestEnableEXT = (PFN_vkCmdSetDepthBoundsTestEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetDepthBoundsTestEnableEXT");
extendedDynamicStateFunctions.vkCmdSetDepthCompareOpEXT = (PFN_vkCmdSetDepthCompareOpEXT)vkGetDeviceProcAddr(device, "vkCmdSetDepthCompareOpEXT");
extendedDynamicStateFunctions.vkCmdSetDepthTestEnableEXT = (PFN_vkCmdSetDepthTestEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetDepthTestEnableEXT");
extendedDynamicStateFunctions.vkCmdSetDepthWriteEnableEXT = (PFN_vkCmdSetDepthWriteEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetDepthWriteEnableEXT");
extendedDynamicStateFunctions.vkCmdSetFrontFaceEXT = (PFN_vkCmdSetFrontFaceEXT)vkGetDeviceProcAddr(device, "vkCmdSetFrontFaceEXT");
extendedDynamicStateFunctions.vkCmdSetPrimitiveTopologyEXT = (PFN_vkCmdSetPrimitiveTopologyEXT)vkGetDeviceProcAddr(device, "vkCmdSetPrimitiveTopologyEXT");
extendedDynamicStateFunctions.vkCmdSetScissorWithCountEXT = (PFN_vkCmdSetScissorWithCountEXT)vkGetDeviceProcAddr(device, "vkCmdSetScissorWithCountEXT");
extendedDynamicStateFunctions.vkCmdSetStencilOpEXT = (PFN_vkCmdSetStencilOpEXT)vkGetDeviceProcAddr(device, "vkCmdSetStencilOpEXT");
extendedDynamicStateFunctions.vkCmdSetStencilTestEnableEXT = (PFN_vkCmdSetStencilTestEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetStencilTestEnableEXT");
extendedDynamicStateFunctions.vkCmdSetViewportWithCountEXT = (PFN_vkCmdSetViewportWithCountEXT)vkGetDeviceProcAddr(device, "vkCmdSetViewportWithCountEXT");
ext.vkCmdSetCullModeEXT = (PFN_vkCmdSetCullModeEXT)vkGetDeviceProcAddr(device, "vkCmdSetCullModeEXT");
ext.vkCmdSetDepthBoundsTestEnableEXT = (PFN_vkCmdSetDepthBoundsTestEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetDepthBoundsTestEnableEXT");
ext.vkCmdSetDepthCompareOpEXT = (PFN_vkCmdSetDepthCompareOpEXT)vkGetDeviceProcAddr(device, "vkCmdSetDepthCompareOpEXT");
ext.vkCmdSetDepthTestEnableEXT = (PFN_vkCmdSetDepthTestEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetDepthTestEnableEXT");
ext.vkCmdSetDepthWriteEnableEXT = (PFN_vkCmdSetDepthWriteEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetDepthWriteEnableEXT");
ext.vkCmdSetFrontFaceEXT = (PFN_vkCmdSetFrontFaceEXT)vkGetDeviceProcAddr(device, "vkCmdSetFrontFaceEXT");
ext.vkCmdSetPrimitiveTopologyEXT = (PFN_vkCmdSetPrimitiveTopologyEXT)vkGetDeviceProcAddr(device, "vkCmdSetPrimitiveTopologyEXT");
ext.vkCmdSetScissorWithCountEXT = (PFN_vkCmdSetScissorWithCountEXT)vkGetDeviceProcAddr(device, "vkCmdSetScissorWithCountEXT");
ext.vkCmdSetStencilOpEXT = (PFN_vkCmdSetStencilOpEXT)vkGetDeviceProcAddr(device, "vkCmdSetStencilOpEXT");
ext.vkCmdSetStencilTestEnableEXT = (PFN_vkCmdSetStencilTestEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetStencilTestEnableEXT");
ext.vkCmdSetViewportWithCountEXT = (PFN_vkCmdSetViewportWithCountEXT)vkGetDeviceProcAddr(device, "vkCmdSetViewportWithCountEXT");
#endif
}
if (optionalDeviceFeatures.pushDescriptor) {
#ifdef LOVE_ANDROID
ext.vkCmdPushDescriptorSetKHR = vkCmdPushDescriptorSetKHR;
#else
ext.vkCmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(device, "vkCmdPushDescriptorSetKHR");
#endif
}
}
@@ -1814,7 +1827,7 @@ void Graphics::prepareDraw(const VertexAttributes& attributes, const BufferBindi
configuration.primitiveType = primitiveType;
if (optionalDeviceFeatures.extendedDynamicState) {
extendedDynamicStateFunctions.vkCmdSetCullModeEXT(commandBuffers.at(currentFrame), Vulkan::getCullMode(cullmode));
ext.vkCmdSetCullModeEXT(commandBuffers.at(currentFrame), Vulkan::getCullMode(cullmode));
} else {
configuration.dynamicState.winding = states.back().winding;
configuration.dynamicState.depthState.compare = states.back().depthTest;
@@ -2016,6 +2029,14 @@ void Graphics::setComputeShader(Shader* shader) {
computeShader = shader;
}
const OptionalDeviceFeatures &Graphics::getOptionalDeviceFeatures() const {
return optionalDeviceFeatures;
}
const OptionalDeviceExtensionFunctions &Graphics::getExtensionFunctions() const {
return ext;
}
VkSampler Graphics::getCachedSampler(const SamplerState& samplerState) {
auto it = samplers.find(samplerState);
if (it != samplers.end()) {
+10 -2
View File
@@ -85,9 +85,11 @@ struct OptionalInstanceExtensions {
struct OptionalDeviceFeatures {
bool extendedDynamicState = false;
bool pushDescriptor = false;
};
struct ExtendedDynamicStateFunctions {
struct OptionalDeviceExtensionFunctions {
// extended dynamic state
PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT = nullptr;
PFN_vkCmdSetDepthBoundsTestEnableEXT vkCmdSetDepthBoundsTestEnableEXT = nullptr;
PFN_vkCmdSetDepthCompareOpEXT vkCmdSetDepthCompareOpEXT = nullptr;
@@ -99,6 +101,9 @@ struct ExtendedDynamicStateFunctions {
PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT = nullptr;
PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT = nullptr;
PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT = nullptr;
// push descriptor
PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR = nullptr;
};
struct GraphicsPipelineConfiguration {
@@ -243,6 +248,9 @@ public:
void setComputeShader(Shader*);
const OptionalDeviceFeatures &getOptionalDeviceFeatures() const;
const OptionalDeviceExtensionFunctions &getExtensionFunctions() const;
protected:
graphics::ShaderStage* newShaderStageInternal(ShaderStageType stage, const std::string& cachekey, const std::string& source, bool gles) override;
graphics::Shader* newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override;
@@ -313,7 +321,7 @@ private:
VkDevice device = VK_NULL_HANDLE;
OptionalInstanceExtensions optionalInstanceExtensions;
OptionalDeviceFeatures optionalDeviceFeatures;
ExtendedDynamicStateFunctions extendedDynamicStateFunctions;
OptionalDeviceExtensionFunctions ext;
VkQueue graphicsQueue = VK_NULL_HANDLE;
VkQueue presentQueue = VK_NULL_HANDLE;
VkSurfaceKHR surface = VK_NULL_HANDLE;
+36 -8
View File
@@ -148,6 +148,13 @@ static EShLanguage getGlslShaderType(ShaderStageType stage) {
Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[])
: graphics::Shader(stages) {
gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
auto vgfx = (Graphics*)gfx;
auto &optionalDeviceFeaures = vgfx->getOptionalDeviceFeatures();
if (optionalDeviceFeaures.pushDescriptor) {
pfn_vkCmdPushDescriptorSetKHR = vgfx->getExtensionFunctions().vkCmdPushDescriptorSetKHR;
}
loadVolatile();
}
@@ -260,11 +267,19 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
}
}
if (currentUsedDescriptorSetsCount >= static_cast<uint32_t>(descriptorSetsVector.at(currentFrame).size())) {
descriptorSetsVector.at(currentFrame).push_back(allocateDescriptorSet());
VkDescriptorSet currentDescriptorSet;
if (pfn_vkCmdPushDescriptorSetKHR) {
currentDescriptorSet = 0;
}
else {
if (currentUsedDescriptorSetsCount >= static_cast<uint32_t>(descriptorSetsVector.at(currentFrame).size())) {
descriptorSetsVector.at(currentFrame).push_back(allocateDescriptorSet());
}
currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(currentUsedDescriptorSetsCount);
}
VkDescriptorSet currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(currentUsedDescriptorSetsCount);
std::vector<VkWriteDescriptorSet> descriptorWrite{};
VkDescriptorBufferInfo* bufferInfo = nullptr;
@@ -333,7 +348,22 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
}
}
vkUpdateDescriptorSets(device, static_cast<uint32_t>(descriptorWrite.size()), descriptorWrite.data(), 0, nullptr);
if (currentDescriptorSet) {
vkUpdateDescriptorSets(device, static_cast<uint32_t>(descriptorWrite.size()), descriptorWrite.data(), 0, nullptr);
vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, 1, &currentDescriptorSet, 0, nullptr);
currentUsedDescriptorSetsCount++;
}
else {
pfn_vkCmdPushDescriptorSetKHR(
commandBuffer,
bindPoint,
pipelineLayout,
0,
static_cast<uint32_t>(descriptorWrite.size()),
descriptorWrite.data());
}
for (const auto imageInfo : imageInfos) {
delete imageInfo;
@@ -342,10 +372,7 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
delete bufferInfo;
}
vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, 1, &currentDescriptorSet, 0, nullptr);
currentUsedUniformStreamBuffersCount++;
currentUsedDescriptorSetsCount++;
}
Shader::~Shader() {
@@ -387,7 +414,6 @@ void Shader::sendTextures(const UniformInfo* info, graphics::Texture** textures,
}
void Shader::calculateUniformBufferSizeAligned() {
gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
auto vgfx = (Graphics*)gfx;
auto minAlignment = vgfx->getMinUniformBufferOffsetAlignment();
size_t size = localUniformStagingData.size();
@@ -764,6 +790,8 @@ void Shader::createDescriptorSetLayout() {
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
layoutInfo.pBindings = bindings.data();
if (pfn_vkCmdPushDescriptorSetKHR)
layoutInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS) {
throw love::Exception("failed to create descriptor set layout");
+2
View File
@@ -74,6 +74,8 @@ private:
VkDescriptorSet allocateDescriptorSet();
PFN_vkCmdPushDescriptorSetKHR pfn_vkCmdPushDescriptorSetKHR = nullptr;
VkDeviceSize uniformBufferSizeAligned;
VkPipeline computePipeline;