Commit db4ed317 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: glClearBuffer* implementation

Refactors FramebufferVk::clear such that specific render targets could be cleared, with clear values not necessarily set through glClearColor etc. FramebufferVk::clearWithRenderPassOp is modified so that loadOp and clear values are set after the render pass has been registered in the graph. This allows multiple glClearBuffer calls to coalesce into the same render pass. glClearBuffer calls are then implemented simply as calls to the refactored clear function with the appropriate parameters. Bug: angleproject:3187 Change-Id: I2fdfcbea5bf244f63ec981b91caca47f5ee3cd3a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1545204 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 750935f4
......@@ -252,7 +252,7 @@
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/FullScreenQuad.vert.00000000.inc":
"287c50011ced97a7338b47a0a50127bf",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000000.inc":
"2d4b01d728c41ef1304ad3ef1305a1c7",
"94ccd6f202120a83e81202e5ce419fad",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000000.inc":
"aa438413134a29ec32ae4551a04e60b5",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000001.inc":
......@@ -296,7 +296,7 @@
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/FullScreenQuad.vert":
"1743adf55153edf91363fa7b4350d859",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/ImageClear.frag":
"98d490413d20118e92dd2b160c1dfc6e",
"037fb888e77491bf7ae746069ea89a55",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/shaders/src/ImageCopy.frag":
"9b9fd690321f53163221f1ebba9f006d",
"Vulkan internal shader programs:src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.cpp":
......
......@@ -101,6 +101,24 @@ class CommandGraphNode final : angle::NonCopyable
const AttachmentOpsArray &renderPassAttachmentOps,
const std::vector<VkClearValue> &clearValues);
void clearRenderPassColorAttachment(size_t attachmentIndex, const VkClearColorValue &clearValue)
{
mRenderPassAttachmentOps[attachmentIndex].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
mRenderPassClearValues[attachmentIndex].color = clearValue;
}
void clearRenderPassDepthAttachment(size_t attachmentIndex, float depth)
{
mRenderPassAttachmentOps[attachmentIndex].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
mRenderPassClearValues[attachmentIndex].depthStencil.depth = depth;
}
void clearRenderPassStencilAttachment(size_t attachmentIndex, uint32_t stencil)
{
mRenderPassAttachmentOps[attachmentIndex].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
mRenderPassClearValues[attachmentIndex].depthStencil.stencil = stencil;
}
// Dependency commands order node execution in the command graph.
// Once a node has commands that must happen after it, recording is stopped and the node is
// frozen forever.
......@@ -291,6 +309,32 @@ class CommandGraphResource : angle::NonCopyable
}
}
// Returns true if the render pass is started, but there are no commands yet recorded in it.
// This is useful to know if the render pass ops can be modified.
bool renderPassStartedButEmpty() const
{
return hasStartedRenderPass() &&
mCurrentWritingNode->getInsideRenderPassCommands()->empty();
}
void clearRenderPassColorAttachment(size_t attachmentIndex, const VkClearColorValue &clearValue)
{
ASSERT(renderPassStartedButEmpty());
mCurrentWritingNode->clearRenderPassColorAttachment(attachmentIndex, clearValue);
}
void clearRenderPassDepthAttachment(size_t attachmentIndex, float depth)
{
ASSERT(renderPassStartedButEmpty());
mCurrentWritingNode->clearRenderPassDepthAttachment(attachmentIndex, depth);
}
void clearRenderPassStencilAttachment(size_t attachmentIndex, uint32_t stencil)
{
ASSERT(renderPassStartedButEmpty());
mCurrentWritingNode->clearRenderPassStencilAttachment(attachmentIndex, stencil);
}
// Accessor for RenderPass RenderArea.
const gl::Rectangle &getRenderPassRenderArea() const;
......
......@@ -31,7 +31,15 @@ namespace rx
namespace
{
// The value to assign an alpha channel that's emulated. The type is unsigned int, though it will
// automatically convert to the actual data type.
constexpr unsigned int kEmulatedAlphaValue = 1;
constexpr size_t kMinReadPixelsBufferSize = 128000;
// Clear values are only used when loadOp=Clear is set in clearWithRenderPassOp. When starting a
// new render pass, the clear value is set to an unlikely value (bright pink) to stand out better
// in case of a bug.
constexpr VkClearValue kUninitializedClearValue = {{{0.95, 0.05, 0.95, 0.95}}};
const gl::InternalFormat &GetReadAttachmentInfo(const gl::Context *context,
RenderTargetVk *renderTarget)
......@@ -95,6 +103,25 @@ const angle::Format &GetDepthStencilImageToBufferFormat(const angle::Format &ima
return imageFormat;
}
}
void SetEmulatedAlphaValue(const vk::Format &format, VkClearColorValue *value)
{
if (format.vkFormatIsInt)
{
if (format.vkFormatIsUnsigned)
{
value->uint32[3] = kEmulatedAlphaValue;
}
else
{
value->int32[3] = kEmulatedAlphaValue;
}
}
else
{
value->float32[3] = kEmulatedAlphaValue;
}
}
} // anonymous namespace
// static
......@@ -165,35 +192,76 @@ angle::Result FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
{
ContextVk *contextVk = vk::GetImpl(context);
bool clearColor = IsMaskFlagSet(mask, static_cast<GLbitfield>(GL_COLOR_BUFFER_BIT));
bool clearDepth = IsMaskFlagSet(mask, static_cast<GLbitfield>(GL_DEPTH_BUFFER_BIT));
bool clearStencil = IsMaskFlagSet(mask, static_cast<GLbitfield>(GL_STENCIL_BUFFER_BIT));
gl::DrawBufferMask clearColorBuffers;
if (clearColor)
{
clearColorBuffers = mState.getEnabledDrawBuffers();
}
const VkClearColorValue &clearColorValue = contextVk->getClearColorValue().color;
const VkClearDepthStencilValue &clearDepthStencilValue =
contextVk->getClearDepthStencilValue().depthStencil;
return clearImpl(context, clearColorBuffers, clearDepth, clearStencil, clearColorValue,
clearDepthStencilValue);
}
angle::Result FramebufferVk::clearImpl(const gl::Context *context,
gl::DrawBufferMask clearColorBuffers,
bool clearDepth,
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue)
{
ContextVk *contextVk = vk::GetImpl(context);
const gl::State &glState = context->getState();
const gl::Rectangle &scissor = glState.getScissor();
const gl::Rectangle renderArea(0, 0, mState.getDimensions().width,
mState.getDimensions().height);
gl::Rectangle scissorRenderAreaIntersection;
// Discard clear altogether if scissor has 0 width or height.
if (glState.isScissorTestEnabled() &&
!gl::ClipRectangle(scissor, renderArea, &scissorRenderAreaIntersection))
{
return angle::Result::Continue;
}
mFramebuffer.updateQueueSerial(contextVk->getRenderer()->getCurrentQueueSerial());
// This function assumes that only enabled attachments are asked to be cleared.
ASSERT((clearColorBuffers & mState.getEnabledDrawBuffers()) == clearColorBuffers);
bool clearColor = clearColorBuffers.any();
// This command buffer is only started once.
vk::CommandBuffer *commandBuffer = nullptr;
const gl::FramebufferAttachment *depthAttachment = mState.getDepthAttachment();
bool clearDepth = (depthAttachment && (mask & GL_DEPTH_BUFFER_BIT) != 0);
clearDepth = clearDepth && depthAttachment;
ASSERT(!clearDepth || depthAttachment->isAttached());
// If depth write is disabled, pretend that GL_DEPTH_BUFFER_BIT is not specified altogether.
// If depth write is disabled, pretend that depth clear is not requested altogether.
clearDepth = clearDepth && contextVk->getState().getDepthStencilState().depthMask;
const gl::FramebufferAttachment *stencilAttachment = mState.getStencilAttachment();
bool clearStencil = (stencilAttachment && (mask & GL_STENCIL_BUFFER_BIT) != 0);
clearStencil = clearStencil && stencilAttachment;
ASSERT(!clearStencil || stencilAttachment->isAttached());
bool clearColor = IsMaskFlagSet(static_cast<int>(mask), GL_COLOR_BUFFER_BIT);
// If the only thing to be cleared was depth and it's masked, there's nothing to do.
if (!clearColor && !clearDepth && !clearStencil)
{
return angle::Result::Continue;
}
const gl::State &glState = context->getState();
VkClearDepthStencilValue clearDepthStencilValue =
contextVk->getClearDepthStencilValue().depthStencil;
VkClearDepthStencilValue modifiedDepthStencilValue = clearDepthStencilValue;
// Apply the stencil mask to the clear value.
clearDepthStencilValue.stencil &= contextVk->getState().getDepthStencilState().stencilWritemask;
// TODO(syoussefi): this logic is flawed. See http://anglebug.com/3241#c9.
modifiedDepthStencilValue.stencil &=
contextVk->getState().getDepthStencilState().stencilWritemask;
// If the depth or stencil is being cleared, and the image was originally requested to have a
// single aspect, but it's emulated with a depth/stencil format, clear both aspects, setting the
......@@ -207,23 +275,20 @@ angle::Result FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
if (format.angleFormat().stencilBits == 0)
{
clearStencil = true;
clearDepthStencilValue.stencil = 0;
modifiedDepthStencilValue.stencil = 0;
}
// GL_STENCIL_INDEX8 may or may not be emulated.
else if (format.angleFormat().depthBits == 0 && format.vkTextureFormat != VK_FORMAT_S8_UINT)
{
clearDepth = true;
clearDepthStencilValue.depth = 0;
modifiedDepthStencilValue.depth = 0;
}
}
// If scissor is enabled, but covers the whole of framebuffer, it can be considered disabled for
// the sake of clear.
const gl::Rectangle &scissorRect = glState.getScissor();
const gl::Rectangle renderArea(0, 0, mState.getDimensions().width,
mState.getDimensions().height);
bool isScissorTestEffectivelyEnabled =
glState.isScissorTestEnabled() && scissorRect != renderArea;
glState.isScissorTestEnabled() && scissorRenderAreaIntersection != renderArea;
// We can use render pass load ops if clearing depth/stencil or unmasked color. If there's a
// depth mask, depth clearing is disabled. If there's a stencil mask, the clear value is
......@@ -233,16 +298,26 @@ angle::Result FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
bool maskedClearColor =
clearColor && (mActiveColorComponents & colorMaskFlags) != mActiveColorComponents;
bool clearColorWithRenderPassLoadOp = clearColor && !maskedClearColor;
// At least one of color, depth or stencil should be clearable with render pass loadOp for us
// to use this clear path.
bool clearAnyWithRenderPassLoadOp =
clearColorWithRenderPassLoadOp || clearDepth || clearStencil;
if (clearAnyWithRenderPassLoadOp && !isScissorTestEffectivelyEnabled &&
!contextVk->getRenderer()->getFeatures().disableClearWithRenderPassLoadOp)
{
// Clearing color is indicated by the set bits in this mask. If not clearing colors with
// render pass loadOp, the default value of all-zeros means the clear is not done in
// clearWithRenderPassOp below.
gl::DrawBufferMask clearBuffersWithRenderPassLoadOp;
if (clearColorWithRenderPassLoadOp)
{
clearBuffersWithRenderPassLoadOp = clearColorBuffers;
}
// If there's a color mask, only clear depth/stencil with render pass loadOp.
ANGLE_TRY(clearWithRenderPassOp(contextVk, clearColorWithRenderPassLoadOp, clearDepth,
clearStencil, contextVk->getClearColorValue().color,
clearDepthStencilValue));
ANGLE_TRY(clearWithRenderPassOp(contextVk, clearBuffersWithRenderPassLoadOp, clearDepth,
clearStencil, clearColorValue, modifiedDepthStencilValue));
// Fallback to other methods for whatever isn't cleared here.
clearDepth = false;
......@@ -263,7 +338,7 @@ angle::Result FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
// this method. Similarly for depth/stencil clear.
if (maskedClearColor)
{
ANGLE_TRY(clearWithDraw(contextVk, colorMaskFlags));
ANGLE_TRY(clearWithDraw(contextVk, clearColorBuffers, clearColorValue, colorMaskFlags));
// Stencil clears must be handled separately. The only way to write out a stencil value from
// a fragment shader in Vulkan is with VK_EXT_shader_stencil_export. Support for this
......@@ -273,8 +348,9 @@ angle::Result FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
if (clearDepth || clearStencil)
{
ANGLE_TRY(clearWithClearAttachments(contextVk, false, clearDepth, clearStencil,
clearDepthStencilValue));
ANGLE_TRY(clearWithClearAttachments(contextVk, gl::DrawBufferMask(), clearDepth,
clearStencil, clearColorValue,
modifiedDepthStencilValue));
}
return angle::Result::Continue;
}
......@@ -284,8 +360,8 @@ angle::Result FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
// With scissor test enabled, we clear very differently and we don't need to access
// the image inside each attachment we can just use clearCmdAttachments with our
// scissor region instead.
ANGLE_TRY(clearWithClearAttachments(contextVk, clearColor, clearDepth, clearStencil,
clearDepthStencilValue));
ANGLE_TRY(clearWithClearAttachments(contextVk, clearColorBuffers, clearDepth, clearStencil,
clearColorValue, modifiedDepthStencilValue));
return angle::Result::Continue;
}
......@@ -312,7 +388,8 @@ angle::Result FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
}
vk::ImageHelper *image = renderTarget->getImageForWrite(&mFramebuffer);
image->clearDepthStencil(aspectFlags, clearAspects, clearDepthStencilValue, commandBuffer);
image->clearDepthStencil(aspectFlags, clearAspects, modifiedDepthStencilValue,
commandBuffer);
}
if (!clearColor)
......@@ -320,9 +397,6 @@ angle::Result FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
return angle::Result::Continue;
}
const auto *attachment = mState.getFirstNonNullAttachment();
ASSERT(attachment && attachment->isAttached());
if (!commandBuffer)
{
ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
......@@ -330,8 +404,7 @@ angle::Result FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
// TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
const auto &colorRenderTargets = mRenderTargetCache.getColors();
const VkClearColorValue &clearColorValue = contextVk->getClearColorValue().color;
for (size_t colorIndex : mState.getEnabledDrawBuffers())
for (size_t colorIndex : clearColorBuffers)
{
VkClearColorValue modifiedClearColorValue = clearColorValue;
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
......@@ -341,7 +414,7 @@ angle::Result FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
// clear value is in that case.
if (mEmulatedAlphaAttachmentMask[colorIndex])
{
modifiedClearColorValue.float32[3] = 1.0;
SetEmulatedAlphaValue(colorRenderTarget->getImageFormat(), &modifiedClearColorValue);
}
ASSERT(colorRenderTarget);
......@@ -360,8 +433,27 @@ angle::Result FramebufferVk::clearBufferfv(const gl::Context *context,
GLint drawbuffer,
const GLfloat *values)
{
ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
return angle::Result::Stop;
VkClearValue clearValue;
bool clearDepth = false;
gl::DrawBufferMask clearColorBuffers;
if (buffer == GL_DEPTH)
{
clearDepth = true;
clearValue.depthStencil.depth = values[0];
}
else
{
clearColorBuffers.set(drawbuffer);
clearValue.color.float32[0] = values[0];
clearValue.color.float32[1] = values[1];
clearValue.color.float32[2] = values[2];
clearValue.color.float32[3] = values[3];
}
return clearImpl(context, clearColorBuffers, clearDepth, false, clearValue.color,
clearValue.depthStencil);
}
angle::Result FramebufferVk::clearBufferuiv(const gl::Context *context,
......@@ -369,8 +461,18 @@ angle::Result FramebufferVk::clearBufferuiv(const gl::Context *context,
GLint drawbuffer,
const GLuint *values)
{
ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
return angle::Result::Stop;
VkClearValue clearValue;
gl::DrawBufferMask clearColorBuffers;
clearColorBuffers.set(drawbuffer);
clearValue.color.uint32[0] = values[0];
clearValue.color.uint32[1] = values[1];
clearValue.color.uint32[2] = values[2];
clearValue.color.uint32[3] = values[3];
return clearImpl(context, clearColorBuffers, false, false, clearValue.color,
clearValue.depthStencil);
}
angle::Result FramebufferVk::clearBufferiv(const gl::Context *context,
......@@ -378,8 +480,28 @@ angle::Result FramebufferVk::clearBufferiv(const gl::Context *context,
GLint drawbuffer,
const GLint *values)
{
ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
return angle::Result::Stop;
VkClearValue clearValue;
bool clearStencil = false;
gl::DrawBufferMask clearColorBuffers;
if (buffer == GL_STENCIL)
{
clearStencil = true;
clearValue.depthStencil.stencil =
gl::clamp(values[0], 0, std::numeric_limits<uint8_t>::max());
}
else
{
clearColorBuffers.set(drawbuffer);
clearValue.color.int32[0] = values[0];
clearValue.color.int32[1] = values[1];
clearValue.color.int32[2] = values[2];
clearValue.color.int32[3] = values[3];
}
return clearImpl(context, clearColorBuffers, false, clearStencil, clearValue.color,
clearValue.depthStencil);
}
angle::Result FramebufferVk::clearBufferfi(const gl::Context *context,
......@@ -388,8 +510,13 @@ angle::Result FramebufferVk::clearBufferfi(const gl::Context *context,
GLfloat depth,
GLint stencil)
{
ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
return angle::Result::Stop;
VkClearValue clearValue;
clearValue.depthStencil.depth = depth;
clearValue.depthStencil.stencil = gl::clamp(stencil, 0, std::numeric_limits<uint8_t>::max());
return clearImpl(context, gl::DrawBufferMask(), true, true, clearValue.color,
clearValue.depthStencil);
}
GLenum FramebufferVk::getImplementationColorReadFormat(const gl::Context *context) const
......@@ -942,22 +1069,69 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe
angle::Result FramebufferVk::clearWithRenderPassOp(
ContextVk *contextVk,
bool clearColor,
gl::DrawBufferMask clearColorBuffers,
bool clearDepth,
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue)
{
// If render pass hasn't started, start it. If it's started and contains commands, we cannot
// modify its ops, so start a new render pass.
if (!mFramebuffer.valid() || !mFramebuffer.renderPassStartedButEmpty())
{
vk::CommandBuffer *commandBuffer;
return startNewRenderPassImpl(contextVk, clearColor, clearDepth, clearStencil, clearColorValue,
clearDepthStencilValue, &commandBuffer);
ANGLE_TRY(startNewRenderPass(contextVk, &commandBuffer));
}
size_t attachmentIndex = 0;
// Go through clearColorBuffers and set the appropriate loadOp and clear values.
// TODO: Support gaps in RenderTargets. http://anglebug.com/2394
for (size_t colorIndex : mState.getEnabledDrawBuffers())
{
if (clearColorBuffers.test(colorIndex))
{
RenderTargetVk *renderTarget = getColorReadRenderTarget();
// If the render target doesn't have alpha, but its emulated format has it, clear the
// alpha to 1.
VkClearColorValue value = clearColorValue;
if (mEmulatedAlphaAttachmentMask[colorIndex])
{
SetEmulatedAlphaValue(renderTarget->getImageFormat(), &value);
}
mFramebuffer.clearRenderPassColorAttachment(attachmentIndex, value);
}
++attachmentIndex;
}
// Set the appropriate loadOp and clear values for depth and stencil.
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget)
{
if (clearDepth)
{
mFramebuffer.clearRenderPassDepthAttachment(attachmentIndex,
clearDepthStencilValue.depth);
}
if (clearStencil)
{
mFramebuffer.clearRenderPassStencilAttachment(attachmentIndex,
clearDepthStencilValue.stencil);
}
}
return angle::Result::Continue;
}
angle::Result FramebufferVk::clearWithClearAttachments(
ContextVk *contextVk,
bool clearColor,
gl::DrawBufferMask clearColorBuffers,
bool clearDepth,
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue)
{
// Trigger a new command node to ensure overlapping writes happen sequentially.
......@@ -995,21 +1169,21 @@ angle::Result FramebufferVk::clearWithClearAttachments(
gl::AttachmentArray<VkClearAttachment> clearAttachments;
int clearAttachmentIndex = 0;
if (clearColor)
if (clearColorBuffers.any())
{
RenderTargetVk *renderTarget = getColorReadRenderTarget();
const vk::Format &format = renderTarget->getImageFormat();
VkClearValue modifiedClear = contextVk->getClearColorValue();
VkClearValue modifiedClear = {clearColorValue};
// We need to make sure we are not clearing the alpha channel if we are using a buffer
// format that doesn't have an alpha channel.
if (format.angleFormat().alphaBits == 0)
{
modifiedClear.color.float32[3] = 1.0;
SetEmulatedAlphaValue(format, &modifiedClear.color);
}
// TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
for (size_t colorIndex : mState.getEnabledDrawBuffers())
for (size_t colorIndex : clearColorBuffers)
{
VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
clearAttachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
......@@ -1059,29 +1233,20 @@ angle::Result FramebufferVk::clearWithClearAttachments(
}
angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
gl::DrawBufferMask clearColorBuffers,
const VkClearColorValue &clearColorValue,
VkColorComponentFlags colorMaskFlags)
{
RendererVk *renderer = contextVk->getRenderer();
// If the format of the framebuffer does not have an alpha channel, we need to make sure we do
// not affect the alpha channel of the type we're using to emulate the format.
// TODO(jmadill): Implement EXT_draw_buffers http://anglebug.com/2394
RenderTargetVk *renderTarget = mRenderTargetCache.getColors()[0];
ASSERT(renderTarget);
UtilsVk::ClearImageParameters params = {};
params.colorMaskFlags = colorMaskFlags;
params.renderAreaHeight = mState.getDimensions().height;
params.clearValue = clearColorValue;
params.alphaMask = &getEmulatedAlphaAttachmentMask();
params.clearBufferMask = &clearColorBuffers;
params.renderPassDesc = &getRenderPassDesc();
const vk::Format &imageFormat = renderTarget->getImageFormat();
params.clearValue = contextVk->getClearColorValue().color;
bool overrideAlphaWithOne =
imageFormat.textureFormat().alphaBits > 0 && imageFormat.angleFormat().alphaBits == 0;
params.clearValue.float32[3] = overrideAlphaWithOne ? 1.0f : params.clearValue.float32[3];
params.renderAreaHeight = mState.getDimensions().height;
return renderer->getUtils().clearImage(contextVk, this, params);
}
......@@ -1112,22 +1277,6 @@ angle::Result FramebufferVk::getCommandBufferForDraw(ContextVk *contextVk,
angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
vk::CommandBuffer **commandBufferOut)
{
VkClearColorValue unusedColor = {};
VkClearDepthStencilValue unusedDepthStencil = {};
return startNewRenderPassImpl(contextVk, false, false, false, unusedColor, unusedDepthStencil,
commandBufferOut);
}
angle::Result FramebufferVk::startNewRenderPassImpl(
ContextVk *contextVk,
bool clearColor,
bool clearDepth,
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue,
vk::CommandBuffer **commandBufferOut)
{
vk::Framebuffer *framebuffer = nullptr;
ANGLE_TRY(getFramebuffer(contextVk, &framebuffer));
......@@ -1137,9 +1286,6 @@ angle::Result FramebufferVk::startNewRenderPassImpl(
vk::CommandBuffer *writeCommands = nullptr;
ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &writeCommands));
VkClearValue clearValue;
clearValue.color = clearColorValue;
vk::RenderPassDesc renderPassDesc;
// Initialize RenderPass info.
......@@ -1153,27 +1299,10 @@ angle::Result FramebufferVk::startNewRenderPassImpl(
ANGLE_TRY(colorRenderTarget->onColorDraw(contextVk, &mFramebuffer, writeCommands,
&renderPassDesc));
VkAttachmentLoadOp colorLoadOp =
clearColor ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
renderPassAttachmentOps.setLayout(attachmentClearValues.size(),
renderPassAttachmentOps.initWithLoadStore(attachmentClearValues.size(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
renderPassAttachmentOps.setLoadOp(attachmentClearValues.size(), colorLoadOp,
VK_ATTACHMENT_LOAD_OP_DONT_CARE);
renderPassAttachmentOps.setStoreOp(attachmentClearValues.size(),
VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_STORE_OP_DONT_CARE);
// If the render target doesn't have alpha, but its emulated format has it, clear the alpha
// to 1.
VkClearValue value = clearValue;
if (mEmulatedAlphaAttachmentMask[colorIndex])
{
value.color.float32[3] = 1.0;
}
attachmentClearValues.emplace_back(value);
attachmentClearValues.emplace_back(kUninitializedClearValue);
}
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
......@@ -1182,21 +1311,10 @@ angle::Result FramebufferVk::startNewRenderPassImpl(
ANGLE_TRY(depthStencilRenderTarget->onDepthStencilDraw(contextVk, &mFramebuffer,
writeCommands, &renderPassDesc));
VkAttachmentLoadOp depthLoadOp =
clearDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
VkAttachmentLoadOp stencilLoadOp =
clearStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
renderPassAttachmentOps.setLayout(attachmentClearValues.size(),
renderPassAttachmentOps.initWithLoadStore(attachmentClearValues.size(),
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
renderPassAttachmentOps.setLoadOp(attachmentClearValues.size(), depthLoadOp, stencilLoadOp);
renderPassAttachmentOps.setStoreOp(attachmentClearValues.size(),
VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_STORE_OP_STORE);
clearValue.depthStencil = clearDepthStencilValue;
attachmentClearValues.emplace_back(clearValue);
attachmentClearValues.emplace_back(kUninitializedClearValue);
}
gl::Rectangle renderArea =
......
......@@ -125,14 +125,6 @@ class FramebufferVk : public FramebufferImpl
const gl::FramebufferState &state,
WindowSurfaceVk *backbuffer);
angle::Result startNewRenderPassImpl(ContextVk *context,
bool clearColor,
bool clearDepth,
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue,
vk::CommandBuffer **commandBufferOut);
// Helper for appendToStarted/else startNewRenderPass.
angle::Result getCommandBufferForDraw(ContextVk *contextVk,
vk::CommandBuffer **commandBufferOut,
......@@ -167,18 +159,28 @@ class FramebufferVk : public FramebufferImpl
angle::Result getFramebuffer(ContextVk *contextVk, vk::Framebuffer **framebufferOut);
angle::Result clearImpl(const gl::Context *context,
gl::DrawBufferMask clearColorBuffers,
bool clearDepth,
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue);
angle::Result clearWithRenderPassOp(ContextVk *contextVk,
bool clearColor,
gl::DrawBufferMask clearColorBuffers,
bool clearDepth,
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue);
angle::Result clearWithClearAttachments(ContextVk *contextVk,
bool clearColor,
gl::DrawBufferMask clearColorBuffers,
bool clearDepth,
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue);
angle::Result clearWithDraw(ContextVk *contextVk, VkColorComponentFlags colorMaskFlags);
angle::Result clearWithDraw(ContextVk *contextVk,
gl::DrawBufferMask clearColorBuffers,
const VkClearColorValue &clearColorValue,
VkColorComponentFlags colorMaskFlags);
void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a);
void updateRenderPassDesc();
......
......@@ -489,6 +489,8 @@ class SecondaryCommandBuffer final : angle::NonCopyable
// The SecondaryCommandBuffer is valid if it's been initialized
bool valid() const { return mAllocator != nullptr; }
bool empty() const { return mCommands.size() == 0 || mCommands[0]->id == CommandID::Invalid; }
private:
template <class StructType>
ANGLE_INLINE StructType *commonInit(CommandID cmdID, size_t allocationSize)
......
......@@ -603,12 +603,8 @@ angle::Result UtilsVk::startRenderPass(ContextVk *contextVk,
std::vector<VkClearValue> clearValues = {{}};
ASSERT(clearValues.size() == 1);
renderPassAttachmentOps.setLayout(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
renderPassAttachmentOps.initWithLoadStore(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
renderPassAttachmentOps.setLoadOp(0, VK_ATTACHMENT_LOAD_OP_LOAD,
VK_ATTACHMENT_LOAD_OP_DONT_CARE);
renderPassAttachmentOps.setStoreOp(0, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_STORE_OP_DONT_CARE);
ANGLE_TRY(image->beginRenderPass(contextVk, framebuffer, renderArea, renderPassDesc,
renderPassAttachmentOps, clearValues, commandBufferOut));
......@@ -635,6 +631,27 @@ angle::Result UtilsVk::clearImage(ContextVk *contextVk,
ImageClearShaderParams shaderParams;
shaderParams.clearValue = params.clearValue;
// TODO(syoussefi): Currently, this only supports float clears. Having the shader as-is support
// a mixture of types results in a large number of shader variations. The solution would be to
// clear the render targets one by one. However, we don't want to recreate the render pass for
// each one, so the shader should be able to select the render target to clear. The variations
// of the shader could look like:
//
// "RenderTarget": [
// "RT0",
// "RT1",
// ...
// "RT7",
// ],
// "Format": [
// "IsFloat",
// "IsInt",
// "IsUint"
// ]
//
// http://anglebug.com/3187
shaderParams.clearBufferMask = static_cast<uint32_t>(params.clearBufferMask->bits());
vk::GraphicsPipelineDesc pipelineDesc;
pipelineDesc.initDefaults();
pipelineDesc.setColorWriteMask(params.colorMaskFlags, *params.alphaMask);
......@@ -650,11 +667,6 @@ angle::Result UtilsVk::clearImage(ContextVk *contextVk,
VkRect2D scissor;
const gl::State &glState = contextVk->getState();
gl_vk::GetScissor(glState, invertViewport, renderArea, &scissor);
// TODO(courtneygo): workaround for scissor issue on some devices. http://anglebug.com/3114
if ((scissor.extent.width == 0) || (scissor.extent.height == 0))
{
return angle::Result::Continue;
}
pipelineDesc.setScissor(scissor);
vk::ShaderLibrary &shaderLibrary = renderer->getShaderLibrary();
......
......@@ -65,6 +65,7 @@ class UtilsVk : angle::NonCopyable
VkColorComponentFlags colorMaskFlags;
GLint renderAreaHeight;
const gl::DrawBufferMask *alphaMask;
const gl::DrawBufferMask *clearBufferMask;
const vk::RenderPassDesc *renderPassDesc;
};
......@@ -142,6 +143,7 @@ class UtilsVk : angle::NonCopyable
{
// Structure matching PushConstants in ImageClear.frag
VkClearColorValue clearValue = {};
uint32_t clearBufferMask = 0;
};
struct ImageCopyShaderParams
......
// 7.11.3170
#pragma once
const uint32_t kImageClear_frag_00000000[] = {
0x07230203,0x00010000,0x00080007,0x00000012,0x00000000,0x00020011,0x00000001,0x0006000b,
0x07230203,0x00010000,0x00080007,0x00000061,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
0x0006000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x00030010,0x00000004,
0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,0x00000000,
0x00050005,0x00000009,0x6f6c6f63,0x74754f72,0x00000000,0x00060005,0x0000000a,0x68737550,
0x736e6f43,0x746e6174,0x00000073,0x00060006,0x0000000a,0x00000000,0x61656c63,0x6c6f4372,
0x0000726f,0x00040005,0x0000000c,0x61726170,0x0000736d,0x00040047,0x00000009,0x0000001e,
0x00000000,0x00050048,0x0000000a,0x00000000,0x00000023,0x00000000,0x00030047,0x0000000a,
0x00000002,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,
0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008,0x00000003,
0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003,0x0003001e,0x0000000a,0x00000007,
0x00040020,0x0000000b,0x00000009,0x0000000a,0x0004003b,0x0000000b,0x0000000c,0x00000009,
0x00040015,0x0000000d,0x00000020,0x00000001,0x0004002b,0x0000000d,0x0000000e,0x00000000,
0x00040020,0x0000000f,0x00000009,0x00000007,0x00050036,0x00000002,0x00000004,0x00000000,
0x00000003,0x000200f8,0x00000005,0x00050041,0x0000000f,0x00000010,0x0000000c,0x0000000e,
0x0004003d,0x00000007,0x00000011,0x00000010,0x0003003e,0x00000009,0x00000011,0x000100fd,
0x00010038
0x000d000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000017,0x00000022,0x0000002c,
0x00000036,0x00000040,0x0000004a,0x00000054,0x0000005e,0x00030010,0x00000004,0x00000007,
0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00060005,
0x00000009,0x68737550,0x736e6f43,0x746e6174,0x00000073,0x00060006,0x00000009,0x00000000,
0x61656c63,0x6c6f4372,0x0000726f,0x00070006,0x00000009,0x00000001,0x61656c63,0x66754272,
0x4d726566,0x006b7361,0x00040005,0x0000000b,0x61726170,0x0000736d,0x00050005,0x00000017,
0x6f6c6f63,0x74754f72,0x00000030,0x00050005,0x00000022,0x6f6c6f63,0x74754f72,0x00000031,
0x00050005,0x0000002c,0x6f6c6f63,0x74754f72,0x00000032,0x00050005,0x00000036,0x6f6c6f63,
0x74754f72,0x00000033,0x00050005,0x00000040,0x6f6c6f63,0x74754f72,0x00000034,0x00050005,
0x0000004a,0x6f6c6f63,0x74754f72,0x00000035,0x00050005,0x00000054,0x6f6c6f63,0x74754f72,
0x00000036,0x00050005,0x0000005e,0x6f6c6f63,0x74754f72,0x00000037,0x00050048,0x00000009,
0x00000000,0x00000023,0x00000000,0x00050048,0x00000009,0x00000001,0x00000023,0x00000010,
0x00030047,0x00000009,0x00000002,0x00040047,0x00000017,0x0000001e,0x00000000,0x00040047,
0x00000022,0x0000001e,0x00000001,0x00040047,0x0000002c,0x0000001e,0x00000002,0x00040047,
0x00000036,0x0000001e,0x00000003,0x00040047,0x00000040,0x0000001e,0x00000004,0x00040047,
0x0000004a,0x0000001e,0x00000005,0x00040047,0x00000054,0x0000001e,0x00000006,0x00040047,
0x0000005e,0x0000001e,0x00000007,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,
0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040015,
0x00000008,0x00000020,0x00000001,0x0004001e,0x00000009,0x00000007,0x00000008,0x00040020,
0x0000000a,0x00000009,0x00000009,0x0004003b,0x0000000a,0x0000000b,0x00000009,0x0004002b,
0x00000008,0x0000000c,0x00000001,0x00040020,0x0000000d,0x00000009,0x00000008,0x0004002b,
0x00000008,0x00000011,0x00000000,0x00020014,0x00000012,0x00040020,0x00000016,0x00000003,
0x00000007,0x0004003b,0x00000016,0x00000017,0x00000003,0x00040020,0x00000018,0x00000009,
0x00000007,0x0004002b,0x00000008,0x0000001d,0x00000002,0x0004003b,0x00000016,0x00000022,
0x00000003,0x0004002b,0x00000008,0x00000027,0x00000004,0x0004003b,0x00000016,0x0000002c,
0x00000003,0x0004002b,0x00000008,0x00000031,0x00000008,0x0004003b,0x00000016,0x00000036,
0x00000003,0x0004002b,0x00000008,0x0000003b,0x00000010,0x0004003b,0x00000016,0x00000040,
0x00000003,0x0004002b,0x00000008,0x00000045,0x00000020,0x0004003b,0x00000016,0x0000004a,
0x00000003,0x0004002b,0x00000008,0x0000004f,0x00000040,0x0004003b,0x00000016,0x00000054,
0x00000003,0x0004002b,0x00000008,0x00000059,0x00000080,0x0004003b,0x00000016,0x0000005e,
0x00000003,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,
0x00050041,0x0000000d,0x0000000e,0x0000000b,0x0000000c,0x0004003d,0x00000008,0x0000000f,
0x0000000e,0x000500c7,0x00000008,0x00000010,0x0000000f,0x0000000c,0x000500ab,0x00000012,
0x00000013,0x00000010,0x00000011,0x000300f7,0x00000015,0x00000000,0x000400fa,0x00000013,
0x00000014,0x00000015,0x000200f8,0x00000014,0x00050041,0x00000018,0x00000019,0x0000000b,
0x00000011,0x0004003d,0x00000007,0x0000001a,0x00000019,0x0003003e,0x00000017,0x0000001a,
0x000200f9,0x00000015,0x000200f8,0x00000015,0x00050041,0x0000000d,0x0000001b,0x0000000b,
0x0000000c,0x0004003d,0x00000008,0x0000001c,0x0000001b,0x000500c7,0x00000008,0x0000001e,
0x0000001c,0x0000001d,0x000500ab,0x00000012,0x0000001f,0x0000001e,0x00000011,0x000300f7,
0x00000021,0x00000000,0x000400fa,0x0000001f,0x00000020,0x00000021,0x000200f8,0x00000020,
0x00050041,0x00000018,0x00000023,0x0000000b,0x00000011,0x0004003d,0x00000007,0x00000024,
0x00000023,0x0003003e,0x00000022,0x00000024,0x000200f9,0x00000021,0x000200f8,0x00000021,
0x00050041,0x0000000d,0x00000025,0x0000000b,0x0000000c,0x0004003d,0x00000008,0x00000026,
0x00000025,0x000500c7,0x00000008,0x00000028,0x00000026,0x00000027,0x000500ab,0x00000012,
0x00000029,0x00000028,0x00000011,0x000300f7,0x0000002b,0x00000000,0x000400fa,0x00000029,
0x0000002a,0x0000002b,0x000200f8,0x0000002a,0x00050041,0x00000018,0x0000002d,0x0000000b,
0x00000011,0x0004003d,0x00000007,0x0000002e,0x0000002d,0x0003003e,0x0000002c,0x0000002e,
0x000200f9,0x0000002b,0x000200f8,0x0000002b,0x00050041,0x0000000d,0x0000002f,0x0000000b,
0x0000000c,0x0004003d,0x00000008,0x00000030,0x0000002f,0x000500c7,0x00000008,0x00000032,
0x00000030,0x00000031,0x000500ab,0x00000012,0x00000033,0x00000032,0x00000011,0x000300f7,
0x00000035,0x00000000,0x000400fa,0x00000033,0x00000034,0x00000035,0x000200f8,0x00000034,
0x00050041,0x00000018,0x00000037,0x0000000b,0x00000011,0x0004003d,0x00000007,0x00000038,
0x00000037,0x0003003e,0x00000036,0x00000038,0x000200f9,0x00000035,0x000200f8,0x00000035,
0x00050041,0x0000000d,0x00000039,0x0000000b,0x0000000c,0x0004003d,0x00000008,0x0000003a,
0x00000039,0x000500c7,0x00000008,0x0000003c,0x0000003a,0x0000003b,0x000500ab,0x00000012,
0x0000003d,0x0000003c,0x00000011,0x000300f7,0x0000003f,0x00000000,0x000400fa,0x0000003d,
0x0000003e,0x0000003f,0x000200f8,0x0000003e,0x00050041,0x00000018,0x00000041,0x0000000b,
0x00000011,0x0004003d,0x00000007,0x00000042,0x00000041,0x0003003e,0x00000040,0x00000042,
0x000200f9,0x0000003f,0x000200f8,0x0000003f,0x00050041,0x0000000d,0x00000043,0x0000000b,
0x0000000c,0x0004003d,0x00000008,0x00000044,0x00000043,0x000500c7,0x00000008,0x00000046,
0x00000044,0x00000045,0x000500ab,0x00000012,0x00000047,0x00000046,0x00000011,0x000300f7,
0x00000049,0x00000000,0x000400fa,0x00000047,0x00000048,0x00000049,0x000200f8,0x00000048,
0x00050041,0x00000018,0x0000004b,0x0000000b,0x00000011,0x0004003d,0x00000007,0x0000004c,
0x0000004b,0x0003003e,0x0000004a,0x0000004c,0x000200f9,0x00000049,0x000200f8,0x00000049,
0x00050041,0x0000000d,0x0000004d,0x0000000b,0x0000000c,0x0004003d,0x00000008,0x0000004e,
0x0000004d,0x000500c7,0x00000008,0x00000050,0x0000004e,0x0000004f,0x000500ab,0x00000012,
0x00000051,0x00000050,0x00000011,0x000300f7,0x00000053,0x00000000,0x000400fa,0x00000051,
0x00000052,0x00000053,0x000200f8,0x00000052,0x00050041,0x00000018,0x00000055,0x0000000b,
0x00000011,0x0004003d,0x00000007,0x00000056,0x00000055,0x0003003e,0x00000054,0x00000056,
0x000200f9,0x00000053,0x000200f8,0x00000053,0x00050041,0x0000000d,0x00000057,0x0000000b,
0x0000000c,0x0004003d,0x00000008,0x00000058,0x00000057,0x000500c7,0x00000008,0x0000005a,
0x00000058,0x00000059,0x000500ab,0x00000012,0x0000005b,0x0000005a,0x00000011,0x000300f7,
0x0000005d,0x00000000,0x000400fa,0x0000005b,0x0000005c,0x0000005d,0x000200f8,0x0000005c,
0x00050041,0x00000018,0x0000005f,0x0000000b,0x00000011,0x0004003d,0x00000007,0x00000060,
0x0000005f,0x0003003e,0x0000005e,0x00000060,0x000200f9,0x0000005d,0x000200f8,0x0000005d,
0x000100fd,0x00010038
};
#if 0 // Generated from:
......@@ -25,12 +86,51 @@ const uint32_t kImageClear_frag_00000000[] = {
layout(push_constant)uniform PushConstants {
vec4 clearColor;
int clearBufferMask;
} params;
layout(location = 0)out vec4 colorOut;
layout(location = 0)out vec4 colorOut0;
layout(location = 1)out vec4 colorOut1;
layout(location = 2)out vec4 colorOut2;
layout(location = 3)out vec4 colorOut3;
layout(location = 4)out vec4 colorOut4;
layout(location = 5)out vec4 colorOut5;
layout(location = 6)out vec4 colorOut6;
layout(location = 7)out vec4 colorOut7;
void main()
{
colorOut = params . clearColor;
if((params . clearBufferMask &(1 << 0))!= 0)
{
colorOut0 = params . clearColor;
}
if((params . clearBufferMask &(1 << 1))!= 0)
{
colorOut1 = params . clearColor;
}
if((params . clearBufferMask &(1 << 2))!= 0)
{
colorOut2 = params . clearColor;
}
if((params . clearBufferMask &(1 << 3))!= 0)
{
colorOut3 = params . clearColor;
}
if((params . clearBufferMask &(1 << 4))!= 0)
{
colorOut4 = params . clearColor;
}
if((params . clearBufferMask &(1 << 5))!= 0)
{
colorOut5 = params . clearColor;
}
if((params . clearBufferMask &(1 << 6))!= 0)
{
colorOut6 = params . clearColor;
}
if((params . clearBufferMask &(1 << 7))!= 0)
{
colorOut7 = params . clearColor;
}
}
#endif // Preprocessed code
......@@ -9,11 +9,51 @@
layout(push_constant) uniform PushConstants {
vec4 clearColor;
int clearBufferMask;
} params;
layout(location = 0) out vec4 colorOut;
// ANGLE supports a maximum of 8 draw buffers
layout(location = 0) out vec4 colorOut0;
layout(location = 1) out vec4 colorOut1;
layout(location = 2) out vec4 colorOut2;
layout(location = 3) out vec4 colorOut3;
layout(location = 4) out vec4 colorOut4;
layout(location = 5) out vec4 colorOut5;
layout(location = 6) out vec4 colorOut6;
layout(location = 7) out vec4 colorOut7;
void main()
{
colorOut = params.clearColor;
if ((params.clearBufferMask & (1 << 0)) != 0)
{
colorOut0 = params.clearColor;
}
if ((params.clearBufferMask & (1 << 1)) != 0)
{
colorOut1 = params.clearColor;
}
if ((params.clearBufferMask & (1 << 2)) != 0)
{
colorOut2 = params.clearColor;
}
if ((params.clearBufferMask & (1 << 3)) != 0)
{
colorOut3 = params.clearColor;
}
if ((params.clearBufferMask & (1 << 4)) != 0)
{
colorOut4 = params.clearColor;
}
if ((params.clearBufferMask & (1 << 5)) != 0)
{
colorOut5 = params.clearColor;
}
if ((params.clearBufferMask & (1 << 6)) != 0)
{
colorOut6 = params.clearColor;
}
if ((params.clearBufferMask & (1 << 7)) != 0)
{
colorOut7 = params.clearColor;
}
}
......@@ -1082,39 +1082,28 @@ void AttachmentOpsArray::initDummyOp(size_t index,
VkImageLayout initialLayout,
VkImageLayout finalLayout)
{
setLayout(index, initialLayout, finalLayout);
setLoadOp(index, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
setStoreOp(index, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_STORE_OP_DONT_CARE);
}
void AttachmentOpsArray::setLayout(size_t index,
VkImageLayout initialLayout,
VkImageLayout finalLayout)
{
PackedAttachmentOpsDesc &ops = mOps[index];
SetBitField(ops.initialLayout, initialLayout);
SetBitField(ops.finalLayout, finalLayout);
SetBitField(ops.loadOp, VK_ATTACHMENT_LOAD_OP_LOAD);
SetBitField(ops.stencilLoadOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
SetBitField(ops.storeOp, VK_ATTACHMENT_STORE_OP_STORE);
SetBitField(ops.stencilStoreOp, VK_ATTACHMENT_STORE_OP_DONT_CARE);
}
void AttachmentOpsArray::setLoadOp(size_t index,
VkAttachmentLoadOp loadOp,
VkAttachmentLoadOp stencilLoadOp)
{
PackedAttachmentOpsDesc &ops = mOps[index];
SetBitField(ops.loadOp, loadOp);
SetBitField(ops.stencilLoadOp, stencilLoadOp);
}
void AttachmentOpsArray::setStoreOp(size_t index,
VkAttachmentStoreOp storeOp,
VkAttachmentStoreOp stencilStoreOp)
void AttachmentOpsArray::initWithLoadStore(size_t index,
VkImageLayout initialLayout,
VkImageLayout finalLayout)
{
PackedAttachmentOpsDesc &ops = mOps[index];
SetBitField(ops.storeOp, storeOp);
SetBitField(ops.stencilStoreOp, stencilStoreOp);
SetBitField(ops.initialLayout, initialLayout);
SetBitField(ops.finalLayout, finalLayout);
SetBitField(ops.loadOp, VK_ATTACHMENT_LOAD_OP_LOAD);
SetBitField(ops.stencilLoadOp, VK_ATTACHMENT_LOAD_OP_LOAD);
SetBitField(ops.storeOp, VK_ATTACHMENT_STORE_OP_STORE);
SetBitField(ops.stencilStoreOp, VK_ATTACHMENT_STORE_OP_STORE);
}
size_t AttachmentOpsArray::hash() const
......
......@@ -115,10 +115,8 @@ class AttachmentOpsArray final
// Initializes an attachment op with whatever values. Used for compatible RenderPass checks.
void initDummyOp(size_t index, VkImageLayout initialLayout, VkImageLayout finalLayout);
void setLayout(size_t index, VkImageLayout initialLayout, VkImageLayout finalLayout);
void setLoadOp(size_t index, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp);
void setStoreOp(size_t index, VkAttachmentStoreOp storeOp, VkAttachmentStoreOp stencilStoreOp);
// Initialize an attachment op with all load and store operations.
void initWithLoadStore(size_t index, VkImageLayout initialLayout, VkImageLayout finalLayout);
size_t hash() const;
......
......@@ -170,6 +170,9 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
VkResult init(VkDevice device, const VkCommandBufferAllocateInfo &createInfo);
// There is no way to know if the command buffer contains any commands.
bool empty() const { return false; }
using WrappedObject::operator=;
static bool SupportsQueries(const VkPhysicalDeviceFeatures &features)
......
......@@ -761,6 +761,9 @@ TEST_P(ClearTestES3, MaskedScissoredClearMultipleAttachments)
// mistakenly clear every channel (including the masked-out ones)
TEST_P(ClearTestES3, MaskedClearBufferBug)
{
// Vulkan doesn't support gaps in render targets yet. http://anglebug.com/2394
ANGLE_SKIP_TEST_IF(IsVulkan());
unsigned char pixelData[] = {255, 255, 255, 255};
glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
......@@ -896,6 +899,9 @@ TEST_P(ClearTestES3, MixedSRGBClear)
// flush or finish after ClearBufferfv or each draw.
TEST_P(ClearTestES3, RepeatedClear)
{
// ES3 shaders are not yet supported on Vulkan.
ANGLE_SKIP_TEST_IF(IsVulkan());
constexpr char kVS[] =
"#version 300 es\n"
"in highp vec2 position;\n"
......@@ -1271,7 +1277,7 @@ ANGLE_INSTANTIATE_TEST(ClearTest,
ES2_OPENGLES(),
ES3_OPENGLES(),
ES2_VULKAN());
ANGLE_INSTANTIATE_TEST(ClearTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
ANGLE_INSTANTIATE_TEST(ClearTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES(), ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(ScissoredClearTest, ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN());
ANGLE_INSTANTIATE_TEST(VulkanClearTest, ES2_VULKAN());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment