Commit f776eb9c by Shahbaz Youssefi Committed by Commit Bot

Vulkan: EXT_multisampled_render_to_texture2 support

The previous change that implemented EXT_multisampled_render_to_texture already provisioned this extension in the Vulkan backend. This change implements the front-end for this extension and enables it in the Vulkan backend. Bug: angleproject:4836 Change-Id: I7080260972e61727c5716051c236f635668cb67b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2330510 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com>
parent 47207e42
......@@ -1576,37 +1576,34 @@ angle::Result Framebuffer::blit(const Context *context,
int Framebuffer::getSamples(const Context *context) const
{
return (isComplete(context) ? getCachedSamples(context, AttachmentSampleType::Emulated) : 0);
}
int Framebuffer::getResourceSamples(const Context *context) const
{
return (isComplete(context) ? getCachedSamples(context, AttachmentSampleType::Resource) : 0);
}
if (!isComplete(context))
{
return 0;
}
int Framebuffer::getCachedSamples(const Context *context, AttachmentSampleType sampleType) const
{
ASSERT(mCachedStatus.valid() && mCachedStatus.value() == GL_FRAMEBUFFER_COMPLETE);
// For a complete framebuffer, all attachments must have the same sample count.
// In this case return the first nonzero sample size.
const auto *firstNonNullAttachment = mState.getFirstNonNullAttachment();
if (firstNonNullAttachment)
const FramebufferAttachment *firstNonNullAttachment = mState.getFirstNonNullAttachment();
ASSERT(firstNonNullAttachment == nullptr || firstNonNullAttachment->isAttached());
return firstNonNullAttachment ? firstNonNullAttachment->getSamples() : 0;
}
int Framebuffer::getReadBufferResourceSamples(const Context *context) const
{
if (!isComplete(context))
{
ASSERT(firstNonNullAttachment->isAttached());
if (sampleType == AttachmentSampleType::Resource)
{
return firstNonNullAttachment->getResourceSamples();
}
else
{
ASSERT(sampleType == AttachmentSampleType::Emulated);
return firstNonNullAttachment->getSamples();
}
return 0;
}
// No attachments found.
return 0;
ASSERT(mCachedStatus.valid() && mCachedStatus.value() == GL_FRAMEBUFFER_COMPLETE);
const FramebufferAttachment *readAttachment = mState.getReadAttachment();
ASSERT(readAttachment == nullptr || readAttachment->isAttached());
return readAttachment ? readAttachment->getResourceSamples() : 0;
}
angle::Result Framebuffer::getSamplePosition(const Context *context,
......
......@@ -49,15 +49,6 @@ class State;
class Texture;
class TextureCapsMap;
enum class AttachmentSampleType
{
// The sample count of the actual resource
Resource,
// If render_to_texture is used, this is the sample count of the multisampled
// texture that is created behind the scenes.
Emulated
};
class FramebufferState final : angle::NonCopyable
{
public:
......@@ -278,7 +269,7 @@ class Framebuffer final : public angle::ObserverInterface,
// This method calls checkStatus.
int getSamples(const Context *context) const;
int getResourceSamples(const Context *context) const;
int getReadBufferResourceSamples(const Context *context) const;
angle::Result getSamplePosition(const Context *context, size_t index, GLfloat *xy) const;
......@@ -309,9 +300,6 @@ class Framebuffer final : public angle::ObserverInterface,
return checkStatusImpl(context);
}
// For when we don't want to check completeness in getSamples().
int getCachedSamples(const Context *context, AttachmentSampleType sampleType) const;
// Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE.
ANGLE_INLINE bool isComplete(const Context *context) const
{
......
......@@ -2142,7 +2142,13 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
VkAttachmentStoreOp depthStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
VkAttachmentStoreOp stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
if (!depthStencilRenderTarget->hasDefinedContent())
// If the image data was previously discarded (with no update in between), don't attempt to
// load the image. Additionally, if the multisampled image data is transient and there is
// no resolve attachment, there's no data to load. The latter is the case with
// depth/stencil texture attachments per GL_EXT_multisampled_render_to_texture2.
if (!depthStencilRenderTarget->hasDefinedContent() ||
(depthStencilRenderTarget->isImageTransient() &&
!depthStencilRenderTarget->hasResolveAttachment()))
{
depthLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
......
......@@ -76,18 +76,19 @@ void RendererVk::ensureCapsInitialized() const
// Enable this for simple buffer readback testing, but some functionality is missing.
// TODO(jmadill): Support full mapBufferRange extension.
mNativeExtensions.mapBufferOES = true;
mNativeExtensions.mapBufferRange = true;
mNativeExtensions.textureStorage = true;
mNativeExtensions.drawBuffers = true;
mNativeExtensions.fragDepth = true;
mNativeExtensions.framebufferBlit = true;
mNativeExtensions.framebufferMultisample = true;
mNativeExtensions.multisampledRenderToTexture = true;
mNativeExtensions.copyTexture = true;
mNativeExtensions.copyTexture3d = true;
mNativeExtensions.copyCompressedTexture = true;
mNativeExtensions.debugMarker = true;
mNativeExtensions.mapBufferOES = true;
mNativeExtensions.mapBufferRange = true;
mNativeExtensions.textureStorage = true;
mNativeExtensions.drawBuffers = true;
mNativeExtensions.fragDepth = true;
mNativeExtensions.framebufferBlit = true;
mNativeExtensions.framebufferMultisample = true;
mNativeExtensions.multisampledRenderToTexture = true;
mNativeExtensions.multisampledRenderToTexture2 = true;
mNativeExtensions.copyTexture = true;
mNativeExtensions.copyTexture3d = true;
mNativeExtensions.copyCompressedTexture = true;
mNativeExtensions.debugMarker = true;
mNativeExtensions.robustness =
!IsSwiftshader(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID) &&
!IsARM(mPhysicalDeviceProperties.vendorID);
......
......@@ -1414,7 +1414,7 @@ bool ValidateBlitFramebufferParameters(const Context *context,
}
// Not allow blitting to MS buffers, therefore if renderToTextureSamples exist,
// consider it MS. needResourceSamples = false
// consider it MS. checkReadBufferResourceSamples = false
if (!ValidateFramebufferNotMultisampled(context, drawFramebuffer, false))
{
return false;
......@@ -2596,8 +2596,8 @@ bool ValidateCopyTexImageParametersBase(const Context *context,
return false;
}
// needResourceSamples = true. Treat renderToTexture textures as single sample since they will
// be resolved before copying
// checkReadBufferResourceSamples = true. Treat renderToTexture textures as single sample since
// they will be resolved before copying.
if (!readFramebuffer->isDefault() &&
!ValidateFramebufferNotMultisampled(context, readFramebuffer, true))
{
......@@ -6632,10 +6632,11 @@ bool ValidateGetInternalFormativBase(const Context *context,
bool ValidateFramebufferNotMultisampled(const Context *context,
const Framebuffer *framebuffer,
bool needResourceSamples)
bool checkReadBufferResourceSamples)
{
int samples = needResourceSamples ? framebuffer->getResourceSamples(context)
: framebuffer->getSamples(context);
int samples = checkReadBufferResourceSamples
? framebuffer->getReadBufferResourceSamples(context)
: framebuffer->getSamples(context);
if (samples != 0)
{
context->validationError(GL_INVALID_OPERATION, kInvalidMultisampledFramebufferOperation);
......
......@@ -650,7 +650,7 @@ bool ValidateGetInternalFormativBase(const Context *context,
bool ValidateFramebufferNotMultisampled(const Context *context,
const Framebuffer *framebuffer,
bool needResourceSamples);
bool checkReadBufferResourceSamples);
bool ValidateMultitextureUnit(const Context *context, GLenum texture);
......
......@@ -6713,7 +6713,9 @@ bool ValidateFramebufferTexture2DMultisampleEXT(const Context *context,
return false;
}
if (attachment != GL_COLOR_ATTACHMENT0)
// Unless EXT_multisampled_render_to_texture2 is enabled, only color attachment 0 can be used.
if (!context->getExtensions().multisampledRenderToTexture2 &&
attachment != GL_COLOR_ATTACHMENT0)
{
context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
return false;
......
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