Commit 9fa248e1 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Implement EXT_draw_buffers

In GLES, color attachments are referenced by their indices. These indices match between the API and GLSL. For example, if a shader has: layout(location=0) out color; layout(location=3) out roughness; Then GLES would bind and enable GL_COLOR_ATTACHMENT0 and GL_COLOR_ATTACHMENT3. In Vulkan, the framebuffer object and the corresponding renderpass define the color attachments, and they don't allow gaps in color attachments as GLES does. A render subpass creates the mapping between the color attachments as defined in the framebuffer and the attachments used by the shader (with possible gaps). This change packs the enabled GL color attachments for the sake of the framebuffer, and sets the subpass up in such a way that the shaders continue to use the same color output indices as GLES. In the example above, we have the attachment indices as follows: Status | GLES | GLSL | RenderPass | Subpass enabled 0 0 0 0 disabled 1 - VK_ATTACHMENT_UNUSED disabled 2 - VK_ATTACHMENT_UNUSED enabled 3 3 1 1 That is, the array of color attachments in the Vulkan framebuffer/renderpass is: [0] = GL color attachment 0 [1] = GL color attachment 3 And the array of color attachment references in the Vulkan render subpass is: [0] = 0 (index 0 of the renderpass attachment array) [1] = VK_ATTACHMENT_UNUSED [2] = VK_ATTACHMENT_UNUSED [3] = 1 (index 1 of the renderpass attachment array) Bug: angleproject:2394 Change-Id: Ib6cd2b60882643ea152986eee453270d09cd4aed Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1595442 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 776694cd
...@@ -652,9 +652,9 @@ angle::Result FramebufferVk::blit(const gl::Context *context, ...@@ -652,9 +652,9 @@ angle::Result FramebufferVk::blit(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
for (size_t colorAttachment : mState.getEnabledDrawBuffers()) for (size_t colorIndexGL : mState.getEnabledDrawBuffers())
{ {
RenderTargetVk *drawRenderTarget = mRenderTargetCache.getColors()[colorAttachment]; RenderTargetVk *drawRenderTarget = mRenderTargetCache.getColors()[colorIndexGL];
ASSERT(drawRenderTarget); ASSERT(drawRenderTarget);
ASSERT(HasSrcAndDstBlitProperties(renderer, readRenderTarget, drawRenderTarget)); ASSERT(HasSrcAndDstBlitProperties(renderer, readRenderTarget, drawRenderTarget));
...@@ -836,30 +836,31 @@ angle::Result FramebufferVk::syncState(const gl::Context *context, ...@@ -836,30 +836,31 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
{ {
ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 && ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX); dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
size_t colorIndex = size_t colorIndexGL =
static_cast<size_t>(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0); static_cast<size_t>(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
ANGLE_TRY(mRenderTargetCache.updateColorRenderTarget(context, mState, colorIndex)); ANGLE_TRY(
mRenderTargetCache.updateColorRenderTarget(context, mState, colorIndexGL));
// Update cached masks for masked clears. // Update cached masks for masked clears.
RenderTargetVk *renderTarget = mRenderTargetCache.getColors()[colorIndex]; RenderTargetVk *renderTarget = mRenderTargetCache.getColors()[colorIndexGL];
if (renderTarget) if (renderTarget)
{ {
const angle::Format &emulatedFormat = const angle::Format &emulatedFormat =
renderTarget->getImageFormat().imageFormat(); renderTarget->getImageFormat().imageFormat();
updateActiveColorMasks( updateActiveColorMasks(
colorIndex, emulatedFormat.redBits > 0, emulatedFormat.greenBits > 0, colorIndexGL, emulatedFormat.redBits > 0, emulatedFormat.greenBits > 0,
emulatedFormat.blueBits > 0, emulatedFormat.alphaBits > 0); emulatedFormat.blueBits > 0, emulatedFormat.alphaBits > 0);
const angle::Format &sourceFormat = const angle::Format &sourceFormat =
renderTarget->getImageFormat().angleFormat(); renderTarget->getImageFormat().angleFormat();
mEmulatedAlphaAttachmentMask.set( mEmulatedAlphaAttachmentMask.set(
colorIndex, sourceFormat.alphaBits == 0 && emulatedFormat.alphaBits > 0); colorIndexGL, sourceFormat.alphaBits == 0 && emulatedFormat.alphaBits > 0);
contextVk->updateColorMask(context->getState().getBlendState()); contextVk->updateColorMask(context->getState().getBlendState());
} }
else else
{ {
updateActiveColorMasks(colorIndex, false, false, false, false); updateActiveColorMasks(colorIndexGL, false, false, false, false);
} }
break; break;
} }
...@@ -888,19 +889,28 @@ void FramebufferVk::updateRenderPassDesc() ...@@ -888,19 +889,28 @@ void FramebufferVk::updateRenderPassDesc()
mRenderPassDesc = {}; mRenderPassDesc = {};
mRenderPassDesc.setSamples(getSamples()); mRenderPassDesc.setSamples(getSamples());
// TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394 const auto &colorRenderTargets = mRenderTargetCache.getColors();
const auto &colorRenderTargets = mRenderTargetCache.getColors(); const gl::DrawBufferMask enabledDrawBuffers = mState.getEnabledDrawBuffers();
for (size_t colorIndex : mState.getEnabledDrawBuffers()) for (size_t colorIndexGL = 0; colorIndexGL < enabledDrawBuffers.size(); ++colorIndexGL)
{ {
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex]; if (enabledDrawBuffers[colorIndexGL])
ASSERT(colorRenderTarget); {
mRenderPassDesc.packAttachment(colorRenderTarget->getImage().getFormat()); RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndexGL];
ASSERT(colorRenderTarget);
mRenderPassDesc.packColorAttachment(
colorIndexGL, colorRenderTarget->getImage().getFormat().angleFormatID);
}
else
{
mRenderPassDesc.packColorAttachmentGap(colorIndexGL);
}
} }
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil(); RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget) if (depthStencilRenderTarget)
{ {
mRenderPassDesc.packAttachment(depthStencilRenderTarget->getImage().getFormat()); mRenderPassDesc.packDepthStencilAttachment(
depthStencilRenderTarget->getImage().getFormat().angleFormatID);
} }
} }
...@@ -927,11 +937,10 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe ...@@ -927,11 +937,10 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe
std::vector<VkImageView> attachments; std::vector<VkImageView> attachments;
gl::Extents attachmentsSize; gl::Extents attachmentsSize;
// TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
const auto &colorRenderTargets = mRenderTargetCache.getColors(); const auto &colorRenderTargets = mRenderTargetCache.getColors();
for (size_t colorIndex : mState.getEnabledDrawBuffers()) for (size_t colorIndexGL : mState.getEnabledDrawBuffers())
{ {
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex]; RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndexGL];
ASSERT(colorRenderTarget); ASSERT(colorRenderTarget);
attachments.push_back(colorRenderTarget->getDrawImageView()->getHandle()); attachments.push_back(colorRenderTarget->getDrawImageView()->getHandle());
...@@ -949,8 +958,6 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe ...@@ -949,8 +958,6 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe
attachmentsSize = depthStencilRenderTarget->getExtents(); attachmentsSize = depthStencilRenderTarget->getExtents();
} }
ASSERT(!attachments.empty());
VkFramebufferCreateInfo framebufferInfo = {}; VkFramebufferCreateInfo framebufferInfo = {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
...@@ -993,27 +1000,26 @@ angle::Result FramebufferVk::clearWithRenderPassOp( ...@@ -993,27 +1000,26 @@ angle::Result FramebufferVk::clearWithRenderPassOp(
ANGLE_TRY(startNewRenderPass(contextVk, clearArea, &commandBuffer)); ANGLE_TRY(startNewRenderPass(contextVk, clearArea, &commandBuffer));
} }
size_t attachmentIndex = 0; size_t attachmentIndexVk = 0;
// Go through clearColorBuffers and set the appropriate loadOp and clear values. // Go through clearColorBuffers and set the appropriate loadOp and clear values.
// TODO: Support gaps in RenderTargets. http://anglebug.com/2394 for (size_t colorIndexGL : mState.getEnabledDrawBuffers())
for (size_t colorIndex : mState.getEnabledDrawBuffers())
{ {
if (clearColorBuffers.test(colorIndex)) if (clearColorBuffers.test(colorIndexGL))
{ {
RenderTargetVk *renderTarget = getColorReadRenderTarget(); RenderTargetVk *renderTarget = getColorReadRenderTarget();
// If the render target doesn't have alpha, but its emulated format has it, clear the // If the render target doesn't have alpha, but its emulated format has it, clear the
// alpha to 1. // alpha to 1.
VkClearColorValue value = clearColorValue; VkClearColorValue value = clearColorValue;
if (mEmulatedAlphaAttachmentMask[colorIndex]) if (mEmulatedAlphaAttachmentMask[colorIndexGL])
{ {
SetEmulatedAlphaValue(renderTarget->getImageFormat(), &value); SetEmulatedAlphaValue(renderTarget->getImageFormat(), &value);
} }
mFramebuffer.clearRenderPassColorAttachment(attachmentIndex, value); mFramebuffer.clearRenderPassColorAttachment(attachmentIndexVk, value);
} }
++attachmentIndex; ++attachmentIndexVk;
} }
// Set the appropriate loadOp and clear values for depth and stencil. // Set the appropriate loadOp and clear values for depth and stencil.
...@@ -1022,13 +1028,13 @@ angle::Result FramebufferVk::clearWithRenderPassOp( ...@@ -1022,13 +1028,13 @@ angle::Result FramebufferVk::clearWithRenderPassOp(
{ {
if (clearDepth) if (clearDepth)
{ {
mFramebuffer.clearRenderPassDepthAttachment(attachmentIndex, mFramebuffer.clearRenderPassDepthAttachment(attachmentIndexVk,
clearDepthStencilValue.depth); clearDepthStencilValue.depth);
} }
if (clearStencil) if (clearStencil)
{ {
mFramebuffer.clearRenderPassStencilAttachment(attachmentIndex, mFramebuffer.clearRenderPassStencilAttachment(attachmentIndexVk,
clearDepthStencilValue.stencil); clearDepthStencilValue.stencil);
} }
} }
...@@ -1059,15 +1065,15 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk, ...@@ -1059,15 +1065,15 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
params.clearStencil = clearStencil; params.clearStencil = clearStencil;
const auto &colorRenderTargets = mRenderTargetCache.getColors(); const auto &colorRenderTargets = mRenderTargetCache.getColors();
for (size_t colorIndex : clearColorBuffers) for (size_t colorIndexGL : clearColorBuffers)
{ {
const RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex]; const RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndexGL];
ASSERT(colorRenderTarget); ASSERT(colorRenderTarget);
params.colorFormat = &colorRenderTarget->getImage().getFormat().imageFormat(); params.colorFormat = &colorRenderTarget->getImage().getFormat().imageFormat();
params.colorAttachmentIndex = colorIndex; params.colorAttachmentIndexGL = colorIndexGL;
params.colorMaskFlags = colorMaskFlags; params.colorMaskFlags = colorMaskFlags;
if (mEmulatedAlphaAttachmentMask[colorIndex]) if (mEmulatedAlphaAttachmentMask[colorIndexGL])
{ {
params.colorMaskFlags &= ~VK_COLOR_COMPONENT_A_BIT; params.colorMaskFlags &= ~VK_COLOR_COMPONENT_A_BIT;
} }
...@@ -1109,18 +1115,14 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, ...@@ -1109,18 +1115,14 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
vk::CommandBuffer *writeCommands = nullptr; vk::CommandBuffer *writeCommands = nullptr;
ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &writeCommands)); ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &writeCommands));
vk::RenderPassDesc renderPassDesc;
// Initialize RenderPass info. // Initialize RenderPass info.
// TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
const auto &colorRenderTargets = mRenderTargetCache.getColors(); const auto &colorRenderTargets = mRenderTargetCache.getColors();
for (size_t colorIndex : mState.getEnabledDrawBuffers()) for (size_t colorIndexGL : mState.getEnabledDrawBuffers())
{ {
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex]; RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndexGL];
ASSERT(colorRenderTarget); ASSERT(colorRenderTarget);
ANGLE_TRY(colorRenderTarget->onColorDraw(contextVk, &mFramebuffer, writeCommands, ANGLE_TRY(colorRenderTarget->onColorDraw(contextVk, &mFramebuffer, writeCommands));
&renderPassDesc));
renderPassAttachmentOps.initWithLoadStore(attachmentClearValues.size(), renderPassAttachmentOps.initWithLoadStore(attachmentClearValues.size(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
...@@ -1131,8 +1133,8 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, ...@@ -1131,8 +1133,8 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil(); RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget) if (depthStencilRenderTarget)
{ {
ANGLE_TRY(depthStencilRenderTarget->onDepthStencilDraw(contextVk, &mFramebuffer, ANGLE_TRY(
writeCommands, &renderPassDesc)); depthStencilRenderTarget->onDepthStencilDraw(contextVk, &mFramebuffer, writeCommands));
renderPassAttachmentOps.initWithLoadStore(attachmentClearValues.size(), renderPassAttachmentOps.initWithLoadStore(attachmentClearValues.size(),
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
...@@ -1145,12 +1147,12 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, ...@@ -1145,12 +1147,12 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
commandBufferOut); commandBufferOut);
} }
void FramebufferVk::updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a) void FramebufferVk::updateActiveColorMasks(size_t colorIndexGL, bool r, bool g, bool b, bool a)
{ {
mActiveColorComponentMasksForClear[0].set(colorIndex, r); mActiveColorComponentMasksForClear[0].set(colorIndexGL, r);
mActiveColorComponentMasksForClear[1].set(colorIndex, g); mActiveColorComponentMasksForClear[1].set(colorIndexGL, g);
mActiveColorComponentMasksForClear[2].set(colorIndex, b); mActiveColorComponentMasksForClear[2].set(colorIndexGL, b);
mActiveColorComponentMasksForClear[3].set(colorIndex, a); mActiveColorComponentMasksForClear[3].set(colorIndexGL, a);
} }
const gl::DrawBufferMask &FramebufferVk::getEmulatedAlphaAttachmentMask() const const gl::DrawBufferMask &FramebufferVk::getEmulatedAlphaAttachmentMask() const
......
...@@ -54,15 +54,11 @@ void RenderTargetVk::reset() ...@@ -54,15 +54,11 @@ void RenderTargetVk::reset()
angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk, angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk, vk::FramebufferHelper *framebufferVk,
vk::CommandBuffer *commandBuffer, vk::CommandBuffer *commandBuffer)
vk::RenderPassDesc *renderPassDesc)
{ {
ASSERT(commandBuffer->valid()); ASSERT(commandBuffer->valid());
ASSERT(!mImage->getFormat().imageFormat().hasDepthOrStencilBits()); ASSERT(!mImage->getFormat().imageFormat().hasDepthOrStencilBits());
// Store the attachment info in the renderPassDesc.
renderPassDesc->packAttachment(mImage->getFormat());
ANGLE_TRY(ensureImageInitialized(contextVk)); ANGLE_TRY(ensureImageInitialized(contextVk));
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361 // TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
...@@ -77,15 +73,11 @@ angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk, ...@@ -77,15 +73,11 @@ angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk,
angle::Result RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk, angle::Result RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk, vk::FramebufferHelper *framebufferVk,
vk::CommandBuffer *commandBuffer, vk::CommandBuffer *commandBuffer)
vk::RenderPassDesc *renderPassDesc)
{ {
ASSERT(commandBuffer->valid()); ASSERT(commandBuffer->valid());
ASSERT(mImage->getFormat().imageFormat().hasDepthOrStencilBits()); ASSERT(mImage->getFormat().imageFormat().hasDepthOrStencilBits());
// Store the attachment info in the renderPassDesc.
renderPassDesc->packAttachment(mImage->getFormat());
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361 // TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
const angle::Format &format = mImage->getFormat().imageFormat(); const angle::Format &format = mImage->getFormat().imageFormat();
VkImageAspectFlags aspectFlags = vk::GetDepthStencilAspectFlags(format); VkImageAspectFlags aspectFlags = vk::GetDepthStencilAspectFlags(format);
......
...@@ -53,12 +53,10 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget ...@@ -53,12 +53,10 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
// Note: RenderTargets should be called in order, with the depth/stencil onRender last. // Note: RenderTargets should be called in order, with the depth/stencil onRender last.
angle::Result onColorDraw(ContextVk *contextVk, angle::Result onColorDraw(ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk, vk::FramebufferHelper *framebufferVk,
vk::CommandBuffer *commandBuffer, vk::CommandBuffer *commandBuffer);
vk::RenderPassDesc *renderPassDesc);
angle::Result onDepthStencilDraw(ContextVk *contextVk, angle::Result onDepthStencilDraw(ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk, vk::FramebufferHelper *framebufferVk,
vk::CommandBuffer *commandBuffer, vk::CommandBuffer *commandBuffer);
vk::RenderPassDesc *renderPassDesc);
vk::ImageHelper &getImage(); vk::ImageHelper &getImage();
const vk::ImageHelper &getImage() const; const vk::ImageHelper &getImage() const;
......
...@@ -30,6 +30,12 @@ std::shared_ptr<WaitableCompileEvent> ShaderVk::compile(const gl::Context *conte ...@@ -30,6 +30,12 @@ std::shared_ptr<WaitableCompileEvent> ShaderVk::compile(const gl::Context *conte
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
bool isWebGL = context->getExtensions().webglCompatibility;
if (isWebGL && mData.getShaderType() != gl::ShaderType::Compute)
{
compileOptions |= SH_INIT_OUTPUT_VARIABLES;
}
if (contextVk->getFeatures().clampPointSize.enabled) if (contextVk->getFeatures().clampPointSize.enabled)
{ {
compileOptions |= SH_CLAMP_POINT_SIZE; compileOptions |= SH_CLAMP_POINT_SIZE;
......
...@@ -664,7 +664,7 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk, ...@@ -664,7 +664,7 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
vk::GraphicsPipelineDesc pipelineDesc; vk::GraphicsPipelineDesc pipelineDesc;
pipelineDesc.initDefaults(); pipelineDesc.initDefaults();
pipelineDesc.setColorWriteMask(0, gl::DrawBufferMask()); pipelineDesc.setColorWriteMask(0, gl::DrawBufferMask());
pipelineDesc.setSingleColorWriteMask(params.colorAttachmentIndex, params.colorMaskFlags); pipelineDesc.setSingleColorWriteMask(params.colorAttachmentIndexGL, params.colorMaskFlags);
pipelineDesc.setRenderPassDesc(*params.renderPassDesc); pipelineDesc.setRenderPassDesc(*params.renderPassDesc);
// Note: depth test is disabled by default so this should be unnecessary, but works around an // Note: depth test is disabled by default so this should be unnecessary, but works around an
// Intel bug on windows. http://anglebug.com/3348 // Intel bug on windows. http://anglebug.com/3348
...@@ -704,7 +704,7 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk, ...@@ -704,7 +704,7 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
ANGLE_TRY(shaderLibrary.getFullScreenQuad_vert(contextVk, 0, &vertexShader)); ANGLE_TRY(shaderLibrary.getFullScreenQuad_vert(contextVk, 0, &vertexShader));
if (params.clearColor) if (params.clearColor)
{ {
uint32_t flags = GetImageClearFlags(*params.colorFormat, params.colorAttachmentIndex); uint32_t flags = GetImageClearFlags(*params.colorFormat, params.colorAttachmentIndexGL);
ANGLE_TRY(shaderLibrary.getImageClear_frag(contextVk, flags, &fragmentShader)); ANGLE_TRY(shaderLibrary.getImageClear_frag(contextVk, flags, &fragmentShader));
imageClearProgram = &mImageClearProgram[flags]; imageClearProgram = &mImageClearProgram[flags];
} }
...@@ -771,7 +771,7 @@ angle::Result UtilsVk::copyImage(ContextVk *contextVk, ...@@ -771,7 +771,7 @@ angle::Result UtilsVk::copyImage(ContextVk *contextVk,
vk::RenderPassDesc renderPassDesc; vk::RenderPassDesc renderPassDesc;
renderPassDesc.setSamples(dest->getSamples()); renderPassDesc.setSamples(dest->getSamples());
renderPassDesc.packAttachment(destFormat); renderPassDesc.packColorAttachment(0, destFormat.angleFormatID);
vk::GraphicsPipelineDesc pipelineDesc; vk::GraphicsPipelineDesc pipelineDesc;
pipelineDesc.initDefaults(); pipelineDesc.initDefaults();
...@@ -849,7 +849,7 @@ UtilsVk::ClearFramebufferParameters::ClearFramebufferParameters() ...@@ -849,7 +849,7 @@ UtilsVk::ClearFramebufferParameters::ClearFramebufferParameters()
clearStencil(false), clearStencil(false),
stencilMask(0), stencilMask(0),
colorMaskFlags(0), colorMaskFlags(0),
colorAttachmentIndex(0), colorAttachmentIndexGL(0),
colorFormat(nullptr), colorFormat(nullptr),
colorClearValue{}, colorClearValue{},
stencilClearValue(0) stencilClearValue(0)
......
...@@ -75,7 +75,7 @@ class UtilsVk : angle::NonCopyable ...@@ -75,7 +75,7 @@ class UtilsVk : angle::NonCopyable
uint8_t stencilMask; uint8_t stencilMask;
VkColorComponentFlags colorMaskFlags; VkColorComponentFlags colorMaskFlags;
uint32_t colorAttachmentIndex; uint32_t colorAttachmentIndexGL;
const angle::Format *colorFormat; const angle::Format *colorFormat;
VkClearColorValue colorClearValue; VkClearColorValue colorClearValue;
......
...@@ -183,35 +183,67 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context, ...@@ -183,35 +183,67 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context,
const AttachmentOpsArray &ops, const AttachmentOpsArray &ops,
RenderPass *renderPass) RenderPass *renderPass)
{ {
size_t attachmentCount = desc.attachmentCount();
// Unpack the packed and split representation into the format required by Vulkan. // Unpack the packed and split representation into the format required by Vulkan.
gl::DrawBuffersVector<VkAttachmentReference> colorAttachmentRefs; gl::DrawBuffersVector<VkAttachmentReference> colorAttachmentRefs;
VkAttachmentReference depthStencilAttachmentRef = {VK_ATTACHMENT_UNUSED}; VkAttachmentReference depthStencilAttachmentRef = {VK_ATTACHMENT_UNUSED};
gl::AttachmentArray<VkAttachmentDescription> attachmentDescs; gl::AttachmentArray<VkAttachmentDescription> attachmentDescs;
for (uint32_t attachmentIndex = 0; attachmentIndex < attachmentCount; ++attachmentIndex)
uint32_t colorAttachmentCount = 0;
uint32_t attachmentCount = 0;
for (uint32_t colorIndexGL = 0; colorIndexGL < desc.colorAttachmentRange(); ++colorIndexGL)
{ {
angle::FormatID formatID = desc[attachmentIndex]; // Vulkan says:
//
// > Each element of the pColorAttachments array corresponds to an output location in the
// > shader, i.e. if the shader declares an output variable decorated with a Location value
// > of X, then it uses the attachment provided in pColorAttachments[X].
//
// This means that colorAttachmentRefs is indexed by colorIndexGL. Where the color
// attachment is disabled, a reference with VK_ATTACHMENT_UNUSED is given.
if (!desc.isColorAttachmentEnabled(colorIndexGL))
{
VkAttachmentReference colorRef;
colorRef.attachment = VK_ATTACHMENT_UNUSED;
colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachmentRefs.push_back(colorRef);
continue;
}
uint32_t colorIndexVk = colorAttachmentCount++;
angle::FormatID formatID = desc[colorIndexGL];
ASSERT(formatID != angle::FormatID::NONE); ASSERT(formatID != angle::FormatID::NONE);
const vk::Format &format = context->getRenderer()->getFormat(formatID); const vk::Format &format = context->getRenderer()->getFormat(formatID);
if (!format.angleFormat().hasDepthOrStencilBits()) VkAttachmentReference colorRef;
{ colorRef.attachment = colorIndexVk;
VkAttachmentReference colorRef = colorAttachmentRefs[attachmentIndex]; colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
colorRef.attachment = attachmentIndex;
colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
colorAttachmentRefs.push_back(colorRef); colorAttachmentRefs.push_back(colorRef);
}
else UnpackAttachmentDesc(&attachmentDescs[colorIndexVk], format, desc.samples(),
{ ops[colorIndexVk]);
ASSERT(depthStencilAttachmentRef.attachment == VK_ATTACHMENT_UNUSED);
depthStencilAttachmentRef.attachment = attachmentIndex; ++attachmentCount;
depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; }
}
UnpackAttachmentDesc(&attachmentDescs[attachmentIndex], format, desc.samples(), if (desc.hasDepthStencilAttachment())
ops[attachmentIndex]); {
uint32_t depthStencilIndex = desc.depthStencilAttachmentIndex();
uint32_t depthStencilIndexVk = colorAttachmentCount;
angle::FormatID formatID = desc[depthStencilIndex];
ASSERT(formatID != angle::FormatID::NONE);
const vk::Format &format = context->getRenderer()->getFormat(formatID);
depthStencilAttachmentRef.attachment = depthStencilIndexVk;
depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
UnpackAttachmentDesc(&attachmentDescs[depthStencilIndexVk], format, desc.samples(),
ops[depthStencilIndexVk]);
++attachmentCount;
} }
VkSubpassDescription subpassDesc = {}; VkSubpassDescription subpassDesc = {};
...@@ -317,39 +349,56 @@ RenderPassDesc::RenderPassDesc(const RenderPassDesc &other) ...@@ -317,39 +349,56 @@ RenderPassDesc::RenderPassDesc(const RenderPassDesc &other)
memcpy(this, &other, sizeof(RenderPassDesc)); memcpy(this, &other, sizeof(RenderPassDesc));
} }
size_t RenderPassDesc::colorAttachmentCount() const void RenderPassDesc::setSamples(GLint samples)
{ {
return mColorAttachmentCount; ASSERT(samples < std::numeric_limits<uint8_t>::max());
mSamples = static_cast<uint8_t>(samples);
} }
size_t RenderPassDesc::attachmentCount() const void RenderPassDesc::packColorAttachment(size_t colorIndexGL, angle::FormatID formatID)
{ {
return mColorAttachmentCount + mDepthStencilAttachmentCount; ASSERT(colorIndexGL < mAttachmentFormats.size());
} static_assert(angle::kNumANGLEFormats < std::numeric_limits<uint8_t>::max(),
"Too many ANGLE formats to fit in uint8_t");
// Force the user to pack the depth/stencil attachment last.
ASSERT(mHasDepthStencilAttachment == false);
// This function should only be called for enabled GL color attachments.`
ASSERT(formatID != angle::FormatID::NONE);
void RenderPassDesc::setSamples(GLint samples) uint8_t &packedFormat = mAttachmentFormats[colorIndexGL];
{ SetBitField(packedFormat, formatID);
ASSERT(samples < std::numeric_limits<uint8_t>::max());
mSamples = static_cast<uint8_t>(samples); // Set color attachment range such that it covers the range from index 0 through last
// active index. This is the reason why we need depth/stencil to be packed last.
mColorAttachmentRange =
std::max<uint8_t>(mColorAttachmentRange, static_cast<uint8_t>(colorIndexGL) + 1);
} }
void RenderPassDesc::packAttachment(const Format &format) void RenderPassDesc::packColorAttachmentGap(size_t colorIndexGL)
{ {
ASSERT(attachmentCount() < mAttachmentFormats.size() - 1); ASSERT(colorIndexGL < mAttachmentFormats.size());
static_assert(angle::kNumANGLEFormats < std::numeric_limits<uint8_t>::max(), static_assert(angle::kNumANGLEFormats < std::numeric_limits<uint8_t>::max(),
"Too many ANGLE formats to fit in uint8_t"); "Too many ANGLE formats to fit in uint8_t");
uint8_t &packedFormat = mAttachmentFormats[attachmentCount()]; // Force the user to pack the depth/stencil attachment last.
SetBitField(packedFormat, format.angleFormatID); ASSERT(mHasDepthStencilAttachment == false);
if (format.angleFormat().hasDepthOrStencilBits())
{ // Use NONE as a flag for gaps in GL color attachments.
mDepthStencilAttachmentCount++; uint8_t &packedFormat = mAttachmentFormats[colorIndexGL];
} SetBitField(packedFormat, angle::FormatID::NONE);
else }
{
// Force the user to pack the depth/stencil attachment last. void RenderPassDesc::packDepthStencilAttachment(angle::FormatID formatID)
ASSERT(mDepthStencilAttachmentCount == 0); {
mColorAttachmentCount++; // Though written as Count, there is only ever a single depth/stencil attachment.
} ASSERT(mHasDepthStencilAttachment == false);
size_t index = depthStencilAttachmentIndex();
ASSERT(index < mAttachmentFormats.size());
uint8_t &packedFormat = mAttachmentFormats[index];
SetBitField(packedFormat, formatID);
mHasDepthStencilAttachment = true;
} }
RenderPassDesc &RenderPassDesc::operator=(const RenderPassDesc &other) RenderPassDesc &RenderPassDesc::operator=(const RenderPassDesc &other)
...@@ -363,6 +412,25 @@ size_t RenderPassDesc::hash() const ...@@ -363,6 +412,25 @@ size_t RenderPassDesc::hash() const
return angle::ComputeGenericHash(*this); return angle::ComputeGenericHash(*this);
} }
bool RenderPassDesc::isColorAttachmentEnabled(size_t colorIndexGL) const
{
angle::FormatID formatID = operator[](colorIndexGL);
return formatID != angle::FormatID::NONE;
}
size_t RenderPassDesc::attachmentCount() const
{
size_t colorAttachmentCount = 0;
for (size_t i = 0; i < mColorAttachmentRange; ++i)
{
colorAttachmentCount += isColorAttachmentEnabled(i);
}
// Note that there are no gaps in depth/stencil attachments. In fact there is a maximum of 1 of
// it.
return colorAttachmentCount + mHasDepthStencilAttachment;
}
bool operator==(const RenderPassDesc &lhs, const RenderPassDesc &rhs) bool operator==(const RenderPassDesc &lhs, const RenderPassDesc &rhs)
{ {
return (memcmp(&lhs, &rhs, sizeof(RenderPassDesc)) == 0); return (memcmp(&lhs, &rhs, sizeof(RenderPassDesc)) == 0);
...@@ -467,9 +535,10 @@ void GraphicsPipelineDesc::initDefaults() ...@@ -467,9 +535,10 @@ void GraphicsPipelineDesc::initDefaults()
VkFlags allColorBits = (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VkFlags allColorBits = (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT); VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
for (uint32_t colorIndex = 0; colorIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; ++colorIndex) for (uint32_t colorIndexGL = 0; colorIndexGL < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS;
++colorIndexGL)
{ {
Int4Array_Set(inputAndBlend.colorWriteMaskBits, colorIndex, allColorBits); Int4Array_Set(inputAndBlend.colorWriteMaskBits, colorIndexGL, allColorBits);
} }
PackedColorBlendAttachmentState blendAttachmentState; PackedColorBlendAttachmentState blendAttachmentState;
...@@ -669,7 +738,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline( ...@@ -669,7 +738,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
blendState.flags = 0; blendState.flags = 0;
blendState.logicOpEnable = static_cast<VkBool32>(inputAndBlend.logic.opEnable); blendState.logicOpEnable = static_cast<VkBool32>(inputAndBlend.logic.opEnable);
blendState.logicOp = static_cast<VkLogicOp>(inputAndBlend.logic.op); blendState.logicOp = static_cast<VkLogicOp>(inputAndBlend.logic.op);
blendState.attachmentCount = mRenderPassDesc.colorAttachmentCount(); blendState.attachmentCount = mRenderPassDesc.colorAttachmentRange();
blendState.pAttachments = blendAttachmentState.data(); blendState.pAttachments = blendAttachmentState.data();
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
...@@ -679,14 +748,14 @@ angle::Result GraphicsPipelineDesc::initializePipeline( ...@@ -679,14 +748,14 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
const gl::DrawBufferMask blendEnableMask(inputAndBlend.blendEnableMask); const gl::DrawBufferMask blendEnableMask(inputAndBlend.blendEnableMask);
for (uint32_t colorIndex = 0; colorIndex < blendState.attachmentCount; ++colorIndex) for (uint32_t colorIndexGL = 0; colorIndexGL < blendState.attachmentCount; ++colorIndexGL)
{ {
VkPipelineColorBlendAttachmentState &state = blendAttachmentState[colorIndex]; VkPipelineColorBlendAttachmentState &state = blendAttachmentState[colorIndexGL];
state.blendEnable = blendEnableMask[colorIndex] ? VK_TRUE : VK_FALSE; state.blendEnable = blendEnableMask[colorIndexGL] ? VK_TRUE : VK_FALSE;
state.colorWriteMask = state.colorWriteMask =
Int4Array_Get<VkColorComponentFlags>(inputAndBlend.colorWriteMaskBits, colorIndex); Int4Array_Get<VkColorComponentFlags>(inputAndBlend.colorWriteMaskBits, colorIndexGL);
UnpackBlendAttachmentState(inputAndBlend.attachments[colorIndex], &state); UnpackBlendAttachmentState(inputAndBlend.attachments[colorIndexGL], &state);
} }
// We would define dynamic state here if it were to be used. // We would define dynamic state here if it were to be used.
...@@ -851,19 +920,21 @@ void GraphicsPipelineDesc::setColorWriteMask(VkColorComponentFlags colorComponen ...@@ -851,19 +920,21 @@ void GraphicsPipelineDesc::setColorWriteMask(VkColorComponentFlags colorComponen
PackedInputAssemblyAndColorBlendStateInfo &inputAndBlend = mInputAssemblyAndColorBlendStateInfo; PackedInputAssemblyAndColorBlendStateInfo &inputAndBlend = mInputAssemblyAndColorBlendStateInfo;
uint8_t colorMask = static_cast<uint8_t>(colorComponentFlags); uint8_t colorMask = static_cast<uint8_t>(colorComponentFlags);
for (size_t colorIndex = 0; colorIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorIndex++) for (size_t colorIndexGL = 0; colorIndexGL < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS;
colorIndexGL++)
{ {
uint8_t mask = alphaMask[colorIndex] ? (colorMask & ~VK_COLOR_COMPONENT_A_BIT) : colorMask; uint8_t mask =
Int4Array_Set(inputAndBlend.colorWriteMaskBits, colorIndex, mask); alphaMask[colorIndexGL] ? (colorMask & ~VK_COLOR_COMPONENT_A_BIT) : colorMask;
Int4Array_Set(inputAndBlend.colorWriteMaskBits, colorIndexGL, mask);
} }
} }
void GraphicsPipelineDesc::setSingleColorWriteMask(uint32_t colorIndex, void GraphicsPipelineDesc::setSingleColorWriteMask(uint32_t colorIndexGL,
VkColorComponentFlags colorComponentFlags) VkColorComponentFlags colorComponentFlags)
{ {
PackedInputAssemblyAndColorBlendStateInfo &inputAndBlend = mInputAssemblyAndColorBlendStateInfo; PackedInputAssemblyAndColorBlendStateInfo &inputAndBlend = mInputAssemblyAndColorBlendStateInfo;
uint8_t colorMask = static_cast<uint8_t>(colorComponentFlags); uint8_t colorMask = static_cast<uint8_t>(colorComponentFlags);
Int4Array_Set(inputAndBlend.colorWriteMaskBits, colorIndex, colorMask); Int4Array_Set(inputAndBlend.colorWriteMaskBits, colorIndexGL, colorMask);
} }
void GraphicsPipelineDesc::updateColorWriteMask(GraphicsPipelineTransitionBits *transition, void GraphicsPipelineDesc::updateColorWriteMask(GraphicsPipelineTransitionBits *transition,
...@@ -872,10 +943,11 @@ void GraphicsPipelineDesc::updateColorWriteMask(GraphicsPipelineTransitionBits * ...@@ -872,10 +943,11 @@ void GraphicsPipelineDesc::updateColorWriteMask(GraphicsPipelineTransitionBits *
{ {
setColorWriteMask(colorComponentFlags, alphaMask); setColorWriteMask(colorComponentFlags, alphaMask);
for (size_t colorIndex = 0; colorIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorIndex++) for (size_t colorIndexGL = 0; colorIndexGL < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS;
colorIndexGL++)
{ {
transition->set(ANGLE_GET_INDEXED_TRANSITION_BIT(mInputAssemblyAndColorBlendStateInfo, transition->set(ANGLE_GET_INDEXED_TRANSITION_BIT(mInputAssemblyAndColorBlendStateInfo,
colorWriteMaskBits, colorIndex, 4)); colorWriteMaskBits, colorIndexGL, 4));
} }
} }
...@@ -1238,7 +1310,7 @@ void DescriptorSetLayoutDesc::unpackBindings(DescriptorSetLayoutBindingVector *b ...@@ -1238,7 +1310,7 @@ void DescriptorSetLayoutDesc::unpackBindings(DescriptorSetLayoutBindingVector *b
binding.descriptorCount = packedBinding.count; binding.descriptorCount = packedBinding.count;
binding.descriptorType = static_cast<VkDescriptorType>(packedBinding.type); binding.descriptorType = static_cast<VkDescriptorType>(packedBinding.type);
binding.stageFlags = VK_SHADER_STAGE_ALL; binding.stageFlags = VK_SHADER_STAGE_ALL;
binding.pImmutableSamplers = nullptr; binding.pImmutableSamplers = nullptr;
bindings->push_back(binding); bindings->push_back(binding);
} }
...@@ -1339,21 +1411,24 @@ angle::Result RenderPassCache::addRenderPass(vk::Context *context, ...@@ -1339,21 +1411,24 @@ angle::Result RenderPassCache::addRenderPass(vk::Context *context,
// It would be nice to pre-populate the cache in the Renderer so we rarely miss here. // It would be nice to pre-populate the cache in the Renderer so we rarely miss here.
vk::AttachmentOpsArray ops; vk::AttachmentOpsArray ops;
for (uint32_t attachmentIndex = 0; attachmentIndex < desc.attachmentCount(); ++attachmentIndex) uint32_t colorAttachmentCount = 0;
for (uint32_t colorIndexGL = 0; colorIndexGL < desc.colorAttachmentRange(); ++colorIndexGL)
{ {
angle::FormatID formatID = desc[attachmentIndex]; if (!desc.isColorAttachmentEnabled(colorIndexGL))
ASSERT(formatID != angle::FormatID::NONE);
const vk::Format &format = context->getRenderer()->getFormat(formatID);
if (!format.angleFormat().hasDepthOrStencilBits())
{ {
ops.initDummyOp(attachmentIndex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, continue;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
}
else
{
ops.initDummyOp(attachmentIndex, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
} }
uint32_t colorIndexVk = colorAttachmentCount++;
ops.initDummyOp(colorIndexVk, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
}
if (desc.hasDepthStencilAttachment())
{
uint32_t depthStencilIndexVk = colorAttachmentCount;
ops.initDummyOp(depthStencilIndexVk, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
} }
return getRenderPassWithOps(context, serial, desc, ops, renderPassOut); return getRenderPassWithOps(context, serial, desc, ops, renderPassOut);
......
...@@ -56,12 +56,25 @@ class alignas(4) RenderPassDesc final ...@@ -56,12 +56,25 @@ class alignas(4) RenderPassDesc final
RenderPassDesc(const RenderPassDesc &other); RenderPassDesc(const RenderPassDesc &other);
RenderPassDesc &operator=(const RenderPassDesc &other); RenderPassDesc &operator=(const RenderPassDesc &other);
// The caller must pack the depth/stencil attachment last. // Set format for an enabled GL color attachment.
void packAttachment(const Format &format); void packColorAttachment(size_t colorIndexGL, angle::FormatID formatID);
// Mark a GL color attachment index as disabled.
void packColorAttachmentGap(size_t colorIndexGL);
// The caller must pack the depth/stencil attachment last, which is packed right after the color
// attachments (including gaps), i.e. with an index starting from |colorAttachmentRange()|.
void packDepthStencilAttachment(angle::FormatID angleFormatID);
size_t hash() const; size_t hash() const;
size_t colorAttachmentCount() const; // Color attachments are in [0, colorAttachmentRange()), with possible gaps.
size_t colorAttachmentRange() const { return mColorAttachmentRange; }
size_t depthStencilAttachmentIndex() const { return colorAttachmentRange(); }
bool isColorAttachmentEnabled(size_t colorIndexGL) const;
bool hasDepthStencilAttachment() const { return mHasDepthStencilAttachment; }
// Get the number of attachments in the Vulkan render pass, i.e. after removing disabled
// color attachments.
size_t attachmentCount() const; size_t attachmentCount() const;
void setSamples(GLint samples); void setSamples(GLint samples);
...@@ -76,8 +89,28 @@ class alignas(4) RenderPassDesc final ...@@ -76,8 +89,28 @@ class alignas(4) RenderPassDesc final
private: private:
uint8_t mSamples; uint8_t mSamples;
uint8_t mColorAttachmentCount : 4; uint8_t mColorAttachmentRange : 7;
uint8_t mDepthStencilAttachmentCount : 4; uint8_t mHasDepthStencilAttachment : 1;
// Color attachment formats are stored with their GL attachment indices. The depth/stencil
// attachment formats follow the last enabled color attachment. When creating a render pass,
// the disabled attachments are removed and the resulting attachments are packed.
//
// The attachment indices provided as input to various functions in this file are thus GL
// attachment indices. These indices are marked as such, e.g. colorIndexGL. The render pass
// (and corresponding framebuffer object) lists the packed attachments, with the corresponding
// indices marked with Vk, e.g. colorIndexVk. The subpass attachment references create the
// link between the two index spaces. The subpass declares attachment references with GL
// indices (which corresponds to the location decoration of shader outputs). The attachment
// references then contain the Vulkan indices or VK_ATTACHMENT_UNUSED.
//
// For example, if GL uses color attachments 0 and 3, then there are two render pass
// attachments (indexed 0 and 1) and 4 subpass attachments:
//
// - Subpass attachment 0 -> Renderpass attachment 0
// - Subpass attachment 1 -> VK_ATTACHMENT_UNUSED
// - Subpass attachment 2 -> VK_ATTACHMENT_UNUSED
// - Subpass attachment 3 -> Renderpass attachment 1
//
gl::AttachmentArray<uint8_t> mAttachmentFormats; gl::AttachmentArray<uint8_t> mAttachmentFormats;
}; };
...@@ -367,7 +400,7 @@ class GraphicsPipelineDesc final ...@@ -367,7 +400,7 @@ class GraphicsPipelineDesc final
const gl::BlendState &blendState); const gl::BlendState &blendState);
void setColorWriteMask(VkColorComponentFlags colorComponentFlags, void setColorWriteMask(VkColorComponentFlags colorComponentFlags,
const gl::DrawBufferMask &alphaMask); const gl::DrawBufferMask &alphaMask);
void setSingleColorWriteMask(uint32_t colorIndex, VkColorComponentFlags colorComponentFlags); void setSingleColorWriteMask(uint32_t colorIndexGL, VkColorComponentFlags colorComponentFlags);
void updateColorWriteMask(GraphicsPipelineTransitionBits *transition, void updateColorWriteMask(GraphicsPipelineTransitionBits *transition,
VkColorComponentFlags colorComponentFlags, VkColorComponentFlags colorComponentFlags,
const gl::DrawBufferMask &alphaMask); const gl::DrawBufferMask &alphaMask);
......
...@@ -43,6 +43,7 @@ void RendererVk::ensureCapsInitialized() const ...@@ -43,6 +43,7 @@ void RendererVk::ensureCapsInitialized() const
mNativeExtensions.mapBuffer = true; mNativeExtensions.mapBuffer = true;
mNativeExtensions.mapBufferRange = true; mNativeExtensions.mapBufferRange = true;
mNativeExtensions.textureStorage = true; mNativeExtensions.textureStorage = true;
mNativeExtensions.drawBuffers = true;
mNativeExtensions.framebufferBlit = true; mNativeExtensions.framebufferBlit = true;
mNativeExtensions.copyTexture = true; mNativeExtensions.copyTexture = true;
mNativeExtensions.copyCompressedTexture = true; mNativeExtensions.copyCompressedTexture = true;
...@@ -100,8 +101,6 @@ void RendererVk::ensureCapsInitialized() const ...@@ -100,8 +101,6 @@ void RendererVk::ensureCapsInitialized() const
// Vulkan natively supports standard derivatives // Vulkan natively supports standard derivatives
mNativeExtensions.standardDerivatives = true; mNativeExtensions.standardDerivatives = true;
// TODO(lucferron): Eventually remove everything above this line in this function as the caps
// get implemented.
// https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch31s02.html // https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch31s02.html
mNativeCaps.maxElementIndex = std::numeric_limits<GLuint>::max() - 1; mNativeCaps.maxElementIndex = std::numeric_limits<GLuint>::max() - 1;
mNativeCaps.max3DTextureSize = mPhysicalDeviceProperties.limits.maxImageDimension3D; mNativeCaps.max3DTextureSize = mPhysicalDeviceProperties.limits.maxImageDimension3D;
......
...@@ -532,10 +532,11 @@ ...@@ -532,10 +532,11 @@
// 3D texture (anglebug.com/3188), 2D array (anglebug.com/3189): // 3D texture (anglebug.com/3188), 2D array (anglebug.com/3189):
3189 VULKAN : dEQP-GLES3.functional.shaders.texture_functions.texturegrad.sampler2darrayshadow_vertex = SKIP 3189 VULKAN : dEQP-GLES3.functional.shaders.texture_functions.texturegrad.sampler2darrayshadow_vertex = SKIP
3189 VULKAN : dEQP-GLES3.functional.fbo.completeness.layer.2darr* = SKIP 3189 VULKAN : dEQP-GLES3.functional.fbo.completeness.layer.2darr* = SKIP
3189 VULKAN : dEQP-GLES3.functional.fbo.completeness.layer.* = SKIP 3188 VULKAN : dEQP-GLES3.functional.fbo.completeness.layer.3d* = SKIP
3189 VULKAN : dEQP-GLES3.functional.fbo.color.tex2darray.* = SKIP 3189 VULKAN : dEQP-GLES3.functional.fbo.color.tex2darray.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.fbo.color.tex3d.* = SKIP 3188 VULKAN : dEQP-GLES3.functional.fbo.color.tex3d.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.* = SKIP 3189 VULKAN : dEQP-GLES3.functional.texture.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.shaders.texture_functions.* = SKIP
// Multisampling: // Multisampling:
3204 VULKAN : dEQP-GLES3.functional.fbo.completeness.samples.* = SKIP 3204 VULKAN : dEQP-GLES3.functional.fbo.completeness.samples.* = SKIP
...@@ -546,6 +547,7 @@ ...@@ -546,6 +547,7 @@
3204 VULKAN : dEQP-GLES3.functional.state_query.rbo.renderbuffer_samples = SKIP 3204 VULKAN : dEQP-GLES3.functional.state_query.rbo.renderbuffer_samples = SKIP
3204 VULKAN : dEQP-GLES3.functional.fragment_out.* = SKIP 3204 VULKAN : dEQP-GLES3.functional.fragment_out.* = SKIP
3204 VULKAN : dEQP-GLES3.functional.rasterization.fbo.rbo_multisample* = SKIP 3204 VULKAN : dEQP-GLES3.functional.rasterization.fbo.rbo_multisample* = SKIP
3204 VULKAN : dEQP-GLES3.functional.shaders.derivate.* = SKIP
// Formats: // Formats:
2950 VULKAN : dEQP-GLES3.functional.fbo.completeness.renderable.renderbuffer.color0.rgba32f = FAIL 2950 VULKAN : dEQP-GLES3.functional.fbo.completeness.renderable.renderbuffer.color0.rgba32f = FAIL
...@@ -607,10 +609,36 @@ ...@@ -607,10 +609,36 @@
3194 VULKAN : dEQP-GLES3.functional.buffer.copy.* = SKIP 3194 VULKAN : dEQP-GLES3.functional.buffer.copy.* = SKIP
// Shader support: // Shader support:
3219 VULKAN : dEQP-GLES3.functional.shaders.* = SKIP
3219 VULKAN : dEQP-GLES3.functional.rasterization.flatshading.* = SKIP 3219 VULKAN : dEQP-GLES3.functional.rasterization.flatshading.* = SKIP
3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.link_program = FAIL 3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.link_program = FAIL
3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.use_program = FAIL 3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.use_program = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.constants.* = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.linkage.varying.* = SKIP
3219 VULKAN : dEQP-GLES3.functional.shaders.conversions.* = SKIP
3219 VULKAN : dEQP-GLES3.functional.shaders.functions.datatypes.* = SKIP
3219 VULKAN : dEQP-GLES3.functional.shaders.qualification_order.variables.valid.* = SKIP
3219 VULKAN : dEQP-GLES3.functional.shaders.matrix.* = SKIP
3219 VULKAN : dEQP-GLES3.functional.shaders.loops.while_dynamic_iterations.infinite_with_unconditional_break_first_vertex = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.loops.while_dynamic_iterations.infinite_with_unconditional_break_last_vertex = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.loops.do_while_dynamic_iterations.infinite_with_unconditional_break_first_vertex = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.loops.do_while_dynamic_iterations.infinite_with_unconditional_break_last_vertex = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.loops.for_dynamic_iterations.infinite_with_unconditional_break_first_vertex = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.loops.for_dynamic_iterations.infinite_with_unconditional_break_last_vertex = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.arrays.length.float_vertex = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.arrays.length.int_vertex = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.arrays.length.bool_vertex = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.arrays.length.struct_vertex = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.builtin* = SKIP
3219 VULKAN : dEQP-GLES3.functional.shaders.constant_expressions.builtin* = SKIP
3219 VULKAN : dEQP-GLES3.functional.shaders.indexing.uniform_array.* = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.invariance.* = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.precision.* = SKIP
3219 VULKAN : dEQP-GLES3.functional.shaders.random.conditionals.* = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.random.all_features.* = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.struct.local.parameter_* = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.struct.local.array_member_equality_vertex = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.struct.uniform.* = FAIL
3219 VULKAN : dEQP-GLES3.functional.shaders.operator.sequence.no_side_effects.* = FAIL
// New vertex attribute formats: // New vertex attribute formats:
3193 VULKAN : dEQP-GLES3.functional.vertex_arrays.single_attribute.strides.int2_10_10_10.* = SKIP 3193 VULKAN : dEQP-GLES3.functional.vertex_arrays.single_attribute.strides.int2_10_10_10.* = SKIP
...@@ -635,15 +663,6 @@ ...@@ -635,15 +663,6 @@
3193 VULKAN : dEQP-GLES3.functional.default_vertex_attrib.ivec* = SKIP 3193 VULKAN : dEQP-GLES3.functional.default_vertex_attrib.ivec* = SKIP
3193 VULKAN : dEQP-GLES3.functional.default_vertex_attrib.uint.* = SKIP 3193 VULKAN : dEQP-GLES3.functional.default_vertex_attrib.uint.* = SKIP
3193 VULKAN : dEQP-GLES3.functional.default_vertex_attrib.uvec* = SKIP 3193 VULKAN : dEQP-GLES3.functional.default_vertex_attrib.uvec* = SKIP
3193 VULKAN : dEQP-GLES3.functional.draw.draw_arrays_instanced.line_loop.* = SKIP
3193 VULKAN : dEQP-GLES3.functional.draw.draw_elements_instanced.line_loop.* = SKIP
3193 VULKAN : dEQP-GLES3.functional.draw.random.* = SKIP
3193 VULKAN : dEQP-GLES3.functional.draw.draw_elements.indices.user_ptr.index_int = FAIL
3193 VULKAN : dEQP-GLES3.functional.draw.draw_elements.indices.unaligned_user_ptr.index_int = FAIL
3193 VULKAN : dEQP-GLES3.functional.draw.draw_elements_instanced.indices.user_ptr.index_int = FAIL
3193 VULKAN : dEQP-GLES3.functional.draw.draw_elements_instanced.indices.unaligned_user_ptr.index_int = FAIL
3193 VULKAN : dEQP-GLES3.functional.negative_api.vertex_array.draw_range_elements = FAIL
3193 VULKAN : dEQP-GLES3.functional.negative_api.vertex_array.draw_range_elements_incomplete_primitive = FAIL
// Polygon offset: // Polygon offset:
2950 VULKAN : dEQP-GLES3.functional.polygon_offset.float32_result_depth_clamp = FAIL 2950 VULKAN : dEQP-GLES3.functional.polygon_offset.float32_result_depth_clamp = FAIL
...@@ -657,18 +676,20 @@ ...@@ -657,18 +676,20 @@
2950 VULKAN : dEQP-GLES3.functional.uniform_api.random.* = SKIP 2950 VULKAN : dEQP-GLES3.functional.uniform_api.random.* = SKIP
// Transform feedback: // Transform feedback:
2950 VULKAN : dEQP-GLES3.functional.negative_api.shader.uniform_block_binding = FAIL 3205 VULKAN : dEQP-GLES3.functional.negative_api.shader.uniform_block_binding = FAIL
2950 VULKAN : dEQP-GLES3.functional.negative_api.shader.bind_transform_feedback = FAIL 3205 VULKAN : dEQP-GLES3.functional.negative_api.shader.bind_transform_feedback = FAIL
2950 VULKAN : dEQP-GLES3.functional.negative_api.shader.begin_transform_feedback = FAIL 3205 VULKAN : dEQP-GLES3.functional.negative_api.shader.begin_transform_feedback = FAIL
2950 VULKAN : dEQP-GLES3.functional.negative_api.shader.pause_transform_feedback = FAIL 3205 VULKAN : dEQP-GLES3.functional.negative_api.shader.pause_transform_feedback = FAIL
2950 VULKAN : dEQP-GLES3.functional.negative_api.shader.resume_transform_feedback = FAIL 3205 VULKAN : dEQP-GLES3.functional.negative_api.shader.resume_transform_feedback = FAIL
2950 VULKAN : dEQP-GLES3.functional.negative_api.shader.end_transform_feedback = FAIL 3205 VULKAN : dEQP-GLES3.functional.negative_api.shader.end_transform_feedback = FAIL
2950 VULKAN : dEQP-GLES3.functional.transform_feedback.* = FAIL 3205 VULKAN : dEQP-GLES3.functional.transform_feedback.* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.boolean.transform_feedback_* = FAIL 3205 VULKAN : dEQP-GLES3.functional.state_query.boolean.transform_feedback_* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.integers.max_transform_feedback_* = FAIL 3205 VULKAN : dEQP-GLES3.functional.state_query.integers.max_transform_feedback_* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.integers.transform_feedback_* = FAIL 3205 VULKAN : dEQP-GLES3.functional.state_query.integers.transform_feedback_* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.indexed.transform_feedback_* = FAIL 3205 VULKAN : dEQP-GLES3.functional.state_query.indexed.transform_feedback_* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.shader.transform_feedback = FAIL 3205 VULKAN : dEQP-GLES3.functional.state_query.shader.transform_feedback = FAIL
3205 VULKAN : dEQP-GLES3.functional.negative_api.vertex_array.draw_range_elements = FAIL
3205 VULKAN : dEQP-GLES3.functional.negative_api.vertex_array.draw_range_elements_incomplete_primitive = FAIL
// Misc unimplemented: // Misc unimplemented:
...@@ -712,6 +733,11 @@ ...@@ -712,6 +733,11 @@
2950 VULKAN : dEQP-GLES3.functional.clipping.point.wide_point_clip_viewport_corner = FAIL 2950 VULKAN : dEQP-GLES3.functional.clipping.point.wide_point_clip_viewport_corner = FAIL
2950 VULKAN : dEQP-GLES3.functional.clipping.point.point_clip_viewport_center = FAIL 2950 VULKAN : dEQP-GLES3.functional.clipping.point.point_clip_viewport_center = FAIL
2950 VULKAN : dEQP-GLES3.functional.clipping.point.point_clip_viewport_corner = FAIL 2950 VULKAN : dEQP-GLES3.functional.clipping.point.point_clip_viewport_corner = FAIL
2672 VULKAN : dEQP-GLES3.functional.draw.draw_arrays_instanced.line_loop.* = SKIP
2672 VULKAN : dEQP-GLES3.functional.draw.draw_elements_instanced.line_loop.* = SKIP
2672 VULKAN : dEQP-GLES3.functional.draw.random.* = SKIP
3199 VULKAN : dEQP-GLES3.functional.shaders.linkage.uniform.block.layout_qualifier_mismatch_1 = FAIL
3199 VULKAN : dEQP-GLES3.functional.shaders.linkage.uniform.block.layout_qualifier_mismatch_2 = FAIL
// To be triaged: // To be triaged:
2950 VULKAN : dEQP-GLES3.functional.fragment_ops.interaction.basic_shader.* = SKIP 2950 VULKAN : dEQP-GLES3.functional.fragment_ops.interaction.basic_shader.* = SKIP
...@@ -723,6 +749,10 @@ ...@@ -723,6 +749,10 @@
2950 VULKAN : dEQP-GLES3.functional.negative_api.state.get_uniform* = SKIP 2950 VULKAN : dEQP-GLES3.functional.negative_api.state.get_uniform* = SKIP
2950 VULKAN : dEQP-GLES3.functional.negative_api.state.get_active_unifor* = SKIP 2950 VULKAN : dEQP-GLES3.functional.negative_api.state.get_active_unifor* = SKIP
2950 VULKAN : dEQP-GLES3.functional.negative_api.state.get_active_attrib = SKIP 2950 VULKAN : dEQP-GLES3.functional.negative_api.state.get_active_attrib = SKIP
2950 VULKAN : dEQP-GLES3.functional.draw.draw_elements.indices.user_ptr.index_int = FAIL
2950 VULKAN : dEQP-GLES3.functional.draw.draw_elements.indices.unaligned_user_ptr.index_int = FAIL
2950 VULKAN : dEQP-GLES3.functional.draw.draw_elements_instanced.indices.user_ptr.index_int = FAIL
2950 VULKAN : dEQP-GLES3.functional.draw.draw_elements_instanced.indices.unaligned_user_ptr.index_int = FAIL
// Android Vulkan failures // Android Vulkan failures
2950 ANDROID VULKAN : dEQP-GLES3.functional.implementation_limits.max_combined_texture_image_units = FAIL 2950 ANDROID VULKAN : dEQP-GLES3.functional.implementation_limits.max_combined_texture_image_units = FAIL
......
...@@ -256,6 +256,10 @@ TEST_P(DrawBuffersTest, Gaps) ...@@ -256,6 +256,10 @@ TEST_P(DrawBuffersTest, Gaps)
// TODO(ynovikov): Investigate the failure (http://anglebug.com/1535) // TODO(ynovikov): Investigate the failure (http://anglebug.com/1535)
ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL()); ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
// TODO(syoussefi): Qualcomm driver crashes in the presence of VK_ATTACHMENT_UNUSED.
// http://anglebug.com/3423
ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
glBindTexture(GL_TEXTURE_2D, mTextures[0]); glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mTextures[0], 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mTextures[0], 0);
...@@ -280,6 +284,10 @@ TEST_P(DrawBuffersTest, FirstAndLast) ...@@ -280,6 +284,10 @@ TEST_P(DrawBuffersTest, FirstAndLast)
// TODO(ynovikov): Investigate the failure (https://anglebug.com/1533) // TODO(ynovikov): Investigate the failure (https://anglebug.com/1533)
ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL()); ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
// TODO(syoussefi): Qualcomm driver crashes in the presence of VK_ATTACHMENT_UNUSED.
// http://anglebug.com/3423
ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
glBindTexture(GL_TEXTURE_2D, mTextures[0]); glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
...@@ -311,6 +319,10 @@ TEST_P(DrawBuffersTest, FirstHalfNULL) ...@@ -311,6 +319,10 @@ TEST_P(DrawBuffersTest, FirstHalfNULL)
// TODO(ynovikov): Investigate the failure (https://anglebug.com/1533) // TODO(ynovikov): Investigate the failure (https://anglebug.com/1533)
ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL()); ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
// TODO(syoussefi): Qualcomm driver crashes in the presence of VK_ATTACHMENT_UNUSED.
// http://anglebug.com/3423
ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
bool flags[8] = {false}; bool flags[8] = {false};
GLenum bufs[8] = {GL_NONE}; GLenum bufs[8] = {GL_NONE};
...@@ -364,6 +376,10 @@ TEST_P(DrawBuffersWebGL2Test, TwoProgramsWithDifferentOutputsAndClear) ...@@ -364,6 +376,10 @@ TEST_P(DrawBuffersWebGL2Test, TwoProgramsWithDifferentOutputsAndClear)
// TODO(ynovikov): Investigate the failure (https://anglebug.com/1533) // TODO(ynovikov): Investigate the failure (https://anglebug.com/1533)
ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL()); ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsDesktopOpenGL());
// TODO(syoussefi): Qualcomm driver crashes in the presence of VK_ATTACHMENT_UNUSED.
// http://anglebug.com/3423
ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
ANGLE_SKIP_TEST_IF(!setupTest()); ANGLE_SKIP_TEST_IF(!setupTest());
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &mMaxDrawBuffers); glGetIntegerv(GL_MAX_DRAW_BUFFERS, &mMaxDrawBuffers);
...@@ -611,8 +627,9 @@ ANGLE_INSTANTIATE_TEST(DrawBuffersTest, ...@@ -611,8 +627,9 @@ ANGLE_INSTANTIATE_TEST(DrawBuffersTest,
ES3_OPENGL(), ES3_OPENGL(),
ES2_OPENGLES(), ES2_OPENGLES(),
ES3_OPENGLES(), ES3_OPENGLES(),
ES2_VULKAN()); ES2_VULKAN(),
ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(DrawBuffersWebGL2Test, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(DrawBuffersWebGL2Test, ES3_D3D11(), ES3_OPENGL(), ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(DrawBuffersTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); ANGLE_INSTANTIATE_TEST(DrawBuffersTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
...@@ -2843,6 +2843,9 @@ TEST_P(WebGLCompatibilityTest, RG32FTextures) ...@@ -2843,6 +2843,9 @@ TEST_P(WebGLCompatibilityTest, RG32FTextures)
TEST_P(WebGLCompatibilityTest, RGB32FTextures) TEST_P(WebGLCompatibilityTest, RGB32FTextures)
{ {
// TODO(syoussefi): Missing format support. http://anglebug.com/2898
ANGLE_SKIP_TEST_IF(IsVulkan());
ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel()); ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel());
constexpr float data[] = {1000.0f, -500.0f, 10.0f, 1.0f}; constexpr float data[] = {1000.0f, -500.0f, 10.0f, 1.0f};
...@@ -2879,6 +2882,9 @@ TEST_P(WebGLCompatibilityTest, RGB32FTextures) ...@@ -2879,6 +2882,9 @@ TEST_P(WebGLCompatibilityTest, RGB32FTextures)
TEST_P(WebGLCompatibilityTest, RGBA32FTextures) TEST_P(WebGLCompatibilityTest, RGBA32FTextures)
{ {
// TODO(syoussefi): Missing format support. http://anglebug.com/2898
ANGLE_SKIP_TEST_IF(IsVulkan());
constexpr float data[] = {7000.0f, 100.0f, 33.0f, -1.0f}; constexpr float data[] = {7000.0f, 100.0f, 33.0f, -1.0f};
for (auto extension : FloatingPointTextureExtensions) for (auto extension : FloatingPointTextureExtensions)
...@@ -3254,6 +3260,9 @@ TEST_P(WebGLCompatibilityTest, RG16FTextures) ...@@ -3254,6 +3260,9 @@ TEST_P(WebGLCompatibilityTest, RG16FTextures)
TEST_P(WebGLCompatibilityTest, RGB16FTextures) TEST_P(WebGLCompatibilityTest, RGB16FTextures)
{ {
// TODO(syoussefi): Missing format support. http://anglebug.com/2898
ANGLE_SKIP_TEST_IF(IsVulkan());
ANGLE_SKIP_TEST_IF(IsOzone() && IsIntel()); ANGLE_SKIP_TEST_IF(IsOzone() && IsIntel());
constexpr float readPixelsData[] = {7000.0f, 100.0f, 33.0f, 1.0f}; constexpr float readPixelsData[] = {7000.0f, 100.0f, 33.0f, 1.0f};
...@@ -4234,6 +4243,10 @@ void main() ...@@ -4234,6 +4243,10 @@ void main()
} }
} }
// TODO(syoussefi): Qualcomm driver crashes in the presence of VK_ATTACHMENT_UNUSED.
// http://anglebug.com/3423
ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
// Test that attachments written to get the correct color from shader output but that even when // Test that attachments written to get the correct color from shader output but that even when
// the extension is used, disabled attachments are not written at all and stay red. // the extension is used, disabled attachments are not written at all and stay red.
{ {
...@@ -4625,7 +4638,8 @@ ANGLE_INSTANTIATE_TEST(WebGLCompatibilityTest, ...@@ -4625,7 +4638,8 @@ ANGLE_INSTANTIATE_TEST(WebGLCompatibilityTest,
ES3_OPENGL(), ES3_OPENGL(),
ES2_OPENGLES(), ES2_OPENGLES(),
ES3_OPENGLES(), ES3_OPENGLES(),
ES2_VULKAN()); ES2_VULKAN(),
ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(WebGL2CompatibilityTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); ANGLE_INSTANTIATE_TEST(WebGL2CompatibilityTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
} // namespace angle } // namespace angle
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