mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 04:22:34 +00:00
- fix vulkan crash when there are no textures in player's view
This commit is contained in:
parent
c485256c74
commit
08e86b5bcc
3 changed files with 54 additions and 9 deletions
|
@ -23,6 +23,7 @@
|
||||||
#include "vk_renderpass.h"
|
#include "vk_renderpass.h"
|
||||||
#include "vk_renderbuffers.h"
|
#include "vk_renderbuffers.h"
|
||||||
#include "vk_renderstate.h"
|
#include "vk_renderstate.h"
|
||||||
|
#include "vulkan/textures/vk_samplers.h"
|
||||||
#include "vulkan/shaders/vk_shader.h"
|
#include "vulkan/shaders/vk_shader.h"
|
||||||
#include "vulkan/system/vk_builders.h"
|
#include "vulkan/system/vk_builders.h"
|
||||||
#include "vulkan/system/vk_framebuffer.h"
|
#include "vulkan/system/vk_framebuffer.h"
|
||||||
|
@ -45,6 +46,7 @@ void VkRenderPassManager::Init()
|
||||||
CreateDynamicSetLayout();
|
CreateDynamicSetLayout();
|
||||||
CreateDescriptorPool();
|
CreateDescriptorPool();
|
||||||
CreateDynamicSet();
|
CreateDynamicSet();
|
||||||
|
CreateNullTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkRenderPassManager::RenderBuffersReset()
|
void VkRenderPassManager::RenderBuffersReset()
|
||||||
|
@ -63,6 +65,7 @@ void VkRenderPassManager::TextureSetPoolReset()
|
||||||
deleteList.DescriptorPools.push_back(std::move(desc));
|
deleteList.DescriptorPools.push_back(std::move(desc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
NullTextureDescriptorSet.reset();
|
||||||
TextureDescriptorPools.clear();
|
TextureDescriptorPools.clear();
|
||||||
TextureDescriptorSetsLeft = 0;
|
TextureDescriptorSetsLeft = 0;
|
||||||
TextureDescriptorsLeft = 0;
|
TextureDescriptorsLeft = 0;
|
||||||
|
@ -187,6 +190,42 @@ void VkRenderPassManager::CreateDynamicSet()
|
||||||
I_FatalError("CreateDynamicSet failed.\n");
|
I_FatalError("CreateDynamicSet failed.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VkRenderPassManager::CreateNullTexture()
|
||||||
|
{
|
||||||
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
|
||||||
|
ImageBuilder imgbuilder;
|
||||||
|
imgbuilder.setFormat(VK_FORMAT_R8G8B8A8_UNORM);
|
||||||
|
imgbuilder.setSize(1, 1);
|
||||||
|
imgbuilder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||||
|
NullTexture = imgbuilder.create(fb->device);
|
||||||
|
NullTexture->SetDebugName("VkRenderPassManager.NullTexture");
|
||||||
|
|
||||||
|
ImageViewBuilder viewbuilder;
|
||||||
|
viewbuilder.setImage(NullTexture.get(), VK_FORMAT_R8G8B8A8_UNORM);
|
||||||
|
NullTextureView = viewbuilder.create(fb->device);
|
||||||
|
NullTextureView->SetDebugName("VkRenderPassManager.NullTextureView");
|
||||||
|
|
||||||
|
PipelineBarrier barrier;
|
||||||
|
barrier.addImage(NullTexture.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
|
barrier.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
VulkanDescriptorSet* VkRenderPassManager::GetNullTextureDescriptorSet()
|
||||||
|
{
|
||||||
|
if (!NullTextureDescriptorSet)
|
||||||
|
{
|
||||||
|
NullTextureDescriptorSet = AllocateTextureDescriptorSet(1);
|
||||||
|
|
||||||
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
WriteDescriptors update;
|
||||||
|
update.addCombinedImageSampler(NullTextureDescriptorSet.get(), 0, NullTextureView.get(), fb->GetSamplerManager()->Get(CLAMP_XY_NOMIP), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
update.updateSets(fb->device);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NullTextureDescriptorSet.get();
|
||||||
|
}
|
||||||
|
|
||||||
void VkRenderPassManager::UpdateDynamicSet()
|
void VkRenderPassManager::UpdateDynamicSet()
|
||||||
{
|
{
|
||||||
auto fb = GetVulkanFrameBuffer();
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
|
|
@ -93,6 +93,8 @@ public:
|
||||||
std::unique_ptr<VulkanDescriptorSet> AllocateTextureDescriptorSet(int numLayers);
|
std::unique_ptr<VulkanDescriptorSet> AllocateTextureDescriptorSet(int numLayers);
|
||||||
VulkanPipelineLayout* GetPipelineLayout(int numLayers);
|
VulkanPipelineLayout* GetPipelineLayout(int numLayers);
|
||||||
|
|
||||||
|
VulkanDescriptorSet* GetNullTextureDescriptorSet();
|
||||||
|
|
||||||
std::unique_ptr<VulkanDescriptorSetLayout> DynamicSetLayout;
|
std::unique_ptr<VulkanDescriptorSetLayout> DynamicSetLayout;
|
||||||
std::map<VkRenderPassKey, std::unique_ptr<VkRenderPassSetup>> RenderPassSetup;
|
std::map<VkRenderPassKey, std::unique_ptr<VkRenderPassSetup>> RenderPassSetup;
|
||||||
|
|
||||||
|
@ -102,6 +104,7 @@ private:
|
||||||
void CreateDynamicSetLayout();
|
void CreateDynamicSetLayout();
|
||||||
void CreateDescriptorPool();
|
void CreateDescriptorPool();
|
||||||
void CreateDynamicSet();
|
void CreateDynamicSet();
|
||||||
|
void CreateNullTexture();
|
||||||
|
|
||||||
VulkanDescriptorSetLayout *GetTextureSetLayout(int numLayers);
|
VulkanDescriptorSetLayout *GetTextureSetLayout(int numLayers);
|
||||||
|
|
||||||
|
@ -112,4 +115,8 @@ private:
|
||||||
std::vector<std::unique_ptr<VulkanDescriptorSetLayout>> TextureSetLayouts;
|
std::vector<std::unique_ptr<VulkanDescriptorSetLayout>> TextureSetLayouts;
|
||||||
std::vector<std::unique_ptr<VulkanPipelineLayout>> PipelineLayouts;
|
std::vector<std::unique_ptr<VulkanPipelineLayout>> PipelineLayouts;
|
||||||
std::vector<VkVertexFormat> VertexFormats;
|
std::vector<VkVertexFormat> VertexFormats;
|
||||||
|
|
||||||
|
std::unique_ptr<VulkanImage> NullTexture;
|
||||||
|
std::unique_ptr<VulkanImageView> NullTextureView;
|
||||||
|
std::unique_ptr<VulkanDescriptorSet> NullTextureDescriptorSet;
|
||||||
};
|
};
|
||||||
|
|
|
@ -228,7 +228,7 @@ void VkRenderState::ApplyRenderPass(int dt)
|
||||||
pipelineKey.StencilPassOp = mStencilOp;
|
pipelineKey.StencilPassOp = mStencilOp;
|
||||||
pipelineKey.ColorMask = mColorMask;
|
pipelineKey.ColorMask = mColorMask;
|
||||||
pipelineKey.CullMode = mCullMode;
|
pipelineKey.CullMode = mCullMode;
|
||||||
pipelineKey.NumTextureLayers = mMaterial.mMaterial ? mMaterial.mMaterial->GetLayers() : 0;
|
pipelineKey.NumTextureLayers = mMaterial.mMaterial ? mMaterial.mMaterial->GetLayers() : 1; // Always force minimum 1 texture as the shader requires it
|
||||||
if (mSpecialEffect > EFF_NONE)
|
if (mSpecialEffect > EFF_NONE)
|
||||||
{
|
{
|
||||||
pipelineKey.SpecialEffect = mSpecialEffect;
|
pipelineKey.SpecialEffect = mSpecialEffect;
|
||||||
|
@ -423,16 +423,15 @@ void VkRenderState::ApplyVertexBuffers()
|
||||||
|
|
||||||
void VkRenderState::ApplyMaterial()
|
void VkRenderState::ApplyMaterial()
|
||||||
{
|
{
|
||||||
if (mMaterial.mChanged && mMaterial.mMaterial)
|
if (mMaterial.mChanged)
|
||||||
{
|
{
|
||||||
auto base = static_cast<VkHardwareTexture*>(mMaterial.mMaterial->GetLayer(0, mMaterial.mTranslation));
|
auto fb = GetVulkanFrameBuffer();
|
||||||
if (base)
|
auto passManager = fb->GetRenderPassManager();
|
||||||
{
|
|
||||||
auto fb = GetVulkanFrameBuffer();
|
|
||||||
auto passManager = fb->GetRenderPassManager();
|
|
||||||
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), 1, base->GetDescriptorSet(mMaterial));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
VkHardwareTexture* base = mMaterial.mMaterial ? static_cast<VkHardwareTexture*>(mMaterial.mMaterial->GetLayer(0, mMaterial.mTranslation)) : nullptr;
|
||||||
|
VulkanDescriptorSet* descriptorset = base ? base->GetDescriptorSet(mMaterial) : passManager->GetNullTextureDescriptorSet();
|
||||||
|
|
||||||
|
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), 1, descriptorset);
|
||||||
mMaterial.mChanged = false;
|
mMaterial.mChanged = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue