mirror of
https://github.com/love2d/love.git
synced 2026-08-15 07:41:11 +02:00
Merge pull request #2342 from erinmaus/relax-shader-storage-requirements
Relax shader storage requirements
This commit is contained in:
@@ -821,6 +821,8 @@ bool Graphics::setMode(void *context, const BackbufferSettings &settings)
|
||||
|
||||
void Graphics::initCapabilities()
|
||||
{
|
||||
VkPhysicalDeviceFeatures features;
|
||||
vkGetPhysicalDeviceFeatures(physicalDevice, &features);
|
||||
capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = true;
|
||||
capabilities.features[FEATURE_CLAMP_ZERO] = true;
|
||||
capabilities.features[FEATURE_CLAMP_ONE] = true;
|
||||
@@ -834,7 +836,9 @@ void Graphics::initCapabilities()
|
||||
capabilities.features[FEATURE_TEXEL_BUFFER] = true;
|
||||
capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = true;
|
||||
capabilities.features[FEATURE_INDIRECT_DRAW] = true;
|
||||
static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
capabilities.features[FEATURE_VERTEX_WRITE] = features.vertexPipelineStoresAndAtomics;
|
||||
capabilities.features[FEATURE_PIXEL_WRITE] = features.fragmentStoresAndAtomics;
|
||||
static_assert(FEATURE_MAX_ENUM == 15, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
|
||||
VkPhysicalDeviceProperties properties;
|
||||
vkGetPhysicalDeviceProperties(physicalDevice, &properties);
|
||||
@@ -953,6 +957,11 @@ void Graphics::draw(const DrawCommand &cmd)
|
||||
{
|
||||
prepareDraw(cmd.attributesID, *cmd.buffers, cmd.texture, cmd.primitiveType, cmd.cullMode);
|
||||
|
||||
VkAccessFlags dstAccessMask;
|
||||
VkPipelineStageFlags dstStageMask;
|
||||
if (!prepareBarrier(dstAccessMask, dstStageMask))
|
||||
return;
|
||||
|
||||
if (cmd.indirectBuffer != nullptr)
|
||||
{
|
||||
vkCmdDrawIndirect(
|
||||
@@ -972,6 +981,7 @@ void Graphics::draw(const DrawCommand &cmd)
|
||||
0);
|
||||
}
|
||||
|
||||
tryBarrier(dstAccessMask, dstStageMask);
|
||||
drawCalls++;
|
||||
}
|
||||
|
||||
@@ -979,6 +989,11 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
|
||||
{
|
||||
prepareDraw(cmd.attributesID, *cmd.buffers, cmd.texture, cmd.primitiveType, cmd.cullMode);
|
||||
|
||||
VkAccessFlags dstAccessMask;
|
||||
VkPipelineStageFlags dstStageMask;
|
||||
if (!prepareBarrier(dstAccessMask, dstStageMask))
|
||||
return;
|
||||
|
||||
vkCmdBindIndexBuffer(
|
||||
commandBuffers.at(currentFrame),
|
||||
(VkBuffer) cmd.indexBuffer->getHandle(),
|
||||
@@ -1005,6 +1020,7 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
|
||||
0);
|
||||
}
|
||||
|
||||
tryBarrier(dstAccessMask, dstStageMask);
|
||||
drawCalls++;
|
||||
}
|
||||
|
||||
@@ -1015,6 +1031,12 @@ void Graphics::drawQuads(int start, int count, VertexAttributesID attributesID,
|
||||
|
||||
prepareDraw(attributesID, buffers, texture, PRIMITIVE_TRIANGLES, CULL_NONE);
|
||||
|
||||
VkAccessFlags dstAccessMask;
|
||||
VkPipelineStageFlags dstStageMask;
|
||||
if (!prepareBarrier(dstAccessMask, dstStageMask))
|
||||
return;
|
||||
|
||||
|
||||
vkCmdBindIndexBuffer(
|
||||
commandBuffers.at(currentFrame),
|
||||
(VkBuffer)quadIndexBuffer->getHandle(),
|
||||
@@ -1036,6 +1058,7 @@ void Graphics::drawQuads(int start, int count, VertexAttributesID attributesID,
|
||||
0);
|
||||
baseVertex += quadcount * 4;
|
||||
|
||||
tryBarrier(dstAccessMask, dstStageMask);
|
||||
drawCalls++;
|
||||
}
|
||||
}
|
||||
@@ -1291,7 +1314,7 @@ graphics::StreamBuffer *Graphics::newStreamBuffer(BufferUsage type, size_t size)
|
||||
return new StreamBuffer(this, type, size);
|
||||
}
|
||||
|
||||
static bool computeDispatchBarrierFlags(Shader *shader, VkAccessFlags &dstAccessFlags, VkPipelineStageFlags &dstStageFlags)
|
||||
static bool shaderBarrierFlags(Shader *shader, VkAccessFlags &dstAccessFlags, VkPipelineStageFlags &dstStageFlags)
|
||||
{
|
||||
for (const auto &info : shader->getActiveTextureInfo())
|
||||
{
|
||||
@@ -1333,7 +1356,7 @@ bool Graphics::dispatch(love::graphics::Shader *shader, int x, int y, int z)
|
||||
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
||||
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
VkPipelineStageFlags dstStageMask = 0;
|
||||
if (!computeDispatchBarrierFlags(computeShader, barrier.dstAccessMask, dstStageMask))
|
||||
if (!shaderBarrierFlags(computeShader, barrier.dstAccessMask, dstStageMask))
|
||||
return false;
|
||||
|
||||
usedShadersInFrame.insert(computeShader);
|
||||
@@ -1362,7 +1385,7 @@ bool Graphics::dispatch(love::graphics::Shader *shader, love::graphics::Buffer *
|
||||
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
||||
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
VkPipelineStageFlags dstStageMask = 0;
|
||||
if (!computeDispatchBarrierFlags(computeShader, barrier.dstAccessMask, dstStageMask))
|
||||
if (!shaderBarrierFlags(computeShader, barrier.dstAccessMask, dstStageMask))
|
||||
return false;
|
||||
|
||||
usedShadersInFrame.insert(computeShader);
|
||||
@@ -2788,6 +2811,32 @@ void Graphics::prepareDraw(VertexAttributesID attributesID, const BufferBindings
|
||||
vkCmdBindVertexBuffers(commandBuffers.at(currentFrame), VERTEX_BUFFER_BINDING_START, buffercount, vkbuffers, vkoffsets);
|
||||
}
|
||||
|
||||
bool Graphics::prepareBarrier(VkAccessFlags &dstAccessMask, VkPipelineStageFlags &dstStageMask)
|
||||
{
|
||||
auto shader = dynamic_cast<Shader *>(Shader::current);
|
||||
if (!shader)
|
||||
return false;
|
||||
|
||||
if (!shaderBarrierFlags(shader, dstAccessMask, dstStageMask))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Graphics::tryBarrier(VkAccessFlags dstAccessMask, VkPipelineStageFlags dstStageMask)
|
||||
{
|
||||
if (dstAccessMask == 0 && dstStageMask == 0)
|
||||
return;
|
||||
|
||||
VkMemoryBarrier barrier{};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
||||
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
barrier.dstAccessMask = dstAccessMask;
|
||||
|
||||
if (barrier.dstAccessMask != 0 || dstStageMask != 0)
|
||||
vkCmdPipelineBarrier(commandBuffers.at(currentFrame), VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, dstStageMask, 0, 1, &barrier, 0, nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
void Graphics::setDefaultRenderPass()
|
||||
{
|
||||
uint32_t numClearValues = 2;
|
||||
|
||||
Reference in New Issue
Block a user