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, ...@@ -1576,37 +1576,34 @@ angle::Result Framebuffer::blit(const Context *context,
int Framebuffer::getSamples(const Context *context) const int Framebuffer::getSamples(const Context *context) const
{ {
return (isComplete(context) ? getCachedSamples(context, AttachmentSampleType::Emulated) : 0); if (!isComplete(context))
} {
return 0;
int Framebuffer::getResourceSamples(const Context *context) const }
{
return (isComplete(context) ? getCachedSamples(context, AttachmentSampleType::Resource) : 0);
}
int Framebuffer::getCachedSamples(const Context *context, AttachmentSampleType sampleType) const
{
ASSERT(mCachedStatus.valid() && mCachedStatus.value() == GL_FRAMEBUFFER_COMPLETE); ASSERT(mCachedStatus.valid() && mCachedStatus.value() == GL_FRAMEBUFFER_COMPLETE);
// For a complete framebuffer, all attachments must have the same sample count. // For a complete framebuffer, all attachments must have the same sample count.
// In this case return the first nonzero sample size. // In this case return the first nonzero sample size.
const auto *firstNonNullAttachment = mState.getFirstNonNullAttachment(); const FramebufferAttachment *firstNonNullAttachment = mState.getFirstNonNullAttachment();
if (firstNonNullAttachment) ASSERT(firstNonNullAttachment == nullptr || firstNonNullAttachment->isAttached());
return firstNonNullAttachment ? firstNonNullAttachment->getSamples() : 0;
}
int Framebuffer::getReadBufferResourceSamples(const Context *context) const
{
if (!isComplete(context))
{ {
ASSERT(firstNonNullAttachment->isAttached()); return 0;
if (sampleType == AttachmentSampleType::Resource)
{
return firstNonNullAttachment->getResourceSamples();
}
else
{
ASSERT(sampleType == AttachmentSampleType::Emulated);
return firstNonNullAttachment->getSamples();
}
} }
// No attachments found. ASSERT(mCachedStatus.valid() && mCachedStatus.value() == GL_FRAMEBUFFER_COMPLETE);
return 0;
const FramebufferAttachment *readAttachment = mState.getReadAttachment();
ASSERT(readAttachment == nullptr || readAttachment->isAttached());
return readAttachment ? readAttachment->getResourceSamples() : 0;
} }
angle::Result Framebuffer::getSamplePosition(const Context *context, angle::Result Framebuffer::getSamplePosition(const Context *context,
......
...@@ -49,15 +49,6 @@ class State; ...@@ -49,15 +49,6 @@ class State;
class Texture; class Texture;
class TextureCapsMap; 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 class FramebufferState final : angle::NonCopyable
{ {
public: public:
...@@ -278,7 +269,7 @@ class Framebuffer final : public angle::ObserverInterface, ...@@ -278,7 +269,7 @@ class Framebuffer final : public angle::ObserverInterface,
// This method calls checkStatus. // This method calls checkStatus.
int getSamples(const Context *context) const; 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; angle::Result getSamplePosition(const Context *context, size_t index, GLfloat *xy) const;
...@@ -309,9 +300,6 @@ class Framebuffer final : public angle::ObserverInterface, ...@@ -309,9 +300,6 @@ class Framebuffer final : public angle::ObserverInterface,
return checkStatusImpl(context); 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. // Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE.
ANGLE_INLINE bool isComplete(const Context *context) const ANGLE_INLINE bool isComplete(const Context *context) const
{ {
......
...@@ -2142,7 +2142,13 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, ...@@ -2142,7 +2142,13 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
VkAttachmentStoreOp depthStoreOp = VK_ATTACHMENT_STORE_OP_STORE; VkAttachmentStoreOp depthStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
VkAttachmentStoreOp stencilStoreOp = 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; depthLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
......
...@@ -76,18 +76,19 @@ void RendererVk::ensureCapsInitialized() const ...@@ -76,18 +76,19 @@ void RendererVk::ensureCapsInitialized() const
// Enable this for simple buffer readback testing, but some functionality is missing. // Enable this for simple buffer readback testing, but some functionality is missing.
// TODO(jmadill): Support full mapBufferRange extension. // TODO(jmadill): Support full mapBufferRange extension.
mNativeExtensions.mapBufferOES = true; mNativeExtensions.mapBufferOES = true;
mNativeExtensions.mapBufferRange = true; mNativeExtensions.mapBufferRange = true;
mNativeExtensions.textureStorage = true; mNativeExtensions.textureStorage = true;
mNativeExtensions.drawBuffers = true; mNativeExtensions.drawBuffers = true;
mNativeExtensions.fragDepth = true; mNativeExtensions.fragDepth = true;
mNativeExtensions.framebufferBlit = true; mNativeExtensions.framebufferBlit = true;
mNativeExtensions.framebufferMultisample = true; mNativeExtensions.framebufferMultisample = true;
mNativeExtensions.multisampledRenderToTexture = true; mNativeExtensions.multisampledRenderToTexture = true;
mNativeExtensions.copyTexture = true; mNativeExtensions.multisampledRenderToTexture2 = true;
mNativeExtensions.copyTexture3d = true; mNativeExtensions.copyTexture = true;
mNativeExtensions.copyCompressedTexture = true; mNativeExtensions.copyTexture3d = true;
mNativeExtensions.debugMarker = true; mNativeExtensions.copyCompressedTexture = true;
mNativeExtensions.debugMarker = true;
mNativeExtensions.robustness = mNativeExtensions.robustness =
!IsSwiftshader(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID) && !IsSwiftshader(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID) &&
!IsARM(mPhysicalDeviceProperties.vendorID); !IsARM(mPhysicalDeviceProperties.vendorID);
......
...@@ -1414,7 +1414,7 @@ bool ValidateBlitFramebufferParameters(const Context *context, ...@@ -1414,7 +1414,7 @@ bool ValidateBlitFramebufferParameters(const Context *context,
} }
// Not allow blitting to MS buffers, therefore if renderToTextureSamples exist, // 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)) if (!ValidateFramebufferNotMultisampled(context, drawFramebuffer, false))
{ {
return false; return false;
...@@ -2596,8 +2596,8 @@ bool ValidateCopyTexImageParametersBase(const Context *context, ...@@ -2596,8 +2596,8 @@ bool ValidateCopyTexImageParametersBase(const Context *context,
return false; return false;
} }
// needResourceSamples = true. Treat renderToTexture textures as single sample since they will // checkReadBufferResourceSamples = true. Treat renderToTexture textures as single sample since
// be resolved before copying // they will be resolved before copying.
if (!readFramebuffer->isDefault() && if (!readFramebuffer->isDefault() &&
!ValidateFramebufferNotMultisampled(context, readFramebuffer, true)) !ValidateFramebufferNotMultisampled(context, readFramebuffer, true))
{ {
...@@ -6632,10 +6632,11 @@ bool ValidateGetInternalFormativBase(const Context *context, ...@@ -6632,10 +6632,11 @@ bool ValidateGetInternalFormativBase(const Context *context,
bool ValidateFramebufferNotMultisampled(const Context *context, bool ValidateFramebufferNotMultisampled(const Context *context,
const Framebuffer *framebuffer, const Framebuffer *framebuffer,
bool needResourceSamples) bool checkReadBufferResourceSamples)
{ {
int samples = needResourceSamples ? framebuffer->getResourceSamples(context) int samples = checkReadBufferResourceSamples
: framebuffer->getSamples(context); ? framebuffer->getReadBufferResourceSamples(context)
: framebuffer->getSamples(context);
if (samples != 0) if (samples != 0)
{ {
context->validationError(GL_INVALID_OPERATION, kInvalidMultisampledFramebufferOperation); context->validationError(GL_INVALID_OPERATION, kInvalidMultisampledFramebufferOperation);
......
...@@ -650,7 +650,7 @@ bool ValidateGetInternalFormativBase(const Context *context, ...@@ -650,7 +650,7 @@ bool ValidateGetInternalFormativBase(const Context *context,
bool ValidateFramebufferNotMultisampled(const Context *context, bool ValidateFramebufferNotMultisampled(const Context *context,
const Framebuffer *framebuffer, const Framebuffer *framebuffer,
bool needResourceSamples); bool checkReadBufferResourceSamples);
bool ValidateMultitextureUnit(const Context *context, GLenum texture); bool ValidateMultitextureUnit(const Context *context, GLenum texture);
......
...@@ -6713,7 +6713,9 @@ bool ValidateFramebufferTexture2DMultisampleEXT(const Context *context, ...@@ -6713,7 +6713,9 @@ bool ValidateFramebufferTexture2DMultisampleEXT(const Context *context,
return false; 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); context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
return false; 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