mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
vulkan: fix incorrect textures in shader uniforms
This commit is contained in:
@@ -358,7 +358,7 @@ void Graphics::submitGpuCommands(bool present, void *screenshotCallbackData)
|
||||
}
|
||||
}
|
||||
|
||||
endRecordingGraphicsCommands(present);
|
||||
endRecordingGraphicsCommands();
|
||||
|
||||
if (imagesInFlight[imageIndex] != VK_NULL_HANDLE)
|
||||
vkWaitForFences(device, 1, &imagesInFlight.at(imageIndex), VK_TRUE, UINT64_MAX);
|
||||
@@ -410,7 +410,7 @@ void Graphics::submitGpuCommands(bool present, void *screenshotCallbackData)
|
||||
callbacks.clear();
|
||||
}
|
||||
|
||||
startRecordingGraphicsCommands(false);
|
||||
startRecordingGraphicsCommands();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1103,7 +1103,7 @@ void Graphics::beginFrame()
|
||||
cleanUpFn();
|
||||
cleanUpFunctions.at(currentFrame).clear();
|
||||
|
||||
startRecordingGraphicsCommands(true);
|
||||
startRecordingGraphicsCommands();
|
||||
|
||||
Vulkan::cmdTransitionImageLayout(
|
||||
commandBuffers.at(currentFrame),
|
||||
@@ -1134,7 +1134,7 @@ void Graphics::beginFrame()
|
||||
usedShadersInFrame.clear();
|
||||
}
|
||||
|
||||
void Graphics::startRecordingGraphicsCommands(bool newFrame)
|
||||
void Graphics::startRecordingGraphicsCommands()
|
||||
{
|
||||
VkCommandBufferBeginInfo beginInfo{};
|
||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
@@ -1149,7 +1149,7 @@ void Graphics::startRecordingGraphicsCommands(bool newFrame)
|
||||
setDefaultRenderPass();
|
||||
}
|
||||
|
||||
void Graphics::endRecordingGraphicsCommands(bool present) {
|
||||
void Graphics::endRecordingGraphicsCommands() {
|
||||
if (renderPassState.active)
|
||||
endRenderPass();
|
||||
|
||||
@@ -1157,16 +1157,6 @@ void Graphics::endRecordingGraphicsCommands(bool present) {
|
||||
throw love::Exception("failed to record command buffer");
|
||||
}
|
||||
|
||||
uint32_t Graphics::getNumImagesInFlight() const
|
||||
{
|
||||
return MAX_FRAMES_IN_FLIGHT;
|
||||
}
|
||||
|
||||
uint32_t Graphics::getFrameIndex() const
|
||||
{
|
||||
return static_cast<uint32_t>(currentFrame);
|
||||
}
|
||||
|
||||
const VkDeviceSize Graphics::getMinUniformBufferOffsetAlignment() const
|
||||
{
|
||||
return minUniformBufferOffsetAlignment;
|
||||
@@ -2263,7 +2253,7 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
|
||||
}
|
||||
}
|
||||
|
||||
if (usesConstantVertexColor(attributes))
|
||||
if (!usesConstantVertexColor(attributes))
|
||||
{
|
||||
bufferVector.push_back((VkBuffer)defaultConstantColor->getHandle());
|
||||
offsets.push_back((VkDeviceSize)0);
|
||||
|
||||
@@ -289,8 +289,6 @@ public:
|
||||
void queueCleanUp(std::function<void()> cleanUp);
|
||||
void addReadbackCallback(std::function<void()> callback);
|
||||
void submitGpuCommands(bool present, void *screenshotCallbackData = nullptr);
|
||||
uint32_t getNumImagesInFlight() const;
|
||||
uint32_t getFrameIndex() const;
|
||||
const VkDeviceSize getMinUniformBufferOffsetAlignment() const;
|
||||
graphics::Texture *getDefaultTexture() const;
|
||||
VkSampler getCachedSampler(const SamplerState &sampler);
|
||||
@@ -349,8 +347,8 @@ private:
|
||||
void recreateSwapChain();
|
||||
void initDynamicState();
|
||||
void beginFrame();
|
||||
void startRecordingGraphicsCommands(bool newFrame);
|
||||
void endRecordingGraphicsCommands(bool present);
|
||||
void startRecordingGraphicsCommands();
|
||||
void endRecordingGraphicsCommands();
|
||||
void ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration &configuration);
|
||||
bool usesConstantVertexColor(const VertexAttributes &attribs);
|
||||
void createVulkanVertexFormat(
|
||||
|
||||
@@ -196,7 +196,7 @@ bool Shader::loadVolatile()
|
||||
createPipelineLayout();
|
||||
createDescriptorPoolSizes();
|
||||
createStreamBuffers();
|
||||
descriptorSetsVector.resize(vgfx->getNumImagesInFlight());
|
||||
descriptorSetsVector.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
currentFrame = 0;
|
||||
currentUsedUniformStreamBuffersCount = 0;
|
||||
currentUsedDescriptorSetsCount = 0;
|
||||
@@ -274,10 +274,11 @@ VkPipeline Shader::getComputePipeline() const
|
||||
return computePipeline;
|
||||
}
|
||||
|
||||
void Shader::newFrame(uint32_t frameIndex)
|
||||
void Shader::newFrame()
|
||||
{
|
||||
currentFrame = frameIndex;
|
||||
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
||||
|
||||
updatedUniforms.clear();
|
||||
currentUsedUniformStreamBuffersCount = 0;
|
||||
currentUsedDescriptorSetsCount = 0;
|
||||
|
||||
@@ -295,12 +296,10 @@ void Shader::newFrame(uint32_t frameIndex)
|
||||
else
|
||||
streamBuffers.at(0)->nextFrame();
|
||||
|
||||
if (currentUsedDescriptorSetsCount >= static_cast<uint32_t>(descriptorSetsVector.at(currentFrame).size()))
|
||||
if (descriptorSetsVector.at(currentFrame).size() == 0)
|
||||
descriptorSetsVector.at(currentFrame).push_back(allocateDescriptorSet());
|
||||
|
||||
currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(currentUsedDescriptorSetsCount);
|
||||
|
||||
initDescriptorSet();
|
||||
currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(0);
|
||||
}
|
||||
|
||||
void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint bindPoint)
|
||||
@@ -336,7 +335,7 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
|
||||
VkWriteDescriptorSet uniformWrite{};
|
||||
uniformWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
uniformWrite.dstSet = currentDescriptorSet;
|
||||
uniformWrite.dstBinding = uniformLocation;
|
||||
uniformWrite.dstBinding = localUniformLocation;
|
||||
uniformWrite.dstArrayElement = 0;
|
||||
uniformWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
uniformWrite.descriptorCount = 1;
|
||||
@@ -345,6 +344,8 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
|
||||
vkUpdateDescriptorSets(device, 1, &uniformWrite, 0, nullptr);
|
||||
|
||||
currentUsedUniformStreamBuffersCount++;
|
||||
|
||||
updatedUniforms.insert(localUniformLocation);
|
||||
}
|
||||
|
||||
static const std::vector<BuiltinUniform> builtinUniformTextures = {
|
||||
@@ -365,18 +366,28 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
|
||||
imageInfo.imageView = (VkImageView)texture->getRenderTargetHandle();
|
||||
imageInfo.sampler = (VkSampler)texture->getSamplerHandle();
|
||||
|
||||
auto location = builtinUniformInfo[builtin]->location;
|
||||
|
||||
VkWriteDescriptorSet textureWrite{};
|
||||
textureWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
textureWrite.dstSet = currentDescriptorSet;
|
||||
textureWrite.dstBinding = builtinUniformInfo[builtin]->location;
|
||||
textureWrite.dstBinding = location;
|
||||
textureWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
textureWrite.descriptorCount = 1;
|
||||
textureWrite.pImageInfo = &imageInfo;
|
||||
|
||||
vkUpdateDescriptorSets(device, 1, &textureWrite, 0, nullptr);
|
||||
|
||||
updatedUniforms.insert(location);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &u : uniformInfos)
|
||||
{
|
||||
if (updatedUniforms.find(u.second.location) == updatedUniforms.end())
|
||||
updateUniform(&u.second, u.second.count);
|
||||
}
|
||||
|
||||
vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, 1, ¤tDescriptorSet, 0, nullptr);
|
||||
|
||||
currentUsedDescriptorSetsCount++;
|
||||
@@ -385,8 +396,6 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
|
||||
descriptorSetsVector.at(currentFrame).push_back(allocateDescriptorSet());
|
||||
|
||||
currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(currentUsedDescriptorSetsCount);
|
||||
|
||||
initDescriptorSet();
|
||||
}
|
||||
|
||||
Shader::~Shader()
|
||||
@@ -399,7 +408,7 @@ void Shader::attach()
|
||||
auto &usedShadersInFrame = vgfx->getUsedShadersInFrame();
|
||||
if (usedShadersInFrame.find(this) == usedShadersInFrame.end())
|
||||
{
|
||||
newFrame(vgfx->getFrameIndex());
|
||||
newFrame();
|
||||
usedShadersInFrame.insert(this);
|
||||
}
|
||||
|
||||
@@ -532,6 +541,8 @@ void Shader::updateUniform(const UniformInfo* info, int count, bool internal)
|
||||
|
||||
vkUpdateDescriptorSets(device, 1, &write, 0, nullptr);
|
||||
}
|
||||
|
||||
updatedUniforms.insert(info->location);
|
||||
}
|
||||
|
||||
void Shader::sendTextures(const UniformInfo *info, graphics::Texture **textures, int count)
|
||||
@@ -544,6 +555,8 @@ void Shader::sendTextures(const UniformInfo *info, graphics::Texture **textures,
|
||||
if (oldTexture)
|
||||
oldTexture->release();
|
||||
}
|
||||
|
||||
updateUniform(info, count);
|
||||
}
|
||||
|
||||
void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count)
|
||||
@@ -556,6 +569,8 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe
|
||||
if (oldBuffer)
|
||||
oldBuffer->release();
|
||||
}
|
||||
|
||||
updateUniform(info, count);
|
||||
}
|
||||
|
||||
void Shader::calculateUniformBufferSizeAligned()
|
||||
@@ -568,13 +583,6 @@ void Shader::calculateUniformBufferSizeAligned()
|
||||
uniformBufferSizeAligned = factor * minAlignment;
|
||||
}
|
||||
|
||||
void Shader::initDescriptorSet()
|
||||
{
|
||||
for (const auto &entry : uniformInfos)
|
||||
if (Vulkan::getDescriptorType(entry.second.baseType) != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
|
||||
updateUniform(&entry.second, entry.second.count, true);
|
||||
}
|
||||
|
||||
void Shader::buildLocalUniforms(spirv_cross::Compiler &comp, const spirv_cross::SPIRType &type, size_t baseoff, const std::string &basename)
|
||||
{
|
||||
using namespace spirv_cross;
|
||||
@@ -776,7 +784,7 @@ void Shader::compileShaders()
|
||||
auto defaultUniformBlockSize = comp.get_declared_struct_size(type);
|
||||
localUniformStagingData.resize(defaultUniformBlockSize);
|
||||
localUniformData.resize(defaultUniformBlockSize);
|
||||
uniformLocation = comp.get_decoration(resource.id, spv::DecorationBinding);
|
||||
localUniformLocation = comp.get_decoration(resource.id, spv::DecorationBinding);
|
||||
|
||||
memset(localUniformStagingData.data(), 0, defaultUniformBlockSize);
|
||||
memset(localUniformData.data(), 0, defaultUniformBlockSize);
|
||||
@@ -956,7 +964,7 @@ void Shader::createDescriptorSetLayout()
|
||||
if (!localUniformStagingData.empty())
|
||||
{
|
||||
VkDescriptorSetLayoutBinding uniformBinding{};
|
||||
uniformBinding.binding = uniformLocation;
|
||||
uniformBinding.binding = localUniformLocation;
|
||||
uniformBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
uniformBinding.descriptorCount = 1;
|
||||
uniformBinding.stageFlags = stageFlags;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
|
||||
|
||||
namespace love
|
||||
@@ -63,7 +64,7 @@ public:
|
||||
|
||||
const VkPipelineLayout getGraphicsPipelineLayout() const;
|
||||
|
||||
void newFrame(uint32_t frameIndex);
|
||||
void newFrame();
|
||||
|
||||
void cmdPushDescriptorSets(VkCommandBuffer, VkPipelineBindPoint);
|
||||
|
||||
@@ -101,7 +102,6 @@ private:
|
||||
const spirv_cross::SPIRType &type,
|
||||
size_t baseoff,
|
||||
const std::string &basename);
|
||||
void initDescriptorSet();
|
||||
void updateUniform(const UniformInfo *info, int count, bool internal);
|
||||
|
||||
VkDescriptorSet allocateDescriptorSet();
|
||||
@@ -121,6 +121,8 @@ private:
|
||||
std::queue<VkDescriptorSet> freeDescriptorSets;
|
||||
std::vector<std::vector<VkDescriptorSet>> descriptorSetsVector;
|
||||
|
||||
std::set<uint32_t> updatedUniforms;
|
||||
|
||||
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
|
||||
std::vector<VkShaderModule> shaderModules;
|
||||
|
||||
@@ -135,7 +137,7 @@ private:
|
||||
std::unique_ptr<StreamBuffer> uniformBufferObjectBuffer;
|
||||
std::vector<uint8> localUniformData;
|
||||
std::vector<uint8> localUniformStagingData;
|
||||
uint32_t uniformLocation;
|
||||
uint32_t localUniformLocation;
|
||||
OptionalInt builtinUniformDataOffset;
|
||||
|
||||
std::unordered_map<std::string, int> attributes;
|
||||
|
||||
Reference in New Issue
Block a user