Commit bddc46b4 by JiangYizhou Committed by Commit Bot

ES31: Implement multisampled Textures.

Implement TexStorage2DMultisample and getMultisamplefv entry point. Also modify sample state for Textures and Framebuffers. BUG=angleproject:1590 TEST=angle_unittests TEST=angle_end2end_tests TEST=dEQP-GLES31.functional.texture.multisample.samples_*.sample_position TEST=dEQP-GLES31.functional.texture.multisample.samples_*.use_texture_color_2d TEST=dEQP-GLES31.functional.texture.multisample.samples_*.use_texture_depth_2d TEST=dEQP-GLES31.functional.texture.multisample.negative.fbo_attach_different_sample_count_tex_tex TEST=dEQP-GLES31.functional.texture.multisample.negative.fbo_attach_different_sample_count_tex_rbo TEST=dEQP-GLES31.functional.texture.multisample.negative.fbo_attach_non_zero_level TEST=dEQP-GLES31.functional.texture.multisample.negative.texture_high_sample_count TEST=dEQP-GLES31.functional.texture.multisample.negative.texture_zero_sample_count TEST=dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_1_texture_2d TEST=dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_4_texture_2d Change-Id: I8fa7bd4e73b95745858a3e16b1b92004b4a18712 Reviewed-on: https://chromium-review.googlesource.com/414309 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarYunchao He <yunchao.he@intel.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 0aff35eb
...@@ -2725,6 +2725,11 @@ void Context::framebufferTexture2D(GLenum target, ...@@ -2725,6 +2725,11 @@ void Context::framebufferTexture2D(GLenum target,
{ {
index = ImageIndex::Make2D(level); index = ImageIndex::Make2D(level);
} }
else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
{
ASSERT(level == 0);
index = ImageIndex::Make2DMultisample();
}
else else
{ {
ASSERT(IsCubeMapTextureTarget(textarget)); ASSERT(IsCubeMapTextureTarget(textarget));
...@@ -3704,4 +3709,32 @@ void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer) ...@@ -3704,4 +3709,32 @@ void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
mGLState.setRenderbufferBinding(object); mGLState.setRenderbufferBinding(object);
} }
void Context::texStorage2DMultisample(GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height,
GLboolean fixedsamplelocations)
{
Extents size(width, height, 1);
Texture *texture = getTargetTexture(target);
handleError(texture->setStorageMultisample(target, samples, internalformat, size,
fixedsamplelocations));
}
void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
{
mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
switch (pname)
{
case GL_SAMPLE_POSITION:
handleError(framebuffer->getSamplePosition(index, val));
break;
default:
UNREACHABLE();
}
}
} // namespace gl } // namespace gl
...@@ -582,6 +582,15 @@ class Context final : public ValidationContext ...@@ -582,6 +582,15 @@ class Context final : public ValidationContext
void bindFramebuffer(GLenum target, GLuint framebuffer); void bindFramebuffer(GLenum target, GLuint framebuffer);
void bindRenderbuffer(GLenum target, GLuint renderbuffer); void bindRenderbuffer(GLenum target, GLuint renderbuffer);
void texStorage2DMultisample(GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height,
GLboolean fixedsamplelocations);
void getMultisamplefv(GLenum pname, GLuint index, GLfloat *val);
void copyBufferSubData(GLenum readTarget, void copyBufferSubData(GLenum readTarget,
GLenum writeTarget, GLenum writeTarget,
GLintptr readOffset, GLintptr readOffset,
......
...@@ -242,6 +242,12 @@ size_t FramebufferState::getDrawBufferCount() const ...@@ -242,6 +242,12 @@ size_t FramebufferState::getDrawBufferCount() const
return mDrawBufferStates.size(); return mDrawBufferStates.size();
} }
Error Framebuffer::getSamplePosition(size_t index, GLfloat *xy) const
{
ANGLE_TRY(mImpl->getSamplePosition(index, xy));
return gl::NoError();
}
bool FramebufferState::colorAttachmentsAreUniqueImages() const bool FramebufferState::colorAttachmentsAreUniqueImages() const
{ {
for (size_t firstAttachmentIdx = 0; firstAttachmentIdx < mColorAttachments.size(); for (size_t firstAttachmentIdx = 0; firstAttachmentIdx < mColorAttachments.size();
......
...@@ -149,6 +149,9 @@ class Framebuffer final : public LabeledObject, public angle::SignalReceiver ...@@ -149,6 +149,9 @@ class Framebuffer final : public LabeledObject, public angle::SignalReceiver
// This method calls checkStatus. // This method calls checkStatus.
int getSamples(const ContextState &state); int getSamples(const ContextState &state);
Error getSamplePosition(size_t index, GLfloat *xy) const;
GLenum checkStatus(const ContextState &state); GLenum checkStatus(const ContextState &state);
// Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE. // Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE.
......
#include "ImageIndex.h"
// //
// Copyright 2014 The ANGLE Project Authors. All rights reserved. // Copyright 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
...@@ -62,6 +63,11 @@ ImageIndex ImageIndex::MakeGeneric(GLenum target, GLint mipIndex) ...@@ -62,6 +63,11 @@ ImageIndex ImageIndex::MakeGeneric(GLenum target, GLint mipIndex)
return ImageIndex(target, mipIndex, layerIndex); return ImageIndex(target, mipIndex, layerIndex);
} }
ImageIndex ImageIndex::Make2DMultisample()
{
return ImageIndex(GL_TEXTURE_2D_MULTISAMPLE, 0, ENTIRE_LEVEL);
}
ImageIndex ImageIndex::MakeInvalid() ImageIndex ImageIndex::MakeInvalid()
{ {
return ImageIndex(GL_NONE, -1, -1); return ImageIndex(GL_NONE, -1, -1);
...@@ -102,18 +108,21 @@ ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn) ...@@ -102,18 +108,21 @@ ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn)
ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip) ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip)
{ {
return ImageIndexIterator(GL_TEXTURE_2D, Range<GLint>(minMip, maxMip), return ImageIndexIterator(GL_TEXTURE_2D, Range<GLint>(minMip, maxMip),
Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), NULL); Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL),
nullptr);
} }
ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip) ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip)
{ {
return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, Range<GLint>(minMip, maxMip), Range<GLint>(0, 6), NULL); return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, Range<GLint>(minMip, maxMip), Range<GLint>(0, 6),
nullptr);
} }
ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip, GLint maxMip, ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip, GLint maxMip,
GLint minLayer, GLint maxLayer) GLint minLayer, GLint maxLayer)
{ {
return ImageIndexIterator(GL_TEXTURE_3D, Range<GLint>(minMip, maxMip), Range<GLint>(minLayer, maxLayer), NULL); return ImageIndexIterator(GL_TEXTURE_3D, Range<GLint>(minMip, maxMip),
Range<GLint>(minLayer, maxLayer), nullptr);
} }
ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip, ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip,
...@@ -123,6 +132,13 @@ ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip, ...@@ -123,6 +132,13 @@ ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip,
Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), layerCounts); Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), layerCounts);
} }
ImageIndexIterator ImageIndexIterator::Make2DMultisample()
{
return ImageIndexIterator(GL_TEXTURE_2D_MULTISAMPLE, Range<GLint>(0, 0),
Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL),
nullptr);
}
ImageIndexIterator::ImageIndexIterator(GLenum type, const Range<GLint> &mipRange, ImageIndexIterator::ImageIndexIterator(GLenum type, const Range<GLint> &mipRange,
const Range<GLint> &layerRange, const GLsizei *layerCounts) const Range<GLint> &layerRange, const GLsizei *layerCounts)
: mType(type), : mType(type),
......
...@@ -35,6 +35,7 @@ struct ImageIndex ...@@ -35,6 +35,7 @@ struct ImageIndex
static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex); static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex);
static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL); static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL);
static ImageIndex MakeGeneric(GLenum target, GLint mipIndex); static ImageIndex MakeGeneric(GLenum target, GLint mipIndex);
static ImageIndex Make2DMultisample();
static ImageIndex MakeInvalid(); static ImageIndex MakeInvalid();
...@@ -57,6 +58,7 @@ class ImageIndexIterator ...@@ -57,6 +58,7 @@ class ImageIndexIterator
static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip); static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip);
static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer); static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer);
static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts); static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts);
static ImageIndexIterator Make2DMultisample();
ImageIndex next(); ImageIndex next();
ImageIndex current() const; ImageIndex current() const;
......
...@@ -475,6 +475,16 @@ void TextureState::setImageDescChain(GLuint baseLevel, ...@@ -475,6 +475,16 @@ void TextureState::setImageDescChain(GLuint baseLevel,
} }
} }
void TextureState::setImageDescChainMultisample(Extents baseSize,
const Format &format,
GLsizei samples,
GLboolean fixedSampleLocations)
{
ASSERT(mTarget == GL_TEXTURE_2D_MULTISAMPLE);
ImageDesc levelInfo(baseSize, format, samples, fixedSampleLocations);
setImageDesc(mTarget, 0, levelInfo);
}
void TextureState::clearImageDesc(GLenum target, size_t level) void TextureState::clearImageDesc(GLenum target, size_t level)
{ {
setImageDesc(target, level, ImageDesc()); setImageDesc(target, level, ImageDesc());
...@@ -773,20 +783,6 @@ GLenum Texture::getUsage() const ...@@ -773,20 +783,6 @@ GLenum Texture::getUsage() const
return mState.mUsage; return mState.mUsage;
} }
GLsizei Texture::getSamples(GLenum target, size_t level) const
{
ASSERT(target == mState.mTarget ||
(mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
return mState.getImageDesc(target, level).samples;
}
GLboolean Texture::getFixedSampleLocations(GLenum target, size_t level) const
{
ASSERT(target == mState.mTarget ||
(mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
return mState.getImageDesc(target, level).fixedSampleLocations;
}
const TextureState &Texture::getTextureState() const const TextureState &Texture::getTextureState() const
{ {
return mState; return mState;
...@@ -820,6 +816,20 @@ const Format &Texture::getFormat(GLenum target, size_t level) const ...@@ -820,6 +816,20 @@ const Format &Texture::getFormat(GLenum target, size_t level) const
return mState.getImageDesc(target, level).format; return mState.getImageDesc(target, level).format;
} }
GLsizei Texture::getSamples(GLenum target, size_t level) const
{
ASSERT(target == mState.mTarget ||
(mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
return mState.getImageDesc(target, level).samples;
}
GLboolean Texture::getFixedSampleLocations(GLenum target, size_t level) const
{
ASSERT(target == mState.mTarget ||
(mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
return mState.getImageDesc(target, level).fixedSampleLocations;
}
bool Texture::isMipmapComplete() const bool Texture::isMipmapComplete() const
{ {
return mState.computeMipmapCompleteness(); return mState.computeMipmapCompleteness();
...@@ -1022,6 +1032,32 @@ Error Texture::setStorage(GLenum target, GLsizei levels, GLenum internalFormat, ...@@ -1022,6 +1032,32 @@ Error Texture::setStorage(GLenum target, GLsizei levels, GLenum internalFormat,
return NoError(); return NoError();
} }
Error Texture::setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalFormat,
const Extents &size,
GLboolean fixedSampleLocations)
{
ASSERT(target == mState.mTarget);
// Release from previous calls to eglBindTexImage, to avoid calling the Impl after
releaseTexImageInternal();
orphanImages();
ANGLE_TRY(mTexture->setStorageMultisample(target, samples, internalFormat, size,
fixedSampleLocations));
mState.mImmutableFormat = true;
mState.mImmutableLevels = static_cast<GLuint>(1);
mState.clearImageDescs();
mState.setImageDescChainMultisample(size, Format(internalFormat), samples,
fixedSampleLocations);
mDirtyChannel.signal();
return NoError();
}
Error Texture::generateMipmap() Error Texture::generateMipmap()
{ {
// Release from previous calls to eglBindTexImage, to avoid calling the Impl after // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
...@@ -1167,10 +1203,9 @@ const Format &Texture::getAttachmentFormat(const gl::FramebufferAttachment::Targ ...@@ -1167,10 +1203,9 @@ const Format &Texture::getAttachmentFormat(const gl::FramebufferAttachment::Targ
return getFormat(target.textureIndex().type, target.textureIndex().mipIndex); return getFormat(target.textureIndex().type, target.textureIndex().mipIndex);
} }
GLsizei Texture::getAttachmentSamples(const gl::FramebufferAttachment::Target & /*target*/) const GLsizei Texture::getAttachmentSamples(const gl::FramebufferAttachment::Target &target) const
{ {
// Multisample textures not currently supported return getSamples(target.textureIndex().type, 0);
return 0;
} }
void Texture::onAttach() void Texture::onAttach()
......
...@@ -49,6 +49,7 @@ struct ImageDesc final ...@@ -49,6 +49,7 @@ struct ImageDesc final
{ {
ImageDesc(); ImageDesc();
ImageDesc(const Extents &size, const Format &format); ImageDesc(const Extents &size, const Format &format);
ImageDesc(const Extents &size, ImageDesc(const Extents &size,
const Format &format, const Format &format,
const GLsizei samples, const GLsizei samples,
...@@ -126,6 +127,11 @@ struct TextureState final : public angle::NonCopyable ...@@ -126,6 +127,11 @@ struct TextureState final : public angle::NonCopyable
GLuint maxLevel, GLuint maxLevel,
Extents baseSize, Extents baseSize,
const Format &format); const Format &format);
void setImageDescChainMultisample(Extents baseSize,
const Format &format,
GLsizei samples,
GLboolean fixedSampleLocations);
void clearImageDesc(GLenum target, size_t level); void clearImageDesc(GLenum target, size_t level);
void clearImageDescs(); void clearImageDescs();
...@@ -246,15 +252,13 @@ class Texture final : public egl::ImageSibling, ...@@ -246,15 +252,13 @@ class Texture final : public egl::ImageSibling,
void setUsage(GLenum usage); void setUsage(GLenum usage);
GLenum getUsage() const; GLenum getUsage() const;
GLsizei getSamples(GLenum target, size_t level) const;
GLboolean getFixedSampleLocations(GLenum target, size_t level) const;
const TextureState &getTextureState() const; const TextureState &getTextureState() const;
size_t getWidth(GLenum target, size_t level) const; size_t getWidth(GLenum target, size_t level) const;
size_t getHeight(GLenum target, size_t level) const; size_t getHeight(GLenum target, size_t level) const;
size_t getDepth(GLenum target, size_t level) const; size_t getDepth(GLenum target, size_t level) const;
GLsizei getSamples(GLenum target, size_t level) const;
GLboolean getFixedSampleLocations(GLenum target, size_t level) const;
const Format &getFormat(GLenum target, size_t level) const; const Format &getFormat(GLenum target, size_t level) const;
bool isMipmapComplete() const; bool isMipmapComplete() const;
...@@ -317,6 +321,12 @@ class Texture final : public egl::ImageSibling, ...@@ -317,6 +321,12 @@ class Texture final : public egl::ImageSibling,
Error setStorage(GLenum target, GLsizei levels, GLenum internalFormat, const Extents &size); Error setStorage(GLenum target, GLsizei levels, GLenum internalFormat, const Extents &size);
Error setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalformat,
const Extents &size,
GLboolean fixedSampleLocations);
Error setEGLImageTarget(GLenum target, egl::Image *imageTarget); Error setEGLImageTarget(GLenum target, egl::Image *imageTarget);
Error generateMipmap(); Error generateMipmap();
......
...@@ -74,6 +74,8 @@ class FramebufferImpl : angle::NonCopyable ...@@ -74,6 +74,8 @@ class FramebufferImpl : angle::NonCopyable
const gl::FramebufferState &getState() const { return mState; } const gl::FramebufferState &getState() const { return mState; }
virtual gl::Error getSamplePosition(size_t index, GLfloat *xy) const = 0;
protected: protected:
const gl::FramebufferState &mState; const gl::FramebufferState &mState;
}; };
......
...@@ -38,6 +38,8 @@ class MockFramebufferImpl : public rx::FramebufferImpl ...@@ -38,6 +38,8 @@ class MockFramebufferImpl : public rx::FramebufferImpl
MOCK_CONST_METHOD5(readPixels, MOCK_CONST_METHOD5(readPixels,
gl::Error(ContextImpl *, const gl::Rectangle &, GLenum, GLenum, GLvoid *)); gl::Error(ContextImpl *, const gl::Rectangle &, GLenum, GLenum, GLvoid *));
MOCK_CONST_METHOD2(getSamplePosition, gl::Error(size_t, GLfloat *));
MOCK_METHOD5( MOCK_METHOD5(
blit, blit,
gl::Error(ContextImpl *, const gl::Rectangle &, const gl::Rectangle &, GLbitfield, GLenum)); gl::Error(ContextImpl *, const gl::Rectangle &, const gl::Rectangle &, GLbitfield, GLenum));
......
...@@ -77,6 +77,12 @@ class TextureImpl : public FramebufferAttachmentObjectImpl ...@@ -77,6 +77,12 @@ class TextureImpl : public FramebufferAttachmentObjectImpl
virtual gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) = 0; virtual gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) = 0;
virtual gl::Error setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalformat,
const gl::Extents &size,
GLboolean fixedSampleLocations) = 0;
virtual gl::Error setEGLImageTarget(GLenum target, egl::Image *image) = 0; virtual gl::Error setEGLImageTarget(GLenum target, egl::Image *image) = 0;
virtual gl::Error setImageExternal(GLenum target, virtual gl::Error setImageExternal(GLenum target,
......
...@@ -46,6 +46,9 @@ class MockTextureImpl : public TextureImpl ...@@ -46,6 +46,9 @@ class MockTextureImpl : public TextureImpl
MOCK_METHOD2(getAttachmentRenderTarget, gl::Error(const gl::FramebufferAttachment::Target &, FramebufferAttachmentRenderTarget **)); MOCK_METHOD2(getAttachmentRenderTarget, gl::Error(const gl::FramebufferAttachment::Target &, FramebufferAttachmentRenderTarget **));
MOCK_METHOD5(setStorageMultisample,
gl::Error(GLenum, GLsizei, GLint, const gl::Extents &, GLboolean));
MOCK_METHOD1(setBaseLevel, void(GLuint)); MOCK_METHOD1(setBaseLevel, void(GLuint));
MOCK_METHOD1(syncState, void(const gl::Texture::DirtyBits &)); MOCK_METHOD1(syncState, void(const gl::Texture::DirtyBits &));
......
...@@ -352,4 +352,9 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender() const ...@@ -352,4 +352,9 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender() const
return mColorAttachmentsForRender.value(); return mColorAttachmentsForRender.value();
} }
gl::Error FramebufferD3D::getSamplePosition(size_t index, GLfloat *xy) const
{
return gl::InternalError() << "getSamplePosition is unimplemented.";
}
} // namespace rx } // namespace rx
...@@ -99,6 +99,8 @@ class FramebufferD3D : public FramebufferImpl ...@@ -99,6 +99,8 @@ class FramebufferD3D : public FramebufferImpl
const gl::AttachmentList &getColorAttachmentsForRender() const; const gl::AttachmentList &getColorAttachmentsForRender() const;
gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
private: private:
virtual gl::Error clearImpl(ContextImpl *impl, const ClearParameters &clearParams) = 0; virtual gl::Error clearImpl(ContextImpl *impl, const ClearParameters &clearParams) = 0;
......
...@@ -144,6 +144,16 @@ GLenum TextureD3D::getBaseLevelInternalFormat() const ...@@ -144,6 +144,16 @@ GLenum TextureD3D::getBaseLevelInternalFormat() const
return (baseImage ? baseImage->getInternalFormat() : GL_NONE); return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
} }
gl::Error TextureD3D::setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalFormat,
const gl::Extents &size,
GLboolean fixedSampleLocations)
{
UNIMPLEMENTED();
return gl::InternalError() << "setStorageMultisample is unimplemented.";
}
bool TextureD3D::shouldUseSetData(const ImageD3D *image) const bool TextureD3D::shouldUseSetData(const ImageD3D *image) const
{ {
if (!mRenderer->getWorkarounds().setDataFasterThanImageUpload) if (!mRenderer->getWorkarounds().setDataFasterThanImageUpload)
...@@ -573,6 +583,198 @@ TextureD3D_2D::TextureD3D_2D(const gl::TextureState &state, RendererD3D *rendere ...@@ -573,6 +583,198 @@ TextureD3D_2D::TextureD3D_2D(const gl::TextureState &state, RendererD3D *rendere
} }
} }
TextureD3D_2DMultisample::TextureD3D_2DMultisample(const gl::TextureState &state,
RendererD3D *renderer)
: TextureD3D(state, renderer)
{
UNIMPLEMENTED();
}
TextureD3D_2DMultisample::~TextureD3D_2DMultisample()
{
UNIMPLEMENTED();
}
ImageD3D *TextureD3D_2DMultisample::getImage(const gl::ImageIndex &index) const
{
UNIMPLEMENTED();
return nullptr;
}
gl::Error TextureD3D_2DMultisample::setImage(GLenum target,
size_t level,
GLenum internalFormat,
const gl::Extents &size,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
const uint8_t *pixels)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error TextureD3D_2DMultisample::setSubImage(GLenum target,
size_t level,
const gl::Box &area,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
const uint8_t *pixels)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error TextureD3D_2DMultisample::setCompressedImage(GLenum target,
size_t level,
GLenum internalFormat,
const gl::Extents &size,
const gl::PixelUnpackState &unpack,
size_t imageSize,
const uint8_t *pixels)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error TextureD3D_2DMultisample::setCompressedSubImage(GLenum target,
size_t level,
const gl::Box &area,
GLenum format,
const gl::PixelUnpackState &unpack,
size_t imageSize,
const uint8_t *pixels)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error TextureD3D_2DMultisample::copyImage(GLenum target,
size_t level,
const gl::Rectangle &sourceArea,
GLenum internalFormat,
const gl::Framebuffer *source)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error TextureD3D_2DMultisample::copySubImage(GLenum target,
size_t level,
const gl::Offset &destOffset,
const gl::Rectangle &sourceArea,
const gl::Framebuffer *source)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error TextureD3D_2DMultisample::setStorage(GLenum target,
size_t levels,
GLenum internalFormat,
const gl::Extents &size)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error TextureD3D_2DMultisample::setImageExternal(GLenum target,
egl::Stream *stream,
const egl::Stream::GLTextureDescription &desc)
{
UNIMPLEMENTED();
return gl::InternalError();
}
void TextureD3D_2DMultisample::bindTexImage(egl::Surface *surface)
{
UNIMPLEMENTED();
}
void TextureD3D_2DMultisample::releaseTexImage()
{
UNIMPLEMENTED();
}
gl::Error TextureD3D_2DMultisample::setEGLImageTarget(GLenum target, egl::Image *image)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error TextureD3D_2DMultisample::getRenderTarget(const gl::ImageIndex &index,
RenderTargetD3D **outRT)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::ImageIndexIterator TextureD3D_2DMultisample::imageIterator() const
{
UNIMPLEMENTED();
return gl::ImageIndexIterator::Make2DMultisample();
}
gl::ImageIndex TextureD3D_2DMultisample::getImageIndex(GLint mip, GLint layer) const
{
UNIMPLEMENTED();
return gl::ImageIndex::Make2DMultisample();
}
bool TextureD3D_2DMultisample::isValidIndex(const gl::ImageIndex &index) const
{
UNIMPLEMENTED();
return false;
}
GLsizei TextureD3D_2DMultisample::getLayerCount(int level) const
{
UNIMPLEMENTED();
return GLsizei();
}
void TextureD3D_2DMultisample::markAllImagesDirty()
{
UNIMPLEMENTED();
}
gl::Error TextureD3D_2DMultisample::initializeStorage(bool renderTarget)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error TextureD3D_2DMultisample::createCompleteStorage(bool renderTarget,
TextureStorage **outTexStorage) const
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error TextureD3D_2DMultisample::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{
UNIMPLEMENTED();
return gl::InternalError();
}
gl::Error TextureD3D_2DMultisample::updateStorage()
{
UNIMPLEMENTED();
return gl::InternalError();
}
void TextureD3D_2DMultisample::initMipmapImages()
{
UNIMPLEMENTED();
}
bool TextureD3D_2DMultisample::isImageComplete(const gl::ImageIndex &index) const
{
UNIMPLEMENTED();
return false;
}
TextureD3D_2D::~TextureD3D_2D() TextureD3D_2D::~TextureD3D_2D()
{ {
// Delete the Images before the TextureStorage. // Delete the Images before the TextureStorage.
...@@ -1242,6 +1444,16 @@ void TextureD3D_2D::markAllImagesDirty() ...@@ -1242,6 +1444,16 @@ void TextureD3D_2D::markAllImagesDirty()
mDirtyImages = true; mDirtyImages = true;
} }
gl::Error TextureD3D_2D::setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalFormat,
const gl::Extents &size,
GLboolean fixedSampleLocations)
{
UNIMPLEMENTED();
return gl::InternalError() << "setStorageMultisample is unimplemented.";
}
TextureD3D_Cube::TextureD3D_Cube(const gl::TextureState &state, RendererD3D *renderer) TextureD3D_Cube::TextureD3D_Cube(const gl::TextureState &state, RendererD3D *renderer)
: TextureD3D(state, renderer) : TextureD3D(state, renderer)
{ {
......
...@@ -45,6 +45,12 @@ class TextureD3D : public TextureImpl ...@@ -45,6 +45,12 @@ class TextureD3D : public TextureImpl
GLint getBaseLevelHeight() const; GLint getBaseLevelHeight() const;
GLenum getBaseLevelInternalFormat() const; GLenum getBaseLevelInternalFormat() const;
gl::Error setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalFormat,
const gl::Extents &size,
GLboolean fixedSampleLocations) override;
bool isImmutable() const { return mImmutable; } bool isImmutable() const { return mImmutable; }
virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0; virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0;
...@@ -187,6 +193,12 @@ class TextureD3D_2D : public TextureD3D ...@@ -187,6 +193,12 @@ class TextureD3D_2D : public TextureD3D
virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const;
virtual bool isValidIndex(const gl::ImageIndex &index) const; virtual bool isValidIndex(const gl::ImageIndex &index) const;
gl::Error setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalFormat,
const gl::Extents &size,
GLboolean fixedSampleLocations);
protected: protected:
void markAllImagesDirty() override; void markAllImagesDirty() override;
...@@ -500,6 +512,92 @@ class TextureD3D_External : public TextureD3D ...@@ -500,6 +512,92 @@ class TextureD3D_External : public TextureD3D
bool isImageComplete(const gl::ImageIndex &index) const override; bool isImageComplete(const gl::ImageIndex &index) const override;
}; };
class TextureD3D_2DMultisample : public TextureD3D
{
public:
TextureD3D_2DMultisample(const gl::TextureState &data, RendererD3D *renderer);
~TextureD3D_2DMultisample() override;
ImageD3D *getImage(const gl::ImageIndex &index) const override;
gl::Error setImage(GLenum target,
size_t level,
GLenum internalFormat,
const gl::Extents &size,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
const uint8_t *pixels) override;
gl::Error setSubImage(GLenum target,
size_t level,
const gl::Box &area,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
const uint8_t *pixels) override;
gl::Error setCompressedImage(GLenum target,
size_t level,
GLenum internalFormat,
const gl::Extents &size,
const gl::PixelUnpackState &unpack,
size_t imageSize,
const uint8_t *pixels) override;
gl::Error setCompressedSubImage(GLenum target,
size_t level,
const gl::Box &area,
GLenum format,
const gl::PixelUnpackState &unpack,
size_t imageSize,
const uint8_t *pixels) override;
gl::Error copyImage(GLenum target,
size_t level,
const gl::Rectangle &sourceArea,
GLenum internalFormat,
const gl::Framebuffer *source) override;
gl::Error copySubImage(GLenum target,
size_t level,
const gl::Offset &destOffset,
const gl::Rectangle &sourceArea,
const gl::Framebuffer *source) override;
gl::Error setStorage(GLenum target,
size_t levels,
GLenum internalFormat,
const gl::Extents &size) override;
gl::Error setImageExternal(GLenum target,
egl::Stream *stream,
const egl::Stream::GLTextureDescription &desc) override;
void bindTexImage(egl::Surface *surface) override;
void releaseTexImage() override;
gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override;
gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) override;
gl::ImageIndexIterator imageIterator() const override;
gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
bool isValidIndex(const gl::ImageIndex &index) const override;
virtual GLsizei getLayerCount(int level) const;
protected:
void markAllImagesDirty() override;
private:
gl::Error initializeStorage(bool renderTarget) override;
gl::Error createCompleteStorage(bool renderTarget,
TextureStorage **outTexStorage) const override;
gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage) override;
gl::Error updateStorage() override;
void initMipmapImages() override;
bool isImageComplete(const gl::ImageIndex &index) const override;
};
} }
#endif // LIBANGLE_RENDERER_D3D_TEXTURED3D_H_ #endif // LIBANGLE_RENDERER_D3D_TEXTURED3D_H_
...@@ -83,7 +83,7 @@ TextureImpl *Context11::createTexture(const gl::TextureState &state) ...@@ -83,7 +83,7 @@ TextureImpl *Context11::createTexture(const gl::TextureState &state)
case GL_TEXTURE_EXTERNAL_OES: case GL_TEXTURE_EXTERNAL_OES:
return new TextureD3D_External(state, mRenderer); return new TextureD3D_External(state, mRenderer);
case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE:
UNIMPLEMENTED(); return new TextureD3D_2DMultisample(state, mRenderer);
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
......
...@@ -425,6 +425,12 @@ void Framebuffer11::signal(SignalToken token) ...@@ -425,6 +425,12 @@ void Framebuffer11::signal(SignalToken token)
} }
} }
gl::Error Framebuffer11::getSamplePosition(size_t index, GLfloat *xy) const
{
UNIMPLEMENTED();
return gl::InternalError() << "getSamplePosition is unimplemented.";
}
bool Framebuffer11::hasAnyInternalDirtyBit() const bool Framebuffer11::hasAnyInternalDirtyBit() const
{ {
return mInternalDirtyBits.any(); return mInternalDirtyBits.any();
......
...@@ -46,6 +46,8 @@ class Framebuffer11 : public FramebufferD3D, public angle::SignalReceiver ...@@ -46,6 +46,8 @@ class Framebuffer11 : public FramebufferD3D, public angle::SignalReceiver
void signal(angle::SignalToken token) override; void signal(angle::SignalToken token) override;
gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
private: private:
gl::Error clearImpl(ContextImpl *context, const ClearParameters &clearParams) override; gl::Error clearImpl(ContextImpl *context, const ClearParameters &clearParams) override;
......
...@@ -85,10 +85,12 @@ static void BindFramebufferAttachment(const FunctionsGL *functions, ...@@ -85,10 +85,12 @@ static void BindFramebufferAttachment(const FunctionsGL *functions,
const Texture *texture = attachment->getTexture(); const Texture *texture = attachment->getTexture();
const TextureGL *textureGL = GetImplAs<TextureGL>(texture); const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
if (texture->getTarget() == GL_TEXTURE_2D) if (texture->getTarget() == GL_TEXTURE_2D ||
texture->getTarget() == GL_TEXTURE_2D_MULTISAMPLE)
{ {
functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint, GL_TEXTURE_2D, functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint,
textureGL->getTextureID(), attachment->mipLevel()); texture->getTarget(), textureGL->getTextureID(),
attachment->mipLevel());
} }
else if (texture->getTarget() == GL_TEXTURE_CUBE_MAP) else if (texture->getTarget() == GL_TEXTURE_CUBE_MAP)
{ {
...@@ -367,6 +369,13 @@ Error FramebufferGL::blit(ContextImpl *context, ...@@ -367,6 +369,13 @@ Error FramebufferGL::blit(ContextImpl *context,
return gl::NoError(); return gl::NoError();
} }
gl::Error FramebufferGL::getSamplePosition(size_t index, GLfloat *xy) const
{
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
mFunctions->getMultisamplefv(GL_SAMPLE_POSITION, static_cast<GLuint>(index), xy);
return gl::NoError();
}
bool FramebufferGL::checkStatus() const bool FramebufferGL::checkStatus() const
{ {
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
......
...@@ -76,6 +76,8 @@ class FramebufferGL : public FramebufferImpl ...@@ -76,6 +76,8 @@ class FramebufferGL : public FramebufferImpl
GLbitfield mask, GLbitfield mask,
GLenum filter) override; GLenum filter) override;
gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
bool checkStatus() const override; bool checkStatus() const override;
void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) override; void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) override;
......
...@@ -807,6 +807,27 @@ gl::Error TextureGL::setStorage(GLenum target, ...@@ -807,6 +807,27 @@ gl::Error TextureGL::setStorage(GLenum target,
return gl::NoError(); return gl::NoError();
} }
gl::Error TextureGL::setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalFormat,
const gl::Extents &size,
GLboolean fixedSampleLocations)
{
nativegl::TexStorageFormat texStorageFormat =
nativegl::GetTexStorageFormat(mFunctions, mWorkarounds, internalFormat);
mStateManager->bindTexture(mState.mTarget, mTextureID);
ASSERT(size.depth == 1);
mFunctions->texStorage2DMultisample(target, samples, texStorageFormat.internalFormat,
size.width, size.height, fixedSampleLocations);
setLevelInfo(0, 1, GetLevelInfo(internalFormat, texStorageFormat.internalFormat));
return gl::NoError();
}
gl::Error TextureGL::setImageExternal(GLenum target, gl::Error TextureGL::setImageExternal(GLenum target,
egl::Stream *stream, egl::Stream *stream,
const egl::Stream::GLTextureDescription &desc) const egl::Stream::GLTextureDescription &desc)
......
...@@ -96,6 +96,12 @@ class TextureGL : public TextureImpl ...@@ -96,6 +96,12 @@ class TextureGL : public TextureImpl
gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override; gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override;
gl::Error setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalFormat,
const gl::Extents &size,
GLboolean fixedSampleLocations) override;
gl::Error setImageExternal(GLenum target, gl::Error setImageExternal(GLenum target,
egl::Stream *stream, egl::Stream *stream,
const egl::Stream::GLTextureDescription &desc) override; const egl::Stream::GLTextureDescription &desc) override;
......
...@@ -132,4 +132,9 @@ void FramebufferNULL::syncState(const gl::Framebuffer::DirtyBits &dirtyBits) ...@@ -132,4 +132,9 @@ void FramebufferNULL::syncState(const gl::Framebuffer::DirtyBits &dirtyBits)
{ {
} }
gl::Error FramebufferNULL::getSamplePosition(size_t index, GLfloat *xy) const
{
return gl::NoError();
}
} // namespace rx } // namespace rx
...@@ -63,6 +63,8 @@ class FramebufferNULL : public FramebufferImpl ...@@ -63,6 +63,8 @@ class FramebufferNULL : public FramebufferImpl
bool checkStatus() const override; bool checkStatus() const override;
void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) override; void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) override;
gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
}; };
} // namespace rx } // namespace rx
......
...@@ -128,4 +128,13 @@ void TextureNULL::syncState(const gl::Texture::DirtyBits &dirtyBits) ...@@ -128,4 +128,13 @@ void TextureNULL::syncState(const gl::Texture::DirtyBits &dirtyBits)
{ {
} }
gl::Error TextureNULL::setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalformat,
const gl::Extents &size,
GLboolean fixedSampleLocations)
{
return gl::NoError();
}
} // namespace rx } // namespace rx
...@@ -82,6 +82,12 @@ class TextureNULL : public TextureImpl ...@@ -82,6 +82,12 @@ class TextureNULL : public TextureImpl
void releaseTexImage() override; void releaseTexImage() override;
void syncState(const gl::Texture::DirtyBits &dirtyBits) override; void syncState(const gl::Texture::DirtyBits &dirtyBits) override;
gl::Error setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalformat,
const gl::Extents &size,
GLboolean fixedSampleLocations) override;
}; };
} // namespace rx } // namespace rx
......
...@@ -296,4 +296,10 @@ void FramebufferVk::syncState(const gl::Framebuffer::DirtyBits &dirtyBits) ...@@ -296,4 +296,10 @@ void FramebufferVk::syncState(const gl::Framebuffer::DirtyBits &dirtyBits)
// TODO(jmadill): Smarter update. // TODO(jmadill): Smarter update.
} }
gl::Error FramebufferVk::getSamplePosition(size_t index, GLfloat *xy) const
{
UNIMPLEMENTED();
return gl::InternalError() << "getSamplePosition is unimplemented.";
}
} // namespace rx } // namespace rx
...@@ -78,6 +78,7 @@ class FramebufferVk : public FramebufferImpl ...@@ -78,6 +78,7 @@ class FramebufferVk : public FramebufferImpl
private: private:
FramebufferVk(const gl::FramebufferState &state); FramebufferVk(const gl::FramebufferState &state);
FramebufferVk(const gl::FramebufferState &state, WindowSurfaceVk *backbuffer); FramebufferVk(const gl::FramebufferState &state, WindowSurfaceVk *backbuffer);
gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
}; };
} // namespace rx } // namespace rx
......
...@@ -147,4 +147,14 @@ void TextureVk::syncState(const gl::Texture::DirtyBits &dirtyBits) ...@@ -147,4 +147,14 @@ void TextureVk::syncState(const gl::Texture::DirtyBits &dirtyBits)
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
gl::Error TextureVk::setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalformat,
const gl::Extents &size,
GLboolean fixedSampleLocations)
{
UNIMPLEMENTED();
return gl::InternalError() << "setStorageMultisample is unimplemented.";
}
} // namespace rx } // namespace rx
...@@ -85,6 +85,12 @@ class TextureVk : public TextureImpl ...@@ -85,6 +85,12 @@ class TextureVk : public TextureImpl
FramebufferAttachmentRenderTarget **rtOut) override; FramebufferAttachmentRenderTarget **rtOut) override;
void syncState(const gl::Texture::DirtyBits &dirtyBits) override; void syncState(const gl::Texture::DirtyBits &dirtyBits) override;
gl::Error setStorageMultisample(GLenum target,
GLsizei samples,
GLint internalformat,
const gl::Extents &size,
GLboolean fixedSampleLocations) override;
}; };
} // namespace rx } // namespace rx
......
...@@ -1313,6 +1313,15 @@ bool ValidateGetInternalFormativBase(Context *context, ...@@ -1313,6 +1313,15 @@ bool ValidateGetInternalFormativBase(Context *context,
case GL_RENDERBUFFER: case GL_RENDERBUFFER:
break; break;
case GL_TEXTURE_2D_MULTISAMPLE:
if (context->getClientVersion() < ES_3_1)
{
context->handleError(
Error(GL_INVALID_OPERATION, "Texture target requires at least OpenGL ES 3.1."));
return false;
}
break;
default: default:
context->handleError(Error(GL_INVALID_ENUM, "Invalid target.")); context->handleError(Error(GL_INVALID_ENUM, "Invalid target."));
return false; return false;
...@@ -3665,7 +3674,8 @@ bool ValidateFramebufferTexture2D(Context *context, ...@@ -3665,7 +3674,8 @@ bool ValidateFramebufferTexture2D(Context *context,
} }
if (tex->getTarget() != GL_TEXTURE_2D) if (tex->getTarget() != GL_TEXTURE_2D)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION,
"Textarget must match the texture target type."));
return false; return false;
} }
} }
...@@ -3685,7 +3695,32 @@ bool ValidateFramebufferTexture2D(Context *context, ...@@ -3685,7 +3695,32 @@ bool ValidateFramebufferTexture2D(Context *context,
} }
if (tex->getTarget() != GL_TEXTURE_CUBE_MAP) if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION,
"Textarget must match the texture target type."));
return false;
}
}
break;
case GL_TEXTURE_2D_MULTISAMPLE:
{
if (context->getClientVersion() < ES_3_1)
{
context->handleError(Error(GL_INVALID_OPERATION,
"Texture target requires at least OpenGL ES 3.1."));
return false;
}
if (level != 0)
{
context->handleError(
Error(GL_INVALID_VALUE, "Level must be 0 for TEXTURE_2D_MULTISAMPLE."));
return false;
}
if (tex->getTarget() != GL_TEXTURE_2D_MULTISAMPLE)
{
context->handleError(Error(GL_INVALID_OPERATION,
"Textarget must match the texture target type."));
return false; return false;
} }
} }
......
...@@ -274,4 +274,118 @@ bool ValidateGetTexLevelParameteriv(Context *context, ...@@ -274,4 +274,118 @@ bool ValidateGetTexLevelParameteriv(Context *context,
return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr); return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
} }
bool ValidateTexStorage2DMultiSample(Context *context,
GLenum target,
GLsizei samples,
GLint internalFormat,
GLsizei width,
GLsizei height,
GLboolean fixedSampleLocations)
{
if (context->getClientVersion() < ES_3_1)
{
context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.1."));
return false;
}
if (target != GL_TEXTURE_2D_MULTISAMPLE)
{
context->handleError(Error(GL_INVALID_ENUM, "Target must be TEXTURE_2D_MULTISAMPLE."));
return false;
}
if (width < 1 || height < 1)
{
context->handleError(Error(GL_INVALID_VALUE, "Width and height must be positive."));
return false;
}
const Caps &caps = context->getCaps();
if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
static_cast<GLuint>(height) > caps.max2DTextureSize)
{
context->handleError(
Error(GL_INVALID_VALUE,
"Width and height must be less than or equal to GL_MAX_TEXTURE_SIZE."));
return false;
}
if (samples == 0)
{
context->handleError(Error(GL_INVALID_VALUE, "Samples may not be zero."));
return false;
}
const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
if (!formatCaps.renderable)
{
context->handleError(
Error(GL_INVALID_ENUM,
"SizedInternalformat must be color-renderable, depth-renderable, "
"or stencil-renderable."));
return false;
}
// The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
// is one of the unsized base internalformats listed in table 8.11.
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
if (formatInfo.pixelBytes == 0)
{
context->handleError(
Error(GL_INVALID_ENUM,
"Internalformat is one of the unsupported unsized base internalformats."));
return false;
}
if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
{
context->handleError(
Error(GL_INVALID_OPERATION,
"Samples must not be greater than maximum supported value for the format."));
return false;
}
Texture *texture = context->getTargetTexture(target);
if (!texture || texture->id() == 0)
{
context->handleError(Error(GL_INVALID_OPERATION, "Zero is bound to target."));
return false;
}
if (texture->getImmutableFormat())
{
context->handleError(
Error(GL_INVALID_OPERATION,
"The value of TEXTURE_IMMUTABLE_FORMAT for the texture "
"currently bound to target on the active texture unit is true."));
return false;
}
return true;
}
bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val)
{
if (context->getClientVersion() < ES_3_1)
{
context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.1."));
return false;
}
if (pname != GL_SAMPLE_POSITION)
{
context->handleError(Error(GL_INVALID_ENUM, "Pname must be SAMPLE_POSITION."));
return false;
}
GLint maxSamples = context->getCaps().maxSamples;
if (index >= static_cast<GLuint>(maxSamples))
{
context->handleError(
Error(GL_INVALID_VALUE, "Index must be less than the value of SAMPLES."));
return false;
}
return true;
}
} // namespace gl } // namespace gl
...@@ -22,6 +22,7 @@ bool ValidateGetBooleani_vRobustANGLE(Context *context, ...@@ -22,6 +22,7 @@ bool ValidateGetBooleani_vRobustANGLE(Context *context,
GLsizei bufSize, GLsizei bufSize,
GLsizei *length, GLsizei *length,
GLboolean *data); GLboolean *data);
bool ValidateGetTexLevelParameterfv(Context *context, bool ValidateGetTexLevelParameterfv(Context *context,
GLenum target, GLenum target,
GLint level, GLint level,
...@@ -33,6 +34,15 @@ bool ValidateGetTexLevelParameteriv(Context *context, ...@@ -33,6 +34,15 @@ bool ValidateGetTexLevelParameteriv(Context *context,
GLenum pname, GLenum pname,
GLint *param); GLint *param);
bool ValidateTexStorage2DMultiSample(Context *context,
GLenum target,
GLsizei samples,
GLint internalFormat,
GLsizei width,
GLsizei height,
GLboolean fixedSampleLocations);
bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val);
bool ValidateDrawIndirectBase(Context *context, GLenum mode, const GLvoid *indirect); bool ValidateDrawIndirectBase(Context *context, GLenum mode, const GLvoid *indirect);
bool ValidateDrawArraysIndirect(Context *context, GLenum mode, const GLvoid *indirect); bool ValidateDrawArraysIndirect(Context *context, GLenum mode, const GLvoid *indirect);
bool ValidateDrawElementsIndirect(Context *context, bool ValidateDrawElementsIndirect(Context *context,
......
...@@ -1021,18 +1021,31 @@ void GL_APIENTRY TexStorage2DMultisample(GLenum target, ...@@ -1021,18 +1021,31 @@ void GL_APIENTRY TexStorage2DMultisample(GLenum target,
Context *context = GetValidGlobalContext(); Context *context = GetValidGlobalContext();
if (context) if (context)
{ {
if (!context->skipValidation()) if (!context->skipValidation() &&
!ValidateTexStorage2DMultiSample(context, target, samples, internalformat, width,
height, fixedsamplelocations))
{ {
context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); return;
} }
UNIMPLEMENTED(); context->texStorage2DMultisample(target, samples, internalformat, width, height,
fixedsamplelocations);
} }
} }
void GL_APIENTRY GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val) void GL_APIENTRY GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
{ {
EVENT("(GLenum pname = 0x%X, GLuint index = %u, GLfloat* val = 0x%0.8p)", pname, index, val); EVENT("(GLenum pname = 0x%X, GLuint index = %u, GLfloat* val = 0x%0.8p)", pname, index, val);
UNIMPLEMENTED();
Context *context = GetValidGlobalContext();
if (context)
{
if (!context->skipValidation() && !ValidateGetMultisamplefv(context, pname, index, val))
{
return;
}
context->getMultisamplefv(pname, index, val);
}
} }
void GL_APIENTRY SampleMaski(GLuint maskNumber, GLbitfield mask) void GL_APIENTRY SampleMaski(GLuint maskNumber, GLbitfield mask)
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
'<(angle_path)/src/tests/gl_tests/StateChangeTest.cpp', '<(angle_path)/src/tests/gl_tests/StateChangeTest.cpp',
'<(angle_path)/src/tests/gl_tests/SwizzleTest.cpp', '<(angle_path)/src/tests/gl_tests/SwizzleTest.cpp',
'<(angle_path)/src/tests/gl_tests/SyncQueriesTest.cpp', '<(angle_path)/src/tests/gl_tests/SyncQueriesTest.cpp',
'<(angle_path)/src/tests/gl_tests/TextureMultisampleTest.cpp',
'<(angle_path)/src/tests/gl_tests/TextureTest.cpp', '<(angle_path)/src/tests/gl_tests/TextureTest.cpp',
'<(angle_path)/src/tests/gl_tests/TimerQueriesTest.cpp', '<(angle_path)/src/tests/gl_tests/TimerQueriesTest.cpp',
'<(angle_path)/src/tests/gl_tests/TransformFeedbackTest.cpp', '<(angle_path)/src/tests/gl_tests/TransformFeedbackTest.cpp',
......
...@@ -49,6 +49,76 @@ ...@@ -49,6 +49,76 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.type.vertex_fragment.struct.* = SKIP 1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.type.vertex_fragment.struct.* = SKIP
1442 D3D11 : dEQP-GLES31.functional.stencil_texturing.* = SKIP 1442 D3D11 : dEQP-GLES31.functional.stencil_texturing.* = SKIP
1442 D3D11 : dEQP-GLES31.functional.state_query.shader.sampler_type = SKIP 1442 D3D11 : dEQP-GLES31.functional.state_query.shader.sampler_type = SKIP
1422 D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.* = SKIP
// OpenGL Failing Tests
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_1.sample_mask_only = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_1.sample_mask_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_1.sample_mask_and_sample_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_1.sample_mask_and_sample_coverage_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_1.sample_mask_non_effective_bits = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_2.sample_mask_only = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_2.sample_mask_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_2.sample_mask_and_sample_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_2.sample_mask_and_sample_coverage_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_2.sample_mask_non_effective_bits = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_3.sample_mask_only = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_3.sample_mask_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_3.sample_mask_and_sample_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_3.sample_mask_and_sample_coverage_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_3.sample_mask_non_effective_bits = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_4.sample_mask_only = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_4.sample_mask_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_4.sample_mask_and_sample_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_4.sample_mask_and_sample_coverage_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_4.sample_mask_non_effective_bits = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_8.sample_mask_only = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_8.sample_mask_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_8.sample_mask_and_sample_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_8.sample_mask_and_sample_coverage_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_8.sample_mask_non_effective_bits = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_10.sample_mask_only = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_10.sample_mask_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_10.sample_mask_and_sample_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_10.sample_mask_and_sample_coverage_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_10.sample_mask_non_effective_bits = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_12.sample_mask_only = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_12.sample_mask_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_12.sample_mask_and_sample_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_12.sample_mask_and_sample_coverage_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_12.sample_mask_non_effective_bits = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_13.sample_mask_only = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_13.sample_mask_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_13.sample_mask_and_sample_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_13.sample_mask_and_sample_coverage_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_13.sample_mask_non_effective_bits = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_16.sample_mask_only = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_16.sample_mask_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_16.sample_mask_and_sample_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_16.sample_mask_and_sample_coverage_and_alpha_to_coverage = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.samples_16.sample_mask_non_effective_bits = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.negative.fbo_attach_different_fixed_state_tex_tex = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.negative.fbo_attach_different_fixed_state_tex_rbo = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.negative.texture_min_filter = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.negative.texture_mag_filter = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.negative.texture_wrap_s = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.negative.texture_wrap_t = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.negative.texture_wrap_r = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.negative.texture_min_lod = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.negative.texture_max_lod = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.negative.texture_compare_mode = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.negative.texture_compare_func = FAIL
1442 OPENGL : dEQP-GLES31.functional.texture.multisample.negative.texture_base_level = FAIL
1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_1_texture_2d_array = FAIL
1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_4_texture_2d_array = FAIL
1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_1_texture_int_2d = FAIL
1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_4_texture_int_2d = FAIL
1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_1_texture_int_2d_array = FAIL
1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_4_texture_int_2d_array = FAIL
1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_1_texture_uint_2d = FAIL
1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_4_texture_uint_2d = FAIL
1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_1_texture_uint_2d_array = FAIL
1442 OPENGL : dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_4_texture_uint_2d_array = FAIL
// D3D11 Failing Tests // D3D11 Failing Tests
1442 D3D11 : dEQP-GLES31.functional.draw_indirect.* = FAIL 1442 D3D11 : dEQP-GLES31.functional.draw_indirect.* = FAIL
...@@ -89,6 +159,7 @@ ...@@ -89,6 +159,7 @@
1442 D3D11 : dEQP-GLES31.functional.state_query.indexed.max_compute_work_group_count_* = FAIL 1442 D3D11 : dEQP-GLES31.functional.state_query.indexed.max_compute_work_group_count_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.indexed.max_compute_work_group_size_* = FAIL 1442 D3D11 : dEQP-GLES31.functional.state_query.indexed.max_compute_work_group_size_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.* = FAIL 1442 D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.texture.multisample.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.texparameter* = SKIP 1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.texparameter* = SKIP
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texparameter* = SKIP 1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texparameter* = SKIP
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.texture.texparameter* = SKIP 1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.texture.texparameter* = SKIP
...@@ -1162,7 +1233,6 @@ ...@@ -1162,7 +1233,6 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.render.depth24_stencil8_draw = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.render.depth24_stencil8_draw = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.misc.compare_mode_effect = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.misc.compare_mode_effect = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.misc.base_level = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.misc.base_level = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.multisample.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.gather.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.texture.gather.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.boolean.sample_mask_* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.boolean.sample_mask_* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.integer.texture_binding_2d_multisample_* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.integer.texture_binding_2d_multisample_* = FAIL
......
//
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// TextureMultisampleTest: Tests of multisampled texture
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
using namespace angle;
namespace
{
class TextureMultisampleTest : public ANGLETest
{
protected:
TextureMultisampleTest()
{
setWindowWidth(64);
setWindowHeight(64);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
void SetUp() override
{
ANGLETest::SetUp();
glGenFramebuffers(1, &mFramebuffer);
glGenTextures(1, &mTexture);
ASSERT_GL_NO_ERROR();
}
void TearDown() override
{
glDeleteFramebuffers(1, &mFramebuffer);
mFramebuffer = 0;
glDeleteTextures(1, &mTexture);
mTexture = 0;
ANGLETest::TearDown();
}
GLuint mFramebuffer = 0;
GLuint mTexture = 0;
};
class TextureMultisampleTestES31 : public TextureMultisampleTest
{
protected:
TextureMultisampleTestES31() : TextureMultisampleTest() {}
};
// Tests that if es version < 3.1, GL_TEXTURE_2D_MULTISAMPLE is not supported in
// GetInternalformativ.
TEST_P(TextureMultisampleTest, MultisampleTargetGetInternalFormativBase)
{
GLint maxSamples = 0;
glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamples);
if (getClientMajorVersion() < 3 || getClientMinorVersion() < 1)
{
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
}
else
{
ASSERT_GL_NO_ERROR();
}
}
// Tests that if es version < 3.1, GL_TEXTURE_2D_MULTISAMPLE is not supported in
// FramebufferTexture2D.
TEST_P(TextureMultisampleTest, MultisampleTargetFramebufferTexture2D)
{
GLint samples = 1;
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, 64, 64, GL_FALSE);
if (getClientMajorVersion() < 3 || getClientMinorVersion() < 1)
{
ASSERT_GL_ERROR(GL_INVALID_ENUM);
}
else
{
ASSERT_GL_NO_ERROR();
}
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
mTexture, 0);
if (getClientMajorVersion() < 3 || getClientMinorVersion() < 1)
{
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
}
else
{
ASSERT_GL_NO_ERROR();
}
}
// Tests basic functionality of glTexStorage2DMultisample.
TEST_P(TextureMultisampleTestES31, ValidateTextureStorageMultisampleParameters)
{
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, GL_FALSE);
if (getClientMajorVersion() < 3 || getClientMinorVersion() < 1)
{
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
return;
}
else
{
ASSERT_GL_NO_ERROR();
}
GLint params = 0;
glGetTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_IMMUTABLE_FORMAT, &params);
EXPECT_EQ(1, params);
glTexStorage2DMultisample(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, GL_FALSE);
ASSERT_GL_ERROR(GL_INVALID_ENUM);
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 0, 0, GL_FALSE);
ASSERT_GL_ERROR(GL_INVALID_VALUE);
GLint maxSize = 0;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, maxSize + 1, 1, GL_FALSE);
ASSERT_GL_ERROR(GL_INVALID_VALUE);
GLint maxSamples = 0;
glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamples);
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, maxSamples + 1, GL_RGBA8, 1, 1, GL_FALSE);
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_RGBA8, 1, 1, GL_FALSE);
ASSERT_GL_ERROR(GL_INVALID_VALUE);
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA, 0, 0, GL_FALSE);
ASSERT_GL_ERROR(GL_INVALID_VALUE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, GL_FALSE);
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
}
ANGLE_INSTANTIATE_TEST(TextureMultisampleTest,
ES3_OPENGL(),
ES3_OPENGLES(),
ES31_OPENGL(),
ES31_OPENGLES());
ANGLE_INSTANTIATE_TEST(TextureMultisampleTestES31, ES31_OPENGL(), ES31_OPENGLES());
}
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