From 18124d727865f1c53b0dac644560bce177b7d233 Mon Sep 17 00:00:00 2001 From: Indrajit Kumar Das Date: Mon, 20 Jan 2020 14:19:47 +0530 Subject: [PATCH] glapi/copyimage: Implement CopyImageSubDataNV MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Implement CopyImageSubDataNV from NV_copy_image spec. This is derived out of the existing implementation of CopyImageSubData. It differs from CopyImageSubData in accordance with the differences laid down in the ARB_copy_image spec. Reviewed-by: Marek Olšák Tested-by: Marge Bot Part-of: --- docs/relnotes/new_features.txt | 1 + src/mapi/glapi/gen/NV_copy_image.xml | 27 ++++ src/mapi/glapi/gen/gl_API.xml | 2 + src/mapi/glapi/gen/meson.build | 1 + src/mapi/glapi/gen/static_data.py | 1 + src/mesa/main/copyimage.c | 200 +++++++++++++++++++++--- src/mesa/main/copyimage.h | 14 ++ src/mesa/main/extensions_table.h | 1 + src/mesa/main/mtypes.h | 1 + src/mesa/main/tests/dispatch_sanity.cpp | 3 + src/mesa/state_tracker/st_extensions.c | 1 + 11 files changed, 226 insertions(+), 26 deletions(-) create mode 100644 src/mapi/glapi/gen/NV_copy_image.xml diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt index 2fe8ecaf8df..7d8597d2ee4 100644 --- a/docs/relnotes/new_features.txt +++ b/docs/relnotes/new_features.txt @@ -1 +1,2 @@ +GL_NV_copy_image VK_KHR_shader_non_semantic_info on Intel, RADV. diff --git a/src/mapi/glapi/gen/NV_copy_image.xml b/src/mapi/glapi/gen/NV_copy_image.xml new file mode 100644 index 00000000000..9fe144cde10 --- /dev/null +++ b/src/mapi/glapi/gen/NV_copy_image.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml index 1cee28f3105..154f85cd4d5 100644 --- a/src/mapi/glapi/gen/gl_API.xml +++ b/src/mapi/glapi/gen/gl_API.xml @@ -12964,6 +12964,8 @@ + + Name) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyImageSubData(%sName incomplete)", dbg_prefix); + "glCopyImageSubData%s(%sName incomplete)", suffix, dbg_prefix); return false; } if (level != 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level); + "glCopyImageSubData%s(%sLevel = %u)", suffix, dbg_prefix, level); return false; } @@ -145,7 +148,7 @@ prepare_target_err(struct gl_context *ctx, GLuint name, GLenum target, * to the corresponding target parameter." */ _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyImageSubData(%sName = %u)", dbg_prefix, name); + "glCopyImageSubData%s(%sName = %u)", suffix, dbg_prefix, name); return false; } @@ -208,7 +211,7 @@ prepare_target_err(struct gl_context *ctx, GLuint name, GLenum target, : texObj->_BaseComplete; if (!texture_complete_aside_from_formats) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyImageSubData(%sName incomplete)", dbg_prefix); + "glCopyImageSubData%s(%sName incomplete)", suffix, dbg_prefix); return false; } @@ -220,14 +223,14 @@ prepare_target_err(struct gl_context *ctx, GLuint name, GLenum target, * of the object." */ _mesa_error(ctx, GL_INVALID_ENUM, - "glCopyImageSubData(%sTarget = %s)", dbg_prefix, + "glCopyImageSubData%s(%sTarget = %s)", suffix, dbg_prefix, _mesa_enum_to_string(target)); return false; } if (level < 0 || level >= MAX_TEXTURE_LEVELS) { _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyImageSubData(%sLevel = %d)", dbg_prefix, level); + "glCopyImageSubData%s(%sLevel = %d)", suffix, dbg_prefix, level); return false; } @@ -254,7 +257,7 @@ prepare_target_err(struct gl_context *ctx, GLuint name, GLenum target, if (!*tex_image) { _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level); + "glCopyImageSubData%s(%sLevel = %u)", suffix, dbg_prefix, level); return false; } @@ -305,21 +308,23 @@ check_region_bounds(struct gl_context *ctx, const struct gl_texture_image *tex_image, const struct gl_renderbuffer *renderbuffer, int x, int y, int z, int width, int height, int depth, - const char *dbg_prefix) + const char *dbg_prefix, + bool is_arb_version) { int surfWidth, surfHeight, surfDepth; + const char *suffix = is_arb_version ? "" : "NV"; if (width < 0 || height < 0 || depth < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyImageSubData(%sWidth, %sHeight, or %sDepth is negative)", - dbg_prefix, dbg_prefix, dbg_prefix); + "glCopyImageSubData%s(%sWidth, %sHeight, or %sDepth is negative)", + suffix, dbg_prefix, dbg_prefix, dbg_prefix); return false; } if (x < 0 || y < 0 || z < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyImageSubData(%sX, %sY, or %sZ is negative)", - dbg_prefix, dbg_prefix, dbg_prefix); + "glCopyImageSubData%s(%sX, %sY, or %sZ is negative)", + suffix, dbg_prefix, dbg_prefix, dbg_prefix); return false; } @@ -333,8 +338,8 @@ check_region_bounds(struct gl_context *ctx, if (x + width > surfWidth) { _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyImageSubData(%sX or %sWidth exceeds image bounds)", - dbg_prefix, dbg_prefix); + "glCopyImageSubData%s(%sX or %sWidth exceeds image bounds)", + suffix, dbg_prefix, dbg_prefix); return false; } @@ -353,8 +358,8 @@ check_region_bounds(struct gl_context *ctx, if (y + height > surfHeight) { _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyImageSubData(%sY or %sHeight exceeds image bounds)", - dbg_prefix, dbg_prefix); + "glCopyImageSubData%s(%sY or %sHeight exceeds image bounds)", + suffix, dbg_prefix, dbg_prefix); return false; } @@ -379,8 +384,8 @@ check_region_bounds(struct gl_context *ctx, if (z < 0 || z + depth > surfDepth) { _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)", - dbg_prefix, dbg_prefix); + "glCopyImageSubData%s(%sZ or %sDepth exceeds image bounds)", + suffix, dbg_prefix, dbg_prefix); return false; } @@ -630,13 +635,13 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, if (!prepare_target_err(ctx, srcName, srcTarget, srcLevel, srcZ, srcDepth, &srcTexImage, &srcRenderbuffer, &srcFormat, &srcIntFormat, &src_w, &src_h, &src_num_samples, - "src")) + "src",true)) return; if (!prepare_target_err(ctx, dstName, dstTarget, dstLevel, dstZ, srcDepth, &dstTexImage, &dstRenderbuffer, &dstFormat, &dstIntFormat, &dst_w, &dst_h, &dst_num_samples, - "dst")) + "dst",true)) return; _mesa_get_format_block_size(srcFormat, &src_bw, &src_bh); @@ -698,12 +703,12 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, if (!check_region_bounds(ctx, srcTarget, srcTexImage, srcRenderbuffer, srcX, srcY, srcZ, srcWidth, srcHeight, srcDepth, - "src")) + "src", true)) return; if (!check_region_bounds(ctx, dstTarget, dstTexImage, dstRenderbuffer, dstX, dstY, dstZ, dstWidth, dstHeight, dstDepth, - "dst")) + "dst", true)) return; /* Section 18.3.2 (Copying Between Images) of the OpenGL 4.5 Core Profile @@ -729,3 +734,146 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, srcLevel, dstTexImage, dstRenderbuffer, dstX, dstY, dstZ, dstLevel, srcWidth, srcHeight, srcDepth); } + +void GLAPIENTRY +_mesa_CopyImageSubDataNV_no_error(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, + GLuint dstName, GLenum dstTarget, GLint dstLevel, + GLint dstX, GLint dstY, GLint dstZ, + GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) +{ + struct gl_texture_image *srcTexImage, *dstTexImage; + struct gl_renderbuffer *srcRenderbuffer, *dstRenderbuffer; + + GET_CURRENT_CONTEXT(ctx); + + prepare_target(ctx, srcName, srcTarget, srcLevel, srcZ, &srcTexImage, + &srcRenderbuffer); + + prepare_target(ctx, dstName, dstTarget, dstLevel, dstZ, &dstTexImage, + &dstRenderbuffer); + + copy_image_subdata(ctx, srcTexImage, srcRenderbuffer, srcX, srcY, srcZ, + srcLevel, dstTexImage, dstRenderbuffer, dstX, dstY, dstZ, + dstLevel, srcWidth, srcHeight, srcDepth); +} + +void GLAPIENTRY +_mesa_CopyImageSubDataNV(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, + GLuint dstName, GLenum dstTarget, GLint dstLevel, + GLint dstX, GLint dstY, GLint dstZ, + GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_image *srcTexImage, *dstTexImage; + struct gl_renderbuffer *srcRenderbuffer, *dstRenderbuffer; + mesa_format srcFormat, dstFormat; + GLenum srcIntFormat, dstIntFormat; + GLuint src_w, src_h, dst_w, dst_h; + GLuint src_bw, src_bh, dst_bw, dst_bh; + GLuint src_num_samples, dst_num_samples; + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glCopyImageSubDataNV(%u, %s, %d, %d, %d, %d, " + "%u, %s, %d, %d, %d, %d, " + "%d, %d, %d)\n", + srcName, _mesa_enum_to_string(srcTarget), srcLevel, + srcX, srcY, srcZ, + dstName, _mesa_enum_to_string(dstTarget), dstLevel, + dstX, dstY, dstZ, + srcWidth, srcHeight, srcDepth); + + if (!ctx->Extensions.NV_copy_image) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyImageSubDataNV(extension not available)"); + return; + } + + if (!prepare_target_err(ctx, srcName, srcTarget, srcLevel, srcZ, srcDepth, + &srcTexImage, &srcRenderbuffer, &srcFormat, + &srcIntFormat, &src_w, &src_h, &src_num_samples, + "src", false)) + return; + + if (!prepare_target_err(ctx, dstName, dstTarget, dstLevel, dstZ, srcDepth, + &dstTexImage, &dstRenderbuffer, &dstFormat, + &dstIntFormat, &dst_w, &dst_h, &dst_num_samples, + "dst", false)) + return; + + /* + * The NV_copy_image spec says: + * + * INVALID_OPERATION is generated if either object is a texture + * and the texture is not consistent, or if the source and destination + * internal formats or number of samples do not match. + * + * In the absence of any definition of texture consistency the texture + * completeness check, which is affected in the prepare_target_err function, + * is used instead in keeping with the ARB version. + * The check related to the internal format here is different from the ARB + * version which adds the ability to copy between images which have + * different formats where the formats are compatible for texture views. + */ + if (srcIntFormat != dstIntFormat) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyImageSubDataNV(internalFormat mismatch)"); + return; + } + + if (src_num_samples != dst_num_samples) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyImageSubDataNV(number of samples mismatch)"); + return; + } + + /* + * The NV_copy_image spec says: + * + * INVALID_VALUE is generated if the image format is compressed + * and the dimensions of the subregion fail to meet the alignment + * constraints of the format. + * + * The check here is identical to the ARB version. + */ + _mesa_get_format_block_size(srcFormat, &src_bw, &src_bh); + if ((srcX % src_bw != 0) || (srcY % src_bh != 0) || + (srcWidth % src_bw != 0 && (srcX + srcWidth) != src_w) || + (srcHeight % src_bh != 0 && (srcY + srcHeight) != src_h)) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubDataNV(unaligned src rectangle)"); + return; + } + + _mesa_get_format_block_size(dstFormat, &dst_bw, &dst_bh); + if ((dstX % dst_bw != 0) || (dstY % dst_bh != 0)) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubDataNV(unaligned dst rectangle)"); + return; + } + + /* + * The NV_copy_image spec says: + * + * INVALID_VALUE is generated if the dimensions of the either subregion + * exceeds the boundaries of the corresponding image object. + * + * The check here is similar to the ARB version except for the fact that + * block sizes are not considered owing to the fact that copying across + * compressed and uncompressed formats is not supported. + */ + if (!check_region_bounds(ctx, srcTarget, srcTexImage, srcRenderbuffer, + srcX, srcY, srcZ, srcWidth, srcHeight, srcDepth, + "src", false)) + return; + + if (!check_region_bounds(ctx, dstTarget, dstTexImage, dstRenderbuffer, + dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth, + "dst", false)) + return; + + copy_image_subdata(ctx, srcTexImage, srcRenderbuffer, srcX, srcY, srcZ, + srcLevel, dstTexImage, dstRenderbuffer, dstX, dstY, dstZ, + dstLevel, srcWidth, srcHeight, srcDepth); +} diff --git a/src/mesa/main/copyimage.h b/src/mesa/main/copyimage.h index 7cebb30d997..09f6dca3bdf 100644 --- a/src/mesa/main/copyimage.h +++ b/src/mesa/main/copyimage.h @@ -49,6 +49,20 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint destX, GLint destY, GLint destZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +void GLAPIENTRY +_mesa_CopyImageSubDataNV_no_error(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, + GLuint destName, GLenum destTarget, GLint destLevel, + GLint destX, GLint destY, GLint destZ, + GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); + +extern void GLAPIENTRY +_mesa_CopyImageSubDataNV(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, + GLuint destName, GLenum destTarget, GLint destLevel, + GLint destX, GLint destY, GLint destZ, + GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); + #ifdef __cplusplus } #endif diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h index 1f5d88e412b..0301590223d 100644 --- a/src/mesa/main/extensions_table.h +++ b/src/mesa/main/extensions_table.h @@ -378,6 +378,7 @@ EXT(NV_conservative_raster , NV_conservative_raster EXT(NV_conservative_raster_dilate , NV_conservative_raster_dilate , GLL, GLC, ES1, ES2, 2015) EXT(NV_conservative_raster_pre_snap , NV_conservative_raster_pre_snap , GLL, GLC, ES1, ES2, 2017) EXT(NV_conservative_raster_pre_snap_triangles, NV_conservative_raster_pre_snap_triangles, GLL, GLC, ES1, ES2, 2015) +EXT(NV_copy_image , NV_copy_image , GLL, GLC, x , x, 2009) EXT(NV_depth_clamp , ARB_depth_clamp , GLL, GLC, x , x , 2001) EXT(NV_draw_buffers , dummy_true , x , x , x , ES2, 2011) EXT(NV_fbo_color_attachments , dummy_true , x , x , x , ES2, 2010) diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index db4921d0106..2ad1ffd82cd 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -4394,6 +4394,7 @@ struct gl_extensions GLboolean MESA_ycbcr_texture; GLboolean NV_compute_shader_derivatives; GLboolean NV_conditional_render; + GLboolean NV_copy_image; GLboolean NV_fill_rectangle; GLboolean NV_fog_distance; GLboolean NV_point_sprite; diff --git a/src/mesa/main/tests/dispatch_sanity.cpp b/src/mesa/main/tests/dispatch_sanity.cpp index 0a86c127d05..e0324bd54d2 100644 --- a/src/mesa/main/tests/dispatch_sanity.cpp +++ b/src/mesa/main/tests/dispatch_sanity.cpp @@ -563,6 +563,9 @@ const struct function common_desktop_functions_possible[] = { { "glEGLImageTargetTexStorageEXT", 31, -1 }, { "glEGLImageTargetTextureStorageEXT", 31, -1 }, + /* GL_NV_copy_image */ + { "glCopyImageSubDataNV", 31, -1 }, + /* GL 3.2 */ { "glGetInteger64i_v", 32, -1 }, { "glGetBufferParameteri64v", 32, -1 }, diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index f3d13d7ad8c..446c9b5a618 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -1036,6 +1036,7 @@ void st_init_extensions(struct pipe_screen *screen, extensions->MESA_framebuffer_flip_y = GL_TRUE; extensions->MESA_pack_invert = GL_TRUE; + extensions->NV_copy_image = GL_TRUE; extensions->NV_fog_distance = GL_TRUE; extensions->NV_texture_env_combine4 = GL_TRUE; extensions->NV_texture_rectangle = GL_TRUE; -- 2.30.2