diff --git a/projects/rocjpeg/CMakeLists.txt b/projects/rocjpeg/CMakeLists.txt index 193e729f27..1bdcc10b3a 100644 --- a/projects/rocjpeg/CMakeLists.txt +++ b/projects/rocjpeg/CMakeLists.txt @@ -124,9 +124,18 @@ else() endif() message("-- ${White}${PROJECT_NAME} -- AMD GPU_TARGETS: ${GPU_TARGETS}${ColourReset}") +# Add an option for enabling the rocprofiler-register +option(ROCJPEG_ENABLE_ROCPROFILER_REGISTER "Enable rocprofiler-register support" OFF) + find_package(HIP QUIET) find_package(Libva QUIET) +if(ROCJPEG_ENABLE_ROCPROFILER_REGISTER) + find_package(rocprofiler-register QUIET + HINTS $ENV{rocprofiler_register_ROOT} $ENV{ROCPROFILER_REGISTER_ROOT} ${CMAKE_INSTALL_PREFIX} + PATHS ${ROCM_PATH}) +endif() + if(HIP_FOUND AND Libva_FOUND) # HIP set(LINK_LIBRARY_LIST ${LINK_LIBRARY_LIST} hip::device) @@ -140,6 +149,11 @@ if(HIP_FOUND AND Libva_FOUND) set(LINK_LIBRARY_LIST ${LINK_LIBRARY_LIST} stdc++fs) endif() + # rocprofiler + if(rocprofiler-register_FOUND) + set(LINK_LIBRARY_LIST ${LINK_LIBRARY_LIST} rocprofiler-register::rocprofiler-register) + endif() + # local include files include_directories(api src) # source files @@ -154,6 +168,18 @@ if(HIP_FOUND AND Libva_FOUND) set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX) set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) + # rocprofiler + if(rocprofiler-register_FOUND) + string(REPLACE "." ";" VERSION_LIST ${VERSION}) + list(GET VERSION_LIST 0 VERSION_MAJOR) + list(GET VERSION_LIST 1 VERSION_MINOR) + list(GET VERSION_LIST 2 VERSION_PATCH) + target_compile_definitions(${PROJECT_NAME} PRIVATE ROCJPEG_ROCPROFILER_REGISTER=1 + ROCJPEG_ROCP_REG_VERSION_MAJOR=${VERSION_MAJOR} + ROCJPEG_ROCP_REG_VERSION_MINOR=${VERSION_MINOR} + ROCJPEG_ROCP_REG_VERSION_PATCH=${VERSION_PATCH}) + endif() + # install rocJPEG libs -- {ROCM_PATH}/lib install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT runtime NAMELINK_SKIP) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT dev NAMELINK_ONLY) @@ -161,6 +187,10 @@ if(HIP_FOUND AND Libva_FOUND) # install rocJPEG include files -- {ROCM_PATH}/include/rocJPEG install(FILES api/rocjpeg.h api/rocjpeg_version.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} COMPONENT dev) + # install rocJPEG api trace include file -- {ROCM_PATH}/include/rocjpeg/amd_detail + install(FILES api/amd_detail/rocjpeg_api_trace.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/amd_detail COMPONENT dev) + # install rocJPEG samples -- {ROCM_PATH}/share/rocJPEG install(DIRECTORY cmake DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME} COMPONENT dev) @@ -216,6 +246,12 @@ if(HIP_FOUND AND Libva_FOUND) # Set the dependent packages set(rocJPEG_DEBIAN_PACKAGE_LIST "rocm-hip-runtime, libva2-amdgpu, libva-amdgpu-drm2, libva-amdgpu-wayland2, libva-amdgpu-x11-2, mesa-amdgpu-va-drivers") set(rocJPEG_RPM_PACKAGE_LIST "rocm-hip-runtime, (libva >= 2.16.0 or libva2 >= 2.16.0 or libva-amdgpu), mesa-amdgpu-va-drivers") + # Add rocprofiler-register dependencies + if(ROCJPEG_ENABLE_ROCPROFILER_REGISTER) + set(rocJPEG_DEBIAN_PACKAGE_LIST "${rocJPEG_DEBIAN_PACKAGE_LIST}, rocprofiler-register") + set(rocJPEG_RPM_PACKAGE_LIST "${rocJPEG_RPM_PACKAGE_LIST}, rocprofiler-register") + endif() + set(rocJPEG_DEBIAN_DEV_PACKAGE_LIST "rocm-hip-runtime-dev, libva-amdgpu-dev, pkg-config") if(UBUNTU_22_FOUND) set(rocJPEG_DEBIAN_DEV_PACKAGE_LIST "${rocJPEG_DEBIAN_DEV_PACKAGE_LIST}, libstdc++-12-dev") diff --git a/projects/rocjpeg/api/amd_detail/rocjpeg_api_trace.h b/projects/rocjpeg/api/amd_detail/rocjpeg_api_trace.h new file mode 100644 index 0000000000..80545c86f0 --- /dev/null +++ b/projects/rocjpeg/api/amd_detail/rocjpeg_api_trace.h @@ -0,0 +1,90 @@ +/* +Copyright (c) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#pragma once + +#include "rocjpeg.h" + +// Define version macros for the rocJPEG API dispatch table, specifying the MAJOR and STEP versions. +// +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// +// 1. When adding new functions to the rocJPEG API dispatch table, always append the new function pointer +// to the end of the table and increment the dispatch table's version number. Never rearrange the order of +// the member variables in the dispatch table, as doing so will break the Application Binary Interface (ABI). +// 2. In critical situations where the type of an existing member variable in a dispatch table has been changed +// or removed due to a data type modification, it is important to increment the major version number of the +// rocJPEG API dispatch table. If the function pointer type can no longer be declared, do not remove it. +// Instead, change the function pointer type to `void*` and ensure it is always initialized to `nullptr`. +// +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// + +// The major version number should ideally remain unchanged. Increment the ROCJPEG_RUNTIME_API_TABLE_MAJOR_VERSION only +// for fundamental changes to the rocJPEGDispatchTable struct, such as altering the type or name of an existing member variable. +// Please DO NOT REMOVE it. +#define ROCJPEG_RUNTIME_API_TABLE_MAJOR_VERSION 0 + +// Increment the ROCJPEG_RUNTIME_API_TABLE_STEP_VERSION when new runtime API functions are added. +// If the corresponding ROCJPEG_RUNTIME_API_TABLE_MAJOR_VERSION increases reset the ROCJPEG_RUNTIME_API_TABLE_STEP_VERSION to zero. +#define ROCJPEG_RUNTIME_API_TABLE_STEP_VERSION 0 + +// rocJPEG API interface +typedef RocJpegStatus (ROCJPEGAPI *PfnRocJpegStreamCreate)(RocJpegStreamHandle *jpeg_stream_handle); +typedef RocJpegStatus (ROCJPEGAPI *PfnRocJpegStreamParse)(const unsigned char *data, size_t length, RocJpegStreamHandle jpeg_stream_handle); +typedef RocJpegStatus (ROCJPEGAPI *PfnRocJpegStreamDestroy)(RocJpegStreamHandle jpeg_stream_handle); +typedef RocJpegStatus (ROCJPEGAPI *PfnRocJpegCreate)(RocJpegBackend backend, int device_id, RocJpegHandle *handle); +typedef RocJpegStatus (ROCJPEGAPI *PfnRocJpegDestroy)(RocJpegHandle handle); +typedef RocJpegStatus (ROCJPEGAPI *PfnRocJpegGetImageInfo)(RocJpegHandle handle, RocJpegStreamHandle jpeg_stream_handle, uint8_t *num_components, RocJpegChromaSubsampling *subsampling, uint32_t *widths, uint32_t *heights); +typedef RocJpegStatus (ROCJPEGAPI *PfnRocJpegDecode)(RocJpegHandle handle, RocJpegStreamHandle jpeg_stream_handle, const RocJpegDecodeParams *decode_params, RocJpegImage *destination); +typedef RocJpegStatus (ROCJPEGAPI *PfnRocJpegDecodeBatched)(RocJpegHandle handle, RocJpegStreamHandle *jpeg_stream_handles, int batch_size, const RocJpegDecodeParams *decode_params, RocJpegImage *destinations); +typedef const char* (ROCJPEGAPI *PfnRocJpegGetErrorName)(RocJpegStatus rocjpeg_status); + + +// rocJPEG API dispatch table +struct RocJpegDispatchTable { + // ROCJPEG_RUNTIME_API_TABLE_STEP_VERSION == 0 + size_t size; + PfnRocJpegStreamCreate pfn_rocjpeg_stream_create; + PfnRocJpegStreamParse pfn_rocjpeg_stream_parse; + PfnRocJpegStreamDestroy pfn_rocjpeg_stream_destroy; + PfnRocJpegCreate pfn_rocjpeg_create; + PfnRocJpegDestroy pfn_rocjpeg_destroy; + PfnRocJpegGetImageInfo pfn_rocjpeg_get_image_info; + PfnRocJpegDecode pfn_rocjpeg_decode; + PfnRocJpegDecodeBatched pfn_rocjpeg_decode_batched; + PfnRocJpegGetErrorName pfn_rocjpeg_get_error_name; + + // PLEASE DO NOT EDIT ABOVE! + // ROCJPEG_RUNTIME_API_TABLE_STEP_VERSION == 1 + + // ******************************************************************************************* // + // READ BELOW + // ******************************************************************************************* // + // Please keep this text at the end of the structure: + + // 1. Do not reorder any existing members. + // 2. Increase the step version definition before adding new members. + // 3. Insert new members under the appropriate step version comment. + // 4. Generate a comment for the next step version. + // 5. Add a "PLEASE DO NOT EDIT ABOVE!" comment. + // ******************************************************************************************* // +}; \ No newline at end of file diff --git a/projects/rocjpeg/src/amd_detail/rocjpeg_api_dispatch_interface.cpp b/projects/rocjpeg/src/amd_detail/rocjpeg_api_dispatch_interface.cpp new file mode 100644 index 0000000000..e02abae8ed --- /dev/null +++ b/projects/rocjpeg/src/amd_detail/rocjpeg_api_dispatch_interface.cpp @@ -0,0 +1,55 @@ +/* +Copyright (c) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#include "../../api/amd_detail/rocjpeg_api_trace.h" + +namespace rocjpeg { +const RocJpegDispatchTable* GetRocJpegDispatchTable(); +} //namespace rocjpeg + + +RocJpegStatus ROCJPEGAPI rocJpegStreamCreate(RocJpegStreamHandle *jpeg_stream_handle) { + return rocjpeg::GetRocJpegDispatchTable()->pfn_rocjpeg_stream_create(jpeg_stream_handle); +} +RocJpegStatus ROCJPEGAPI rocJpegStreamParse(const unsigned char *data, size_t length, RocJpegStreamHandle jpeg_stream_handle) { + return rocjpeg::GetRocJpegDispatchTable()->pfn_rocjpeg_stream_parse(data, length, jpeg_stream_handle); +} +RocJpegStatus ROCJPEGAPI rocJpegStreamDestroy(RocJpegStreamHandle jpeg_stream_handle) { + return rocjpeg::GetRocJpegDispatchTable()->pfn_rocjpeg_stream_destroy(jpeg_stream_handle); +} +RocJpegStatus ROCJPEGAPI rocJpegCreate(RocJpegBackend backend, int device_id, RocJpegHandle *handle) { + return rocjpeg::GetRocJpegDispatchTable()->pfn_rocjpeg_create(backend, device_id, handle); +} +RocJpegStatus ROCJPEGAPI rocJpegDestroy(RocJpegHandle handle) { + return rocjpeg::GetRocJpegDispatchTable()->pfn_rocjpeg_destroy(handle); +} +RocJpegStatus ROCJPEGAPI rocJpegGetImageInfo(RocJpegHandle handle, RocJpegStreamHandle jpeg_stream_handle, uint8_t *num_components, RocJpegChromaSubsampling *subsampling, uint32_t *widths, uint32_t *heights) { + return rocjpeg::GetRocJpegDispatchTable()->pfn_rocjpeg_get_image_info(handle, jpeg_stream_handle, num_components, subsampling, widths, heights); +} +RocJpegStatus ROCJPEGAPI rocJpegDecode(RocJpegHandle handle, RocJpegStreamHandle jpeg_stream_handle, const RocJpegDecodeParams *decode_params, RocJpegImage *destination) { + return rocjpeg::GetRocJpegDispatchTable()->pfn_rocjpeg_decode(handle, jpeg_stream_handle, decode_params, destination); +} +RocJpegStatus ROCJPEGAPI rocJpegDecodeBatched(RocJpegHandle handle, RocJpegStreamHandle *jpeg_stream_handles, int batch_size, const RocJpegDecodeParams *decode_params, RocJpegImage *destinations) { + return rocjpeg::GetRocJpegDispatchTable()->pfn_rocjpeg_decode_batched(handle, jpeg_stream_handles, batch_size, decode_params, destinations); +} +const char* ROCJPEGAPI rocJpegGetErrorName(RocJpegStatus rocjpeg_status) { + return rocjpeg::GetRocJpegDispatchTable()->pfn_rocjpeg_get_error_name(rocjpeg_status); +} \ No newline at end of file diff --git a/projects/rocjpeg/src/amd_detail/rocjpeg_api_trace.cpp b/projects/rocjpeg/src/amd_detail/rocjpeg_api_trace.cpp new file mode 100644 index 0000000000..a234775bc0 --- /dev/null +++ b/projects/rocjpeg/src/amd_detail/rocjpeg_api_trace.cpp @@ -0,0 +1,162 @@ +/* +Copyright (c) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#include "../../api/amd_detail/rocjpeg_api_trace.h" + +#if defined(ROCJPEG_ROCPROFILER_REGISTER) && ROCJPEG_ROCPROFILER_REGISTER > 0 +#include + +#define ROCJPEG_ROCP_REG_VERSION \ + ROCPROFILER_REGISTER_COMPUTE_VERSION_3(ROCJPEG_ROCP_REG_VERSION_MAJOR, ROCJPEG_ROCP_REG_VERSION_MINOR, \ + ROCJPEG_ROCP_REG_VERSION_PATCH) + +ROCPROFILER_REGISTER_DEFINE_IMPORT(rocjpeg, ROCJPEG_ROCP_REG_VERSION) +#elif !defined(ROCJPEG_ROCPROFILER_REGISTER) +#define ROCJPEG_ROCPROFILER_REGISTER 0 +#endif + +namespace rocjpeg { +RocJpegStatus ROCJPEGAPI rocJpegStreamCreate(RocJpegStreamHandle *jpeg_stream_handle); +RocJpegStatus ROCJPEGAPI rocJpegStreamParse(const unsigned char *data, size_t length, RocJpegStreamHandle jpeg_stream_handle); +RocJpegStatus ROCJPEGAPI rocJpegStreamDestroy(RocJpegStreamHandle jpeg_stream_handle); +RocJpegStatus ROCJPEGAPI rocJpegCreate(RocJpegBackend backend, int device_id, RocJpegHandle *handle); +RocJpegStatus ROCJPEGAPI rocJpegDestroy(RocJpegHandle handle); +RocJpegStatus ROCJPEGAPI rocJpegGetImageInfo(RocJpegHandle handle, RocJpegStreamHandle jpeg_stream_handle, uint8_t *num_components, RocJpegChromaSubsampling *subsampling, uint32_t *widths, uint32_t *heights); +RocJpegStatus ROCJPEGAPI rocJpegDecode(RocJpegHandle handle, RocJpegStreamHandle jpeg_stream_handle, const RocJpegDecodeParams *decode_params, RocJpegImage *destination); +RocJpegStatus ROCJPEGAPI rocJpegDecodeBatched(RocJpegHandle handle, RocJpegStreamHandle *jpeg_stream_handles, int batch_size, const RocJpegDecodeParams *decode_params, RocJpegImage *destinations); +const char* ROCJPEGAPI rocJpegGetErrorName(RocJpegStatus rocjpeg_status); +} + +namespace rocjpeg { +namespace { +void UpdateDispatchTable(RocJpegDispatchTable* ptr_dispatch_table) { + ptr_dispatch_table->size = sizeof(RocJpegDispatchTable); + ptr_dispatch_table->pfn_rocjpeg_stream_create = rocjpeg::rocJpegStreamCreate; + ptr_dispatch_table->pfn_rocjpeg_stream_parse = rocjpeg::rocJpegStreamParse; + ptr_dispatch_table->pfn_rocjpeg_stream_destroy = rocjpeg::rocJpegStreamDestroy; + ptr_dispatch_table->pfn_rocjpeg_create = rocjpeg::rocJpegCreate; + ptr_dispatch_table->pfn_rocjpeg_destroy = rocjpeg::rocJpegDestroy; + ptr_dispatch_table->pfn_rocjpeg_get_image_info = rocjpeg::rocJpegGetImageInfo; + ptr_dispatch_table->pfn_rocjpeg_decode = rocjpeg::rocJpegDecode; + ptr_dispatch_table->pfn_rocjpeg_decode_batched = rocjpeg::rocJpegDecodeBatched; + ptr_dispatch_table->pfn_rocjpeg_get_error_name = rocjpeg::rocJpegGetErrorName; +} + +#if ROCJPEG_ROCPROFILER_REGISTER > 0 +template struct dispatch_table_info; + +#define ROCJPEG_DEFINE_DISPATCH_TABLE_INFO(TYPE, NAME) \ +template <> struct dispatch_table_info { \ + static constexpr auto name = #NAME; \ + static constexpr auto version = ROCJPEG_ROCP_REG_VERSION; \ + static constexpr auto import_func = &ROCPROFILER_REGISTER_IMPORT_FUNC(NAME); \ +}; + +constexpr auto ComputeTableSize(size_t num_funcs) { + return (num_funcs * sizeof(void*)) + sizeof(uint64_t); +} + +ROCJPEG_DEFINE_DISPATCH_TABLE_INFO(RocJpegDispatchTable, rocjpeg) +#endif + +template void ToolInit(Tp* table) { +#if ROCJPEG_ROCPROFILER_REGISTER > 0 + auto table_array = std::array{static_cast(table)}; + auto lib_id = rocprofiler_register_library_indentifier_t{}; + auto rocp_reg_status = rocprofiler_register_library_api_table( + dispatch_table_info::name, dispatch_table_info::import_func, + dispatch_table_info::version, table_array.data(), table_array.size(), &lib_id); + + bool report_register_errors = false; + if (report_register_errors && rocp_reg_status != ROCP_REG_SUCCESS) + fprintf(stderr, "rocprofiler-register failed for %s with error code %i: %s\n", + dispatch_table_info::name, rocp_reg_status, rocprofiler_register_error_string(rocp_reg_status)); +#else + (void)table; +#endif +} + +template Tp& GetDispatchTableImpl() { + static auto dispatch_table = Tp{}; + // Update all function pointers to reference the runtime implementation functions of rocJPEG. + UpdateDispatchTable(&dispatch_table); + // The profiler registration process may encapsulate the function pointers. + ToolInit(&dispatch_table); + return dispatch_table; +} +} //namespace + +const RocJpegDispatchTable* GetRocJpegDispatchTable() { + static auto* rocjpeg_dispatch_table = &GetDispatchTableImpl(); + return rocjpeg_dispatch_table; +} +} //namespace rocjpeg + +#if !defined(_WIN32) +constexpr auto ComputeTableOffset(size_t num_funcs) { + return (num_funcs * sizeof(void*)) + sizeof(size_t); +} + +// The `ROCJPEG_ENFORCE_ABI_VERSIONING` macro will trigger a compiler error if the size of the rocJPEG dispatch API table changes, +// which is most likely due to the addition of a new dispatch table entry. This serves as a reminder for developers to update the table +// versioning value before changing the value in `ROCJPEG_ENFORCE_ABI_VERSIONING`, ensuring that this static assertion passes. +// +// The `ROCJPEG_ENFORCE_ABI` macro will also trigger a compiler error if the order of the members in the rocJPEG dispatch API table +// is altered. Therefore, it is essential to avoid reordering member variables. +// +// Please be aware that `rocprofiler` performs strict compile-time checks to ensure that these versioning values are correctly updated. +// Commenting out this check or merely updating the size field in `ROCJPEG_ENFORCE_ABI_VERSIONING` will cause the `rocprofiler` to fail +// during the build process. +#define ROCJPEG_ENFORCE_ABI_VERSIONING(TABLE, NUM) \ + static_assert( \ + sizeof(TABLE) == ComputeTableOffset(NUM), \ + "The size of the API table structure has been updated. Please modify the " \ + "STEP_VERSION number (or, in rare cases, the MAJOR_VERSION number) " \ + "in for the failing API " \ + "structure before changing the SIZE field passed to ROCJPEG_DEFINE_DISPATCH_TABLE_INFO."); + +#define ROCJPEG_ENFORCE_ABI(TABLE, ENTRY, NUM) \ + static_assert(offsetof(TABLE, ENTRY) == ComputeTableOffset(NUM), \ + "ABI broke for " #TABLE "." #ENTRY \ + ", only add new function pointers at the end of the struct and do not rearrange them."); + +// These ensure that function pointers are not re-ordered +// ROCJPEG_RUNTIME_API_TABLE_STEP_VERSION == 0 +ROCJPEG_ENFORCE_ABI(RocJpegDispatchTable, pfn_rocjpeg_stream_create, 0) +ROCJPEG_ENFORCE_ABI(RocJpegDispatchTable, pfn_rocjpeg_stream_parse, 1) +ROCJPEG_ENFORCE_ABI(RocJpegDispatchTable, pfn_rocjpeg_stream_destroy, 2) +ROCJPEG_ENFORCE_ABI(RocJpegDispatchTable, pfn_rocjpeg_create, 3) +ROCJPEG_ENFORCE_ABI(RocJpegDispatchTable, pfn_rocjpeg_destroy, 4) +ROCJPEG_ENFORCE_ABI(RocJpegDispatchTable, pfn_rocjpeg_get_image_info, 5) +ROCJPEG_ENFORCE_ABI(RocJpegDispatchTable, pfn_rocjpeg_decode, 6) +ROCJPEG_ENFORCE_ABI(RocJpegDispatchTable, pfn_rocjpeg_decode_batched, 7) +ROCJPEG_ENFORCE_ABI(RocJpegDispatchTable, pfn_rocjpeg_get_error_name, 8) + +// If ROCJPEG_ENFORCE_ABI entries are added for each new function pointer in the table, +// the number below will be one greater than the number in the last ROCJPEG_ENFORCE_ABI line. For example: +// ROCJPEG_ENFORCE_ABI(, , 8) +// ROCJPEG_ENFORCE_ABI_VERSIONING(
, 9) <- 8 + 1 = 9 +ROCJPEG_ENFORCE_ABI_VERSIONING(RocJpegDispatchTable, 9) + +static_assert(ROCJPEG_RUNTIME_API_TABLE_MAJOR_VERSION == 0 && ROCJPEG_RUNTIME_API_TABLE_STEP_VERSION == 0, + "If you encounter this error, add the new ROCJPEG_ENFORCE_ABI(...) code for the updated function pointers, " + "and then modify this check to ensure it evaluates to true."); +#endif \ No newline at end of file diff --git a/projects/rocjpeg/src/rocjpeg_api.cpp b/projects/rocjpeg/src/rocjpeg_api.cpp index aa8914ff1a..38028e42f0 100644 --- a/projects/rocjpeg/src/rocjpeg_api.cpp +++ b/projects/rocjpeg/src/rocjpeg_api.cpp @@ -24,6 +24,7 @@ THE SOFTWARE. #include "rocjpeg_api_decoder_handle.h" #include "rocjpeg_commons.h" +namespace rocjpeg { /** * @brief Creates a RocJpegStreamHandle for JPEG stream processing. * @@ -274,4 +275,5 @@ extern const char* ROCJPEGAPI rocJpegGetErrorName(RocJpegStatus rocjpeg_status) default: return "UNKNOWN_ERROR"; } -} \ No newline at end of file +} +} //namespace rocjpeg \ No newline at end of file