Commit 47110bf4 by Geoff Lang Committed by Commit Bot

Implement CHROMIUM_copy_compressed_texture for D3D11.

BUG=angleproject:1356 Change-Id: Id563997d2921cf558c52a781ae66d8bde58d1f2f Reviewed-on: https://chromium-review.googlesource.com/339847Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 55e98210
Name
CHROMIUM_copy_compressed_texture
Name Strings
GL_CHROMIUM_copy_compressed_texture
Version
Last Modifed Date: August 5, 2015
Dependencies
OpenGL ES 2.0 is required.
GL_AMD_compressed_ATC_texture, GL_ATI_texture_compression_atitc,
GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt5,
GL_EXT_texture_compression_s3tc and GL_OES_compressed_ETC1_RGB8_texture
affects the definition of this extension.
Overview
This extension provides functionality for copying compressed textures. It
adds a new function glCompressedCopyTextureCHROMIUM that works similarily
to glCopyTextureCHROMIUM, but for compressed textures.
Which compressed texture formats that this extension supports depends on
the supported texture compression formats of the host GPU.
Issues
glCompressedCopyTextureCHROMIUM will first try to copy into a compressed
texture of the same format as the source texture. If unsucessful, the
destination texture format will be changed to GL_RGBA and the texture will
be stored uncompressed.
New Procedures and Functions
The command
void glCompressedCopyTextureCHROMIUM (GLuint source_id, GLuint dest_id)
Copies the contents of a compressed texture referred to by <source_id> to
<dest_id> texture.
Texture level 0 is copied from the source image to level 0 of the
destination texture.
The internal format of the source texture must be one of the following
symbolic constants: GL_ATC_RGB_AMD, GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD,
GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
GL_ETC1_RGB8_OES
The destination texture will be created or replaced with the same internal
format as the source texture.
INVALID_OPERATION is generated if internal format of source texture is not
one of the valid formats described above.
INVALID_OPERATION is generated if destination texture is immutable.
INVALID_VALUE is generated if <source_id> or <dest_id> are not valid texture
objects.
INVALID_VALUE is generated if textures corresponding to <dest_id> have not
been bound as GL_TEXTURE_2D object.
INVALID_VALUE is generated if level 0 of the source texture is not defined.
Errors
None.
New Tokens
None.
New State
None.
Revision History
15/6/2015 Documented the extension.
5/8/2015 Added glCompressedCopySubTextureCHROMIUM.
1/6/2016 Remove glCompressedCopySubTextureCHROMIUM.
1/8/2016 Remove <target> argument.
......@@ -1316,6 +1316,14 @@ GL_APICALL void GL_APIENTRY glCopySubTextureCHROMIUM(GLuint sourceId,
#endif
#endif /* GL_CHROMIUM_copy_texture */
#ifndef GL_CHROMIUM_compressed_copy_texture
#define GL_CHROMIUM_compressed_copy_texture 1
typedef void(GL_APIENTRYP PFNGLCOMPRESSEDCOPYTEXTURECHROMIUMPROC)(GLuint sourceId, GLuint destId);
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glCompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId);
#endif
#endif /* GL_CHROMIUM_compressed_copy_texture */
#ifndef GL_CHROMIUM_sync_query
#define GL_CHROMIUM_sync_query 1
#define GL_COMMANDS_COMPLETED_CHROMIUM 0x84F7
......
......@@ -166,6 +166,7 @@ Extensions::Extensions()
bindUniformLocation(false),
syncQuery(false),
copyTexture(false),
copyCompressedTexture(false),
webglCompatibility(false),
bindGeneratesResource(false),
robustClientMemory(false),
......@@ -580,6 +581,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
map["GL_CHROMIUM_bind_uniform_location"] = esOnlyExtension(&Extensions::bindUniformLocation);
map["GL_CHROMIUM_sync_query"] = esOnlyExtension(&Extensions::syncQuery);
map["GL_CHROMIUM_copy_texture"] = esOnlyExtension(&Extensions::copyTexture);
map["GL_CHROMIUM_copy_compressed_texture"] = esOnlyExtension(&Extensions::copyCompressedTexture);
map["GL_ANGLE_webgl_compatibility"] = esOnlyExtension(&Extensions::webglCompatibility);
map["GL_CHROMIUM_bind_generates_resource"] = esOnlyExtension(&Extensions::bindGeneratesResource);
map["GL_ANGLE_robust_client_memory"] = esOnlyExtension(&Extensions::robustClientMemory);
......
......@@ -293,6 +293,9 @@ struct Extensions
// GL_CHROMIUM_copy_texture
bool copyTexture;
// GL_CHROMIUM_copy_compressed_texture
bool copyCompressedTexture;
// GL_ANGLE_webgl_compatibility
bool webglCompatibility;
......
......@@ -3071,6 +3071,15 @@ void Context::copySubTextureCHROMIUM(GLuint sourceId,
unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
}
void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
{
syncStateForTexImage();
gl::Texture *sourceTexture = getTexture(sourceId);
gl::Texture *destTexture = getTexture(destId);
handleError(destTexture->copyCompressedTexture(sourceTexture));
}
void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
{
Buffer *buffer = mGLState.getTargetBuffer(target);
......
......@@ -482,6 +482,7 @@ class Context final : public ValidationContext
GLboolean unpackFlipY,
GLboolean unpackPremultiplyAlpha,
GLboolean unpackUnmultiplyAlpha);
void compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId);
void generateMipmap(GLenum target);
......
......@@ -49,9 +49,7 @@ class Path final : angle::NonCopyable
bool hasPathData() const { return mHasData; }
const rx::PathImpl *getImplementation() const { return mPath; }
rx::PathImpl *getImplementation() { return mPath; }
rx::PathImpl *getImplementation() const { return mPath; }
private:
rx::PathImpl *mPath;
......
......@@ -241,8 +241,7 @@ class Program final : angle::NonCopyable, public LabeledObject
void setLabel(const std::string &label) override;
const std::string &getLabel() const override;
rx::ProgramImpl *getImplementation() { return mProgram; }
const rx::ProgramImpl *getImplementation() const { return mProgram; }
rx::ProgramImpl *getImplementation() const { return mProgram; }
bool attachShader(Shader *shader);
bool detachShader(Shader *shader);
......
......@@ -95,17 +95,12 @@ Error Renderbuffer::setStorageEGLImageTarget(egl::Image *image)
return NoError();
}
rx::RenderbufferImpl *Renderbuffer::getImplementation()
rx::RenderbufferImpl *Renderbuffer::getImplementation() const
{
ASSERT(mRenderbuffer);
return mRenderbuffer;
}
const rx::RenderbufferImpl *Renderbuffer::getImplementation() const
{
return mRenderbuffer;
}
GLsizei Renderbuffer::getWidth() const
{
return mWidth;
......
......@@ -42,8 +42,7 @@ class Renderbuffer final : public egl::ImageSibling,
Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height);
Error setStorageEGLImageTarget(egl::Image *imageTarget);
rx::RenderbufferImpl *getImplementation();
const rx::RenderbufferImpl *getImplementation() const;
rx::RenderbufferImpl *getImplementation() const;
GLsizei getWidth() const;
GLsizei getHeight() const;
......
......@@ -140,13 +140,9 @@ const SamplerState &Sampler::getSamplerState() const
return mSamplerState;
}
const rx::SamplerImpl *Sampler::getImplementation() const
rx::SamplerImpl *Sampler::getImplementation() const
{
return mImpl;
}
rx::SamplerImpl *Sampler::getImplementation()
{
return mImpl;
}
}
......@@ -64,8 +64,7 @@ class Sampler final : public RefCountObject, public LabeledObject
const SamplerState &getSamplerState() const;
const rx::SamplerImpl *getImplementation() const;
rx::SamplerImpl *getImplementation();
rx::SamplerImpl *getImplementation() const;
private:
rx::SamplerImpl *mImpl;
......
......@@ -96,7 +96,7 @@ class Shader final : angle::NonCopyable, public LabeledObject
GLenum getType() const { return mType; }
GLuint getHandle() const;
const rx::ShaderImpl *getImplementation() const { return mImplementation; }
rx::ShaderImpl *getImplementation() const { return mImplementation; }
void deleteSource();
void setSource(GLsizei count, const char *const *string, const GLint *length);
......
......@@ -903,6 +903,21 @@ Error Texture::copySubTexture(const Offset &destOffset,
unpackUnmultiplyAlpha, source);
}
Error Texture::copyCompressedTexture(const Texture *source)
{
// Release from previous calls to eglBindTexImage, to avoid calling the Impl after
releaseTexImageInternal();
orphanImages();
ANGLE_TRY(mTexture->copyCompressedTexture(source));
ASSERT(source->getTarget() != GL_TEXTURE_CUBE_MAP && getTarget() != GL_TEXTURE_CUBE_MAP);
const auto &sourceDesc = source->mState.getImageDesc(source->getTarget(), 0);
mState.setImageDesc(getTarget(), 0, sourceDesc);
return NoError();
}
Error Texture::setStorage(GLenum target, GLsizei levels, GLenum internalFormat, const Extents &size)
{
ASSERT(target == mState.mTarget);
......
......@@ -295,6 +295,7 @@ class Texture final : public egl::ImageSibling,
bool unpackPremultiplyAlpha,
bool unpackUnmultiplyAlpha,
const Texture *source);
Error copyCompressedTexture(const Texture *source);
Error setStorage(GLenum target, GLsizei levels, GLenum internalFormat, const Extents &size);
......@@ -305,8 +306,7 @@ class Texture final : public egl::ImageSibling,
egl::Surface *getBoundSurface() const;
egl::Stream *getBoundStream() const;
rx::TextureImpl *getImplementation() { return mTexture; }
const rx::TextureImpl *getImplementation() const { return mTexture; }
rx::TextureImpl *getImplementation() const { return mTexture; }
// FramebufferAttachmentObject implementation
Extents getAttachmentSize(const FramebufferAttachment::Target &target) const override;
......
......@@ -87,8 +87,7 @@ class VertexArray final : public LabeledObject
return mState.getVertexAttributes();
}
rx::VertexArrayImpl *getImplementation() { return mVertexArray; }
const rx::VertexArrayImpl *getImplementation() const { return mVertexArray; }
rx::VertexArrayImpl *getImplementation() const { return mVertexArray; }
size_t getMaxEnabledAttribute() const { return mState.getMaxEnabledAttribute(); }
......
......@@ -297,12 +297,6 @@ inline DestT *GetImplAs(SrcT *src)
return GetAs<DestT>(src->getImplementation());
}
template <typename DestT, typename SrcT>
inline const DestT *GetImplAs(const SrcT *src)
{
return GetAs<const DestT>(src->getImplementation());
}
}
#include "angletypes.inl"
......
......@@ -40,4 +40,11 @@ gl::Error TextureImpl::copySubTexture(const gl::Offset &destOffset,
UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION, "CHROMIUM_copy_texture exposed but not implemented.");
}
gl::Error TextureImpl::copyCompressedTexture(const gl::Texture *source)
{
UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION,
"CHROMIUM_copy_compressed_texture exposed but not implemented.");
}
}
......@@ -72,6 +72,8 @@ class TextureImpl : public FramebufferAttachmentObjectImpl
bool unpackUnmultiplyAlpha,
const gl::Texture *source);
virtual gl::Error copyCompressedTexture(const gl::Texture *source);
virtual gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) = 0;
virtual gl::Error setEGLImageTarget(GLenum target, egl::Image *image) = 0;
......
......@@ -35,6 +35,7 @@ class MockTextureImpl : public TextureImpl
bool,
bool,
const gl::Texture *));
MOCK_METHOD1(copyCompressedTexture, gl::Error(const gl::Texture *source));
MOCK_METHOD4(setStorage, gl::Error(GLenum, size_t, GLenum, const gl::Extents &));
MOCK_METHOD3(setImageExternal,
gl::Error(GLenum, egl::Stream *, const egl::Stream::GLTextureDescription &));
......
......@@ -169,6 +169,10 @@ class RendererD3D : public BufferFactoryD3D
bool unpackFlipY,
bool unpackPremultiplyAlpha,
bool unpackUnmultiplyAlpha) = 0;
virtual gl::Error copyCompressedTexture(const gl::Texture *source,
GLint sourceLevel,
TextureStorage *storage,
GLint destLevel) = 0;
// RenderTarget creation
virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) = 0;
......
......@@ -968,6 +968,26 @@ gl::Error TextureD3D_2D::copySubTexture(const gl::Offset &destOffset,
return gl::NoError();
}
gl::Error TextureD3D_2D::copyCompressedTexture(const gl::Texture *source)
{
GLenum sourceTarget = source->getTarget();
GLint sourceLevel = 0;
GLint destLevel = 0;
GLenum sizedInternalFormat = source->getFormat(sourceTarget, sourceLevel).asSized();
gl::Extents size(static_cast<int>(source->getWidth(sourceTarget, sourceLevel)),
static_cast<int>(source->getHeight(sourceTarget, sourceLevel)), 1);
redefineImage(destLevel, sizedInternalFormat, size, false);
ANGLE_TRY(initializeStorage(false));
ASSERT(mTexStorage);
ANGLE_TRY(mRenderer->copyCompressedTexture(source, sourceLevel, mTexStorage, destLevel));
return gl::NoError();
}
gl::Error TextureD3D_2D::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size)
{
ASSERT(GL_TEXTURE_2D && size.depth == 1);
......
......@@ -170,6 +170,7 @@ class TextureD3D_2D : public TextureD3D
bool unpackPremultiplyAlpha,
bool unpackUnmultiplyAlpha,
const gl::Texture *source) override;
gl::Error copyCompressedTexture(const gl::Texture *source) override;
gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override;
......
......@@ -3109,6 +3109,41 @@ gl::Error Renderer11::copyTexture(const gl::Texture *source,
return gl::NoError();
}
gl::Error Renderer11::copyCompressedTexture(const gl::Texture *source,
GLint sourceLevel,
TextureStorage *storage,
GLint destLevel)
{
TextureStorage11_2D *destStorage11 = GetAs<TextureStorage11_2D>(storage);
ASSERT(destStorage11);
ID3D11Resource *destResource = nullptr;
ANGLE_TRY(destStorage11->getResource(&destResource));
gl::ImageIndex destIndex = gl::ImageIndex::Make2D(destLevel);
UINT destSubresource = destStorage11->getSubresourceIndex(destIndex);
TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
ASSERT(sourceD3D);
TextureStorage *sourceStorage = nullptr;
ANGLE_TRY(sourceD3D->getNativeTexture(&sourceStorage));
TextureStorage11_2D *sourceStorage11 = GetAs<TextureStorage11_2D>(sourceStorage);
ASSERT(sourceStorage11);
ID3D11Resource *sourceResource = nullptr;
ANGLE_TRY(sourceStorage11->getResource(&sourceResource));
gl::ImageIndex sourceIndex = gl::ImageIndex::Make2D(sourceLevel);
UINT sourceSubresource = sourceStorage11->getSubresourceIndex(sourceIndex);
mDeviceContext->CopySubresourceRegion(destResource, destSubresource, 0, 0, 0, sourceResource,
sourceSubresource, nullptr);
return gl::NoError();
}
gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT)
{
const d3d11::Format &formatInfo = d3d11::Format::Get(format, mRenderer11DeviceCaps);
......
......@@ -215,6 +215,10 @@ class Renderer11 : public RendererD3D
bool unpackFlipY,
bool unpackPremultiplyAlpha,
bool unpackUnmultiplyAlpha) override;
gl::Error copyCompressedTexture(const gl::Texture *source,
GLint sourceLevel,
TextureStorage *storage,
GLint destLevel) override;
// RenderTarget creation
gl::Error createRenderTarget(int width,
......
......@@ -1239,6 +1239,7 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons
extensions->lossyETCDecode = true;
extensions->syncQuery = GetEventQuerySupport(featureLevel);
extensions->copyTexture = true;
extensions->copyCompressedTexture = true;
// D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing.
// D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't support gl_FrontFacing.
......
......@@ -2340,6 +2340,15 @@ gl::Error Renderer9::copyTexture(const gl::Texture *source,
return gl::Error(GL_INVALID_OPERATION);
}
gl::Error Renderer9::copyCompressedTexture(const gl::Texture *source,
GLint sourceLevel,
TextureStorage *storage,
GLint destLevel)
{
UNIMPLEMENTED();
return gl::Error(GL_INVALID_OPERATION);
}
gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT)
{
const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format);
......
......@@ -211,6 +211,10 @@ class Renderer9 : public RendererD3D
bool unpackFlipY,
bool unpackPremultiplyAlpha,
bool unpackUnmultiplyAlpha) override;
gl::Error copyCompressedTexture(const gl::Texture *source,
GLint sourceLevel,
TextureStorage *storage,
GLint destLevel) override;
// RenderTarget creation
gl::Error createRenderTarget(int width,
......
......@@ -3320,6 +3320,68 @@ bool ValidateCopySubTextureCHROMIUM(Context *context,
return true;
}
bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
{
if (!context->getExtensions().copyCompressedTexture)
{
context->handleError(Error(GL_INVALID_OPERATION,
"GL_CHROMIUM_copy_compressed_texture extension not available."));
return false;
}
const gl::Texture *source = context->getTexture(sourceId);
if (source == nullptr)
{
context->handleError(
Error(GL_INVALID_VALUE, "Source texture is not a valid texture object."));
return false;
}
if (source->getTarget() != GL_TEXTURE_2D)
{
context->handleError(
Error(GL_INVALID_VALUE, "Source texture must be of type GL_TEXTURE_2D."));
return false;
}
if (source->getWidth(GL_TEXTURE_2D, 0) == 0 || source->getHeight(GL_TEXTURE_2D, 0) == 0)
{
context->handleError(Error(GL_INVALID_VALUE, "Source texture must level 0 defined."));
return false;
}
const gl::Format &sourceFormat = source->getFormat(GL_TEXTURE_2D, 0);
if (!sourceFormat.info->compressed)
{
context->handleError(
Error(GL_INVALID_OPERATION, "Source texture must have a compressed internal format."));
return false;
}
const gl::Texture *dest = context->getTexture(destId);
if (dest == nullptr)
{
context->handleError(
Error(GL_INVALID_VALUE, "Destination texture is not a valid texture object."));
return false;
}
if (dest->getTarget() != GL_TEXTURE_2D)
{
context->handleError(
Error(GL_INVALID_VALUE, "Destination texture must be of type GL_TEXTURE_2D."));
return false;
}
if (dest->getImmutableFormat())
{
context->handleError(Error(GL_INVALID_OPERATION, "Destination cannot be immutable."));
return false;
}
return true;
}
bool ValidateCreateShader(Context *context, GLenum type)
{
switch (type)
......
......@@ -325,6 +325,7 @@ bool ValidateCopySubTextureCHROMIUM(Context *context,
GLboolean unpackFlipY,
GLboolean unpackPremultiplyAlpha,
GLboolean unpackUnmultiplyAlpha);
bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId);
bool ValidateCreateShader(Context *context, GLenum type);
bool ValidateBufferData(ValidationContext *context,
......
......@@ -1472,6 +1472,9 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *
INSERT_PROC_ADDRESS(gl, CopyTextureCHROMIUM);
INSERT_PROC_ADDRESS(gl, CopySubTextureCHROMIUM);
// GL_CHROMIUM_copy_compressed_texture
INSERT_PROC_ADDRESS(gl, CompressedCopyTextureCHROMIUM);
// GL_ANGLE_webgl_compatibility
INSERT_PROC_ADDRESS(gl, EnableExtensionANGLE);
......
......@@ -1950,6 +1950,23 @@ ANGLE_EXPORT void GL_APIENTRY CopySubTextureCHROMIUM(GLuint sourceId,
}
}
ANGLE_EXPORT void GL_APIENTRY CompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
{
EVENT("(GLuint sourceId = %u, GLuint destId = %u)", sourceId, destId);
Context *context = GetValidGlobalContext();
if (context)
{
if (!context->skipValidation() &&
!ValidateCompressedCopyTextureCHROMIUM(context, sourceId, destId))
{
return;
}
context->compressedCopyTextureCHROMIUM(sourceId, destId);
}
}
GL_APICALL GLboolean GL_APIENTRY EnableExtensionANGLE(const GLchar *name)
{
EVENT("(const GLchar *name = %p)", name);
......
......@@ -259,6 +259,9 @@ ANGLE_EXPORT void GL_APIENTRY CopySubTextureCHROMIUM(GLuint sourceId,
GLboolean unpackPremultiplyAlpha,
GLboolean unpackUnmultiplyAlpha);
// GL_CHROMIUM_copy_compressed_texture
ANGLE_EXPORT void GL_APIENTRY CompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId);
// GL_ANGLE_webgl_compatibility
GL_APICALL GLboolean GL_APIENTRY EnableExtensionANGLE(const GLchar *name);
......
......@@ -24,6 +24,7 @@
'<(angle_path)/src/tests/gl_tests/ClearTest.cpp',
'<(angle_path)/src/tests/gl_tests/ColorMaskTest.cpp',
'<(angle_path)/src/tests/gl_tests/ComputeShaderTest.cpp',
'<(angle_path)/src/tests/gl_tests/CopyCompressedTextureTest.cpp',
'<(angle_path)/src/tests/gl_tests/CopyTexImageTest.cpp',
'<(angle_path)/src/tests/gl_tests/CopyTextureTest.cpp',
'<(angle_path)/src/tests/gl_tests/CubeMapTextureTest.cpp',
......
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