mirror of
https://github.com/love2d/love.git
synced 2026-08-20 04:30:09 +02:00
vulkan: fix bug: incorrect uniform values
This commit is contained in:
@@ -498,8 +498,6 @@ Graphics::RendererInfo Graphics::getRendererInfo() const
|
|||||||
ss << "Vulkan( ";
|
ss << "Vulkan( ";
|
||||||
if (optionalDeviceFeatures.extendedDynamicState)
|
if (optionalDeviceFeatures.extendedDynamicState)
|
||||||
ss << VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME << " ";
|
ss << VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME << " ";
|
||||||
if (optionalDeviceFeatures.pushDescriptor)
|
|
||||||
ss << VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME << " ";
|
|
||||||
ss << ")";
|
ss << ")";
|
||||||
|
|
||||||
info.name = ss.str();
|
info.name = ss.str();
|
||||||
@@ -732,7 +730,7 @@ bool Graphics::dispatch(int x, int y, int z)
|
|||||||
|
|
||||||
vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_COMPUTE, computeShader->getComputePipeline());
|
vkCmdBindPipeline(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_COMPUTE, computeShader->getComputePipeline());
|
||||||
|
|
||||||
computeShader->cmdPushDescriptorSets(commandBuffers.at(currentFrame), static_cast<uint32_t>(currentFrame), VK_PIPELINE_BIND_POINT_COMPUTE);
|
computeShader->cmdPushDescriptorSets(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_COMPUTE);
|
||||||
|
|
||||||
vkCmdDispatch(commandBuffers.at(currentFrame), static_cast<uint32_t>(x), static_cast<uint32_t>(y), static_cast<uint32_t>(z));
|
vkCmdDispatch(commandBuffers.at(currentFrame), static_cast<uint32_t>(x), static_cast<uint32_t>(y), static_cast<uint32_t>(z));
|
||||||
|
|
||||||
@@ -836,6 +834,8 @@ void Graphics::beginFrame()
|
|||||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
|
|
||||||
Vulkan::resetShaderSwitches();
|
Vulkan::resetShaderSwitches();
|
||||||
|
|
||||||
|
usedShadersInFrame.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::startRecordingGraphicsCommands(bool newFrame)
|
void Graphics::startRecordingGraphicsCommands(bool newFrame)
|
||||||
@@ -883,6 +883,11 @@ uint32_t Graphics::getNumImagesInFlight() const
|
|||||||
return MAX_FRAMES_IN_FLIGHT;
|
return MAX_FRAMES_IN_FLIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t Graphics::getFrameIndex() const
|
||||||
|
{
|
||||||
|
return currentFrame;
|
||||||
|
}
|
||||||
|
|
||||||
const VkDeviceSize Graphics::getMinUniformBufferOffsetAlignment() const
|
const VkDeviceSize Graphics::getMinUniformBufferOffsetAlignment() const
|
||||||
{
|
{
|
||||||
return minUniformBufferOffsetAlignment;
|
return minUniformBufferOffsetAlignment;
|
||||||
@@ -1189,8 +1194,6 @@ static void findOptionalDeviceExtensions(VkPhysicalDevice physicalDevice, Option
|
|||||||
{
|
{
|
||||||
if (strcmp(extension.extensionName, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) == 0)
|
if (strcmp(extension.extensionName, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) == 0)
|
||||||
optionalDeviceFeatures.extendedDynamicState = true;
|
optionalDeviceFeatures.extendedDynamicState = true;
|
||||||
if (strcmp(extension.extensionName, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME) == 0)
|
|
||||||
optionalDeviceFeatures.pushDescriptor = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1231,8 +1234,6 @@ void Graphics::createLogicalDevice()
|
|||||||
|
|
||||||
if (optionalDeviceFeatures.extendedDynamicState)
|
if (optionalDeviceFeatures.extendedDynamicState)
|
||||||
enabledExtensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
|
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.enabledExtensionCount = static_cast<uint32_t>(enabledExtensions.size());
|
||||||
createInfo.ppEnabledExtensionNames = enabledExtensions.data();
|
createInfo.ppEnabledExtensionNames = enabledExtensions.data();
|
||||||
@@ -1288,14 +1289,6 @@ void Graphics::createLogicalDevice()
|
|||||||
ext.vkCmdSetStencilOpEXT = (PFN_vkCmdSetStencilOpEXT)vkGetDeviceProcAddr(device, "vkCmdSetStencilOpEXT");
|
ext.vkCmdSetStencilOpEXT = (PFN_vkCmdSetStencilOpEXT)vkGetDeviceProcAddr(device, "vkCmdSetStencilOpEXT");
|
||||||
ext.vkCmdSetStencilTestEnableEXT = (PFN_vkCmdSetStencilTestEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetStencilTestEnableEXT");
|
ext.vkCmdSetStencilTestEnableEXT = (PFN_vkCmdSetStencilTestEnableEXT)vkGetDeviceProcAddr(device, "vkCmdSetStencilTestEnableEXT");
|
||||||
ext.vkCmdSetViewportWithCountEXT = (PFN_vkCmdSetViewportWithCountEXT)vkGetDeviceProcAddr(device, "vkCmdSetViewportWithCountEXT");
|
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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1852,6 +1845,8 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
|
|||||||
if (!renderPassState.active)
|
if (!renderPassState.active)
|
||||||
startRenderPass();
|
startRenderPass();
|
||||||
|
|
||||||
|
Shader::current->attach();
|
||||||
|
|
||||||
GraphicsPipelineConfiguration configuration{};
|
GraphicsPipelineConfiguration configuration{};
|
||||||
|
|
||||||
configuration.renderPass = renderPassState.renderPass;
|
configuration.renderPass = renderPassState.renderPass;
|
||||||
@@ -1892,8 +1887,6 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
|
|||||||
offsets.push_back((VkDeviceSize)0);
|
offsets.push_back((VkDeviceSize)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto currentUniformData = getCurrentBuiltinUniformData();
|
|
||||||
configuration.shader->setUniformData(currentUniformData);
|
|
||||||
if (texture == nullptr)
|
if (texture == nullptr)
|
||||||
configuration.shader->setMainTex(standardTexture.get());
|
configuration.shader->setMainTex(standardTexture.get());
|
||||||
else
|
else
|
||||||
@@ -1901,7 +1894,7 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
|
|||||||
|
|
||||||
ensureGraphicsPipelineConfiguration(configuration);
|
ensureGraphicsPipelineConfiguration(configuration);
|
||||||
|
|
||||||
configuration.shader->cmdPushDescriptorSets(commandBuffers.at(currentFrame), static_cast<uint32_t>(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS);
|
configuration.shader->cmdPushDescriptorSets(commandBuffers.at(currentFrame), VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||||
vkCmdBindVertexBuffers(commandBuffers.at(currentFrame), 0, static_cast<uint32_t>(bufferVector.size()), bufferVector.data(), offsets.data());
|
vkCmdBindVertexBuffers(commandBuffers.at(currentFrame), 0, static_cast<uint32_t>(bufferVector.size()), bufferVector.data(), offsets.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2074,6 +2067,11 @@ void Graphics::setComputeShader(Shader *shader)
|
|||||||
computeShader = shader;
|
computeShader = shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<Shader*> &Graphics::getUsedShadersInFrame()
|
||||||
|
{
|
||||||
|
return usedShadersInFrame;
|
||||||
|
}
|
||||||
|
|
||||||
const OptionalDeviceFeatures &Graphics::getOptionalDeviceFeatures() const
|
const OptionalDeviceFeatures &Graphics::getOptionalDeviceFeatures() const
|
||||||
{
|
{
|
||||||
return optionalDeviceFeatures;
|
return optionalDeviceFeatures;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
@@ -99,7 +100,6 @@ struct OptionalInstanceExtensions
|
|||||||
struct OptionalDeviceFeatures
|
struct OptionalDeviceFeatures
|
||||||
{
|
{
|
||||||
bool extendedDynamicState = false;
|
bool extendedDynamicState = false;
|
||||||
bool pushDescriptor = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OptionalDeviceExtensionFunctions
|
struct OptionalDeviceExtensionFunctions
|
||||||
@@ -116,9 +116,6 @@ struct OptionalDeviceExtensionFunctions
|
|||||||
PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT = nullptr;
|
PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT = nullptr;
|
||||||
PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT = nullptr;
|
PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT = nullptr;
|
||||||
PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT = nullptr;
|
PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT = nullptr;
|
||||||
|
|
||||||
// push descriptor
|
|
||||||
PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GraphicsPipelineConfiguration
|
struct GraphicsPipelineConfiguration
|
||||||
@@ -232,7 +229,7 @@ public:
|
|||||||
|
|
||||||
virtual ~Graphics();
|
virtual ~Graphics();
|
||||||
|
|
||||||
const char* getName() const override;
|
const char *getName() const override;
|
||||||
const VkDevice getDevice() const;
|
const VkDevice getDevice() const;
|
||||||
const VkPhysicalDevice getPhysicalDevice() const;
|
const VkPhysicalDevice getPhysicalDevice() const;
|
||||||
const VmaAllocator getVmaAllocator() const;
|
const VmaAllocator getVmaAllocator() const;
|
||||||
@@ -281,15 +278,20 @@ public:
|
|||||||
void submitGpuCommands(bool present);
|
void submitGpuCommands(bool present);
|
||||||
|
|
||||||
uint32_t getNumImagesInFlight() const;
|
uint32_t getNumImagesInFlight() const;
|
||||||
|
uint32_t getFrameIndex() const;
|
||||||
|
|
||||||
const VkDeviceSize getMinUniformBufferOffsetAlignment() const;
|
const VkDeviceSize getMinUniformBufferOffsetAlignment() const;
|
||||||
graphics::Texture *getDefaultTexture() const;
|
graphics::Texture *getDefaultTexture() const;
|
||||||
VkSampler getCachedSampler(const SamplerState&);
|
VkSampler getCachedSampler(const SamplerState&);
|
||||||
|
|
||||||
void setComputeShader(Shader*);
|
void setComputeShader(Shader*);
|
||||||
|
std::set<Shader*> &getUsedShadersInFrame();
|
||||||
|
|
||||||
const OptionalDeviceFeatures &getOptionalDeviceFeatures() const;
|
const OptionalDeviceFeatures &getOptionalDeviceFeatures() const;
|
||||||
const OptionalDeviceExtensionFunctions &getExtensionFunctions() const;
|
const OptionalDeviceExtensionFunctions &getExtensionFunctions() const;
|
||||||
|
|
||||||
|
graphics::Shader::BuiltinUniformData getCurrentBuiltinUniformData();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
graphics::ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
|
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;
|
graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override;
|
||||||
@@ -319,11 +321,11 @@ private:
|
|||||||
void createImageViews();
|
void createImageViews();
|
||||||
void createDefaultRenderPass();
|
void createDefaultRenderPass();
|
||||||
void createDefaultFramebuffers();
|
void createDefaultFramebuffers();
|
||||||
VkFramebuffer createFramebuffer(FramebufferConfiguration&);
|
VkFramebuffer createFramebuffer(FramebufferConfiguration &);
|
||||||
VkFramebuffer getFramebuffer(FramebufferConfiguration&);
|
VkFramebuffer getFramebuffer(FramebufferConfiguration &);
|
||||||
void createDefaultShaders();
|
void createDefaultShaders();
|
||||||
VkRenderPass createRenderPass(RenderPassConfiguration&);
|
VkRenderPass createRenderPass(RenderPassConfiguration &);
|
||||||
VkPipeline createGraphicsPipeline(GraphicsPipelineConfiguration&);
|
VkPipeline createGraphicsPipeline(GraphicsPipelineConfiguration &);
|
||||||
void createColorResources();
|
void createColorResources();
|
||||||
VkFormat findSupportedFormat(const std::vector<VkFormat> &candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
|
VkFormat findSupportedFormat(const std::vector<VkFormat> &candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
|
||||||
VkFormat findDepthFormat();
|
VkFormat findDepthFormat();
|
||||||
@@ -339,10 +341,9 @@ private:
|
|||||||
void beginFrame();
|
void beginFrame();
|
||||||
void startRecordingGraphicsCommands(bool newFrame);
|
void startRecordingGraphicsCommands(bool newFrame);
|
||||||
void endRecordingGraphicsCommands(bool present);
|
void endRecordingGraphicsCommands(bool present);
|
||||||
void ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration&);
|
void ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration &);
|
||||||
graphics::Shader::BuiltinUniformData getCurrentBuiltinUniformData();
|
|
||||||
void updatedBatchedDrawBuffers();
|
void updatedBatchedDrawBuffers();
|
||||||
bool usesConstantVertexColor(const VertexAttributes&);
|
bool usesConstantVertexColor(const VertexAttributes &);
|
||||||
void createVulkanVertexFormat(
|
void createVulkanVertexFormat(
|
||||||
VertexAttributes vertexAttributes,
|
VertexAttributes vertexAttributes,
|
||||||
std::vector<VkVertexInputBindingDescription> &bindingDescriptions,
|
std::vector<VkVertexInputBindingDescription> &bindingDescriptions,
|
||||||
@@ -405,6 +406,7 @@ private:
|
|||||||
// just like batchedDrawBuffers we need a vector for each frame in flight.
|
// just like batchedDrawBuffers we need a vector for each frame in flight.
|
||||||
std::vector<std::vector<std::function<void()>>> cleanUpFunctions;
|
std::vector<std::vector<std::function<void()>>> cleanUpFunctions;
|
||||||
std::vector<std::vector<std::function<void()>>> readbackCallbacks;
|
std::vector<std::vector<std::function<void()>>> readbackCallbacks;
|
||||||
|
std::set<Shader*> usedShadersInFrame;
|
||||||
RenderpassState renderPassState;
|
RenderpassState renderPassState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -160,8 +160,6 @@ Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[])
|
|||||||
auto gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
|
auto gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
|
||||||
vgfx = dynamic_cast<Graphics*>(gfx);
|
vgfx = dynamic_cast<Graphics*>(gfx);
|
||||||
auto &optionalDeviceFeaures = vgfx->getOptionalDeviceFeatures();
|
auto &optionalDeviceFeaures = vgfx->getOptionalDeviceFeatures();
|
||||||
if (optionalDeviceFeaures.pushDescriptor)
|
|
||||||
pfn_vkCmdPushDescriptorSetKHR = vgfx->getExtensionFunctions().vkCmdPushDescriptorSetKHR;
|
|
||||||
|
|
||||||
loadVolatile();
|
loadVolatile();
|
||||||
}
|
}
|
||||||
@@ -232,7 +230,7 @@ VkPipeline Shader::getComputePipeline() const
|
|||||||
return computePipeline;
|
return computePipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkDescriptorImageInfo* createDescriptorImageInfo(graphics::Texture *texture, bool sampler)
|
static VkDescriptorImageInfo* createDescriptorImageInfo(graphics::Texture* texture, bool sampler)
|
||||||
{
|
{
|
||||||
auto vkTexture = (Texture*)texture;
|
auto vkTexture = (Texture*)texture;
|
||||||
|
|
||||||
@@ -246,90 +244,38 @@ static VkDescriptorImageInfo* createDescriptorImageInfo(graphics::Texture *textu
|
|||||||
return imageInfo;
|
return imageInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frameIndex, VkPipelineBindPoint bindPoint)
|
void Shader::newFrame(uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
// detect whether a new frame has begun
|
currentFrame = frameIndex;
|
||||||
if (currentFrame != frameIndex)
|
|
||||||
|
currentUsedUniformStreamBuffersCount = 0;
|
||||||
|
currentUsedDescriptorSetsCount = 0;
|
||||||
|
|
||||||
|
if (streamBuffers.at(currentFrame).size() > 1)
|
||||||
{
|
{
|
||||||
currentFrame = frameIndex;
|
size_t newSize = 0;
|
||||||
|
for (auto streamBuffer : streamBuffers.at(currentFrame))
|
||||||
currentUsedUniformStreamBuffersCount = 0;
|
|
||||||
currentUsedDescriptorSetsCount = 0;
|
|
||||||
|
|
||||||
// we needed more memory last frame, let's collapse all buffers into a single one.
|
|
||||||
if (streamBuffers.at(currentFrame).size() > 1)
|
|
||||||
{
|
{
|
||||||
size_t newSize = 0;
|
newSize += streamBuffer->getSize();
|
||||||
for (auto streamBuffer : streamBuffers.at(currentFrame))
|
delete streamBuffer;
|
||||||
{
|
|
||||||
newSize += streamBuffer->getSize();
|
|
||||||
delete streamBuffer;
|
|
||||||
}
|
|
||||||
streamBuffers.at(currentFrame).clear();
|
|
||||||
streamBuffers.at(currentFrame).push_back(new StreamBuffer(vgfx, BUFFERUSAGE_UNIFORM, newSize));
|
|
||||||
}
|
}
|
||||||
// no collapse necessary, can just call nextFrame to reset the current (only) streambuffer
|
streamBuffers.at(currentFrame).clear();
|
||||||
else
|
streamBuffers.at(currentFrame).push_back(new StreamBuffer(vgfx, BUFFERUSAGE_UNIFORM, newSize));
|
||||||
streamBuffers.at(currentFrame).at(0)->nextFrame();
|
|
||||||
}
|
}
|
||||||
// still the same frame
|
|
||||||
else
|
else
|
||||||
{
|
streamBuffers.at(currentFrame).at(0)->nextFrame();
|
||||||
auto usedStreamBufferMemory = currentUsedUniformStreamBuffersCount * uniformBufferSizeAligned;
|
|
||||||
if (usedStreamBufferMemory >= streamBuffers.at(currentFrame).back()->getSize())
|
|
||||||
{
|
|
||||||
// we ran out of memory in the current frame, need to allocate more.
|
|
||||||
streamBuffers.at(currentFrame).push_back(new StreamBuffer(vgfx, BUFFERUSAGE_UNIFORM, STREAMBUFFER_DEFAULT_SIZE * uniformBufferSizeAligned));
|
|
||||||
currentUsedUniformStreamBuffersCount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDescriptorSet currentDescriptorSet;
|
if (currentUsedDescriptorSetsCount >= static_cast<uint32_t>(descriptorSetsVector.at(currentFrame).size()))
|
||||||
|
descriptorSetsVector.at(currentFrame).push_back(allocateDescriptorSet());
|
||||||
|
|
||||||
if (pfn_vkCmdPushDescriptorSetKHR)
|
currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(currentUsedDescriptorSetsCount);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<VkWriteDescriptorSet> descriptorWrite{};
|
std::vector<VkWriteDescriptorSet> descriptorWrite{};
|
||||||
|
|
||||||
VkDescriptorBufferInfo* bufferInfo = nullptr;
|
|
||||||
|
|
||||||
if (!localUniformStagingData.empty()) {
|
|
||||||
// additional data is always added onto the last stream buffer in the current frame
|
|
||||||
auto currentStreamBuffer = streamBuffers.at(currentFrame).back();
|
|
||||||
|
|
||||||
auto mapInfo = currentStreamBuffer->map(uniformBufferSizeAligned);
|
|
||||||
memcpy(mapInfo.data, localUniformStagingData.data(), localUniformStagingData.size());
|
|
||||||
currentStreamBuffer->unmap(uniformBufferSizeAligned);
|
|
||||||
currentStreamBuffer->markUsed(uniformBufferSizeAligned);
|
|
||||||
|
|
||||||
bufferInfo = new VkDescriptorBufferInfo();
|
|
||||||
bufferInfo->buffer = (VkBuffer)currentStreamBuffer->getHandle();
|
|
||||||
bufferInfo->offset = currentUsedUniformStreamBuffersCount * uniformBufferSizeAligned;
|
|
||||||
bufferInfo->range = localUniformStagingData.size();
|
|
||||||
|
|
||||||
VkWriteDescriptorSet uniformWrite{};
|
|
||||||
uniformWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
||||||
uniformWrite.dstSet = currentDescriptorSet;
|
|
||||||
uniformWrite.dstBinding = uniformLocation;
|
|
||||||
uniformWrite.dstArrayElement = 0;
|
|
||||||
uniformWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
||||||
uniformWrite.descriptorCount = 1;
|
|
||||||
uniformWrite.pBufferInfo = bufferInfo;
|
|
||||||
|
|
||||||
descriptorWrite.push_back(uniformWrite);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<VkDescriptorImageInfo*> imageInfos;
|
std::vector<VkDescriptorImageInfo*> imageInfos;
|
||||||
|
|
||||||
// update everything other than uniform buffers (since that's already taken care of.
|
// update everything other than uniform buffers
|
||||||
for (const auto& [key, val] : uniformInfos) {
|
for (const auto &[key, val] : uniformInfos) {
|
||||||
// fixme: other types.
|
// fixme: other types.
|
||||||
if (val.baseType == UNIFORM_SAMPLER) {
|
if (val.baseType == UNIFORM_SAMPLER) {
|
||||||
VkWriteDescriptorSet write{};
|
VkWriteDescriptorSet write{};
|
||||||
@@ -364,29 +310,93 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pfn_vkCmdPushDescriptorSetKHR)
|
vkUpdateDescriptorSets(device, static_cast<uint32_t>(descriptorWrite.size()), descriptorWrite.data(), 0, nullptr);
|
||||||
pfn_vkCmdPushDescriptorSetKHR(
|
|
||||||
commandBuffer,
|
|
||||||
bindPoint,
|
|
||||||
pipelineLayout,
|
|
||||||
0,
|
|
||||||
static_cast<uint32_t>(descriptorWrite.size()),
|
|
||||||
descriptorWrite.data());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vkUpdateDescriptorSets(device, static_cast<uint32_t>(descriptorWrite.size()), descriptorWrite.data(), 0, nullptr);
|
|
||||||
|
|
||||||
vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, 1, ¤tDescriptorSet, 0, nullptr);
|
|
||||||
|
|
||||||
currentUsedDescriptorSetsCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto imageInfo : imageInfos)
|
for (const auto imageInfo : imageInfos)
|
||||||
delete imageInfo;
|
delete imageInfo;
|
||||||
if (bufferInfo)
|
}
|
||||||
delete bufferInfo;
|
|
||||||
|
|
||||||
currentUsedUniformStreamBuffersCount++;
|
void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint bindPoint)
|
||||||
|
{
|
||||||
|
if (!localUniformData.empty())
|
||||||
|
{
|
||||||
|
auto usedStreamBufferMemory = currentUsedUniformStreamBuffersCount * uniformBufferSizeAligned;
|
||||||
|
if (usedStreamBufferMemory >= streamBuffers.at(currentFrame).back()->getSize())
|
||||||
|
{
|
||||||
|
streamBuffers.at(currentFrame).push_back(new StreamBuffer(vgfx, BUFFERUSAGE_UNIFORM, STREAMBUFFER_DEFAULT_SIZE * uniformBufferSizeAligned));
|
||||||
|
currentUsedUniformStreamBuffersCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (builtinUniformDataOffset.has_value())
|
||||||
|
{
|
||||||
|
auto builtinData = vgfx->getCurrentBuiltinUniformData();
|
||||||
|
auto dst = localUniformData.data() + builtinUniformDataOffset.value();
|
||||||
|
memcpy(dst, &builtinData, sizeof(builtinData));
|
||||||
|
}
|
||||||
|
|
||||||
|
// additional data is always added onto the last stream buffer in the current frame
|
||||||
|
auto currentStreamBuffer = streamBuffers.at(currentFrame).back();
|
||||||
|
|
||||||
|
auto mapInfo = currentStreamBuffer->map(uniformBufferSizeAligned);
|
||||||
|
memcpy(mapInfo.data, localUniformData.data(), localUniformData.size());
|
||||||
|
currentStreamBuffer->unmap(uniformBufferSizeAligned);
|
||||||
|
currentStreamBuffer->markUsed(uniformBufferSizeAligned);
|
||||||
|
|
||||||
|
VkDescriptorBufferInfo bufferInfo{};
|
||||||
|
bufferInfo.buffer = (VkBuffer)currentStreamBuffer->getHandle();
|
||||||
|
bufferInfo.offset = currentUsedUniformStreamBuffersCount * uniformBufferSizeAligned;
|
||||||
|
bufferInfo.range = localUniformData.size();
|
||||||
|
|
||||||
|
VkWriteDescriptorSet uniformWrite{};
|
||||||
|
uniformWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
uniformWrite.dstSet = currentDescriptorSet;
|
||||||
|
uniformWrite.dstBinding = uniformLocation;
|
||||||
|
uniformWrite.dstArrayElement = 0;
|
||||||
|
uniformWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
|
uniformWrite.descriptorCount = 1;
|
||||||
|
uniformWrite.pBufferInfo = &bufferInfo;
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(device, 1, &uniformWrite, 0, nullptr);
|
||||||
|
|
||||||
|
currentUsedUniformStreamBuffersCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::vector<BuiltinUniform> builtinUniformTextures = {
|
||||||
|
BUILTIN_TEXTURE_MAIN,
|
||||||
|
BUILTIN_TEXTURE_VIDEO_Y,
|
||||||
|
BUILTIN_TEXTURE_VIDEO_CB,
|
||||||
|
BUILTIN_TEXTURE_VIDEO_CR,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto &builtin : builtinUniformTextures)
|
||||||
|
if (builtinUniformInfo[builtin] != nullptr)
|
||||||
|
{
|
||||||
|
auto texture = dynamic_cast<Texture*>(builtinUniformInfo[builtin]->textures[0]);
|
||||||
|
|
||||||
|
VkDescriptorImageInfo imageInfo{};
|
||||||
|
imageInfo.imageLayout = texture->getImageLayout();
|
||||||
|
imageInfo.imageView = (VkImageView)texture->getRenderTargetHandle();
|
||||||
|
imageInfo.sampler = (VkSampler)texture->getSamplerHandle();
|
||||||
|
|
||||||
|
VkWriteDescriptorSet mainTexWrite{};
|
||||||
|
mainTexWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
mainTexWrite.dstSet = currentDescriptorSet;
|
||||||
|
mainTexWrite.dstBinding = builtinUniformInfo[builtin]->location;
|
||||||
|
mainTexWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
mainTexWrite.descriptorCount = 1;
|
||||||
|
mainTexWrite.pImageInfo = &imageInfo;
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(device, 1, &mainTexWrite, 0, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, 1, ¤tDescriptorSet, 0, nullptr);
|
||||||
|
|
||||||
|
currentUsedDescriptorSetsCount++;
|
||||||
|
|
||||||
|
if (currentUsedDescriptorSetsCount >= static_cast<uint32_t>(descriptorSetsVector.at(currentFrame).size()))
|
||||||
|
descriptorSetsVector.at(currentFrame).push_back(allocateDescriptorSet());
|
||||||
|
|
||||||
|
currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(currentUsedDescriptorSetsCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader::~Shader()
|
Shader::~Shader()
|
||||||
@@ -396,6 +406,13 @@ Shader::~Shader()
|
|||||||
|
|
||||||
void Shader::attach()
|
void Shader::attach()
|
||||||
{
|
{
|
||||||
|
auto &usedShadersInFrame = vgfx->getUsedShadersInFrame();
|
||||||
|
if (usedShadersInFrame.find(this) == usedShadersInFrame.end())
|
||||||
|
{
|
||||||
|
newFrame(vgfx->getFrameIndex());
|
||||||
|
usedShadersInFrame.insert(this);
|
||||||
|
}
|
||||||
|
|
||||||
if (!isCompute)
|
if (!isCompute)
|
||||||
{
|
{
|
||||||
if (Shader::current != this)
|
if (Shader::current != this)
|
||||||
@@ -415,25 +432,68 @@ int Shader::getVertexAttributeIndex(const std::string &name)
|
|||||||
return it == attributes.end() ? -1 : it->second;
|
return it == attributes.end() ? -1 : it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Shader::UniformInfo* Shader::getUniformInfo(const std::string &name) const
|
const Shader::UniformInfo *Shader::getUniformInfo(const std::string &name) const
|
||||||
{
|
{
|
||||||
return &uniformInfos.at(name);
|
return &uniformInfos.at(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Shader::UniformInfo* Shader::getUniformInfo(BuiltinUniform builtin) const
|
const Shader::UniformInfo *Shader::getUniformInfo(BuiltinUniform builtin) const
|
||||||
{
|
{
|
||||||
return builtinUniformInfo[builtin];
|
return builtinUniformInfo[builtin];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::updateUniform(const UniformInfo* info, int count)
|
static bool usesLocalUniformData(const graphics::Shader::UniformInfo *info)
|
||||||
|
{
|
||||||
|
return info->baseType == graphics::Shader::UNIFORM_BOOL ||
|
||||||
|
info->baseType == graphics::Shader::UNIFORM_FLOAT ||
|
||||||
|
info->baseType == graphics::Shader::UNIFORM_INT ||
|
||||||
|
info->baseType == graphics::Shader::UNIFORM_MATRIX ||
|
||||||
|
info->baseType == graphics::Shader::UNIFORM_UINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::updateUniform(const UniformInfo *info, int count)
|
||||||
{
|
{
|
||||||
if (current == this)
|
if (current == this)
|
||||||
Graphics::flushBatchedDrawsGlobal();
|
Graphics::flushBatchedDrawsGlobal();
|
||||||
|
|
||||||
|
if (usesLocalUniformData(info))
|
||||||
|
memcpy(localUniformData.data(), localUniformStagingData.data(), localUniformStagingData.size());
|
||||||
|
else if (info->baseType == UNIFORM_SAMPLER || info->baseType == UNIFORM_STORAGETEXTURE)
|
||||||
|
{
|
||||||
|
bool isSampler = info->baseType == UNIFORM_SAMPLER;
|
||||||
|
|
||||||
|
std::vector<VkDescriptorImageInfo> imageInfos;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
auto vkTexture = dynamic_cast<Texture*>(info->textures[i]);
|
||||||
|
|
||||||
|
VkDescriptorImageInfo imageInfo{};
|
||||||
|
|
||||||
|
imageInfo.imageLayout = vkTexture->getImageLayout();
|
||||||
|
imageInfo.imageView = (VkImageView)vkTexture->getRenderTargetHandle();
|
||||||
|
if (isSampler)
|
||||||
|
imageInfo.sampler = (VkSampler)vkTexture->getSamplerHandle();
|
||||||
|
|
||||||
|
imageInfos.push_back(imageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkWriteDescriptorSet write{};
|
||||||
|
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
write.dstSet = currentDescriptorSet;
|
||||||
|
write.dstBinding = info->location;
|
||||||
|
write.dstArrayElement = 0;
|
||||||
|
write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
write.descriptorCount = static_cast<uint32_t>(count);
|
||||||
|
write.pImageInfo = imageInfos.data();
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(device, 1, &write, 0, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::sendTextures(const UniformInfo *info, graphics::Texture **textures, int count)
|
void Shader::sendTextures(const UniformInfo *info, graphics::Texture **textures, int count)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
auto oldTexture = info->textures[i];
|
auto oldTexture = info->textures[i];
|
||||||
info->textures[i] = textures[i];
|
info->textures[i] = textures[i];
|
||||||
@@ -457,11 +517,11 @@ void Shader::buildLocalUniforms(spirv_cross::Compiler &comp, const spirv_cross::
|
|||||||
{
|
{
|
||||||
using namespace spirv_cross;
|
using namespace spirv_cross;
|
||||||
|
|
||||||
const auto& membertypes = type.member_types;
|
const auto &membertypes = type.member_types;
|
||||||
|
|
||||||
for (size_t uindex = 0; uindex < membertypes.size(); uindex++)
|
for (size_t uindex = 0; uindex < membertypes.size(); uindex++)
|
||||||
{
|
{
|
||||||
const auto& memberType = comp.get_type(membertypes[uindex]);
|
const auto &memberType = comp.get_type(membertypes[uindex]);
|
||||||
size_t memberSize = comp.get_declared_struct_member_size(type, uindex);
|
size_t memberSize = comp.get_declared_struct_member_size(type, uindex);
|
||||||
size_t offset = baseoff + comp.type_struct_member_offset(type, uindex);
|
size_t offset = baseoff + comp.type_struct_member_offset(type, uindex);
|
||||||
|
|
||||||
@@ -505,11 +565,11 @@ void Shader::buildLocalUniforms(spirv_cross::Compiler &comp, const spirv_cross::
|
|||||||
u.matrix.columns = memberType.columns;
|
u.matrix.columns = memberType.columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& reflectionIt = validationReflection.localUniforms.find(u.name);
|
const auto &reflectionIt = validationReflection.localUniforms.find(u.name);
|
||||||
if (reflectionIt != validationReflection.localUniforms.end())
|
if (reflectionIt != validationReflection.localUniforms.end())
|
||||||
{
|
{
|
||||||
const auto& localUniform = reflectionIt->second;
|
const auto &localUniform = reflectionIt->second;
|
||||||
const auto& values = localUniform.initializerValues;
|
const auto &values = localUniform.initializerValues;
|
||||||
if (!values.empty())
|
if (!values.empty())
|
||||||
memcpy(
|
memcpy(
|
||||||
u.data,
|
u.data,
|
||||||
@@ -562,8 +622,8 @@ void Shader::compileShaders()
|
|||||||
tshader->setGlobalUniformBinding(0);
|
tshader->setGlobalUniformBinding(0);
|
||||||
tshader->setGlobalUniformSet(0);
|
tshader->setGlobalUniformSet(0);
|
||||||
|
|
||||||
auto& glsl = stages[i]->getSource();
|
auto &glsl = stages[i]->getSource();
|
||||||
const char* csrc = glsl.c_str();
|
const char *csrc = glsl.c_str();
|
||||||
const int sourceLength = static_cast<int>(glsl.length());
|
const int sourceLength = static_cast<int>(glsl.length());
|
||||||
tshader->setStringsWithLengths(&csrc, &sourceLength, 1);
|
tshader->setStringsWithLengths(&csrc, &sourceLength, 1);
|
||||||
|
|
||||||
@@ -574,8 +634,8 @@ void Shader::compileShaders()
|
|||||||
|
|
||||||
if (!tshader->parse(&defaultTBuiltInResource, defaultVersion, defaultProfile, forceDefault, forwardCompat, EShMsgSuppressWarnings))
|
if (!tshader->parse(&defaultTBuiltInResource, defaultVersion, defaultProfile, forceDefault, forwardCompat, EShMsgSuppressWarnings))
|
||||||
{
|
{
|
||||||
const char* msg1 = tshader->getInfoLog();
|
const char *msg1 = tshader->getInfoLog();
|
||||||
const char* msg2 = tshader->getInfoDebugLog();
|
const char *msg2 = tshader->getInfoDebugLog();
|
||||||
|
|
||||||
throw love::Exception("error while parsing shader");
|
throw love::Exception("error while parsing shader");
|
||||||
}
|
}
|
||||||
@@ -640,7 +700,7 @@ void Shader::compileShaders()
|
|||||||
auto shaderResources = comp.get_shader_resources(active);
|
auto shaderResources = comp.get_shader_resources(active);
|
||||||
comp.set_enabled_interface_variables(std::move(active));
|
comp.set_enabled_interface_variables(std::move(active));
|
||||||
|
|
||||||
for (const auto& resource : shaderResources.uniform_buffers)
|
for (const auto &resource : shaderResources.uniform_buffers)
|
||||||
{
|
{
|
||||||
if (resource.name == "gl_DefaultUniformBlock")
|
if (resource.name == "gl_DefaultUniformBlock")
|
||||||
{
|
{
|
||||||
@@ -648,22 +708,26 @@ void Shader::compileShaders()
|
|||||||
size_t uniformBufferObjectSize = comp.get_declared_struct_size(type);
|
size_t uniformBufferObjectSize = comp.get_declared_struct_size(type);
|
||||||
auto defaultUniformBlockSize = comp.get_declared_struct_size(type);
|
auto defaultUniformBlockSize = comp.get_declared_struct_size(type);
|
||||||
localUniformStagingData.resize(defaultUniformBlockSize);
|
localUniformStagingData.resize(defaultUniformBlockSize);
|
||||||
|
localUniformData.resize(defaultUniformBlockSize);
|
||||||
uniformLocation = comp.get_decoration(resource.id, spv::DecorationBinding);
|
uniformLocation = comp.get_decoration(resource.id, spv::DecorationBinding);
|
||||||
|
|
||||||
memset(localUniformStagingData.data(), 0, defaultUniformBlockSize);
|
memset(localUniformStagingData.data(), 0, defaultUniformBlockSize);
|
||||||
|
memset(localUniformData.data(), 0, defaultUniformBlockSize);
|
||||||
|
|
||||||
std::string basename("");
|
std::string basename("");
|
||||||
buildLocalUniforms(comp, type, 0, basename);
|
buildLocalUniforms(comp, type, 0, basename);
|
||||||
|
|
||||||
|
memcpy(localUniformData.data(), localUniformStagingData.data(), localUniformStagingData.size());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw love::Exception("unimplemented: non default uniform blocks.");
|
throw love::Exception("unimplemented: non default uniform blocks.");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& r : shaderResources.sampled_images)
|
for (const auto &r : shaderResources.sampled_images)
|
||||||
{
|
{
|
||||||
const SPIRType& basetype = comp.get_type(r.base_type_id);
|
const SPIRType &basetype = comp.get_type(r.base_type_id);
|
||||||
const SPIRType& type = comp.get_type(r.type_id);
|
const SPIRType &type = comp.get_type(r.type_id);
|
||||||
const SPIRType& imagetype = comp.get_type(basetype.image.type);
|
const SPIRType &imagetype = comp.get_type(basetype.image.type);
|
||||||
|
|
||||||
graphics::Shader::UniformInfo info;
|
graphics::Shader::UniformInfo info;
|
||||||
info.location = comp.get_decoration(r.id, spv::DecorationBinding);
|
info.location = comp.get_decoration(r.id, spv::DecorationBinding);
|
||||||
@@ -729,9 +793,9 @@ void Shader::compileShaders()
|
|||||||
builtinUniformInfo[builtin] = &uniformInfos[info.name];
|
builtinUniformInfo[builtin] = &uniformInfos[info.name];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& r : shaderResources.storage_buffers)
|
for (const auto &r : shaderResources.storage_buffers)
|
||||||
{
|
{
|
||||||
const auto& type = comp.get_type(r.type_id);
|
const auto &type = comp.get_type(r.type_id);
|
||||||
|
|
||||||
UniformInfo u{};
|
UniformInfo u{};
|
||||||
u.baseType = UNIFORM_STORAGEBUFFER;
|
u.baseType = UNIFORM_STORAGEBUFFER;
|
||||||
@@ -752,7 +816,7 @@ void Shader::compileShaders()
|
|||||||
|
|
||||||
// todo: some stuff missing
|
// todo: some stuff missing
|
||||||
|
|
||||||
u.buffers = new love::graphics::Buffer * [u.count];
|
u.buffers = new love::graphics::Buffer *[u.count];
|
||||||
|
|
||||||
for (int i = 0; i < u.count; i++)
|
for (int i = 0; i < u.count; i++)
|
||||||
u.buffers[i] = nullptr;
|
u.buffers[i] = nullptr;
|
||||||
@@ -760,16 +824,16 @@ void Shader::compileShaders()
|
|||||||
uniformInfos[u.name] = u;
|
uniformInfos[u.name] = u;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& r : shaderResources.storage_images)
|
for (const auto &r : shaderResources.storage_images)
|
||||||
{
|
{
|
||||||
const auto& type = comp.get_type(r.type_id);
|
const auto &type = comp.get_type(r.type_id);
|
||||||
|
|
||||||
UniformInfo u{};
|
UniformInfo u{};
|
||||||
u.baseType = UNIFORM_STORAGETEXTURE;
|
u.baseType = UNIFORM_STORAGETEXTURE;
|
||||||
u.components = 1;
|
u.components = 1;
|
||||||
u.name = r.name;
|
u.name = r.name;
|
||||||
u.count = type.array.empty() ? 1 : type.array[0];
|
u.count = type.array.empty() ? 1 : type.array[0];
|
||||||
u.textures = new love::graphics::Texture * [u.count];
|
u.textures = new love::graphics::Texture *[u.count];
|
||||||
u.location = comp.get_decoration(r.id, spv::DecorationBinding);
|
u.location = comp.get_decoration(r.id, spv::DecorationBinding);
|
||||||
|
|
||||||
for (int i = 0; i < u.count; i++)
|
for (int i = 0; i < u.count; i++)
|
||||||
@@ -781,9 +845,9 @@ void Shader::compileShaders()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (shaderStage == SHADERSTAGE_VERTEX)
|
if (shaderStage == SHADERSTAGE_VERTEX)
|
||||||
for (const auto& r : shaderResources.stage_inputs)
|
for (const auto &r : shaderResources.stage_inputs)
|
||||||
{
|
{
|
||||||
const auto& name = r.name;
|
const auto &name = r.name;
|
||||||
const int attributeLocation = static_cast<int>(comp.get_decoration(r.id, spv::DecorationLocation));
|
const int attributeLocation = static_cast<int>(comp.get_decoration(r.id, spv::DecorationLocation));
|
||||||
attributes[name] = attributeLocation;
|
attributes[name] = attributeLocation;
|
||||||
}
|
}
|
||||||
@@ -798,7 +862,7 @@ void Shader::createDescriptorSetLayout()
|
|||||||
{
|
{
|
||||||
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
||||||
|
|
||||||
for (auto const& [key, val] : uniformInfos)
|
for (auto const &[key, val] : uniformInfos)
|
||||||
{
|
{
|
||||||
auto type = Vulkan::getDescriptorType(val.baseType);
|
auto type = Vulkan::getDescriptorType(val.baseType);
|
||||||
if (type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
|
if (type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
|
||||||
@@ -834,8 +898,6 @@ void Shader::createDescriptorSetLayout()
|
|||||||
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
|
layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
|
||||||
layoutInfo.pBindings = bindings.data();
|
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)
|
if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS)
|
||||||
throw love::Exception("failed to create descriptor set layout");
|
throw love::Exception("failed to create descriptor set layout");
|
||||||
@@ -874,7 +936,7 @@ void Shader::createStreamBuffers()
|
|||||||
streamBuffers[i].push_back(new StreamBuffer(vgfx, BUFFERUSAGE_UNIFORM, STREAMBUFFER_DEFAULT_SIZE * uniformBufferSizeAligned));
|
streamBuffers[i].push_back(new StreamBuffer(vgfx, BUFFERUSAGE_UNIFORM, STREAMBUFFER_DEFAULT_SIZE * uniformBufferSizeAligned));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::setVideoTextures(graphics::Texture* ytexture, graphics::Texture* cbtexture, graphics::Texture* crtexture)
|
void Shader::setVideoTextures(graphics::Texture *ytexture, graphics::Texture *cbtexture, graphics::Texture *crtexture)
|
||||||
{
|
{
|
||||||
// if the shader doesn't actually use these textures they might get optimized out
|
// if the shader doesn't actually use these textures they might get optimized out
|
||||||
// in that case this function becomes a noop.
|
// in that case this function becomes a noop.
|
||||||
@@ -901,21 +963,13 @@ void Shader::setVideoTextures(graphics::Texture* ytexture, graphics::Texture* cb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Shader::hasUniform(const std::string& name) const
|
bool Shader::hasUniform(const std::string &name) const
|
||||||
{
|
{
|
||||||
return uniformInfos.find(name) != uniformInfos.end();
|
return uniformInfos.find(name) != uniformInfos.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::setUniformData(BuiltinUniformData& data)
|
void Shader::setMainTex(graphics::Texture *texture)
|
||||||
{
|
{
|
||||||
char* ptr = (char*) builtinUniformInfo[BUILTIN_UNIFORMS_PER_DRAW]->data + builtinUniformDataOffset;
|
|
||||||
memcpy(ptr, &data, sizeof(BuiltinUniformData));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setMainTex(graphics::Texture* texture)
|
|
||||||
{
|
|
||||||
// if the shader doesn't actually use the texture it might get optimized out
|
|
||||||
// in that case this function becomes a noop.
|
|
||||||
if (builtinUniformInfo[BUILTIN_TEXTURE_MAIN] != nullptr)
|
if (builtinUniformInfo[BUILTIN_TEXTURE_MAIN] != nullptr)
|
||||||
{
|
{
|
||||||
auto oldTexture = builtinUniformInfo[BUILTIN_TEXTURE_MAIN]->textures[0];
|
auto oldTexture = builtinUniformInfo[BUILTIN_TEXTURE_MAIN]->textures[0];
|
||||||
@@ -938,7 +992,7 @@ VkDescriptorSet Shader::allocateDescriptorSet()
|
|||||||
|
|
||||||
sizes.push_back(size);
|
sizes.push_back(size);
|
||||||
|
|
||||||
for (const auto& [key, val] : uniformInfos)
|
for (const auto &[key, val] : uniformInfos)
|
||||||
{
|
{
|
||||||
VkDescriptorPoolSize size{};
|
VkDescriptorPoolSize size{};
|
||||||
auto type = Vulkan::getDescriptorType(val.baseType);
|
auto type = Vulkan::getDescriptorType(val.baseType);
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
// C++
|
// C++
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <iostream>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
@@ -43,7 +43,9 @@ public:
|
|||||||
|
|
||||||
const VkPipelineLayout getGraphicsPipelineLayout() const;
|
const VkPipelineLayout getGraphicsPipelineLayout() const;
|
||||||
|
|
||||||
void cmdPushDescriptorSets(VkCommandBuffer, uint32_t currentFrame, VkPipelineBindPoint);
|
void newFrame(uint32_t frameIndex);
|
||||||
|
|
||||||
|
void cmdPushDescriptorSets(VkCommandBuffer, VkPipelineBindPoint);
|
||||||
|
|
||||||
void attach() override;
|
void attach() override;
|
||||||
|
|
||||||
@@ -65,8 +67,6 @@ public:
|
|||||||
|
|
||||||
void setVideoTextures(graphics::Texture *ytexture, graphics::Texture *cbtexture, graphics::Texture *crtexture) override;
|
void setVideoTextures(graphics::Texture *ytexture, graphics::Texture *cbtexture, graphics::Texture *crtexture) override;
|
||||||
|
|
||||||
// fixme: use normal methods for this in the future.
|
|
||||||
void setUniformData(BuiltinUniformData &data);
|
|
||||||
void setMainTex(graphics::Texture *texture);
|
void setMainTex(graphics::Texture *texture);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -83,8 +83,6 @@ private:
|
|||||||
|
|
||||||
VkDescriptorSet allocateDescriptorSet();
|
VkDescriptorSet allocateDescriptorSet();
|
||||||
|
|
||||||
PFN_vkCmdPushDescriptorSetKHR pfn_vkCmdPushDescriptorSetKHR = nullptr;
|
|
||||||
|
|
||||||
VkDeviceSize uniformBufferSizeAligned;
|
VkDeviceSize uniformBufferSizeAligned;
|
||||||
|
|
||||||
VkPipeline computePipeline;
|
VkPipeline computePipeline;
|
||||||
@@ -112,12 +110,15 @@ private:
|
|||||||
UniformInfo *builtinUniformInfo[BUILTIN_MAX_ENUM];
|
UniformInfo *builtinUniformInfo[BUILTIN_MAX_ENUM];
|
||||||
|
|
||||||
std::unique_ptr<StreamBuffer> uniformBufferObjectBuffer;
|
std::unique_ptr<StreamBuffer> uniformBufferObjectBuffer;
|
||||||
|
std::vector<uint8> localUniformData;
|
||||||
std::vector<uint8> localUniformStagingData;
|
std::vector<uint8> localUniformStagingData;
|
||||||
uint32_t uniformLocation;
|
uint32_t uniformLocation;
|
||||||
size_t builtinUniformDataOffset;
|
std::optional<size_t> builtinUniformDataOffset;
|
||||||
|
|
||||||
std::unordered_map<std::string, int> attributes;
|
std::unordered_map<std::string, int> attributes;
|
||||||
|
|
||||||
|
VkDescriptorSet currentDescriptorSet;
|
||||||
|
|
||||||
uint32_t currentFrame;
|
uint32_t currentFrame;
|
||||||
uint32_t currentUsedUniformStreamBuffersCount;
|
uint32_t currentUsedUniformStreamBuffersCount;
|
||||||
uint32_t currentUsedDescriptorSetsCount;
|
uint32_t currentUsedDescriptorSetsCount;
|
||||||
|
|||||||
Reference in New Issue
Block a user