mirror of
https://github.com/love2d/love.git
synced 2026-08-12 00:20:52 +02:00
Don't draw if not all writable images and/or buffers are set.
This commit is contained in:
@@ -210,7 +210,7 @@ private:
|
||||
id<MTLDepthStencilState> getCachedDepthStencilState(const DepthState &depth, const StencilState &stencil);
|
||||
void applyRenderState(id<MTLRenderCommandEncoder> renderEncoder, VertexAttributesID attributesID);
|
||||
bool applyShaderUniforms(id<MTLComputeCommandEncoder> encoder, love::graphics::Shader *shader);
|
||||
void applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, love::graphics::Shader *shader, Texture *maintex);
|
||||
bool applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, love::graphics::Shader *shader, Texture *maintex);
|
||||
|
||||
id<MTLCommandQueue> commandQueue;
|
||||
|
||||
|
||||
@@ -1105,7 +1105,7 @@ bool Graphics::applyShaderUniforms(id<MTLComputeCommandEncoder> encoder, love::g
|
||||
return allWritableVariablesSet;
|
||||
}
|
||||
|
||||
void Graphics::applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, love::graphics::Shader *shader, love::graphics::Texture *maintex)
|
||||
bool Graphics::applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, love::graphics::Shader *shader, love::graphics::Texture *maintex)
|
||||
{
|
||||
Shader *s = (Shader *)shader;
|
||||
|
||||
@@ -1168,6 +1168,8 @@ void Graphics::applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, lo
|
||||
|
||||
uniformBufferOffset += alignUp(size, alignment);
|
||||
|
||||
bool allWritableVariablesSet = true;
|
||||
|
||||
for (const Shader::TextureBinding &b : s->getTextureBindings())
|
||||
{
|
||||
id<MTLTexture> texture = b.texture;
|
||||
@@ -1183,7 +1185,13 @@ void Graphics::applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, lo
|
||||
uint8 sampindex = b.samplerStages[SHADERSTAGE_VERTEX];
|
||||
|
||||
if (texindex != LOVE_UINT8_MAX)
|
||||
{
|
||||
setTexture(renderEncoder, bindings, SHADERSTAGE_VERTEX, texindex, texture);
|
||||
|
||||
if ((b.access & Shader::ACCESS_WRITE) != 0 && texture == nil)
|
||||
allWritableVariablesSet = false;
|
||||
}
|
||||
|
||||
if (sampindex != LOVE_UINT8_MAX)
|
||||
setSampler(renderEncoder, bindings, SHADERSTAGE_VERTEX, sampindex, samplertex);
|
||||
|
||||
@@ -1191,7 +1199,13 @@ void Graphics::applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, lo
|
||||
sampindex = b.samplerStages[SHADERSTAGE_PIXEL];
|
||||
|
||||
if (texindex != LOVE_UINT8_MAX)
|
||||
{
|
||||
setTexture(renderEncoder, bindings, SHADERSTAGE_PIXEL, texindex, texture);
|
||||
|
||||
if ((b.access & Shader::ACCESS_WRITE) != 0 && texture == nil)
|
||||
allWritableVariablesSet = false;
|
||||
}
|
||||
|
||||
if (sampindex != LOVE_UINT8_MAX)
|
||||
setSampler(renderEncoder, bindings, SHADERSTAGE_PIXEL, sampindex, samplertex);
|
||||
}
|
||||
@@ -1200,11 +1214,24 @@ void Graphics::applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, lo
|
||||
{
|
||||
uint8 index = b.stages[SHADERSTAGE_VERTEX];
|
||||
if (index != LOVE_UINT8_MAX)
|
||||
{
|
||||
setBuffer(renderEncoder, bindings, SHADERSTAGE_VERTEX, index, b.buffer, 0);
|
||||
|
||||
if ((b.access & Shader::ACCESS_WRITE) != 0 && b.buffer == nil)
|
||||
allWritableVariablesSet = false;
|
||||
}
|
||||
|
||||
index = b.stages[SHADERSTAGE_PIXEL];
|
||||
if (index != LOVE_UINT8_MAX)
|
||||
{
|
||||
setBuffer(renderEncoder, bindings, SHADERSTAGE_PIXEL, index, b.buffer, 0);
|
||||
|
||||
if ((b.access & Shader::ACCESS_WRITE) != 0 && b.buffer == nil)
|
||||
allWritableVariablesSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
return allWritableVariablesSet;
|
||||
}
|
||||
|
||||
static void setVertexBuffers(id<MTLRenderCommandEncoder> encoder, love::graphics::Shader *shader, const BufferBindings *buffers, Graphics::RenderEncoderBindings &bindings)
|
||||
@@ -1240,7 +1267,8 @@ void Graphics::draw(const DrawCommand &cmd)
|
||||
}
|
||||
|
||||
applyRenderState(encoder, cmd.attributesID);
|
||||
applyShaderUniforms(encoder, Shader::current, cmd.texture);
|
||||
if (!applyShaderUniforms(encoder, Shader::current, cmd.texture))
|
||||
return;
|
||||
|
||||
setVertexBuffers(encoder, Shader::current, cmd.buffers, renderBindings);
|
||||
|
||||
@@ -1272,7 +1300,8 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
|
||||
}
|
||||
|
||||
applyRenderState(encoder, cmd.attributesID);
|
||||
applyShaderUniforms(encoder, Shader::current, cmd.texture);
|
||||
if (!applyShaderUniforms(encoder, Shader::current, cmd.texture))
|
||||
return;
|
||||
|
||||
setVertexBuffers(encoder, Shader::current, cmd.buffers, renderBindings);
|
||||
|
||||
@@ -1337,7 +1366,8 @@ void Graphics::drawQuads(int start, int count, VertexAttributesID attributesID,
|
||||
}
|
||||
|
||||
applyRenderState(encoder, attributesID);
|
||||
applyShaderUniforms(encoder, Shader::current, texture);
|
||||
if (!applyShaderUniforms(encoder, Shader::current, texture))
|
||||
return;
|
||||
|
||||
id<MTLBuffer> ib = getMTLBuffer(quadIndexBuffer);
|
||||
|
||||
|
||||
@@ -562,7 +562,9 @@ void Graphics::draw(const DrawCommand &cmd)
|
||||
GLbitfield preDrawBarriers = 0;
|
||||
GLbitfield postDrawBarriers = 0;
|
||||
|
||||
shaderBarriers((Shader *)Shader::current, preDrawBarriers, postDrawBarriers);
|
||||
if (!shaderBarriers((Shader *)Shader::current, preDrawBarriers, postDrawBarriers))
|
||||
return;
|
||||
|
||||
if (preDrawBarriers != 0)
|
||||
glMemoryBarrier(preDrawBarriers);
|
||||
|
||||
@@ -597,7 +599,9 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
|
||||
GLbitfield preDrawBarriers = 0;
|
||||
GLbitfield postDrawBarriers = 0;
|
||||
|
||||
shaderBarriers((Shader *)Shader::current, preDrawBarriers, postDrawBarriers);
|
||||
if (!shaderBarriers((Shader *)Shader::current, preDrawBarriers, postDrawBarriers))
|
||||
return;
|
||||
|
||||
if (preDrawBarriers != 0)
|
||||
glMemoryBarrier(preDrawBarriers);
|
||||
|
||||
@@ -661,7 +665,8 @@ void Graphics::drawQuads(int start, int count, VertexAttributesID attributesID,
|
||||
GLbitfield preDrawBarriers = 0;
|
||||
GLbitfield postDrawBarriers = 0;
|
||||
|
||||
shaderBarriers((Shader *)Shader::current, preDrawBarriers, postDrawBarriers);
|
||||
if (!shaderBarriers((Shader *)Shader::current, preDrawBarriers, postDrawBarriers))
|
||||
return;
|
||||
|
||||
VertexAttributes attributes;
|
||||
findVertexAttributes(attributesID, attributes);
|
||||
|
||||
@@ -957,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(
|
||||
@@ -976,7 +981,7 @@ void Graphics::draw(const DrawCommand &cmd)
|
||||
0);
|
||||
}
|
||||
|
||||
endDraw();
|
||||
tryBarrier(dstAccessMask, dstStageMask);
|
||||
drawCalls++;
|
||||
}
|
||||
|
||||
@@ -984,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(),
|
||||
@@ -1010,7 +1020,7 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
|
||||
0);
|
||||
}
|
||||
|
||||
endDraw();
|
||||
tryBarrier(dstAccessMask, dstStageMask);
|
||||
drawCalls++;
|
||||
}
|
||||
|
||||
@@ -1021,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(),
|
||||
@@ -1042,7 +1058,7 @@ void Graphics::drawQuads(int start, int count, VertexAttributesID attributesID,
|
||||
0);
|
||||
baseVertex += quadcount * 4;
|
||||
|
||||
endDraw();
|
||||
tryBarrier(dstAccessMask, dstStageMask);
|
||||
drawCalls++;
|
||||
}
|
||||
}
|
||||
@@ -2785,18 +2801,27 @@ void Graphics::prepareDraw(VertexAttributesID attributesID, const BufferBindings
|
||||
vkCmdBindVertexBuffers(commandBuffers.at(currentFrame), VERTEX_BUFFER_BINDING_START, buffercount, vkbuffers, vkoffsets);
|
||||
}
|
||||
|
||||
void Graphics::endDraw()
|
||||
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;
|
||||
VkPipelineStageFlags dstStageMask = 0;
|
||||
if (!shaderBarrierFlags(shader, barrier.dstAccessMask, dstStageMask))
|
||||
return;
|
||||
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);
|
||||
|
||||
@@ -372,6 +372,8 @@ private:
|
||||
VertexAttributesID attributesID,
|
||||
const BufferBindings &buffers, graphics::Texture *texture,
|
||||
PrimitiveType, CullMode);
|
||||
bool prepareBarrier(VkAccessFlags &dstAccessMask, VkPipelineStageFlags &dstStageMask);
|
||||
void tryBarrier(VkAccessFlags dstAccessMask, VkPipelineStageFlags dstStageMask);
|
||||
void setRenderPass(const RenderTargets &rts, int pixelw, int pixelh);
|
||||
void setDefaultRenderPass();
|
||||
void startRenderPass();
|
||||
@@ -379,7 +381,6 @@ private:
|
||||
void applyScissor();
|
||||
VkSampler createSampler(const SamplerState &sampler);
|
||||
void requestSwapchainRecreation();
|
||||
void endDraw();
|
||||
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||
|
||||
Reference in New Issue
Block a user