Skip to content

Commit

Permalink
Vulkan: Add support for EXT_copy_image
Browse files Browse the repository at this point in the history
Add support for GL_EXT_copy_image which allows
image data transfer between image objects.
This is implemented by using the vkCmdCopyImage
API call.

Bug: angleproject:3593
Test: dEQP-GLES31.functional.copy_image.*
Change-Id: I30a34a8711b5d2e5834064d7453e03d6ec0df478
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2393955
Commit-Queue: Brandon Schade <b.schade@samsung.com>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
  • Loading branch information
Brandon Schade authored and Commit Bot committed Nov 5, 2020
1 parent 658ede5 commit 1e494ca
Show file tree
Hide file tree
Showing 28 changed files with 1,602 additions and 35 deletions.
1 change: 1 addition & 0 deletions src/libANGLE/Caps.cpp
Expand Up @@ -1040,6 +1040,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
map["GL_OES_shader_image_atomic"] = enableableExtension(&Extensions::shaderImageAtomicOES);
map["GL_NV_robustness_video_memory_purge"] = esOnlyExtension(&Extensions::robustnessVideoMemoryPurgeNV);
map["GL_ANGLE_get_tex_level_parameter"] = enableableExtension(&Extensions::getTexLevelParameterANGLE);
map["GL_EXT_copy_image"] = enableableExtension(&Extensions::copyImageEXT);
// GLES1 extensions
map["GL_OES_point_size_array"] = enableableExtension(&Extensions::pointSizeArrayOES);
map["GL_OES_texture_cube_map"] = enableableExtension(&Extensions::textureCubeMapOES);
Expand Down
3 changes: 3 additions & 0 deletions src/libANGLE/Caps.h
Expand Up @@ -665,6 +665,9 @@ struct Extensions

// GL_ANGLE_get_tex_level_parameter
bool getTexLevelParameterANGLE = false;

// GL_EXT_copy_image
bool copyImageEXT = false;
};

// Pointer to a boolean memeber of the Extensions struct
Expand Down
82 changes: 81 additions & 1 deletion src/libANGLE/Context.cpp
Expand Up @@ -4122,7 +4122,75 @@ void Context::copyImageSubData(GLuint srcName,
GLsizei srcHeight,
GLsizei srcDepth)
{
UNIMPLEMENTED();
// if copy region is zero, the copy is a successful no-op
if ((srcWidth == 0) || (srcHeight == 0) || (srcDepth == 0))
{
return;
}

if (srcTarget == GL_RENDERBUFFER)
{
// Source target is a Renderbuffer
Renderbuffer *readBuffer = getRenderbuffer(FromGL<RenderbufferID>(srcName));
if (dstTarget == GL_RENDERBUFFER)
{
// Destination target is a Renderbuffer
Renderbuffer *writeBuffer = getRenderbuffer(FromGL<RenderbufferID>(dstName));

// Copy Renderbuffer to Renderbuffer
ANGLE_CONTEXT_TRY(writeBuffer->copyRenderbufferSubData(
this, readBuffer, srcLevel, srcX, srcY, srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
srcHeight, srcDepth));
}
else
{
// Destination target is a Texture
ASSERT(dstTarget == GL_TEXTURE_2D || dstTarget == GL_TEXTURE_2D_ARRAY ||
dstTarget == GL_TEXTURE_3D || dstTarget == GL_TEXTURE_CUBE_MAP);

Texture *writeTexture = getTexture(FromGL<TextureID>(dstName));
ANGLE_CONTEXT_TRY(syncTextureForCopy(writeTexture));

// Copy Renderbuffer to Texture
ANGLE_CONTEXT_TRY(writeTexture->copyRenderbufferSubData(
this, readBuffer, srcLevel, srcX, srcY, srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
srcHeight, srcDepth));
}
}
else
{
// Source target is a Texture
ASSERT(srcTarget == GL_TEXTURE_2D || srcTarget == GL_TEXTURE_2D_ARRAY ||
srcTarget == GL_TEXTURE_3D || srcTarget == GL_TEXTURE_CUBE_MAP);

Texture *readTexture = getTexture(FromGL<TextureID>(srcName));
ANGLE_CONTEXT_TRY(syncTextureForCopy(readTexture));

if (dstTarget == GL_RENDERBUFFER)
{
// Destination target is a Renderbuffer
Renderbuffer *writeBuffer = getRenderbuffer(FromGL<RenderbufferID>(dstName));

// Copy Texture to Renderbuffer
ANGLE_CONTEXT_TRY(writeBuffer->copyTextureSubData(this, readTexture, srcLevel, srcX,
srcY, srcZ, dstLevel, dstX, dstY,
dstZ, srcWidth, srcHeight, srcDepth));
}
else
{
// Destination target is a Texture
ASSERT(dstTarget == GL_TEXTURE_2D || dstTarget == GL_TEXTURE_2D_ARRAY ||
dstTarget == GL_TEXTURE_3D || dstTarget == GL_TEXTURE_CUBE_MAP);

Texture *writeTexture = getTexture(FromGL<TextureID>(dstName));
ANGLE_CONTEXT_TRY(syncTextureForCopy(writeTexture));

// Copy Texture to Texture
ANGLE_CONTEXT_TRY(writeTexture->copyTextureSubData(
this, readTexture, srcLevel, srcX, srcY, srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
srcHeight, srcDepth));
}
}
}

void Context::framebufferTexture2D(GLenum target,
Expand Down Expand Up @@ -4862,6 +4930,18 @@ angle::Result Context::syncStateForClear()
return syncState(mClearDirtyBits, mClearDirtyObjects, Command::Clear);
}

angle::Result Context::syncTextureForCopy(Texture *texture)
{
ASSERT(texture);
// Sync texture not active but scheduled for a copy
if (texture->hasAnyDirtyBit())
{
return texture->syncState(this, Command::Other);
}

return angle::Result::Continue;
}

void Context::activeShaderProgram(ProgramPipelineID pipeline, ShaderProgramID program)
{
Program *shaderProgram = getProgramNoResolveLink(program);
Expand Down
1 change: 1 addition & 0 deletions src/libANGLE/Context.h
Expand Up @@ -653,6 +653,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
angle::Result syncStateForTexImage();
angle::Result syncStateForBlit();
angle::Result syncStateForClear();
angle::Result syncTextureForCopy(Texture *texture);

VertexArray *checkVertexArrayAllocation(VertexArrayID vertexArrayHandle);
TransformFeedback *checkTransformFeedbackAllocation(TransformFeedbackID transformFeedback);
Expand Down
4 changes: 4 additions & 0 deletions src/libANGLE/ErrorStrings.h
Expand Up @@ -104,6 +104,7 @@ MSG kEnumRequiresGLES30 = "Enum requires GLES 3.0";
MSG kEnumRequiresGLES31 = "Enum requires GLES 3.1";
MSG kES1or32Required = "OpenGL ES 1.x or 3.2 Required";
MSG kES31Required = "OpenGL ES 3.1 Required";
MSG kES32Required = "OpenGL ES 3.2 Required";
MSG kES3Required = "OpenGL ES 3.0 Required.";
MSG kExceedsComputeWorkGroupCountX = "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]";
MSG kExceedsComputeWorkGroupCountY = "num_groups_y cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[1]";
Expand Down Expand Up @@ -150,6 +151,7 @@ MSG kImageSizeTooSmall = "imageSize is too small.";
MSG kImmutableMemoryObject = "The memory object is immutable.";
MSG kImmutableTextureBound = "The value of TEXTURE_IMMUTABLE_FORMAT for the texture currently bound to target on the active texture unit is true.";
MSG kIncompatibleDrawModeAgainstGeometryShader = "Primitive mode is incompatible with the input primitive type of the geometry shader.";
MSG kIncompatibleTextures = "Texture formats are not compatible";
MSG kIndexExceedsActiveUniformBlockCount = "Index exceeds active uniform block count.";
MSG kIndexExceedsMaxActiveUniform = "Index must be less than program active uniform count.";
MSG kIndexExceedsMaxActiveUniformBlock = "Index must be less than program active uniform block count.";
Expand Down Expand Up @@ -191,6 +193,7 @@ MSG kInvalidCombinedImageUnit = "Specified unit must be in [GL_TEXTURE0, GL_TEXT
MSG kInvalidComponents = "Invalid components.";
MSG kInvalidCompressedFormat = "Not a valid compressed texture format.";
MSG kInvalidCompressedImageSize = "Invalid compressed image size.";
MSG kInvalidCompressedRegionSize = "Invalid region for compressed texture format.";
MSG kInvalidConstantColor = "CONSTANT_COLOR (or ONE_MINUS_CONSTANT_COLOR) and CONSTANT_ALPHA (or ONE_MINUS_CONSTANT_ALPHA) cannot be used together as source and destination color factors in the blend function.";
MSG kInvalidCopyCombination = "Invalid copy texture format combination.";
MSG kInvalidCoverageComponents = "components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.";
Expand Down Expand Up @@ -395,6 +398,7 @@ MSG kNonPositiveDrawTextureDimension = "Both width and height argument of drawn
MSG kNoProgramBinaryFormats = "No program binary formats supported.";
MSG kNoReadFramebuffer = "No active read framebuffer.";
MSG kNoSampleAlphaToCoveragesLimitation = "Current renderer doesn't support alpha-to-coverage.";
MSG kNotTextureComplete = "The texture is not complete.";
MSG kNoTransformArray = "No transform array given.";
MSG kNoTransformFeedbackOutputVariables = "The active program has specified no output variables to record.";
MSG kNoZeroDivisor = "At least one enabled attribute must have a divisor of zero.";
Expand Down
42 changes: 42 additions & 0 deletions src/libANGLE/Renderbuffer.cpp
Expand Up @@ -169,6 +169,48 @@ angle::Result Renderbuffer::setStorageEGLImageTarget(const Context *context, egl
return angle::Result::Continue;
}

angle::Result Renderbuffer::copyRenderbufferSubData(Context *context,
const gl::Renderbuffer *srcBuffer,
GLint srcLevel,
GLint srcX,
GLint srcY,
GLint srcZ,
GLint dstLevel,
GLint dstX,
GLint dstY,
GLint dstZ,
GLsizei srcWidth,
GLsizei srcHeight,
GLsizei srcDepth)
{
ANGLE_TRY(mImplementation->copyRenderbufferSubData(context, srcBuffer, srcLevel, srcX, srcY,
srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
srcHeight, srcDepth));

return angle::Result::Continue;
}

angle::Result Renderbuffer::copyTextureSubData(Context *context,
const gl::Texture *srcTexture,
GLint srcLevel,
GLint srcX,
GLint srcY,
GLint srcZ,
GLint dstLevel,
GLint dstX,
GLint dstY,
GLint dstZ,
GLsizei srcWidth,
GLsizei srcHeight,
GLsizei srcDepth)
{
ANGLE_TRY(mImplementation->copyTextureSubData(context, srcTexture, srcLevel, srcX, srcY, srcZ,
dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
srcDepth));

return angle::Result::Continue;
}

rx::RenderbufferImpl *Renderbuffer::getImplementation() const
{
ASSERT(mImplementation);
Expand Down
28 changes: 28 additions & 0 deletions src/libANGLE/Renderbuffer.h
Expand Up @@ -90,6 +90,34 @@ class Renderbuffer final : public RefCountObject<RenderbufferID>,
MultisamplingMode mode);
angle::Result setStorageEGLImageTarget(const Context *context, egl::Image *imageTarget);

angle::Result copyRenderbufferSubData(Context *context,
const gl::Renderbuffer *srcBuffer,
GLint srcLevel,
GLint srcX,
GLint srcY,
GLint srcZ,
GLint dstLevel,
GLint dstX,
GLint dstY,
GLint dstZ,
GLsizei srcWidth,
GLsizei srcHeight,
GLsizei srcDepth);

angle::Result copyTextureSubData(Context *context,
const gl::Texture *srcTexture,
GLint srcLevel,
GLint srcX,
GLint srcY,
GLint srcZ,
GLint dstLevel,
GLint dstX,
GLint dstY,
GLint dstZ,
GLsizei srcWidth,
GLsizei srcHeight,
GLsizei srcDepth);

rx::RenderbufferImpl *getImplementation() const;

GLsizei getWidth() const;
Expand Down
46 changes: 46 additions & 0 deletions src/libANGLE/Texture.cpp
Expand Up @@ -1326,6 +1326,52 @@ angle::Result Texture::copySubImage(Context *context,
return angle::Result::Continue;
}

angle::Result Texture::copyRenderbufferSubData(Context *context,
const gl::Renderbuffer *srcBuffer,
GLint srcLevel,
GLint srcX,
GLint srcY,
GLint srcZ,
GLint dstLevel,
GLint dstX,
GLint dstY,
GLint dstZ,
GLsizei srcWidth,
GLsizei srcHeight,
GLsizei srcDepth)
{
ANGLE_TRY(mTexture->copyRenderbufferSubData(context, srcBuffer, srcLevel, srcX, srcY, srcZ,
dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
srcDepth));

signalDirtyStorage(InitState::Initialized);

return angle::Result::Continue;
}

angle::Result Texture::copyTextureSubData(Context *context,
const gl::Texture *srcTexture,
GLint srcLevel,
GLint srcX,
GLint srcY,
GLint srcZ,
GLint dstLevel,
GLint dstX,
GLint dstY,
GLint dstZ,
GLsizei srcWidth,
GLsizei srcHeight,
GLsizei srcDepth)
{
ANGLE_TRY(mTexture->copyTextureSubData(context, srcTexture, srcLevel, srcX, srcY, srcZ,
dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
srcDepth));

signalDirtyStorage(InitState::Initialized);

return angle::Result::Continue;
}

angle::Result Texture::copyTexture(Context *context,
TextureTarget target,
GLint level,
Expand Down
28 changes: 28 additions & 0 deletions src/libANGLE/Texture.h
Expand Up @@ -390,6 +390,34 @@ class Texture final : public RefCountObject<TextureID>,
const Rectangle &sourceArea,
Framebuffer *source);

angle::Result copyRenderbufferSubData(Context *context,
const gl::Renderbuffer *srcBuffer,
GLint srcLevel,
GLint srcX,
GLint srcY,
GLint srcZ,
GLint dstLevel,
GLint dstX,
GLint dstY,
GLint dstZ,
GLsizei srcWidth,
GLsizei srcHeight,
GLsizei srcDepth);

angle::Result copyTextureSubData(Context *context,
const gl::Texture *srcTexture,
GLint srcLevel,
GLint srcX,
GLint srcY,
GLint srcZ,
GLint dstLevel,
GLint dstX,
GLint dstY,
GLint dstZ,
GLsizei srcWidth,
GLsizei srcHeight,
GLsizei srcDepth);

angle::Result copyTexture(Context *context,
TextureTarget target,
GLint level,
Expand Down

0 comments on commit 1e494ca

Please sign in to comment.