Update amdgpu-windows-interop with latest changes (#1718)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
이 커밋은 다음에 포함됨:
systems-assistant[bot]
2025-11-05 21:13:32 +01:00
커밋한 사람 GitHub
부모 280cda3196
커밋 321e497048
136개의 변경된 파일44376개의 추가작업 그리고 44160개의 파일을 삭제
+92 -92
파일 보기
@@ -1,92 +1,92 @@
## ##
####################################################################################################################### #######################################################################################################################
# #
# Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved. # Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved.
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal # of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights # in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is # copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions: # furnished to do so, subject to the following conditions:
# #
# The above copyright notice and this permission notice shall be included in all # The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software. # copies or substantial portions of the Software.
# #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE. # SOFTWARE.
# #
####################################################################################################################### #######################################################################################################################
cmake_minimum_required(VERSION 3.21) cmake_minimum_required(VERSION 3.21)
project(PAL LANGUAGES CXX) project(PAL LANGUAGES CXX)
add_library(pal INTERFACE) add_library(pal INTERFACE)
set_target_properties(pal PROPERTIES set_target_properties(pal PROPERTIES
CXX_STANDARD 20 CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF CXX_EXTENSIONS OFF
POSITION_INDEPENDENT_CODE TRUE POSITION_INDEPENDENT_CODE TRUE
) )
target_compile_features(pal INTERFACE cxx_std_20) target_compile_features(pal INTERFACE cxx_std_20)
if (NOT PAL_CLIENT_INTERFACE_MAJOR_VERSION EQUAL 932) if (NOT PAL_CLIENT_INTERFACE_MAJOR_VERSION EQUAL 932)
message(WARNING "PAL: PAL_CLIENT_INTERFACE_MAJOR_VERSION ${PAL_CLIENT_INTERFACE_MAJOR_VERSION} not supported !!!") message(WARNING "PAL: PAL_CLIENT_INTERFACE_MAJOR_VERSION ${PAL_CLIENT_INTERFACE_MAJOR_VERSION} not supported !!!")
endif() endif()
target_link_libraries(pal target_link_libraries(pal
INTERFACE INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/pal.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/pal.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/palCompilerDeps.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/palCompilerDeps.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/palUtil.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/palUtil.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/pal_uuid.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/pal_uuid.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/cwpack.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/cwpack.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/pal_lz4.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/pal_lz4.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/addrlib.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/addrlib.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/amdrdf.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/amdrdf.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/zstd.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/zstd.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/vam.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/vam.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/UberTraceService.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/UberTraceService.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/DriverUtilsService.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/DriverUtilsService.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/dd_settings.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/dd_settings.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/SettingsRpcService2.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/SettingsRpcService2.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddRpcServer.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddRpcServer.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddNet.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddNet.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddRpcShared.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddRpcShared.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddSocket.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddSocket.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/devdriver.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/devdriver.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/dd_common.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/dd_common.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddCommon.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddCommon.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddCore.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddCore.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/dd_libyaml.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/dd_libyaml.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/mpack.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/mpack.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/metrohash.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/metrohash.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/stb_sprintf.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/stb_sprintf.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddRpcClient.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddRpcClient.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddEventStreamer.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddEventStreamer.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddEventClient.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddEventClient.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddEventParser.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddEventParser.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddEventServer.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddEventServer.lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddYaml.lib ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/x64/ddYaml.lib
SetupAPI.Lib SetupAPI.Lib
) )
target_compile_definitions(pal target_compile_definitions(pal
INTERFACE INTERFACE
PAL_CLIENT_INTERFACE_MAJOR_VERSION=932 PAL_CLIENT_INTERFACE_MAJOR_VERSION=932
GPUOPEN_CLIENT_INTERFACE_MAJOR_VERSION=42 GPUOPEN_CLIENT_INTERFACE_MAJOR_VERSION=42
PAL_BUILD_RDF=1 PAL_BUILD_RDF=1
PAL_DEVELOPER_BUILD=0 PAL_DEVELOPER_BUILD=0
PAL_KMT_BUILD=1 PAL_KMT_BUILD=1
) )
target_include_directories(pal target_include_directories(pal
INTERFACE INTERFACE
inc inc
inc/core inc/core
inc/gpuUtil inc/gpuUtil
inc/util inc/util
shared/inc shared/inc
shared/devdriver/shared/legacy/inc shared/devdriver/shared/legacy/inc
shared/devdriver/third_party/dd_crc32/inc shared/devdriver/third_party/dd_crc32/inc
shared/metrohash/src shared/metrohash/src
) )
+21 -21
파일 보기
@@ -1,21 +1,21 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved. Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+204 -204
파일 보기
@@ -1,204 +1,204 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palCmdAllocator.h * @file palCmdAllocator.h
* @brief Defines the Platform Abstraction Library (PAL) ICmdAllocator interface and related types. * @brief Defines the Platform Abstraction Library (PAL) ICmdAllocator interface and related types.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "pal.h" #include "pal.h"
#include "palDestroyable.h" #include "palDestroyable.h"
namespace Pal namespace Pal
{ {
// Forward declarations. // Forward declarations.
struct GpuMemSubAllocInfo; struct GpuMemSubAllocInfo;
class IGpuMemory; class IGpuMemory;
/// Flags controlling the creation of ICmdAllocator objects. /// Flags controlling the creation of ICmdAllocator objects.
union CmdAllocatorCreateFlags union CmdAllocatorCreateFlags
{ {
struct struct
{ {
uint32 threadSafe : 1; ///< If set, the allocator will acquire a lock each time it is accessed; uint32 threadSafe : 1; ///< If set, the allocator will acquire a lock each time it is accessed;
/// otherwise it will not attempt to protect itself from multithreaded /// otherwise it will not attempt to protect itself from multithreaded
/// access. /// access.
uint32 autoMemoryReuse : 1; ///< If set, the allocator will track when the GPU finishes accessing uint32 autoMemoryReuse : 1; ///< If set, the allocator will track when the GPU finishes accessing
/// each piece of command memory and attempt to reuse memory which the /// each piece of command memory and attempt to reuse memory which the
/// GPU is done with before allocating more memory from the OS. If not /// GPU is done with before allocating more memory from the OS. If not
/// set, memory will only be recycled after a call to /// set, memory will only be recycled after a call to
/// @ref ICmdAllocator::Reset(). /// @ref ICmdAllocator::Reset().
uint32 disableBusyChunkTracking : 1; ///< If set, the allocator will not do any GPU-side tracking of which uint32 disableBusyChunkTracking : 1; ///< If set, the allocator will not do any GPU-side tracking of which
/// command chunks are still in use. It will be the client's (or the /// command chunks are still in use. It will be the client's (or the
/// application's) responsibility to guarantee that command chunks are /// application's) responsibility to guarantee that command chunks are
/// not returned to the allocator before the GPU has finished processing /// not returned to the allocator before the GPU has finished processing
/// them. Failure to guarantee this will result in undefined behavior. /// them. Failure to guarantee this will result in undefined behavior.
/// This flag has no effect if @ref autoMemoryReuse is not set. /// This flag has no effect if @ref autoMemoryReuse is not set.
uint32 autoTrimMemory : 1; ///< If set the allocator will automatically trim down the allocations uint32 autoTrimMemory : 1; ///< If set the allocator will automatically trim down the allocations
/// (where all chunks are idle on the freeList). A minimum of /// (where all chunks are idle on the freeList). A minimum of
/// allocFreeThreshold allocations are kept for fast reuse. /// allocFreeThreshold allocations are kept for fast reuse.
uint32 reserved : 28; ///< Reserved for future use. uint32 reserved : 28; ///< Reserved for future use.
}; };
uint32 u32All; ///< Flags packed as 32-bit uint. uint32 u32All; ///< Flags packed as 32-bit uint.
}; };
/// Different type of allocation data that an ICmdAllocator allocates and distributes to command buffers. /// Different type of allocation data that an ICmdAllocator allocates and distributes to command buffers.
enum CmdAllocType : uint32 enum CmdAllocType : uint32
{ {
CommandDataAlloc = 0, ///< Data allocated is for executable commands. CommandDataAlloc = 0, ///< Data allocated is for executable commands.
EmbeddedDataAlloc, ///< Data allocated is for embedded data. EmbeddedDataAlloc, ///< Data allocated is for embedded data.
LargeEmbeddedDataAlloc, ///< Data allocated is for embedded data, allocation is >32kb LargeEmbeddedDataAlloc, ///< Data allocated is for embedded data, allocation is >32kb
GpuScratchMemAlloc, ///< Data allocated is GPU-only accessible at command buffer execution-time. Possible GpuScratchMemAlloc, ///< Data allocated is GPU-only accessible at command buffer execution-time. Possible
/// uses like GPU events. /// uses like GPU events.
CmdAllocatorTypeCount ///< Number of allocation types for ICmdAllocator's. CmdAllocatorTypeCount ///< Number of allocation types for ICmdAllocator's.
}; };
/// Specifies properties for creation of an ICmdAllocator object. Input structure to IDevice::CreateCmdAllocator(). /// Specifies properties for creation of an ICmdAllocator object. Input structure to IDevice::CreateCmdAllocator().
struct CmdAllocatorCreateInfo struct CmdAllocatorCreateInfo
{ {
CmdAllocatorCreateFlags flags; ///< Flags controlling command allocator creation. CmdAllocatorCreateFlags flags; ///< Flags controlling command allocator creation.
struct struct
{ {
GpuHeap allocHeap; ///< Preferred allocation heap. For @ref GpuScratchMemAlloc, this field is GpuHeap allocHeap; ///< Preferred allocation heap. For @ref GpuScratchMemAlloc, this field is
/// ignored and the allocation will always be in GPU-invisible memory. For /// ignored and the allocation will always be in GPU-invisible memory. For
/// all other allocation types, this must be CPU-mappable. /// all other allocation types, this must be CPU-mappable.
/// For best performance, command allocators that will be used by the /// For best performance, command allocators that will be used by the
/// UVD engine should prefer the Local heap /// UVD engine should prefer the Local heap
gpusize allocSize; ///< Size, in bytes, of the GPU memory allocations this allocator will create. gpusize allocSize; ///< Size, in bytes, of the GPU memory allocations this allocator will create.
/// It must be an integer multiple of suballocSize. /// It must be an integer multiple of suballocSize.
gpusize suballocSize; ///< Size, in bytes, of the chunks of GPU memory this allocator will give to gpusize suballocSize; ///< Size, in bytes, of the chunks of GPU memory this allocator will give to
/// command buffers. It must be an integer multiple of 4096. /// command buffers. It must be an integer multiple of 4096.
/// Must be greater than zero even if the client doesn't plan on using this /// Must be greater than zero even if the client doesn't plan on using this
/// allocation type. /// allocation type.
uint32 allocFreeThreshold; ///< Minimum count of free allocations that the allocator should keep around uint32 allocFreeThreshold; ///< Minimum count of free allocations that the allocator should keep around
/// for fast reuse. It is used when the autoTrimMemory flag is set. /// for fast reuse. It is used when the autoTrimMemory flag is set.
} allocInfo[CmdAllocatorTypeCount]; ///< Information for each allocation type. } allocInfo[CmdAllocatorTypeCount]; ///< Information for each allocation type.
}; };
/// Output structure for QueryUtilizationInfo(). /// Output structure for QueryUtilizationInfo().
/// The CmdAllocator utilization data can be queried by PAL clients in order to decide whether to trim the allocations. /// The CmdAllocator utilization data can be queried by PAL clients in order to decide whether to trim the allocations.
struct CmdAllocatorUtilizationInfo struct CmdAllocatorUtilizationInfo
{ {
uint32 numAllocations; ///< Number of allocations owned by the allocator. uint32 numAllocations; ///< Number of allocations owned by the allocator.
uint32 numFreeChunks; ///< Number of chunks that are reset and not in use. uint32 numFreeChunks; ///< Number of chunks that are reset and not in use.
uint32 numBusyChunks; ///< Number of chunks that in use by the GPU. uint32 numBusyChunks; ///< Number of chunks that in use by the GPU.
uint32 numReuseChunks; ///< Number of chunks that have been 'returned' to the allocator for reuse. uint32 numReuseChunks; ///< Number of chunks that have been 'returned' to the allocator for reuse.
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @interface ICmdAllocator * @interface ICmdAllocator
* @brief Allocates and distributes GPU memory to command buffers on the client's behalf. * @brief Allocates and distributes GPU memory to command buffers on the client's behalf.
* *
* All ICmdBuffer objects must be associated with an ICmdAllocator at creation. Command buffers may switch command * All ICmdBuffer objects must be associated with an ICmdAllocator at creation. Command buffers may switch command
* allocators when ICmdBuffer::Reset() is called. The set of command buffers associated with a given command allocator * allocators when ICmdBuffer::Reset() is called. The set of command buffers associated with a given command allocator
* will query that allocator for additional GPU memory as they are building commands. * will query that allocator for additional GPU memory as they are building commands.
* *
* To protect against race conditions the client must ask for a thread safe command allocator unless its can guarantee * To protect against race conditions the client must ask for a thread safe command allocator unless its can guarantee
* that all command buffers associated with a given command allocator will be built, reset, and destroyed in a thread- * that all command buffers associated with a given command allocator will be built, reset, and destroyed in a thread-
* safe manner. It is illegal to destroy a command allocator while it still has command buffers associated with it. * safe manner. It is illegal to destroy a command allocator while it still has command buffers associated with it.
* *
* @see IDevice::CreateCmdAllocator() * @see IDevice::CreateCmdAllocator()
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class ICmdAllocator : public IDestroyable class ICmdAllocator : public IDestroyable
{ {
public: public:
/// Explicitly resets a command allocator, marking all internal GPU memory allocations as unused. /// Explicitly resets a command allocator, marking all internal GPU memory allocations as unused.
/// ///
/// The client is responsible for guaranteeing that all command buffers associated with this allocator have finished /// The client is responsible for guaranteeing that all command buffers associated with this allocator have finished
/// GPU execution and have been explicitly reset before calling this function. /// GPU execution and have been explicitly reset before calling this function.
/// ///
/// @param [in] freeMemory If the all GPU and CPU memory allocations should be returned to the OS. /// @param [in] freeMemory If the all GPU and CPU memory allocations should be returned to the OS.
/// ///
/// @returns Success if the command allocator was successfully reset. Otherwise, one of the following errors may be /// @returns Success if the command allocator was successfully reset. Otherwise, one of the following errors may be
/// returned: /// returned:
/// + ErrorUnknown if an internal PAL error occurs. /// + ErrorUnknown if an internal PAL error occurs.
virtual Result Reset(bool freeMemory) = 0; virtual Result Reset(bool freeMemory) = 0;
/// Explicitly trims a command allocator, deleting as many unused internal GPU memory allocations as possible. /// Explicitly trims a command allocator, deleting as many unused internal GPU memory allocations as possible.
/// ///
/// @returns Success if the command allocator was successfully trimmed. /// @returns Success if the command allocator was successfully trimmed.
/// ///
/// @param [in] allocTypeMask Gives control whether trimming will be applied for each CmdAllocType. /// @param [in] allocTypeMask Gives control whether trimming will be applied for each CmdAllocType.
/// Use (1 << CmdAllocatorTypeCount) - 1 to apply trimming to all types. /// Use (1 << CmdAllocatorTypeCount) - 1 to apply trimming to all types.
/// When trimming only the embedded date use (1 << EmbeddedDataAlloc). /// When trimming only the embedded date use (1 << EmbeddedDataAlloc).
/// @param [in] dynamicThreshold Minimum count of free allocations that the allocator should keep around /// @param [in] dynamicThreshold Minimum count of free allocations that the allocator should keep around
virtual Result Trim(uint32 allocTypeMask, uint32 dynamicThreshold) = 0; virtual Result Trim(uint32 allocTypeMask, uint32 dynamicThreshold) = 0;
/// Query the numbers of allocations and chunks of the given CmdAllocator type. /// Query the numbers of allocations and chunks of the given CmdAllocator type.
/// This may help clients to decide whether they may apply trimming or not. /// This may help clients to decide whether they may apply trimming or not.
/// ///
/// @returns Success if valid values can be reported. /// @returns Success if valid values can be reported.
/// ///
/// @param [in] type CmdAllocType that is being queried /// @param [in] type CmdAllocType that is being queried
/// @param [out] pUtilizationInfo The allocation and chunk counts will be stored here. /// @param [out] pUtilizationInfo The allocation and chunk counts will be stored here.
virtual Result QueryUtilizationInfo(CmdAllocType type, CmdAllocatorUtilizationInfo* pUtilizationInfo) const = 0; virtual Result QueryUtilizationInfo(CmdAllocType type, CmdAllocatorUtilizationInfo* pUtilizationInfo) const = 0;
/// Returns the value of the associated arbitrary client data pointer. /// Returns the value of the associated arbitrary client data pointer.
/// Can be used to associate arbitrary data with a particular PAL object. /// Can be used to associate arbitrary data with a particular PAL object.
/// ///
/// @returns Pointer to client data. /// @returns Pointer to client data.
void* GetClientData() const void* GetClientData() const
{ {
return m_pClientData; return m_pClientData;
} }
/// Sets the value of the associated arbitrary client data pointer. /// Sets the value of the associated arbitrary client data pointer.
/// Can be used to associate arbitrary data with a particular PAL object. /// Can be used to associate arbitrary data with a particular PAL object.
/// ///
/// @param [in] pClientData A pointer to arbitrary client data. /// @param [in] pClientData A pointer to arbitrary client data.
void SetClientData( void SetClientData(
void* pClientData) void* pClientData)
{ {
m_pClientData = pClientData; m_pClientData = pClientData;
} }
protected: protected:
/// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly /// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly
/// called the proper create method. /// called the proper create method.
ICmdAllocator() : m_pClientData(nullptr) {} ICmdAllocator() : m_pClientData(nullptr) {}
/// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by /// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by
/// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the /// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the
/// object on their own. /// object on their own.
virtual ~ICmdAllocator() { } virtual ~ICmdAllocator() { }
private: private:
/// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData() /// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData()
/// and set via SetClientData(). /// and set via SetClientData().
/// For non-top-layer objects, this will point to the layer above the current object. /// For non-top-layer objects, this will point to the layer above the current object.
void* m_pClientData; void* m_pClientData;
}; };
} // Pal } // Pal
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+370 -370
파일 보기
@@ -1,370 +1,370 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palCmdTracking.h * @file palCmdTracking.h
* @brief Defines a number of support classes used for construction and storage of struct TrackedCmdLocation * @brief Defines a number of support classes used for construction and storage of struct TrackedCmdLocation
* defined in trackedCmdLocation.h * defined in trackedCmdLocation.h
* *
* - struct TrackingEventInfo: A single from uint8 to name, used for logging * - struct TrackingEventInfo: A single from uint8 to name, used for logging
* - class TrackedCmdSupportBase A set of TrackingEventInfo, maintained outside of Pal * - class TrackedCmdSupportBase A set of TrackingEventInfo, maintained outside of Pal
* - class TrackedCmdLocationArray The arrays for TrackedCmdLocation's used for reporting * - class TrackedCmdLocationArray The arrays for TrackedCmdLocation's used for reporting
* correlation data through ICmdBufferReporting::CorrelationReportOnSubmit * correlation data through ICmdBufferReporting::CorrelationReportOnSubmit
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "pal.h" #include "pal.h"
#include "palVector.h" #include "palVector.h"
#include "trackedCmdLocation.h" #include "trackedCmdLocation.h"
namespace Pal namespace Pal
{ {
// forward decl // forward decl
class Platform; class Platform;
namespace CmdDisassembly namespace CmdDisassembly
{ {
// forward definition // forward definition
class TrackedCmdLocationArray; class TrackedCmdLocationArray;
/** /**
************************************************************************************************************************ ************************************************************************************************************************
* @brief class TrackedCmdLocationRef * @brief class TrackedCmdLocationRef
* A copyable reference to a member in a TrackedCmdLocationArray, invariant to that array be * A copyable reference to a member in a TrackedCmdLocationArray, invariant to that array be
* re-allocated. * re-allocated.
* *
* @detail Is simply a pointer to a TrackedCmdLocationArray, and an index in to that array * @detail Is simply a pointer to a TrackedCmdLocationArray, and an index in to that array
* *
************************************************************************************************************************ ************************************************************************************************************************
*/ */
class TrackedCmdLocationRef class TrackedCmdLocationRef
{ {
public: public:
TrackedCmdLocationRef() TrackedCmdLocationRef()
: m_pSourceArray(nullptr), : m_pSourceArray(nullptr),
m_index(0) m_index(0)
{ {
} }
TrackedCmdLocationRef( TrackedCmdLocationRef(
TrackedCmdLocationArray* pSourceArray, TrackedCmdLocationArray* pSourceArray,
Util::uint32 index) Util::uint32 index)
: m_pSourceArray(pSourceArray), : m_pSourceArray(pSourceArray),
m_index(index) m_index(index)
{ {
} }
TrackedCmdLocationRef( TrackedCmdLocationRef(
TrackedCmdLocationRef&& other) = default; TrackedCmdLocationRef&& other) = default;
TrackedCmdLocationRef( TrackedCmdLocationRef(
TrackedCmdLocationRef const& other) = default; TrackedCmdLocationRef const& other) = default;
TrackedCmdLocationRef& operator=( TrackedCmdLocationRef& operator=(
TrackedCmdLocationRef&& other) = default; TrackedCmdLocationRef&& other) = default;
TrackedCmdLocationRef& operator=( TrackedCmdLocationRef& operator=(
TrackedCmdLocationRef const& other) = default; TrackedCmdLocationRef const& other) = default;
bool operator==( bool operator==(
TrackedCmdLocationRef const& other) const TrackedCmdLocationRef const& other) const
{ return (this->m_pSourceArray == other.m_pSourceArray) && (this->m_index == other.m_index); } { return (this->m_pSourceArray == other.m_pSourceArray) && (this->m_index == other.m_index); }
bool operator!=( bool operator!=(
TrackedCmdLocationRef const& other) const TrackedCmdLocationRef const& other) const
{ return (this->m_pSourceArray != other.m_pSourceArray) || (this->m_index != other.m_index); } { return (this->m_pSourceArray != other.m_pSourceArray) || (this->m_index != other.m_index); }
TrackedCmdLocation* Use(); TrackedCmdLocation* Use();
const TrackedCmdLocation* Get() const; const TrackedCmdLocation* Get() const;
Util::uint32 GetIndex() const Util::uint32 GetIndex() const
{ {
return m_index; return m_index;
} }
/// Helper functions /// Helper functions
/// ///
/// Clears the TrackedCmdLocation referred to by this TrackedCmdLocationRef /// Clears the TrackedCmdLocation referred to by this TrackedCmdLocationRef
/// ///
/// @returns /// @returns
/// Result::ErrorInvalidPointer if (IsValid() == false) /// Result::ErrorInvalidPointer if (IsValid() == false)
/// Result::Success if successful /// Result::Success if successful
Result Clear(); Result Clear();
/// @returns /// @returns
/// TrackedCmdLocationMode::Invalid if (IsValid() == false) /// TrackedCmdLocationMode::Invalid if (IsValid() == false)
/// Get()->m_mode otherwise /// Get()->m_mode otherwise
TrackedCmdLocationMode GetMode() const; TrackedCmdLocationMode GetMode() const;
/// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef /// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef
/// to mode TrackedCmdLocationMode::Before /// to mode TrackedCmdLocationMode::Before
/// ///
/// @param [in] eventId Refers to an uint8 event that has a begin and/or an end associated with it /// @param [in] eventId Refers to an uint8 event that has a begin and/or an end associated with it
/// Most likely, a value registered to a TrackedCmdSupportBase /// Most likely, a value registered to a TrackedCmdSupportBase
/// @param [in] beforePtr The end pointer for the cmdList being tracked before the event referred to by eventId /// @param [in] beforePtr The end pointer for the cmdList being tracked before the event referred to by eventId
/// Only 48-bits of beforePtr are used /// Only 48-bits of beforePtr are used
/// ///
/// @returns /// @returns
/// Result::ErrorInvalidPointer if (IsValid() == false) /// Result::ErrorInvalidPointer if (IsValid() == false)
/// Result::Success if successful /// Result::Success if successful
Result SetAsBefore( Result SetAsBefore(
uint8 eventId, uint8 eventId,
uint64 beforePtr); uint64 beforePtr);
/// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef /// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef
/// to mode TrackedCmdLocationMode::After /// to mode TrackedCmdLocationMode::After
/// ///
/// @param [in] eventId Refers to an uint8 event that has a begin and/or an end associated with it /// @param [in] eventId Refers to an uint8 event that has a begin and/or an end associated with it
/// Most likely, a value registered to a TrackedCmdSupportBase /// Most likely, a value registered to a TrackedCmdSupportBase
/// @param [in] afterPtr The end pointer for the cmdList being tracked after the event referred to by eventId /// @param [in] afterPtr The end pointer for the cmdList being tracked after the event referred to by eventId
/// Only 48-bits of afterPtr are used /// Only 48-bits of afterPtr are used
/// ///
/// @returns /// @returns
/// Result::ErrorInvalidPointer if (IsValid() == false) /// Result::ErrorInvalidPointer if (IsValid() == false)
/// Result::Success if successful /// Result::Success if successful
Result SetAsAfter( Result SetAsAfter(
uint8 eventId, uint8 eventId,
uint64 afterPtr); uint64 afterPtr);
/// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef /// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef
/// to mode TrackedCmdLocationMode::Delta, with no begin or end (ie, no data can be written to /// to mode TrackedCmdLocationMode::Delta, with no begin or end (ie, no data can be written to
/// the cmdList being tracked "during" the event referred to be eventId /// the cmdList being tracked "during" the event referred to be eventId
/// ///
/// @param [in] eventId Refers to an uint8 event that does not have a begin and/or an end associated with it /// @param [in] eventId Refers to an uint8 event that does not have a begin and/or an end associated with it
/// Such as Pal::CmdDisassembly::TrackedCmdLocation::PostClientEvent /// Such as Pal::CmdDisassembly::TrackedCmdLocation::PostClientEvent
/// @param [in] ptr The end pointer for the cmdList being tracked after the event referred to by eventId /// @param [in] ptr The end pointer for the cmdList being tracked after the event referred to by eventId
/// Only 48-bits of ptr are used /// Only 48-bits of ptr are used
/// ///
/// @returns /// @returns
/// Result::ErrorInvalidPointer if (IsValid() == false) /// Result::ErrorInvalidPointer if (IsValid() == false)
/// Result::Success if successful /// Result::Success if successful
Result SetAsEmptyDelta( Result SetAsEmptyDelta(
uint8 eventId, uint8 eventId,
uint64 ptr); uint64 ptr);
/// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef /// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef
/// to mode TrackedCmdLocationMode::ClientId /// to mode TrackedCmdLocationMode::ClientId
/// ///
/// @param [in] clientId A 61-bit bit value used by the client application to identify which cmdList is being /// @param [in] clientId A 61-bit bit value used by the client application to identify which cmdList is being
/// tracked /// tracked
/// ///
/// @returns /// @returns
/// Result::ErrorInvalidPointer if (IsValid() == false) /// Result::ErrorInvalidPointer if (IsValid() == false)
/// Result::Success if successful /// Result::Success if successful
Result SetAsClientId( Result SetAsClientId(
uint64 clientId); uint64 clientId);
/// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef /// Sets the TrackedCmdLocation referred to by this TrackedCmdLocationRef
/// to mode TrackedCmdLocationMode::ClientEventId /// to mode TrackedCmdLocationMode::ClientEventId
/// ///
/// @param [in] clientEventId A 61-bit bit value used by the client application to identify /// @param [in] clientEventId A 61-bit bit value used by the client application to identify
/// a client event relative to the current end position of the cmdList being tracked /// a client event relative to the current end position of the cmdList being tracked
/// ///
/// @returns /// @returns
/// Result::ErrorInvalidPointer if (IsValid() == false) /// Result::ErrorInvalidPointer if (IsValid() == false)
/// Result::Success if successful /// Result::Success if successful
Result SetAsClientEvent( Result SetAsClientEvent(
uint64 clientEventId); uint64 clientEventId);
/// @brief bool TrackedCmdLocation::TrySetAsDelta(uint64 afterPtr) /// @brief bool TrackedCmdLocation::TrySetAsDelta(uint64 afterPtr)
/// Will attempt to set this TrackedCmdLocation to type TrackedCmdLocationMode::Delta /// Will attempt to set this TrackedCmdLocation to type TrackedCmdLocationMode::Delta
/// ///
/// @detail If GetMode() == TrackedCmdLocationMode::Before and afterPtr - m_correlateInternal.m_ptr is small /// @detail If GetMode() == TrackedCmdLocationMode::Before and afterPtr - m_correlateInternal.m_ptr is small
/// enough to be encoded in m_correlateInternal.m_deltaInDWords, the mode will be altered to /// enough to be encoded in m_correlateInternal.m_deltaInDWords, the mode will be altered to
/// TrackedCmdLocationMode::Delta, with afterPtr - m_correlateInternal.m_ptr encoded in /// TrackedCmdLocationMode::Delta, with afterPtr - m_correlateInternal.m_ptr encoded in
/// m_correlateInternal.m_deltaInDWords. /// m_correlateInternal.m_deltaInDWords.
/// If this attempt fails, the calling function should instead create a TrackedCmdLocationMode::After /// If this attempt fails, the calling function should instead create a TrackedCmdLocationMode::After
/// TrackedCmdLocation /// TrackedCmdLocation
/// ///
/// @param [in] afterPtr, the value a TrackedCmdLocationMode::After would have for m_correlateInternal.m_ptr /// @param [in] afterPtr, the value a TrackedCmdLocationMode::After would have for m_correlateInternal.m_ptr
/// @return Result::Success if it was possible to set this TrackedCmdLocation to type /// @return Result::Success if it was possible to set this TrackedCmdLocation to type
/// TrackedCmdLocationMode::Delta /// TrackedCmdLocationMode::Delta
/// Result::Unsupported if the conditions described above are not met. /// Result::Unsupported if the conditions described above are not met.
Result TrySetAsDelta( Result TrySetAsDelta(
uint64 afterPtr); uint64 afterPtr);
private: private:
TrackedCmdLocationArray* m_pSourceArray; TrackedCmdLocationArray* m_pSourceArray;
Util::uint32 m_index; Util::uint32 m_index;
Result SetMode( Result SetMode(
TrackedCmdLocationMode mode); TrackedCmdLocationMode mode);
}; };
/// @brief struct TrackingEventInfo /// @brief struct TrackingEventInfo
/// Essentially just a name, plus a boolean to indicate whether the name is valid / has been set /// Essentially just a name, plus a boolean to indicate whether the name is valid / has been set
struct TrackingEventInfo struct TrackingEventInfo
{ {
Util::StringView<char> name; Util::StringView<char> name;
bool isValid; bool isValid;
TrackingEventInfo() TrackingEventInfo()
: isValid(false) : isValid(false)
{} {}
}; };
/** /**
************************************************************************************************************************ ************************************************************************************************************************
* @brief class TrackedCmdSupportBase translates eventId's to strings for internal correlation events * @brief class TrackedCmdSupportBase translates eventId's to strings for internal correlation events
* *
* @detail For use in Pal::Queue when dumping to text files. Corresponds to * @detail For use in Pal::Queue when dumping to text files. Corresponds to
* TrackedCmdLocation::m_correlateInternal.m_event for the cases where TrackedCmdLocation::m_mode * TrackedCmdLocation::m_correlateInternal.m_event for the cases where TrackedCmdLocation::m_mode
* is not TrackedCmdLocationMode::ClientEvent * is not TrackedCmdLocationMode::ClientEvent
* *
* The implementation for this is in whatever client of Pal that is creating the internal correlation events, * The implementation for this is in whatever client of Pal that is creating the internal correlation events,
* *
************************************************************************************************************************ ************************************************************************************************************************
*/ */
class TrackedCmdSupportBase class TrackedCmdSupportBase
{ {
public: public:
virtual ~TrackedCmdSupportBase() = default; virtual ~TrackedCmdSupportBase() = default;
void SetEventIdName( void SetEventIdName(
uint8 eventId, uint8 eventId,
const char* name) const char* name)
{ {
PAL_ASSERT(static_cast<uint32>(eventId) < NumUInt8Values); PAL_ASSERT(static_cast<uint32>(eventId) < NumUInt8Values);
m_allEventsMap[eventId].name = name; m_allEventsMap[eventId].name = name;
m_allEventsMap[eventId].isValid = true; m_allEventsMap[eventId].isValid = true;
} }
TrackingEventInfo const& GetEventInfo( TrackingEventInfo const& GetEventInfo(
uint8 eventId) const uint8 eventId) const
{ {
PAL_ASSERT(static_cast<uint32>(eventId) < NumUInt8Values); PAL_ASSERT(static_cast<uint32>(eventId) < NumUInt8Values);
return m_allEventsMap[eventId]; return m_allEventsMap[eventId];
} }
protected: protected:
static constexpr uint32 NumUInt8Values = UINT8_MAX + 1; static constexpr uint32 NumUInt8Values = UINT8_MAX + 1;
TrackingEventInfo m_allEventsMap[NumUInt8Values]; TrackingEventInfo m_allEventsMap[NumUInt8Values];
TrackedCmdSupportBase() = default; TrackedCmdSupportBase() = default;
}; };
/** /**
************************************************************************************************************************ ************************************************************************************************************************
* @brief class TrackedCmdLocationArray is simple a TrackedCmdLocationVec together with a clientId * @brief class TrackedCmdLocationArray is simple a TrackedCmdLocationVec together with a clientId
* and some helpers. TrackedCmdLocationArray live on Pal::GfxCmdBuffer * and some helpers. TrackedCmdLocationArray live on Pal::GfxCmdBuffer
* *
* @detail Each Pal::GfxCmdBuffer has at most CmdDisassembly::MaxNumSubCmdBuffers TrackedCmdLocationArray's * @detail Each Pal::GfxCmdBuffer has at most CmdDisassembly::MaxNumSubCmdBuffers TrackedCmdLocationArray's
* corresponding to Pal::GfxCmdBuffer::NumCmdStreams(); * corresponding to Pal::GfxCmdBuffer::NumCmdStreams();
* *
* The clientId used for TrackedCmdLocationArray::m_clientId, corresponds to the client Id used in * The clientId used for TrackedCmdLocationArray::m_clientId, corresponds to the client Id used in
* TrackedCmdLocation::m_clientId.m_clientId * TrackedCmdLocation::m_clientId.m_clientId
* *
* For the moment, the underlying implementation used is * For the moment, the underlying implementation used is
* Util::Vector<TrackedCmdLocation, DefaultCapacity, Pal::Platform>, but could be changed to use a Chunk * Util::Vector<TrackedCmdLocation, DefaultCapacity, Pal::Platform>, but could be changed to use a Chunk
* scheme, especially as sizes of cmdLists can become very large. * scheme, especially as sizes of cmdLists can become very large.
* The only requirement to a change, is for TrackedCmdLocationRef continues to function as an accessor * The only requirement to a change, is for TrackedCmdLocationRef continues to function as an accessor
* *
* Note that the functions in TrackedCmdLocationArray are not designed for thread-safety, as they are * Note that the functions in TrackedCmdLocationArray are not designed for thread-safety, as they are
* issued from command-list-building functions that are, in their turn, not thread safe. Adding mutex * issued from command-list-building functions that are, in their turn, not thread safe. Adding mutex
* behavior here would potentially hide issues relating to thread-safety. * behavior here would potentially hide issues relating to thread-safety.
* *
************************************************************************************************************************ ************************************************************************************************************************
*/ */
class TrackedCmdLocationArray class TrackedCmdLocationArray
{ {
public: public:
static constexpr uint32 DefaultCapacity = 1024; static constexpr uint32 DefaultCapacity = 1024;
static constexpr uint32 BadIndex = UINT32_MAX; static constexpr uint32 BadIndex = UINT32_MAX;
static constexpr uint64 InvalidClientId = UINT64_MAX; static constexpr uint64 InvalidClientId = UINT64_MAX;
typedef Util::Vector<TrackedCmdLocation, DefaultCapacity, Pal::Platform> TrackedCmdLocationVec; typedef Util::Vector<TrackedCmdLocation, DefaultCapacity, Pal::Platform> TrackedCmdLocationVec;
static uint32 GetTrackedCmdLocationArraySizeInBytes() static uint32 GetTrackedCmdLocationArraySizeInBytes()
{ {
return sizeof(TrackedCmdLocationArray); return sizeof(TrackedCmdLocationArray);
} }
static TrackedCmdLocationArray* CreateTrackedCmdLocationArray( static TrackedCmdLocationArray* CreateTrackedCmdLocationArray(
void* pMemory, void* pMemory,
Pal::Platform* pPlatform); Pal::Platform* pPlatform);
void Reset() void Reset()
{ {
m_lastLocation = TrackedCmdLocationRef(this, BadIndex); m_lastLocation = TrackedCmdLocationRef(this, BadIndex);
m_clientId = InvalidClientId; m_clientId = InvalidClientId;
m_locations.Clear(); m_locations.Clear();
} }
void Destroy(); void Destroy();
uint64 GetClientId() const uint64 GetClientId() const
{ {
return m_clientId; return m_clientId;
} }
Result SetClientId( Result SetClientId(
uint64 clientId); uint64 clientId);
Util::uint32 GetTotalSize() const Util::uint32 GetTotalSize() const
{ {
return m_locations.size(); return m_locations.size();
} }
const TrackedCmdLocationVec& GetLocationsVec() const const TrackedCmdLocationVec& GetLocationsVec() const
{ {
return m_locations; return m_locations;
} }
TrackedCmdLocationVec& UseLocationsVec() TrackedCmdLocationVec& UseLocationsVec()
{ {
return m_locations; return m_locations;
} }
Pal::Result MakeNext( Pal::Result MakeNext(
TrackedCmdLocationRef* pResult); TrackedCmdLocationRef* pResult);
const TrackedCmdLocationRef GetLast() const const TrackedCmdLocationRef GetLast() const
{ {
return m_lastLocation; return m_lastLocation;
} }
bool IsLast( bool IsLast(
TrackedCmdLocationRef const& location) const TrackedCmdLocationRef const& location) const
{ {
return location == m_lastLocation; return location == m_lastLocation;
} }
private: private:
TrackedCmdLocationVec m_locations; TrackedCmdLocationVec m_locations;
Pal::Platform* m_pPlatform; Pal::Platform* m_pPlatform;
uint64 m_clientId; uint64 m_clientId;
TrackedCmdLocationRef m_lastLocation; TrackedCmdLocationRef m_lastLocation;
TrackedCmdLocationArray( TrackedCmdLocationArray(
Pal::Platform* pPlatform); Pal::Platform* pPlatform);
~TrackedCmdLocationArray() = default; ~TrackedCmdLocationArray() = default;
}; };
} // namespace CmdDisassembly } // namespace CmdDisassembly
} // namespace Pal } // namespace Pal
+70 -70
파일 보기
@@ -1,70 +1,70 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palDestroyable.h * @file palDestroyable.h
* @brief Defines the Platform Abstraction Library (PAL) IDestroyable interface. * @brief Defines the Platform Abstraction Library (PAL) IDestroyable interface.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
namespace Pal namespace Pal
{ {
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @interface IDestroyable * @interface IDestroyable
* @brief Interface inherited by objects that must be explicitly destroyed by the client. * @brief Interface inherited by objects that must be explicitly destroyed by the client.
* *
* This includes all objects except: * This includes all objects except:
* *
* + @ref IColorTargetView, @ref IDepthStencilView - These classes are treated as SRDs by the DX12 runtime. Therefore, * + @ref IColorTargetView, @ref IDepthStencilView - These classes are treated as SRDs by the DX12 runtime. Therefore,
* PAL guarantees that no action needs to be taken at Destroy() - the client should just free the memory backing these * PAL guarantees that no action needs to be taken at Destroy() - the client should just free the memory backing these
* classes. * classes.
* + @ref IDevice - These objects are created during IPlatform::EnumerateDevices() and are automatically destroyed * + @ref IDevice - These objects are created during IPlatform::EnumerateDevices() and are automatically destroyed
* along with the Platform object. * along with the Platform object.
* + @ref IPrivateScreen - These objects are created as during IPlatform::EnumerateDevices() based on * + @ref IPrivateScreen - These objects are created as during IPlatform::EnumerateDevices() based on
* which screens are attached to each device. They are automatically destroyed along with the Platform object. * which screens are attached to each device. They are automatically destroyed along with the Platform object.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class IDestroyable class IDestroyable
{ {
public: public:
/// Frees all resources associated with this object. /// Frees all resources associated with this object.
/// ///
/// It is the client's responsibility to only call this method once there are no more existing references to this /// It is the client's responsibility to only call this method once there are no more existing references to this
/// object. This method does not free the system memory associated with the object (as specified in pPlacementAddr /// object. This method does not free the system memory associated with the object (as specified in pPlacementAddr
/// during creation); the client is responsible for freeing that memory since they allocated it. /// during creation); the client is responsible for freeing that memory since they allocated it.
virtual void Destroy() = 0; virtual void Destroy() = 0;
protected: protected:
/// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by /// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by
/// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the /// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the
/// object on their own. /// object on their own.
virtual ~IDestroyable() { } virtual ~IDestroyable() { }
}; };
} // Pal } // Pal
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+171 -171
파일 보기
@@ -1,171 +1,171 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palFence.h * @file palFence.h
* @brief Defines the Platform Abstraction Library (PAL) IFence interface and related types. * @brief Defines the Platform Abstraction Library (PAL) IFence interface and related types.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "pal.h" #include "pal.h"
#include "palDestroyable.h" #include "palDestroyable.h"
namespace Pal namespace Pal
{ {
/// Specifies properties for fence @ref IFence fence creation. Input structure to IDevice::CreateFence(). /// Specifies properties for fence @ref IFence fence creation. Input structure to IDevice::CreateFence().
struct FenceCreateInfo struct FenceCreateInfo
{ {
union union
{ {
struct struct
{ {
uint32 signaled : 1; ///< Specify whether the initial status of the fence is signaled or not. uint32 signaled : 1; ///< Specify whether the initial status of the fence is signaled or not.
uint32 eventCanBeInherited : 1; ///< The event handle can be inherited by child process. uint32 eventCanBeInherited : 1; ///< The event handle can be inherited by child process.
uint32 shareable : 1; ///< This fence may be opened for use by a different device. uint32 shareable : 1; ///< This fence may be opened for use by a different device.
uint32 reserved : 29; ///< Reserved for future use. uint32 reserved : 29; ///< Reserved for future use.
}; };
uint32 u32All; ///< Flags packed as 32-bit uint. uint32 u32All; ///< Flags packed as 32-bit uint.
} flags; ///< Fence creation flags. } flags; ///< Fence creation flags.
#if defined(_WIN32) #if defined(_WIN32)
const wchar_t* pName; /// The name of the event object, Windows uses this name to uniquely identify fence objects const wchar_t* pName; /// The name of the event object, Windows uses this name to uniquely identify fence objects
/// across processes. /// across processes.
#endif #endif
}; };
/// Specifies properties for fence opening. Input structure to IDevice::OpenFence(). /// Specifies properties for fence opening. Input structure to IDevice::OpenFence().
struct FenceOpenInfo struct FenceOpenInfo
{ {
union union
{ {
struct struct
{ {
uint32 isReference : 1; ///< If set, then the opened fence will reference the same sync object uint32 isReference : 1; ///< If set, then the opened fence will reference the same sync object
///< in the kernel. Otherwise, the object is copied to the new Fence. ///< in the kernel. Otherwise, the object is copied to the new Fence.
uint32 reserved : 31; ///< Reserved for future use. uint32 reserved : 31; ///< Reserved for future use.
}; };
uint32 u32All; ///< Flags packed as 32-bit uint. uint32 u32All; ///< Flags packed as 32-bit uint.
} flags; } flags;
OsExternalHandle externalFence; ///< External shared fence handle. OsExternalHandle externalFence; ///< External shared fence handle.
#if defined(_WIN32) #if defined(_WIN32)
const wchar_t* pName; /// The name of the event object,Windows uses this name to uniquely identify const wchar_t* pName; /// The name of the event object,Windows uses this name to uniquely identify
/// fence objects across processes. /// fence objects across processes.
#endif #endif
}; };
/// Specifies properties for fence exporting. Input structure to IFence::ExportExternalHandle(). /// Specifies properties for fence exporting. Input structure to IFence::ExportExternalHandle().
struct FenceExportInfo struct FenceExportInfo
{ {
union union
{ {
struct struct
{ {
uint32 isReference : 1; ///< If set, then the fence exporting a handle that reference the same sync uint32 isReference : 1; ///< If set, then the fence exporting a handle that reference the same sync
///< object in the kernel. Otherwise, the object is copied to the new Fence. ///< object in the kernel. Otherwise, the object is copied to the new Fence.
uint32 implicitReset : 1; ///< If set, a fence reset will be done for the sync fd exported. uint32 implicitReset : 1; ///< If set, a fence reset will be done for the sync fd exported.
uint32 reserved : 30; ///< Reserved for future use. uint32 reserved : 30; ///< Reserved for future use.
}; };
uint32 u32All; ///< Flags packed as 32-bit uint. uint32 u32All; ///< Flags packed as 32-bit uint.
} flags; } flags;
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @interface IFence * @interface IFence
* @brief Represents a command buffer fence the client can use for coarse-level synchronization between the GPU and * @brief Represents a command buffer fence the client can use for coarse-level synchronization between the GPU and
* CPU. * CPU.
* *
* Fences can be specified when calling IQueue::Submit() and will be signaled when certain prior queue operations have * Fences can be specified when calling IQueue::Submit() and will be signaled when certain prior queue operations have
* completed. The status of the fence can be queried by the client to determine when the GPU work of interest has * completed. The status of the fence can be queried by the client to determine when the GPU work of interest has
* completed. * completed.
* *
* Fences are guaranteed to wait for: * Fences are guaranteed to wait for:
* + Prior command buffer submissions. * + Prior command buffer submissions.
* + Prior queue semaphore signals and waits. * + Prior queue semaphore signals and waits.
* + Prior direct presents. * + Prior direct presents.
* *
* @see IDevice::CreateFence() * @see IDevice::CreateFence()
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class IFence : public IDestroyable class IFence : public IDestroyable
{ {
public: public:
/// Gets the status (completed or not) of the fence. /// Gets the status (completed or not) of the fence.
/// ///
/// @returns Success if the fence has been reached, or NotReady if the fence hasn't been reached. Other return /// @returns Success if the fence has been reached, or NotReady if the fence hasn't been reached. Other return
/// codes indicate an error: /// codes indicate an error:
/// + ErrorFenceNeverSubmitted if the fence hasn't been submitted yet and the fence is not created with /// + ErrorFenceNeverSubmitted if the fence hasn't been submitted yet and the fence is not created with
/// initialSignaled set to true. /// initialSignaled set to true.
virtual Result GetStatus() const = 0; virtual Result GetStatus() const = 0;
/// Export the event handle or sync object handle of the fence for external usage. /// Export the event handle or sync object handle of the fence for external usage.
/// If @ref FenceExportInfo::isReference is not set, then this also performs an implicit reset operation on /// If @ref FenceExportInfo::isReference is not set, then this also performs an implicit reset operation on
/// the Fence. /// the Fence.
/// ///
/// @param [in] exportInfo Information describing how the Fence handle should be exported. /// @param [in] exportInfo Information describing how the Fence handle should be exported.
/// @returns the handle in the type OsExternalHandle /// @returns the handle in the type OsExternalHandle
virtual OsExternalHandle ExportExternalHandle( virtual OsExternalHandle ExportExternalHandle(
const FenceExportInfo& exportInfo) const = 0; const FenceExportInfo& exportInfo) const = 0;
/// Returns the value of the associated arbitrary client data pointer. /// Returns the value of the associated arbitrary client data pointer.
/// Can be used to associate arbitrary data with a particular PAL object. /// Can be used to associate arbitrary data with a particular PAL object.
/// ///
/// @returns Pointer to client data. /// @returns Pointer to client data.
void* GetClientData() const void* GetClientData() const
{ {
return m_pClientData; return m_pClientData;
} }
/// Sets the value of the associated arbitrary client data pointer. /// Sets the value of the associated arbitrary client data pointer.
/// Can be used to associate arbitrary data with a particular PAL object. /// Can be used to associate arbitrary data with a particular PAL object.
/// ///
/// @param [in] pClientData A pointer to arbitrary client data. /// @param [in] pClientData A pointer to arbitrary client data.
void SetClientData( void SetClientData(
void* pClientData) void* pClientData)
{ {
m_pClientData = pClientData; m_pClientData = pClientData;
} }
protected: protected:
/// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly /// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly
/// called the proper create method. /// called the proper create method.
IFence() : m_pClientData(nullptr) {} IFence() : m_pClientData(nullptr) {}
/// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by /// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by
/// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the /// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the
/// object on their own. /// object on their own.
virtual ~IFence() { } virtual ~IFence() { }
private: private:
/// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData() /// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData()
/// and set via SetClientData(). /// and set via SetClientData().
/// For non-top-layer objects, this will point to the layer above the current object. /// For non-top-layer objects, this will point to the layer above the current object.
void* m_pClientData; void* m_pClientData;
}; };
} // Pal } // Pal
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+139 -139
파일 보기
@@ -1,139 +1,139 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palGpuMemoryBindable.h * @file palGpuMemoryBindable.h
* @brief Defines the Platform Abstraction Library (PAL) IGpuMemoryBindable interface and related types. * @brief Defines the Platform Abstraction Library (PAL) IGpuMemoryBindable interface and related types.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "pal.h" #include "pal.h"
#include "palDestroyable.h" #include "palDestroyable.h"
namespace Pal namespace Pal
{ {
// Forward declarations. // Forward declarations.
class IGpuMemory; class IGpuMemory;
/// Reports required properties of a GPU memory object bound to a specific object. The client must query these /// Reports required properties of a GPU memory object bound to a specific object. The client must query these
/// properties via IGpuMemoryBindable::GetGpuMemoryRequirements() and bind an @ref IGpuMemory object matching these /// properties via IGpuMemoryBindable::GetGpuMemoryRequirements() and bind an @ref IGpuMemory object matching these
/// requirements to the @ref IGpuMemoryBindable object using IGpuMemoryBindable::BindGpuMemory(). /// requirements to the @ref IGpuMemoryBindable object using IGpuMemoryBindable::BindGpuMemory().
struct GpuMemoryRequirements struct GpuMemoryRequirements
{ {
union union
{ {
struct struct
{ {
uint32 cpuAccess : 1; ///< CPU access is required. If set, the client must not set cpuInvisible in uint32 cpuAccess : 1; ///< CPU access is required. If set, the client must not set cpuInvisible in
/// GpuMemoryCreateFlags and must provide CPU visible heaps or CPU visible heap /// GpuMemoryCreateFlags and must provide CPU visible heaps or CPU visible heap
/// access mode. If not set, it's strongly recommended to set cpuInvisible. /// access mode. If not set, it's strongly recommended to set cpuInvisible.
uint32 reserved : 31; ///< Reserved for future use. uint32 reserved : 31; ///< Reserved for future use.
}; };
uint32 u32All; ///< Flags packed as 32-bit uint. uint32 u32All; ///< Flags packed as 32-bit uint.
} flags; ///< Flags specifying required GPU memory properties. } flags; ///< Flags specifying required GPU memory properties.
gpusize size; ///< Amount of GPU memory required, in bytes. gpusize size; ///< Amount of GPU memory required, in bytes.
gpusize alignment; ///< Required GPU memory virtual address alignment, in bytes. gpusize alignment; ///< Required GPU memory virtual address alignment, in bytes.
uint32 heapCount; ///< Number of valid entries in heaps[]. uint32 heapCount; ///< Number of valid entries in heaps[].
GpuHeap heaps[GpuHeapCount]; ///< List of allowed heaps for the GPU memory in order of predicted performance. GpuHeap heaps[GpuHeapCount]; ///< List of allowed heaps for the GPU memory in order of predicted performance.
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @interface IGpuMemoryBindable * @interface IGpuMemoryBindable
* @brief Interface inherited by objects that may require GPU memory be bound to them. * @brief Interface inherited by objects that may require GPU memory be bound to them.
* *
* In the future, PAL may discover a need to allocate GPU memory for a class that currently doesn't require it. In that * In the future, PAL may discover a need to allocate GPU memory for a class that currently doesn't require it. In that
* situation, that class will be updated to inherit from IGpuMemoryBindable. This change would break backward * situation, that class will be updated to inherit from IGpuMemoryBindable. This change would break backward
* compatibility and would result in the major interface version being incremented. * compatibility and would result in the major interface version being incremented.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class IGpuMemoryBindable : public IDestroyable class IGpuMemoryBindable : public IDestroyable
{ {
public: public:
/// Queries the GPU memory properties required by this object. The client should query properties with this method, /// Queries the GPU memory properties required by this object. The client should query properties with this method,
/// create/sub-allocate a memory range matching the requirements, then bind the memory to the object via /// create/sub-allocate a memory range matching the requirements, then bind the memory to the object via
/// @ref BindGpuMemory(). /// @ref BindGpuMemory().
/// ///
/// @note Not all objects may actually need GPU memory, and in that case the memory properties will reflect a 0 size /// @note Not all objects may actually need GPU memory, and in that case the memory properties will reflect a 0 size
/// and alignment. /// and alignment.
/// ///
/// @param [out] pGpuMemReqs Required properties of GPU memory to be bound to this object. Includes properties like /// @param [out] pGpuMemReqs Required properties of GPU memory to be bound to this object. Includes properties like
/// size, alignment, and allowed heaps. /// size, alignment, and allowed heaps.
virtual void GetGpuMemoryRequirements( virtual void GetGpuMemoryRequirements(
GpuMemoryRequirements* pGpuMemReqs) const = 0; GpuMemoryRequirements* pGpuMemReqs) const = 0;
/// Binds GPU memory to this object according to the requirements queried via GetGpuMemoryRequirements(). /// Binds GPU memory to this object according to the requirements queried via GetGpuMemoryRequirements().
/// ///
/// Binding memory to objects other than images automatically initializes the object memory as necessary. Image /// Binding memory to objects other than images automatically initializes the object memory as necessary. Image
/// objects used as color or depth-stencil targets have to be explicitly initialized in command buffers using a /// objects used as color or depth-stencil targets have to be explicitly initialized in command buffers using a
/// ICmdBuffer::CmdReleaseThenAcquire() command to transition them out of the LayoutUninitializedTarget usage. /// ICmdBuffer::CmdReleaseThenAcquire() command to transition them out of the LayoutUninitializedTarget usage.
/// ///
/// Binding memory to an object automatically unbinds any previously bound memory. There is no need to bind null to /// Binding memory to an object automatically unbinds any previously bound memory. There is no need to bind null to
/// an object to explicitly unbind a previously bound allocation before binding a new allocation. /// an object to explicitly unbind a previously bound allocation before binding a new allocation.
/// ///
/// This call is invalid on objects that have no memory requirements, even if binding null. /// This call is invalid on objects that have no memory requirements, even if binding null.
/// ///
/// @param [in] pGpuMemory GPU memory to be bound. If null, the previous binding will be released. /// @param [in] pGpuMemory GPU memory to be bound. If null, the previous binding will be released.
/// @param [in] offset Offset into the GPU memory where the object's memory range should begin. This allows /// @param [in] offset Offset into the GPU memory where the object's memory range should begin. This allows
/// sub-allocating many object's GPU memory from the same IGpuMemory object. /// sub-allocating many object's GPU memory from the same IGpuMemory object.
/// ///
/// @returns Success if the specified GPU memory was successfully bound to the object. Otherwise, one of the /// @returns Success if the specified GPU memory was successfully bound to the object. Otherwise, one of the
/// following errors may be returned: /// following errors may be returned:
/// + ErrorUnavailable if binding a non-image to a virtual allocation. /// + ErrorUnavailable if binding a non-image to a virtual allocation.
/// + ErrorInvalidAlignment if the offset does not match the alignment requirements of the object. /// + ErrorInvalidAlignment if the offset does not match the alignment requirements of the object.
/// + ErrorInvalidMemorySize if the object's required memory size does not fit completely within the given /// + ErrorInvalidMemorySize if the object's required memory size does not fit completely within the given
/// memory object at the specified offset. /// memory object at the specified offset.
virtual Result BindGpuMemory( virtual Result BindGpuMemory(
IGpuMemory* pGpuMemory, IGpuMemory* pGpuMemory,
gpusize offset) = 0; gpusize offset) = 0;
/// Returns the GPU memory object and offset that this object is bound to or nullptr and 0 if not bound. /// Returns the GPU memory object and offset that this object is bound to or nullptr and 0 if not bound.
/// ///
/// @param [out] ppGpuMemory Returns the GPU memory object to the address specified in this pointer. /// @param [out] ppGpuMemory Returns the GPU memory object to the address specified in this pointer.
/// Returns nullptr if this object is not bound to any GPU memory. /// Returns nullptr if this object is not bound to any GPU memory.
/// @param [out] pOffset Returns the GPU memory offset to the address specified in this pointer. /// @param [out] pOffset Returns the GPU memory offset to the address specified in this pointer.
/// Returns 0 if this object is not bound to any GPU memory. /// Returns 0 if this object is not bound to any GPU memory.
/// ///
/// @returns Success if the GPU memory and offset was successfully returned. Otherwise, one of the following errors /// @returns Success if the GPU memory and offset was successfully returned. Otherwise, one of the following errors
/// may be returned: /// may be returned:
/// + ErrorGpuMemoryNotBound if this object is not bound to any GPU memory. /// + ErrorGpuMemoryNotBound if this object is not bound to any GPU memory.
/// + ErrorInvalidPointer if either ppGpuMemory or pOffset is nullptr. /// + ErrorInvalidPointer if either ppGpuMemory or pOffset is nullptr.
/// + ErrorUnavailable if binding is not supported in the derived class /// + ErrorUnavailable if binding is not supported in the derived class
virtual Result GetGpuMemory( virtual Result GetGpuMemory(
IGpuMemory** ppGpuMemory, IGpuMemory** ppGpuMemory,
gpusize* pOffset) const = 0; gpusize* pOffset) const = 0;
protected: protected:
/// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by /// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by
/// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the /// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the
/// object on their own. /// object on their own.
virtual ~IGpuMemoryBindable() { } virtual ~IGpuMemoryBindable() { }
}; };
} // Pal } // Pal
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+187 -187
파일 보기
@@ -1,187 +1,187 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palMsaaState.h * @file palMsaaState.h
* @brief Defines the Platform Abstraction Library (PAL) IMsaaState interface and related types. * @brief Defines the Platform Abstraction Library (PAL) IMsaaState interface and related types.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "pal.h" #include "pal.h"
#include "palDestroyable.h" #include "palDestroyable.h"
namespace Pal namespace Pal
{ {
/// Specifies conservative rasterization mode /// Specifies conservative rasterization mode
enum class ConservativeRasterizationMode : uint8 enum class ConservativeRasterizationMode : uint8
{ {
Overestimate = 0x0, ///< Fragments will be generated if the primitive area covers any portion of the pixel. Overestimate = 0x0, ///< Fragments will be generated if the primitive area covers any portion of the pixel.
Underestimate = 0x1, ///< Fragments will be generated if all of the pixel is covered by the primitive. Underestimate = 0x1, ///< Fragments will be generated if all of the pixel is covered by the primitive.
Count Count
}; };
/// Maximum supported number of MSAA color samples. /// Maximum supported number of MSAA color samples.
constexpr uint32 MaxMsaaColorSamples = 16; constexpr uint32 MaxMsaaColorSamples = 16;
/// Maximum supported number of MSAA depth samples. /// Maximum supported number of MSAA depth samples.
constexpr uint32 MaxMsaaDepthSamples = 8; constexpr uint32 MaxMsaaDepthSamples = 8;
/// Maximum supported number of MSAA fragments. /// Maximum supported number of MSAA fragments.
constexpr uint32 MaxMsaaFragments = 8; constexpr uint32 MaxMsaaFragments = 8;
/// Sampling pattern grid size. This is a quad of pixels, i.e. 2x2 grid of pixels. /// Sampling pattern grid size. This is a quad of pixels, i.e. 2x2 grid of pixels.
constexpr Extent2d MaxGridSize = { 2, 2 }; constexpr Extent2d MaxGridSize = { 2, 2 };
/// The positions are rounded to 1/Pow2(SubPixelBits) /// The positions are rounded to 1/Pow2(SubPixelBits)
constexpr uint32 SubPixelBits = 4; constexpr uint32 SubPixelBits = 4;
/// Each pixel is subdivided into Pow2(SubPixelBits) x Pow2(SubPixelBits) grid of possible sample locations. /// Each pixel is subdivided into Pow2(SubPixelBits) x Pow2(SubPixelBits) grid of possible sample locations.
constexpr Extent2d SubPixelGridSize = { 16, 16 }; constexpr Extent2d SubPixelGridSize = { 16, 16 };
/// Represents a 2D coordinate with each component in [-8/16, 7/16] /// Represents a 2D coordinate with each component in [-8/16, 7/16]
struct SampleLocation struct SampleLocation
{ {
int8 x; ///< X offset. int8 x; ///< X offset.
int8 y; ///< Y offset. int8 y; ///< Y offset.
/// Conversion operator that does sign-extension. /// Conversion operator that does sign-extension.
operator Offset2d() const { return { x, y }; } operator Offset2d() const { return { x, y }; }
}; };
/// Specifies a custom multisample pattern for a pixel quad. /// Specifies a custom multisample pattern for a pixel quad.
struct MsaaQuadSamplePattern struct MsaaQuadSamplePattern
{ {
SampleLocation topLeft[MaxMsaaRasterizerSamples]; ///< Sample locations for TL pixel of quad. SampleLocation topLeft[MaxMsaaRasterizerSamples]; ///< Sample locations for TL pixel of quad.
SampleLocation topRight[MaxMsaaRasterizerSamples]; ///< Sample locations for TR pixel of quad. SampleLocation topRight[MaxMsaaRasterizerSamples]; ///< Sample locations for TR pixel of quad.
SampleLocation bottomLeft[MaxMsaaRasterizerSamples]; ///< Sample locations for BL pixel of quad. SampleLocation bottomLeft[MaxMsaaRasterizerSamples]; ///< Sample locations for BL pixel of quad.
SampleLocation bottomRight[MaxMsaaRasterizerSamples]; ///< Sample locations for BR pixel of quad. SampleLocation bottomRight[MaxMsaaRasterizerSamples]; ///< Sample locations for BR pixel of quad.
}; };
/// Specifies properties for creation of an @ref IMsaaState object. Input structure to IDevice::CreateMsaaState(). /// Specifies properties for creation of an @ref IMsaaState object. Input structure to IDevice::CreateMsaaState().
struct MsaaStateCreateInfo struct MsaaStateCreateInfo
{ {
uint8 coverageSamples; ///< Number of rasterizer samples. Must be greater than or equal to all sample uint8 coverageSamples; ///< Number of rasterizer samples. Must be greater than or equal to all sample
/// rates in the pipeline. Valid values are 1, 2, 4, 8, and 16. /// rates in the pipeline. Valid values are 1, 2, 4, 8, and 16.
uint8 exposedSamples; ///< Number of samples exposed in the pixel shader coverage mask. Must be less uint8 exposedSamples; ///< Number of samples exposed in the pixel shader coverage mask. Must be less
/// than or equal to coverageSamples. Valid values are 1, 2, 4, and 8. /// than or equal to coverageSamples. Valid values are 1, 2, 4, and 8.
uint8 pixelShaderSamples; ///< Controls the pixel shader execution rate. Must be less than or equal to uint8 pixelShaderSamples; ///< Controls the pixel shader execution rate. Must be less than or equal to
/// coverageSamples. Valid values are 1, 2, 4, and 8. Note that value with /// coverageSamples. Valid values are 1, 2, 4, and 8. Note that value with
/// greater than 1 doesn't mean sample rate shading is enabled. Sample rate /// greater than 1 doesn't mean sample rate shading is enabled. Sample rate
/// shading is enabled by either @ref forceSampleRateShading or pixel shader. /// shading is enabled by either @ref forceSampleRateShading or pixel shader.
uint8 depthStencilSamples; ///< Number of samples in the bound depth target. Must be less than or equal to uint8 depthStencilSamples; ///< Number of samples in the bound depth target. Must be less than or equal to
/// coverageSamples. Valid values are 1, 2, 4, and 8. /// coverageSamples. Valid values are 1, 2, 4, and 8.
uint8 shaderExportMaskSamples; ///< Number of samples to use in the shader export mask. Should match the number uint8 shaderExportMaskSamples; ///< Number of samples to use in the shader export mask. Should match the number
/// of color target fragments clamped to /// of color target fragments clamped to
/// @ref DeviceProperties imageProperties.maxMsaaFragments. /// @ref DeviceProperties imageProperties.maxMsaaFragments.
uint8 sampleClusters; ///< Number of sample clusters to control over-rasterization (all samples in a uint8 sampleClusters; ///< Number of sample clusters to control over-rasterization (all samples in a
/// cluster are rasterized if any are hit). Must be less than or equal to /// cluster are rasterized if any are hit). Must be less than or equal to
/// coverageSamples. Valid values are 1, 2, 4, and 8. /// coverageSamples. Valid values are 1, 2, 4, and 8.
uint8 alphaToCoverageSamples; ///< How many samples of quality to generate with alpha-to-coverage. Must be uint8 alphaToCoverageSamples; ///< How many samples of quality to generate with alpha-to-coverage. Must be
/// less than or equal to coverageSamples. Valid values are 1, 2, 4, 8, and 16. /// less than or equal to coverageSamples. Valid values are 1, 2, 4, 8, and 16.
uint8 occlusionQuerySamples; ///< Controls the number of samples to use for occlusion queries. uint8 occlusionQuerySamples; ///< Controls the number of samples to use for occlusion queries.
/// This value must never exceed the MSAA rate. /// This value must never exceed the MSAA rate.
uint16 sampleMask; ///< Bitmask of which color target and depth/stencil samples should be updated. uint16 sampleMask; ///< Bitmask of which color target and depth/stencil samples should be updated.
/// The lowest bit corresponds to sample 0. /// The lowest bit corresponds to sample 0.
/// Selects overestimate or underestimate conservative rasterization mode. Used only if /// Selects overestimate or underestimate conservative rasterization mode. Used only if
/// @ref MsaaStateCreateInfo::flags::enableConservativeRasterization is set to true. /// @ref MsaaStateCreateInfo::flags::enableConservativeRasterization is set to true.
ConservativeRasterizationMode conservativeRasterizationMode; ConservativeRasterizationMode conservativeRasterizationMode;
union union
{ {
struct struct
{ {
uint8 enableConservativeRasterization : 1; ///< Set to true to enable conservative rasterization uint8 enableConservativeRasterization : 1; ///< Set to true to enable conservative rasterization
uint8 enable1xMsaaSampleLocations : 1; ///< Set to true to enable 1xMSAA quad sample pattern uint8 enable1xMsaaSampleLocations : 1; ///< Set to true to enable 1xMSAA quad sample pattern
uint8 disableAlphaToCoverageDither : 1; ///< Disables coverage dithering. uint8 disableAlphaToCoverageDither : 1; ///< Disables coverage dithering.
uint8 enableLineStipple : 1; ///< Set to true to enable line stippling uint8 enableLineStipple : 1; ///< Set to true to enable line stippling
uint8 forceSampleRateShading : 1; ///< Sample rate shading can be enabled by either the pixel uint8 forceSampleRateShading : 1; ///< Sample rate shading can be enabled by either the pixel
/// shader, or forced here with forceSampleRateShading = 1. /// shader, or forced here with forceSampleRateShading = 1.
/// Value 0 means sample rate shading is decided by pixel shader /// Value 0 means sample rate shading is decided by pixel shader
/// and value 1 means sample rate shading is forced enabled. /// and value 1 means sample rate shading is forced enabled.
/// This bit is for openGL glMinSampleShading, where sample rate /// This bit is for openGL glMinSampleShading, where sample rate
/// shading can be enabled by glEnable(GL_SAMPLE_SHADING) /// shading can be enabled by glEnable(GL_SAMPLE_SHADING)
/// instead of by the pixel shader. /// instead of by the pixel shader.
uint8 reserved : 3; ///< Reserved for future use uint8 reserved : 3; ///< Reserved for future use
}; };
uint8 u8All; uint8 u8All;
} flags; } flags;
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @interface IMsaaState * @interface IMsaaState
* @brief Dynamic state object controlling fixed function MSAA state. * @brief Dynamic state object controlling fixed function MSAA state.
* *
* Configures sample counts of various portions of the pipeline, specifies sample positions, etc. The full range of * Configures sample counts of various portions of the pipeline, specifies sample positions, etc. The full range of
* EQAA hardware features are exposed. * EQAA hardware features are exposed.
* *
* @see IDevice::CreateMsaaState * @see IDevice::CreateMsaaState
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class IMsaaState : public IDestroyable class IMsaaState : public IDestroyable
{ {
public: public:
/// Returns the value of the associated arbitrary client data pointer. /// Returns the value of the associated arbitrary client data pointer.
/// Can be used to associate arbitrary data with a particular PAL object. /// Can be used to associate arbitrary data with a particular PAL object.
/// ///
/// @returns Pointer to client data. /// @returns Pointer to client data.
void* GetClientData() const void* GetClientData() const
{ {
return m_pClientData; return m_pClientData;
} }
/// Sets the value of the associated arbitrary client data pointer. /// Sets the value of the associated arbitrary client data pointer.
/// Can be used to associate arbitrary data with a particular PAL object. /// Can be used to associate arbitrary data with a particular PAL object.
/// ///
/// @param [in] pClientData A pointer to arbitrary client data. /// @param [in] pClientData A pointer to arbitrary client data.
void SetClientData( void SetClientData(
void* pClientData) void* pClientData)
{ {
m_pClientData = pClientData; m_pClientData = pClientData;
} }
protected: protected:
/// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly /// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly
/// called the proper create method. /// called the proper create method.
IMsaaState() : m_pClientData(nullptr) {} IMsaaState() : m_pClientData(nullptr) {}
/// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by /// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by
/// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the /// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the
/// object on their own. /// object on their own.
virtual ~IMsaaState() { } virtual ~IMsaaState() { }
private: private:
/// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData() /// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData()
/// and set via SetClientData(). /// and set via SetClientData().
/// For non-top-layer objects, this will point to the layer above the current object. /// For non-top-layer objects, this will point to the layer above the current object.
void* m_pClientData; void* m_pClientData;
}; };
} // Pal } // Pal
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+234 -234
파일 보기
@@ -1,234 +1,234 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palQueryPool.h * @file palQueryPool.h
* @brief Defines the Platform Abstraction Library (PAL) IQueryPool interface and related types. * @brief Defines the Platform Abstraction Library (PAL) IQueryPool interface and related types.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "pal.h" #include "pal.h"
#include "palGpuMemoryBindable.h" #include "palGpuMemoryBindable.h"
namespace Pal namespace Pal
{ {
/// Specifies a category of GPU query pool. /// Specifies a category of GPU query pool.
enum class QueryPoolType : uint32 enum class QueryPoolType : uint32
{ {
Occlusion = 0x0, ///< Occlusion query pool. Supports queries based on the Z test. Occlusion = 0x0, ///< Occlusion query pool. Supports queries based on the Z test.
PipelineStats = 0x1, ///< Pipeline stats query pool. Supports queries based on statistics from the GPU's execution PipelineStats = 0x1, ///< Pipeline stats query pool. Supports queries based on statistics from the GPU's execution
/// such as a count of prims generated, shader invocations, etc. /// such as a count of prims generated, shader invocations, etc.
StreamoutStats = 0x2, ///< Streamout query pool. Supports queries based on statistics from the GPU's execution StreamoutStats = 0x2, ///< Streamout query pool. Supports queries based on statistics from the GPU's execution
/// such as number of primitives written to SO buffer and storage needed. /// such as number of primitives written to SO buffer and storage needed.
Count, Count,
}; };
/// Specifies what data a query slot must produce. Some query pool types support multiple query types. /// Specifies what data a query slot must produce. Some query pool types support multiple query types.
enum class QueryType : uint32 enum class QueryType : uint32
{ {
Occlusion = 0x0, ///< The total passes recorded by the Z test. Occlusion = 0x0, ///< The total passes recorded by the Z test.
BinaryOcclusion = 0x1, ///< One if there were one or more Z test passes, zero otherwise. BinaryOcclusion = 0x1, ///< One if there were one or more Z test passes, zero otherwise.
PipelineStats = 0x2, ///< The total statistics selected by the given pipeline stats query pool. PipelineStats = 0x2, ///< The total statistics selected by the given pipeline stats query pool.
StreamoutStats = 0x3, ///< SO statistics tracked by CP/VGT including primitives written and storage needed. StreamoutStats = 0x3, ///< SO statistics tracked by CP/VGT including primitives written and storage needed.
StreamoutStats1 = 0x4, ///< SO1 statistics tracked by CP/VGT including primitives written and storage needed. StreamoutStats1 = 0x4, ///< SO1 statistics tracked by CP/VGT including primitives written and storage needed.
StreamoutStats2 = 0x5, ///< SO2 statistics tracked by CP/VGT including primitives written and storage needed. StreamoutStats2 = 0x5, ///< SO2 statistics tracked by CP/VGT including primitives written and storage needed.
StreamoutStats3 = 0x6, ///< SO3 statistics tracked by CP/VGT including primitives written and storage needed. StreamoutStats3 = 0x6, ///< SO3 statistics tracked by CP/VGT including primitives written and storage needed.
Count, Count,
}; };
/// Specifies which pipeline stats should be tracked by a pipeline stats query pool. /// Specifies which pipeline stats should be tracked by a pipeline stats query pool.
enum QueryPipelineStatsFlags : uint32 enum QueryPipelineStatsFlags : uint32
{ {
QueryPipelineStatsIaVertices = 0x1, ///< Input vertices. QueryPipelineStatsIaVertices = 0x1, ///< Input vertices.
QueryPipelineStatsIaPrimitives = 0x2, ///< Input primitives. QueryPipelineStatsIaPrimitives = 0x2, ///< Input primitives.
QueryPipelineStatsVsInvocations = 0x4, ///< Vertex shader invocations. QueryPipelineStatsVsInvocations = 0x4, ///< Vertex shader invocations.
QueryPipelineStatsGsInvocations = 0x8, ///< Geometry shader invocations. QueryPipelineStatsGsInvocations = 0x8, ///< Geometry shader invocations.
QueryPipelineStatsGsPrimitives = 0x10, ///< Geometry shader primitives. QueryPipelineStatsGsPrimitives = 0x10, ///< Geometry shader primitives.
QueryPipelineStatsCInvocations = 0x20, ///< Clipper invocations. QueryPipelineStatsCInvocations = 0x20, ///< Clipper invocations.
QueryPipelineStatsCPrimitives = 0x40, ///< Clipper primitives. QueryPipelineStatsCPrimitives = 0x40, ///< Clipper primitives.
QueryPipelineStatsPsInvocations = 0x80, ///< Pixel shader invocations. QueryPipelineStatsPsInvocations = 0x80, ///< Pixel shader invocations.
QueryPipelineStatsHsInvocations = 0x100, ///< Hull shader invocations. QueryPipelineStatsHsInvocations = 0x100, ///< Hull shader invocations.
QueryPipelineStatsDsInvocations = 0x200, ///< Domain shader invocations. QueryPipelineStatsDsInvocations = 0x200, ///< Domain shader invocations.
QueryPipelineStatsCsInvocations = 0x400, ///< Compute shader invocations. QueryPipelineStatsCsInvocations = 0x400, ///< Compute shader invocations.
QueryPipelineStatsTsInvocations = 0x800, ///< Task shader invocations. QueryPipelineStatsTsInvocations = 0x800, ///< Task shader invocations.
QueryPipelineStatsMsInvocations = 0x1000, ///< Mesh shader invocations. QueryPipelineStatsMsInvocations = 0x1000, ///< Mesh shader invocations.
QueryPipelineStatsMsPrimitives = 0x2000, ///< Mesh shader primitives. QueryPipelineStatsMsPrimitives = 0x2000, ///< Mesh shader primitives.
QueryPipelineStatsAll = 0x3FFF ///< All of the above stats. QueryPipelineStatsAll = 0x3FFF ///< All of the above stats.
}; };
/// Specifies properties for @ref IQueryPool creation. Input structure to IDevice::CreateQueryPool(). /// Specifies properties for @ref IQueryPool creation. Input structure to IDevice::CreateQueryPool().
struct QueryPoolCreateInfo struct QueryPoolCreateInfo
{ {
QueryPoolType queryPoolType; ///< Type of query pool to create (i.e., occlusion vs. pipeline stats). QueryPoolType queryPoolType; ///< Type of query pool to create (i.e., occlusion vs. pipeline stats).
uint32 numSlots; ///< Number of slots in the query pool. uint32 numSlots; ///< Number of slots in the query pool.
uint32 enabledStats; ///< An ORed mask of stats flags specific to the query pool type. uint32 enabledStats; ///< An ORed mask of stats flags specific to the query pool type.
/// @see QueryPipelineStatsFlags for PipelineStats query pools. /// @see QueryPipelineStatsFlags for PipelineStats query pools.
union union
{ {
struct struct
{ {
/// If true, this query pool can have results retrieved using the CPU (using @ref IQueryPool::GetResults) /// If true, this query pool can have results retrieved using the CPU (using @ref IQueryPool::GetResults)
/// and can be reset using the CPU (using @ref IQueryPool::Reset). Otherwise, the client must use command /// and can be reset using the CPU (using @ref IQueryPool::Reset). Otherwise, the client must use command
/// buffers to perform these operations (using @ref ICmdBuffer::CmdResetQueryPool and /// buffers to perform these operations (using @ref ICmdBuffer::CmdResetQueryPool and
/// @ref ICmdBuffer::CmdResolveQuery). /// @ref ICmdBuffer::CmdResolveQuery).
uint32 enableCpuAccess : 1; uint32 enableCpuAccess : 1;
uint32 reserved : 31; ///< Reserved for future use. uint32 reserved : 31; ///< Reserved for future use.
}; };
uint32 u32All; ///< Flags packed together as a uint32. uint32 u32All; ///< Flags packed together as a uint32.
} flags; ///< Flags controlling QueryPool behavior. } flags; ///< Flags controlling QueryPool behavior.
}; };
/// Controls operations that compute query results. /// Controls operations that compute query results.
enum QueryResultFlags : uint32 enum QueryResultFlags : uint32
{ {
QueryResultDefault = 0x0, ///< Default to 32-bit results with no waiting. QueryResultDefault = 0x0, ///< Default to 32-bit results with no waiting.
QueryResult64Bit = 0x1, ///< Store all results as 64-bit values. QueryResult64Bit = 0x1, ///< Store all results as 64-bit values.
QueryResultWait = 0x2, ///< Wait for the queries to finish when computing the results. QueryResultWait = 0x2, ///< Wait for the queries to finish when computing the results.
QueryResultAvailability = 0x4, ///< If the results of a query are available at computation time a one will be QueryResultAvailability = 0x4, ///< If the results of a query are available at computation time a one will be
/// written as a separate value after the result value, if the results were not /// written as a separate value after the result value, if the results were not
/// available a zero will be written. /// available a zero will be written.
QueryResultPartial = 0x8, ///< If the final result of a query would be unavailable, then return a QueryResultPartial = 0x8, ///< If the final result of a query would be unavailable, then return a
/// result for that query between 0 and what the final result would be. /// result for that query between 0 and what the final result would be.
QueryResultAccumulate = 0x10, ///< Results are added to the values present in the destination, if availability QueryResultAccumulate = 0x10, ///< Results are added to the values present in the destination, if availability
/// data is enabled it will be ANDed with the present availability data. /// data is enabled it will be ANDed with the present availability data.
QueryResultPreferShaderPath = 0x20, ///< Prefer a shader resolve path over a command processor path. QueryResultPreferShaderPath = 0x20, ///< Prefer a shader resolve path over a command processor path.
QueryResultOnlyPrimNeeded = 0x40, ///< Select only primitives storage needed in Streamout query results QueryResultOnlyPrimNeeded = 0x40, ///< Select only primitives storage needed in Streamout query results
QueryResultAll = 0x7F ///< Clients should NOT use it, for internal static_assert purpose only. QueryResultAll = 0x7F ///< Clients should NOT use it, for internal static_assert purpose only.
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @interface IQueryPool * @interface IQueryPool
* @brief Represents a set of queries that can be used to retrieve detailed info about the GPU's execution of a * @brief Represents a set of queries that can be used to retrieve detailed info about the GPU's execution of a
* particular range of a command buffer. * particular range of a command buffer.
* *
* Currently, only occlusion queries and pipeline statistic queries are supported. All queries in a pool are the same * Currently, only occlusion queries and pipeline statistic queries are supported. All queries in a pool are the same
* type. * type.
* *
* @see IDevice::CreateQueryPool() * @see IDevice::CreateQueryPool()
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class IQueryPool : public IGpuMemoryBindable class IQueryPool : public IGpuMemoryBindable
{ {
public: public:
/// Retrieves query results from a query pool. /// Retrieves query results from a query pool.
/// ///
/// Multiple consecutive query results can be retrieved with one call. /// Multiple consecutive query results can be retrieved with one call.
/// ///
/// @param [in] flags Flags that control the result data layout and how the results are retrieved. /// @param [in] flags Flags that control the result data layout and how the results are retrieved.
/// @param [in] queryType Specifies what data the query slots must produce. /// @param [in] queryType Specifies what data the query slots must produce.
/// @param [in] startQuery First query pool slot to retrieve data for. /// @param [in] startQuery First query pool slot to retrieve data for.
/// @param [in] queryCount Number of query pool slots to retrieve data for. /// @param [in] queryCount Number of query pool slots to retrieve data for.
/// @param [in] pMappedGpuAddr Specify the query buffer mapped address. If the parameter equals nullptr, /// @param [in] pMappedGpuAddr Specify the query buffer mapped address. If the parameter equals nullptr,
// this method will use Map\UnMap to access the data. // this method will use Map\UnMap to access the data.
/// @param [in,out] pDataSize Input value specifies the available size in pData in bytes; output value reports the /// @param [in,out] pDataSize Input value specifies the available size in pData in bytes; output value reports the
/// number of bytes required to hold all result data. /// number of bytes required to hold all result data.
/// @param [out] pData Location where the query results should be written. Can be null in order to query the /// @param [out] pData Location where the query results should be written. Can be null in order to query the
/// required size. The data returned depends on the query pool type and flags. All data /// required size. The data returned depends on the query pool type and flags. All data
/// entries are either uint32 or uint64 integers. One or more type-specific entries will /// entries are either uint32 or uint64 integers. One or more type-specific entries will
/// be optionally followed by one entry for availability. The type-specific data is:<br> /// be optionally followed by one entry for availability. The type-specific data is:<br>
/// + QueryOcclusion: One entry to store the zPass count. /// + QueryOcclusion: One entry to store the zPass count.
/// + QueryPipelineStats: One entry per statistic enabled in the create info. The stats /// + QueryPipelineStats: One entry per statistic enabled in the create info. The stats
/// will be written in the appropriate order for each PAL client. /// will be written in the appropriate order for each PAL client.
/// @param [in] stride Stride in bytes between subsequent query result data or zero to request tightly /// @param [in] stride Stride in bytes between subsequent query result data or zero to request tightly
/// packed result data. /// packed result data.
/// ///
/// @returns Success if query results were successfully returned in pData, or NotReady if any of the requested query /// @returns Success if query results were successfully returned in pData, or NotReady if any of the requested query
/// slots does not yet have results available. Otherwise, one of the following error codes may be /// slots does not yet have results available. Otherwise, one of the following error codes may be
/// returned: /// returned:
/// + ErrorInvalidValue if the range defined by startQuery and queryCount is not valid for this query pool. /// + ErrorInvalidValue if the range defined by startQuery and queryCount is not valid for this query pool.
/// + ErrorGpuMemoryNotBound if the query pool requires GPU memory but none is bound. /// + ErrorGpuMemoryNotBound if the query pool requires GPU memory but none is bound.
/// + ErrorInvalidMemorySize if pData is non-null and the value stored in pDataSize is too small. /// + ErrorInvalidMemorySize if pData is non-null and the value stored in pDataSize is too small.
virtual Result GetResults( virtual Result GetResults(
QueryResultFlags flags, QueryResultFlags flags,
QueryType queryType, QueryType queryType,
uint32 startQuery, uint32 startQuery,
uint32 queryCount, uint32 queryCount,
const void* pMappedGpuAddr, const void* pMappedGpuAddr,
size_t* pDataSize, size_t* pDataSize,
void* pData, void* pData,
size_t stride) = 0; size_t stride) = 0;
/// Use CPU to reset the query pool slots. /// Use CPU to reset the query pool slots.
/// ///
/// Supported for occlusion and video decode statistics query pools. /// Supported for occlusion and video decode statistics query pools.
/// ///
/// @param [in] startQuery First query pool slot to reset. /// @param [in] startQuery First query pool slot to reset.
/// @param [in] queryCount Number of query pool slots to reset. /// @param [in] queryCount Number of query pool slots to reset.
/// @param [in] pMappedCpuAddr Specify the query buffer mapped address. If the parameter equals nullptr, /// @param [in] pMappedCpuAddr Specify the query buffer mapped address. If the parameter equals nullptr,
// this method will use Map/UnMap to access the data. // this method will use Map/UnMap to access the data.
/// ///
/// @returns Success if the reset was successfully performed. /// @returns Success if the reset was successfully performed.
virtual Result Reset( virtual Result Reset(
uint32 startQuery, uint32 startQuery,
uint32 queryCount, uint32 queryCount,
void* pMappedCpuAddr) = 0; void* pMappedCpuAddr) = 0;
/// Returns the distance, in bytes, between successive query slots in the bound GPU memory. /// Returns the distance, in bytes, between successive query slots in the bound GPU memory.
/// This method is only supported for @ref QueryPoolType::VideoDecodeStats /// This method is only supported for @ref QueryPoolType::VideoDecodeStats
/// ///
/// @returns the distance, in bytes, between successive query slots in the bound GPU memory. /// @returns the distance, in bytes, between successive query slots in the bound GPU memory.
virtual gpusize GetQuerySlotStride() const = 0; virtual gpusize GetQuerySlotStride() const = 0;
/// Returns the value of the associated arbitrary client data pointer. /// Returns the value of the associated arbitrary client data pointer.
/// Can be used to associate arbitrary data with a particular PAL object. /// Can be used to associate arbitrary data with a particular PAL object.
/// ///
/// @returns Pointer to client data. /// @returns Pointer to client data.
void* GetClientData() const void* GetClientData() const
{ {
return m_pClientData; return m_pClientData;
} }
/// Sets the value of the associated arbitrary client data pointer. /// Sets the value of the associated arbitrary client data pointer.
/// Can be used to associate arbitrary data with a particular PAL object. /// Can be used to associate arbitrary data with a particular PAL object.
/// ///
/// @param [in] pClientData A pointer to arbitrary client data. /// @param [in] pClientData A pointer to arbitrary client data.
void SetClientData( void SetClientData(
void* pClientData) void* pClientData)
{ {
m_pClientData = pClientData; m_pClientData = pClientData;
} }
protected: protected:
/// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly /// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly
/// called the proper create method. /// called the proper create method.
IQueryPool() : m_pClientData(nullptr) {} IQueryPool() : m_pClientData(nullptr) {}
/// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by /// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by
/// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the /// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the
/// object on their own. /// object on their own.
virtual ~IQueryPool() { } virtual ~IQueryPool() { }
private: private:
/// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData() /// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData()
/// and set via SetClientData(). /// and set via SetClientData().
/// For non-top-layer objects, this will point to the layer above the current object. /// For non-top-layer objects, this will point to the layer above the current object.
void* m_pClientData; void* m_pClientData;
}; };
} // Pal } // Pal
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+275 -275
파일 보기
@@ -1,275 +1,275 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palQueueSemaphore.h * @file palQueueSemaphore.h
* @brief Defines the Platform Abstraction Library (PAL) IQueueSemaphore interface and related types. * @brief Defines the Platform Abstraction Library (PAL) IQueueSemaphore interface and related types.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "pal.h" #include "pal.h"
#include "palDestroyable.h" #include "palDestroyable.h"
#include <chrono> #include <chrono>
#if defined(_WIN32) #if defined(_WIN32)
struct _SECURITY_ATTRIBUTES; struct _SECURITY_ATTRIBUTES;
#endif #endif
namespace Pal namespace Pal
{ {
// Forward declarations. // Forward declarations.
class IQueueSemaphore; class IQueueSemaphore;
/// Specifies properties for @ref IQueueSemaphore creation. Input structure to IDevice::CreateQueueSemaphore(). /// Specifies properties for @ref IQueueSemaphore creation. Input structure to IDevice::CreateQueueSemaphore().
struct QueueSemaphoreCreateInfo struct QueueSemaphoreCreateInfo
{ {
union union
{ {
struct struct
{ {
/// This queue semaphore may be opened for use by a different device. /// This queue semaphore may be opened for use by a different device.
/// For DX12 native fence, the flag needs to be consistent with D3DDDI_SYNCHRONIZATIONOBJECT_FLAGS.Shared /// For DX12 native fence, the flag needs to be consistent with D3DDDI_SYNCHRONIZATIONOBJECT_FLAGS.Shared
/// given by DX runtime. /// given by DX runtime.
uint32 shareable : 1; uint32 shareable : 1;
/// This queue semaphore can only be shared through Nt handle. /// This queue semaphore can only be shared through Nt handle.
/// For DX12 native fence, the flag needs to be consistent with /// For DX12 native fence, the flag needs to be consistent with
/// D3DDDI_SYNCHRONIZATIONOBJECT_FLAGS.NtSecuritySharing given by DX runtime. /// D3DDDI_SYNCHRONIZATIONOBJECT_FLAGS.NtSecuritySharing given by DX runtime.
uint32 sharedViaNtHandle : 1; uint32 sharedViaNtHandle : 1;
uint32 externalOpened : 1; ///< Semaphore was created by other APIs uint32 externalOpened : 1; ///< Semaphore was created by other APIs
/// This queue semaphore is a timeline semaphore. Timeline semaphores have a 64-bit unsigned integer payload /// This queue semaphore is a timeline semaphore. Timeline semaphores have a 64-bit unsigned integer payload
/// which gets monotonically increased with each Signal operation. A wait on a timeline semaphore blocks the /// which gets monotonically increased with each Signal operation. A wait on a timeline semaphore blocks the
/// waiter until the specified payload value has been signaled. /// waiter until the specified payload value has been signaled.
/// For DX12 native fence, runtime determines initialCount. Therefore, timeline flag has to be set. /// For DX12 native fence, runtime determines initialCount. Therefore, timeline flag has to be set.
uint32 timeline : 1; uint32 timeline : 1;
/// Do not signal the queue semaphore to max if the device is lost. /// Do not signal the queue semaphore to max if the device is lost.
/// For DX12 native fence, the flag needs to be consistent with /// For DX12 native fence, the flag needs to be consistent with
/// D3DDDI_SYNCHRONIZATIONOBJECT_FLAGS.NoSignalMaxValueOnTdr given by DX runtime. /// D3DDDI_SYNCHRONIZATIONOBJECT_FLAGS.NoSignalMaxValueOnTdr given by DX runtime.
uint32 noSignalOnDeviceLost : 1; uint32 noSignalOnDeviceLost : 1;
/// For native fence only. If it's 0x0, the native fence type is D3DDDI_NATIVEFENCE_TYPE_DEFAULT. /// For native fence only. If it's 0x0, the native fence type is D3DDDI_NATIVEFENCE_TYPE_DEFAULT.
/// If it's 0x1, native fence type is D3DDDI_NATIVEFENCE_TYPE_INTRA_GPU. /// If it's 0x1, native fence type is D3DDDI_NATIVEFENCE_TYPE_INTRA_GPU.
/// For DX12, the value is determined by runtime. DXCP needs to set it by reading D3DDDI_NATIVEFENCEINFO. /// For DX12, the value is determined by runtime. DXCP needs to set it by reading D3DDDI_NATIVEFENCEINFO.
uint32 gpuOnly : 1; uint32 gpuOnly : 1;
/// This queue semaphore will be a monitored fence if this flag set, even if OS supports native fence. /// This queue semaphore will be a monitored fence if this flag set, even if OS supports native fence.
uint32 forceUseMonitoredFence : 1; uint32 forceUseMonitoredFence : 1;
uint32 reserved : 25; ///< Reserved for future use. uint32 reserved : 25; ///< Reserved for future use.
}; };
uint32 u32All; ///< Flags packed as 32-bit uint. uint32 u32All; ///< Flags packed as 32-bit uint.
} flags; ///< Queue semaphore creation flags. } flags; ///< Queue semaphore creation flags.
uint32 maxCount; ///< The maximum signal count; once reached, further signals are dropped. Must be uint32 maxCount; ///< The maximum signal count; once reached, further signals are dropped. Must be
/// non-zero and no more than maxSemaphoreCount in @ref DeviceProperties. For /// non-zero and no more than maxSemaphoreCount in @ref DeviceProperties. For
/// example, a value of one would request a binary semaphore. /// example, a value of one would request a binary semaphore.
/// NOTE: maxCount does not apply to timeline semaphores. /// NOTE: maxCount does not apply to timeline semaphores.
uint64 initialCount; ///< Initial value for timeline semaphores. (or) uint64 initialCount; ///< Initial value for timeline semaphores. (or)
/// Initial count value for counting semaphores. /// Initial count value for counting semaphores.
/// Must not be larger than maxCount for counting semaphores. /// Must not be larger than maxCount for counting semaphores.
/// For DX12 native fence, DXCP needs to pass InitialFenceValue from /// For DX12 native fence, DXCP needs to pass InitialFenceValue from
/// D3DDDI_NATIVEFENCEINFO. /// D3DDDI_NATIVEFENCEINFO.
}; };
/// Specifies parameters for opening a queue semaphore for use on another device. Input structure to /// Specifies parameters for opening a queue semaphore for use on another device. Input structure to
/// IDevice::OpenSharedQueueSemaphore(). /// IDevice::OpenSharedQueueSemaphore().
struct QueueSemaphoreOpenInfo struct QueueSemaphoreOpenInfo
{ {
/// Shared queue semaphore object from another device to be opened. /// Shared queue semaphore object from another device to be opened.
IQueueSemaphore* pSharedQueueSemaphore; IQueueSemaphore* pSharedQueueSemaphore;
}; };
/// Specifies parameters for opening a queue semaphore created by other APIs such as D3D. /// Specifies parameters for opening a queue semaphore created by other APIs such as D3D.
struct ExternalQueueSemaphoreOpenInfo struct ExternalQueueSemaphoreOpenInfo
{ {
union union
{ {
struct struct
{ {
uint32 crossProcess : 1; ///< This semaphore is created in another process. uint32 crossProcess : 1; ///< This semaphore is created in another process.
uint32 sharedViaNtHandle : 1; ///< The shared semaphore handle is NT handle. uint32 sharedViaNtHandle : 1; ///< The shared semaphore handle is NT handle.
uint32 isReference : 1; ///< If set, then the opened semaphore will reference the same sync uint32 isReference : 1; ///< If set, then the opened semaphore will reference the same sync
///< object in the kernel. Otherwise, the object is copied to the ///< object in the kernel. Otherwise, the object is copied to the
///< new Semaphore. ///< new Semaphore.
/// This queue semaphore is a timeline semaphore. Timeline semaphores have a 64-bit unsigned integer payload /// This queue semaphore is a timeline semaphore. Timeline semaphores have a 64-bit unsigned integer payload
/// which gets monotonically increased with each Signal operation. A wait on a timeline semaphore blocks the /// which gets monotonically increased with each Signal operation. A wait on a timeline semaphore blocks the
/// waiter until the specified payload value has been signaled. /// waiter until the specified payload value has been signaled.
uint32 timeline : 1; uint32 timeline : 1;
uint32 reserved : 28; ///< Reserved for future use. uint32 reserved : 28; ///< Reserved for future use.
}; };
uint32 u32All; ///< Flags packed as 32-bit uint. uint32 u32All; ///< Flags packed as 32-bit uint.
} flags; ///< External queue semaphore open flags. } flags; ///< External queue semaphore open flags.
OsExternalHandle externalSemaphore; ///< External shared semaphore handle. OsExternalHandle externalSemaphore; ///< External shared semaphore handle.
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 882 #if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 882
#if defined(__unix__) && PAL_KMT_BUILD #if defined(__unix__) && PAL_KMT_BUILD
uint64 syncFdSignalValue; ///< Signal timeline value when importing the state of a sync file uint64 syncFdSignalValue; ///< Signal timeline value when importing the state of a sync file
#endif #endif
#endif #endif
}; };
/// Specifies parameters for exporting a queue semaphore. Input structure to IQueueSemaphore::ExportExternalHandle(). /// Specifies parameters for exporting a queue semaphore. Input structure to IQueueSemaphore::ExportExternalHandle().
struct QueueSemaphoreExportInfo struct QueueSemaphoreExportInfo
{ {
union union
{ {
struct struct
{ {
uint32 isReference : 1; ///< If set, then the semaphore exporting a handle that reference the uint32 isReference : 1; ///< If set, then the semaphore exporting a handle that reference the
///< same sync object in the kernel. Otherwise, the object is copied ///< same sync object in the kernel. Otherwise, the object is copied
///< to the new Semaphore. ///< to the new Semaphore.
uint32 reserved : 31; ///< Resevered for future use. uint32 reserved : 31; ///< Resevered for future use.
}; };
uint32 u32All; ///< Flags packed as 32-bit uint. uint32 u32All; ///< Flags packed as 32-bit uint.
} flags; ///< External queue semaphore export flags. } flags; ///< External queue semaphore export flags.
#if PAL_KMT_BUILD #if PAL_KMT_BUILD
const _SECURITY_ATTRIBUTES* pSecurityAttributes; ///< It specifies the security descriptor and the inheritable const _SECURITY_ATTRIBUTES* pSecurityAttributes; ///< It specifies the security descriptor and the inheritable
/// attribute. /// attribute.
const wchar_t* pNtObjectName; ///< A name to NT handle, if the object is exported as a NT const wchar_t* pNtObjectName; ///< A name to NT handle, if the object is exported as a NT
/// handle with a name, and then the handle can be acquired /// handle with a name, and then the handle can be acquired
/// via this name. /// via this name.
uint32 accessFlags; ///< Desried access rights of GPU memory. uint32 accessFlags; ///< Desried access rights of GPU memory.
#if defined(__unix__) #if defined(__unix__)
uint64 syncFdWaitValue; ///< Wait timeline value when exporting the state of a sync file uint64 syncFdWaitValue; ///< Wait timeline value when exporting the state of a sync file
#endif #endif
#endif #endif
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @interface IQueueSemaphore * @interface IQueueSemaphore
* @brief Semaphore object used to synchronize GPU work performed by multiple, parallel queues. * @brief Semaphore object used to synchronize GPU work performed by multiple, parallel queues.
* *
* These semaphores are used by calling IQueue::SignalQueueSemaphore() and IQueue::WaitQueueSemaphore(). * These semaphores are used by calling IQueue::SignalQueueSemaphore() and IQueue::WaitQueueSemaphore().
* *
* @see IDevice::CreateQueueSemaphore() * @see IDevice::CreateQueueSemaphore()
* @see IDevice::OpenSharedQueueSemaphore() * @see IDevice::OpenSharedQueueSemaphore()
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class IQueueSemaphore : public IDestroyable class IQueueSemaphore : public IDestroyable
{ {
public: public:
/// An IQueue::WaitQueueSemaphore operation may need to be sent down to the OS after the corresponding /// An IQueue::WaitQueueSemaphore operation may need to be sent down to the OS after the corresponding
/// IQueue::SignalQueueSemaphore operation due to GPU scheduler limitations. This method checks if any queues have /// IQueue::SignalQueueSemaphore operation due to GPU scheduler limitations. This method checks if any queues have
/// batched-up commands waiting for a SignalQueueSemaphore operation to appear. /// batched-up commands waiting for a SignalQueueSemaphore operation to appear.
/// ///
/// @returns True if one or more queues have some number of commands batched-up waiting for other queues to signal /// @returns True if one or more queues have some number of commands batched-up waiting for other queues to signal
/// this semaphore. False otherwise. /// this semaphore. False otherwise.
virtual bool HasStalledQueues() = 0; virtual bool HasStalledQueues() = 0;
/// Query timeline Semaphore payload /// Query timeline Semaphore payload
/// ///
/// @param [out] pValue returned payload from querying /// @param [out] pValue returned payload from querying
/// ///
/// @returns Success if the timeline semaphore is queried successful. Otherwise, one of the following errors may /// @returns Success if the timeline semaphore is queried successful. Otherwise, one of the following errors may
/// be returned: /// be returned:
/// + ErrorInvalidValue if an unexpected conversion error occurs. /// + ErrorInvalidValue if an unexpected conversion error occurs.
/// + ErrorInvalidObjectType if semaphore is non-timeline type. /// + ErrorInvalidObjectType if semaphore is non-timeline type.
virtual Result QuerySemaphoreValue( virtual Result QuerySemaphoreValue(
uint64* pValue) = 0; uint64* pValue) = 0;
/// Wait on timeline Semaphore points, to be clarified, this is a CPU wait. /// Wait on timeline Semaphore points, to be clarified, this is a CPU wait.
/// ///
/// @param [in] value Indicate which point to be waited. /// @param [in] value Indicate which point to be waited.
/// @param [in] timeout the max waiting time, timeout is the timeout period in units of nanoseconds. /// @param [in] timeout the max waiting time, timeout is the timeout period in units of nanoseconds.
/// ///
/// @returns Success if the timeline semaphore point is waited successful. Otherwise, one of the following errors /// @returns Success if the timeline semaphore point is waited successful. Otherwise, one of the following errors
/// may be returned: /// may be returned:
/// + ErrorInvalidValue if an unexpected conversion error occurs. /// + ErrorInvalidValue if an unexpected conversion error occurs.
/// + ErrorInvalidObjectType if semaphore is non-timeline type. /// + ErrorInvalidObjectType if semaphore is non-timeline type.
virtual Result WaitSemaphoreValue( virtual Result WaitSemaphoreValue(
uint64 value, uint64 value,
std::chrono::nanoseconds timeout) = 0; std::chrono::nanoseconds timeout) = 0;
/// Signal on timeline Semaphore points, to be clarified, this is a CPU signal. /// Signal on timeline Semaphore points, to be clarified, this is a CPU signal.
/// ///
/// @param [in] value Indicate which point to be signaled. /// @param [in] value Indicate which point to be signaled.
/// ///
/// @returns Success if the timeline semaphore point is signaled successful. Otherwise, one of the following errors /// @returns Success if the timeline semaphore point is signaled successful. Otherwise, one of the following errors
/// may be returned: /// may be returned:
/// + ErrorInvalidValue if an unexpected conversion error occurs. /// + ErrorInvalidValue if an unexpected conversion error occurs.
/// + ErrorInvalidObjectType if semaphore is non-timeline type. /// + ErrorInvalidObjectType if semaphore is non-timeline type.
virtual Result SignalSemaphoreValue( virtual Result SignalSemaphoreValue(
uint64 value) = 0; uint64 value) = 0;
#if PAL_KMT_BUILD || PAL_AMDGPU_BUILD #if PAL_KMT_BUILD || PAL_AMDGPU_BUILD
/// Returns an OS-specific handle which can be used to refer to this semaphore object across processes. This will /// Returns an OS-specific handle which can be used to refer to this semaphore object across processes. This will
/// return a null or invalid handle if the object was not created with the external create flag set. /// return a null or invalid handle if the object was not created with the external create flag set.
/// ///
/// @param [in] exportInfo Information describing how the Semamphore handle should be exported. /// @param [in] exportInfo Information describing how the Semamphore handle should be exported.
/// @note This function is only available for Linux builds. /// @note This function is only available for Linux builds.
/// ///
/// @returns An OS-specific handle which can be used to access the semaphore object across processes. /// @returns An OS-specific handle which can be used to access the semaphore object across processes.
virtual OsExternalHandle ExportExternalHandle( virtual OsExternalHandle ExportExternalHandle(
const QueueSemaphoreExportInfo& exportInfo) const = 0; const QueueSemaphoreExportInfo& exportInfo) const = 0;
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
/// Returns an OS-specific handle which can be used by another device to access the semaphore object. /// Returns an OS-specific handle which can be used by another device to access the semaphore object.
/// ///
/// @returns An OS-specific handle which can be used by another device to access the semaphore object. /// @returns An OS-specific handle which can be used by another device to access the semaphore object.
virtual OsExternalHandle ExportKmtHandle() const = 0; virtual OsExternalHandle ExportKmtHandle() const = 0;
#endif #endif
/// Returns the value of the associated arbitrary client data pointer. /// Returns the value of the associated arbitrary client data pointer.
/// Can be used to associate arbitrary data with a particular PAL object. /// Can be used to associate arbitrary data with a particular PAL object.
/// ///
/// @returns Pointer to client data. /// @returns Pointer to client data.
void* GetClientData() const void* GetClientData() const
{ {
return m_pClientData; return m_pClientData;
} }
/// Sets the value of the associated arbitrary client data pointer. /// Sets the value of the associated arbitrary client data pointer.
/// Can be used to associate arbitrary data with a particular PAL object. /// Can be used to associate arbitrary data with a particular PAL object.
/// ///
/// @param [in] pClientData A pointer to arbitrary client data. /// @param [in] pClientData A pointer to arbitrary client data.
void SetClientData( void SetClientData(
void* pClientData) void* pClientData)
{ {
m_pClientData = pClientData; m_pClientData = pClientData;
} }
protected: protected:
/// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly /// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly
/// called the proper create method. /// called the proper create method.
IQueueSemaphore() : m_pClientData(nullptr) {} IQueueSemaphore() : m_pClientData(nullptr) {}
/// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by /// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by
/// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the /// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the
/// object on their own. /// object on their own.
virtual ~IQueueSemaphore() { } virtual ~IQueueSemaphore() { }
private: private:
/// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData() /// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData()
/// and set via SetClientData(). /// and set via SetClientData().
/// For non-top-layer objects, this will point to the layer above the current object. /// For non-top-layer objects, this will point to the layer above the current object.
void* m_pClientData; void* m_pClientData;
}; };
} // Pal } // Pal
+253 -251
파일 보기
@@ -1,251 +1,253 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palShaderLibrary.h * @file palShaderLibrary.h
* @brief Defines the Platform Abstraction Library (PAL) IShaderLibrary interface and related types. * @brief Defines the Platform Abstraction Library (PAL) IShaderLibrary interface and related types.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "pal.h" #include "pal.h"
#include "palDestroyable.h" #include "palDestroyable.h"
#include "palStringView.h" #include "palStringView.h"
#include "palSpan.h" #include "palSpan.h"
namespace Pal namespace Pal
{ {
struct GpuMemSubAllocInfo; struct GpuMemSubAllocInfo;
/// Common flags controlling creation of shader libraries. /// Common flags controlling creation of shader libraries.
union LibraryCreateFlags union LibraryCreateFlags
{ {
struct struct
{ {
uint32 clientInternal : 1; ///< Internal library not created by the application. uint32 clientInternal : 1; ///< Internal library not created by the application.
uint32 isGraphics : 1; ///< Whether it is a graphics library uint32 isGraphics : 1; ///< Whether it is a graphics library
uint32 reserved : 30; ///< Reserved for future use. uint32 reserved : 30; ///< Reserved for future use.
}; };
uint32 u32All; ///< Flags packed as 32-bit uint. uint32 u32All; ///< Flags packed as 32-bit uint.
}; };
/// Specifies properties about an indirect function belonging to a @ref IShaderLibrary object. Part of the input /// Specifies properties about an indirect function belonging to a @ref IShaderLibrary object. Part of the input
/// structure to IDevice::CreateShaderLibrary(). /// structure to IDevice::CreateShaderLibrary().
struct ShaderLibraryFunctionInfo struct ShaderLibraryFunctionInfo
{ {
Util::StringView<char> symbolName; ///< ELF Symbol name for the associated function. Util::StringView<char> symbolName; ///< ELF Symbol name for the associated function.
gpusize gpuVirtAddr; ///< [out] GPU virtual address of the function. This is computed by PAL during gpusize gpuVirtAddr; ///< [out] GPU virtual address of the function. This is computed by PAL during
/// library creation. /// library creation.
}; };
/// Specifies a shader sub type / ShaderKind. /// Specifies a shader sub type / ShaderKind.
enum class ShaderSubType : uint32 enum class ShaderSubType : uint32
{ {
Unknown = 0, Unknown = 0,
Traversal, Traversal,
RayGeneration, RayGeneration,
Intersection, Intersection,
AnyHit, AnyHit,
ClosestHit, ClosestHit,
Miss, Miss,
Callable, Callable,
LaunchKernel, ///< Raytracing launch kernel LaunchKernel, ///< Raytracing launch kernel
Count Count
}; };
/// Specifies properties for creation of a compute @ref IShaderLibrary object. Input structure to /// Specifies properties for creation of a compute @ref IShaderLibrary object. Input structure to
/// IDevice::CreateShaderLibrary(). /// IDevice::CreateShaderLibrary().
struct ShaderLibraryCreateInfo struct ShaderLibraryCreateInfo
{ {
LibraryCreateFlags flags; ///< Library creation flags LibraryCreateFlags flags; ///< Library creation flags
const void* pCodeObject; ///< Pointer to code-object ELF binary implementing the Pipeline ABI interface. const void* pCodeObject; ///< Pointer to code-object ELF binary implementing the Pipeline ABI interface.
/// The code-object ELF contains pre-compiled shaders, register values, and /// The code-object ELF contains pre-compiled shaders, register values, and
/// additional metadata. /// additional metadata.
size_t codeObjectSize; ///< Size of code object in bytes. size_t codeObjectSize; ///< Size of code object in bytes.
}; };
/// Reports properties of a compiled library. /// Reports properties of a compiled library.
struct LibraryInfo struct LibraryInfo
{ {
PipelineHash internalLibraryHash; ///< 128-bit identifier extracted from this library's ELF binary, composed of PipelineHash internalLibraryHash; ///< 128-bit identifier extracted from this library's ELF binary, composed of
/// the state the compiler decided was appropriate to identify the compiled /// the state the compiler decided was appropriate to identify the compiled
/// library. The lower 64 bits are "stable"; the upper 64 bits are "unique". /// library. The lower 64 bits are "stable"; the upper 64 bits are "unique".
}; Util::StringView<char> colorExports; ///< For a Graphics Partial Pipeline pixel shader, an opaque
/// string to pass to the compiler to build the color export shader.
/// Reports shader stats. Multiple bits set in the shader stage mask indicates that multiple shaders have been combined };
/// due to HW support. The same information will be repeated for both the constituent shaders in this case.
struct ShaderLibStats /// Reports shader stats. Multiple bits set in the shader stage mask indicates that multiple shaders have been combined
{ /// due to HW support. The same information will be repeated for both the constituent shaders in this case.
ShaderHash shaderHash; ///< Shader hash. struct ShaderLibStats
CommonShaderStats common; ///< The shader compilation parameters for this shader. {
/// Maximum number of VGPRs the compiler was allowed to use for this shader. This limit will be the minimum ShaderHash shaderHash; ///< Shader hash.
/// of any architectural restriction and any client-requested limit intended to increase the number of waves in CommonShaderStats common; ///< The shader compilation parameters for this shader.
/// flight. /// Maximum number of VGPRs the compiler was allowed to use for this shader. This limit will be the minimum
uint32 numAvailableVgprs; /// of any architectural restriction and any client-requested limit intended to increase the number of waves in
/// Maximum number of SGPRs the compiler was allowed to use for this shader. This limit will be the minimum /// flight.
/// of any architectural restriction and any client-requested limit intended to increase the number of waves in uint32 numAvailableVgprs;
/// flight. /// Maximum number of SGPRs the compiler was allowed to use for this shader. This limit will be the minimum
uint32 numAvailableSgprs; /// of any architectural restriction and any client-requested limit intended to increase the number of waves in
size_t isaSizeInBytes; ///< Size of the shader ISA disassembly for this shader. /// flight.
PipelineHash palInternalLibraryHash; ///< Internal hash of the shader compilation data used by PAL. uint32 numAvailableSgprs;
uint32 stackFrameSizeInBytes; ///< Shader function stack frame size size_t isaSizeInBytes; ///< Size of the shader ISA disassembly for this shader.
ShaderSubType shaderSubType; ///< ShaderSubType / Shader Kind PipelineHash palInternalLibraryHash; ///< Internal hash of the shader compilation data used by PAL.
CompilerStackSizes cpsStackSizes; ///< Stack used in Continuation uint32 stackFrameSizeInBytes; ///< Shader function stack frame size
}; ShaderSubType shaderSubType; ///< ShaderSubType / Shader Kind
CompilerStackSizes cpsStackSizes; ///< Stack used in Continuation
/** };
***********************************************************************************************************************
* @interface IShaderLibrary /**
* @brief Object containing one or more shader functions stored in GPU memory. These shader functions are callable ***********************************************************************************************************************
* from the shaders contained within IPipeline objects. * @interface IShaderLibrary
* * @brief Object containing one or more shader functions stored in GPU memory. These shader functions are callable
* Before a pipeline which calls into this library is bound to a command buffer (using @ref ICmdBuffer::BindPipeline), * from the shaders contained within IPipeline objects.
* the client must call @ref IPipeline::LinkWithLibraries() and specify this library in the list of linked libraries. *
* Failure to comply with this requirement is an error and will result in undefined behavior. * Before a pipeline which calls into this library is bound to a command buffer (using @ref ICmdBuffer::BindPipeline),
* * the client must call @ref IPipeline::LinkWithLibraries() and specify this library in the list of linked libraries.
* @see IDevice::CreateShaderLibrary() * Failure to comply with this requirement is an error and will result in undefined behavior.
* @see IPipeline::LinkWithLibraries() *
*********************************************************************************************************************** * @see IDevice::CreateShaderLibrary()
*/ * @see IPipeline::LinkWithLibraries()
class IShaderLibrary : public IDestroyable ***********************************************************************************************************************
{ */
public: class IShaderLibrary : public IDestroyable
/// Returns properties of this library and its corresponding shader functions. {
/// public:
/// @returns Property structure describing this library. /// Returns properties of this library and its corresponding shader functions.
virtual const LibraryInfo& GetInfo() const = 0; ///
/// @returns Property structure describing this library.
/// Returns a list of GPU memory allocations used by this library. virtual const LibraryInfo& GetInfo() const = 0;
///
/// @param [in,out] pNumEntries Input value specifies the available size in pAllocInfoList; output value /// Returns a list of GPU memory allocations used by this library.
/// reports the number of GPU memory allocations. ///
/// @param [out] pAllocInfoList If pAllocInfoList=nullptr, then pNumEntries is ignored on input. On output it /// @param [in,out] pNumEntries Input value specifies the available size in pAllocInfoList; output value
/// will reflect the number of allocations that make up this pipeline. If /// reports the number of GPU memory allocations.
/// pAllocInfoList!=nullptr, then on input pNumEntries is assumed to be the number /// @param [out] pAllocInfoList If pAllocInfoList=nullptr, then pNumEntries is ignored on input. On output it
/// of entries in the pAllocInfoList array. On output, pNumEntries reflects the /// will reflect the number of allocations that make up this pipeline. If
/// number of entries in pAllocInfoList that are valid. /// pAllocInfoList!=nullptr, then on input pNumEntries is assumed to be the number
/// @returns Success if the allocation info was successfully written to the buffer. /// of entries in the pAllocInfoList array. On output, pNumEntries reflects the
/// + ErrorInvalidValue if the caller provides a buffer size that is different from the size needed. /// number of entries in pAllocInfoList that are valid.
/// + ErrorInvalidPointer if pNumEntries is nullptr. /// @returns Success if the allocation info was successfully written to the buffer.
virtual Result QueryAllocationInfo( /// + ErrorInvalidValue if the caller provides a buffer size that is different from the size needed.
size_t* pNumEntries, /// + ErrorInvalidPointer if pNumEntries is nullptr.
GpuMemSubAllocInfo* const pAllocInfoList) const = 0; virtual Result QueryAllocationInfo(
size_t* pNumEntries,
/// Gives the client access to the resource ID used for internal Pal events. GpuMemSubAllocInfo* const pAllocInfoList) const = 0;
/// EX: Resource Create, Resource Bind, Resource Destroy.
/// /// Gives the client access to the resource ID used for internal Pal events.
/// @returns The Resource ID. /// EX: Resource Create, Resource Bind, Resource Destroy.
virtual const void* GetResourceId() const = 0; ///
/// @returns The Resource ID.
/// Obtains the binary code object for this library. virtual const void* GetResourceId() const = 0;
///
/// @param [in, out] pSize Represents the size of the shader ISA code. /// Obtains the binary code object for this library.
/// ///
/// @param [out] pBuffer If non-null, the library ELF is written in the buffer. If null, the size required /// @param [in, out] pSize Represents the size of the shader ISA code.
/// for the library ELF is given out in the location pSize. ///
/// /// @param [out] pBuffer If non-null, the library ELF is written in the buffer. If null, the size required
/// @returns Success if the library binary was fetched successfully. /// for the library ELF is given out in the location pSize.
/// +ErrorUnavailable if the library binary was not fetched successfully. ///
virtual Result GetCodeObject( /// @returns Success if the library binary was fetched successfully.
uint32* pSize, /// +ErrorUnavailable if the library binary was not fetched successfully.
void* pBuffer) const = 0; virtual Result GetCodeObject(
uint32* pSize,
/// Returns the value of the associated arbitrary client data pointer. void* pBuffer) const = 0;
/// Can be used to associate arbitrary data with a particular PAL object.
/// /// Returns the value of the associated arbitrary client data pointer.
/// @returns Pointer to client data. /// Can be used to associate arbitrary data with a particular PAL object.
void* GetClientData() const { return m_pClientData; } ///
/// @returns Pointer to client data.
/// Sets the value of the associated arbitrary client data pointer. void* GetClientData() const { return m_pClientData; }
/// Can be used to associate arbitrary data with a particular PAL object.
/// /// Sets the value of the associated arbitrary client data pointer.
/// @param [in] pClientData A pointer to arbitrary client data. /// Can be used to associate arbitrary data with a particular PAL object.
void SetClientData( ///
void* pClientData) /// @param [in] pClientData A pointer to arbitrary client data.
{ void SetClientData(
m_pClientData = pClientData; void* pClientData)
} {
m_pClientData = pClientData;
/// Obtains the compiled shader ISA code for the shader function specified. }
///
/// @param [in] pShaderExportName The shader exported name /// Obtains the compiled shader ISA code for the shader function specified.
/// ///
/// @param [in, out] pSize Represents the size of the shader ISA code. /// @param [in] pShaderExportName The shader exported name
/// ///
/// @param [out] pBuffer If non-null, the shader ISA code is written in the buffer. If null, the size required /// @param [in, out] pSize Represents the size of the shader ISA code.
/// for the shader ISA is given out in the location pSize. ///
/// /// @param [out] pBuffer If non-null, the shader ISA code is written in the buffer. If null, the size required
/// @returns Success if the shader ISA code was fetched successfully. /// for the shader ISA is given out in the location pSize.
/// +ErrorUnavailable if the shader ISA code was not fetched successfully. ///
/// @returns Success if the shader ISA code was fetched successfully.
virtual Result GetShaderFunctionCode( /// +ErrorUnavailable if the shader ISA code was not fetched successfully.
Util::StringView<char> shaderExportName,
size_t* pSize, virtual Result GetShaderFunctionCode(
void* pBuffer) const = 0; Util::StringView<char> shaderExportName,
size_t* pSize,
/// Obtains the shader pre and post compilation stats/params for the specified shader. void* pBuffer) const = 0;
///
/// @param [in] pShaderExportName The shader exported name /// Obtains the shader pre and post compilation stats/params for the specified shader.
/// ///
/// @param [out] pShaderStats Pointer to the ShaderStats structure which will be filled with the shader stats for /// @param [in] pShaderExportName The shader exported name
/// the shader stage mentioned in shaderType. This cannot be nullptr. ///
/// @param [in] getDisassemblySize If set to true performs disassembly on the shader binary code and reports the /// @param [out] pShaderStats Pointer to the ShaderStats structure which will be filled with the shader stats for
/// size of the disassembly string in ShaderStats::isaSizeInBytes. Else reports 0. /// the shader stage mentioned in shaderType. This cannot be nullptr.
/// @returns Success if the stats were successfully obtained for this shader, including the shader disassembly size. /// @param [in] getDisassemblySize If set to true performs disassembly on the shader binary code and reports the
/// +ErrorUnavailable if a wrong shader stage for this pipeline was specified, or if some internal error /// size of the disassembly string in ShaderStats::isaSizeInBytes. Else reports 0.
/// occured. /// @returns Success if the stats were successfully obtained for this shader, including the shader disassembly size.
virtual Result GetShaderFunctionStats( /// +ErrorUnavailable if a wrong shader stage for this pipeline was specified, or if some internal error
Util::StringView<char> shaderExportName, /// occured.
ShaderLibStats* pShaderStats) const = 0; virtual Result GetShaderFunctionStats(
Util::StringView<char> shaderExportName,
/// Returns the function list owned by this shader library ShaderLibStats* pShaderStats) const = 0;
///
/// @returns A list of ShaderLibraryFunctionInfo. /// Returns the function list owned by this shader library
virtual const Util::Span<const ShaderLibraryFunctionInfo> GetShaderLibFunctionInfos() const = 0; ///
/// @returns A list of ShaderLibraryFunctionInfo.
protected: virtual const Util::Span<const ShaderLibraryFunctionInfo> GetShaderLibFunctionInfos() const = 0;
/// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly
/// called the proper create method. protected:
IShaderLibrary() : m_pClientData(nullptr) { } /// @internal Constructor. Prevent use of new operator on this interface. Client must create objects by explicitly
/// called the proper create method.
/// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by IShaderLibrary() : m_pClientData(nullptr) { }
/// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the
/// object on their own. /// @internal Destructor. Prevent use of delete operator on this interface. Client must destroy objects by
virtual ~IShaderLibrary() { } /// explicitly calling IDestroyable::Destroy() and is responsible for freeing the system memory allocated for the
/// object on their own.
private: virtual ~IShaderLibrary() { }
/// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData()
/// and set via SetClientData(). private:
/// For non-top-layer objects, this will point to the layer above the current object. /// @internal Client data pointer. This can have an arbitrary value and can be returned by calling GetClientData()
void* m_pClientData; /// and set via SetClientData().
/// For non-top-layer objects, this will point to the layer above the current object.
IShaderLibrary(const IShaderLibrary&) = delete; void* m_pClientData;
IShaderLibrary& operator=(const IShaderLibrary&) = delete;
}; IShaderLibrary(const IShaderLibrary&) = delete;
IShaderLibrary& operator=(const IShaderLibrary&) = delete;
} // Pal };
} // Pal
+214 -212
파일 보기
@@ -1,212 +1,214 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2023-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2023-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
#pragma once #pragma once
#include "palGpaSession.h" #include "palGpaSession.h"
#include "palGpuUtil.h" #include "palGpuUtil.h"
#include "palTraceSession.h" #include "palTraceSession.h"
#include "palVector.h" #include "palVector.h"
#include "palHashSet.h" #include "palHashSet.h"
#include "palMutex.h" #include "palMutex.h"
namespace Pal namespace Pal
{ {
class IPlatform; class IPlatform;
class IDevice; class IDevice;
class IShaderLibrary; class IShaderLibrary;
} // namespace Pal } // namespace Pal
namespace GpuUtil namespace GpuUtil
{ {
class GpaSession; class GpaSession;
} // namespace GpuUtil } // namespace GpuUtil
namespace GpuUtil namespace GpuUtil
{ {
namespace TraceChunk namespace TraceChunk
{ {
/// "CodeObject" RDF chunk identifier & version /// "CodeObject" RDF chunk identifier & version
constexpr char CodeObjectChunkId[TextIdentifierSize] = "CodeObject"; constexpr char CodeObjectChunkId[TextIdentifierSize] = "CodeObject";
constexpr Pal::uint32 CodeObjectChunkVersion = 2; constexpr Pal::uint32 CodeObjectChunkVersion = 2;
/// Header for the "CodeObject" RDF chunk /// Header for the "CodeObject" RDF chunk
struct CodeObjectHeader struct CodeObjectHeader
{ {
Pal::uint32 pciId; /// The ID of the GPU the trace was run on Pal::uint32 pciId; /// The ID of the GPU the trace was run on
Pal::ShaderHash codeObjectHash; /// Hash of the Code Object binary Pal::ShaderHash codeObjectHash; /// Hash of the Code Object binary
}; };
/// "COLoadEvent" RDF chunk identifier & version /// "COLoadEvent" RDF chunk identifier & version
constexpr char CodeObjectLoadEventChunkId[TextIdentifierSize] = "COLoadEvent"; constexpr char CodeObjectLoadEventChunkId[TextIdentifierSize] = "COLoadEvent";
constexpr Pal::uint32 CodeObjectLoadEventChunkVersion = 3; constexpr Pal::uint32 CodeObjectLoadEventChunkVersion = 3;
struct CodeObjectLoadEventHeader struct CodeObjectLoadEventHeader
{ {
Pal::uint32 count; /// Number of load events in this chunk Pal::uint32 count; /// Number of load events in this chunk
}; };
/// Describes whether a load event was into GPU memory or from. /// Describes whether a load event was into GPU memory or from.
enum class CodeObjectLoadEventType : Pal::uint32 enum class CodeObjectLoadEventType : Pal::uint32
{ {
LoadToGpuMemory = 0, /// Code Object was loaded into GPU memory LoadToGpuMemory = 0, /// Code Object was loaded into GPU memory
UnloadFromGpuMemory = 1 /// Code Object was unloaded from GPU memory UnloadFromGpuMemory = 1 /// Code Object was unloaded from GPU memory
}; };
/// Describes one or more GPU load/unload(s) of a Code Object. Payload for "COLoadEvent" RDF chunk. /// Describes one or more GPU load/unload(s) of a Code Object. Payload for "COLoadEvent" RDF chunk.
struct CodeObjectLoadEvent struct CodeObjectLoadEvent
{ {
Pal::uint32 pciId; /// The ID of the GPU the trace was run on Pal::uint32 pciId; /// The ID of the GPU the trace was run on
CodeObjectLoadEventType eventType; /// Type of loader event CodeObjectLoadEventType eventType; /// Type of loader event
Pal::uint64 baseAddress; /// Base address where the Code Object was loaded Pal::uint64 baseAddress; /// Base address where the Code Object was loaded
Pal::ShaderHash codeObjectHash; /// Hash of the (un)loaded Code Object binary Pal::ShaderHash codeObjectHash; /// Hash of the (un)loaded Code Object binary
Pal::uint64 timestamp; /// CPU timestamp of this event being triggered Pal::uint64 timestamp; /// CPU timestamp of this event being triggered
}; };
/// "PsoCorrelation" RDF chunk identifier & version /// "PsoCorrelation" RDF chunk identifier & version
constexpr char PsoCorrelationChunkId[TextIdentifierSize] = "PsoCorrelation"; constexpr char PsoCorrelationChunkId[TextIdentifierSize] = "PsoCorrelation";
constexpr Pal::uint32 PsoCorrelationChunkVersion = 3; constexpr Pal::uint32 PsoCorrelationChunkVersion = 3;
struct PsoCorrelationHeader struct PsoCorrelationHeader
{ {
Pal::uint32 count; /// Number of PSO correlations in this chunk Pal::uint32 count; /// Number of PSO correlations in this chunk
}; };
/// Payload for the "PsoCorrelation" RDF chunks /// Payload for the "PsoCorrelation" RDF chunks
struct PsoCorrelation struct PsoCorrelation
{ {
Pal::uint32 pciId; /// The ID of the GPU the trace was run on Pal::uint32 pciId; /// The ID of the GPU the trace was run on
Pal::uint64 apiPsoHash; /// Hash of the API-level Pipeline State Object Pal::uint64 apiPsoHash; /// Hash of the API-level Pipeline State Object
Pal::PipelineHash internalPipelineHash; /// Hash of all inputs to the pipeline compiler Pal::PipelineHash internalPipelineHash; /// Hash of all inputs to the pipeline compiler
char apiLevelObjectName[64]; /// Debug object name (null-terminated) char apiLevelObjectName[64]; /// Debug object name (null-terminated)
}; };
/// "COCorrelation" RDF chunk identifier & version /// "COCorrelation" RDF chunk identifier & version
constexpr char CodeObjectCorrelationChunkId[TextIdentifierSize] = "COCorrelation"; constexpr char CodeObjectCorrelationChunkId[TextIdentifierSize] = "COCorrelation";
constexpr uint32_t CodeObjectCorrelationChunkVersion = 4; constexpr uint32_t CodeObjectCorrelationChunkVersion = 4;
struct CodeObjectCorrelationHeader struct CodeObjectCorrelationHeader
{ {
Pal::uint32 count; /// Number of Code Object Correlations in this chunk Pal::uint32 count; /// Number of Code Object Correlations in this chunk
}; };
/// Payload for the "CodeObjectCorrelation" RDF chunks /// Payload for the "CodeObjectCorrelation" RDF chunks
struct CodeObjectCorrelation struct CodeObjectCorrelation
{ {
Pal::PipelineHash internalPipelineHash; /// Hash of all inputs to the pipeline compiler Pal::PipelineHash internalPipelineHash; /// Hash of all inputs to the pipeline compiler
Pal::ShaderHash codeObjectHash; /// Hash of the Code Object binary in the CO Database Pal::ShaderHash codeObjectHash; /// Hash of the Code Object binary in the CO Database
Pal::uint32 containsMetadata : 1; /// 1 if the code object contains metadata, 0 otherwise Pal::uint32 containsMetadata : 1; /// 1 if the code object contains metadata, 0 otherwise
Pal::uint32 reserved : 31; /// Bitflags reserved for future use Pal::uint32 reserved : 31; /// Bitflags reserved for future use
}; };
} // namespace TraceChunk } // namespace TraceChunk
/// CodeObject Trace Source name & version /// CodeObject Trace Source name & version
constexpr char CodeObjectTraceSourceName[] = "codeobject"; constexpr char CodeObjectTraceSourceName[] = "codeobject";
constexpr Pal::uint32 CodeObjectTraceSourceVersion = 3; constexpr Pal::uint32 CodeObjectTraceSourceVersion = 3;
// ===================================================================================================================== // =====================================================================================================================
class CodeObjectTraceSource : public ITraceSource class CodeObjectTraceSource : public ITraceSource
{ {
public: public:
CodeObjectTraceSource(Pal::IPlatform* pPlatform); CodeObjectTraceSource(Pal::IPlatform* pPlatform);
~CodeObjectTraceSource(); ~CodeObjectTraceSource();
// ==== TraceSource Native Functions ========================================================================== // // ==== TraceSource Native Functions ========================================================================== //
Pal::Result RegisterPipeline(const Pal::IPipeline* pPipeline, const RegisterPipelineInfo& clientInfo); Pal::Result RegisterPipeline(const Pal::IPipeline* pPipeline, const RegisterPipelineInfo& clientInfo);
Pal::Result UnregisterPipeline(const Pal::IPipeline* pPipeline); Pal::Result UnregisterPipeline(const Pal::IPipeline* pPipeline);
Pal::Result RegisterLibrary(const Pal::IShaderLibrary* pLibrary, const RegisterLibraryInfo& clientInfo); Pal::Result RegisterLibrary(const Pal::IShaderLibrary* pLibrary, const RegisterLibraryInfo& clientInfo);
Pal::Result UnregisterLibrary(const Pal::IShaderLibrary* pLibrary); Pal::Result UnregisterLibrary(const Pal::IShaderLibrary* pLibrary);
Pal::Result RegisterElfBinary(const ElfBinaryInfo& elfBinaryInfo); Pal::Result RegisterElfBinary(const ElfBinaryInfo& elfBinaryInfo);
Pal::Result UnregisterElfBinary(const ElfBinaryInfo& elfBinaryInfo); Pal::Result UnregisterElfBinary(const ElfBinaryInfo& elfBinaryInfo);
// ==== Base Class Overrides =================================================================================== // // ==== Base Class Overrides =================================================================================== //
virtual void OnConfigUpdated(DevDriver::StructuredValue* pJsonConfig) override { } #if PAL_CLIENT_INTERFACE_MAJOR_VERSION < COMPRESSION_ARG_VERSION
virtual void OnConfigUpdated(DevDriver::StructuredValue* pJsonConfig) override { }
virtual Pal::uint64 QueryGpuWorkMask() const override { return 0; } #endif
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 908 virtual Pal::uint64 QueryGpuWorkMask() const override { return 0; }
virtual void OnTraceAccepted(Pal::uint32 gpuIndex, Pal::ICmdBuffer* pCmdBuf) override { }
#else #if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 908
virtual void OnTraceAccepted() override { } virtual void OnTraceAccepted(Pal::uint32 gpuIndex, Pal::ICmdBuffer* pCmdBuf) override { }
#endif #else
virtual void OnTraceBegin(Pal::uint32 gpuIndex, Pal::ICmdBuffer* pCmdBuf) override { } virtual void OnTraceAccepted() override { }
virtual void OnTraceEnd(Pal::uint32 gpuIndex, Pal::ICmdBuffer* pCmdBuf) override { } #endif
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 939 virtual void OnTraceBegin(Pal::uint32 gpuIndex, Pal::ICmdBuffer* pCmdBuf) override { }
virtual void OnPostambleEnd( virtual void OnTraceEnd(Pal::uint32 gpuIndex, Pal::ICmdBuffer* pCmdBuf) override { }
Pal::uint32 gpuIndex, #if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 939
Pal::ICmdBuffer* pCmdBuf) override { } virtual void OnPostambleEnd(
#endif Pal::uint32 gpuIndex,
virtual void OnTraceFinished() override; Pal::ICmdBuffer* pCmdBuf) override { }
#endif
virtual const char* GetName() const override { return CodeObjectTraceSourceName; } virtual void OnTraceFinished() override;
virtual Pal::uint32 GetVersion() const override { return CodeObjectTraceSourceVersion; }
virtual const char* GetName() const override { return CodeObjectTraceSourceName; }
private: virtual Pal::uint32 GetVersion() const override { return CodeObjectTraceSourceVersion; }
Pal::Result RegisterSinglePipeline(const Pal::IPipeline* pPipeline, const RegisterPipelineInfo& clientInfo);
Pal::Result UnregisterSinglePipeline(const Pal::IPipeline* pPipeline); private:
Pal::Result RegisterSinglePipeline(const Pal::IPipeline* pPipeline, const RegisterPipelineInfo& clientInfo);
Pal::Result AddCodeObjectLoadEvent( Pal::Result UnregisterSinglePipeline(const Pal::IPipeline* pPipeline);
const Pal::IShaderLibrary* pLibrary,
TraceChunk::CodeObjectLoadEventType eventType); Pal::Result AddCodeObjectLoadEvent(
Pal::Result AddCodeObjectLoadEvent( const Pal::IShaderLibrary* pLibrary,
const Pal::IPipeline* pLibrary, TraceChunk::CodeObjectLoadEventType eventType);
TraceChunk::CodeObjectLoadEventType eventType); Pal::Result AddCodeObjectLoadEvent(
Pal::Result AddCodeObjectLoadEvent( const Pal::IPipeline* pLibrary,
const ElfBinaryInfo& elfBinaryInfo, TraceChunk::CodeObjectLoadEventType eventType);
TraceChunk::CodeObjectLoadEventType eventType); Pal::Result AddCodeObjectLoadEvent(
const ElfBinaryInfo& elfBinaryInfo,
Pal::Result WriteCodeObjectChunks(); TraceChunk::CodeObjectLoadEventType eventType);
Pal::Result WriteLoaderEventsChunk();
Pal::Result WritePsoCorrelationChunk(); Pal::Result WriteCodeObjectChunks();
Pal::Result WriteCoCorrelationChunk(); Pal::Result WriteLoaderEventsChunk();
Pal::Result WritePsoCorrelationChunk();
struct CodeObjectDatabaseRecord Pal::Result WriteCoCorrelationChunk();
{
Pal::uint32 recordSize; struct CodeObjectDatabaseRecord
Pal::ShaderHash codeObjectHash; {
}; Pal::uint32 recordSize;
Pal::ShaderHash codeObjectHash;
Pal::IPlatform* const m_pPlatform; };
Util::RWLock m_registerPipelineLock; Pal::IPlatform* const m_pPlatform;
Util::Vector<CodeObjectDatabaseRecord*, 1, Pal::IPlatform> m_codeObjectRecords;
Util::Vector<TraceChunk::CodeObjectLoadEvent, 1, Pal::IPlatform> m_loadEventRecords; Util::RWLock m_registerPipelineLock;
Util::Vector<TraceChunk::PsoCorrelation, 1, Pal::IPlatform> m_psoCorrelationRecords; Util::Vector<CodeObjectDatabaseRecord*, 1, Pal::IPlatform> m_codeObjectRecords;
Util::Vector<TraceChunk::CodeObjectCorrelation, 1, Pal::IPlatform> m_coCorrelationRecords; Util::Vector<TraceChunk::CodeObjectLoadEvent, 1, Pal::IPlatform> m_loadEventRecords;
Util::Vector<TraceChunk::PsoCorrelation, 1, Pal::IPlatform> m_psoCorrelationRecords;
// API hashes -> internal pipeline hash (-> child code object hashes) Util::Vector<TraceChunk::CodeObjectCorrelation, 1, Pal::IPlatform> m_coCorrelationRecords;
Util::HashSet<Pal::uint64, Pal::IPlatform, Util::JenkinsHashFunc> m_registeredApiHashes;
Util::HashSet<Pal::uint64, Pal::IPlatform, Util::JenkinsHashFunc> m_registeredPipelines; // API hashes -> internal pipeline hash (-> child code object hashes)
Util::HashSet<Pal::uint64, Pal::IPlatform, Util::JenkinsHashFunc> m_registeredCoHashes; Util::HashSet<Pal::uint64, Pal::IPlatform, Util::JenkinsHashFunc> m_registeredApiHashes;
Util::HashSet<Pal::uint64, Pal::IPlatform, Util::JenkinsHashFunc> m_registeredPipelines;
}; Util::HashSet<Pal::uint64, Pal::IPlatform, Util::JenkinsHashFunc> m_registeredCoHashes;
} // namespace GpuUtil };
} // namespace GpuUtil
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+141 -141
파일 보기
@@ -1,141 +1,141 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palGpuUtil.h * @file palGpuUtil.h
* @brief Common include for the PAL GPU utility collection. Defines common types, macros, enums, etc. * @brief Common include for the PAL GPU utility collection. Defines common types, macros, enums, etc.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "pal.h" #include "pal.h"
// Forward declarations. // Forward declarations.
namespace Pal namespace Pal
{ {
struct DeviceProperties; struct DeviceProperties;
class IImage; class IImage;
class IGpuMemory; class IGpuMemory;
struct ImageCopyRegion; struct ImageCopyRegion;
struct TypedBufferCopyRegion; struct TypedBufferCopyRegion;
struct MemoryImageCopyRegion; struct MemoryImageCopyRegion;
} }
/// Library-wide namespace encapsulating all PAL GPU utility entities. /// Library-wide namespace encapsulating all PAL GPU utility entities.
namespace GpuUtil namespace GpuUtil
{ {
/// Validate image copy region. /// Validate image copy region.
/// ///
/// @param [in] properties The device properties. /// @param [in] properties The device properties.
/// @param [in] engineType Engine to validate. /// @param [in] engineType Engine to validate.
/// @param [in] src Src image. /// @param [in] src Src image.
/// @param [in] dst Des image. /// @param [in] dst Des image.
/// @param [in] region Copy region. /// @param [in] region Copy region.
/// ///
/// @returns true if the image copy is supported by the specific engine, otherwise false. /// @returns true if the image copy is supported by the specific engine, otherwise false.
extern bool ValidateImageCopyRegion( extern bool ValidateImageCopyRegion(
const Pal::DeviceProperties& properties, const Pal::DeviceProperties& properties,
Pal::EngineType engineType, Pal::EngineType engineType,
const Pal::IImage& src, const Pal::IImage& src,
const Pal::IImage& dst, const Pal::IImage& dst,
const Pal::ImageCopyRegion& region); const Pal::ImageCopyRegion& region);
/// Validate typed buffer copy region. /// Validate typed buffer copy region.
/// ///
/// @param [in] properties The device properties. /// @param [in] properties The device properties.
/// @param [in] engineType Engine to validate. /// @param [in] engineType Engine to validate.
/// @param [in] region Copy region. /// @param [in] region Copy region.
/// ///
/// @returns true if the typed buffer copy is supported by the specific engine, otherwise false. /// @returns true if the typed buffer copy is supported by the specific engine, otherwise false.
extern bool ValidateTypedBufferCopyRegion( extern bool ValidateTypedBufferCopyRegion(
const Pal::DeviceProperties& properties, const Pal::DeviceProperties& properties,
Pal::EngineType engineType, Pal::EngineType engineType,
const Pal::TypedBufferCopyRegion& region); const Pal::TypedBufferCopyRegion& region);
/// Validate image-memory copy region. /// Validate image-memory copy region.
/// ///
/// @param [in] properties The device properties. /// @param [in] properties The device properties.
/// @param [in] engineType Engine to validate. /// @param [in] engineType Engine to validate.
/// @param [in] image The IImage object. /// @param [in] image The IImage object.
/// @param [in] region Copy region. /// @param [in] region Copy region.
/// ///
/// @returns true if the image-memory copy is supported by the specific engine, otherwise false. /// @returns true if the image-memory copy is supported by the specific engine, otherwise false.
extern bool ValidateMemoryImageRegion( extern bool ValidateMemoryImageRegion(
const Pal::DeviceProperties& properties, const Pal::DeviceProperties& properties,
Pal::EngineType engineType, Pal::EngineType engineType,
const Pal::IImage& image, const Pal::IImage& image,
const Pal::IGpuMemory& memory, const Pal::IGpuMemory& memory,
const Pal::MemoryImageCopyRegion& region); const Pal::MemoryImageCopyRegion& region);
/// Generate a 64-bit uniqueId for a GPU memory allocation /// Generate a 64-bit uniqueId for a GPU memory allocation
/// ///
/// @param [in] isInterprocess Indicates this uniqueId is for an externally shareable GPU memory allocation /// @param [in] isInterprocess Indicates this uniqueId is for an externally shareable GPU memory allocation
/// ///
/// @returns 64-bit uniqueId /// @returns 64-bit uniqueId
extern Pal::uint64 GenerateGpuMemoryUniqueId( extern Pal::uint64 GenerateGpuMemoryUniqueId(
bool isInterprocess); bool isInterprocess);
} // GpuUtil } // GpuUtil
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @page GpuUtilOverview GPU Utility Collection * @page GpuUtilOverview GPU Utility Collection
* *
* In addition to the generic, OS-abstracted software utilities, PAL provides GPU-specific utilities in the @ref GpuUtil * In addition to the generic, OS-abstracted software utilities, PAL provides GPU-specific utilities in the @ref GpuUtil
* namespace. The PAL GPU Utility Collection relies on both PAL core and PAL Utility. They are also available for use by * namespace. The PAL GPU Utility Collection relies on both PAL core and PAL Utility. They are also available for use by
* its clients. * its clients.
* *
* All available PAL GPU utilities are defined in the @ref GpuUtil namespace, and are briefly summarized below. See the * All available PAL GPU utilities are defined in the @ref GpuUtil namespace, and are briefly summarized below. See the
* Reference topics for more detailed information on specific classes, enums, etc. * Reference topics for more detailed information on specific classes, enums, etc.
* *
* ### TextWriter * ### TextWriter
* The TextWriter GPU utility class provides a method for clients to write text directly to an image. This can be used * The TextWriter GPU utility class provides a method for clients to write text directly to an image. This can be used
* for debugging purposes. PAL's internal DbgOverlay uses the TextWriter class to write information about the current * for debugging purposes. PAL's internal DbgOverlay uses the TextWriter class to write information about the current
* FPS and total allocated GPU video memory usage. * FPS and total allocated GPU video memory usage.
* *
* The TextWriter class is broken up into palTextWriter.h and palTextWriterImpl.h. The intention is that palTextWriter.h * The TextWriter class is broken up into palTextWriter.h and palTextWriterImpl.h. The intention is that palTextWriter.h
* will be included from other header files that need a full TextWriter definition, while palTextWriterImpl.h will be * will be included from other header files that need a full TextWriter definition, while palTextWriterImpl.h will be
* included by .cpp files that actually interact with the TextWriter. This should keep build times down versus putting * included by .cpp files that actually interact with the TextWriter. This should keep build times down versus putting
* all implementations directly in palTextWriter.h. * all implementations directly in palTextWriter.h.
* *
* Also included in the TextWriter is the TextWriterFont namespace, which defines the shader IL for drawing the text via * Also included in the TextWriter is the TextWriterFont namespace, which defines the shader IL for drawing the text via
* a compute shader. It also defines the Font data, which is a packed binary that represents which pixels of a 10x16 * a compute shader. It also defines the Font data, which is a packed binary that represents which pixels of a 10x16
* rectangle to render. The font is monospaced. * rectangle to render. The font is monospaced.
* *
* ### Helper Functions * ### Helper Functions
* ValidateImageCopyRegion - Validate the image copy region, returns true if the image copy is supported by the specific * ValidateImageCopyRegion - Validate the image copy region, returns true if the image copy is supported by the specific
* engine, otherwise false. * engine, otherwise false.
* *
* ValidateTypedBufferCopyRegion - Validate the typed buffer copy region, returns true if the typed buffer copy is * ValidateTypedBufferCopyRegion - Validate the typed buffer copy region, returns true if the typed buffer copy is
* supported by the specific engine, otherwise false. * supported by the specific engine, otherwise false.
* *
* ValidateMemoryImageRegion - Validate the image-memory copy region, returns true if the image-memory copy is supported * ValidateMemoryImageRegion - Validate the image-memory copy region, returns true if the image-memory copy is supported
* by the specific engine, otherwise false. * by the specific engine, otherwise false.
* *
* Next: @ref Overview * Next: @ref Overview
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
+238 -236
파일 보기
@@ -1,236 +1,238 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2024-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2024-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
#pragma once #pragma once
#include "palGpuUtil.h" #include "palGpuUtil.h"
#include "palTraceSession.h" #include "palTraceSession.h"
#include "palGpaSession.h" #include "palGpaSession.h"
#include <atomic> #include <atomic>
struct SqttQueueEventRecord; struct SqttQueueEventRecord;
struct SqttQueueInfoRecord; struct SqttQueueInfoRecord;
namespace Pal namespace Pal
{ {
class Platform; class Platform;
} }
namespace GpuUtil namespace GpuUtil
{ {
namespace TraceChunk namespace TraceChunk
{ {
/// "QueueInfo" RDF chunk identifier & version /// "QueueInfo" RDF chunk identifier & version
constexpr char QueueInfoChunkId[TextIdentifierSize] = "QueueInfo"; constexpr char QueueInfoChunkId[TextIdentifierSize] = "QueueInfo";
constexpr Pal::uint32 QueueInfoChunkVersion = 1; constexpr Pal::uint32 QueueInfoChunkVersion = 1;
/// Enum describing logical queue types /// Enum describing logical queue types
enum class QueueType : Pal::uint8 enum class QueueType : Pal::uint8
{ {
Unknown = 0, Unknown = 0,
Universal = 1, Universal = 1,
Compute = 2, Compute = 2,
Dma = 3, Dma = 3,
Encode = 4, Encode = 4,
Decode = 5, Decode = 5,
Security = 6, Security = 6,
VideoProcessor = 7 VideoProcessor = 7
}; };
/// Enum describing hardware engine types /// Enum describing hardware engine types
enum class HwEngineType : Pal::uint8 enum class HwEngineType : Pal::uint8
{ {
Unknown = 0, Unknown = 0,
Universal = 1, Universal = 1,
Compute = 2, Compute = 2,
ExclusiveCompute = 3, ExclusiveCompute = 3,
Dma = 4, Dma = 4,
Decode = 5, Decode = 5,
Encode = 6, Encode = 6,
HighPriorityUniversal = 7, HighPriorityUniversal = 7,
HighPriorityGraphics = 8, HighPriorityGraphics = 8,
Security = 9, Security = 9,
Vpe = 10 Vpe = 10
}; };
/// Structure describing a queue's properties /// Structure describing a queue's properties
struct QueueInfo struct QueueInfo
{ {
Pal::uint32 pciId; ///< The ID of the GPU queried Pal::uint32 pciId; ///< The ID of the GPU queried
Pal::uint64 queueId; ///< API-specific queue ID Pal::uint64 queueId; ///< API-specific queue ID
Pal::uint64 queueContext; ///< OS-level queue context value from Windows KMD to correlate with ETW data. Pal::uint64 queueContext; ///< OS-level queue context value from Windows KMD to correlate with ETW data.
/// Only applicable to D3D on Windows; 0 otherwise. /// Only applicable to D3D on Windows; 0 otherwise.
QueueType queueType; ///< The logical queue type QueueType queueType; ///< The logical queue type
HwEngineType engineType; ///< The hardware engine that the queue is mapped to HwEngineType engineType; ///< The hardware engine that the queue is mapped to
}; };
// ------------------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------------------- //
/// "QueueEvent" RDF chunk identifier & version /// "QueueEvent" RDF chunk identifier & version
constexpr char QueueEventChunkId[TextIdentifierSize] = "QueueEvent"; constexpr char QueueEventChunkId[TextIdentifierSize] = "QueueEvent";
constexpr Pal::uint32 QueueEventChunkVersion = 1; constexpr Pal::uint32 QueueEventChunkVersion = 1;
/// The type of queue-level timings event /// The type of queue-level timings event
enum class QueueEventType : Pal::uint32 enum class QueueEventType : Pal::uint32
{ {
CmdBufSubmit = 0, CmdBufSubmit = 0,
SignalSemaphore = 1, SignalSemaphore = 1,
WaitSemaphore = 2, WaitSemaphore = 2,
Present = 3 Present = 3
}; };
/// Structure describing a queue-level timings event /// Structure describing a queue-level timings event
struct QueueEvent struct QueueEvent
{ {
Pal::uint32 pciId; ///< The ID of the GPU queried Pal::uint32 pciId; ///< The ID of the GPU queried
Pal::uint64 queueId; ///< The API-specific queue ID which triggered the event Pal::uint64 queueId; ///< The API-specific queue ID which triggered the event
QueueEventType eventType; ///< The type of the queue-timing event QueueEventType eventType; ///< The type of the queue-timing event
Pal::uint32 sqttCmdBufId; ///< [`CmdBufSubmit` only; 0 otherwise] Pal::uint32 sqttCmdBufId; ///< [`CmdBufSubmit` only; 0 otherwise]
/// SQTT command buffer ID matching CmdBufStart user data marker /// SQTT command buffer ID matching CmdBufStart user data marker
Pal::uint64 frameIndex; ///< [`CmdBufSubmit` & `Present` only; 0 otherwise] Pal::uint64 frameIndex; ///< [`CmdBufSubmit` & `Present` only; 0 otherwise]
/// Global frame index incremented for each "Present" call /// Global frame index incremented for each "Present" call
Pal::uint32 submitSubIndex; ///< [`CmdBufSubmit` only; 0 otherwise] Pal::uint32 submitSubIndex; ///< [`CmdBufSubmit` only; 0 otherwise]
/// Sub-index of event within submission. /// Sub-index of event within submission.
/// When there is only one CmdBuffer per submission, `submitSubIndex` is 0. /// When there is only one CmdBuffer per submission, `submitSubIndex` is 0.
/// When there are multiple command buffers per submission, `submitSubIndex` /// When there are multiple command buffers per submission, `submitSubIndex`
/// is incremented by one for each command buffer within the submission. /// is incremented by one for each command buffer within the submission.
Pal::uint64 apiEventId; ///< [`CmdBufSubmit`] API-specific command buffer ID signaled Pal::uint64 apiEventId; ///< [`CmdBufSubmit`] API-specific command buffer ID signaled
/// [`SignalSemaphore`] API-specific semaphore ID signaled /// [`SignalSemaphore`] API-specific semaphore ID signaled
/// [`WaitSemaphore`] API-specific semaphore ID waited on /// [`WaitSemaphore`] API-specific semaphore ID waited on
/// [`Present`] N/A (set to 0) /// [`Present`] N/A (set to 0)
Pal::uint64 cpuTimestamp; ///< CPU start timestamp of when this event is triggered in clock cycle units Pal::uint64 cpuTimestamp; ///< CPU start timestamp of when this event is triggered in clock cycle units
Pal::uint64 gpuTimestamp1; ///< [`CmdBufSubmit`] GPU timestamp when the HW execution of command buffer began Pal::uint64 gpuTimestamp1; ///< [`CmdBufSubmit`] GPU timestamp when the HW execution of command buffer began
/// [`SignalSemaphore`] GPU timestamp when the HW signaled the queue semaphore /// [`SignalSemaphore`] GPU timestamp when the HW signaled the queue semaphore
/// [`WaitSemaphore`] GPU timestamp when HW finished waiting on the semaphore /// [`WaitSemaphore`] GPU timestamp when HW finished waiting on the semaphore
/// [`Present`] GPU timestamp when HW processed the Present call /// [`Present`] GPU timestamp when HW processed the Present call
/// ///
/// All timestamps are expressed in clock cycle units. /// All timestamps are expressed in clock cycle units.
Pal::uint64 gpuTimestamp2; ///< [`CmdBufSubmit` only; 0 otherwise] Pal::uint64 gpuTimestamp2; ///< [`CmdBufSubmit` only; 0 otherwise]
/// GPU timestamp when the HW execution of command buffer finished /// GPU timestamp when the HW execution of command buffer finished
}; };
} // namespace TraceChunk } // namespace TraceChunk
// QueueTimings Trace Source name & version // QueueTimings Trace Source name & version
constexpr char QueueTimingsTraceSourceName[] = "queuetimings"; constexpr char QueueTimingsTraceSourceName[] = "queuetimings";
constexpr Pal::uint32 QueueTimingsTraceSourceVersion = 2; constexpr Pal::uint32 QueueTimingsTraceSourceVersion = 2;
// ===================================================================================================================== // =====================================================================================================================
// This trace source captures queue timings data through GPA session & produces "QueueInfo" and "QueueEvent" RDF chunks // This trace source captures queue timings data through GPA session & produces "QueueInfo" and "QueueEvent" RDF chunks
class QueueTimingsTraceSource : public ITraceSource class QueueTimingsTraceSource : public ITraceSource
{ {
public: public:
explicit QueueTimingsTraceSource(Pal::IPlatform* pPlatform); explicit QueueTimingsTraceSource(Pal::IPlatform* pPlatform);
virtual ~QueueTimingsTraceSource(); virtual ~QueueTimingsTraceSource();
// ==== TraceSource Native Functions ========================================================================== // // ==== TraceSource Native Functions ========================================================================== //
Pal::Result Init(Pal::IDevice* pDevice); Pal::Result Init(Pal::IDevice* pDevice);
Pal::Result RegisterTimedQueue(Pal::IQueue* pQueue, Pal::Result RegisterTimedQueue(Pal::IQueue* pQueue,
Pal::uint64 queueId, Pal::uint64 queueId,
Pal::uint64 queueContext); Pal::uint64 queueContext);
Pal::Result UnregisterTimedQueue(Pal::IQueue* pQueue); Pal::Result UnregisterTimedQueue(Pal::IQueue* pQueue);
Pal::Result TimedSubmit(Pal::IQueue* pQueue, Pal::Result TimedSubmit(Pal::IQueue* pQueue,
const Pal::MultiSubmitInfo& submitInfo, const Pal::MultiSubmitInfo& submitInfo,
const TimedSubmitInfo& timedSubmitInfo); const TimedSubmitInfo& timedSubmitInfo);
Pal::Result TimedSignalQueueSemaphore(Pal::IQueue* pQueue, Pal::Result TimedSignalQueueSemaphore(Pal::IQueue* pQueue,
Pal::IQueueSemaphore* pQueueSemaphore, Pal::IQueueSemaphore* pQueueSemaphore,
const TimedQueueSemaphoreInfo& timedSignalInfo, const TimedQueueSemaphoreInfo& timedSignalInfo,
Pal::uint64 value = 0); Pal::uint64 value = 0);
Pal::Result TimedWaitQueueSemaphore(Pal::IQueue* pQueue, Pal::Result TimedWaitQueueSemaphore(Pal::IQueue* pQueue,
Pal::IQueueSemaphore* pQueueSemaphore, Pal::IQueueSemaphore* pQueueSemaphore,
const TimedQueueSemaphoreInfo& timedWaitInfo, const TimedQueueSemaphoreInfo& timedWaitInfo,
Pal::uint64 value = 0); Pal::uint64 value = 0);
Pal::Result TimedQueuePresent(Pal::IQueue* pQueue, Pal::Result TimedQueuePresent(Pal::IQueue* pQueue,
const TimedQueuePresentInfo& timedPresentInfo); const TimedQueuePresentInfo& timedPresentInfo);
Pal::Result ExternalTimedWaitQueueSemaphore(Pal::uint64 queueContext, Pal::Result ExternalTimedWaitQueueSemaphore(Pal::uint64 queueContext,
Pal::uint64 cpuSubmissionTimestamp, Pal::uint64 cpuSubmissionTimestamp,
Pal::uint64 cpuCompletionTimestamp, Pal::uint64 cpuCompletionTimestamp,
const TimedQueueSemaphoreInfo& timedWaitInfo); const TimedQueueSemaphoreInfo& timedWaitInfo);
Pal::Result ExternalTimedSignalQueueSemaphore(Pal::uint64 queueContext, Pal::Result ExternalTimedSignalQueueSemaphore(Pal::uint64 queueContext,
Pal::uint64 cpuSubmissionTimestamp, Pal::uint64 cpuSubmissionTimestamp,
Pal::uint64 cpuCompletionTimestamp, Pal::uint64 cpuCompletionTimestamp,
const TimedQueueSemaphoreInfo& timedSignalInfo); const TimedQueueSemaphoreInfo& timedSignalInfo);
bool IsTimingInProgress() const; bool IsTimingInProgress() const;
// ==== Base Class Overrides =================================================================================== // // ==== Base Class Overrides =================================================================================== //
virtual void OnConfigUpdated(DevDriver::StructuredValue* pJsonConfig) override { }; #if PAL_CLIENT_INTERFACE_MAJOR_VERSION < COMPRESSION_ARG_VERSION
virtual void OnConfigUpdated(DevDriver::StructuredValue* pJsonConfig) override { }
virtual Pal::uint64 QueryGpuWorkMask() const override { return 0; } #endif
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 908 virtual Pal::uint64 QueryGpuWorkMask() const override { return 0; }
virtual void OnTraceAccepted(Pal::uint32 gpuIndex, Pal::ICmdBuffer* pCmdBuf) override;
#else #if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 908
virtual void OnTraceAccepted() override; virtual void OnTraceAccepted(Pal::uint32 gpuIndex, Pal::ICmdBuffer* pCmdBuf) override;
#endif #else
virtual void OnTraceBegin(Pal::uint32 gpuIndex, Pal::ICmdBuffer* pCmdBuf) override { }; virtual void OnTraceAccepted() override;
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 939 #endif
virtual void OnPostambleEnd( virtual void OnTraceBegin(Pal::uint32 gpuIndex, Pal::ICmdBuffer* pCmdBuf) override { };
Pal::uint32 gpuIndex, #if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 939
Pal::ICmdBuffer* pCmdBuf) override; virtual void OnPostambleEnd(
virtual void OnTraceEnd( Pal::uint32 gpuIndex,
Pal::uint32 gpuIndex, Pal::ICmdBuffer* pCmdBuf) override;
Pal::ICmdBuffer* pCmdBuf) override {}; virtual void OnTraceEnd(
#else Pal::uint32 gpuIndex,
virtual void OnTraceEnd( Pal::ICmdBuffer* pCmdBuf) override {};
Pal::uint32 gpuIndex, #else
Pal::ICmdBuffer* pCmdBuf) override; virtual void OnTraceEnd(
#endif Pal::uint32 gpuIndex,
virtual void OnTraceFinished() override; Pal::ICmdBuffer* pCmdBuf) override;
#endif
virtual const char* GetName() const override { return QueueTimingsTraceSourceName; } virtual void OnTraceFinished() override;
virtual Pal::uint32 GetVersion() const override { return QueueTimingsTraceSourceVersion; }
virtual const char* GetName() const override { return QueueTimingsTraceSourceName; }
private: virtual Pal::uint32 GetVersion() const override { return QueueTimingsTraceSourceVersion; }
void WriteQueueInfoChunks(
const SqttQueueInfoRecord* pQueueInfoRecords, private:
size_t numQueueInfoRecords); void WriteQueueInfoChunks(
const SqttQueueInfoRecord* pQueueInfoRecords,
void WriteQueueEventChunks( size_t numQueueInfoRecords);
const SqttQueueInfoRecord* pQueueInfoRecords,
size_t numQueueInfoRecords, void WriteQueueEventChunks(
const SqttQueueEventRecord* pQueueEventRecords, const SqttQueueInfoRecord* pQueueInfoRecords,
size_t numQueueEventRecords); size_t numQueueInfoRecords,
const SqttQueueEventRecord* pQueueEventRecords,
void ReportInternalError(const char* pErrorMsg, Pal::Result result); size_t numQueueEventRecords);
Pal::IPlatform* const m_pPlatform; // IPlatform owning the parent TraceSession void ReportInternalError(const char* pErrorMsg, Pal::Result result);
GpaSession* m_pGpaSession; // Handle to GpaSession object for tracking queue timings
bool m_traceIsHealthy; // Internal flag for tracking resource and state health Pal::IPlatform* const m_pPlatform; // IPlatform owning the parent TraceSession
std::atomic<bool> m_timingInProgress; // Flag for tracking if queue timings operations are ongoing GpaSession* m_pGpaSession; // Handle to GpaSession object for tracking queue timings
bool m_traceIsHealthy; // Internal flag for tracking resource and state health
}; std::atomic<bool> m_timingInProgress; // Flag for tracking if queue timings operations are ongoing
} // namespace GpuUtil };
} // namespace GpuUtil
+155 -150
파일 보기
@@ -1,150 +1,155 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2024-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2024-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
#pragma once #pragma once
#include "palTraceSession.h" #include "palTraceSession.h"
namespace Pal namespace Pal
{ {
class IPlatform; class IPlatform;
class IQueue; class IQueue;
class ICmdBuffer; class ICmdBuffer;
class Device; class Device;
} }
namespace GpuUtil namespace GpuUtil
{ {
/// Supported render operations used to advance the trace /// Supported render operations used to advance the trace
enum RenderOp : Pal::uint8 enum RenderOp : Pal::uint8
{ {
RenderOpDraw = (1u << 0), RenderOpDraw = (1u << 0),
RenderOpDispatch = (1u << 1) RenderOpDispatch = (1u << 1)
}; };
/// Structure used to batch submit render operations on queue submission /// Structure used to batch submit render operations on queue submission
/// This struct should have a `*Count` field for each @ref RenderOp enumeration above /// This struct should have a `*Count` field for each @ref RenderOp enumeration above
struct RenderOpCounts struct RenderOpCounts
{ {
Pal::uint32 drawCount; Pal::uint32 drawCount;
Pal::uint32 dispatchCount; Pal::uint32 dispatchCount;
}; };
constexpr Pal::uint32 RenderOpTraceControllerVersion = 4; constexpr Pal::uint32 RenderOpTraceControllerVersion = 4;
constexpr char RenderOpTraceControllerName[] = "renderop"; constexpr char RenderOpTraceControllerName[] = "renderop";
// ===================================================================================================================== // =====================================================================================================================
class RenderOpTraceController : public ITraceController class RenderOpTraceController : public ITraceController
{ {
public: public:
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 896 #if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 896
using RenderOp = GpuUtil::RenderOp; using RenderOp = GpuUtil::RenderOp;
#endif #endif
RenderOpTraceController(Pal::IPlatform* pPlatform, Pal::IDevice* pDevice); RenderOpTraceController(Pal::IPlatform* pPlatform, Pal::IDevice* pDevice);
virtual ~RenderOpTraceController(); virtual ~RenderOpTraceController();
virtual const char* GetName() const override { return RenderOpTraceControllerName; } virtual const char* GetName() const override { return RenderOpTraceControllerName; }
virtual Pal::uint32 GetVersion() const override { return RenderOpTraceControllerVersion; } virtual Pal::uint32 GetVersion() const override { return RenderOpTraceControllerVersion; }
virtual void OnConfigUpdated(DevDriver::StructuredValue* pJsonConfig) override; virtual void OnConfigUpdated(DevDriver::StructuredValue* pJsonConfig) override;
virtual Pal::Result OnTraceRequested() override; virtual Pal::Result OnTraceRequested() override;
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 908 #if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 908
virtual Pal::Result OnPreparationGpuWork(Pal::uint32 gpuIndex, Pal::ICmdBuffer** ppCmdBuf) override; virtual Pal::Result OnPreparationGpuWork(Pal::uint32 gpuIndex, Pal::ICmdBuffer** ppCmdBuf) override;
#endif #endif
virtual Pal::Result OnBeginGpuWork(Pal::uint32 gpuIndex, Pal::ICmdBuffer** ppCmdBuffer) override; virtual Pal::Result OnBeginGpuWork(Pal::uint32 gpuIndex, Pal::ICmdBuffer** ppCmdBuffer) override;
virtual Pal::Result OnEndGpuWork(Pal::uint32 gpuIndex, Pal::ICmdBuffer** ppCmdBuffer) override; virtual Pal::Result OnEndGpuWork(Pal::uint32 gpuIndex, Pal::ICmdBuffer** ppCmdBuffer) override;
virtual Pal::Result OnEndPostambleGpuWork( virtual Pal::Result OnEndPostambleGpuWork(
Pal::uint32 gpuIndex, Pal::uint32 gpuIndex,
Pal::ICmdBuffer** ppCmdBuffer) override; Pal::ICmdBuffer** ppCmdBuffer) override;
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 896 #if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 896
void RecordRenderOp(Pal::IQueue* pQueue, RenderOp renderOp); void RecordRenderOp(Pal::IQueue* pQueue, RenderOp renderOp);
#endif #endif
void FinishTrace(); void FinishTrace();
// Cancel the trace currently in progress. // Cancel the trace currently in progress.
virtual Pal::Result OnTraceCanceled() override; virtual Pal::Result OnTraceCanceled() override;
/// This function must be called by client drivers implementing the RenderOp controller. /// This function must be called by client drivers implementing the RenderOp controller.
/// On every queue submission, this function is called with the cumulative counts of render operations /// On every queue submission, this function is called with the cumulative counts of render operations
/// recorded into that queue's command buffers. /// recorded into that queue's command buffers.
/// Based on the controller's internal mask, set by the user during trace configuration, /// Based on the controller's internal mask, set by the user during trace configuration,
/// the trace controller may advance its state. /// the trace controller may advance its state.
void RecordRenderOps(Pal::IQueue* pQueue, const RenderOpCounts& renderOpCounts); void RecordRenderOps(Pal::IQueue* pQueue, const RenderOpCounts& renderOpCounts);
private: // Force a controller update
/// Controls whether the trace proceeds on absolute render op counts or relative virtual void OnUpdated() override { OnRenderOpUpdated(0); }
enum class CaptureMode : Pal::uint8
{ virtual Pal::IQueue* GetTraceQueue() const override { return m_pQueue; }
Relative = 0, ///< Relative to when the trace request is received
Absolute ///< Absolute render op index private:
}; /// Controls whether the trace proceeds on absolute render op counts or relative
enum class CaptureMode : Pal::uint8
Pal::Result AcceptTrace(); {
Pal::Result BeginTrace(); Relative = 0, ///< Relative to when the trace request is received
Absolute ///< Absolute render op index
Pal::Result SubmitBeginTraceGpuWork() const; };
Pal::Result SubmitEndTraceGpuWork();
Pal::Result SubmitEndPostambleGpuWork(); Pal::Result AcceptTrace();
Pal::Result BeginTrace();
Pal::Result WaitForTraceEndGpuWorkCompletion() const;
Pal::Result CreateFence(Pal::IFence** ppFence) const; Pal::Result SubmitBeginTraceGpuWork() const;
Pal::Result CreateCommandBuffer(bool traceEnd, Pal::ICmdBuffer** ppCmdBuf) const; Pal::Result SubmitEndTraceGpuWork();
Pal::Result CreateCmdAllocator(); Pal::Result SubmitEndPostambleGpuWork();
void OnRenderOpUpdated(Pal::uint64 countRecorded); Pal::Result WaitForTraceEndGpuWorkCompletion() const;
void FreeResources(); Pal::Result CreateFence(Pal::IFence** ppFence) const;
void AbortTrace(); Pal::Result CreateCommandBuffer(bool traceEnd, Pal::ICmdBuffer** ppCmdBuf) const;
Pal::Result CreateCmdAllocator();
Pal::IPlatform* const m_pPlatform; // Platform associated with this TraceController
Pal::IDevice* m_pDevice; // Device associated with this TraceController void OnRenderOpUpdated(Pal::uint64 countRecorded);
Pal::ICmdAllocator* m_pCmdAllocator; // Command allocator for the TraceController void FreeResources();
void AbortTrace();
TraceSession* m_pTraceSession; // TraceSession owning this TraceController
Pal::uint64 m_supportedGpuMask; // Bit mask of GPU indices that are capable of participating in the trace Pal::IPlatform* const m_pPlatform; // Platform associated with this TraceController
Pal::uint8 m_renderOpMask; // Bitmask of RenderOp modes, indicating which are accepted Pal::IDevice* m_pDevice; // Device associated with this TraceController
CaptureMode m_captureMode; // Modality for determining the starting renderop index of the trace Pal::ICmdAllocator* m_pCmdAllocator; // Command allocator for the TraceController
Pal::uint64 m_renderOpCount; // The "global" count, incremented on every render op
Pal::uint64 m_prepStartRenderOp; // Relative or absolute render op number indicating trace begin TraceSession* m_pTraceSession; // TraceSession owning this TraceController
Pal::uint64 m_numPrepRenderOps; // Number of "warm-up" frames before the start frame Pal::uint64 m_supportedGpuMask; // Bit mask of GPU indices that are capable of participating in the trace
Pal::uint64 m_captureRenderOpCount; // Number of frames to wait before ending the trace Pal::uint8 m_renderOpMask; // Bitmask of RenderOp modes, indicating which are accepted
Pal::uint64 m_renderOpTraceAccepted; // The frame number when the trace was accepted CaptureMode m_captureMode; // Modality for determining the starting renderop index of the trace
Pal::uint64 m_renderOpCount; // The "global" count, incremented on every render op
Util::Mutex m_renderOpLock; // Lock over UpdateFrame/OnFrameUpdated Pal::uint64 m_prepStartRenderOp; // Relative or absolute render op number indicating trace begin
Pal::IQueue* m_pQueue; // The queue being used to submit Begin/End GPU trace command buffers Pal::uint64 m_numPrepRenderOps; // Number of "warm-up" frames before the start frame
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 908 Pal::uint64 m_captureRenderOpCount; // Number of frames to wait before ending the trace
Pal::ICmdBuffer* m_pCmdBufTracePrepare; // Command buffer for recording during the prep phase Pal::uint64 m_renderOpTraceAccepted; // The frame number when the trace was accepted
#endif
Pal::ICmdBuffer* m_pCmdBufTraceBegin; // Command buffer to submit Trace Begin Util::Mutex m_renderOpLock; // Lock over UpdateFrame/OnFrameUpdated
Pal::ICmdBuffer* m_pCmdBufTraceEnd; // Command buffer to submit Trace End Pal::IQueue* m_pQueue; // The queue being used to submit Begin/End GPU trace command buffers
Pal::ICmdBuffer* m_pCmdBufPostambleEnd; // Command buffer to submit Postamble End #if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 908
Pal::IFence* m_pFenceTraceEnd; // Fence to wait for Trace End command buffer completion Pal::ICmdBuffer* m_pCmdBufTracePrepare; // Command buffer for recording during the prep phase
Pal::IFence* m_pFencePostambleEnd; // Fence to wait for Postamble End command buffer completion #endif
}; Pal::ICmdBuffer* m_pCmdBufTraceBegin; // Command buffer to submit Trace Begin
Pal::ICmdBuffer* m_pCmdBufTraceEnd; // Command buffer to submit Trace End
} // namespace GpuUtil Pal::ICmdBuffer* m_pCmdBufPostambleEnd; // Command buffer to submit Postamble End
Pal::IFence* m_pFenceTraceEnd; // Fence to wait for Trace End command buffer completion
Pal::IFence* m_pFencePostambleEnd; // Fence to wait for Postamble End command buffer completion
};
} // namespace GpuUtil
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+368 -368
파일 보기
@@ -1,368 +1,368 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2017-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2017-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palAssert.h * @file palAssert.h
* @brief PAL utility collection assert macros. * @brief PAL utility collection assert macros.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palDbgPrint.h" #include "palDbgPrint.h"
#include "palUtil.h" #include "palUtil.h"
#if defined(_WIN32) #if defined(_WIN32)
#include <intrin.h> #include <intrin.h>
/// OS-independent macro to force a break into the debugger. /// OS-independent macro to force a break into the debugger.
#define PAL_DEBUG_BREAK() [[unlikely]] __debugbreak() #define PAL_DEBUG_BREAK() [[unlikely]] __debugbreak()
#else #else
#include <signal.h> #include <signal.h>
/// OS-independent macro to force a break into the debugger. /// OS-independent macro to force a break into the debugger.
#define PAL_DEBUG_BREAK() [[unlikely]] raise(SIGTRAP); #define PAL_DEBUG_BREAK() [[unlikely]] raise(SIGTRAP);
#endif #endif
#if defined(_MSC_VER) && !defined(__clang__) #if defined(_MSC_VER) && !defined(__clang__)
/// Macro to direct static code analysis to assume the specified expression will always be true. /// Macro to direct static code analysis to assume the specified expression will always be true.
/// Purpose is to suppress warnings from MSVC's /analysis setting. /// Purpose is to suppress warnings from MSVC's /analysis setting.
/// Only pertains to static code analysis. Does not impact compile optimization. Not the same as C++23's [[assume]]. /// Only pertains to static code analysis. Does not impact compile optimization. Not the same as C++23's [[assume]].
# define PAL_ANALYSIS_ASSUME(_expr) __analysis_assume(_expr) # define PAL_ANALYSIS_ASSUME(_expr) __analysis_assume(_expr)
#else #else
/// This macro is only useful on MSVC builds. It has no meaning for other builds. /// This macro is only useful on MSVC builds. It has no meaning for other builds.
# define PAL_ANALYSIS_ASSUME(_expr) ((void)0) # define PAL_ANALYSIS_ASSUME(_expr) ((void)0)
#endif #endif
namespace Util namespace Util
{ {
/// A helper function to check the size-in-bits of a 'reserved' member in a bitfield. /// A helper function to check the size-in-bits of a 'reserved' member in a bitfield.
/// This is intended for use with static_asserts to ensure things don't go out-of-sync. /// This is intended for use with static_asserts to ensure things don't go out-of-sync.
/// ///
/// @param [in] expectedTotalBitWidth Number of bits expected in the whole type /// @param [in] expectedTotalBitWidth Number of bits expected in the whole type
/// @param [in] expectedReservedBits Number of bits in the 'reserved' field /// @param [in] expectedReservedBits Number of bits in the 'reserved' field
/// ///
/// @return true if the bit lengths of the type T match the values in the args. /// @return true if the bit lengths of the type T match the values in the args.
/// true if the compiler lacks support to do this at compile time. /// true if the compiler lacks support to do this at compile time.
/// ///
/// @note This may not work properly with old compilers, but this is meant for linting anyhow. /// @note This may not work properly with old compilers, but this is meant for linting anyhow.
template <typename T> template <typename T>
constexpr bool CheckReservedBits( constexpr bool CheckReservedBits(
uint32 expectedTotalBitWidth, uint32 expectedTotalBitWidth,
uint32 expectedReservedBits) uint32 expectedReservedBits)
{ {
bool match = false; bool match = false;
// Fail if the whole size is different // Fail if the whole size is different
if (sizeof(T) * 8 == expectedTotalBitWidth) if (sizeof(T) * 8 == expectedTotalBitWidth)
{ {
// Get the width of the reserved field by detecting when it stops filling bits // Get the width of the reserved field by detecting when it stops filling bits
T sample = {}; T sample = {};
uint64 mask = 0; uint64 mask = 0;
uint32 reservedBits = 0; uint32 reservedBits = 0;
do do
{ {
sample = {}; sample = {};
mask = (mask << 1) | 1; mask = (mask << 1) | 1;
reservedBits++; reservedBits++;
sample.reserved = mask; sample.reserved = mask;
} while ((sample.reserved == mask) && (reservedBits < sizeof(T) * 8)); } while ((sample.reserved == mask) && (reservedBits < sizeof(T) * 8));
// when the loop terminates, it's one past the size of the field. // when the loop terminates, it's one past the size of the field.
match = (reservedBits - 1) == expectedReservedBits; match = (reservedBits - 1) == expectedReservedBits;
} }
return match; return match;
} }
/// A helper function to check that a series of static numeric values are sequential. /// A helper function to check that a series of static numeric values are sequential.
/// This is intended for use with static_asserts to ensure things don't go out-of-sync. /// This is intended for use with static_asserts to ensure things don't go out-of-sync.
/// ///
/// @param [in] args Array of numeric values to check /// @param [in] args Array of numeric values to check
/// @param [in] interval Expected interval between each (default 1, 4 is also common for field offsets) /// @param [in] interval Expected interval between each (default 1, 4 is also common for field offsets)
/// ///
/// @return true if all the values are sequential /// @return true if all the values are sequential
/// true if the compiler lacks support to do this at compile time. /// true if the compiler lacks support to do this at compile time.
/// ///
/// @note This may not work properly with old compilers, but this is meant for linting anyhow. /// @note This may not work properly with old compilers, but this is meant for linting anyhow.
template <typename T, size_t N> template <typename T, size_t N>
constexpr bool CheckSequential( constexpr bool CheckSequential(
const T (&args)[N], const T (&args)[N],
T interval = 1) T interval = 1)
{ {
bool isSequential = true; bool isSequential = true;
for (int i = 0; i < (N - 1); i++) for (int i = 0; i < (N - 1); i++)
{ {
if ((args[i] + interval) != args[i + 1]) if ((args[i] + interval) != args[i + 1])
{ {
isSequential = false; isSequential = false;
break; break;
} }
} }
return isSequential; return isSequential;
} }
#if (PAL_ENABLE_PRINTS_ASSERTS || PAL_ENABLE_LOGGING) #if (PAL_ENABLE_PRINTS_ASSERTS || PAL_ENABLE_LOGGING)
/// Specifies how severe an triggered assert (or alert) is. /// Specifies how severe an triggered assert (or alert) is.
/// ///
/// Both asserts and alerts can print out a debug string and break into the debugger. Asserts are to be used to verify /// Both asserts and alerts can print out a debug string and break into the debugger. Asserts are to be used to verify
/// the known, assumed state of the program at any time. Alerts are to be used to notify the developer of a _possible_, /// the known, assumed state of the program at any time. Alerts are to be used to notify the developer of a _possible_,
/// but unexpected condition such as memory allocation failure, an OS call failure, or an application behavior that is /// but unexpected condition such as memory allocation failure, an OS call failure, or an application behavior that is
/// known to be slow. /// known to be slow.
enum AssertCategory : uint32 enum AssertCategory : uint32
{ {
AssertCatAssert = 0, AssertCatAssert = 0,
AssertCatAlert, AssertCatAlert,
AssertCatCount AssertCatCount
}; };
/// Enables/disables the specified assert category. /// Enables/disables the specified assert category.
/// ///
/// Probably controlled by a setting and set during initialization. /// Probably controlled by a setting and set during initialization.
/// ///
/// @param [in] category Assert category to enable/disable (asserts or alerts). /// @param [in] category Assert category to enable/disable (asserts or alerts).
/// @param [in] enable True to enable the specified assert category, false to disable it. /// @param [in] enable True to enable the specified assert category, false to disable it.
extern void EnableAssertMode( extern void EnableAssertMode(
AssertCategory category, AssertCategory category,
bool enable); bool enable);
/// Returns true if the specified assert category is enabled and false otherwise. /// Returns true if the specified assert category is enabled and false otherwise.
/// ///
/// @param [in] category Assert category to check /// @param [in] category Assert category to check
extern bool IsAssertCategoryEnabled( extern bool IsAssertCategoryEnabled(
AssertCategory category); AssertCategory category);
#endif #endif
} // namespace Util } // namespace Util
#if (PAL_ENABLE_PRINTS_ASSERTS || PAL_ENABLE_LOGGING) #if (PAL_ENABLE_PRINTS_ASSERTS || PAL_ENABLE_LOGGING)
/// Prints an error message with the specified reason via the debug print system. A debug break will also be triggered /// Prints an error message with the specified reason via the debug print system. A debug break will also be triggered
/// if they're currently enabled for asserts. /// if they're currently enabled for asserts.
/// ///
/// @note This version of assert inlines an 'int 3' every time it is used so that each occurrence can be zapped /// @note This version of assert inlines an 'int 3' every time it is used so that each occurrence can be zapped
/// independently. This macro cannot be used in assignment operations. /// independently. This macro cannot be used in assignment operations.
#define PAL_TRIGGER_ASSERT(_pFormat, ...) [[unlikely]] \ #define PAL_TRIGGER_ASSERT(_pFormat, ...) [[unlikely]] \
do { \ do { \
PAL_DPERROR(_pFormat, ##__VA_ARGS__); \ PAL_DPERROR(_pFormat, ##__VA_ARGS__); \
if (::Util::IsAssertCategoryEnabled(::Util::AssertCatAssert)) \ if (::Util::IsAssertCategoryEnabled(::Util::AssertCatAssert)) \
{ \ { \
PAL_DEBUG_BREAK(); \ PAL_DEBUG_BREAK(); \
} \ } \
} while (false) } while (false)
/// If the expression evaluates to false, then it calls the PAL_TRIGGER_ASSERT macro with an error message with the /// If the expression evaluates to false, then it calls the PAL_TRIGGER_ASSERT macro with an error message with the
/// specified reason. /// specified reason.
/// ///
/// @note This assert should not be used in constant evaluated contexts (e.g., constexpr functions). /// @note This assert should not be used in constant evaluated contexts (e.g., constexpr functions).
// //
// This previously said: // This previously said:
// if (_expr_eval == false) [[unlikely]] // if (_expr_eval == false) [[unlikely]]
// { // {
// PAL_TRIGGER_ASSERT(...); // PAL_TRIGGER_ASSERT(...);
// } // }
// However there is a bug in the initial gcc implementation of [[unlikely]] that means you cannot // However there is a bug in the initial gcc implementation of [[unlikely]] that means you cannot
// attach it to a compound statement. So: // attach it to a compound statement. So:
// 1. we ignore PAL coding standards and don't use a compound statement; // 1. we ignore PAL coding standards and don't use a compound statement;
// 2. we don't use [[unlikely]] as the expansion of PAL_TRIGGER_ASSERT already has one. // 2. we don't use [[unlikely]] as the expansion of PAL_TRIGGER_ASSERT already has one.
#define PAL_ASSERT_MSG(_expr, _pReasonFmt, ...) \ #define PAL_ASSERT_MSG(_expr, _pReasonFmt, ...) \
do { \ do { \
const bool _expr_eval = static_cast<bool>(_expr); \ const bool _expr_eval = static_cast<bool>(_expr); \
if (_expr_eval == false) \ if (_expr_eval == false) \
PAL_TRIGGER_ASSERT("Assertion failed: %s | Reason: " _pReasonFmt, #_expr, ##__VA_ARGS__); \ PAL_TRIGGER_ASSERT("Assertion failed: %s | Reason: " _pReasonFmt, #_expr, ##__VA_ARGS__); \
PAL_ANALYSIS_ASSUME(_expr_eval); \ PAL_ANALYSIS_ASSUME(_expr_eval); \
} while (false) } while (false)
#if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ < 6) #if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ < 6)
// Function to circumvent gcc 5.x inability to use lambdas in unevaluated constant expression contexts. // Function to circumvent gcc 5.x inability to use lambdas in unevaluated constant expression contexts.
constexpr void PalTriggerAssertImpl( constexpr void PalTriggerAssertImpl(
const char* pFormat, const char* pFormat,
const char* pExpr, const char* pExpr,
const char* pFile, const char* pFile,
int line, int line,
const char* pFunc) const char* pFunc)
{ {
// pExpr is always not nullptr, as it's supposed to be a preprocessor string, but it does convince gcc // pExpr is always not nullptr, as it's supposed to be a preprocessor string, but it does convince gcc
// to compile PalTriggerAssertImpl() as potentially constexpr // to compile PalTriggerAssertImpl() as potentially constexpr
pExpr != nullptr ? pExpr != nullptr ?
[&] [&]
{ {
Util::DbgPrintf( Util::DbgPrintf(
Util::DbgPrintCatErrorMsg, Util::DbgPrintCatErrorMsg,
Util::DbgPrintStyleDefault, Util::DbgPrintStyleDefault,
pFormat, pFormat,
pExpr, pExpr,
pFile, pFile,
line, line,
pFunc); pFunc);
if (Util::IsAssertCategoryEnabled(Util::AssertCatAssert)) if (Util::IsAssertCategoryEnabled(Util::AssertCatAssert))
{ {
PAL_DEBUG_BREAK(); PAL_DEBUG_BREAK();
} }
return 0; return 0;
}() }()
: 0; : 0;
} }
// gcc 5.4 implementation of PAL_CONSTEXPR_ASSERT_MSG that ignores the additional reason for the assertion // gcc 5.4 implementation of PAL_CONSTEXPR_ASSERT_MSG that ignores the additional reason for the assertion
// //
// This previously said: // This previously said:
// if (_expr_eval == false) [[unlikely]] // if (_expr_eval == false) [[unlikely]]
// { // {
// PalTriggerAssertImpl(...); // PalTriggerAssertImpl(...);
// } // }
// However there is a bug in the initial gcc implementation of [[unlikely]] that means you cannot // However there is a bug in the initial gcc implementation of [[unlikely]] that means you cannot
// attach it to a compound statement. So we ignore PAL coding standards and don't use a compound statement. // attach it to a compound statement. So we ignore PAL coding standards and don't use a compound statement.
#define PAL_CONSTEXPR_ASSERT_MSG(_expr, _pReasonFmt, ...) \ #define PAL_CONSTEXPR_ASSERT_MSG(_expr, _pReasonFmt, ...) \
do { \ do { \
const bool _expr_eval = static_cast<bool>(_expr); \ const bool _expr_eval = static_cast<bool>(_expr); \
if (_expr_eval == false) [[unlikely]] \ if (_expr_eval == false) [[unlikely]] \
PalTriggerAssertImpl("Assertion failed: %s (%s:%d:%s)", #_expr, __FILE__, __LINE__, __func__); \ PalTriggerAssertImpl("Assertion failed: %s (%s:%d:%s)", #_expr, __FILE__, __LINE__, __func__); \
PAL_ANALYSIS_ASSUME(_expr_eval); \ PAL_ANALYSIS_ASSUME(_expr_eval); \
} while (false) } while (false)
#else #else
/// If the expression evaluates to false, then it calls the PAL_TRIGGER_ASSERT macro with an error message with the /// If the expression evaluates to false, then it calls the PAL_TRIGGER_ASSERT macro with an error message with the
/// specified reason. /// specified reason.
/// ///
/// @note This assert should be used in constant evaluated contexts (e.g., constexpr functions). /// @note This assert should be used in constant evaluated contexts (e.g., constexpr functions).
/// @note This assert uses an immediately-invoked function expression in the form of an internal lambda to signal a /// @note This assert uses an immediately-invoked function expression in the form of an internal lambda to signal a
/// failed assert. Since PAL_TRIGGER_ASSERT is not constexpr, an _expr that evaluates to false will fail to /// failed assert. Since PAL_TRIGGER_ASSERT is not constexpr, an _expr that evaluates to false will fail to
/// compile the function operator of the lambda. /// compile the function operator of the lambda.
// //
// This previously said: // This previously said:
// if (_expr_eval == false) [[unlikely]] // if (_expr_eval == false) [[unlikely]]
// { // {
// [&] { PAL_TRIGGER_ASSERT(...); }(); // [&] { PAL_TRIGGER_ASSERT(...); }();
// } // }
// However there is a bug in the initial gcc implementation of [[unlikely]] that means you cannot // However there is a bug in the initial gcc implementation of [[unlikely]] that means you cannot
// attach it to a compound statement. So we ignore PAL coding standards and don't use a compound statement. // attach it to a compound statement. So we ignore PAL coding standards and don't use a compound statement.
#define PAL_CONSTEXPR_ASSERT_MSG(_expr, _pReasonFmt, ...) \ #define PAL_CONSTEXPR_ASSERT_MSG(_expr, _pReasonFmt, ...) \
do { \ do { \
const bool _expr_eval = static_cast<bool>(_expr); \ const bool _expr_eval = static_cast<bool>(_expr); \
if (_expr_eval == false) [[unlikely]] \ if (_expr_eval == false) [[unlikely]] \
[&] { PAL_TRIGGER_ASSERT("Assertion failed: %s | Reason: " _pReasonFmt, #_expr, ##__VA_ARGS__); }(); \ [&] { PAL_TRIGGER_ASSERT("Assertion failed: %s | Reason: " _pReasonFmt, #_expr, ##__VA_ARGS__); }(); \
PAL_ANALYSIS_ASSUME(_expr_eval); \ PAL_ANALYSIS_ASSUME(_expr_eval); \
} while (false) } while (false)
#endif #endif
/// Calls the PAL_ASSERT_MSG macro with a generic reason string /// Calls the PAL_ASSERT_MSG macro with a generic reason string
#define PAL_ASSERT(_expr) PAL_ASSERT_MSG(_expr, "%s", "Unknown") #define PAL_ASSERT(_expr) PAL_ASSERT_MSG(_expr, "%s", "Unknown")
/// Calls the PAL_CONSTEXPR_ASSERT_MSG macro with a generic reason string /// Calls the PAL_CONSTEXPR_ASSERT_MSG macro with a generic reason string
#define PAL_CONSTEXPR_ASSERT(_expr) PAL_CONSTEXPR_ASSERT_MSG(_expr, "%s", "Unknown") #define PAL_CONSTEXPR_ASSERT(_expr) PAL_CONSTEXPR_ASSERT_MSG(_expr, "%s", "Unknown")
#if DEBUG #if DEBUG
/// Debug build only PAL assert, the typical usage is when make an assertion on a debug-only variables. /// Debug build only PAL assert, the typical usage is when make an assertion on a debug-only variables.
/// The only difference than PAL assert is it's empty in release mode. /// The only difference than PAL assert is it's empty in release mode.
#define PAL_DEBUG_BUILD_ONLY_ASSERT(_expr) \ #define PAL_DEBUG_BUILD_ONLY_ASSERT(_expr) \
do { \ do { \
PAL_ASSERT(_expr); \ PAL_ASSERT(_expr); \
} while (false) } while (false)
#else #else
#define PAL_DEBUG_BUILD_ONLY_ASSERT(_expr) ((void)0) #define PAL_DEBUG_BUILD_ONLY_ASSERT(_expr) ((void)0)
#endif #endif
/// If the expression evaluates to true, then a warning message with the specified reason will be printed via the /// If the expression evaluates to true, then a warning message with the specified reason will be printed via the
/// debug print system. A debug break will also be triggered if they're currently enabled for alerts. /// debug print system. A debug break will also be triggered if they're currently enabled for alerts.
/// ///
/// @note This is the opposite polarity of asserts. The assert macro _asserts_ that the specified condition is true. /// @note This is the opposite polarity of asserts. The assert macro _asserts_ that the specified condition is true.
/// While the alert macro _alerts_ the developer if the specified condition is true. /// While the alert macro _alerts_ the developer if the specified condition is true.
/// ///
/// This macro should be used in places where an assert is inappropriate because an error condition is _possible_, but /// This macro should be used in places where an assert is inappropriate because an error condition is _possible_, but
/// not typically expected. For example, asserting that an OS call succeeded should be avoided since there cannot be an /// not typically expected. For example, asserting that an OS call succeeded should be avoided since there cannot be an
/// assumption that it will succeed. Nonetheless, a developer may want to be alerted immediately and dropped into the /// assumption that it will succeed. Nonetheless, a developer may want to be alerted immediately and dropped into the
/// debugger when such a failure occurs. /// debugger when such a failure occurs.
#define PAL_TRIGGER_ALERT(_pFormat, ...) [[unlikely]] \ #define PAL_TRIGGER_ALERT(_pFormat, ...) [[unlikely]] \
do { \ do { \
PAL_DPWARN(_pFormat, ##__VA_ARGS__); \ PAL_DPWARN(_pFormat, ##__VA_ARGS__); \
if (::Util::IsAssertCategoryEnabled(::Util::AssertCatAlert)) \ if (::Util::IsAssertCategoryEnabled(::Util::AssertCatAlert)) \
{ \ { \
PAL_DEBUG_BREAK(); \ PAL_DEBUG_BREAK(); \
} \ } \
} while (false) } while (false)
// //
// This previously said: // This previously said:
// if (_expr) [[unlikely]] // if (_expr) [[unlikely]]
// { // {
// PAL_TRIGGER_ASSERT(...); // PAL_TRIGGER_ASSERT(...);
// } // }
// However there is a bug in the initial gcc implementation of [[unlikely]] that means you cannot // However there is a bug in the initial gcc implementation of [[unlikely]] that means you cannot
// attach it to a compound statement. So: // attach it to a compound statement. So:
// 1. we ignore PAL coding standards and don't use a compound statement; // 1. we ignore PAL coding standards and don't use a compound statement;
// 2. we don't use [[unlikely]] as the expansion of PAL_TRIGGER_ASSERT already has one. // 2. we don't use [[unlikely]] as the expansion of PAL_TRIGGER_ASSERT already has one.
#define PAL_ALERT_MSG(_expr, _pReasonFmt, ...) \ #define PAL_ALERT_MSG(_expr, _pReasonFmt, ...) \
do { \ do { \
if (_expr) \ if (_expr) \
PAL_TRIGGER_ALERT("Alert triggered: %s | Reason: " _pReasonFmt, #_expr, ##__VA_ARGS__); \ PAL_TRIGGER_ALERT("Alert triggered: %s | Reason: " _pReasonFmt, #_expr, ##__VA_ARGS__); \
} while (false) } while (false)
/// Calls the PAL_ALERT_MSG macro with a generic reason string /// Calls the PAL_ALERT_MSG macro with a generic reason string
#define PAL_ALERT(_expr) PAL_ALERT_MSG(_expr, "%s", "Unknown") #define PAL_ALERT(_expr) PAL_ALERT_MSG(_expr, "%s", "Unknown")
/// Convenience macro that asserts if something has never been tested. /// Convenience macro that asserts if something has never been tested.
#define PAL_NOT_TESTED_MSG(_pReasonFmt, ...) PAL_TRIGGER_ASSERT("Code Not Tested! | Reason: " _pReasonFmt, ##__VA_ARGS__) #define PAL_NOT_TESTED_MSG(_pReasonFmt, ...) PAL_TRIGGER_ASSERT("Code Not Tested! | Reason: " _pReasonFmt, ##__VA_ARGS__)
#define PAL_NOT_TESTED() PAL_NOT_TESTED_MSG("%s", "Unknown") #define PAL_NOT_TESTED() PAL_NOT_TESTED_MSG("%s", "Unknown")
/// Convenience macro that asserts if something has not been implemented. /// Convenience macro that asserts if something has not been implemented.
#define PAL_NOT_IMPLEMENTED_MSG(_pReasonFmt, ...) PAL_TRIGGER_ASSERT("Not Implemented! | Reason: " _pReasonFmt, ##__VA_ARGS__) #define PAL_NOT_IMPLEMENTED_MSG(_pReasonFmt, ...) PAL_TRIGGER_ASSERT("Not Implemented! | Reason: " _pReasonFmt, ##__VA_ARGS__)
#define PAL_NOT_IMPLEMENTED() PAL_NOT_IMPLEMENTED_MSG("%s", "Unknown") #define PAL_NOT_IMPLEMENTED() PAL_NOT_IMPLEMENTED_MSG("%s", "Unknown")
/// Convenience macro that asserts if an area of code that shouldn't be executed is reached. /// Convenience macro that asserts if an area of code that shouldn't be executed is reached.
#define PAL_NEVER_CALLED_MSG(_pReasonFmt, ...) PAL_TRIGGER_ASSERT("Code should never be called! | Reason: " _pReasonFmt, ##__VA_ARGS__) #define PAL_NEVER_CALLED_MSG(_pReasonFmt, ...) PAL_TRIGGER_ASSERT("Code should never be called! | Reason: " _pReasonFmt, ##__VA_ARGS__)
#define PAL_NEVER_CALLED() PAL_NEVER_CALLED_MSG("%s", "Unknown") #define PAL_NEVER_CALLED() PAL_NEVER_CALLED_MSG("%s", "Unknown")
/// Convenience macro that always asserts. Expect this to be used instead of PAL_ASSERT(false). /// Convenience macro that always asserts. Expect this to be used instead of PAL_ASSERT(false).
#define PAL_ASSERT_ALWAYS_MSG(_pReasonFmt, ...) PAL_TRIGGER_ASSERT("Unconditional Assert | Reason: " _pReasonFmt, ##__VA_ARGS__) #define PAL_ASSERT_ALWAYS_MSG(_pReasonFmt, ...) PAL_TRIGGER_ASSERT("Unconditional Assert | Reason: " _pReasonFmt, ##__VA_ARGS__)
#define PAL_ASSERT_ALWAYS() PAL_ASSERT_ALWAYS_MSG("%s", "Unknown") #define PAL_ASSERT_ALWAYS() PAL_ASSERT_ALWAYS_MSG("%s", "Unknown")
/// Convenience macro that always alerts. Expect this to be used instead of PAL_ALERT(true). /// Convenience macro that always alerts. Expect this to be used instead of PAL_ALERT(true).
#define PAL_ALERT_ALWAYS_MSG(_pReasonFmt, ...) PAL_TRIGGER_ALERT("Unconditional Alert | Reason: " _pReasonFmt, ##__VA_ARGS__) #define PAL_ALERT_ALWAYS_MSG(_pReasonFmt, ...) PAL_TRIGGER_ALERT("Unconditional Alert | Reason: " _pReasonFmt, ##__VA_ARGS__)
#define PAL_ALERT_ALWAYS() PAL_ALERT_ALWAYS_MSG("%s", "Unknown") #define PAL_ALERT_ALWAYS() PAL_ALERT_ALWAYS_MSG("%s", "Unknown")
#else #else
#define PAL_ASSERT(_expr) PAL_ANALYSIS_ASSUME(_expr) #define PAL_ASSERT(_expr) PAL_ANALYSIS_ASSUME(_expr)
#define PAL_CONSTEXPR_ASSERT(_expr) PAL_ANALYSIS_ASSUME(_expr) #define PAL_CONSTEXPR_ASSERT(_expr) PAL_ANALYSIS_ASSUME(_expr)
#define PAL_ASSERT_MSG(_expr, ...) PAL_ANALYSIS_ASSUME(_expr) #define PAL_ASSERT_MSG(_expr, ...) PAL_ANALYSIS_ASSUME(_expr)
#define PAL_CONSTEXPR_ASSERT_MSG(_expr, ...) PAL_ANALYSIS_ASSUME(_expr) #define PAL_CONSTEXPR_ASSERT_MSG(_expr, ...) PAL_ANALYSIS_ASSUME(_expr)
#define PAL_DEBUG_BUILD_ONLY_ASSERT(_expr) ((void)0) #define PAL_DEBUG_BUILD_ONLY_ASSERT(_expr) ((void)0)
#define PAL_ALERT(_expr) ((void)0) #define PAL_ALERT(_expr) ((void)0)
#define PAL_ALERT_MSG(_expr, ...) ((void)0) #define PAL_ALERT_MSG(_expr, ...) ((void)0)
#define PAL_NOT_TESTED() [[unlikely]] ((void)0) #define PAL_NOT_TESTED() [[unlikely]] ((void)0)
#define PAL_NOT_TESTED_MSG(...) [[unlikely]] ((void)0) #define PAL_NOT_TESTED_MSG(...) [[unlikely]] ((void)0)
#define PAL_NOT_IMPLEMENTED() [[unlikely]] ((void)0) #define PAL_NOT_IMPLEMENTED() [[unlikely]] ((void)0)
#define PAL_NOT_IMPLEMENTED_MSG(...) [[unlikely]] ((void)0) #define PAL_NOT_IMPLEMENTED_MSG(...) [[unlikely]] ((void)0)
#define PAL_NEVER_CALLED() [[unlikely]] ((void)0) #define PAL_NEVER_CALLED() [[unlikely]] ((void)0)
#define PAL_NEVER_CALLED_MSG(...) [[unlikely]] ((void)0) #define PAL_NEVER_CALLED_MSG(...) [[unlikely]] ((void)0)
#define PAL_ASSERT_ALWAYS() [[unlikely]] ((void)0) #define PAL_ASSERT_ALWAYS() [[unlikely]] ((void)0)
#define PAL_ASSERT_ALWAYS_MSG(...) [[unlikely]] ((void)0) #define PAL_ASSERT_ALWAYS_MSG(...) [[unlikely]] ((void)0)
#define PAL_ALERT_ALWAYS() [[unlikely]] ((void)0) #define PAL_ALERT_ALWAYS() [[unlikely]] ((void)0)
#define PAL_ALERT_ALWAYS_MSG(...) [[unlikely]] ((void)0) #define PAL_ALERT_ALWAYS_MSG(...) [[unlikely]] ((void)0)
#endif #endif
+212 -212
파일 보기
@@ -1,212 +1,212 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palAutoBuffer.h * @file palAutoBuffer.h
* @brief PAL utility collection AutoBuffer class definition. * @brief PAL utility collection AutoBuffer class definition.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palSpan.h" #include "palSpan.h"
#include "palSysMemory.h" #include "palSysMemory.h"
namespace Util namespace Util
{ {
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Safe version of C99's variable-length arrays. * @brief Safe version of C99's variable-length arrays.
* *
* The general idea is that this class encapsulates a variable-length array where we expect the size required to not * The general idea is that this class encapsulates a variable-length array where we expect the size required to not
* exceed the 'defaultCapacity' template parameter most of the time. In those "normal" cases, this buffer will * exceed the 'defaultCapacity' template parameter most of the time. In those "normal" cases, this buffer will
* reference a static array of size 'defaultCapacity', but if the constructor's parameter exceeds defaultCapacity, then * reference a static array of size 'defaultCapacity', but if the constructor's parameter exceeds defaultCapacity, then
* a dynamic array will be allocated from the heap to satisfy the space requirements. The destructor will clean-up any * a dynamic array will be allocated from the heap to satisfy the space requirements. The destructor will clean-up any
* dynamic allocation made by the constructor. * dynamic allocation made by the constructor.
* *
* This class violates several PAL coding conventions, but for good reason: * This class violates several PAL coding conventions, but for good reason:
* *
* - We have overloaded the [] (array-element-accessor) operator to make using this class just like using a regular * - We have overloaded the [] (array-element-accessor) operator to make using this class just like using a regular
* array, which it semantically represents. * array, which it semantically represents.
* - In order to return array elements by-reference instead of by-value, we need to use C++ references in the * - In order to return array elements by-reference instead of by-value, we need to use C++ references in the
* overloaded operators because this is required by C++. * overloaded operators because this is required by C++.
* *
* This class __does not__ clear the contents of the static or dynamic arrays, for performance reasons. If a client * This class __does not__ clear the contents of the static or dynamic arrays, for performance reasons. If a client
* needs the buffer to be cleared, it must do the memset itself. (However, if 'Item' is a class type rather than * needs the buffer to be cleared, it must do the memset itself. (However, if 'Item' is a class type rather than
* plain-old-data, the default c'tor will be invoked.) * plain-old-data, the default c'tor will be invoked.)
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template<typename Item, size_t defaultCapacity, typename Allocator> template<typename Item, size_t defaultCapacity, typename Allocator>
class AutoBuffer class AutoBuffer
{ {
public: public:
/// Constructor. /// Constructor.
/// ///
/// The object is initialized to use the static array of items if the required capacity is less than or equal to the /// The object is initialized to use the static array of items if the required capacity is less than or equal to the
/// default capacity. Otherwise, a larger array is allocated on the heap. /// default capacity. Otherwise, a larger array is allocated on the heap.
/// ///
/// @param [in] requiredCapacity Number of items actually required (unknown until runtime). /// @param [in] requiredCapacity Number of items actually required (unknown until runtime).
/// @param [in] pAllocator The allocator that will allocate memory if required. /// @param [in] pAllocator The allocator that will allocate memory if required.
AutoBuffer( AutoBuffer(
size_t requiredCapacity, size_t requiredCapacity,
Allocator*const pAllocator) Allocator*const pAllocator)
: :
m_capacity(requiredCapacity), m_capacity(requiredCapacity),
m_pBuffer(reinterpret_cast<Item*>(m_localBuffer)), m_pBuffer(reinterpret_cast<Item*>(m_localBuffer)),
m_pAllocator(pAllocator) m_pAllocator(pAllocator)
{ {
if (requiredCapacity > defaultCapacity) if (requiredCapacity > defaultCapacity)
{ {
// Create dynamically allocated array, by allocating memory and constructing its objects. // Create dynamically allocated array, by allocating memory and constructing its objects.
// On failure, to avoid subtle bugs from misuse, AutoBuffer will be in a zombie state with zero capacity. // On failure, to avoid subtle bugs from misuse, AutoBuffer will be in a zombie state with zero capacity.
m_pBuffer = PAL_NEW_ARRAY(Item, requiredCapacity, pAllocator, AllocInternalTemp); m_pBuffer = PAL_NEW_ARRAY(Item, requiredCapacity, pAllocator, AllocInternalTemp);
if (m_pBuffer == nullptr) if (m_pBuffer == nullptr)
{ {
m_capacity = 0; m_capacity = 0;
} }
} }
else if (!std::is_trivial<Item>::value) else if (!std::is_trivial<Item>::value)
{ {
// Explicitly construct all objects of non-trivial type in the local buffer. // Explicitly construct all objects of non-trivial type in the local buffer.
for (uint32 idx = 0; idx < m_capacity; ++idx) for (uint32 idx = 0; idx < m_capacity; ++idx)
{ {
PAL_PLACEMENT_NEW(m_pBuffer + idx) Item(); PAL_PLACEMENT_NEW(m_pBuffer + idx) Item();
} }
} }
} }
/// Destructor. /// Destructor.
/// ///
/// Cleans up the dynamically allocated buffer if we allocated one. /// Cleans up the dynamically allocated buffer if we allocated one.
~AutoBuffer() ~AutoBuffer()
{ {
if (m_pBuffer != reinterpret_cast<Item*>(m_localBuffer)) if (m_pBuffer != reinterpret_cast<Item*>(m_localBuffer))
{ {
// Destory dynamically allocated array, by destroying its objects and freeing memory. // Destory dynamically allocated array, by destroying its objects and freeing memory.
PAL_SAFE_DELETE_ARRAY(m_pBuffer, m_pAllocator); PAL_SAFE_DELETE_ARRAY(m_pBuffer, m_pAllocator);
} }
else if (!std::is_trivial<Item>::value) else if (!std::is_trivial<Item>::value)
{ {
// Explicitly destroy all objects of non-trivial type from the local buffer. // Explicitly destroy all objects of non-trivial type from the local buffer.
for (uint32 idx = 0; idx < m_capacity; ++idx) for (uint32 idx = 0; idx < m_capacity; ++idx)
{ {
m_pBuffer[idx].~Item(); m_pBuffer[idx].~Item();
} }
} }
} }
/// Getter for the capacity of the buffer. /// Getter for the capacity of the buffer.
/// ///
/// Clients can use this function to determine if the constuctor's allocation succeeded. /// Clients can use this function to determine if the constuctor's allocation succeeded.
/// ///
/// @returns Size of the array in bytes. Should match the requiredCapacity parameter passed to the constructor /// @returns Size of the array in bytes. Should match the requiredCapacity parameter passed to the constructor
/// unless a dynamic memory allocation failed. /// unless a dynamic memory allocation failed.
constexpr size_t Capacity() const noexcept { return m_capacity; } constexpr size_t Capacity() const noexcept { return m_capacity; }
/// Getter for the size of this buffer, in bytes. /// Getter for the size of this buffer, in bytes.
constexpr size_t SizeBytes() const noexcept { return (sizeof(Item) * m_capacity); } constexpr size_t SizeBytes() const noexcept { return (sizeof(Item) * m_capacity); }
/// Accessor for the nth element of this buffer. /// Accessor for the nth element of this buffer.
const Item& operator[](size_t n) const const Item& operator[](size_t n) const
{ {
PAL_ASSERT(n < m_capacity); PAL_ASSERT(n < m_capacity);
return m_pBuffer[n]; return m_pBuffer[n];
} }
/// Non-const accessor for the nth element of this buffer. /// Non-const accessor for the nth element of this buffer.
Item& operator[](size_t n) Item& operator[](size_t n)
{ {
PAL_ASSERT(n < m_capacity); PAL_ASSERT(n < m_capacity);
return m_pBuffer[n]; return m_pBuffer[n];
} }
///@{ ///@{
/// Implicitly gets the current contents of the buffer as a Span. /// Implicitly gets the current contents of the buffer as a Span.
/// ///
/// @returns The contents of the buffer as a Span; same as Span<T>(Data(), Size()). /// @returns The contents of the buffer as a Span; same as Span<T>(Data(), Size()).
operator Span<Item>() { return Span<Item>(Data(), Capacity()); } operator Span<Item>() { return Span<Item>(Data(), Capacity()); }
operator Span<const Item>() const { return Span<const Item>(Data(), Capacity()); } operator Span<const Item>() const { return Span<const Item>(Data(), Capacity()); }
///@} ///@}
/// Returns pointer to the underlying buffer serving as data storage. /// Returns pointer to the underlying buffer serving as data storage.
/// The returned pointer defines always valid range [Data(), Data() + Capacity()). /// The returned pointer defines always valid range [Data(), Data() + Capacity()).
/// ///
/// @returns Pointer to the underlying data storage for read & write access. /// @returns Pointer to the underlying data storage for read & write access.
/// The returned pointer contains address of the first element. /// The returned pointer contains address of the first element.
constexpr Item* Data() noexcept { return m_pBuffer; } constexpr Item* Data() noexcept { return m_pBuffer; }
/// Returns pointer to the underlying buffer serving as data storage. /// Returns pointer to the underlying buffer serving as data storage.
/// The returned pointer defines always valid range [Data(), Data() + Capacity()), /// The returned pointer defines always valid range [Data(), Data() + Capacity()),
/// even if the container is empty (Data() is not dereferenceable in that case). /// even if the container is empty (Data() is not dereferenceable in that case).
/// ///
/// @returns Pointer to the underlying data storage for read only access. /// @returns Pointer to the underlying data storage for read only access.
/// The returned pointer contains address of the first element. /// The returned pointer contains address of the first element.
constexpr const Item* Data() const noexcept { return m_pBuffer; } constexpr const Item* Data() const noexcept { return m_pBuffer; }
///@{ ///@{
/// @internal Satisfies concept `range_expression`, using Item* as `iterator` and 64-bit size and difference types /// @internal Satisfies concept `range_expression`, using Item* as `iterator` and 64-bit size and difference types
/// ///
/// @note - These are a convenience intended to be used by c++ language features such as range-based-for-loops. /// @note - These are a convenience intended to be used by c++ language features such as range-based-for-loops.
using value_type = Item; using value_type = Item;
using reference = Item&; using reference = Item&;
using const_reference = const Item&; using const_reference = const Item&;
using iterator = Item*; using iterator = Item*;
using const_iterator = const Item*; using const_iterator = const Item*;
using difference_type = ptrdiff_t; using difference_type = ptrdiff_t;
using size_type = size_t; using size_type = size_t;
constexpr iterator begin() noexcept { return Data(); } constexpr iterator begin() noexcept { return Data(); }
constexpr iterator end() noexcept { return Data() + Capacity(); } constexpr iterator end() noexcept { return Data() + Capacity(); }
constexpr const_iterator begin() const noexcept { return Data(); } constexpr const_iterator begin() const noexcept { return Data(); }
constexpr const_iterator end() const noexcept { return Data() + Capacity(); } constexpr const_iterator end() const noexcept { return Data() + Capacity(); }
constexpr const_iterator cbegin() const noexcept { return Data(); } constexpr const_iterator cbegin() const noexcept { return Data(); }
constexpr const_iterator cend() const noexcept { return Data() + Capacity(); } constexpr const_iterator cend() const noexcept { return Data() + Capacity(); }
[[nodiscard]] constexpr bool empty() const noexcept { return Capacity() == 0; } [[nodiscard]] constexpr bool empty() const noexcept { return Capacity() == 0; }
constexpr size_type size() const noexcept { return Capacity(); } constexpr size_type size() const noexcept { return Capacity(); }
///@} ///@}
private: private:
// This is a POD-type that exactly fits one Item value. // This is a POD-type that exactly fits one Item value.
using ValueStorage = typename std::aligned_storage<sizeof(Item), alignof(Item)>::type; using ValueStorage = typename std::aligned_storage<sizeof(Item), alignof(Item)>::type;
// Capacity of this buffer (in Items). // Capacity of this buffer (in Items).
size_t m_capacity; size_t m_capacity;
// Buffer pointer this object uses to access the buffer's elements: if the required capacity exceeds the default // Buffer pointer this object uses to access the buffer's elements: if the required capacity exceeds the default
// capacity, this points to a dynamic array of Items. Otherwise, this points to m_localBuffer. // capacity, this points to a dynamic array of Items. Otherwise, this points to m_localBuffer.
Item* m_pBuffer; Item* m_pBuffer;
// Static array providing storage for Items which we expect most objects of this type to end up using. // Static array providing storage for Items which we expect most objects of this type to end up using.
ValueStorage m_localBuffer[defaultCapacity]; ValueStorage m_localBuffer[defaultCapacity];
// Allocator for this AutoBuffer. // Allocator for this AutoBuffer.
Allocator*const m_pAllocator; Allocator*const m_pAllocator;
PAL_DISALLOW_DEFAULT_CTOR(AutoBuffer); PAL_DISALLOW_DEFAULT_CTOR(AutoBuffer);
PAL_DISALLOW_COPY_AND_ASSIGN(AutoBuffer); PAL_DISALLOW_COPY_AND_ASSIGN(AutoBuffer);
}; };
} // Util } // Util
+202 -202
파일 보기
@@ -1,202 +1,202 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palBuddyAllocator.h * @file palBuddyAllocator.h
* @brief PAL utility BuddyAllocator class declaration. * @brief PAL utility BuddyAllocator class declaration.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palUtil.h" #include "palUtil.h"
#include "palHashSet.h" #include "palHashSet.h"
#include "palHashMap.h" #include "palHashMap.h"
#include "palMutex.h" #include "palMutex.h"
namespace Util namespace Util
{ {
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Buddy Allocator * @brief Buddy Allocator
* *
* Responsible for managing small GPU memory requests by allocating a large base allocation and dividing it into * Responsible for managing small GPU memory requests by allocating a large base allocation and dividing it into
* appropriately sized suballocation blocks. * appropriately sized suballocation blocks.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template <typename Allocator> template <typename Allocator>
class BuddyAllocator class BuddyAllocator
{ {
public: public:
/// Constructor. /// Constructor.
/// ///
/// @param [in] pAllocator The allocator that will allocate memory if required. /// @param [in] pAllocator The allocator that will allocate memory if required.
/// @param [in] baseAllocSize The size of the base allocation this buddy allocator suballocates. /// @param [in] baseAllocSize The size of the base allocation this buddy allocator suballocates.
/// @param [in] minAllocSize The size of the smallest block this buddy allocator can allocate. /// @param [in] minAllocSize The size of the smallest block this buddy allocator can allocate.
BuddyAllocator( BuddyAllocator(
Allocator* pAllocator, Allocator* pAllocator,
gpusize baseAllocSize, gpusize baseAllocSize,
gpusize minAllocSize); gpusize minAllocSize);
~BuddyAllocator(); ~BuddyAllocator();
/// Initializes the buddy allocator. /// Initializes the buddy allocator.
/// ///
/// @returns Success if the buddy allocator has been successfully initialized. /// @returns Success if the buddy allocator has been successfully initialized.
Result Init(); Result Init();
/// Suballocates a block from the base allocation that this buddy allocator manages. Expects @ref ClaimGpuMemory to /// Suballocates a block from the base allocation that this buddy allocator manages. Expects @ref ClaimGpuMemory to
/// be called directly before it. If a memory manager with multiple buddyAllocators is used, use pattern should /// be called directly before it. If a memory manager with multiple buddyAllocators is used, use pattern should
/// be: Iterate through buddyAllocators calling ClaimGpuMemory, if one returns @ref Success break out of the loop, /// be: Iterate through buddyAllocators calling ClaimGpuMemory, if one returns @ref Success break out of the loop,
/// then call Allocate on that buddyAllocator. If none return @ref Success, then a new buddyAllocator needs to be /// then call Allocate on that buddyAllocator. If none return @ref Success, then a new buddyAllocator needs to be
/// created. The purpose of splitting up buddyAllocator selection and Allocation is to reduce lock contention in /// created. The purpose of splitting up buddyAllocator selection and Allocation is to reduce lock contention in
/// multithreaded memory managers. /// multithreaded memory managers.
/// ///
/// @param [in] size The size of the requested suballocation. /// @param [in] size The size of the requested suballocation.
/// @param [in] alignment The alignment requirements of the requested suballocation. /// @param [in] alignment The alignment requirements of the requested suballocation.
/// @param [out] pOffset The offset the suballocated block starts within the base allocation. /// @param [out] pOffset The offset the suballocated block starts within the base allocation.
/// ///
/// @returns Success if the allocation succeeded, @ref ErrorOutOfMemory if there isn't enough system memory to /// @returns Success if the allocation succeeded, @ref ErrorOutOfMemory if there isn't enough system memory to
/// fulfill the request, or @ref ErrorOutOfGpuMemory if there isn't a large enough block free in the /// fulfill the request, or @ref ErrorOutOfGpuMemory if there isn't a large enough block free in the
/// base allocation to fulfill the request. /// base allocation to fulfill the request.
/// ///
/// @warning Unless @ref ClaimGpuMemory is called before every single call, the results of @ref Allocate will /// @warning Unless @ref ClaimGpuMemory is called before every single call, the results of @ref Allocate will
/// be invalid. If @ref ClaimGpuMemory returns @ref Success, then @ref ErrorOutOfGpuMemory will never be /// be invalid. If @ref ClaimGpuMemory returns @ref Success, then @ref ErrorOutOfGpuMemory will never be
/// returned. /// returned.
Result Allocate( Result Allocate(
gpusize size, gpusize size,
gpusize alignment, gpusize alignment,
gpusize* pOffset); gpusize* pOffset);
/// Frees a previously allocated suballocation. /// Frees a previously allocated suballocation.
/// ///
/// @param [in] offset The offset the suballocated block starts within the base allocation. /// @param [in] offset The offset the suballocated block starts within the base allocation.
/// @param [in] size Optional parameter specifying the size of the original allocation. /// @param [in] size Optional parameter specifying the size of the original allocation.
/// @param [in] alignment Optional parameter specifying the alignment of the original allocation. /// @param [in] alignment Optional parameter specifying the alignment of the original allocation.
void Free( void Free(
gpusize offset, gpusize offset,
gpusize size = 0, gpusize size = 0,
gpusize alignment = 0); gpusize alignment = 0);
/// Tells whether the base allocation is completely free. If the returned value is true then the caller is safe /// Tells whether the base allocation is completely free. If the returned value is true then the caller is safe
/// to deallocate the base allocation. /// to deallocate the base allocation.
bool IsEmpty() const bool IsEmpty() const
{ {
return (m_numSuballocations == 0); return (m_numSuballocations == 0);
} }
/// Returns the size of the largest allocation that can be suballocated with this buddy allocator. /// Returns the size of the largest allocation that can be suballocated with this buddy allocator.
gpusize MaximumAllocationSize() const; gpusize MaximumAllocationSize() const;
/// Claims (doesn't allocate) some memory, used to quickly determine if a pool of memory has availible memory. /// Claims (doesn't allocate) some memory, used to quickly determine if a pool of memory has availible memory.
/// Doesn't affect internal state unless Result::Success is returned /// Doesn't affect internal state unless Result::Success is returned
/// ///
/// @param [in] size The size of the requested suballocation. /// @param [in] size The size of the requested suballocation.
/// @param [in] alignment The alignment requirements of the requested suballocation. /// @param [in] alignment The alignment requirements of the requested suballocation.
/// ///
/// @returns Success if there is enough memory in this buddyAllocator to allocate the requested size of memory, /// @returns Success if there is enough memory in this buddyAllocator to allocate the requested size of memory,
/// @ref ErrorOutOfGpuMemory if there is not enough memory /// @ref ErrorOutOfGpuMemory if there is not enough memory
/// ///
/// @warning Unless this is called to test availible memory before every call to Allocate, then the results will not /// @warning Unless this is called to test availible memory before every call to Allocate, then the results will not
/// be valid. /// be valid.
Result ClaimGpuMemory( Result ClaimGpuMemory(
gpusize size, gpusize size,
gpusize alignment); gpusize alignment);
/// Checks if @ref ClaimGpuMemory can actually claim memory, can be used to find the best fit pool. This function /// Checks if @ref ClaimGpuMemory can actually claim memory, can be used to find the best fit pool. This function
/// does NOT acquire a lock on the structures ClaimGpuMemory uses, and does NOT claim or allocate the memory. /// does NOT acquire a lock on the structures ClaimGpuMemory uses, and does NOT claim or allocate the memory.
/// ///
/// @param [in] size The size of the requested suballocation. /// @param [in] size The size of the requested suballocation.
/// @param [in] alignment The alignment requirements of the requested suballocation. /// @param [in] alignment The alignment requirements of the requested suballocation.
/// @param [out] pKval The highest kval that will need to be split will be stored here. /// @param [out] pKval The highest kval that will need to be split will be stored here.
/// ///
/// @returns Success if there is enough memory in this buddyAllocator to allocate the requested size of memory, /// @returns Success if there is enough memory in this buddyAllocator to allocate the requested size of memory,
/// @ref ErrorOutOfGpuMemory if there is not enough memory /// @ref ErrorOutOfGpuMemory if there is not enough memory
/// ///
Result CheckIfOpenMemory( Result CheckIfOpenMemory(
gpusize size, gpusize size,
gpusize alignment, gpusize alignment,
uint32* pKval); uint32* pKval);
private: private:
typedef Util::HashSet<gpusize, Allocator, JenkinsHashFunc> FreeSet; typedef Util::HashSet<gpusize, Allocator, JenkinsHashFunc> FreeSet;
typedef Util::HashMap<gpusize, uint32, Allocator, JenkinsHashFunc> UsedMap; typedef Util::HashMap<gpusize, uint32, Allocator, JenkinsHashFunc> UsedMap;
Result GetNextFreeBlock( Result GetNextFreeBlock(
uint32 kval, uint32 kval,
gpusize* pOffset); gpusize* pOffset);
Result FreeBlock(gpusize offset); Result FreeBlock(gpusize offset);
static constexpr gpusize KvalToSize(uint32 kVal) { return (1ull << kVal); } static constexpr gpusize KvalToSize(uint32 kVal) { return (1ull << kVal); }
static uint32 SizeToKval(gpusize size) { return Log2(size); } static uint32 SizeToKval(gpusize size) { return Log2(size); }
Allocator* const m_pAllocator; Allocator* const m_pAllocator;
const uint32 m_baseAllocKval; const uint32 m_baseAllocKval;
const uint32 m_minKval; const uint32 m_minKval;
// Array of hashSets of blocks that are free at each level // Array of hashSets of blocks that are free at each level
FreeSet* m_pFreeBlockSets; FreeSet* m_pFreeBlockSets;
// Hashmap of blocks that are used, key=offset, value=level (kval) // Hashmap of blocks that are used, key=offset, value=level (kval)
UsedMap* m_pUsedBlockMap; UsedMap* m_pUsedBlockMap;
// List of the free memory at each level // List of the free memory at each level
uint32* m_pNumFreeList; uint32* m_pNumFreeList;
// The highest Kval that has at least 1 free block (used in ClaimGpuMemory) // The highest Kval that has at least 1 free block (used in ClaimGpuMemory)
uint32 m_highestFreeKval; uint32 m_highestFreeKval;
uint32 m_numSuballocations; uint32 m_numSuballocations;
// mutex on altering the numFreeList // mutex on altering the numFreeList
Util::Mutex m_numFreeMutex; Util::Mutex m_numFreeMutex;
// mutex on the used block map // mutex on the used block map
Util::Mutex m_usedBlockMapMutex; Util::Mutex m_usedBlockMapMutex;
// array of mutexes, one for each freeBlockSet // array of mutexes, one for each freeBlockSet
Util::Mutex* m_pFreeSetMutexes; Util::Mutex* m_pFreeSetMutexes;
// mutex on the freeing. Serialize freeing blocks and don't allow allocating blocks while one is freeing. Based on // mutex on the freeing. Serialize freeing blocks and don't allow allocating blocks while one is freeing. Based on
// testing, applications typically don't try to free and allocate memory at the same time, and almost all of the // testing, applications typically don't try to free and allocate memory at the same time, and almost all of the
// memory freeing is done at the end of the application. // memory freeing is done at the end of the application.
Util::RWLock m_freeLock; Util::RWLock m_freeLock;
// Set to true if ClaimGpuMemory is ever called on this buddyAllocator. This signals to free to not merge blocks // Set to true if ClaimGpuMemory is ever called on this buddyAllocator. This signals to free to not merge blocks
// if m_pNumFreeList[kval - m_minKval] = 0 // if m_pNumFreeList[kval - m_minKval] = 0
bool m_usedClaim; bool m_usedClaim;
// HashSet and HashMap utility functions // HashSet and HashMap utility functions
Result InsertToFreeSet(gpusize offset, uint32 kval); Result InsertToFreeSet(gpusize offset, uint32 kval);
bool GetKvalUsed(gpusize offset, uint32* pKval); bool GetKvalUsed(gpusize offset, uint32* pKval);
Result SetKvalUsed(gpusize offset, uint32 kval); Result SetKvalUsed(gpusize offset, uint32 kval);
Result PopFromFreeSet(gpusize* pOffset, uint32 kval); Result PopFromFreeSet(gpusize* pOffset, uint32 kval);
bool IsOffsetFree(gpusize offset, uint32 kval); bool IsOffsetFree(gpusize offset, uint32 kval);
Result RemoveOffsetFromFreeSet(gpusize offset, uint32 kval); Result RemoveOffsetFromFreeSet(gpusize offset, uint32 kval);
Result RemoveOffsetFromUsedMap(gpusize offset); Result RemoveOffsetFromUsedMap(gpusize offset);
PAL_DISALLOW_COPY_AND_ASSIGN(BuddyAllocator); PAL_DISALLOW_COPY_AND_ASSIGN(BuddyAllocator);
PAL_DISALLOW_DEFAULT_CTOR(BuddyAllocator); PAL_DISALLOW_DEFAULT_CTOR(BuddyAllocator);
}; };
} // Util } // Util
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+364 -364
파일 보기
@@ -1,364 +1,364 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2017-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2017-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palDbgPrint.h * @file palDbgPrint.h
* @brief Defines PAL utility collection debug print functionality. * @brief Defines PAL utility collection debug print functionality.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palUtil.h" #include "palUtil.h"
#include <stdarg.h> #include <stdarg.h>
#if PAL_ENABLE_LOGGING #if PAL_ENABLE_LOGGING
#include "palDbgLogHelper.h" #include "palDbgLogHelper.h"
#endif #endif
namespace Util namespace Util
{ {
#if (PAL_ENABLE_PRINTS_ASSERTS || PAL_ENABLE_LOGGING) #if (PAL_ENABLE_PRINTS_ASSERTS || PAL_ENABLE_LOGGING)
// Forward declarations. // Forward declarations.
class File; class File;
enum FileAccessMode : uint32; enum FileAccessMode : uint32;
/// Specifies the category of a debug print. /// Specifies the category of a debug print.
/// ///
/// Driver developer can enable/disable each category separately through settings. /// Driver developer can enable/disable each category separately through settings.
enum DbgPrintCategory : uint32 enum DbgPrintCategory : uint32
{ {
DbgPrintCatInfoMsg = 0, ///< Generic informational messages. DbgPrintCatInfoMsg = 0, ///< Generic informational messages.
DbgPrintCatWarnMsg, ///< Warning messages. DbgPrintCatWarnMsg, ///< Warning messages.
DbgPrintCatErrorMsg, ///< Error messages. DbgPrintCatErrorMsg, ///< Error messages.
DbgPrintCatScMsg, ///< Generic shader compiler messages. DbgPrintCatScMsg, ///< Generic shader compiler messages.
DbgPrintCatEventPrintMsg, ///< System event messages. DbgPrintCatEventPrintMsg, ///< System event messages.
DbgPrintCatEventPrintCallbackMsg, ///< System event messages via callback. DbgPrintCatEventPrintCallbackMsg, ///< System event messages via callback.
DbgPrintCatMsgFile, ///< All Messages via file. DbgPrintCatMsgFile, ///< All Messages via file.
DbgPrintCatCount DbgPrintCatCount
}; };
/// Specifies the debug print mode: disabled, print to debugger, or print to file. /// Specifies the debug print mode: disabled, print to debugger, or print to file.
enum class DbgPrintMode : uint32 enum class DbgPrintMode : uint32
{ {
Disable, ///< Debug print is ignored. Disable, ///< Debug print is ignored.
Print, ///< Debug print is routed to the debug window or stdout. Print, ///< Debug print is routed to the debug window or stdout.
File, ///< Debug print is routed to a file. File, ///< Debug print is routed to a file.
PrintCallback, ///< Debug print is routed to the print callback only PrintCallback, ///< Debug print is routed to the print callback only
}; };
/// Flags specifying style controls for a debug print. /// Flags specifying style controls for a debug print.
enum DbgPrintStyle : uint32 enum DbgPrintStyle : uint32
{ {
DbgPrintStyleDefault = 0x0, ///< Normal mode: has a prefix and a CR-LF. DbgPrintStyleDefault = 0x0, ///< Normal mode: has a prefix and a CR-LF.
DbgPrintStyleNoPrefix = 0x1, ///< Skip the prefix. DbgPrintStyleNoPrefix = 0x1, ///< Skip the prefix.
DbgPrintStyleNoCrLf = 0x2, ///< Skip the CR-LF. DbgPrintStyleNoCrLf = 0x2, ///< Skip the CR-LF.
DbgPrintStyleNoPrefixNoCrLf = 0x3, ///< Skip both the prefix and the CR-LF. DbgPrintStyleNoPrefixNoCrLf = 0x3, ///< Skip both the prefix and the CR-LF.
}; };
/// Definition for debug print callback. /// Definition for debug print callback.
/// ///
/// @param [in] pUserData User data that is installed with the callback for use by the installer. /// @param [in] pUserData User data that is installed with the callback for use by the installer.
/// @param [in] category Debug print category that the message belongs to. /// @param [in] category Debug print category that the message belongs to.
/// @param [in] pText Text data to be printed by the callback. /// @param [in] pText Text data to be printed by the callback.
typedef void (PAL_STDCALL *DbgPrintCallbackFunc)( typedef void (PAL_STDCALL *DbgPrintCallbackFunc)(
void* pUserdata, void* pUserdata,
DbgPrintCategory category, DbgPrintCategory category,
const char* pText); const char* pText);
/// Debug print callback struct that bundles the callback function and its userdata pointer. /// Debug print callback struct that bundles the callback function and its userdata pointer.
struct DbgPrintCallback struct DbgPrintCallback
{ {
DbgPrintCallbackFunc pCallbackFunc; DbgPrintCallbackFunc pCallbackFunc;
void* pUserdata; void* pUserdata;
}; };
/// Generic debug printf function to be used when the caller wishes to specify the output category and style. Clients /// Generic debug printf function to be used when the caller wishes to specify the output category and style. Clients
/// should use the PAL_DPF macro instead of calling this function directly. /// should use the PAL_DPF macro instead of calling this function directly.
/// ///
/// @param [in] category Message category (e.g., CS dumps, SC output, etc.). /// @param [in] category Message category (e.g., CS dumps, SC output, etc.).
/// @param [in] style Text output style (i.e., has prefix and/or CR-LF). /// @param [in] style Text output style (i.e., has prefix and/or CR-LF).
/// @param [in] pFormat Printf-style format string. /// @param [in] pFormat Printf-style format string.
extern void DbgPrintf( extern void DbgPrintf(
DbgPrintCategory category, DbgPrintCategory category,
DbgPrintStyle style, DbgPrintStyle style,
const char* pFormat, const char* pFormat,
...); ...);
/// Generic printf function to be used when the caller wishes to specify the output category and style, and has /// Generic printf function to be used when the caller wishes to specify the output category and style, and has
/// pre-started the variable arg list (va_list argument instead of ...). /// pre-started the variable arg list (va_list argument instead of ...).
/// ///
/// @param [in] category Message category (e.g., CS dumps, SC output, etc.). /// @param [in] category Message category (e.g., CS dumps, SC output, etc.).
/// @param [in] style Text output style (i.e., has prefix and/or CR-LF). /// @param [in] style Text output style (i.e., has prefix and/or CR-LF).
/// @param [in] pFormat Printf-style format string. /// @param [in] pFormat Printf-style format string.
/// @param [in] argList Variable argument list. /// @param [in] argList Variable argument list.
extern void DbgVPrintf( extern void DbgVPrintf(
DbgPrintCategory category, DbgPrintCategory category,
DbgPrintStyle style, DbgPrintStyle style,
const char* pFormat, const char* pFormat,
va_list argList); va_list argList);
#endif #endif
#if PAL_ENABLE_PRINTS_ASSERTS #if PAL_ENABLE_PRINTS_ASSERTS
/// Sets the debug print mode (output to debugger, write to file, or disabled) for the specified category of messages. /// Sets the debug print mode (output to debugger, write to file, or disabled) for the specified category of messages.
/// ///
/// Probably controlled by a setting and set during initialization. /// Probably controlled by a setting and set during initialization.
/// ///
/// @param [in] category Message category to control (e.g., CS dumps, SC output, etc.). /// @param [in] category Message category to control (e.g., CS dumps, SC output, etc.).
/// @param [in] mode New mode to be used for this message category (print to file, etc.). /// @param [in] mode New mode to be used for this message category (print to file, etc.).
extern void SetDbgPrintMode( extern void SetDbgPrintMode(
DbgPrintCategory category, DbgPrintCategory category,
DbgPrintMode mode); DbgPrintMode mode);
/// Opens a file that resides in the selected log directory. /// Opens a file that resides in the selected log directory.
/// ///
/// This function exists in all build configurations. /// This function exists in all build configurations.
/// ///
/// @param [in,out] pFile File object to represent the opened file. /// @param [in,out] pFile File object to represent the opened file.
/// @param [in] pFilename Filename to open. /// @param [in] pFilename Filename to open.
/// @param [in] flags ORed mask of FileAccessMode values specifying how this file will be accessed. /// @param [in] flags ORed mask of FileAccessMode values specifying how this file will be accessed.
/// ///
/// @returns Success if successful, otherwise an appropriate error. /// @returns Success if successful, otherwise an appropriate error.
extern Result OpenLogFile( extern Result OpenLogFile(
File* pFile, File* pFile,
const char* pFilename, const char* pFilename,
uint32 flags); uint32 flags);
/// Sets the global debug print callback. /// Sets the global debug print callback.
/// ///
/// @param [in] callback Debug print callback struct that contains the callback function and a userdata pointer /// @param [in] callback Debug print callback struct that contains the callback function and a userdata pointer
extern void SetDbgPrintCallback( extern void SetDbgPrintCallback(
const DbgPrintCallback& callback); const DbgPrintCallback& callback);
#endif #endif
// Forward declarations. // Forward declarations.
template<typename CharT> class StringView; template<typename CharT> class StringView;
/// Logs a text string via client callback when provided. /// Logs a text string via client callback when provided.
/// ///
/// @param [in] pClientData Pointer to client-defined data. The pClientData value specified in the pLogCbInfo /// @param [in] pClientData Pointer to client-defined data. The pClientData value specified in the pLogCbInfo
/// parameter to CreatePlatform() will be passed back to the client on every log callback. /// parameter to CreatePlatform() will be passed back to the client on every log callback.
/// @param [in] level Log priority level associated with the message. /// @param [in] level Log priority level associated with the message.
/// @param [in] categoryMask Log category mask that represents what category fields the message relates to. /// @param [in] categoryMask Log category mask that represents what category fields the message relates to.
/// @param [in] pFormat Format string for the log message. /// @param [in] pFormat Format string for the log message.
/// @param [in] args Variable arguments that correspond to the format string. /// @param [in] args Variable arguments that correspond to the format string.
typedef void (PAL_STDCALL *LogCallbackFunc)( typedef void (PAL_STDCALL *LogCallbackFunc)(
void* pClientData, void* pClientData,
uint32 level, uint32 level,
uint64 categoryMask, uint64 categoryMask,
const char* pFormat, const char* pFormat,
va_list args); va_list args);
/// Specifies client-provided logging callbacks. Used as a parameter to Pal::CreatePlatform(). /// Specifies client-provided logging callbacks. Used as a parameter to Pal::CreatePlatform().
/// ///
/// @ingroup LibInit /// @ingroup LibInit
struct LogCallbackInfo struct LogCallbackInfo
{ {
void* pClientData; ///< Opaque pointer to data of client's choosing. This pointer will be passed back to void* pClientData; ///< Opaque pointer to data of client's choosing. This pointer will be passed back to
/// every @ref LogCallbackFunc call made by PAL. /// every @ref LogCallbackFunc call made by PAL.
LogCallbackFunc pfnLogCb; ///< Debug print logging callback. @see LogCallbackFunc. LogCallbackFunc pfnLogCb; ///< Debug print logging callback. @see LogCallbackFunc.
}; };
/// Compiler-specific wrapper of the standard snprintf implementation. /// Compiler-specific wrapper of the standard snprintf implementation.
/// ///
/// @param [out] pOutput Output string. /// @param [out] pOutput Output string.
/// @param [in] bufSize Available space in pOutput. /// @param [in] bufSize Available space in pOutput.
/// @param [in] pFormat Printf-style format string. /// @param [in] pFormat Printf-style format string.
/// ///
/// @returns The resultant length of the formatted string. /// @returns The resultant length of the formatted string.
extern int32 Snprintf( extern int32 Snprintf(
char* pOutput, char* pOutput,
size_t bufSize, size_t bufSize,
const char* pFormat, const char* pFormat,
...); ...);
/// Compiler-specific wrapper of the standard vsnprintf implementation. /// Compiler-specific wrapper of the standard vsnprintf implementation.
/// ///
/// @param [out] pOutput Output string. If buffer is a nullptr it returns the length of the string that would be /// @param [out] pOutput Output string. If buffer is a nullptr it returns the length of the string that would be
/// printed had a buffer with enough space been provided. /// printed had a buffer with enough space been provided.
/// @param [in] bufSize Available space in pOutput. /// @param [in] bufSize Available space in pOutput.
/// @param [in] pFormat Printf-style format string. /// @param [in] pFormat Printf-style format string.
/// @param [in] argList variable argument list. /// @param [in] argList variable argument list.
/// ///
/// @returns The resultant length of the formatted string. /// @returns The resultant length of the formatted string.
extern int32 Vsnprintf( extern int32 Vsnprintf(
char* pOutput, char* pOutput,
size_t bufSize, size_t bufSize,
const char* pFormat, const char* pFormat,
va_list argList); va_list argList);
/// Compiler-specific wrapper of the standard snprintf implementation. /// Compiler-specific wrapper of the standard snprintf implementation.
/// ///
/// @param [out] pOutput Output string. /// @param [out] pOutput Output string.
/// @param [in] bufSize Available space in pOutput. /// @param [in] bufSize Available space in pOutput.
/// @param [in] pFormat Printf-style format string. /// @param [in] pFormat Printf-style format string.
/// ///
/// @returns The resultant length of the formatted string. /// @returns The resultant length of the formatted string.
extern int32 Snprintf( extern int32 Snprintf(
wchar_t* pOutput, wchar_t* pOutput,
size_t bufSize, size_t bufSize,
const wchar_t* pFormat, const wchar_t* pFormat,
...); ...);
/// Compiler-specific wrapper of the standard vsnprintf implementation. /// Compiler-specific wrapper of the standard vsnprintf implementation.
/// ///
/// @param [out] pOutput Output string. If buffer is a nullptr it returns the length of the string that would be /// @param [out] pOutput Output string. If buffer is a nullptr it returns the length of the string that would be
/// printed had a buffer with enough space been provided. /// printed had a buffer with enough space been provided.
/// @param [in] bufSize Available space in pOutput. /// @param [in] bufSize Available space in pOutput.
/// @param [in] pFormat Printf-style format string. /// @param [in] pFormat Printf-style format string.
/// @param [in] argList variable argument list. /// @param [in] argList variable argument list.
/// ///
/// @returns The resultant length of the formatted string. /// @returns The resultant length of the formatted string.
extern int32 Vsnprintf( extern int32 Vsnprintf(
wchar_t* pOutput, wchar_t* pOutput,
size_t bufSize, size_t bufSize,
const wchar_t* pFormat, const wchar_t* pFormat,
va_list argList); va_list argList);
/// Copy an arbitrary string into the provided buffer, encoding as necessary to avoid characters that are illegal /// Copy an arbitrary string into the provided buffer, encoding as necessary to avoid characters that are illegal
/// in filenames (assuming the more restrictive Windows rules, even on non-Windows OSs). /// in filenames (assuming the more restrictive Windows rules, even on non-Windows OSs).
/// ///
/// Any byte that would be illegal is encoded as % then two hex digits, like in a URL. /// Any byte that would be illegal is encoded as % then two hex digits, like in a URL.
/// ///
/// @param [out] pOutput Output string. /// @param [out] pOutput Output string.
/// @param bufSize Available space in pOutput. /// @param bufSize Available space in pOutput.
/// @param [in] input Input string /// @param [in] input Input string
/// @param allowSpace Allow (do not % encode) space /// @param allowSpace Allow (do not % encode) space
/// @param allowDirSeparator Allow (do not % encode) / and \ characters /// @param allowDirSeparator Allow (do not % encode) / and \ characters
/// ///
/// @returns Works like C++ standard snprintf: /// @returns Works like C++ standard snprintf:
/// - If the provided buffer is big enough, it returns the number of bytes written, excluding the /// - If the provided buffer is big enough, it returns the number of bytes written, excluding the
/// terminating \0. /// terminating \0.
/// - If the provided buffer is not big enough, then the result string is truncated to fit, and the /// - If the provided buffer is not big enough, then the result string is truncated to fit, and the
/// function returns the number of bytes that would have been written if the buffer had been long /// function returns the number of bytes that would have been written if the buffer had been long
/// enough, excluding the terminating \0. /// enough, excluding the terminating \0.
/// - Passing 0 buffer length is allowed as a special case of that, and nullptr pOutput is then allowed. /// - Passing 0 buffer length is allowed as a special case of that, and nullptr pOutput is then allowed.
extern size_t EncodeAsFilename( extern size_t EncodeAsFilename(
char* pOutput, char* pOutput,
size_t bufSize, size_t bufSize,
const StringView<char>& input, const StringView<char>& input,
bool allowSpace, bool allowSpace,
bool allowDirSeparator); bool allowDirSeparator);
/// Generate a log filename. /// Generate a log filename.
/// ///
/// @param [inout] pFilenameBuffer Buffer to hold the filename. /// @param [inout] pFilenameBuffer Buffer to hold the filename.
/// @param maxSize Max size of the pFilenameBuffer. /// @param maxSize Max size of the pFilenameBuffer.
/// @param nextPost The next write position. /// @param nextPost The next write position.
/// @param [in] pExt The filename extension. /// @param [in] pExt The filename extension.
/// @param logDuplicate Log duplicate objects. /// @param logDuplicate Log duplicate objects.
extern void GenLogFilename( extern void GenLogFilename(
char* pFilenameBuffer, char* pFilenameBuffer,
size_t maxSize, size_t maxSize,
size_t nextPos, size_t nextPos,
const char* const pExt, const char* const pExt,
bool logDuplicate); bool logDuplicate);
} // Util } // Util
/// PAL_ENABLE_LOGGING enables the new logging code. At this time, both, the current and new logging /// PAL_ENABLE_LOGGING enables the new logging code. At this time, both, the current and new logging
/// code will be active for development purpose if both macros are enabled. /// code will be active for development purpose if both macros are enabled.
#if (PAL_ENABLE_PRINTS_ASSERTS && PAL_ENABLE_LOGGING) #if (PAL_ENABLE_PRINTS_ASSERTS && PAL_ENABLE_LOGGING)
/// Debug printf macro. /// Debug printf macro.
#define PAL_DPF ::Util::DbgPrintf #define PAL_DPF ::Util::DbgPrintf
/// Debug info printf macro. /// Debug info printf macro.
#define PAL_DPINFO(_pFormat, ...) \ #define PAL_DPINFO(_pFormat, ...) \
{ \ { \
::Util::DbgPrintf(::Util::DbgPrintCatInfoMsg, ::Util::DbgPrintStyleDefault, _pFormat " (%s:%d:%s)", \ ::Util::DbgPrintf(::Util::DbgPrintCatInfoMsg, ::Util::DbgPrintStyleDefault, _pFormat " (%s:%d:%s)", \
##__VA_ARGS__, __FILE__, __LINE__, __func__); \ ##__VA_ARGS__, __FILE__, __LINE__, __func__); \
::Util::DbgLog(::Util::SeverityLevel::Info, ::Util::OriginationType::DebugPrint, \ ::Util::DbgLog(::Util::SeverityLevel::Info, ::Util::OriginationType::DebugPrint, \
"AMD-PAL", _pFormat " (%s:%d:%s)", ##__VA_ARGS__, __FILE__, __LINE__, __func__); \ "AMD-PAL", _pFormat " (%s:%d:%s)", ##__VA_ARGS__, __FILE__, __LINE__, __func__); \
} }
/// Debug warning printf macro. /// Debug warning printf macro.
#define PAL_DPWARN(_pFormat, ...) \ #define PAL_DPWARN(_pFormat, ...) \
{ \ { \
::Util::DbgPrintf(::Util::DbgPrintCatWarnMsg, ::Util::DbgPrintStyleDefault, _pFormat " (%s:%d:%s)", \ ::Util::DbgPrintf(::Util::DbgPrintCatWarnMsg, ::Util::DbgPrintStyleDefault, _pFormat " (%s:%d:%s)", \
##__VA_ARGS__, __FILE__, __LINE__, __func__); \ ##__VA_ARGS__, __FILE__, __LINE__, __func__); \
::Util::DbgLog(::Util::SeverityLevel::Warning, ::Util::OriginationType::DebugPrint, \ ::Util::DbgLog(::Util::SeverityLevel::Warning, ::Util::OriginationType::DebugPrint, \
"AMD-PAL", _pFormat " (%s:%d:%s)", ##__VA_ARGS__, __FILE__, __LINE__, __func__); \ "AMD-PAL", _pFormat " (%s:%d:%s)", ##__VA_ARGS__, __FILE__, __LINE__, __func__); \
} }
/// Debug error printf macro. /// Debug error printf macro.
#define PAL_DPERROR(_pFormat, ...) \ #define PAL_DPERROR(_pFormat, ...) \
{ \ { \
::Util::DbgPrintf(::Util::DbgPrintCatErrorMsg, ::Util::DbgPrintStyleDefault, _pFormat " (%s:%d:%s)", \ ::Util::DbgPrintf(::Util::DbgPrintCatErrorMsg, ::Util::DbgPrintStyleDefault, _pFormat " (%s:%d:%s)", \
##__VA_ARGS__, __FILE__, __LINE__, __func__); \ ##__VA_ARGS__, __FILE__, __LINE__, __func__); \
::Util::DbgLog(::Util::SeverityLevel::Error, ::Util::OriginationType::DebugPrint, \ ::Util::DbgLog(::Util::SeverityLevel::Error, ::Util::OriginationType::DebugPrint, \
"AMD-PAL", _pFormat " (%s:%d:%s)", ##__VA_ARGS__, __FILE__, __LINE__, __func__); \ "AMD-PAL", _pFormat " (%s:%d:%s)", ##__VA_ARGS__, __FILE__, __LINE__, __func__); \
} }
#elif PAL_ENABLE_PRINTS_ASSERTS #elif PAL_ENABLE_PRINTS_ASSERTS
/// Debug printf macro. /// Debug printf macro.
#define PAL_DPF ::Util::DbgPrintf #define PAL_DPF ::Util::DbgPrintf
/// Debug info printf macro. /// Debug info printf macro.
#define PAL_DPINFO(_pFormat, ...) \ #define PAL_DPINFO(_pFormat, ...) \
{ \ { \
::Util::DbgPrintf(::Util::DbgPrintCatInfoMsg, ::Util::DbgPrintStyleDefault, _pFormat " (%s:%d:%s)", \ ::Util::DbgPrintf(::Util::DbgPrintCatInfoMsg, ::Util::DbgPrintStyleDefault, _pFormat " (%s:%d:%s)", \
##__VA_ARGS__, __FILE__, __LINE__, __func__); \ ##__VA_ARGS__, __FILE__, __LINE__, __func__); \
} }
/// Debug warning printf macro. /// Debug warning printf macro.
#define PAL_DPWARN(_pFormat, ...) \ #define PAL_DPWARN(_pFormat, ...) \
{ \ { \
::Util::DbgPrintf(::Util::DbgPrintCatWarnMsg, ::Util::DbgPrintStyleDefault, _pFormat " (%s:%d:%s)", \ ::Util::DbgPrintf(::Util::DbgPrintCatWarnMsg, ::Util::DbgPrintStyleDefault, _pFormat " (%s:%d:%s)", \
##__VA_ARGS__, __FILE__, __LINE__, __func__); \ ##__VA_ARGS__, __FILE__, __LINE__, __func__); \
} }
/// Debug error printf macro. /// Debug error printf macro.
#define PAL_DPERROR(_pFormat, ...) \ #define PAL_DPERROR(_pFormat, ...) \
{ \ { \
::Util::DbgPrintf(::Util::DbgPrintCatErrorMsg, ::Util::DbgPrintStyleDefault, _pFormat " (%s:%d:%s)", \ ::Util::DbgPrintf(::Util::DbgPrintCatErrorMsg, ::Util::DbgPrintStyleDefault, _pFormat " (%s:%d:%s)", \
##__VA_ARGS__, __FILE__, __LINE__, __func__); \ ##__VA_ARGS__, __FILE__, __LINE__, __func__); \
} }
#elif PAL_ENABLE_LOGGING #elif PAL_ENABLE_LOGGING
/// Debug printf macro. /// Debug printf macro.
#define PAL_DPF ::Util::DbgPrintf #define PAL_DPF ::Util::DbgPrintf
/// Debug info printf macro. /// Debug info printf macro.
#define PAL_DPINFO(_pFormat, ...) \ #define PAL_DPINFO(_pFormat, ...) \
{ \ { \
::Util::DbgLog(::Util::SeverityLevel::Info, ::Util::OriginationType::DebugPrint, \ ::Util::DbgLog(::Util::SeverityLevel::Info, ::Util::OriginationType::DebugPrint, \
"AMD-PAL", _pFormat " (%s:%d:%s)", ##__VA_ARGS__, __FILE__, __LINE__, __func__); \ "AMD-PAL", _pFormat " (%s:%d:%s)", ##__VA_ARGS__, __FILE__, __LINE__, __func__); \
} }
/// Debug warning printf macro. /// Debug warning printf macro.
#define PAL_DPWARN(_pFormat, ...) \ #define PAL_DPWARN(_pFormat, ...) \
{ \ { \
::Util::DbgLog(::Util::SeverityLevel::Warning, ::Util::OriginationType::DebugPrint, \ ::Util::DbgLog(::Util::SeverityLevel::Warning, ::Util::OriginationType::DebugPrint, \
"AMD-PAL", _pFormat " (%s:%d:%s)", ##__VA_ARGS__, __FILE__, __LINE__, __func__); \ "AMD-PAL", _pFormat " (%s:%d:%s)", ##__VA_ARGS__, __FILE__, __LINE__, __func__); \
} }
/// Debug error printf macro. /// Debug error printf macro.
#define PAL_DPERROR(_pFormat, ...) \ #define PAL_DPERROR(_pFormat, ...) \
{ \ { \
::Util::DbgLog(::Util::SeverityLevel::Error, ::Util::OriginationType::DebugPrint, \ ::Util::DbgLog(::Util::SeverityLevel::Error, ::Util::OriginationType::DebugPrint, \
"AMD-PAL", _pFormat " (%s:%d:%s)", ##__VA_ARGS__, __FILE__, __LINE__, __func__); \ "AMD-PAL", _pFormat " (%s:%d:%s)", ##__VA_ARGS__, __FILE__, __LINE__, __func__); \
} }
#else #else
/// Debug printf macro. /// Debug printf macro.
#define PAL_DPF(...) ((void)0) #define PAL_DPF(...) ((void)0)
/// Debug info printf macro. /// Debug info printf macro.
#define PAL_DPINFO(...) ((void)0) #define PAL_DPINFO(...) ((void)0)
/// Debug warning printf macro. /// Debug warning printf macro.
#define PAL_DPWARN(...) ((void)0) #define PAL_DPWARN(...) ((void)0)
/// Debug error printf macro. /// Debug error printf macro.
#define PAL_DPERROR(...) ((void)0) #define PAL_DPERROR(...) ((void)0)
#endif #endif
+319 -319
파일 보기
@@ -1,319 +1,319 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palDeque.h * @file palDeque.h
* @brief PAL utility collection Deque and DequeIterator class declarations. * @brief PAL utility collection Deque and DequeIterator class declarations.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palAssert.h" #include "palAssert.h"
#include "palSysMemory.h" #include "palSysMemory.h"
namespace Util namespace Util
{ {
// Forward declarations. // Forward declarations.
template<typename T, typename Allocator> class Deque; template<typename T, typename Allocator> class Deque;
/// @internal Private structure used by Deque and its iterators to store chunks of data elements. /// @internal Private structure used by Deque and its iterators to store chunks of data elements.
struct DequeBlockHeader struct DequeBlockHeader
{ {
DequeBlockHeader* pPrev; ///< Pointer to the previous block. DequeBlockHeader* pPrev; ///< Pointer to the previous block.
DequeBlockHeader* pNext; ///< Pointer to the next block. DequeBlockHeader* pNext; ///< Pointer to the next block.
void* pStart; ///< Pointer to the first element in this block. void* pStart; ///< Pointer to the first element in this block.
void* pEnd; ///< Pointer to the last element in this block. void* pEnd; ///< Pointer to the last element in this block.
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Iterator for traversal of elements in a Deque collection. * @brief Iterator for traversal of elements in a Deque collection.
* *
* Allows traversal of all elements in a Deque going either forwards or backwards. If you traverse off either end of * Allows traversal of all elements in a Deque going either forwards or backwards. If you traverse off either end of
* the deque, then you must create a new iterator by calling either the Deque's Begin() or End() method. * the deque, then you must create a new iterator by calling either the Deque's Begin() or End() method.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template<typename T, typename Allocator> template<typename T, typename Allocator>
class DequeIterator class DequeIterator
{ {
public: public:
/// Trivial destructor. /// Trivial destructor.
~DequeIterator() { } ~DequeIterator() { }
/// Returns a pointer to the current element. Will return null if we've gone past the end. /// Returns a pointer to the current element. Will return null if we've gone past the end.
T* Get() const { return m_pCurrent; } T* Get() const { return m_pCurrent; }
/// Advances the iterator to the next position (move forward). /// Advances the iterator to the next position (move forward).
void Next(); void Next();
/// Advances the iterator to the previous position (move backward). /// Advances the iterator to the previous position (move backward).
void Prev(); void Prev();
/// Check if the element the iterator references is valid. /// Check if the element the iterator references is valid.
bool IsValid() const { return m_pCurrent != nullptr; } bool IsValid() const { return m_pCurrent != nullptr; }
private: private:
DequeIterator(const Deque<T, Allocator>* pDeque, DequeBlockHeader* pHeader, T* pCurrent); DequeIterator(const Deque<T, Allocator>* pDeque, DequeBlockHeader* pHeader, T* pCurrent);
const Deque<T, Allocator>*const m_pDeque; // The Deque we're iterating over. const Deque<T, Allocator>*const m_pDeque; // The Deque we're iterating over.
const DequeBlockHeader* m_pCurrentHeader; // The block we're iterating over. const DequeBlockHeader* m_pCurrentHeader; // The block we're iterating over.
T* m_pCurrent; // Pointer to the current element. Null if we've gone past the T* m_pCurrent; // Pointer to the current element. Null if we've gone past the
// end. // end.
PAL_DISALLOW_DEFAULT_CTOR(DequeIterator); PAL_DISALLOW_DEFAULT_CTOR(DequeIterator);
// Although this is a transgression of coding standards, it means that Deque does not need to have a public // Although this is a transgression of coding standards, it means that Deque does not need to have a public
// interface specifically to implement this class. The added encapsulation this provides is worthwhile. // interface specifically to implement this class. The added encapsulation this provides is worthwhile.
friend class Deque<T, Allocator>; friend class Deque<T, Allocator>;
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Simple templated deque container - a double-ended queue. * @brief Simple templated deque container - a double-ended queue.
* *
* This is meant for storing elements of an arbitrary (but uniform) type. Operations which this class supports are: * This is meant for storing elements of an arbitrary (but uniform) type. Operations which this class supports are:
* *
* - Insertion from the front and back. * - Insertion from the front and back.
* - Deletion from the front and back. * - Deletion from the front and back.
* - Forwards and reverse iteration * - Forwards and reverse iteration
* *
* @warning This class is not thread-safe for push, pop, or iteration! * @warning This class is not thread-safe for push, pop, or iteration!
* *
* @note This class is only designed to work with native types and POD-style structures. If it is needed to have a Deque * @note This class is only designed to work with native types and POD-style structures. If it is needed to have a Deque
* of complex objects with nontrivial destructors, copy constructors or assign operators, then a specialized * of complex objects with nontrivial destructors, copy constructors or assign operators, then a specialized
* implementation of CleanupElement() will need to be explicitly defined. * implementation of CleanupElement() will need to be explicitly defined.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template<typename T, typename Allocator> template<typename T, typename Allocator>
class Deque class Deque
{ {
public: public:
/// Constructor. /// Constructor.
/// ///
/// @param [in] pAllocator The allocator that will allocate memory if required. /// @param [in] pAllocator The allocator that will allocate memory if required.
Deque(Allocator*const pAllocator, size_t numElementsPerBlock = 256); Deque(Allocator*const pAllocator, size_t numElementsPerBlock = 256);
~Deque(); ~Deque();
/// Returns the number of elements in the deque. /// Returns the number of elements in the deque.
size_t NumElements() const { return m_numElements; } size_t NumElements() const { return m_numElements; }
/// Returns an iterator pointing to the first element in the deque. /// Returns an iterator pointing to the first element in the deque.
/// ///
/// @returns An iterator pointing at the front end of the deque. /// @returns An iterator pointing at the front end of the deque.
DequeIterator<T, Allocator> Begin() const { return DequeIterator<T, Allocator>(this, m_pFrontHeader, m_pFront); } DequeIterator<T, Allocator> Begin() const { return DequeIterator<T, Allocator>(this, m_pFrontHeader, m_pFront); }
/// Returns an iterator pointing to the last element in the deque. /// Returns an iterator pointing to the last element in the deque.
/// ///
/// This is somewhat different from std::deque.End() which returns a pointer to the theoretical object _past_ the /// This is somewhat different from std::deque.End() which returns a pointer to the theoretical object _past_ the
/// end of the deque. /// end of the deque.
/// ///
/// @returns An iterator pointing at the back end of the deque. /// @returns An iterator pointing at the back end of the deque.
DequeIterator<T, Allocator> End() const { return DequeIterator<T, Allocator>(this, m_pBackHeader, m_pBack); } DequeIterator<T, Allocator> End() const { return DequeIterator<T, Allocator>(this, m_pBackHeader, m_pBack); }
///@{ ///@{
/// Returns the element at the location specified. /// Returns the element at the location specified.
/// ///
/// @warning Calling this function with an out-of-bounds index will cause an access violation! /// @warning Calling this function with an out-of-bounds index will cause an access violation!
/// ///
/// @param [in] index Integer location of the element needed. /// @param [in] index Integer location of the element needed.
/// ///
/// @returns The element at location specified by index by reference /// @returns The element at location specified by index by reference
T& At(uint32 index); T& At(uint32 index);
const T& At(uint32 index) const; const T& At(uint32 index) const;
T& operator[](uint32 index); T& operator[](uint32 index);
const T& operator[](uint32 index) const; const T& operator[](uint32 index) const;
///@} ///@}
/// Returns the object at the front of the deque. /// Returns the object at the front of the deque.
/// ///
/// @warning This will cause an access violation if called on an empty deque! /// @warning This will cause an access violation if called on an empty deque!
/// ///
/// @returns Reference to the item stored at the front end of the deque. /// @returns Reference to the item stored at the front end of the deque.
T& Front() const T& Front() const
{ {
PAL_ASSERT(m_numElements != 0); PAL_ASSERT(m_numElements != 0);
return *m_pFront; return *m_pFront;
} }
/// Returns the object at the tail of the deque. /// Returns the object at the tail of the deque.
/// ///
/// @warning This will cause an access violation if called on an empty deque! /// @warning This will cause an access violation if called on an empty deque!
/// ///
/// @returns Reference to the item stored at the back end of the deque. /// @returns Reference to the item stored at the back end of the deque.
T& Back() const T& Back() const
{ {
PAL_ASSERT(m_numElements != 0); PAL_ASSERT(m_numElements != 0);
return *m_pBack; return *m_pBack;
} }
/// Pushes a copy of the specified item onto the front of the deque. /// Pushes a copy of the specified item onto the front of the deque.
/// ///
/// @param [in] data Item to be added to the front of the deque. /// @param [in] data Item to be added to the front of the deque.
/// ///
/// @returns @ref Success if the item was successfully added to the deque or @ref ErrorOutOfMemory if the operation /// @returns @ref Success if the item was successfully added to the deque or @ref ErrorOutOfMemory if the operation
/// failed because of an internal failure to allocate system memory. /// failed because of an internal failure to allocate system memory.
Result PushFront(const T& data); Result PushFront(const T& data);
/// Emplaces a newly constructed item onto the front of the deque. /// Emplaces a newly constructed item onto the front of the deque.
/// ///
/// @param [in] args arguments used to construct the new item. /// @param [in] args arguments used to construct the new item.
/// ///
/// @returns @ref Success if the item was successfully added to the deque or @ref ErrorOutOfMemory if the operation /// @returns @ref Success if the item was successfully added to the deque or @ref ErrorOutOfMemory if the operation
/// failed because of an internal failure to allocate system memory. /// failed because of an internal failure to allocate system memory.
template<typename... Args> template<typename... Args>
Result EmplaceFront(Args&&... args); Result EmplaceFront(Args&&... args);
/// Pushes a copy of the specified item onto the back of the deque. /// Pushes a copy of the specified item onto the back of the deque.
/// ///
/// @param [in] data Item to be added to the back of the deque. /// @param [in] data Item to be added to the back of the deque.
/// ///
/// @returns @ref Success if the item was successfully added to the deque or @ref ErrorOutOfMemory if the operation /// @returns @ref Success if the item was successfully added to the deque or @ref ErrorOutOfMemory if the operation
/// failed because of an internal failure to allocate system memory. /// failed because of an internal failure to allocate system memory.
Result PushBack(const T& data); Result PushBack(const T& data);
/// Emplaces a newly constructed item onto the back of the deque. /// Emplaces a newly constructed item onto the back of the deque.
/// ///
/// @param [in] args arguments used to construct the new item. /// @param [in] args arguments used to construct the new item.
/// ///
/// @returns @ref Success if the item was successfully added to the deque or @ref ErrorOutOfMemory if the operation /// @returns @ref Success if the item was successfully added to the deque or @ref ErrorOutOfMemory if the operation
/// failed because of an internal failure to allocate system memory. /// failed because of an internal failure to allocate system memory.
template<typename... Args> template<typename... Args>
Result EmplaceBack(Args&&... args); Result EmplaceBack(Args&&... args);
/// Pops the first item off the front of the deque, returning the popped value. /// Pops the first item off the front of the deque, returning the popped value.
/// ///
/// @param [out] pOut Item popped off the front of the deque. /// @param [out] pOut Item popped off the front of the deque.
/// ///
/// @returns @ref Success if the item was successfully popped from the deque or @ref ErrorUnavailable if the deque /// @returns @ref Success if the item was successfully popped from the deque or @ref ErrorUnavailable if the deque
/// is empty. /// is empty.
Result PopFront(T* pOut); Result PopFront(T* pOut);
/// Pops the first item off the back of the deque, returning the popped value. /// Pops the first item off the back of the deque, returning the popped value.
/// ///
/// @param [out] pOut Item popped off the back of the deque. /// @param [out] pOut Item popped off the back of the deque.
/// ///
/// @returns @ref Success if the item was successfully popped from the deque or @ref ErrorUnavailable if the deque /// @returns @ref Success if the item was successfully popped from the deque or @ref ErrorUnavailable if the deque
/// is empty. /// is empty.
Result PopBack(T* pOut); Result PopBack(T* pOut);
private: private:
Result AllocateFront(T**); Result AllocateFront(T**);
Result AllocateBack(T**); Result AllocateBack(T**);
DequeBlockHeader* AllocateNewBlock(); DequeBlockHeader* AllocateNewBlock();
void FreeUnusedBlock(DequeBlockHeader* pHeader); void FreeUnusedBlock(DequeBlockHeader* pHeader);
// A helper function to avoid duplication in const and non-const versions of At(). // A helper function to avoid duplication in const and non-const versions of At().
T& InternalAt(uint32 index) const; T& InternalAt(uint32 index) const;
size_t m_numElements; // Number of elements size_t m_numElements; // Number of elements
const size_t m_numElementsPerBlock; // Block granularity when we need to alloc a new one const size_t m_numElementsPerBlock; // Block granularity when we need to alloc a new one
DequeBlockHeader* m_pFrontHeader; // First block of data elements, null for empty deques. DequeBlockHeader* m_pFrontHeader; // First block of data elements, null for empty deques.
DequeBlockHeader* m_pBackHeader; // Last block of data elements, null for empty deques/ DequeBlockHeader* m_pBackHeader; // Last block of data elements, null for empty deques/
T* m_pFront; // First data element, null for empty deques. T* m_pFront; // First data element, null for empty deques.
T* m_pBack; // Last data element, null for empty deques. T* m_pBack; // Last data element, null for empty deques.
DequeBlockHeader* m_pLazyFreeHeader; // Cached pointer to the most-recently freed block. DequeBlockHeader* m_pLazyFreeHeader; // Cached pointer to the most-recently freed block.
Allocator*const m_pAllocator; // Pointer to the allocator for this deque. Allocator*const m_pAllocator; // Pointer to the allocator for this deque.
PAL_DISALLOW_COPY_AND_ASSIGN(Deque); PAL_DISALLOW_COPY_AND_ASSIGN(Deque);
// Although this is a transgression of coding standards, it prevents DequeIterator requiring a public constructor; // Although this is a transgression of coding standards, it prevents DequeIterator requiring a public constructor;
// constructing a 'bare' DequeIterator (i.e. without calling Deque::GetIterator) can never be a legal operation, so // constructing a 'bare' DequeIterator (i.e. without calling Deque::GetIterator) can never be a legal operation, so
// this means that these two classes are much safer to use. // this means that these two classes are much safer to use.
friend class DequeIterator<T, Allocator>; friend class DequeIterator<T, Allocator>;
}; };
// ===================================================================================================================== // =====================================================================================================================
template<typename T, typename Allocator> template<typename T, typename Allocator>
Deque<T, Allocator>::Deque( Deque<T, Allocator>::Deque(
Allocator*const pAllocator, Allocator*const pAllocator,
size_t numElementsPerBlock) size_t numElementsPerBlock)
: :
m_numElements(0), m_numElements(0),
m_numElementsPerBlock(numElementsPerBlock), m_numElementsPerBlock(numElementsPerBlock),
m_pFrontHeader(nullptr), m_pFrontHeader(nullptr),
m_pBackHeader(nullptr), m_pBackHeader(nullptr),
m_pFront(nullptr), m_pFront(nullptr),
m_pBack(nullptr), m_pBack(nullptr),
m_pLazyFreeHeader(nullptr), m_pLazyFreeHeader(nullptr),
m_pAllocator(pAllocator) m_pAllocator(pAllocator)
{ {
} }
// ===================================================================================================================== // =====================================================================================================================
// Frees all of the blocks this object allocated over its lifetime. // Frees all of the blocks this object allocated over its lifetime.
template<typename T, typename Allocator> template<typename T, typename Allocator>
Deque<T, Allocator>::~Deque() Deque<T, Allocator>::~Deque()
{ {
if (!std::is_trivial<T>::value) if (!std::is_trivial<T>::value)
{ {
while (m_pFrontHeader != nullptr) while (m_pFrontHeader != nullptr)
{ {
// Explicitly destroy the removed value since it's non-trivial and advance. // Explicitly destroy the removed value since it's non-trivial and advance.
// We must destroy all of them in the current block before freeing it. // We must destroy all of them in the current block before freeing it.
m_pFront->~T(); m_pFront->~T();
++m_pFront; ++m_pFront;
--m_numElements; --m_numElements;
if ((m_pFront == m_pFrontHeader->pEnd) || (m_numElements == 0)) if ((m_pFront == m_pFrontHeader->pEnd) || (m_numElements == 0))
{ {
// Okay, the front block is now empty. Free it and advance to the next block. // Okay, the front block is now empty. Free it and advance to the next block.
DequeBlockHeader* pBlockToFree = m_pFrontHeader; DequeBlockHeader* pBlockToFree = m_pFrontHeader;
m_pFrontHeader = m_pFrontHeader->pNext; m_pFrontHeader = m_pFrontHeader->pNext;
PAL_SAFE_FREE(pBlockToFree, m_pAllocator); PAL_SAFE_FREE(pBlockToFree, m_pAllocator);
if (m_pFrontHeader != nullptr) if (m_pFrontHeader != nullptr)
{ {
// Fixup to the new block. // Fixup to the new block.
m_pFront = static_cast<T*>(m_pFrontHeader->pStart); m_pFront = static_cast<T*>(m_pFrontHeader->pStart);
} }
} }
} }
} }
else else
{ {
// Elements are trivial so skip iterating through elements and free each block. // Elements are trivial so skip iterating through elements and free each block.
while (m_pFrontHeader != nullptr) while (m_pFrontHeader != nullptr)
{ {
DequeBlockHeader* pBlockToFree = m_pFrontHeader; DequeBlockHeader* pBlockToFree = m_pFrontHeader;
m_pFrontHeader = m_pFrontHeader->pNext; m_pFrontHeader = m_pFrontHeader->pNext;
PAL_SAFE_FREE(pBlockToFree, m_pAllocator); PAL_SAFE_FREE(pBlockToFree, m_pAllocator);
} }
} }
if (m_pLazyFreeHeader != nullptr) if (m_pLazyFreeHeader != nullptr)
{ {
PAL_SAFE_FREE(m_pLazyFreeHeader, m_pAllocator); PAL_SAFE_FREE(m_pLazyFreeHeader, m_pAllocator);
} }
} }
} // Util } // Util
+141 -141
파일 보기
@@ -1,141 +1,141 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palEvent.h * @file palEvent.h
* @brief PAL utility collection Event class declaration. * @brief PAL utility collection Event class declaration.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palTime.h" #include "palTime.h"
#include "palUtil.h" #include "palUtil.h"
namespace Util namespace Util
{ {
/// Specifies the flags for event. /// Specifies the flags for event.
struct EventCreateFlags struct EventCreateFlags
{ {
union union
{ {
struct struct
{ {
uint32 manualReset : 1; ///< If true, the event is created as manual reset. uint32 manualReset : 1; ///< If true, the event is created as manual reset.
uint32 initiallySignaled : 1; ///< If true, the event is created in signaled state. uint32 initiallySignaled : 1; ///< If true, the event is created in signaled state.
#if defined(_WIN32) #if defined(_WIN32)
uint32 canBeInherited : 1; ///< If true, the event can be inherited by child process, it's uint32 canBeInherited : 1; ///< If true, the event can be inherited by child process, it's
/// Windows-specific. /// Windows-specific.
uint32 reserved : 29; ///< Reserved for future use. uint32 reserved : 29; ///< Reserved for future use.
#else #else
uint32 semaphore : 1; ///< If true, provide semaphore-like semantics for reads from the file uint32 semaphore : 1; ///< If true, provide semaphore-like semantics for reads from the file
/// descriptor. /// descriptor.
uint32 nonBlocking : 1; ///< If true, set the O_NONBLOCK file status flag on the new file descriptor. uint32 nonBlocking : 1; ///< If true, set the O_NONBLOCK file status flag on the new file descriptor.
uint32 closeOnExecute : 1; ///< If true, set the close-on-exec flag for the new file descriptor. uint32 closeOnExecute : 1; ///< If true, set the close-on-exec flag for the new file descriptor.
uint32 reserved : 27; ///< Reserved for future use. uint32 reserved : 27; ///< Reserved for future use.
#endif #endif
}; };
uint32 u32All; ///< Flags packed as 32-bit uint. uint32 u32All; ///< Flags packed as 32-bit uint.
}; };
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Synchronization primitive that can either be in the _set_ or _reset_ state. * @brief Synchronization primitive that can either be in the _set_ or _reset_ state.
* *
* Threads can call WaitForEvents() to block waiting for an Event object to be _set_. This is useful for fine-grain * Threads can call WaitForEvents() to block waiting for an Event object to be _set_. This is useful for fine-grain
* synchronization between threads. * synchronization between threads.
* *
* Event objects start out in the _reset_ state. * Event objects start out in the _reset_ state.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class Event class Event
{ {
public: public:
Event(); Event();
~Event(); ~Event();
/// Initializes the event object. Clients must call this before using the Event object. /// Initializes the event object. Clients must call this before using the Event object.
/// ///
/// @param flags Event creation flags. /// @param flags Event creation flags.
/// @param pName Specified the event's name, it's Windows-specific, Windows uses this name to /// @param pName Specified the event's name, it's Windows-specific, Windows uses this name to
/// uniquely identify fence objects across processes. /// uniquely identify fence objects across processes.
/// @returns Success if the event was successfully initialized, otherwise an appropriate error code. /// @returns Success if the event was successfully initialized, otherwise an appropriate error code.
Result Init( Result Init(
const EventCreateFlags& flags const EventCreateFlags& flags
#if defined(_WIN32) #if defined(_WIN32)
, ,
const wchar_t* pName = nullptr const wchar_t* pName = nullptr
#endif #endif
); );
/// Changes the event state to _set_ /// Changes the event state to _set_
/// ///
/// @returns Success unless the Event has not been initialized yet (@ref ErrorUnavailable) or an unexpected internal /// @returns Success unless the Event has not been initialized yet (@ref ErrorUnavailable) or an unexpected internal
/// error occured when calling the OS (ErrorUnknown). /// error occured when calling the OS (ErrorUnknown).
Result Set() const; Result Set() const;
/// Changes the event state to _reset_. /// Changes the event state to _reset_.
/// ///
/// @returns Success unless the Event has not been initialized yet (ErrorUnavailable) or an unexpected /// @returns Success unless the Event has not been initialized yet (ErrorUnavailable) or an unexpected
/// internal error occured when calling the OS (ErrorUnknown). /// internal error occured when calling the OS (ErrorUnknown).
Result Reset() const; Result Reset() const;
/// Waits for the event to enter the _set_ state before returning control to the caller. The event will change to /// Waits for the event to enter the _set_ state before returning control to the caller. The event will change to
/// the _reset_ state if manualReset was false on initialization. /// the _reset_ state if manualReset was false on initialization.
/// ///
/// @param [in] timeout Max time to wait, in seconds. If zero, this call will poll the event without blocking. /// @param [in] timeout Max time to wait, in seconds. If zero, this call will poll the event without blocking.
/// ///
/// @returns Success if the wait completed successfully or Timeout if the wait did not complete but the operation /// @returns Success if the wait completed successfully or Timeout if the wait did not complete but the operation
/// timed out. Otherwise, one of the following errors may be returned: /// timed out. Otherwise, one of the following errors may be returned:
/// + ErrorInvalidValue will be returned if the timeout is negative. /// + ErrorInvalidValue will be returned if the timeout is negative.
/// + ErrorUnknown may be returned if an unexpected internal occurs when calling the OS. /// + ErrorUnknown may be returned if an unexpected internal occurs when calling the OS.
Result Wait(fseconds timeout) const; Result Wait(fseconds timeout) const;
#if defined(_WIN32) #if defined(_WIN32)
/// On Windows, a handle to an OS event primitive is a HANDLE, which is just a void*. /// On Windows, a handle to an OS event primitive is a HANDLE, which is just a void*.
typedef void* EventHandle; typedef void* EventHandle;
#else #else
/// On Linux, a handle to an OS event primitive is a file descriptor, which is just an int. /// On Linux, a handle to an OS event primitive is a file descriptor, which is just an int.
typedef int32 EventHandle; typedef int32 EventHandle;
#endif #endif
/// Returns a handle to the actual OS event primitive associated with this object. /// Returns a handle to the actual OS event primitive associated with this object.
EventHandle GetHandle() const { return m_hEvent; } EventHandle GetHandle() const { return m_hEvent; }
/// Open event handle. /// Open event handle.
Result Open(EventHandle handle, bool isReference); Result Open(EventHandle handle, bool isReference);
/// Constant EventHandle value which represents an invalid event object. /// Constant EventHandle value which represents an invalid event object.
static const EventHandle InvalidEvent; static const EventHandle InvalidEvent;
private: private:
EventHandle m_hEvent; // OS-specific event handle. EventHandle m_hEvent; // OS-specific event handle.
bool m_isReference; // If true, the event is a global sharing object handle (not a duplicate) which is bool m_isReference; // If true, the event is a global sharing object handle (not a duplicate) which is
// imported from external, so it can't be closed in the currect destructor, and can only // imported from external, so it can't be closed in the currect destructor, and can only
// be closed by the creater. // be closed by the creater.
PAL_DISALLOW_COPY_AND_ASSIGN(Event); PAL_DISALLOW_COPY_AND_ASSIGN(Event);
}; };
} // Util } // Util
+300 -300
파일 보기
@@ -1,300 +1,300 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palFile.h * @file palFile.h
* @brief PAL utility collection File class declaration. * @brief PAL utility collection File class declaration.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
// pal // pal
#include "palUtil.h" #include "palUtil.h"
#include "palInlineFuncs.h" #include "palInlineFuncs.h"
// stl // stl
#include <chrono> #include <chrono>
#include <cstdio> #include <cstdio>
#if defined(_WIN32) #if defined(_WIN32)
/// Macro for wide string literal concatenation. /// Macro for wide string literal concatenation.
#define PAL_PATH_SEPW L"\\" #define PAL_PATH_SEPW L"\\"
/// Macro for narrow string literal concatenation. /// Macro for narrow string literal concatenation.
#define PAL_PATH_SEP "\\" #define PAL_PATH_SEP "\\"
#else #else
/// Macro for wide string literal concatenation. /// Macro for wide string literal concatenation.
#define PAL_PATH_SEPW L"/" #define PAL_PATH_SEPW L"/"
/// Macro for narrow string literal concatenation. /// Macro for narrow string literal concatenation.
#define PAL_PATH_SEP "/" #define PAL_PATH_SEP "/"
#endif #endif
namespace Util namespace Util
{ {
#if defined(_WIN32) #if defined(_WIN32)
/// Wide-character of the platform's prefered path separator. /// Wide-character of the platform's prefered path separator.
static constexpr wchar_t PathSepW = L'\\'; static constexpr wchar_t PathSepW = L'\\';
/// Narrow-character of the platform's prefered path separator. /// Narrow-character of the platform's prefered path separator.
static constexpr char PathSep = '\\'; static constexpr char PathSep = '\\';
#else #else
/// Wide-character of the platform's prefered path separator. /// Wide-character of the platform's prefered path separator.
static constexpr wchar_t PathSepW = L'/'; static constexpr wchar_t PathSepW = L'/';
/// Narrow-character of the platform's prefered path separator. /// Narrow-character of the platform's prefered path separator.
static constexpr char PathSep = '/'; static constexpr char PathSep = '/';
#endif #endif
static constexpr uint32 MaxPathStrLen = 512; static constexpr uint32 MaxPathStrLen = 512;
static constexpr uint32 MaxFileNameStrLen = 256; static constexpr uint32 MaxFileNameStrLen = 256;
/// Enumerates access modes that may be required on an opened file. /// Enumerates access modes that may be required on an opened file.
/// Can be bitwise ORed together to specify multiple simultaneous modes. /// Can be bitwise ORed together to specify multiple simultaneous modes.
enum FileAccessMode : uint32 enum FileAccessMode : uint32
{ {
FileAccessRead = 0x1, ///< Read access. FileAccessRead = 0x1, ///< Read access.
FileAccessWrite = 0x2, ///< Write access. FileAccessWrite = 0x2, ///< Write access.
FileAccessAppend = 0x4, ///< Append access. FileAccessAppend = 0x4, ///< Append access.
FileAccessBinary = 0x8, ///< Binary access. FileAccessBinary = 0x8, ///< Binary access.
FileAccessNoDiscard = 0x10, ///< Don't discard existing file. FileAccessNoDiscard = 0x10, ///< Don't discard existing file.
FileAccessShared = 0x20, ///< Require shared file access (simultaneous reading/writing by more than one process) FileAccessShared = 0x20, ///< Require shared file access (simultaneous reading/writing by more than one process)
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Exposes simple file I/O functionality by encapsulating standard C runtime file I/O functions like fopen, * @brief Exposes simple file I/O functionality by encapsulating standard C runtime file I/O functions like fopen,
* fwrite, etc. * fwrite, etc.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class File class File
{ {
public: public:
// Platform-agnostic 64-bit stat structure. // Platform-agnostic 64-bit stat structure.
struct Stat struct Stat
{ {
uint64 size; // Size of the file in bytes. uint64 size; // Size of the file in bytes.
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 922 #if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 922
uint64 ctime; // Time of creation of the file (not valid on FAT). uint64 ctime; // Time of creation of the file (not valid on FAT).
uint64 atime; // Time of last access to the file (not valid on FAT). uint64 atime; // Time of last access to the file (not valid on FAT).
uint64 mtime; // Time of last modification to the file. uint64 mtime; // Time of last modification to the file.
#else #else
std::chrono::system_clock::time_point ctime; // Time of creation of the file (not valid on FAT). std::chrono::system_clock::time_point ctime; // Time of creation of the file (not valid on FAT).
std::chrono::system_clock::time_point atime; // Time of last access to the file (not valid on FAT). std::chrono::system_clock::time_point atime; // Time of last access to the file (not valid on FAT).
std::chrono::system_clock::time_point mtime; // Time of last modification to the file. std::chrono::system_clock::time_point mtime; // Time of last modification to the file.
#endif #endif
uint32 nlink; // Number of hard links (always 1 on FAT on Windows). uint32 nlink; // Number of hard links (always 1 on FAT on Windows).
uint32 mode; // Bitmask for the file-mode information. uint32 mode; // Bitmask for the file-mode information.
uint32 dev; // Drive number of the disk containing the file. uint32 dev; // Drive number of the disk containing the file.
union union
{ {
struct struct
{ {
uint32 isDir : 1; uint32 isDir : 1;
uint32 isRegular : 1; uint32 isRegular : 1;
uint32 reserved : 30; uint32 reserved : 30;
}; };
uint32 u32All; uint32 u32All;
} flags; } flags;
// Common stat members omitted from this structure: // Common stat members omitted from this structure:
// uid, gid, and ino because it's not used on Windows // uid, gid, and ino because it's not used on Windows
// rdev because it's a duplicate of dev // rdev because it's a duplicate of dev
}; };
// Where in the file to start seeking from. // Where in the file to start seeking from.
enum class SeekPosition : int32 enum class SeekPosition : int32
{ {
// start of the file // start of the file
Start = SEEK_SET, Start = SEEK_SET,
// current file pointer position // current file pointer position
Current = SEEK_CUR, Current = SEEK_CUR,
// end of the file // end of the file
End = SEEK_END End = SEEK_END
}; };
File() : m_pFileHandle(nullptr), m_ownsHandle(false) {} File() : m_pFileHandle(nullptr), m_ownsHandle(false) {}
/// Closes the file if it is still open. /// Closes the file if it is still open.
~File() { Close(); } ~File() { Close(); }
/// Opens a file stream for read, write or append access. /// Opens a file stream for read, write or append access.
/// ///
/// @param [in] pFilename Name of file to open. /// @param [in] pFilename Name of file to open.
/// @param [in] accessFlags Bitmask of FileAccessMode values indicating the usage of the file. /// @param [in] accessFlags Bitmask of FileAccessMode values indicating the usage of the file.
/// ///
/// @returns Success if successful, otherwise an appropriate error. /// @returns Success if successful, otherwise an appropriate error.
Result Open(const char* pFilename, uint32 accessFlags); Result Open(const char* pFilename, uint32 accessFlags);
/// Borrows an externally opened C runtime file handle for use by a File object. /// Borrows an externally opened C runtime file handle for use by a File object.
/// ///
/// The caller is still responsible for closing this handle after the File object is destroyed. /// The caller is still responsible for closing this handle after the File object is destroyed.
/// ///
/// @param [in] pFile Externally opened C runtime file handle to borrow. /// @param [in] pFile Externally opened C runtime file handle to borrow.
/// ///
/// @returns Success if successful, otherwise an appropriate error. /// @returns Success if successful, otherwise an appropriate error.
Result FromNative(std::FILE* pFile); Result FromNative(std::FILE* pFile);
/// Closes the file handle. /// Closes the file handle.
void Close(); void Close();
/// Writes a stream of bytes to the file. /// Writes a stream of bytes to the file.
/// ///
/// @param [in] pBuffer Byte stream to be written to the file. /// @param [in] pBuffer Byte stream to be written to the file.
/// @param [in] bufferSize Number of bytes to write. /// @param [in] bufferSize Number of bytes to write.
/// ///
/// @returns Success if successful, otherwise an appropriate error. /// @returns Success if successful, otherwise an appropriate error.
Result Write(const void* pBuffer, size_t bufferSize); Result Write(const void* pBuffer, size_t bufferSize);
/// Reads a stream of bytes from the file. /// Reads a stream of bytes from the file.
/// ///
/// @param [out] pBuffer Buffer to be written with data read from file. /// @param [out] pBuffer Buffer to be written with data read from file.
/// @param [in] bufferSize Size of the output buffer. /// @param [in] bufferSize Size of the output buffer.
/// @param [out] pBytesRead Number of bytes actually read (can be null). /// @param [out] pBytesRead Number of bytes actually read (can be null).
/// ///
/// @returns Success if successful, otherwise an appropriate error. /// @returns Success if successful, otherwise an appropriate error.
Result Read(void* pBuffer, size_t bufferSize, size_t* pBytesRead); Result Read(void* pBuffer, size_t bufferSize, size_t* pBytesRead);
/// Reads a single line of bytes from the file. /// Reads a single line of bytes from the file.
/// ///
/// @param [out] pBuffer Buffer to be written with data read from file. /// @param [out] pBuffer Buffer to be written with data read from file.
/// @param [in] bufferSize Size of the output buffer. /// @param [in] bufferSize Size of the output buffer.
/// @param [out] pBytesRead Number of bytes actually read (can be null). /// @param [out] pBytesRead Number of bytes actually read (can be null).
/// ///
/// @returns Success if successful, otherwise an appropriate error. /// @returns Success if successful, otherwise an appropriate error.
Result ReadLine(void* pBuffer, size_t bufferSize, size_t* pBytesRead); Result ReadLine(void* pBuffer, size_t bufferSize, size_t* pBytesRead);
/// Prints a formatted string to the file. /// Prints a formatted string to the file.
/// ///
/// @param [in] pFormatStr Printf-style format string. /// @param [in] pFormatStr Printf-style format string.
/// ///
/// @returns Success if successful, otherwise an appropriate error. /// @returns Success if successful, otherwise an appropriate error.
Result Printf(const char* pFormatStr, ...) const; Result Printf(const char* pFormatStr, ...) const;
/// Prints a formatted string to the file. /// Prints a formatted string to the file.
/// ///
/// @param [in] pFormatStr Printf-style format string. /// @param [in] pFormatStr Printf-style format string.
/// @param [in] argList Variable argument list. /// @param [in] argList Variable argument list.
/// ///
/// @returns Success if successful, otherwise an appropriate error. /// @returns Success if successful, otherwise an appropriate error.
Result VPrintf(const char* pFormatStr, va_list argList); Result VPrintf(const char* pFormatStr, va_list argList);
/// Flushes pending I/O to the file. /// Flushes pending I/O to the file.
/// ///
/// @returns Success if successful, otherwise an appropriate error. /// @returns Success if successful, otherwise an appropriate error.
Result Flush() const; Result Flush() const;
/// Sets the file position to the beginning of the file. /// Sets the file position to the beginning of the file.
void Rewind(); void Rewind();
/// Sets the position indicator to a new position. /// Sets the position indicator to a new position.
/// ///
/// @param offset Number of bytes to offset /// @param offset Number of bytes to offset
/// @param pos File position to seek from /// @param pos File position to seek from
void Seek(int64 offset, SeekPosition pos); void Seek(int64 offset, SeekPosition pos);
/// Sets the position indicator to a new position relative to the beginning of the file. /// Sets the position indicator to a new position relative to the beginning of the file.
/// ///
/// @param offset Number of bytes to offset /// @param offset Number of bytes to offset
void Seek(size_t offset) { Seek(offset, SeekPosition::Start); } void Seek(size_t offset) { Seek(offset, SeekPosition::Start); }
/// Sets the position indicator to a new position relative to the end of the file /// Sets the position indicator to a new position relative to the end of the file
/// ///
/// @param offset Number of bytes to offset /// @param offset Number of bytes to offset
void Rseek(size_t offset) { Seek(-static_cast<int64>(offset), SeekPosition::End); } void Rseek(size_t offset) { Seek(-static_cast<int64>(offset), SeekPosition::End); }
/// Sets the file position to the end of the file. /// Sets the file position to the end of the file.
void FastForward() { Rseek(0); } void FastForward() { Rseek(0); }
/// Returns true if the file is presently open. /// Returns true if the file is presently open.
bool IsOpen() const { return (m_pFileHandle != nullptr); } bool IsOpen() const { return (m_pFileHandle != nullptr); }
/// Gets the size of the file contents in bytes /// Gets the size of the file contents in bytes
/// ///
/// @param [in] pFilename Name of the file to check. /// @param [in] pFilename Name of the file to check.
/// ///
/// @returns Size of the file in bytes, or std::numeric_limits<size_t>::max() on failure. /// @returns Size of the file in bytes, or std::numeric_limits<size_t>::max() on failure.
static size_t GetFileSize(const char* pFilename); static size_t GetFileSize(const char* pFilename);
/// Checks if a file with the specified name exists. /// Checks if a file with the specified name exists.
/// ///
/// @param [in] pFilename Name of the file to check. /// @param [in] pFilename Name of the file to check.
/// ///
/// @returns True if the specified file exists. /// @returns True if the specified file exists.
static bool Exists(const char* pFilename); static bool Exists(const char* pFilename);
/// Platform-agnostic 64-bit stat() function. /// Platform-agnostic 64-bit stat() function.
/// ///
/// @param [in] pFilename Name of the file to check. /// @param [in] pFilename Name of the file to check.
/// @param [out] pStatus The status of that file, if it exists. /// @param [out] pStatus The status of that file, if it exists.
/// ///
/// @returns Success if the structure was retrieved, error otherwise. /// @returns Success if the structure was retrieved, error otherwise.
static Result GetStat(const char* pFilename, Stat* pStatus); static Result GetStat(const char* pFilename, Stat* pStatus);
/// Removes/erases a file, if it exists. /// Removes/erases a file, if it exists.
/// ///
/// @param [in] pFilename Name of file to remove. /// @param [in] pFilename Name of file to remove.
/// ///
/// @returns Success if successful, otherwise an appropriate error. /// @returns Success if successful, otherwise an appropriate error.
static Result Remove(const char* pFilename); static Result Remove(const char* pFilename);
/// Reads a file into memory. /// Reads a file into memory.
/// ///
/// @param [in] pFilename Name of the file to read. /// @param [in] pFilename Name of the file to read.
/// @param [in] pData Buffer where the file contents are written to. /// @param [in] pData Buffer where the file contents are written to.
/// @param [in] dataSize Size of the buffer in bytes. /// @param [in] dataSize Size of the buffer in bytes.
/// @param [out] pBytesRead Number of bytes successfully read into the input buffer (can be null). /// @param [out] pBytesRead Number of bytes successfully read into the input buffer (can be null).
/// @param [in] binary True for binary mode, false for text. Defaults to binary. /// @param [in] binary True for binary mode, false for text. Defaults to binary.
/// ///
/// @returns Success if successful, otherwise an appropriate error. /// @returns Success if successful, otherwise an appropriate error.
/// ///
/// @note The input buffer must be large enough to hold the file's contents. If the buffer is larger than the file, /// @note The input buffer must be large enough to hold the file's contents. If the buffer is larger than the file,
/// then the region of the buffer beyond the file size is _not_ modified by this function. It is the caller's /// then the region of the buffer beyond the file size is _not_ modified by this function. It is the caller's
/// responsibility to _not_ read uninitialized portions of the supplied buffer after this call returns. /// responsibility to _not_ read uninitialized portions of the supplied buffer after this call returns.
/// ///
/// @note In binary mode, the number of bytes read is equal to the file size in bytes upon a successful return. /// @note In binary mode, the number of bytes read is equal to the file size in bytes upon a successful return.
/// In text mode, newline conversion is performed on Windows, in which case the number of bytes read may not equal /// In text mode, newline conversion is performed on Windows, in which case the number of bytes read may not equal
/// the file size in bytes. /// the file size in bytes.
/// ///
/// @note In text mode, should the caller treat the resulting data as a C string, it is the caller's responsibility /// @note In text mode, should the caller treat the resulting data as a C string, it is the caller's responsibility
/// to null-terminate the buffer. /// to null-terminate the buffer.
static Result ReadFile( static Result ReadFile(
const char* pFilename, const char* pFilename,
void* pData, void* pData,
size_t dataSize, size_t dataSize,
size_t* pBytesRead = nullptr, size_t* pBytesRead = nullptr,
bool binary = true); bool binary = true);
/// Gets the handle associated with this file. /// Gets the handle associated with this file.
/// ///
/// @returns A pointer to the file handle /// @returns A pointer to the file handle
const std::FILE* GetHandle() const { return m_pFileHandle; } const std::FILE* GetHandle() const { return m_pFileHandle; }
private: private:
std::FILE* m_pFileHandle; std::FILE* m_pFileHandle;
bool m_ownsHandle; // This object owns the file handle and will close it on destruction. bool m_ownsHandle; // This object owns the file handle and will close it on destruction.
PAL_DISALLOW_COPY_AND_ASSIGN(File); PAL_DISALLOW_COPY_AND_ASSIGN(File);
}; };
} // Util } // Util
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+137 -143
파일 보기
@@ -1,143 +1,137 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palHashMap.h * @file palHashMap.h
* @brief PAL utility collection HashMap class declaration. * @brief PAL utility collection HashMap class declaration.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palHashBase.h" #include "palHashBase.h"
namespace Util namespace Util
{ {
/// Encapsulates one key/value pair in a hash map. /// Encapsulates one key/value pair in a hash map.
template<typename Key, typename Value> template<typename Key, typename Value>
struct HashMapEntry struct HashMapEntry
{ {
Key key; ///< Hash map entry key. Key key; ///< Hash map entry key.
Value value; ///< Hash map entry value. Value value; ///< Hash map entry value.
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Templated hash map container. * @brief Templated hash map container.
* *
* This container is meant for storing elements of an arbitrary (but uniform) key/value type. Supported operations: * This container is meant for storing elements of an arbitrary (but uniform) key/value type. Supported operations:
* *
* - Searching * - Searching
* - Insertion * - Insertion
* - Deletion * - Deletion
* - Iteration * - Iteration
* *
* HashFunc is a functor for hashing keys. Built-in choices for HashFunc are: * HashFunc is a functor for hashing keys. Built-in choices for HashFunc are:
* *
* - DefaultHashFunc: Good choice when the key is a pointer. * - DefaultHashFunc: Default hash function, selects best hash function based on type of key.
* - JenkinsHashFunc: Good choice when the key is arbitrary binary data. * - PointerHashFunc: Good choice when the key is a pointer.
* - StringJenkinsHashFunc: Good choice when the key is a C-style string. * - JenkinsHashFunc: Good choice when the key is arbitrary binary data.
* * - StringJenkinsHashFunc: Good choice when the key is a C-style string.
* EqualFunc is a functor for comparing keys. Built-in choices for EqualFunc are: *
* * EqualFunc is a functor for comparing keys. Built-in choices for EqualFunc are:
* - DefaultEqualFunc: Determines keys are equal by bitwise comparison. *
* - StringEqualFunc: Treats keys as a char* and compares them as C-style strings. * - DefaultEqualFunc: Determines keys are equal by bitwise comparison.
* * - StringEqualFunc: Treats keys as a char* and compares them as C-style strings.
* @warning This class is not thread-safe for Insert, FindAllocate, Erase, or iteration! *
* @warning Init() must be called before using this container. Begin() and Reset() can be safely called before * @warning This class is not thread-safe for Insert, FindAllocate, Erase, or iteration!
* initialization and Begin() will always return an iterator that points to null. * @warning Init() must be called before using this container. Begin() and Reset() can be safely called before
* * initialization and Begin() will always return an iterator that points to null.
* For more details please refer to @ref HashBase. *
*********************************************************************************************************************** * For more details please refer to @ref HashBase.
*/ ***********************************************************************************************************************
template<typename Key, */
typename Value, template<typename Key,
typename Allocator, typename Value,
template<typename> class HashFunc = DefaultHashFunc, typename Allocator,
template<typename> class EqualFunc = DefaultEqualFunc, template<typename> class HashFunc = DefaultHashFunc,
typename AllocFunc = HashAllocator<Allocator>, template<typename> class EqualFunc = DefaultEqualFunc,
size_t GroupSize = PAL_CACHE_LINE_BYTES * 2> typename AllocFunc = HashAllocator<Allocator>,
class HashMap : public HashBase<Key, HashMapEntry<Key, Value>, Allocator, HashFunc<Key>, EqualFunc<Key>, AllocFunc, GroupSize> size_t GroupSize = PAL_CACHE_LINE_BYTES * 2>
{ class HashMap : public HashBase<Key, HashMapEntry<Key, Value>, Allocator, HashFunc<Key>, EqualFunc<Key>, AllocFunc, GroupSize>
public: {
/// Convenience typedef for a templated entry of this hash map. public:
typedef HashMapEntry<Key, Value> Entry; /// Convenience typedef for a templated entry of this hash map.
typedef HashMapEntry<Key, Value> Entry;
/// @internal Constructor
/// /// @internal Constructor
/// @param [in] numBuckets Number of buckets to allocate for this hash container. The initial hash container will ///
/// take (buckets * GroupSize) bytes. /// @param [in] numBuckets Number of buckets to allocate for this hash container. The initial hash container will
/// @param [in] pAllocator Pointer to an allocator that will create system memory requested by this hash container. /// take (buckets * GroupSize) bytes.
explicit HashMap(uint32 numBuckets, Allocator*const pAllocator): Base::HashBase(numBuckets, pAllocator) { } /// @param [in] pAllocator Pointer to an allocator that will create system memory requested by this hash container.
virtual ~HashMap() { } explicit HashMap(uint32 numBuckets, Allocator*const pAllocator): Base::HashBase(numBuckets, pAllocator) { }
~HashMap() { }
/// Finds a given entry; if no entry was found, allocate it.
/// /// Finds a given entry; if no entry was found, allocate it.
/// @param [in] key Key to search for. ///
/// @param [out] pExisted True if an entry for the specified key existed before this call was made. False indicates /// @param [in] key Key to search for.
/// that a new entry was allocated as a result of this call. /// @param [out] pExisted True if an entry for the specified key existed before this call was made. False indicates
/// @param [out] ppValue Readable/writeable value in the hash map corresponding to the specified key. /// that a new entry was allocated as a result of this call.
/// /// @param [out] ppValue Readable/writeable value in the hash map corresponding to the specified key.
/// @returns @ref Success if the operation completed successfully, or @ref ErrorOutOfMemory if the operation failed ///
/// because an internal memory allocation failed. /// @returns @ref Success if the operation completed successfully, or @ref ErrorOutOfMemory if the operation failed
Result FindAllocate(const Key& key, bool* pExisted, Value** ppValue); /// because an internal memory allocation failed.
Result FindAllocate(const Key& key, bool* pExisted, Value** ppValue);
/// Gets a pointer to the value that matches the specified key.
/// /// Gets a pointer to the value that matches the specified key.
/// @param [in] key Key to search for. ///
/// /// @param [in] key Key to search for.
/// @returns A pointer to the value that matches the specified key or null if an entry for the key does not exist. ///
Value* FindKey(const Key& key) const; /// @returns A pointer to the value that matches the specified key or null if an entry for the key does not exist.
Value* FindKey(const Key& key) const;
/// Inserts a key/value pair entry if the key doesn't already exist in the hash map.
/// /// Inserts a key/value pair entry if the key doesn't already exist in the hash map.
/// @warning No action will be taken if an entry matching this key already exists, even if the specified value ///
/// differs from the current value stored in the entry matching the specified key. /// @warning No action will be taken if an entry matching this key already exists, even if the specified value
/// /// differs from the current value stored in the entry matching the specified key.
/// @param [in] key Key of the new entry to insert. ///
/// @param [in] value Value of the new entry to insert. /// @param [in] key Key of the new entry to insert.
/// /// @param [in] value Value of the new entry to insert.
/// @returns @ref Success if the operation completed successfully, or @ref ErrorOutOfMemory if the operation failed ///
/// because an internal memory allocation failed. /// @returns @ref Success if the operation completed successfully, or @ref ErrorOutOfMemory if the operation failed
Result Insert(const Key& key, const Value& value); /// because an internal memory allocation failed.
Result Insert(const Key& key, const Value& value);
/// Removes an entry that matches the specified key.
/// private:
/// @param [in] key Key of the entry to erase. // Typedef for the specialized 'HashBase' object we're inheriting from so we can use properly qualified names when
/// // accessing members of HashBase.
/// @returns True if the erase completed successfully, false if an entry for this key did not exist. typedef HashBase<Key, HashMapEntry<Key, Value>, Allocator, HashFunc<Key>, EqualFunc<Key>, AllocFunc, GroupSize> Base;
bool Erase(const Key& key);
PAL_DISALLOW_DEFAULT_CTOR(HashMap);
private: PAL_DISALLOW_COPY_AND_ASSIGN(HashMap);
// Typedef for the specialized 'HashBase' object we're inheriting from so we can use properly qualified names when };
// accessing members of HashBase.
typedef HashBase<Key, HashMapEntry<Key, Value>, Allocator, HashFunc<Key>, EqualFunc<Key>, AllocFunc, GroupSize> Base; } // Util
PAL_DISALLOW_DEFAULT_CTOR(HashMap);
PAL_DISALLOW_COPY_AND_ASSIGN(HashMap);
};
} // Util
+114 -250
파일 보기
@@ -1,250 +1,114 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palHashMapImpl.h * @file palHashMapImpl.h
* @brief PAL utility collection HashMap class implementation. * @brief PAL utility collection HashMap class implementation.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palHashBaseImpl.h" #include "palHashBaseImpl.h"
#include "palHashMap.h" #include "palHashMap.h"
namespace Util namespace Util
{ {
// ===================================================================================================================== // =====================================================================================================================
// Gets a pointer to the value that matches the key. If the key is not present, a pointer to empty space for the value // Gets a pointer to the value that matches the key. If the key is not present, a pointer to empty space for the value
// is returned. // is returned.
template<typename Key, template<typename Key,
typename Value, typename Value,
typename Allocator, typename Allocator,
template<typename> class HashFunc, template<typename> class HashFunc,
template<typename> class EqualFunc, template<typename> class EqualFunc,
typename AllocFunc, typename AllocFunc,
size_t GroupSize> size_t GroupSize>
Result HashMap<Key, Value, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::FindAllocate( Result HashMap<Key, Value, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::FindAllocate(
const Key& key, // Key to search for. const Key& key, // Key to search for.
bool* pExisted, // [out] True if a matching key was found. bool* pExisted, // [out] True if a matching key was found.
Value** ppValue) // [out] Pointer to the value entry of the hash map's entry for the specified key. Value** ppValue) // [out] Pointer to the value entry of the hash map's entry for the specified key.
{ {
PAL_ASSERT(pExisted != nullptr); PAL_ASSERT(pExisted != nullptr);
PAL_ASSERT(ppValue != nullptr); PAL_ASSERT(ppValue != nullptr);
Result result = Result::ErrorOutOfMemory; Entry* pEntry = nullptr;
Result result = Base::FindAllocateEntry(key, pExisted, &pEntry);
// Get the bucket base address.... if (result == Result::Success)
Entry* pGroup = this->InitAndFindBucket(key); {
*ppValue = &pEntry->value;
*pExisted = false; }
*ppValue = nullptr;
return result;
Entry* pMatchingEntry = nullptr; }
while (pGroup != nullptr) // =====================================================================================================================
{ // Gets a pointer to the value that matches the key. Returns null if no entry is present matching the specified key.
const uint32 numEntries = this->GetGroupFooterNumEntries(pGroup); template<typename Key,
typename Value,
// Search this entry group. typename Allocator,
uint32 i = 0; template<typename> class HashFunc,
for (; i < numEntries; i++) template<typename> class EqualFunc,
{ typename AllocFunc,
if (this->m_equalFunc(pGroup[i].key, key)) size_t GroupSize>
{ Value* HashMap<Key, Value, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::FindKey(
// We've found the entry. const Key& key
pMatchingEntry = &(pGroup[i]); ) const
*pExisted = true; {
break; Entry* pEntry = Base::FindEntry(key);
} return (pEntry != nullptr) ? &pEntry->value : nullptr;
} }
// We've reached the end of the allocated buckets and the entry was not found. // =====================================================================================================================
// Allocate this entry for the key. // Inserts a key/value pair entry if it doesn't already exist.
if ((pMatchingEntry == nullptr) && (i < Base::EntriesInGroup)) template<typename Key,
{ typename Value,
pGroup[i].key = key; typename Allocator,
pMatchingEntry = &(pGroup[i]); template<typename> class HashFunc,
this->m_numEntries++; template<typename> class EqualFunc,
this->SetGroupFooterNumEntries(pGroup, numEntries + 1); typename AllocFunc,
} size_t GroupSize>
Result HashMap<Key, Value, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::Insert(
if (pMatchingEntry != nullptr) const Key& key,
{ const Value& value)
*ppValue = &(pMatchingEntry->value); {
result = Result::Success; bool existed = true;
break; Entry* pEntry = nullptr;
}
Result result = Base::FindAllocateEntry(key, &existed, &pEntry);
// Chain to the next entry group.
pGroup = this->AllocateNextGroup(pGroup); // Add the new value if it did not exist already. If FindAllocate returns Success, pValue != nullptr.
} if ((result == Result::Success) && (existed == false))
{
PAL_ASSERT(result == Result::Success); pEntry->value = value;
}
return result;
} PAL_ASSERT(result == Result::Success);
// ===================================================================================================================== return result;
// Gets a pointer to the value that matches the key. Returns null if no entry is present matching the specified key. }
template<typename Key,
typename Value, } // Util
typename Allocator,
template<typename> class HashFunc,
template<typename> class EqualFunc,
typename AllocFunc,
size_t GroupSize>
Value* HashMap<Key, Value, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::FindKey(
const Key& key
) const
{
// Get the bucket base address.
Entry* pGroup = this->FindBucket(key);
Entry* pMatchingEntry = nullptr;
while (pGroup != nullptr)
{
const uint32 numEntries = this->GetGroupFooterNumEntries(pGroup);
// Search this entry group
uint32 i = 0;
for (; i < numEntries; i++)
{
if (this->m_equalFunc(pGroup[i].key, key))
{
// We've found the entry.
pMatchingEntry = &(pGroup[i]);
break;
}
}
if ((pMatchingEntry != nullptr) || (i < Base::EntriesInGroup))
{
break;
}
// Chain to the next entry group.
pGroup = this->GetNextGroup(pGroup);
}
return (pMatchingEntry != nullptr) ? &(pMatchingEntry->value) : nullptr;
}
// =====================================================================================================================
// Inserts a key/value pair entry if it doesn't already exist.
template<typename Key,
typename Value,
typename Allocator,
template<typename> class HashFunc,
template<typename> class EqualFunc,
typename AllocFunc,
size_t GroupSize>
Result HashMap<Key, Value, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::Insert(
const Key& key,
const Value& value)
{
bool existed = true;
Value* pValue = nullptr;
Result result = FindAllocate(key, &existed, &pValue);
// Add the new value if it did not exist already. If FindAllocate returns Success, pValue != nullptr.
if ((result == Result::Success) && (existed == false))
{
*pValue = value;
}
PAL_ASSERT(result == Result::Success);
return result;
}
// =====================================================================================================================
// Removes an entry with the specified key.
template<typename Key,
typename Value,
typename Allocator,
template<typename> class HashFunc,
template<typename> class EqualFunc,
typename AllocFunc,
size_t GroupSize>
bool HashMap<Key, Value, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::Erase(
const Key& key)
{
// Get the bucket base address.
Entry* pGroup = this->FindBucket(key);
Entry* pFoundEntry = nullptr;
Entry* pLastEntry = nullptr;
Entry* pLastEntryGroup = nullptr;
// Find the entry to delete
while (pGroup != nullptr)
{
const uint32 numEntries = this->GetGroupFooterNumEntries(pGroup);
// Search each group
uint32 i = 0;
for (; i < numEntries; i++)
{
if (this->m_equalFunc(pGroup[i].key, key) == true)
{
// We shouldn't find the same key twice.
PAL_ASSERT(pFoundEntry == nullptr);
pFoundEntry = &(pGroup[i]);
}
// keep track of last entry of all groups in bucket
pLastEntry = &(pGroup[i]);
pLastEntryGroup = pGroup;
}
// Chain to the next entry group.
pGroup = this->GetNextGroup(pGroup);
}
// Copy the last entry's data into the entry that we are removing and invalidate the last entry as it now appears
// earlier in the list. This also handles the case where the entry to be removed is the last entry.
if (pFoundEntry != nullptr)
{
PAL_ASSERT(pLastEntry != nullptr);
pFoundEntry->key = pLastEntry->key;
pFoundEntry->value = pLastEntry->value;
memset(pLastEntry, 0, sizeof(Entry));
PAL_ASSERT(this->m_numEntries > 0);
this->m_numEntries--;
const uint32 numEntries = this->GetGroupFooterNumEntries(pLastEntryGroup);
this->SetGroupFooterNumEntries(pLastEntryGroup, numEntries - 1);
}
return (pFoundEntry != nullptr);
}
} // Util
+131 -144
파일 보기
@@ -1,144 +1,131 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palHashSet.h * @file palHashSet.h
* @brief PAL utility collection HashSet class declaration. * @brief PAL utility collection HashSet class declaration.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palHashBase.h" #include "palHashBase.h"
namespace Util namespace Util
{ {
/// Encapsulates one entry of a hash set. /// Encapsulates one entry of a hash set.
template<typename Key> template<typename Key>
struct HashSetEntry struct HashSetEntry
{ {
Key key; ///< Hash set entry key. Key key; ///< Hash set entry key.
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Templated hash set container. * @brief Templated hash set container.
* *
* This is meant for storing elements of an arbitrary (but uniform) key type. Supported operations: * This is meant for storing elements of an arbitrary (but uniform) key type. Supported operations:
* *
* - Searching * - Searching
* - Insertion * - Insertion
* - Deletion * - Deletion
* - Iteration * - Iteration
* *
* HashFunc is a functor for hashing keys. Built-in choices for HashFunc are: * HashFunc is a functor for hashing keys. Built-in choices for HashFunc are:
* *
* - DefaultHashFunc: Good choice when the key is a pointer. * - DefaultHashFunc: Default hash function, selects best hash function based on type of key.
* - JenkinsHashFunc: Good choice when the key is arbitrary binary data. * - PointerHashFunc: Good choice when the key is a pointer.
* - StringJenkinsHashFunc: Good choice when the key is a C-style string. * - JenkinsHashFunc: Good choice when the key is arbitrary binary data.
* * - StringJenkinsHashFunc: Good choice when the key is a C-style string.
* EqualFunc is a functor for comparing keys. Built-in choices for EqualFunc are: *
* * EqualFunc is a functor for comparing keys. Built-in choices for EqualFunc are:
* - DefaultEqualFunc: Determines keys are equal by bitwise comparison. *
* - StringEqualFunc: Treats keys as a char* and compares them as C-style strings. * - DefaultEqualFunc: Determines keys are equal by bitwise comparison.
* * - StringEqualFunc: Treats keys as a char* and compares them as C-style strings.
* @warning This class is not thread-safe for Insert, Erase, or iteration! *
* @warning Init() must be called before using this container. Begin() and Reset() can be safely called before * @warning This class is not thread-safe for Insert, Erase, or iteration!
* initialization and Begin() will always return an iterator that points to null. * @warning Init() must be called before using this container. Begin() and Reset() can be safely called before
* * initialization and Begin() will always return an iterator that points to null.
* For more details please refer to @ref HashBase. *
*********************************************************************************************************************** * For more details please refer to @ref HashBase.
*/ ***********************************************************************************************************************
template<typename Key, */
typename Allocator, template<typename Key,
template<typename> class HashFunc = DefaultHashFunc, typename Allocator,
template<typename> class EqualFunc = DefaultEqualFunc, template<typename> class HashFunc = DefaultHashFunc,
typename AllocFunc = HashAllocator<Allocator>, template<typename> class EqualFunc = DefaultEqualFunc,
size_t GroupSize = PAL_CACHE_LINE_BYTES * 2> typename AllocFunc = HashAllocator<Allocator>,
class HashSet : public HashBase<Key, size_t GroupSize = PAL_CACHE_LINE_BYTES * 2>
HashSetEntry<Key>, class HashSet : public HashBase<Key,
Allocator, HashSetEntry<Key>,
HashFunc<Key>, Allocator,
EqualFunc<Key>, HashFunc<Key>,
AllocFunc, EqualFunc<Key>,
GroupSize> AllocFunc,
{ GroupSize>
public: {
/// Convenience typedef for a templated entry of this hash set. public:
typedef HashSetEntry<Key> Entry; /// Convenience typedef for a templated entry of this hash set.
typedef HashSetEntry<Key> Entry;
/// @internal Constructor
/// /// @internal Constructor
/// @param [in] numBuckets Number of buckets to allocate for this hash container. The initial hash container will ///
/// take (buckets * GroupSize) bytes. /// @param [in] numBuckets Number of buckets to allocate for this hash container. The initial hash container will
/// @param [in] pAllocator Pointer to an allocator that will create system memory requested by this hash container. /// take (buckets * GroupSize) bytes.
explicit HashSet(uint32 numBuckets, Allocator*const pAllocator) : Base::HashBase(numBuckets, pAllocator) {} /// @param [in] pAllocator Pointer to an allocator that will create system memory requested by this hash container.
virtual ~HashSet() { } explicit HashSet(uint32 numBuckets, Allocator*const pAllocator) : Base::HashBase(numBuckets, pAllocator) {}
~HashSet() { }
/// Finds a given entry; if no entry was found, allocate it.
/// /// Finds a given entry; if no entry was found, allocate it.
/// @param [in] ppKey Key to search for. ///
/// @param [out] pExisted True if an entry for the specified key existed before this call was made. /// @param [in] ppKey Key to search for.
/// False indicates that a new entry was allocated as a result of this call. /// @param [out] pExisted True if an entry for the specified key existed before this call was made.
/// /// False indicates that a new entry was allocated as a result of this call.
/// @returns @ref Success if the operation completed successfully ///
/// @ref ErrorOutOfMemory if the operation failed because an internal memory allocation failed. /// @returns @ref Success if the operation completed successfully
Result FindAllocate(Key** ppKey, bool* pExisted); /// @ref ErrorOutOfMemory if the operation failed because an internal memory allocation failed.
Result FindAllocate(Key** ppKey, bool* pExisted);
/// Returns true if the specified key exists in the set.
/// /// Inserts an entry.
/// @param [in] key Key to search for. ///
/// /// No action will be taken if an entry matching this key already exists in the set.
/// @returns True if the specified key exists in the set. ///
bool Contains(const Key& key) const; /// @param [in] key New entry to insert.
///
/// Inserts an entry. /// @returns @ref Success if the operation completed successfully, or @ref ErrorOutOfMemory if the operation failed
/// /// because an internal memory allocation failed.
/// No action will be taken if an entry matching this key already exists in the set. Result Insert(const Key& key);
///
/// @param [in] key New entry to insert. private:
/// // Typedef for the specialized 'HashBase' object we're inheriting from so we can use properly qualified names when
/// @returns @ref Success if the operation completed successfully, or @ref ErrorOutOfMemory if the operation failed // accessing members of HashBase.
/// because an internal memory allocation failed. typedef HashBase<Key, HashSetEntry<Key>, Allocator, HashFunc<Key>, EqualFunc<Key>, AllocFunc, GroupSize> Base;
Result Insert(const Key& key);
PAL_DISALLOW_DEFAULT_CTOR(HashSet);
/// Removes an entry that matches the specified key. PAL_DISALLOW_COPY_AND_ASSIGN(HashSet);
/// };
/// @param [in] key Key of the entry to erase.
/// } // Util
/// @returns True if the erase completed successfully, false if an entry for this key did not exist.
bool Erase(const Key& key);
private:
// Typedef for the specialized 'HashBase' object we're inheriting from so we can use properly qualified names when
// accessing members of HashBase.
typedef HashBase<Key, HashSetEntry<Key>, Allocator, HashFunc<Key>, EqualFunc<Key>, AllocFunc, GroupSize> Base;
PAL_DISALLOW_DEFAULT_CTOR(HashSet);
PAL_DISALLOW_COPY_AND_ASSIGN(HashSet);
};
} // Util
+75 -231
파일 보기
@@ -1,231 +1,75 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palHashSetImpl.h * @file palHashSetImpl.h
* @brief PAL utility collection HashSet class implementation. * @brief PAL utility collection HashSet class implementation.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palHashBaseImpl.h" #include "palHashBaseImpl.h"
#include "palHashSet.h" #include "palHashSet.h"
namespace Util namespace Util
{ {
// ===================================================================================================================== // =====================================================================================================================
// Inserts a key if it doesn't already exist. // Inserts a key if it doesn't already exist.
template<typename Key, template<typename Key,
typename Allocator, typename Allocator,
template<typename> class HashFunc, template<typename> class HashFunc,
template<typename> class EqualFunc, template<typename> class EqualFunc,
typename AllocFunc, typename AllocFunc,
size_t GroupSize> size_t GroupSize>
Result HashSet<Key, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::Insert( Result HashSet<Key, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::Insert(
const Key& key) const Key& key)
{ {
Key* pKey = const_cast<Key*>(&key); Entry* pEntry = nullptr;
bool existed; bool existed = false;
const Result result = FindAllocate(&pKey, &existed); return Base::FindAllocateEntry(key, &existed, &pEntry);
if (existed == false) }
{
*pKey = key; // =====================================================================================================================
} // Finds a given entry; if no entry was found, allocate it.
return result; template<typename Key,
} typename Allocator,
template<typename> class HashFunc,
// ===================================================================================================================== template<typename> class EqualFunc,
// Finds a given entry; if no entry was found, allocate it. typename AllocFunc,
template<typename Key, size_t GroupSize>
typename Allocator, Result HashSet<Key, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::FindAllocate(
template<typename> class HashFunc, Key** ppKey,
template<typename> class EqualFunc, bool* pExisted)
typename AllocFunc, {
size_t GroupSize> PAL_ASSERT(ppKey != nullptr);
Result HashSet<Key, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::FindAllocate( PAL_ASSERT(pExisted != nullptr);
Key** ppKey,
bool* pExisted) static_assert(offsetof(Entry, key) == 0);
{ return Base::FindAllocateEntry(**ppKey, pExisted, reinterpret_cast<Entry**>(ppKey));
PAL_ASSERT(ppKey != nullptr); }
PAL_ASSERT(pExisted != nullptr);
} // Util
Result result = Result::ErrorOutOfMemory;
// Get the bucket base address.
Entry* pGroup = this->InitAndFindBucket(**ppKey);
Entry* pMatchingEntry = nullptr;
while (pGroup != nullptr)
{
const uint32 numEntries = this->GetGroupFooterNumEntries(pGroup);
// Search this entry group.
uint32 i = 0;
for (; i < numEntries; i++)
{
if (this->m_equalFunc(pGroup[i].key, **ppKey))
{
// We've found the entry.
pMatchingEntry = &(pGroup[i]);
*pExisted = true;
break;
}
}
if ((pMatchingEntry == nullptr) && (i < Base::EntriesInGroup))
{
// We've reached the end of the bucket and the entry was not found. Allocate this entry for the key.
*pExisted = false;
*ppKey = &pGroup[i].key;
pMatchingEntry = &(pGroup[i]);
this->m_numEntries++;
this->SetGroupFooterNumEntries(pGroup, numEntries + 1);
}
if (pMatchingEntry != nullptr)
{
result = Result::Success;
break;
}
// Chain to the next entry group.
pGroup = this->AllocateNextGroup(pGroup);
}
PAL_ASSERT(result == Result::Success);
return result;
}
// =====================================================================================================================
// Searches for the specified key to see if it exists.
template<typename Key,
typename Allocator,
template<typename> class HashFunc,
template<typename> class EqualFunc,
typename AllocFunc,
size_t GroupSize>
bool HashSet<Key, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::Contains(
const Key& key
) const
{
// Get the bucket base address.
Entry* pGroup = this->FindBucket(key);
Entry* pMatchingEntry = nullptr;
while (pGroup != nullptr)
{
const uint32 numEntries = this->GetGroupFooterNumEntries(pGroup);
// Search this entry group.
uint32 i = 0;
for (; i < numEntries; i++)
{
if (this->m_equalFunc(pGroup[i].key, key))
{
// We've found the entry.
pMatchingEntry = &(pGroup[i]);
break;
}
}
if ((pMatchingEntry != nullptr) || (i < Base::EntriesInGroup))
{
break;
}
// Chain to the next entry group.
pGroup = this->GetNextGroup(pGroup);
}
return (pMatchingEntry != nullptr);
}
// =====================================================================================================================
// Removes an entry with the specified key.
template<typename Key,
typename Allocator,
template<typename> class HashFunc,
template<typename> class EqualFunc,
typename AllocFunc,
size_t GroupSize>
bool HashSet<Key, Allocator, HashFunc, EqualFunc, AllocFunc, GroupSize>::Erase(
const Key& key)
{
// Get the bucket base address.
Entry* pGroup = this->FindBucket(key);
Entry* pFoundEntry = nullptr;
Entry* pLastEntry = nullptr;
Entry* pLastEntryGroup = nullptr;
// Find the entry to delete.
while ((pGroup != nullptr))
{
const uint32 numEntries = this->GetGroupFooterNumEntries(pGroup);
// Search this entry
uint32 i = 0;
for (; i < numEntries; i++)
{
if (this->m_equalFunc(pGroup[i].key, key) == true)
{
// We shouldn't find the same key twice.
PAL_ASSERT(pFoundEntry == nullptr);
pFoundEntry = &(pGroup[i]);
}
// keep track of last entry of all groups in bucket
pLastEntry = &(pGroup[i]);
pLastEntryGroup = pGroup;
}
// Chain to the next entry group
pGroup = this->GetNextGroup(pGroup);
}
// Copy the last entry's data into the entry that we are removing and invalidate the last entry as it now appears
// earlier in the list. This also handles the case where the entry to be removed is the last entry.
if (pFoundEntry != nullptr)
{
PAL_ASSERT(pLastEntry != nullptr);
pFoundEntry->key = pLastEntry->key;
memset(pLastEntry, 0, sizeof(Entry));
PAL_ASSERT(this->m_numEntries > 0);
this->m_numEntries--;
const uint32 numEntries = this->GetGroupFooterNumEntries(pLastEntryGroup);
this->SetGroupFooterNumEntries(pLastEntryGroup, numEntries - 1);
}
return (pFoundEntry != nullptr);
}
} // Util
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+293 -293
파일 보기
@@ -1,293 +1,293 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palIntrusiveList.h * @file palIntrusiveList.h
* @brief PAL utility collection IntrusiveList and IntrusiveListIterator class declarations. * @brief PAL utility collection IntrusiveList and IntrusiveListIterator class declarations.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palUtil.h" #include "palUtil.h"
#include "palAssert.h" #include "palAssert.h"
namespace Util namespace Util
{ {
// Forward declarations. // Forward declarations.
template<typename T> class IntrusiveList; template<typename T> class IntrusiveList;
template<typename T> class IntrusiveListIterator; template<typename T> class IntrusiveListIterator;
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Encapsulates one node of an intrusive double-linked-list. * @brief Encapsulates one node of an intrusive double-linked-list.
* *
* A node is associated with one data pointer at construction. The data pointer cannot be changed and must be non-null. * A node is associated with one data pointer at construction. The data pointer cannot be changed and must be non-null.
* *
* Note that InList() allows intrusive list users to verify if a given value has been stored in a list without iterating * Note that InList() allows intrusive list users to verify if a given value has been stored in a list without iterating
* over the list provided that each node object has been designated for a particular list. * over the list provided that each node object has been designated for a particular list.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template<typename T> template<typename T>
class IntrusiveListNode class IntrusiveListNode
{ {
public: public:
/// @param [in,out] pData Address of the data element which contains this intrusive node. /// @param [in,out] pData Address of the data element which contains this intrusive node.
explicit IntrusiveListNode(T* pData); explicit IntrusiveListNode(T* pData);
/// Returns true if this node is present in an intrusive list. /// Returns true if this node is present in an intrusive list.
bool InList() const; bool InList() const;
private: private:
// This special constructor is provided for IntrusiveList's sentinel node which must have a null data pointer. // This special constructor is provided for IntrusiveList's sentinel node which must have a null data pointer.
IntrusiveListNode(); IntrusiveListNode();
T*const m_pData; // The data object that contains this node. T*const m_pData; // The data object that contains this node.
IntrusiveListNode<T>* m_pPrev; // Previous node in the list or null if this node is not in a list. IntrusiveListNode<T>* m_pPrev; // Previous node in the list or null if this node is not in a list.
IntrusiveListNode<T>* m_pNext; // Next node in the list or null if this node is not in a list. IntrusiveListNode<T>* m_pNext; // Next node in the list or null if this node is not in a list.
PAL_DISALLOW_COPY_AND_ASSIGN(IntrusiveListNode); PAL_DISALLOW_COPY_AND_ASSIGN(IntrusiveListNode);
// Although this is a transgression of coding standards, it prevents IntrusiveListNode from requiring public // Although this is a transgression of coding standards, it prevents IntrusiveListNode from requiring public
// accessor functions. The added encapsulation this provides is worthwhile. // accessor functions. The added encapsulation this provides is worthwhile.
friend class IntrusiveList<T>; friend class IntrusiveList<T>;
friend class IntrusiveListIterator<T>; friend class IntrusiveListIterator<T>;
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Iterator for traversal of elements in a List collection. * @brief Iterator for traversal of elements in a List collection.
* *
* Allows traversal of all elements in a List going either forwards or backwards. * Allows traversal of all elements in a List going either forwards or backwards.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template<typename T> template<typename T>
class IntrusiveListIterator class IntrusiveListIterator
{ {
public: public:
~IntrusiveListIterator() { } ~IntrusiveListIterator() { }
/// Returns true unless the iterator has advanced past the end of the list. /// Returns true unless the iterator has advanced past the end of the list.
bool IsValid() const { return m_pCurrent != m_pSentinel; } bool IsValid() const { return m_pCurrent != m_pSentinel; }
/// Returns a pointer to the current element. Returns null if the iterator is invalid. /// Returns a pointer to the current element. Returns null if the iterator is invalid.
T* Get() const { return m_pCurrent->m_pData; } T* Get() const { return m_pCurrent->m_pData; }
/// Advances the iterator to the previous position (move backward). /// Advances the iterator to the previous position (move backward).
void Prev() { m_pCurrent = m_pCurrent->m_pPrev; } void Prev() { m_pCurrent = m_pCurrent->m_pPrev; }
/// Advances the iterator to the next position (move forward). /// Advances the iterator to the next position (move forward).
void Next() { m_pCurrent = m_pCurrent->m_pNext; } void Next() { m_pCurrent = m_pCurrent->m_pNext; }
/// Moves the iterator back to the start of the list. /// Moves the iterator back to the start of the list.
void Restart() { m_pCurrent = m_pSentinel->m_pNext; } void Restart() { m_pCurrent = m_pSentinel->m_pNext; }
private: private:
IntrusiveListIterator(const IntrusiveListNode<T>*const pSentinel, IntrusiveListNode<T>* pStart); IntrusiveListIterator(const IntrusiveListNode<T>*const pSentinel, IntrusiveListNode<T>* pStart);
const IntrusiveListNode<T>*const m_pSentinel; // We need the sentinel to locate the list boundaries. const IntrusiveListNode<T>*const m_pSentinel; // We need the sentinel to locate the list boundaries.
IntrusiveListNode<T>* m_pCurrent; // Pointer to the current node. IntrusiveListNode<T>* m_pCurrent; // Pointer to the current node.
PAL_DISALLOW_DEFAULT_CTOR(IntrusiveListIterator); PAL_DISALLOW_DEFAULT_CTOR(IntrusiveListIterator);
// Although this is a transgression of coding standards, it means that List does not need to have a public interface // Although this is a transgression of coding standards, it means that List does not need to have a public interface
// specifically to implement this class. The added encapsulation this provides is worthwhile. // specifically to implement this class. The added encapsulation this provides is worthwhile.
friend class IntrusiveList<T>; friend class IntrusiveList<T>;
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Templated, doubly-linked, intrusive, list container. * @brief Templated, doubly-linked, intrusive, list container.
* *
* This is meant for storing non-null pointers to elements of an arbitrary type using externally managed nodes. * This is meant for storing non-null pointers to elements of an arbitrary type using externally managed nodes.
* Operations which this class supports are: * Operations which this class supports are:
* *
* - Insertion at any point * - Insertion at any point
* - Deletion at any point * - Deletion at any point
* - Forwards and reverse iteration * - Forwards and reverse iteration
* *
* @warning This class is not thread-safe. * @warning This class is not thread-safe.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template<typename T> template<typename T>
class IntrusiveList class IntrusiveList
{ {
public: public:
/// A convenient shorthand for IntrusiveListNode. /// A convenient shorthand for IntrusiveListNode.
typedef IntrusiveListNode<T> Node; typedef IntrusiveListNode<T> Node;
/// A convenient shorthand for IntrusiveListIterator. /// A convenient shorthand for IntrusiveListIterator.
typedef IntrusiveListIterator<T> Iter; typedef IntrusiveListIterator<T> Iter;
IntrusiveList(); IntrusiveList();
/// Returns the number of elements in the list, not counting the sentinel. /// Returns the number of elements in the list, not counting the sentinel.
size_t NumElements() const { return m_numElements; } size_t NumElements() const { return m_numElements; }
/// Returns true if the list is empty. /// Returns true if the list is empty.
bool IsEmpty() const { return m_sentinel.m_pNext == &m_sentinel; } bool IsEmpty() const { return m_sentinel.m_pNext == &m_sentinel; }
/// Returns an iterator pointing to the first element in the list. If the list is empty, the iterator starts out /// Returns an iterator pointing to the first element in the list. If the list is empty, the iterator starts out
/// pointing at the permanent sentinel node. /// pointing at the permanent sentinel node.
/// ///
/// @returns An iterator pointing at the front end of the list. /// @returns An iterator pointing at the front end of the list.
Iter Begin() const { return Iter(&m_sentinel, m_sentinel.m_pNext); } Iter Begin() const { return Iter(&m_sentinel, m_sentinel.m_pNext); }
/// Returns an iterator pointing to the last element in the list. If the list is empty, the iterator starts out /// Returns an iterator pointing to the last element in the list. If the list is empty, the iterator starts out
/// pointing at the permanent sentinel node. /// pointing at the permanent sentinel node.
/// ///
/// @returns An iterator pointing at the back end of the list. /// @returns An iterator pointing at the back end of the list.
Iter End() const { return Iter(&m_sentinel, m_sentinel.m_pPrev); } Iter End() const { return Iter(&m_sentinel, m_sentinel.m_pPrev); }
/// Returns the data pointer at the front of the list. /// Returns the data pointer at the front of the list.
/// ///
/// @returns The data pointer at the front of the list or null if the list is empty. /// @returns The data pointer at the front of the list or null if the list is empty.
T* Front() const { return m_sentinel.m_pNext->m_pData; } T* Front() const { return m_sentinel.m_pNext->m_pData; }
/// Returns the data pointer at the back of the list. /// Returns the data pointer at the back of the list.
/// ///
/// @returns The data pointer at the back of the list or null if the list is empty. /// @returns The data pointer at the back of the list or null if the list is empty.
T* Back() const { return m_sentinel.m_pPrev->m_pData; } T* Back() const { return m_sentinel.m_pPrev->m_pData; }
/// Pushes the specified node onto the front of the list. /// Pushes the specified node onto the front of the list.
/// ///
/// @param [in] pNode Externally-owned list node to link into the list. /// @param [in] pNode Externally-owned list node to link into the list.
void PushFront(Node* pNode) { InsertBefore(m_sentinel.m_pNext, pNode); } void PushFront(Node* pNode) { InsertBefore(m_sentinel.m_pNext, pNode); }
/// Pushes the specified node onto the back of the list. /// Pushes the specified node onto the back of the list.
/// ///
/// @param [in] pNode Externally-owned list node to link into the list. /// @param [in] pNode Externally-owned list node to link into the list.
void PushBack(Node* pNode) { InsertBefore(&m_sentinel, pNode); } void PushBack(Node* pNode) { InsertBefore(&m_sentinel, pNode); }
/// Pushes the contents of pSource onto the front of this list. The ordering of pSource is preserved, meaning that /// Pushes the contents of pSource onto the front of this list. The ordering of pSource is preserved, meaning that
/// the front of pSource will be the new front of this list. Note that pSource will be left entirely empty. /// the front of pSource will be the new front of this list. Note that pSource will be left entirely empty.
/// ///
/// It is illegal to call this function with an empty pSource. /// It is illegal to call this function with an empty pSource.
/// ///
/// @param [in] pSource The contents of pSource will be pushed in-order onto the front of this list. /// @param [in] pSource The contents of pSource will be pushed in-order onto the front of this list.
void PushFrontList(IntrusiveList<T>* pSource); void PushFrontList(IntrusiveList<T>* pSource);
/// Pushes the contents of pSource onto the back of this list. The ordering of pSource is preserved, meaning that /// Pushes the contents of pSource onto the back of this list. The ordering of pSource is preserved, meaning that
/// the end of pSource will be the new end of this list. Note that pSource will be left entirely empty. /// the end of pSource will be the new end of this list. Note that pSource will be left entirely empty.
/// ///
/// It is illegal to call this function with an empty pSource. /// It is illegal to call this function with an empty pSource.
/// ///
/// @param [in] pSource The contents of pSource will be pushed in-order onto the back of this list. /// @param [in] pSource The contents of pSource will be pushed in-order onto the back of this list.
void PushBackList(IntrusiveList<T>* pSource); void PushBackList(IntrusiveList<T>* pSource);
/// Inserts the specified node before a particular node in a list. /// Inserts the specified node before a particular node in a list.
/// ///
/// If the iterator has advanced off the end of the list (i.e., the iterator is invalid), the added node will be the /// If the iterator has advanced off the end of the list (i.e., the iterator is invalid), the added node will be the
/// new tail node. /// new tail node.
/// ///
/// @param [in] iter Identifies a node where the insertion should take place. The iterator will point to the same /// @param [in] iter Identifies a node where the insertion should take place. The iterator will point to the same
/// spot in the list after insertion. /// spot in the list after insertion.
/// @param [in] pNode Externally-owned list node to link into the list. /// @param [in] pNode Externally-owned list node to link into the list.
void InsertBefore(const Iter& iter, Node* pNode); void InsertBefore(const Iter& iter, Node* pNode);
/// Removes the node at the specified position from the list. /// Removes the node at the specified position from the list.
/// ///
/// It is illegal to call this function with an iterator that has already advanced off the end of the list. /// It is illegal to call this function with an iterator that has already advanced off the end of the list.
/// ///
/// @param [in,out] pIter Iterator identifying the node to be removed. After the node is removed, this iterator /// @param [in,out] pIter Iterator identifying the node to be removed. After the node is removed, this iterator
/// will be advanced to the next node. If this call removes the final remaining node in the /// will be advanced to the next node. If this call removes the final remaining node in the
/// list then the iterator will point at the sentinel and will be invalid. /// list then the iterator will point at the sentinel and will be invalid.
void Erase(Iter* pIter); void Erase(Iter* pIter);
/// Removes the node at the specified position from the list. It is illegal to call this function with a Node that /// Removes the node at the specified position from the list. It is illegal to call this function with a Node that
/// not in this list. /// not in this list.
/// ///
/// @param [in] pNode Node to be removed. /// @param [in] pNode Node to be removed.
void Erase(Node* pNode); void Erase(Node* pNode);
/// Removes all nodes from the list. /// Removes all nodes from the list.
void EraseAll(); void EraseAll();
/// Truncates the list without touching the elements /// Truncates the list without touching the elements
void InvalidateList() void InvalidateList()
{ {
m_sentinel.m_pNext = &m_sentinel; m_sentinel.m_pNext = &m_sentinel;
m_sentinel.m_pPrev = &m_sentinel; m_sentinel.m_pPrev = &m_sentinel;
m_numElements = 0; m_numElements = 0;
} }
private: private:
void InsertBefore(Node* pBeforeMe, Node* pNode); void InsertBefore(Node* pBeforeMe, Node* pNode);
void Unlink(Node* pNode); void Unlink(Node* pNode);
Node m_sentinel; // Ties the head to the tail and signifies the boundary of the list. Node m_sentinel; // Ties the head to the tail and signifies the boundary of the list.
size_t m_numElements; // Number of elements. size_t m_numElements; // Number of elements.
PAL_DISALLOW_COPY_AND_ASSIGN(IntrusiveList); PAL_DISALLOW_COPY_AND_ASSIGN(IntrusiveList);
}; };
// ===================================================================================================================== // =====================================================================================================================
// This is the public node constructor; it must be given a non-null data pointer. // This is the public node constructor; it must be given a non-null data pointer.
template<typename T> template<typename T>
IntrusiveListNode<T>::IntrusiveListNode( IntrusiveListNode<T>::IntrusiveListNode(
T* pData) T* pData)
: :
m_pData(pData), m_pData(pData),
m_pPrev(nullptr), m_pPrev(nullptr),
m_pNext(nullptr) m_pNext(nullptr)
{ {
PAL_ASSERT(pData != nullptr); PAL_ASSERT(pData != nullptr);
} }
// ===================================================================================================================== // =====================================================================================================================
// This is the private node constructor which is used exclusively for sentinel nodes. // This is the private node constructor which is used exclusively for sentinel nodes.
template<typename T> template<typename T>
IntrusiveListNode<T>::IntrusiveListNode() IntrusiveListNode<T>::IntrusiveListNode()
: :
m_pData(nullptr), m_pData(nullptr),
m_pPrev(nullptr), m_pPrev(nullptr),
m_pNext(nullptr) m_pNext(nullptr)
{ {
} }
// ===================================================================================================================== // =====================================================================================================================
// Returns true if this node is present in an intrusive list. // Returns true if this node is present in an intrusive list.
template<typename T> template<typename T>
bool IntrusiveListNode<T>::InList() const bool IntrusiveListNode<T>::InList() const
{ {
// The node pointers should always be null or non-null together. // The node pointers should always be null or non-null together.
PAL_DEBUG_BUILD_ONLY_ASSERT((m_pPrev == nullptr) == (m_pNext == nullptr)); PAL_DEBUG_BUILD_ONLY_ASSERT((m_pPrev == nullptr) == (m_pNext == nullptr));
return (m_pNext != nullptr); return (m_pNext != nullptr);
} }
// ===================================================================================================================== // =====================================================================================================================
template<typename T> template<typename T>
IntrusiveListIterator<T>::IntrusiveListIterator( IntrusiveListIterator<T>::IntrusiveListIterator(
const IntrusiveListNode<T>*const pSentinel, const IntrusiveListNode<T>*const pSentinel,
IntrusiveListNode<T>* pStart) IntrusiveListNode<T>* pStart)
: :
m_pSentinel(pSentinel), m_pSentinel(pSentinel),
m_pCurrent(pStart) m_pCurrent(pStart)
{ {
} }
} // Util } // Util
+346 -346
파일 보기
@@ -1,346 +1,346 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palLinearAllocator.h * @file palLinearAllocator.h
* @brief * @brief PAL utility allocator LinearAllocator class. * @brief * @brief PAL utility allocator LinearAllocator class.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palIntrusiveList.h" #include "palIntrusiveList.h"
#include "palSysMemory.h" #include "palSysMemory.h"
namespace Util namespace Util
{ {
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief A linear allocator that allocates virtual memory. * @brief A linear allocator that allocates virtual memory.
* *
* To improve performance, a linear allocator can be used in performance-critical areas to avoid unnecessary heap * To improve performance, a linear allocator can be used in performance-critical areas to avoid unnecessary heap
* allocations. The VirtualLinearAllocator will instead reserve a specified amount of virtual address space and will * allocations. The VirtualLinearAllocator will instead reserve a specified amount of virtual address space and will
* incrementally back it with real memory as necessary. * incrementally back it with real memory as necessary.
* *
* As clients reach a steady state, allocations from this allocator will become "free," essentially just costing a * As clients reach a steady state, allocations from this allocator will become "free," essentially just costing a
* pointer increment. * pointer increment.
* *
* This allocator can be used with any of the memory management macros. @see Allocators for more information about the * This allocator can be used with any of the memory management macros. @see Allocators for more information about the
* Allocation pattern. * Allocation pattern.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class VirtualLinearAllocator class VirtualLinearAllocator
{ {
public: public:
/// Constructor. /// Constructor.
/// ///
/// @param [in] size Maximum size, in bytes, of virtual memory that this allocator should reserve. /// @param [in] size Maximum size, in bytes, of virtual memory that this allocator should reserve.
/// Does not need to be aligned to page size. /// Does not need to be aligned to page size.
VirtualLinearAllocator(size_t size) : VirtualLinearAllocator(size_t size) :
m_pStart(nullptr), m_pStart(nullptr),
m_pCurrent(nullptr), m_pCurrent(nullptr),
m_size(size), m_size(size),
m_pageSize(0) {} m_pageSize(0) {}
/// Destructor. /// Destructor.
virtual ~VirtualLinearAllocator() virtual ~VirtualLinearAllocator()
{ {
if (m_pStart != nullptr) if (m_pStart != nullptr)
{ {
// Free all of the pages. // Free all of the pages.
Result result = VirtualRelease(m_pStart, m_size); Result result = VirtualRelease(m_pStart, m_size);
PAL_ASSERT(result == Result::_Success); PAL_ASSERT(result == Result::_Success);
} }
} }
/// Initializes the linear allocator by reserving the requested number of pages. /// Initializes the linear allocator by reserving the requested number of pages.
/// ///
/// @returns Result::Success if memory reservation and committing of the first page is successful. /// @returns Result::Success if memory reservation and committing of the first page is successful.
Result Init() Result Init()
{ {
m_pageSize = VirtualPageSize(); m_pageSize = VirtualPageSize();
m_size = Pow2Align(m_size, m_pageSize); m_size = Pow2Align(m_size, m_pageSize);
Result result = VirtualReserve(m_size, &m_pStart); Result result = VirtualReserve(m_size, &m_pStart);
if (result == Result::_Success) if (result == Result::_Success)
{ {
result = VirtualCommit(m_pStart, m_pageSize); result = VirtualCommit(m_pStart, m_pageSize);
} }
if (result == Result::_Success) if (result == Result::_Success)
{ {
m_pCurrent = m_pStart; m_pCurrent = m_pStart;
m_pCommittedToPage = VoidPtrInc(m_pCurrent, m_pageSize); m_pCommittedToPage = VoidPtrInc(m_pCurrent, m_pageSize);
} }
return result; return result;
} }
/// Allocates a block of memory. /// Allocates a block of memory.
/// ///
/// @param [in] allocInfo Contains information about the requested allocation. /// @param [in] allocInfo Contains information about the requested allocation.
/// ///
/// @returns Pointer to the allocated memory, nullptr if the allocation failed. /// @returns Pointer to the allocated memory, nullptr if the allocation failed.
void* Alloc(const AllocInfo& allocInfo) void* Alloc(const AllocInfo& allocInfo)
{ {
void* pAlignedCurrent = VoidPtrAlign(m_pCurrent, allocInfo.alignment); void* pAlignedCurrent = VoidPtrAlign(m_pCurrent, allocInfo.alignment);
void* pNextCurrent = VoidPtrInc(pAlignedCurrent, allocInfo.bytes); void* pNextCurrent = VoidPtrInc(pAlignedCurrent, allocInfo.bytes);
void* pAlignedEnd = VoidPtrAlign(pNextCurrent, m_pageSize); void* pAlignedEnd = VoidPtrAlign(pNextCurrent, m_pageSize);
if (allocInfo.bytes > Remaining()) if (allocInfo.bytes > Remaining())
{ {
pAlignedCurrent = nullptr; pAlignedCurrent = nullptr;
} }
else if (pAlignedEnd > m_pCommittedToPage) else if (pAlignedEnd > m_pCommittedToPage)
{ {
const size_t commitBytes = VoidPtrDiff(pAlignedEnd, m_pCommittedToPage); const size_t commitBytes = VoidPtrDiff(pAlignedEnd, m_pCommittedToPage);
const Result result = VirtualCommit(m_pCommittedToPage, commitBytes); const Result result = VirtualCommit(m_pCommittedToPage, commitBytes);
if (result == Result::_Success) if (result == Result::_Success)
{ {
m_pCommittedToPage = VoidPtrInc(m_pCommittedToPage, commitBytes); m_pCommittedToPage = VoidPtrInc(m_pCommittedToPage, commitBytes);
m_pCurrent = pNextCurrent; m_pCurrent = pNextCurrent;
} }
else else
{ {
// Return nullptr if allocation fails. // Return nullptr if allocation fails.
pAlignedCurrent = nullptr; pAlignedCurrent = nullptr;
} }
} }
else else
{ {
m_pCurrent = pNextCurrent; m_pCurrent = pNextCurrent;
} }
return pAlignedCurrent; return pAlignedCurrent;
} }
/// Frees a block of memory. /// Frees a block of memory.
/// ///
/// @param [in] freeInfo Contains information about the requested free. /// @param [in] freeInfo Contains information about the requested free.
void Free(const FreeInfo& freeInfo) {} void Free(const FreeInfo& freeInfo) {}
/// Rewinds the current pointer to the specified location to reuse already allocated memory. /// Rewinds the current pointer to the specified location to reuse already allocated memory.
/// ///
/// @param pStart Where to reset the m_pCurrent to. /// @param pStart Where to reset the m_pCurrent to.
/// @param decommit If true, pages that are rewound are freed/decommitted. /// @param decommit If true, pages that are rewound are freed/decommitted.
void Rewind(void* pStart, bool decommit) void Rewind(void* pStart, bool decommit)
{ {
PAL_ASSERT((m_pStart <= pStart) && (pStart <= m_pCurrent)); PAL_ASSERT((m_pStart <= pStart) && (pStart <= m_pCurrent));
if (pStart != m_pCurrent) if (pStart != m_pCurrent)
{ {
if (decommit) if (decommit)
{ {
void* pStartPage = VoidPtrAlign(VoidPtrInc(pStart, 1), m_pageSize); void* pStartPage = VoidPtrAlign(VoidPtrInc(pStart, 1), m_pageSize);
void* pCurrentPage = VoidPtrAlign(m_pCurrent, m_pageSize); void* pCurrentPage = VoidPtrAlign(m_pCurrent, m_pageSize);
const size_t numPages = VoidPtrDiff(pCurrentPage, pStartPage) / m_pageSize; const size_t numPages = VoidPtrDiff(pCurrentPage, pStartPage) / m_pageSize;
if (numPages > 0) if (numPages > 0)
{ {
Result result = VirtualDecommit(pStartPage, m_pageSize * numPages); Result result = VirtualDecommit(pStartPage, m_pageSize * numPages);
PAL_ASSERT(result == Result::_Success); PAL_ASSERT(result == Result::_Success);
m_pCommittedToPage = pStartPage; m_pCommittedToPage = pStartPage;
} }
} }
#if DEBUG #if DEBUG
else else
{ {
void* pStartPage = VoidPtrAlign(VoidPtrInc(pStart, 1), m_pageSize); void* pStartPage = VoidPtrAlign(VoidPtrInc(pStart, 1), m_pageSize);
void* pCurrentPage = VoidPtrAlign(m_pCurrent, m_pageSize); void* pCurrentPage = VoidPtrAlign(m_pCurrent, m_pageSize);
const size_t numDwords = VoidPtrDiff(pCurrentPage, pStartPage) / sizeof(uint32); const size_t numDwords = VoidPtrDiff(pCurrentPage, pStartPage) / sizeof(uint32);
uint32* pNewCurrent = static_cast<uint32*>(pStartPage); uint32* pNewCurrent = static_cast<uint32*>(pStartPage);
for (size_t dword = 0; dword < numDwords; dword++) for (size_t dword = 0; dword < numDwords; dword++)
{ {
pNewCurrent[dword] = 0xDEADBEEF; pNewCurrent[dword] = 0xDEADBEEF;
} }
} }
#endif #endif
m_pCurrent = pStart; m_pCurrent = pStart;
} }
} }
/// Returns the current pointer to backing memory. /// Returns the current pointer to backing memory.
/// ///
/// @returns Current pointer to backing memory. /// @returns Current pointer to backing memory.
void* Current() { return m_pCurrent; } void* Current() { return m_pCurrent; }
/// Returns the starting pointer to backing memory. /// Returns the starting pointer to backing memory.
/// ///
/// @returns Pointer to the start of backing memory. /// @returns Pointer to the start of backing memory.
void* Start() { return m_pStart; } void* Start() { return m_pStart; }
/// Returns the number of bytes that have been allocated. /// Returns the number of bytes that have been allocated.
/// ///
/// @returns Number of bytes allocated through this allocator. /// @returns Number of bytes allocated through this allocator.
size_t BytesAllocated() { return VoidPtrDiff(m_pCurrent, m_pStart); } size_t BytesAllocated() { return VoidPtrDiff(m_pCurrent, m_pStart); }
/// Compute remaining unallocated space in the allocator; once this space is exhausted allocations will fail. /// Compute remaining unallocated space in the allocator; once this space is exhausted allocations will fail.
/// ///
/// @returns The size of the remaining unallocated space in bytes. /// @returns The size of the remaining unallocated space in bytes.
size_t Remaining() const { return m_size - VoidPtrDiff(m_pCurrent, m_pStart); } size_t Remaining() const { return m_size - VoidPtrDiff(m_pCurrent, m_pStart); }
private: private:
void* m_pStart; ///< Pointer to where the backing allocation starts. void* m_pStart; ///< Pointer to where the backing allocation starts.
void* m_pCurrent; ///< Pointer to the current position of backing memory. void* m_pCurrent; ///< Pointer to the current position of backing memory.
void* m_pCommittedToPage; ///< Pointer to the end of the last committed page. void* m_pCommittedToPage; ///< Pointer to the end of the last committed page.
size_t m_size; ///< Size of the allocation. size_t m_size; ///< Size of the allocation.
size_t m_pageSize; ///< OS' defined page size. size_t m_pageSize; ///< OS' defined page size.
PAL_DISALLOW_DEFAULT_CTOR(VirtualLinearAllocator); PAL_DISALLOW_DEFAULT_CTOR(VirtualLinearAllocator);
PAL_DISALLOW_COPY_AND_ASSIGN(VirtualLinearAllocator); PAL_DISALLOW_COPY_AND_ASSIGN(VirtualLinearAllocator);
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief A "resource acquisition is initialization" (RAII) wrapper for the LinearAllocator classes. * @brief A "resource acquisition is initialization" (RAII) wrapper for the LinearAllocator classes.
* *
* The RAII paradigm allows critical sections to be automatically acquired during this class' constructor, and * The RAII paradigm allows critical sections to be automatically acquired during this class' constructor, and
* automatically released when a stack-allocated wrapper object goes out-of-scope. As such, it only makes sense to use * automatically released when a stack-allocated wrapper object goes out-of-scope. As such, it only makes sense to use
* this class for stack-allocated objects. * this class for stack-allocated objects.
* *
* This object will ensure that anything allocated the object is allocated on the stack and when it goes out of scope * This object will ensure that anything allocated the object is allocated on the stack and when it goes out of scope
* will be properly "rewound" by the allocator. See the below example. * will be properly "rewound" by the allocator. See the below example.
* *
* *
* { * {
* [Current pointer = 0x10] * [Current pointer = 0x10]
* LinearAllocatorAuto allocator(pPtrToAllocator); * LinearAllocatorAuto allocator(pPtrToAllocator);
* Allocations occur ... * Allocations occur ...
* [Current pointer = 0x80] * [Current pointer = 0x80]
* } * }
* [Current pointer rewinds = 0x10] * [Current pointer rewinds = 0x10]
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template <class LinearAllocator> template <class LinearAllocator>
class LinearAllocatorAuto class LinearAllocatorAuto
{ {
public: public:
/// Tracks the current start pointer. /// Tracks the current start pointer.
/// ///
/// @param pAllocator The allocator to wrap. /// @param pAllocator The allocator to wrap.
/// @param decommit Whether to decommit any pages of memory allocated when this goes out of scope. /// @param decommit Whether to decommit any pages of memory allocated when this goes out of scope.
LinearAllocatorAuto(LinearAllocator* pAllocator, bool decommit) LinearAllocatorAuto(LinearAllocator* pAllocator, bool decommit)
: :
m_pAllocator(pAllocator), m_pAllocator(pAllocator),
#if PAL_MEMTRACK #if PAL_MEMTRACK
m_memTracker(pAllocator), m_memTracker(pAllocator),
#endif #endif
m_pStart(nullptr), m_pStart(nullptr),
m_decommit(decommit) m_decommit(decommit)
{ {
PAL_ASSERT(pAllocator != nullptr); PAL_ASSERT(pAllocator != nullptr);
m_pStart = m_pAllocator->Current(); m_pStart = m_pAllocator->Current();
#if PAL_MEMTRACK #if PAL_MEMTRACK
Result result = m_memTracker.Init(); Result result = m_memTracker.Init();
PAL_ASSERT(result == Result::_Success); PAL_ASSERT(result == Result::_Success);
#endif #endif
} }
/// Rewinds any allocations made when this goes out of scope. /// Rewinds any allocations made when this goes out of scope.
~LinearAllocatorAuto() ~LinearAllocatorAuto()
{ {
m_pAllocator->Rewind(m_pStart, m_decommit); m_pAllocator->Rewind(m_pStart, m_decommit);
} }
/// Allocates a block of memory. /// Allocates a block of memory.
/// ///
/// @param [in] allocInfo Contains information about the requested allocation. /// @param [in] allocInfo Contains information about the requested allocation.
/// ///
/// @returns Pointer to the allocated memory, nullptr if the allocation failed. /// @returns Pointer to the allocated memory, nullptr if the allocation failed.
void* Alloc(const AllocInfo& allocInfo) void* Alloc(const AllocInfo& allocInfo)
{ {
void* pMemory = nullptr; void* pMemory = nullptr;
#if PAL_MEMTRACK #if PAL_MEMTRACK
pMemory = m_memTracker.Alloc(allocInfo); pMemory = m_memTracker.Alloc(allocInfo);
#else #else
pMemory = m_pAllocator->Alloc(allocInfo); pMemory = m_pAllocator->Alloc(allocInfo);
#endif #endif
return pMemory; return pMemory;
} }
/// Frees a block of memory. /// Frees a block of memory.
/// ///
/// @param [in] freeInfo Contains information about the requested free. /// @param [in] freeInfo Contains information about the requested free.
void Free(const FreeInfo& freeInfo) void Free(const FreeInfo& freeInfo)
{ {
#if PAL_MEMTRACK #if PAL_MEMTRACK
m_memTracker.Free(freeInfo); m_memTracker.Free(freeInfo);
#else #else
m_pAllocator->Free(freeInfo); m_pAllocator->Free(freeInfo);
#endif #endif
} }
private: private:
LinearAllocator*const m_pAllocator; ///< The LinearAllocator which this object wraps. LinearAllocator*const m_pAllocator; ///< The LinearAllocator which this object wraps.
#if PAL_MEMTRACK #if PAL_MEMTRACK
MemTracker<LinearAllocator> m_memTracker; ///< Memory tracker for this LinearAllocatorAuto. MemTracker<LinearAllocator> m_memTracker; ///< Memory tracker for this LinearAllocatorAuto.
#endif #endif
void* m_pStart; ///< Where the LinearAllocator started when wrapped by this. void* m_pStart; ///< Where the LinearAllocator started when wrapped by this.
const bool m_decommit; ///< Whether to decommit any pages of memory allocated on destruction. const bool m_decommit; ///< Whether to decommit any pages of memory allocated on destruction.
PAL_DISALLOW_DEFAULT_CTOR(LinearAllocatorAuto); PAL_DISALLOW_DEFAULT_CTOR(LinearAllocatorAuto);
PAL_DISALLOW_COPY_AND_ASSIGN(LinearAllocatorAuto); PAL_DISALLOW_COPY_AND_ASSIGN(LinearAllocatorAuto);
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief A simple extension of VirtualLinearAllocator that contains an IntrusiveListNode pointing at itself. * @brief A simple extension of VirtualLinearAllocator that contains an IntrusiveListNode pointing at itself.
* This makes it very easy to create and manage IntrusiveLists of VirtualLinearAllocators. * This makes it very easy to create and manage IntrusiveLists of VirtualLinearAllocators.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class VirtualLinearAllocatorWithNode : public VirtualLinearAllocator class VirtualLinearAllocatorWithNode : public VirtualLinearAllocator
{ {
public: public:
/// Constructor. /// Constructor.
VirtualLinearAllocatorWithNode(size_t size) : VirtualLinearAllocator(size), m_node(this) {} VirtualLinearAllocatorWithNode(size_t size) : VirtualLinearAllocator(size), m_node(this) {}
/// Destructor. /// Destructor.
virtual ~VirtualLinearAllocatorWithNode() {} virtual ~VirtualLinearAllocatorWithNode() {}
/// Gets this linear allocator's associated IntrusiveListNode. /// Gets this linear allocator's associated IntrusiveListNode.
/// ///
/// @returns Pointer to this allocator's associated IntrusiveListNode. /// @returns Pointer to this allocator's associated IntrusiveListNode.
IntrusiveListNode<VirtualLinearAllocatorWithNode>* GetNode() { return &m_node; } IntrusiveListNode<VirtualLinearAllocatorWithNode>* GetNode() { return &m_node; }
private: private:
IntrusiveListNode<VirtualLinearAllocatorWithNode> m_node; IntrusiveListNode<VirtualLinearAllocatorWithNode> m_node;
PAL_DISALLOW_DEFAULT_CTOR(VirtualLinearAllocatorWithNode); PAL_DISALLOW_DEFAULT_CTOR(VirtualLinearAllocatorWithNode);
PAL_DISALLOW_COPY_AND_ASSIGN(VirtualLinearAllocatorWithNode); PAL_DISALLOW_COPY_AND_ASSIGN(VirtualLinearAllocatorWithNode);
}; };
} // Util } // Util
+226 -226
파일 보기
@@ -1,226 +1,226 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palMath.h * @file palMath.h
* @brief PAL utility collection function/constant declarations for the Math sub-namespace. * @brief PAL utility collection function/constant declarations for the Math sub-namespace.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palSysMemory.h" #include "palSysMemory.h"
#include <limits> #include <limits>
namespace Util namespace Util
{ {
/// Util sub-namespace defining several useful math routines and constants. /// Util sub-namespace defining several useful math routines and constants.
namespace Math namespace Math
{ {
/// Exponent mask of a single-precision IEEE float. /// Exponent mask of a single-precision IEEE float.
constexpr uint32 FloatExponentMask = 0x7F800000; constexpr uint32 FloatExponentMask = 0x7F800000;
/// Exponent bias of a single-precision IEEE float. /// Exponent bias of a single-precision IEEE float.
constexpr uint32 FloatExponentBias = 127; constexpr uint32 FloatExponentBias = 127;
/// Number of bits in the mantissa of a single-precision IEEE float. /// Number of bits in the mantissa of a single-precision IEEE float.
constexpr uint32 FloatNumMantissaBits = 23; constexpr uint32 FloatNumMantissaBits = 23;
/// Mantissa mask of a single-precision IEEE float. /// Mantissa mask of a single-precision IEEE float.
constexpr uint32 FloatMantissaMask = 0x007FFFFF; constexpr uint32 FloatMantissaMask = 0x007FFFFF;
/// Sign bit mask of a single precision IEEE float. /// Sign bit mask of a single precision IEEE float.
constexpr uint32 FloatSignBitMask = 0x80000000; constexpr uint32 FloatSignBitMask = 0x80000000;
/// Mask of all non-sign bits of a single-precision IEEE float. /// Mask of all non-sign bits of a single-precision IEEE float.
constexpr uint32 FloatMaskOutSignBit = 0x7FFFFFFF; constexpr uint32 FloatMaskOutSignBit = 0x7FFFFFFF;
/// Minimum number of float bits in a normalized IEE float. /// Minimum number of float bits in a normalized IEE float.
constexpr uint32 MinNormalizedFloatBits = 0x00800000; constexpr uint32 MinNormalizedFloatBits = 0x00800000;
/// Positive one. /// Positive one.
constexpr float FloatOne = 1.0f; constexpr float FloatOne = 1.0f;
/// Negative one. /// Negative one.
constexpr float FloatNegOne = -1.0f; constexpr float FloatNegOne = -1.0f;
/// Zero. /// Zero.
constexpr float FloatZero = 0.0f; constexpr float FloatZero = 0.0f;
/// Positive infinity. /// Positive infinity.
constexpr float FloatInfinity = std::numeric_limits<float>::infinity(); constexpr float FloatInfinity = std::numeric_limits<float>::infinity();
/// Fraction structure. /// Fraction structure.
struct Fraction struct Fraction
{ {
uint32 num; ///< Numerator uint32 num; ///< Numerator
uint32 den; ///< Denominator uint32 den; ///< Denominator
}; };
/// Returns the bits of a floating point value as an unsigned integer. /// Returns the bits of a floating point value as an unsigned integer.
inline uint32 FloatToBits(float f) inline uint32 FloatToBits(float f)
{ {
return (*(reinterpret_cast<uint32*>(&f))); return (*(reinterpret_cast<uint32*>(&f)));
} }
/// Assigns the bits contained in an unsigned integer to the float pointer location /// Assigns the bits contained in an unsigned integer to the float pointer location
inline void SetBitsToFloat(float* f, uint32 u) inline void SetBitsToFloat(float* f, uint32 u)
{ {
*(reinterpret_cast<uint32*>(f)) = u; *(reinterpret_cast<uint32*>(f)) = u;
} }
/// Returns true if the specified float is denormalized. /// Returns true if the specified float is denormalized.
extern bool IsDenorm(float f); extern bool IsDenorm(float f);
/// Returns true if the specified float is +/- infinity. /// Returns true if the specified float is +/- infinity.
extern bool IsInf(float f); extern bool IsInf(float f);
/// Returns true if the specified float is a NaN. /// Returns true if the specified float is a NaN.
extern bool IsNaN(float f); extern bool IsNaN(float f);
/// Determines if a floating-point number is either +/-Infinity or NaN. /// Determines if a floating-point number is either +/-Infinity or NaN.
inline bool IsInfOrNaN(float f) inline bool IsInfOrNaN(float f)
{ {
return (IsInf(f) || IsNaN(f)); return (IsInf(f) || IsNaN(f));
} }
/// @brief Converts a floating point number to a signed fixed point number with the given integer and fractional bits. /// @brief Converts a floating point number to a signed fixed point number with the given integer and fractional bits.
/// ///
/// If the number of integer bits is zero, the incoming value is treated as normalized, i.e. [-1.0, 1.0]. If the /// If the number of integer bits is zero, the incoming value is treated as normalized, i.e. [-1.0, 1.0]. If the
/// intBits is zero, the fracBits is assumed to include 1 sign bit, otherwise the sign bit is assumed to be part of the /// intBits is zero, the fracBits is assumed to include 1 sign bit, otherwise the sign bit is assumed to be part of the
/// intBits. A typical use for enableRounding would be when converting SNORM/UNORM values to fixed point. /// intBits. A typical use for enableRounding would be when converting SNORM/UNORM values to fixed point.
/// ///
/// @param [in] f Floating point value to convert. /// @param [in] f Floating point value to convert.
/// @param [in] intBits Number of integer bits (including the sign bit) in the fixed point output. /// @param [in] intBits Number of integer bits (including the sign bit) in the fixed point output.
/// @param [in] fracBits Number of fractional bits in the fixed point output. /// @param [in] fracBits Number of fractional bits in the fixed point output.
/// @param [in] enableRounding Round before conversion. /// @param [in] enableRounding Round before conversion.
/// ///
/// @returns Fixed point number in a uint32. /// @returns Fixed point number in a uint32.
extern uint32 FloatToSFixed(float f, uint32 intBits, uint32 fracBits, bool enableRounding = false); extern uint32 FloatToSFixed(float f, uint32 intBits, uint32 fracBits, bool enableRounding = false);
/// @brief Converts a floating point number to an unsigned fixed point number with the given integer and /// @brief Converts a floating point number to an unsigned fixed point number with the given integer and
/// fractional bits. /// fractional bits.
/// ///
/// If the number of integer bits is zero, the incoming value is treated as normalized, i.e. [-1.0, 1.0]. A typical use /// If the number of integer bits is zero, the incoming value is treated as normalized, i.e. [-1.0, 1.0]. A typical use
/// for enableRounding would be when converting SNORM/UNORM values to fixed point. /// for enableRounding would be when converting SNORM/UNORM values to fixed point.
/// ///
/// @param [in] f Floating point value to convert. /// @param [in] f Floating point value to convert.
/// @param [in] intBits Number of integer bits (including the sign bit) in the fixed point output. /// @param [in] intBits Number of integer bits (including the sign bit) in the fixed point output.
/// @param [in] fracBits Number of fractional bits in the fixed point output. /// @param [in] fracBits Number of fractional bits in the fixed point output.
/// @param [in] enableRounding Round before conversion. /// @param [in] enableRounding Round before conversion.
/// ///
/// @returns Fixed point number in a uint32. /// @returns Fixed point number in a uint32.
extern uint32 FloatToUFixed(float f, uint32 intBits, uint32 fracBits, bool enableRounding = false); extern uint32 FloatToUFixed(float f, uint32 intBits, uint32 fracBits, bool enableRounding = false);
/// @brief Converts a signed fixed point number with the given integer and fractional bits to a floating point number. /// @brief Converts a signed fixed point number with the given integer and fractional bits to a floating point number.
/// ///
/// If the number of integer bits is zero, the incoming value is treated as normalized, i.e. [-1.0, 1.0]. If numIntBits /// If the number of integer bits is zero, the incoming value is treated as normalized, i.e. [-1.0, 1.0]. If numIntBits
/// is 0, numFracBits is assumed to have 1 bit for the sign, otherwise the sign bit is assumed to be part of the integer /// is 0, numFracBits is assumed to have 1 bit for the sign, otherwise the sign bit is assumed to be part of the integer
/// bits. /// bits.
/// ///
/// @param [in] fixedPtNum Fixed point number to convert. /// @param [in] fixedPtNum Fixed point number to convert.
/// @param [in] intBits Number of integer bits (including the sign bit). /// @param [in] intBits Number of integer bits (including the sign bit).
/// @param [in] fracBits Number of fractional bits. /// @param [in] fracBits Number of fractional bits.
/// ///
/// @returns Converted floating point number. /// @returns Converted floating point number.
extern float SFixedToFloat(int32 fixedPtNum, uint32 intBits, uint32 fracBits); extern float SFixedToFloat(int32 fixedPtNum, uint32 intBits, uint32 fracBits);
/// @brief Converts a unsigned fixed point number with the given integer and fractional bits to a floating point number. /// @brief Converts a unsigned fixed point number with the given integer and fractional bits to a floating point number.
/// ///
/// If the number of integer bits is zero, the incoming value is treated as normalized, i.e. [0, 1.0]. /// If the number of integer bits is zero, the incoming value is treated as normalized, i.e. [0, 1.0].
/// ///
/// @param [in] fixedPtNum Fixed point number to convert. /// @param [in] fixedPtNum Fixed point number to convert.
/// @param [in] intBits Number of integer bits (including the sign bit). /// @param [in] intBits Number of integer bits (including the sign bit).
/// @param [in] fracBits Number of fractional bits. /// @param [in] fracBits Number of fractional bits.
/// ///
/// @returns Converted floating point number. /// @returns Converted floating point number.
extern float UFixedToFloat(uint32 fixedPtNum, uint32 intBits, uint32 fracBits); extern float UFixedToFloat(uint32 fixedPtNum, uint32 intBits, uint32 fracBits);
/// Converts a 32-bit IEEE floating point number to a 16-bit signed floating point number. /// Converts a 32-bit IEEE floating point number to a 16-bit signed floating point number.
extern uint32 Float32ToFloat16(float f); extern uint32 Float32ToFloat16(float f);
/// Converts a 32-bit IEEE floating point number to an 11-bit signed floating point number. /// Converts a 32-bit IEEE floating point number to an 11-bit signed floating point number.
extern uint32 Float32ToFloat11(float f); extern uint32 Float32ToFloat11(float f);
/// Converts a 32-bit IEEE floating point number to a 10-bit signed floating point number. /// Converts a 32-bit IEEE floating point number to a 10-bit signed floating point number.
extern uint32 Float32ToFloat10(float f); extern uint32 Float32ToFloat10(float f);
/// Converts a 32-bit IEEE floating-point number to a 10-bit unsigned floating-point number. /// Converts a 32-bit IEEE floating-point number to a 10-bit unsigned floating-point number.
extern uint32 Float32ToFloat10_6e4(float f); extern uint32 Float32ToFloat10_6e4(float f);
/// Converts a 10-bit signed floating point number to a 32-bit IEEE floating point number. /// Converts a 10-bit signed floating point number to a 32-bit IEEE floating point number.
extern float Float10_6e4ToFloat32(uint32 fBits); extern float Float10_6e4ToFloat32(uint32 fBits);
/// Converts a 32-bit IEEE floating point number to a N-bit signed floating point number. /// Converts a 32-bit IEEE floating point number to a N-bit signed floating point number.
extern uint32 Float32ToNumBits(float float32, uint32 numBits); extern uint32 Float32ToNumBits(float float32, uint32 numBits);
/// Converts a 16-bit signed floating point number to a 32-bit IEEE floating point number. /// Converts a 16-bit signed floating point number to a 32-bit IEEE floating point number.
extern float Float16ToFloat32(uint32 fBits); extern float Float16ToFloat32(uint32 fBits);
/// Converts an 11-bit signed floating point number to a 32-bit IEEE floating point number. /// Converts an 11-bit signed floating point number to a 32-bit IEEE floating point number.
extern float Float11ToFloat32(uint32 fBits); extern float Float11ToFloat32(uint32 fBits);
/// Converts a 10-bit signed floating point number to a 32-bit IEEE floating point number. /// Converts a 10-bit signed floating point number to a 32-bit IEEE floating point number.
extern float Float10ToFloat32(uint32 fBits); extern float Float10ToFloat32(uint32 fBits);
/// Converts an N-bit signed floating point number to a 32-bit IEEE floating point number. /// Converts an N-bit signed floating point number to a 32-bit IEEE floating point number.
extern float FloatNumBitsToFloat32(uint32 input, uint32 numBits); extern float FloatNumBitsToFloat32(uint32 input, uint32 numBits);
/// Converts a 32-bit IEEE floating point number to a fraction. /// Converts a 32-bit IEEE floating point number to a fraction.
extern Fraction Float32ToFraction(float float32); extern Fraction Float32ToFraction(float float32);
/// Returns the square root of the specified value. /// Returns the square root of the specified value.
extern float Sqrt(float f); extern float Sqrt(float f);
/// Returns the result of an exponent operation (base^exponent). /// Returns the result of an exponent operation (base^exponent).
extern float Pow(float base, float exponent); extern float Pow(float base, float exponent);
/// Returns the unsigned integer absolute value. /// Returns the unsigned integer absolute value.
extern uint32 Absu(int32 number); extern uint32 Absu(int32 number);
/// Return sign-preserved zero if input is denorm, otherwise input value /// Return sign-preserved zero if input is denorm, otherwise input value
extern float FlushDenormToZero(float input); extern float FlushDenormToZero(float input);
/// Return value in 1.7 signed magnitude format. Valid input range is (-127, 127) /// Return value in 1.7 signed magnitude format. Valid input range is (-127, 127)
extern uint8 IntToSignedMagnitude(int8 input); extern uint8 IntToSignedMagnitude(int8 input);
/// @brief Performs unsigned fixed-point rounding operation. /// @brief Performs unsigned fixed-point rounding operation.
/// ///
/// @param [in] value Fixed point number to convert in Qm.f format. /// @param [in] value Fixed point number to convert in Qm.f format.
/// @param [in] n Number of fractional bits. /// @param [in] n Number of fractional bits.
/// ///
/// @returns rounded fixed point number in Q0 format (unsigned integer). /// @returns rounded fixed point number in Q0 format (unsigned integer).
constexpr uint32 UFixedRoundToUint32(uint32 value, uint8 n) constexpr uint32 UFixedRoundToUint32(uint32 value, uint8 n)
{ {
PAL_CONSTEXPR_ASSERT((0 < n) && (n < 31)); PAL_CONSTEXPR_ASSERT((0 < n) && (n < 31));
return ((value + (((1 << n) >> 1))) >> n); return ((value + (((1 << n) >> 1))) >> n);
} }
/// @brief Performs signed fixed-point rounding operation. /// @brief Performs signed fixed-point rounding operation.
/// ///
/// @param [in] value Fixed point number to convert in Qm.f format. /// @param [in] value Fixed point number to convert in Qm.f format.
/// @param [in] n Number of fractional bits. /// @param [in] n Number of fractional bits.
/// ///
/// @returns rounded fixed point number in Q0 format (signed integer). /// @returns rounded fixed point number in Q0 format (signed integer).
constexpr int32 SFixedRoundToInt32(int32 value, uint8 n) constexpr int32 SFixedRoundToInt32(int32 value, uint8 n)
{ {
PAL_CONSTEXPR_ASSERT((0 < n) && (n < 30)); PAL_CONSTEXPR_ASSERT((0 < n) && (n < 30));
return ((value + (((1 << n) >> 1))) >> n); return ((value + (((1 << n) >> 1))) >> n);
} }
} // Math } // Math
} // Util } // Util
+158 -158
파일 보기
@@ -1,158 +1,158 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palMemTracker.h * @file palMemTracker.h
* @brief PAL utility collection MemTracker class declaration. * @brief PAL utility collection MemTracker class declaration.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#if PAL_MEMTRACK #if PAL_MEMTRACK
#include "palIntrusiveList.h" #include "palIntrusiveList.h"
#include "palMutex.h" #include "palMutex.h"
namespace Util namespace Util
{ {
// Forward declarations // Forward declarations
struct AllocInfo; struct AllocInfo;
struct FreeInfo; struct FreeInfo;
struct MemTrackerElem; struct MemTrackerElem;
enum SystemAllocType : uint32; enum SystemAllocType : uint32;
/// @internal /// @internal
/// ///
/// An alloc-less list used by the MemTracker to keep track of all allocations. /// An alloc-less list used by the MemTracker to keep track of all allocations.
typedef IntrusiveList<MemTrackerElem> MemTrackerList; typedef IntrusiveList<MemTrackerElem> MemTrackerList;
/// @internal /// @internal
/// ///
/// Specifies whether a particular memory block was allocated with PAL_MALLOC/PAL_CALLOC, PAL_NEW, or PAL_NEW_ARRAY. /// Specifies whether a particular memory block was allocated with PAL_MALLOC/PAL_CALLOC, PAL_NEW, or PAL_NEW_ARRAY.
/// Used to verify correct matching with PAL_FREE, PAL_DELETE, and PAL_DELETE_ARRAY. /// Used to verify correct matching with PAL_FREE, PAL_DELETE, and PAL_DELETE_ARRAY.
enum class MemBlkType : uint32 enum class MemBlkType : uint32
{ {
Malloc = 0, Malloc = 0,
New, New,
NewArray, NewArray,
}; };
/// @internal /// @internal
/// ///
/// Internal structure used by MemTracker to store information on each allocation. /// Internal structure used by MemTracker to store information on each allocation.
struct MemTrackerElem struct MemTrackerElem
{ {
size_t size; ///< Size of allocation request. size_t size; ///< Size of allocation request.
MemBlkType blockType; ///< Memory block type (malloc, new, new array). MemBlkType blockType; ///< Memory block type (malloc, new, new array).
const char* pFilename; ///< File that requested allocation. const char* pFilename; ///< File that requested allocation.
uint32 lineNumber; ///< Line number that requested allocation. uint32 lineNumber; ///< Line number that requested allocation.
void* pClientMem; ///< Starting "client usable" data address. void* pClientMem; ///< Starting "client usable" data address.
void* pOrigMem; ///< Original address of the allocation returned from our underlying allocator. void* pOrigMem; ///< Original address of the allocation returned from our underlying allocator.
size_t allocNum; ///< The number of the memory allocation. 1 based. size_t allocNum; ///< The number of the memory allocation. 1 based.
MemTrackerList* pList; ///< The list this struct is in. It helps check which MemTracker owns this struct. MemTrackerList* pList; ///< The list this struct is in. It helps check which MemTracker owns this struct.
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Class responsible for tracking allocations and frees to notify the developer of memory leaks. * @brief Class responsible for tracking allocations and frees to notify the developer of memory leaks.
* *
* Tracking is enabled/disabled via the PAL_MEMTRACK define. * Tracking is enabled/disabled via the PAL_MEMTRACK define.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template <typename Allocator> template <typename Allocator>
class MemTracker class MemTracker
{ {
public: public:
/// Constructor. /// Constructor.
/// ///
/// @param [in] pAllocator The allocator that will allocate memory if required. /// @param [in] pAllocator The allocator that will allocate memory if required.
MemTracker(Allocator*const pAllocator); MemTracker(Allocator*const pAllocator);
~MemTracker(); ~MemTracker();
/// Performs any non-safe initialization that cannot be done in the constructor. /// Performs any non-safe initialization that cannot be done in the constructor.
/// ///
/// @returns Result::Success if initialization is successful, otherwise an appropriate error. /// @returns Result::Success if initialization is successful, otherwise an appropriate error.
Result Init(); Result Init();
/// Allocates a block of memory and track it using the memory tracker. /// Allocates a block of memory and track it using the memory tracker.
/// ///
/// @param [in] allocInfo Contains information about the requested allocation. /// @param [in] allocInfo Contains information about the requested allocation.
/// ///
/// @returns Pointer to the allocated memory, nullptr if the allocation failed. /// @returns Pointer to the allocated memory, nullptr if the allocation failed.
void* Alloc( void* Alloc(
const AllocInfo& allocInfo); const AllocInfo& allocInfo);
/// Frees a block of memory. /// Frees a block of memory.
/// ///
/// @param [in] freeInfo Contains information about the requested free. /// @param [in] freeInfo Contains information about the requested free.
void Free( void Free(
const FreeInfo& freeInfo); const FreeInfo& freeInfo);
private: private:
void* AddMemElement( void* AddMemElement(
void* pMem, void* pMem,
size_t bytes, size_t bytes,
size_t align, size_t align,
MemBlkType blockType, MemBlkType blockType,
const char* pFilename, const char* pFilename,
uint32 lineNumber); uint32 lineNumber);
void* RemoveMemElement(void* pMem, MemBlkType blockType); void* RemoveMemElement(void* pMem, MemBlkType blockType);
void MemoryReport(); void MemoryReport();
void FreeLeakedMemory(); void FreeLeakedMemory();
// Sentinel patterns used to detect memory underrun. // Sentinel patterns used to detect memory underrun.
static constexpr uint32 UnderrunSentinel = 0xDEADBEEF; static constexpr uint32 UnderrunSentinel = 0xDEADBEEF;
// Sentinel patterns used to detect memory overrun. // Sentinel patterns used to detect memory overrun.
static constexpr uint32 OverrunSentinel = 0xCAFEBABE; static constexpr uint32 OverrunSentinel = 0xCAFEBABE;
// Size of markers for underruns/overruns. Setting this to 0 disables this feature. // Size of markers for underruns/overruns. Setting this to 0 disables this feature.
static constexpr size_t MarkerSizeUints = PAL_CACHE_LINE_BYTES / sizeof(uint32); static constexpr size_t MarkerSizeUints = PAL_CACHE_LINE_BYTES / sizeof(uint32);
// Size of underrun/overrun markers in bytes. // Size of underrun/overrun markers in bytes.
static constexpr size_t MarkerSizeBytes = MarkerSizeUints * sizeof(uint32); static constexpr size_t MarkerSizeBytes = MarkerSizeUints * sizeof(uint32);
MemTrackerList m_trackerList; // The list of active allocations. MemTrackerList m_trackerList; // The list of active allocations.
Mutex m_mutex; // Serializes access to list of active allocations. Mutex m_mutex; // Serializes access to list of active allocations.
const size_t m_markerSizeUints; // Member variable copy of MarkerSizeUints. Only used to prevent compiler const size_t m_markerSizeUints; // Member variable copy of MarkerSizeUints. Only used to prevent compiler
// warnings when MarkerSizeUints is 0. // warnings when MarkerSizeUints is 0.
const size_t m_markerSizeBytes; // Member variable copy of MarkerSizeBytes. Only used to prevent compiler const size_t m_markerSizeBytes; // Member variable copy of MarkerSizeBytes. Only used to prevent compiler
// warnings when MarkerSizeBytes is 0. // warnings when MarkerSizeBytes is 0.
Allocator*const m_pAllocator; // Allocator for performing the actual allocations. Allocator*const m_pAllocator; // Allocator for performing the actual allocations.
size_t m_nextAllocNum; // The allocation number that the next allocated block will receive. size_t m_nextAllocNum; // The allocation number that the next allocated block will receive.
const size_t m_breakOnAllocNum; // The allocation number to trigger a debug break on. const size_t m_breakOnAllocNum; // The allocation number to trigger a debug break on.
PAL_DISALLOW_COPY_AND_ASSIGN(MemTracker); PAL_DISALLOW_COPY_AND_ASSIGN(MemTracker);
}; };
} // Util } // Util
#endif #endif
+331 -331
파일 보기
@@ -1,331 +1,331 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palMemTrackerImpl.h * @file palMemTrackerImpl.h
* @brief PAL utility collection MemTracker class implementations. * @brief PAL utility collection MemTracker class implementations.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#if PAL_MEMTRACK #if PAL_MEMTRACK
#include "palIntrusiveListImpl.h" #include "palIntrusiveListImpl.h"
#include "palMemTracker.h" #include "palMemTracker.h"
#include "palSysMemory.h" #include "palSysMemory.h"
#include <cstring> #include <cstring>
namespace Util namespace Util
{ {
/// Table to convert a blockType to a string. Used by the logging routines. /// Table to convert a blockType to a string. Used by the logging routines.
constexpr const char* MemBlkTypeStr[] = constexpr const char* MemBlkTypeStr[] =
{ {
"Malloc", ///< MemBlkType::Malloc "Malloc", ///< MemBlkType::Malloc
"New", ///< MemBlkType::New "New", ///< MemBlkType::New
"NewArray", ///< MemBlkType::NewArray "NewArray", ///< MemBlkType::NewArray
}; };
// ===================================================================================================================== // =====================================================================================================================
template <typename Allocator> template <typename Allocator>
MemTracker<Allocator>::MemTracker( MemTracker<Allocator>::MemTracker(
Allocator*const pAllocator) Allocator*const pAllocator)
: :
m_markerSizeUints(MarkerSizeUints), m_markerSizeUints(MarkerSizeUints),
m_markerSizeBytes(MarkerSizeBytes), m_markerSizeBytes(MarkerSizeBytes),
m_pAllocator(pAllocator), m_pAllocator(pAllocator),
m_nextAllocNum(1), m_nextAllocNum(1),
m_breakOnAllocNum(0) m_breakOnAllocNum(0)
{ {
} }
// ===================================================================================================================== // =====================================================================================================================
template <typename Allocator> template <typename Allocator>
MemTracker<Allocator>::~MemTracker() MemTracker<Allocator>::~MemTracker()
{ {
// Clean-up leaked memory if needed // Clean-up leaked memory if needed
if (m_trackerList.IsEmpty() == false) if (m_trackerList.IsEmpty() == false)
{ {
// If the list isn't empty, we have a leak. The leak could either be caused by an internal PAL leak, // If the list isn't empty, we have a leak. The leak could either be caused by an internal PAL leak,
// a client leak, or even the application not destroying API objects. // a client leak, or even the application not destroying API objects.
PAL_ALERT_ALWAYS(); PAL_ALERT_ALWAYS();
// Dump out a list of unfreed blocks. // Dump out a list of unfreed blocks.
MemoryReport(); MemoryReport();
FreeLeakedMemory(); FreeLeakedMemory();
} }
} }
// ===================================================================================================================== // =====================================================================================================================
template <typename Allocator> template <typename Allocator>
Result MemTracker<Allocator>::Init() Result MemTracker<Allocator>::Init()
{ {
return Result::Success; return Result::Success;
} }
// ===================================================================================================================== // =====================================================================================================================
// Adds the newly allocated memory block to the list of blocks for tracking. // Adds the newly allocated memory block to the list of blocks for tracking.
// //
// The tracking information includes things like filename, line numbers, and type of block. Also, given a pointer, // The tracking information includes things like filename, line numbers, and type of block. Also, given a pointer,
// adds the Underrun/Overrun markers to the memory allocated, and return a pointer to the actual client usable memory. // adds the Underrun/Overrun markers to the memory allocated, and return a pointer to the actual client usable memory.
// //
// See MemTracker::Alloc() which is used to allocate memory that is being tracked. // See MemTracker::Alloc() which is used to allocate memory that is being tracked.
template <typename Allocator> template <typename Allocator>
void* MemTracker<Allocator>::AddMemElement( void* MemTracker<Allocator>::AddMemElement(
void* pMem, // [in,out] Original pointer allocated by MemTracker::Alloc. void* pMem, // [in,out] Original pointer allocated by MemTracker::Alloc.
size_t bytes, // Client requested allocation size in bytes. size_t bytes, // Client requested allocation size in bytes.
size_t align, // The max of the client-requested alignment or the internal alignment, in bytes. size_t align, // The max of the client-requested alignment or the internal alignment, in bytes.
MemBlkType blockType, // Block type based on calling allocation routine. MemBlkType blockType, // Block type based on calling allocation routine.
const char* pFilename, // Client filename that is requesting the memory. const char* pFilename, // Client filename that is requesting the memory.
uint32 lineNumber) // Line number in client file that is requesting the memory. uint32 lineNumber) // Line number in client file that is requesting the memory.
{ {
// Our internal data is all relative to the client pointer so find that first. See Alloc for more details. // Our internal data is all relative to the client pointer so find that first. See Alloc for more details.
// (align1)(MemTrackerList::Node)(MemTrackerElem)(underflow tracker)(client allocation)(align2)(overflow tracker) // (align1)(MemTrackerList::Node)(MemTrackerElem)(underflow tracker)(client allocation)(align2)(overflow tracker)
constexpr size_t InternalSize = sizeof(MemTrackerList::Node) + sizeof(MemTrackerElem); constexpr size_t InternalSize = sizeof(MemTrackerList::Node) + sizeof(MemTrackerElem);
void*const pClientMem = VoidPtrAlign(VoidPtrInc(pMem, m_markerSizeBytes + InternalSize), align); void*const pClientMem = VoidPtrAlign(VoidPtrInc(pMem, m_markerSizeBytes + InternalSize), align);
uint32* pUnderrun = static_cast<uint32*>(VoidPtrDec(pClientMem, m_markerSizeBytes)); uint32* pUnderrun = static_cast<uint32*>(VoidPtrDec(pClientMem, m_markerSizeBytes));
uint32* pOverrun = static_cast<uint32*>(VoidPtrInc(pClientMem, Pow2Align(bytes, sizeof(uint32)))); uint32* pOverrun = static_cast<uint32*>(VoidPtrInc(pClientMem, Pow2Align(bytes, sizeof(uint32))));
auto*const pNewElement = static_cast<MemTrackerElem*>(VoidPtrDec(pUnderrun, sizeof(MemTrackerElem))); auto*const pNewElement = static_cast<MemTrackerElem*>(VoidPtrDec(pUnderrun, sizeof(MemTrackerElem)));
void*const pNewNodeMem = VoidPtrDec(pNewElement, sizeof(MemTrackerList::Node)); void*const pNewNodeMem = VoidPtrDec(pNewElement, sizeof(MemTrackerList::Node));
auto*const pNewNode = PAL_PLACEMENT_NEW(pNewNodeMem) MemTrackerList::Node(pNewElement); auto*const pNewNode = PAL_PLACEMENT_NEW(pNewNodeMem) MemTrackerList::Node(pNewElement);
// Mark the memory with the underrun/overrun marker. // Mark the memory with the underrun/overrun marker.
for (uint32 markerUints = 0; markerUints < m_markerSizeUints; ++markerUints) for (uint32 markerUints = 0; markerUints < m_markerSizeUints; ++markerUints)
{ {
*pUnderrun++ = UnderrunSentinel; *pUnderrun++ = UnderrunSentinel;
*pOverrun++ = OverrunSentinel; *pOverrun++ = OverrunSentinel;
} }
pNewElement->size = bytes; pNewElement->size = bytes;
pNewElement->pFilename = pFilename; pNewElement->pFilename = pFilename;
pNewElement->lineNumber = lineNumber; pNewElement->lineNumber = lineNumber;
pNewElement->blockType = blockType; pNewElement->blockType = blockType;
pNewElement->pClientMem = pClientMem; pNewElement->pClientMem = pClientMem;
pNewElement->pOrigMem = pMem; pNewElement->pOrigMem = pMem;
pNewElement->pList = &m_trackerList; pNewElement->pList = &m_trackerList;
MutexAuto lock(&m_mutex); MutexAuto lock(&m_mutex);
// Trigger an assert if we're about to allocate the break-on-allocation number. // Trigger an assert if we're about to allocate the break-on-allocation number.
if (m_nextAllocNum == m_breakOnAllocNum) if (m_nextAllocNum == m_breakOnAllocNum)
{ {
PAL_ASSERT_ALWAYS(); PAL_ASSERT_ALWAYS();
} }
pNewElement->allocNum = m_nextAllocNum; pNewElement->allocNum = m_nextAllocNum;
++m_nextAllocNum; ++m_nextAllocNum;
m_trackerList.PushFront(pNewNode); m_trackerList.PushFront(pNewNode);
return pClientMem; return pClientMem;
} }
// ===================================================================================================================== // =====================================================================================================================
// Removes an allocated block from the list of blocks used for tracking. // Removes an allocated block from the list of blocks used for tracking.
// //
// The routine checks for invalid frees (and duplicate frees). Also, the routine is able to detect mismatched alloc/free // The routine checks for invalid frees (and duplicate frees). Also, the routine is able to detect mismatched alloc/free
// usage based on the blockType. The routine is called with the pointer to the client usable memory and returns the // usage based on the blockType. The routine is called with the pointer to the client usable memory and returns the
// pointer to the allocated memory. // pointer to the allocated memory.
// //
// See MemTracker::Free() which is used to free memory that is being tracked. // See MemTracker::Free() which is used to free memory that is being tracked.
template <typename Allocator> template <typename Allocator>
void* MemTracker<Allocator>::RemoveMemElement( void* MemTracker<Allocator>::RemoveMemElement(
void* pClientMem, // Pointer to client usable memory. void* pClientMem, // Pointer to client usable memory.
MemBlkType blockType) // Block type based on calling deallocation routine. MemBlkType blockType) // Block type based on calling deallocation routine.
{ {
void* pOrigPtr = nullptr; void* pOrigPtr = nullptr;
// Recall that this is our internal memory layout. See Alloc for more details. // Recall that this is our internal memory layout. See Alloc for more details.
// (align1)(MemTrackerList::Node)(MemTrackerElem)(underflow tracker)(client allocation)(align2)(overflow tracker) // (align1)(MemTrackerList::Node)(MemTrackerElem)(underflow tracker)(client allocation)(align2)(overflow tracker)
uint32* pUnderrun = static_cast<uint32*>(VoidPtrDec(pClientMem, m_markerSizeBytes)); uint32* pUnderrun = static_cast<uint32*>(VoidPtrDec(pClientMem, m_markerSizeBytes));
auto*const pCurrent = static_cast<MemTrackerElem*>(VoidPtrDec(pUnderrun, sizeof(MemTrackerElem))); auto*const pCurrent = static_cast<MemTrackerElem*>(VoidPtrDec(pUnderrun, sizeof(MemTrackerElem)));
auto*const pCurrentNode = static_cast<MemTrackerList::Node*>(VoidPtrDec(pCurrent, sizeof(MemTrackerList::Node))); auto*const pCurrentNode = static_cast<MemTrackerList::Node*>(VoidPtrDec(pCurrent, sizeof(MemTrackerList::Node)));
uint32* pOverrun = static_cast<uint32*>(VoidPtrInc(pClientMem, Pow2Align(pCurrent->size, sizeof(uint32)))); uint32* pOverrun = static_cast<uint32*>(VoidPtrInc(pClientMem, Pow2Align(pCurrent->size, sizeof(uint32))));
// We should not be trying to free something twice or trying to free something which has not been allocated // We should not be trying to free something twice or trying to free something which has not been allocated
// by this MemTracker. We can verify both of these things by checking that the tracker's pList is equal to the // by this MemTracker. We can verify both of these things by checking that the tracker's pList is equal to the
// MemTracker's list. // MemTracker's list.
if (pCurrent->pList != &m_trackerList) if (pCurrent->pList != &m_trackerList)
{ {
// A free was attempted on an unrecognized pointer. // A free was attempted on an unrecognized pointer.
PAL_DPERROR("Invalid Free Attempted with ptr = : (%#x)", pClientMem); PAL_DPERROR("Invalid Free Attempted with ptr = : (%#x)", pClientMem);
} }
else if (pCurrent->blockType != blockType) else if (pCurrent->blockType != blockType)
{ {
// We have a mismatch in the alloc/free pair, e.g. PAL_NEW with PAL_FREE etc. return early here without freeing // We have a mismatch in the alloc/free pair, e.g. PAL_NEW with PAL_FREE etc. return early here without freeing
// the memory so it shows up as a leak. // the memory so it shows up as a leak.
PAL_DPERROR("Trying to Free %s as %s.", PAL_DPERROR("Trying to Free %s as %s.",
MemBlkTypeStr[static_cast<uint32>(pCurrent->blockType)], MemBlkTypeStr[static_cast<uint32>(pCurrent->blockType)],
MemBlkTypeStr[static_cast<uint32>(blockType)]); MemBlkTypeStr[static_cast<uint32>(blockType)]);
} }
else else
{ {
// We should check for memory corruption due to overflow or underflow before continuing because any underflow // We should check for memory corruption due to overflow or underflow before continuing because any underflow
// might indicate that our internal state is corrupted. This could lead to a crash in the code below. // might indicate that our internal state is corrupted. This could lead to a crash in the code below.
for (uint32 markerUints = 0; markerUints < m_markerSizeUints; ++markerUints) for (uint32 markerUints = 0; markerUints < m_markerSizeUints; ++markerUints)
{ {
PAL_ASSERT(*pUnderrun++ == UnderrunSentinel); PAL_ASSERT(*pUnderrun++ == UnderrunSentinel);
PAL_ASSERT(*pOverrun++ == OverrunSentinel); PAL_ASSERT(*pOverrun++ == OverrunSentinel);
} }
// Remove our tracker from the list and set it's pList to null to detect a double-free in the future. // Remove our tracker from the list and set it's pList to null to detect a double-free in the future.
MutexAuto lock(&m_mutex); MutexAuto lock(&m_mutex);
m_trackerList.Erase(pCurrentNode); m_trackerList.Erase(pCurrentNode);
pCurrent->pList = nullptr; pCurrent->pList = nullptr;
pOrigPtr = pCurrent->pOrigMem; pOrigPtr = pCurrent->pOrigMem;
} }
// Return a pointer to the actual allocated block. // Return a pointer to the actual allocated block.
return pOrigPtr; return pOrigPtr;
} }
// ===================================================================================================================== // =====================================================================================================================
// Allocates a block of memory and tracks it using the memory tracker. // Allocates a block of memory and tracks it using the memory tracker.
template <typename Allocator> template <typename Allocator>
void* MemTracker<Allocator>::Alloc( void* MemTracker<Allocator>::Alloc(
const AllocInfo& allocInfo) const AllocInfo& allocInfo)
{ {
// Allocating zero bytes of memory results in undefined behavior. // Allocating zero bytes of memory results in undefined behavior.
PAL_ASSERT(allocInfo.bytes > 0); PAL_ASSERT(allocInfo.bytes > 0);
void* pMem = nullptr; void* pMem = nullptr;
// We want to allocate extra memory from the caller's allocator, in this layout: // We want to allocate extra memory from the caller's allocator, in this layout:
// (align1)(MemTrackerList::Node)(MemTrackerElem)(underflow tracker)(client allocation)(align2)(overflow tracker) // (align1)(MemTrackerList::Node)(MemTrackerElem)(underflow tracker)(client allocation)(align2)(overflow tracker)
// Here's why we need each of those sections: // Here's why we need each of those sections:
// 1. align1 is zero or more bytes needed to align the client allocation and our internal data. // 1. align1 is zero or more bytes needed to align the client allocation and our internal data.
// 2. The MemTrackerList::Node object, which is used to link this allocation into m_trackerList. // 2. The MemTrackerList::Node object, which is used to link this allocation into m_trackerList.
// 3. The MemTrackerElem struct contains bookkeeping data we need to report memory errors. // 3. The MemTrackerElem struct contains bookkeeping data we need to report memory errors.
// 4. The underflow and overflow trackers detect out of bounds writes. They are optional. // 4. The underflow and overflow trackers detect out of bounds writes. They are optional.
// 5. The client allocation, which is actually returned to the caller. // 5. The client allocation, which is actually returned to the caller.
// 6. align2 is zero or more bytes needed to DWORD-align the overflow tracker. // 6. align2 is zero or more bytes needed to DWORD-align the overflow tracker.
constexpr size_t InternalAlignment = Max(alignof(MemTrackerList::Node), alignof(MemTrackerElem)); constexpr size_t InternalAlignment = Max(alignof(MemTrackerList::Node), alignof(MemTrackerElem));
const size_t paddedAlignBytes = Max(allocInfo.alignment, InternalAlignment); const size_t paddedAlignBytes = Max(allocInfo.alignment, InternalAlignment);
const size_t paddedSizeBytes = (paddedAlignBytes + // 1 const size_t paddedSizeBytes = (paddedAlignBytes + // 1
sizeof(MemTrackerList::Node) + // 2 sizeof(MemTrackerList::Node) + // 2
sizeof(MemTrackerElem) + // 3 sizeof(MemTrackerElem) + // 3
m_markerSizeBytes + // 4.a m_markerSizeBytes + // 4.a
Pow2Align(allocInfo.bytes, sizeof(uint32)) + // 5 & 6 Pow2Align(allocInfo.bytes, sizeof(uint32)) + // 5 & 6
m_markerSizeBytes); // 4.b m_markerSizeBytes); // 4.b
const AllocInfo memTrackerInfo(paddedSizeBytes, paddedAlignBytes, allocInfo.zeroMem, allocInfo.allocType, const AllocInfo memTrackerInfo(paddedSizeBytes, paddedAlignBytes, allocInfo.zeroMem, allocInfo.allocType,
allocInfo.blockType, allocInfo.pFilename, allocInfo.lineNumber); allocInfo.blockType, allocInfo.pFilename, allocInfo.lineNumber);
pMem = m_pAllocator->Alloc(memTrackerInfo); pMem = m_pAllocator->Alloc(memTrackerInfo);
if (pMem != nullptr) if (pMem != nullptr)
{ {
// Don't bother adding a failed allocation to the Memtrack list. // Don't bother adding a failed allocation to the Memtrack list.
pMem = AddMemElement(pMem, pMem = AddMemElement(pMem,
allocInfo.bytes, allocInfo.bytes,
paddedAlignBytes, paddedAlignBytes,
allocInfo.blockType, allocInfo.blockType,
allocInfo.pFilename, allocInfo.pFilename,
allocInfo.lineNumber); allocInfo.lineNumber);
} }
return pMem; return pMem;
} }
// ===================================================================================================================== // =====================================================================================================================
// Frees a block of memory. The routine is called with the pointer to the client usable memory. // Frees a block of memory. The routine is called with the pointer to the client usable memory.
// //
// See MemTracker::RemoveMemElement() which is used to validate the free. // See MemTracker::RemoveMemElement() which is used to validate the free.
template <typename Allocator> template <typename Allocator>
void MemTracker<Allocator>::Free( void MemTracker<Allocator>::Free(
const FreeInfo& freeInfo) const FreeInfo& freeInfo)
{ {
// Don't want to call RemoveMemElement if the ptr is null. // Don't want to call RemoveMemElement if the ptr is null.
if (freeInfo.pClientMem != nullptr) if (freeInfo.pClientMem != nullptr)
{ {
void* pMem = RemoveMemElement(freeInfo.pClientMem, freeInfo.blockType); void* pMem = RemoveMemElement(freeInfo.pClientMem, freeInfo.blockType);
// If this free call is valid (RemoveMemElement doesn't return nullptr), release the memory. // If this free call is valid (RemoveMemElement doesn't return nullptr), release the memory.
if (pMem != nullptr) if (pMem != nullptr)
{ {
m_pAllocator->Free(FreeInfo(pMem, freeInfo.blockType)); m_pAllocator->Free(FreeInfo(pMem, freeInfo.blockType));
} }
} }
} }
// ===================================================================================================================== // =====================================================================================================================
// Frees all memory that has not been explicitly freed (in other words, memory that has leaked). This function is only // Frees all memory that has not been explicitly freed (in other words, memory that has leaked). This function is only
// expected to be called when the memory tracker is being destroyed. // expected to be called when the memory tracker is being destroyed.
template <typename Allocator> template <typename Allocator>
void MemTracker<Allocator>::FreeLeakedMemory() void MemTracker<Allocator>::FreeLeakedMemory()
{ {
for (MemTrackerList::Iter iter = m_trackerList.Begin(); iter.IsValid(); ) for (MemTrackerList::Iter iter = m_trackerList.Begin(); iter.IsValid(); )
{ {
MemTrackerElem*const pCurrent = iter.Get(); MemTrackerElem*const pCurrent = iter.Get();
// Free will release the memory for tracking and the actual element. This will invalidate our list iterator // Free will release the memory for tracking and the actual element. This will invalidate our list iterator
// unless we advance the iterator first. // unless we advance the iterator first.
iter.Next(); iter.Next();
Free(FreeInfo(pCurrent->pClientMem, pCurrent->blockType)); Free(FreeInfo(pCurrent->pClientMem, pCurrent->blockType));
} }
} }
// ===================================================================================================================== // =====================================================================================================================
// Outputs information about leaked memory by traversing the memory tracker list. // Outputs information about leaked memory by traversing the memory tracker list.
template <typename Allocator> template <typename Allocator>
void MemTracker<Allocator>::MemoryReport() void MemTracker<Allocator>::MemoryReport()
{ {
// When this env var is set to non-zero, don't report leaks. // When this env var is set to non-zero, don't report leaks.
// Useful for crashing apps that don't give us a chance to clean up. // Useful for crashing apps that don't give us a chance to clean up.
const char* pToggle = getenv("AMDPAL_NO_LEAK_REPORT"); const char* pToggle = getenv("AMDPAL_NO_LEAK_REPORT");
if ((pToggle == nullptr) || (atoi(pToggle) == 0)) if ((pToggle == nullptr) || (atoi(pToggle) == 0))
{ {
PAL_DPWARN("================ List of Leaked Blocks ================"); PAL_DPWARN("================ List of Leaked Blocks ================");
for (MemTrackerList::Iter iter = m_trackerList.Begin(); iter.IsValid(); iter.Next()) for (MemTrackerList::Iter iter = m_trackerList.Begin(); iter.IsValid(); iter.Next())
{ {
MemTrackerElem*const pCurrent = iter.Get(); MemTrackerElem*const pCurrent = iter.Get();
PAL_DPWARN( PAL_DPWARN(
"ClientMem = 0x%p, AllocSize = %8d, MemBlkType = %s, File = %-15s, LineNumber = %8d, AllocNum = %8d", "ClientMem = 0x%p, AllocSize = %8d, MemBlkType = %s, File = %-15s, LineNumber = %8d, AllocNum = %8d",
pCurrent->pClientMem, pCurrent->pClientMem,
pCurrent->size, pCurrent->size,
MemBlkTypeStr[static_cast<uint32>(pCurrent->blockType)], MemBlkTypeStr[static_cast<uint32>(pCurrent->blockType)],
pCurrent->pFilename, pCurrent->pFilename,
pCurrent->lineNumber, pCurrent->lineNumber,
pCurrent->allocNum); pCurrent->allocNum);
} }
PAL_DPWARN("================ End of List ==========================="); PAL_DPWARN("================ End of List ===========================");
} }
} }
} // Util } // Util
#endif #endif
+398 -398
파일 보기
@@ -1,398 +1,398 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2014-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palMutex.h * @file palMutex.h
* @brief PAL utility collection Mutex and MutexAuto class declarations. * @brief PAL utility collection Mutex and MutexAuto class declarations.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palAssert.h" #include "palAssert.h"
#if defined(_WIN32) #if defined(_WIN32)
// WIN32_NO_STATUS prevents winnt.h from re-defining NTSTATUS macros that cause build warnings if // WIN32_NO_STATUS prevents winnt.h from re-defining NTSTATUS macros that cause build warnings if
// ntstatus.h is also included. // ntstatus.h is also included.
#define WIN32_NO_STATUS #define WIN32_NO_STATUS
#include <windows.h> #include <windows.h>
#undef WIN32_NO_STATUS #undef WIN32_NO_STATUS
#else #else
#include <pthread.h> #include <pthread.h>
#include <string.h> #include <string.h>
#endif #endif
namespace Util namespace Util
{ {
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Platform-agnostic mutex primitive. * @brief Platform-agnostic mutex primitive.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class Mutex class Mutex
{ {
public: public:
#if defined(_WIN32) #if defined(_WIN32)
/// Defines MutexData as a Windows CRITICAL_SECTION /// Defines MutexData as a Windows CRITICAL_SECTION
typedef CRITICAL_SECTION MutexData; typedef CRITICAL_SECTION MutexData;
Mutex() noexcept : m_osMutex {} { InitializeCriticalSection(&m_osMutex); } Mutex() noexcept : m_osMutex {} { InitializeCriticalSection(&m_osMutex); }
~Mutex() { DeleteCriticalSection(&m_osMutex); }; ~Mutex() { DeleteCriticalSection(&m_osMutex); };
#else #else
/// Defines MutexData as a unix pthread_mutex_t /// Defines MutexData as a unix pthread_mutex_t
typedef pthread_mutex_t MutexData; typedef pthread_mutex_t MutexData;
Mutex() noexcept : m_osMutex {} { pthread_mutex_init(&m_osMutex, nullptr); } Mutex() noexcept : m_osMutex {} { pthread_mutex_init(&m_osMutex, nullptr); }
~Mutex() { pthread_mutex_destroy(&m_osMutex); }; ~Mutex() { pthread_mutex_destroy(&m_osMutex); };
#endif #endif
/// Enters the critical section if it is not contended. If it is contended, wait for the critical section to become /// Enters the critical section if it is not contended. If it is contended, wait for the critical section to become
/// available, then enter it. /// available, then enter it.
void Lock(); void Lock();
/// Enters the critical section if it is not contended. Does not wait for the critical section to become available /// Enters the critical section if it is not contended. Does not wait for the critical section to become available
/// if it is contended. /// if it is contended.
/// ///
/// @returns True if the critical section was entered, false otherwise. /// @returns True if the critical section was entered, false otherwise.
bool TryLock(); bool TryLock();
/// Leaves the critical section. /// Leaves the critical section.
void Unlock(); void Unlock();
/// Returns the OS specific mutex data. /// Returns the OS specific mutex data.
MutexData* GetMutexData() { return &m_osMutex; } MutexData* GetMutexData() { return &m_osMutex; }
private: private:
MutexData m_osMutex; ///< Opaque structure to the OS-specific Mutex data MutexData m_osMutex; ///< Opaque structure to the OS-specific Mutex data
PAL_DISALLOW_COPY_AND_ASSIGN(Mutex); PAL_DISALLOW_COPY_AND_ASSIGN(Mutex);
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief A "resource acquisition is initialization" (RAII) wrapper for the Mutex class. * @brief A "resource acquisition is initialization" (RAII) wrapper for the Mutex class.
* *
* The RAII paradigm allows critical sections to be automatically acquired during this class' constructor, and * The RAII paradigm allows critical sections to be automatically acquired during this class' constructor, and
* automatically released when a stack-allocated wrapper object goes out-of-scope. As such, it only makes sense to use * automatically released when a stack-allocated wrapper object goes out-of-scope. As such, it only makes sense to use
* this class for stack-allocated objects. * this class for stack-allocated objects.
* *
* This object will ensure that anything between when the object is allocated on the stack and when it goes out of scope * This object will ensure that anything between when the object is allocated on the stack and when it goes out of scope
* will be protected from access by multiple threads. See the below example. * will be protected from access by multiple threads. See the below example.
* *
* [Code not protected] * [Code not protected]
* { * {
* [Code not protected] * [Code not protected]
* MutexAuto lock(pPtrToMutex); * MutexAuto lock(pPtrToMutex);
* [Code is protected] * [Code is protected]
* } * }
* [Code not protected] * [Code not protected]
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class MutexAuto class MutexAuto
{ {
public: public:
/// Locks the given Mutex. /// Locks the given Mutex.
explicit MutexAuto(Mutex* pMutex) : m_pMutex(pMutex) explicit MutexAuto(Mutex* pMutex) : m_pMutex(pMutex)
{ {
PAL_ASSERT(m_pMutex != nullptr); PAL_ASSERT(m_pMutex != nullptr);
m_pMutex->Lock(); m_pMutex->Lock();
} }
/// Unlocks the Mutex we locked in the constructor. /// Unlocks the Mutex we locked in the constructor.
~MutexAuto() ~MutexAuto()
{ {
m_pMutex->Unlock(); m_pMutex->Unlock();
} }
private: private:
Mutex* const m_pMutex; ///< The Mutex which this object wraps. Mutex* const m_pMutex; ///< The Mutex which this object wraps.
PAL_DISALLOW_DEFAULT_CTOR(MutexAuto); PAL_DISALLOW_DEFAULT_CTOR(MutexAuto);
PAL_DISALLOW_COPY_AND_ASSIGN(MutexAuto); PAL_DISALLOW_COPY_AND_ASSIGN(MutexAuto);
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Platform-agnostic rw lock primitive. * @brief Platform-agnostic rw lock primitive.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
class RWLock class RWLock
{ {
public: public:
#if defined(_WIN32) #if defined(_WIN32)
/// Defines RWLockData as a Windows RWLOCK /// Defines RWLockData as a Windows RWLOCK
typedef SRWLOCK RWLockData; typedef SRWLOCK RWLockData;
RWLock() noexcept : m_osRWLock {} { InitializeSRWLock(&m_osRWLock); } RWLock() noexcept : m_osRWLock {} { InitializeSRWLock(&m_osRWLock); }
~RWLock() noexcept { /* No Win32 destory function */ }; ~RWLock() noexcept { /* No Win32 destory function */ };
#else #else
/// Defines RWLockData as a unix pthread_rwlock_t /// Defines RWLockData as a unix pthread_rwlock_t
typedef pthread_rwlock_t RWLockData; typedef pthread_rwlock_t RWLockData;
/// @note pthread_rwlock_init will not fail as called /// @note pthread_rwlock_init will not fail as called
RWLock() noexcept : m_osRWLock {} { pthread_rwlock_init(&m_osRWLock, nullptr); } RWLock() noexcept : m_osRWLock {} { pthread_rwlock_init(&m_osRWLock, nullptr); }
~RWLock() noexcept { pthread_rwlock_destroy(&m_osRWLock); }; ~RWLock() noexcept { pthread_rwlock_destroy(&m_osRWLock); };
#endif #endif
/// Enumerates the lock type of RWLockAuto /// Enumerates the lock type of RWLockAuto
enum LockType enum LockType
{ {
ReadOnly = 0, ///< Lock in readonly mode, in other words shared mode. ReadOnly = 0, ///< Lock in readonly mode, in other words shared mode.
ReadWrite ///< Lock in readwrite mode, in other words exclusive mode. ReadWrite ///< Lock in readwrite mode, in other words exclusive mode.
}; };
/// Acquires a rw lock in shared mode if it is not contended in exclusive mode. /// Acquires a rw lock in shared mode if it is not contended in exclusive mode.
/// If it is contended, wait for rw lock to become available, then enter it. /// If it is contended, wait for rw lock to become available, then enter it.
void LockForRead(); void LockForRead();
/// Acquires a rw lock in exclusive mode if it is not contended. /// Acquires a rw lock in exclusive mode if it is not contended.
/// If it is contended, wait for rw lock to become available, then enter it. /// If it is contended, wait for rw lock to become available, then enter it.
void LockForWrite(); void LockForWrite();
/// Try to acquires a rw lock in shared mode if it is not contended in exclusive mode. /// Try to acquires a rw lock in shared mode if it is not contended in exclusive mode.
/// Does not wait for the rw lock to become available. /// Does not wait for the rw lock to become available.
/// @returns True if the rw lock was acquired, false otherwise. /// @returns True if the rw lock was acquired, false otherwise.
bool TryLockForRead(); bool TryLockForRead();
/// Try to acquires a rw lock in exclusive mode if it is not contended. /// Try to acquires a rw lock in exclusive mode if it is not contended.
/// Does not wait for the rw lock to become available. /// Does not wait for the rw lock to become available.
/// @returns True if the rw lock was acquired, false otherwise. /// @returns True if the rw lock was acquired, false otherwise.
bool TryLockForWrite(); bool TryLockForWrite();
/// Release the rw lock which is previously contended in shared mode. /// Release the rw lock which is previously contended in shared mode.
void UnlockForRead(); void UnlockForRead();
/// Release the rw lock which is previously contended in exclusive mode. /// Release the rw lock which is previously contended in exclusive mode.
void UnlockForWrite(); void UnlockForWrite();
/// Returns the OS specific RWLOCK data. /// Returns the OS specific RWLOCK data.
RWLockData* GetRWLockData() { return &m_osRWLock; } RWLockData* GetRWLockData() { return &m_osRWLock; }
private: private:
RWLockData m_osRWLock; ///< Opaque structure to the OS-specific RWLock data RWLockData m_osRWLock; ///< Opaque structure to the OS-specific RWLock data
PAL_DISALLOW_COPY_AND_ASSIGN(RWLock); PAL_DISALLOW_COPY_AND_ASSIGN(RWLock);
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief A "resource acquisition is initialization" (RAII) wrapper for the RWLock class. * @brief A "resource acquisition is initialization" (RAII) wrapper for the RWLock class.
* *
* The RAII paradigm allows rw lcok to be automatically acquired during this class' constructor, and * The RAII paradigm allows rw lcok to be automatically acquired during this class' constructor, and
* automatically released when a stack-allocated wrapper object goes out-of-scope. As such, it only makes sense to use * automatically released when a stack-allocated wrapper object goes out-of-scope. As such, it only makes sense to use
* this class for stack-allocated objects. * this class for stack-allocated objects.
* *
* This object will ensure that anything between when the object is allocated on the stack and when it goes out of scope * This object will ensure that anything between when the object is allocated on the stack and when it goes out of scope
* will be protected from access by multiple threads. See the below example. * will be protected from access by multiple threads. See the below example.
* *
* [Code not protected] * [Code not protected]
* { * {
* [Code not protected] * [Code not protected]
* RWLockAuto lock(pPtrToMutex, type); * RWLockAuto lock(pPtrToMutex, type);
* [Code is protected] * [Code is protected]
* } * }
* [Code not protected] * [Code not protected]
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template <RWLock::LockType type> template <RWLock::LockType type>
class RWLockAuto class RWLockAuto
{ {
public: public:
/// Locks the given RWLock. /// Locks the given RWLock.
explicit RWLockAuto(RWLock* pRWLock) : m_pRWLock(pRWLock) explicit RWLockAuto(RWLock* pRWLock) : m_pRWLock(pRWLock)
{ {
PAL_ASSERT(m_pRWLock != nullptr); PAL_ASSERT(m_pRWLock != nullptr);
if (type == RWLock::ReadOnly) if (type == RWLock::ReadOnly)
{ {
m_pRWLock->LockForRead(); m_pRWLock->LockForRead();
} }
else else
{ {
m_pRWLock->LockForWrite(); m_pRWLock->LockForWrite();
} }
} }
/// Unlocks the RWLock we locked in the constructor. /// Unlocks the RWLock we locked in the constructor.
~RWLockAuto() ~RWLockAuto()
{ {
if (type == RWLock::ReadOnly) if (type == RWLock::ReadOnly)
{ {
m_pRWLock->UnlockForRead(); m_pRWLock->UnlockForRead();
} }
else else
{ {
m_pRWLock->UnlockForWrite(); m_pRWLock->UnlockForWrite();
} }
} }
private: private:
RWLock* const m_pRWLock; ///< The RWLock which this object wraps. RWLock* const m_pRWLock; ///< The RWLock which this object wraps.
PAL_DISALLOW_DEFAULT_CTOR(RWLockAuto); PAL_DISALLOW_DEFAULT_CTOR(RWLockAuto);
PAL_DISALLOW_COPY_AND_ASSIGN(RWLockAuto); PAL_DISALLOW_COPY_AND_ASSIGN(RWLockAuto);
}; };
/// Yields the current thread to another thread in the ready state (if available). /// Yields the current thread to another thread in the ready state (if available).
extern void YieldThread(); extern void YieldThread();
/// Atomic write of 64-bit unsigned integer, using a relaxed memory ordering policy. /// Atomic write of 64-bit unsigned integer, using a relaxed memory ordering policy.
/// If you need to synchronize more than just pTarget, you may need a new function. /// If you need to synchronize more than just pTarget, you may need a new function.
/// ///
/// @param [in] pTarget Pointer to the value to be read. /// @param [in] pTarget Pointer to the value to be read.
/// ///
/// @returns The original value of *pTarget. /// @returns The original value of *pTarget.
extern void AtomicWriteRelaxed64(volatile uint64* pTarget, uint64 newValue); extern void AtomicWriteRelaxed64(volatile uint64* pTarget, uint64 newValue);
/// Atomic read of 64-bit unsigned integer, using a relaxed memory ordering policy. /// Atomic read of 64-bit unsigned integer, using a relaxed memory ordering policy.
/// If you need to synchronize more than just pTarget, you may need a new function. /// If you need to synchronize more than just pTarget, you may need a new function.
/// ///
/// @param [in] pTarget Pointer to the value to be read. /// @param [in] pTarget Pointer to the value to be read.
/// ///
/// @returns The original value of *pTarget. /// @returns The original value of *pTarget.
extern uint64 AtomicReadRelaxed64(const volatile uint64* pTarget); extern uint64 AtomicReadRelaxed64(const volatile uint64* pTarget);
/// Atomically increments the specified 32-bit unsigned integer. /// Atomically increments the specified 32-bit unsigned integer.
/// ///
/// @param [in,out] pValue Pointer to the value to be incremented. /// @param [in,out] pValue Pointer to the value to be incremented.
/// ///
/// @returns Result of the increment operation. /// @returns Result of the increment operation.
extern uint32 AtomicIncrement(volatile uint32* pValue); extern uint32 AtomicIncrement(volatile uint32* pValue);
/// Atomically increment a 64-bit-unsigned integer /// Atomically increment a 64-bit-unsigned integer
/// ///
/// @param [in,out] pAddend Pointer to the value to be incremented /// @param [in,out] pAddend Pointer to the value to be incremented
/// ///
/// @returns Result of the increment operation. /// @returns Result of the increment operation.
extern uint64 AtomicIncrement64(volatile uint64* pAddend); extern uint64 AtomicIncrement64(volatile uint64* pAddend);
/// Atomically decrements the specified 32-bit unsigned integer. /// Atomically decrements the specified 32-bit unsigned integer.
/// ///
/// @param [in,out] pValue Pointer to the value to be decremented. /// @param [in,out] pValue Pointer to the value to be decremented.
/// ///
/// @returns Result of the decrement operation. /// @returns Result of the decrement operation.
extern uint32 AtomicDecrement(volatile uint32* pValue); extern uint32 AtomicDecrement(volatile uint32* pValue);
/// Atomically decrements the specified 64-bit unsigned integer. /// Atomically decrements the specified 64-bit unsigned integer.
/// ///
/// @param [in,out] pValue Pointer to the value to be decremented. /// @param [in,out] pValue Pointer to the value to be decremented.
/// ///
/// @returns Result of the decrement operation. /// @returns Result of the decrement operation.
extern uint32 AtomicDecrement64(volatile uint64* pValue); extern uint32 AtomicDecrement64(volatile uint64* pValue);
/// Performs an atomic compare and swap operation on two 32-bit unsigned integers. This operation compares *pTarget /// Performs an atomic compare and swap operation on two 32-bit unsigned integers. This operation compares *pTarget
/// with oldValue and replaces it with newValue if they match. If the values don't match, no action is taken. /// with oldValue and replaces it with newValue if they match. If the values don't match, no action is taken.
/// The original value of *pTarget is returned as a result. /// The original value of *pTarget is returned as a result.
/// ///
/// @param [in,out] pTarget Pointer to the destination value of the operation. /// @param [in,out] pTarget Pointer to the destination value of the operation.
/// @param [in] oldValue Value to compare *pTarget to. /// @param [in] oldValue Value to compare *pTarget to.
/// @param [in] newValue Value to replace *pTarget with if *pTarget matches oldValue. /// @param [in] newValue Value to replace *pTarget with if *pTarget matches oldValue.
/// ///
/// @returns Previous value at *pTarget. /// @returns Previous value at *pTarget.
extern uint32 AtomicCompareAndSwap(volatile uint32* pTarget, uint32 oldValue, uint32 newValue); extern uint32 AtomicCompareAndSwap(volatile uint32* pTarget, uint32 oldValue, uint32 newValue);
/// Atomically exchanges a pair of 32-bit unsigned integers. /// Atomically exchanges a pair of 32-bit unsigned integers.
/// ///
/// @param [in,out] pTarget Pointer to the destination value of the operation. /// @param [in,out] pTarget Pointer to the destination value of the operation.
/// @param [in] value New value to be stored in *pTarget. /// @param [in] value New value to be stored in *pTarget.
/// ///
/// @returns Previous value at *pTarget. /// @returns Previous value at *pTarget.
extern uint32 AtomicExchange(volatile uint32* pTarget, uint32 value); extern uint32 AtomicExchange(volatile uint32* pTarget, uint32 value);
/// Atomically exchanges a pair of 64-bit unsigned integers. /// Atomically exchanges a pair of 64-bit unsigned integers.
/// ///
/// @param [in,out] pTarget Pointer to the destination value of the operation. /// @param [in,out] pTarget Pointer to the destination value of the operation.
/// @param [in] value New value to be stored in *pTarget. /// @param [in] value New value to be stored in *pTarget.
/// ///
/// @returns Previous value at *pTarget. /// @returns Previous value at *pTarget.
extern uint64 AtomicExchange64(volatile uint64* pTarget, uint64 value); extern uint64 AtomicExchange64(volatile uint64* pTarget, uint64 value);
/// Atomically exchanges a pair of pointers. /// Atomically exchanges a pair of pointers.
/// ///
/// @param [in,out] ppTarget Pointer to the address to exchange. The function sets the address pointed to by *ppTarget /// @param [in,out] ppTarget Pointer to the address to exchange. The function sets the address pointed to by *ppTarget
/// to pValue. /// to pValue.
/// @param [in] pValue New pointer to be stored in *ppTarget. /// @param [in] pValue New pointer to be stored in *ppTarget.
/// ///
/// @returns Previous value at *ppTarget. /// @returns Previous value at *ppTarget.
extern void* AtomicExchangePointer(void*volatile* ppTarget, void* pValue); extern void* AtomicExchangePointer(void*volatile* ppTarget, void* pValue);
/// Performs an atomic compare and swap operation on a pair of pointers. This operation compares *ppTarget /// Performs an atomic compare and swap operation on a pair of pointers. This operation compares *ppTarget
/// with pOldValue and replaces it with pNewValue if they match. If the values don't match, no action is taken. /// with pOldValue and replaces it with pNewValue if they match. If the values don't match, no action is taken.
/// The original value of *ppTarget is returned as a result. /// The original value of *ppTarget is returned as a result.
/// ///
/// @param [in,out] ppTarget Pointer to the destination value of the operation. /// @param [in,out] ppTarget Pointer to the destination value of the operation.
/// @param [in] pOldValue Old pointer to compare *ppTarget to. /// @param [in] pOldValue Old pointer to compare *ppTarget to.
/// @param [in] pNewValue New pointer to replace *ppTarget with if *ppTarget matches pOldValue. /// @param [in] pNewValue New pointer to replace *ppTarget with if *ppTarget matches pOldValue.
/// ///
/// @returns Previous value at *ppTarget. /// @returns Previous value at *ppTarget.
extern void* AtomicCompareExchangePointer(void*volatile* ppTarget, void* pOldValue, void* pNewValue); extern void* AtomicCompareExchangePointer(void*volatile* ppTarget, void* pOldValue, void* pNewValue);
/// Atomically add a value to the specific 32-bit unsigned integer. /// Atomically add a value to the specific 32-bit unsigned integer.
/// ///
/// @param [in,out] pAddend Pointer to the value to be modified. /// @param [in,out] pAddend Pointer to the value to be modified.
/// @param [in] value Value to add to *pAddend. /// @param [in] value Value to add to *pAddend.
/// ///
/// @returns Result of the add operation. /// @returns Result of the add operation.
extern uint32 AtomicAdd(volatile uint32* pAddend, uint32 value); extern uint32 AtomicAdd(volatile uint32* pAddend, uint32 value);
/// Atomically add a value to the specified 64-bit unsigned integer. /// Atomically add a value to the specified 64-bit unsigned integer.
/// ///
/// @param [in,out] pAddend Pointer to the value to be modified. /// @param [in,out] pAddend Pointer to the value to be modified.
/// @param [in] value Value to add to *pAddend. /// @param [in] value Value to add to *pAddend.
/// ///
/// @returns Result of the add operation. /// @returns Result of the add operation.
extern uint64 AtomicAdd64(volatile uint64* pAddend, uint64 value); extern uint64 AtomicAdd64(volatile uint64* pAddend, uint64 value);
/// Atomically OR a value to the specific 32-bit unsigned integer. /// Atomically OR a value to the specific 32-bit unsigned integer.
/// ///
/// @param [in,out] pTarget Pointer to the value to be modified. /// @param [in,out] pTarget Pointer to the value to be modified.
/// @param [in] value Value to OR to *pTarget. /// @param [in] value Value to OR to *pTarget.
/// ///
/// @returns The original value of *pTarget. /// @returns The original value of *pTarget.
extern uint32 AtomicOr(volatile uint32* pTarget, uint32 value); extern uint32 AtomicOr(volatile uint32* pTarget, uint32 value);
/// Atomically OR a value to the specified 64-bit unsigned integer. /// Atomically OR a value to the specified 64-bit unsigned integer.
/// ///
/// @param [in,out] pTarget Pointer to the value to be modified. /// @param [in,out] pTarget Pointer to the value to be modified.
/// @param [in] value Value to OR to *pTarget. /// @param [in] value Value to OR to *pTarget.
/// ///
/// @returns The original value of *pTarget. /// @returns The original value of *pTarget.
extern uint64 AtomicOr64(volatile uint64* pTarget, uint64 value); extern uint64 AtomicOr64(volatile uint64* pTarget, uint64 value);
/// Atomically AND a value to the specific 32-bit unsigned integer. /// Atomically AND a value to the specific 32-bit unsigned integer.
/// ///
/// @param [in,out] pTarget Pointer to the value to be modified. /// @param [in,out] pTarget Pointer to the value to be modified.
/// @param [in] value Value to AND to *pTarget. /// @param [in] value Value to AND to *pTarget.
/// ///
/// @returns The original value of *pTarget. /// @returns The original value of *pTarget.
extern uint32 AtomicAnd(volatile uint32* pTarget, uint32 value); extern uint32 AtomicAnd(volatile uint32* pTarget, uint32 value);
/// Atomically AND a value to the specified 64-bit unsigned integer. /// Atomically AND a value to the specified 64-bit unsigned integer.
/// ///
/// @param [in,out] pTarget Pointer to the value to be modified. /// @param [in,out] pTarget Pointer to the value to be modified.
/// @param [in] value Value to AND to *pTarget. /// @param [in] value Value to AND to *pTarget.
/// ///
/// @returns The original value of *pTarget. /// @returns The original value of *pTarget.
extern uint64 AtomicAnd64(volatile uint64* pTarget, uint64 value); extern uint64 AtomicAnd64(volatile uint64* pTarget, uint64 value);
} // Util } // Util
+447 -447
파일 보기
@@ -1,447 +1,447 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2022-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2022-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palSpan.h * @file palSpan.h
* @brief PAL utility collection Span class declaration. * @brief PAL utility collection Span class declaration.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palUtil.h" #include "palUtil.h"
#include "palAssert.h" #include "palAssert.h"
#include "palSysMemory.h" #include "palSysMemory.h"
#include "palInlineFuncs.h" #include "palInlineFuncs.h"
#include <type_traits> #include <type_traits>
namespace Util namespace Util
{ {
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Span container * @brief Span container
* *
* Span is an array with a length, where the data is not owned by the Span object. It is similar to C++20 std::span, * Span is an array with a length, where the data is not owned by the Span object. It is similar to C++20 std::span,
* but only the dynamic extent variant. It is similar to LLVM MutableArrayRef and ArrayRef. A Span is intended to * but only the dynamic extent variant. It is similar to LLVM MutableArrayRef and ArrayRef. A Span is intended to
* be passed around by value. * be passed around by value.
* *
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template<typename T> template<typename T>
class Span class Span
{ {
public: public:
/// Constructor from nothing. This allows you to use {} to mean an empty Span. /// Constructor from nothing. This allows you to use {} to mean an empty Span.
constexpr Span() : m_pData(nullptr), m_numElements(0) {} constexpr Span() : m_pData(nullptr), m_numElements(0) {}
/// Constructor from pointer and length /// Constructor from pointer and length
/// ///
/// @param [in] data Pointer to the start of the array /// @param [in] data Pointer to the start of the array
/// @param numElements Number of elements in the array /// @param numElements Number of elements in the array
constexpr Span(T* pData, size_t numElements) : m_pData(pData), m_numElements(numElements) {} constexpr Span(T* pData, size_t numElements) : m_pData(pData), m_numElements(numElements) {}
/// Copy constructor /// Copy constructor
/// ///
/// @param [in] src Other Span to copy from /// @param [in] src Other Span to copy from
constexpr Span(const Span<T>& src) : m_pData(src.m_pData), m_numElements(src.m_numElements) {} constexpr Span(const Span<T>& src) : m_pData(src.m_pData), m_numElements(src.m_numElements) {}
/// Constructor from C++ array /// Constructor from C++ array
/// ///
/// @param [in] src C++ array /// @param [in] src C++ array
template<size_t NumElements> constexpr Span(T(& src)[NumElements]) : m_pData(&src[0]), m_numElements(NumElements) {} template<size_t NumElements> constexpr Span(T(& src)[NumElements]) : m_pData(&src[0]), m_numElements(NumElements) {}
/// Constructor from single element /// Constructor from single element
/// ///
/// @param [in] src Single element /// @param [in] src Single element
constexpr Span(T& src) : m_pData(&src), m_numElements(1) {} constexpr Span(T& src) : m_pData(&src), m_numElements(1) {}
/// Implicitly convert a Span to its const-element equivalent. /// Implicitly convert a Span to its const-element equivalent.
/// ///
/// @returns The same span, but with const element type /// @returns The same span, but with const element type
constexpr operator Span<const T>() const { return Span<const T>(m_pData, m_numElements); } constexpr operator Span<const T>() const { return Span<const T>(m_pData, m_numElements); }
/// Assignment operator /// Assignment operator
/// ///
/// @param [in] src Other Span to copy from /// @param [in] src Other Span to copy from
constexpr Span<T>& operator=(const Span<T>& src) { constexpr Span<T>& operator=(const Span<T>& src) {
m_pData = src.m_pData; m_pData = src.m_pData;
m_numElements = src.m_numElements; m_numElements = src.m_numElements;
return *this; return *this;
} }
///@{ ///@{
/// Returns the element at the location specified. /// Returns the element at the location specified.
/// ///
/// @param [in] index Integer location of the element needed. /// @param [in] index Integer location of the element needed.
/// ///
/// @returns The element at location specified by index by reference /// @returns The element at location specified by index by reference
constexpr T& At(size_t index) const constexpr T& At(size_t index) const
{ {
PAL_CONSTEXPR_ASSERT(index < m_numElements); PAL_CONSTEXPR_ASSERT(index < m_numElements);
return *(m_pData + index); return *(m_pData + index);
} }
constexpr T& operator[](size_t index) const noexcept { return At(index); } constexpr T& operator[](size_t index) const noexcept { return At(index); }
///@} ///@}
/// Returns the data at the front of the vector. /// Returns the data at the front of the vector.
/// ///
/// @returns The data at the front of the vector. /// @returns The data at the front of the vector.
constexpr T& Front() const constexpr T& Front() const
{ {
PAL_CONSTEXPR_ASSERT(IsEmpty() == false); PAL_CONSTEXPR_ASSERT(IsEmpty() == false);
return *m_pData; return *m_pData;
} }
/// Returns the data at the back of the vector. /// Returns the data at the back of the vector.
/// ///
/// @returns The data at the back of the vector. /// @returns The data at the back of the vector.
constexpr T& Back() const constexpr T& Back() const
{ {
PAL_CONSTEXPR_ASSERT(IsEmpty() == false); PAL_CONSTEXPR_ASSERT(IsEmpty() == false);
return *(m_pData + (m_numElements - 1)); return *(m_pData + (m_numElements - 1));
} }
/// Returns an iterator to the first element of the vector. /// Returns an iterator to the first element of the vector.
/// ///
/// @returns An iterator to first element of the vector. /// @returns An iterator to first element of the vector.
constexpr T* Begin() const { return m_pData; } constexpr T* Begin() const { return m_pData; }
/// Returns an iterator beyond the last element of the vector. (NOT at the last element like Util::Vector::End()!) /// Returns an iterator beyond the last element of the vector. (NOT at the last element like Util::Vector::End()!)
/// ///
/// @warning Accessing an element using an iterator of an empty vector will cause an access violation! /// @warning Accessing an element using an iterator of an empty vector will cause an access violation!
/// ///
/// @returns VectorIterator An iterator to last element of the vector. /// @returns VectorIterator An iterator to last element of the vector.
constexpr T* End() const { return m_pData + m_numElements; } constexpr T* End() const { return m_pData + m_numElements; }
/// Returns pointer to the underlying buffer serving as data storage. /// Returns pointer to the underlying buffer serving as data storage.
/// ///
/// @returns Pointer to the underlying data storage. /// @returns Pointer to the underlying data storage.
/// For a non-empty span, the returned pointer contains address of the first element. /// For a non-empty span, the returned pointer contains address of the first element.
/// For an empty span, the returned pointer may or may not be a null pointer. /// For an empty span, the returned pointer may or may not be a null pointer.
constexpr T* Data() const { return m_pData; } constexpr T* Data() const { return m_pData; }
/// Returns the extent of the span. /// Returns the extent of the span.
/// ///
/// @returns An unsigned integer equal to the number of elements currently present in the span. /// @returns An unsigned integer equal to the number of elements currently present in the span.
constexpr size_t NumElements() const { return m_numElements; } constexpr size_t NumElements() const { return m_numElements; }
/// Returns the size in bytes the Span represents. /// Returns the size in bytes the Span represents.
/// ///
/// @returns An unsigned integer equal to the size in bytes the entire span represents. /// @returns An unsigned integer equal to the size in bytes the entire span represents.
constexpr size_t SizeInBytes() const { return ElementSize() * m_numElements; } constexpr size_t SizeInBytes() const { return ElementSize() * m_numElements; }
/// Returns true if the number of elements present in the vector is equal to zero. /// Returns true if the number of elements present in the vector is equal to zero.
/// ///
/// @returns True if the span is empty. /// @returns True if the span is empty.
constexpr bool IsEmpty() const { return (m_numElements == 0); } constexpr bool IsEmpty() const { return (m_numElements == 0); }
/// Returns a "subspan", a view over a subset range of the elements. /// Returns a "subspan", a view over a subset range of the elements.
/// ///
/// @warning Behavior is undefined if either /// @warning Behavior is undefined if either
/// - offset is greater than NumElements(), or /// - offset is greater than NumElements(), or
/// - count is not size_t(-1) and is greater than NumElements()-offset. /// - count is not size_t(-1) and is greater than NumElements()-offset.
/// ///
/// Note that size_t(-1) is equivalent to C++20 std::dynamic_extent, which the C++20 std::span::subspan uses /// Note that size_t(-1) is equivalent to C++20 std::dynamic_extent, which the C++20 std::span::subspan uses
/// in the same way to mean "take the remainder of the elements from offset". /// in the same way to mean "take the remainder of the elements from offset".
/// ///
/// @param offset Zero-based offset to start the subspan at /// @param offset Zero-based offset to start the subspan at
/// @param count Number of elements in the subspan, or size_t(-1) for the remainder of the elements from offset /// @param count Number of elements in the subspan, or size_t(-1) for the remainder of the elements from offset
/// ///
/// @returns The subspan /// @returns The subspan
constexpr Span Subspan( constexpr Span Subspan(
size_t offset, size_t offset,
size_t count) const size_t count) const
{ {
PAL_CONSTEXPR_ASSERT((offset <= NumElements()) PAL_CONSTEXPR_ASSERT((offset <= NumElements())
&& ((count == size_t(-1)) || (count <= NumElements() - offset))); && ((count == size_t(-1)) || (count <= NumElements() - offset)));
if (count == size_t(-1)) if (count == size_t(-1))
{ {
count = NumElements() - offset; count = NumElements() - offset;
} }
return Span(Data() + offset, count); return Span(Data() + offset, count);
} }
/// Returns a subspan dropping the specified number (default 1) of elements from the front. /// Returns a subspan dropping the specified number (default 1) of elements from the front.
/// Returns an empty Span if there were no more elements than that to start with. /// Returns an empty Span if there were no more elements than that to start with.
/// ///
/// @param count Number of elements to drop from the front /// @param count Number of elements to drop from the front
/// ///
/// @returns The subspan /// @returns The subspan
constexpr Span DropFront( constexpr Span DropFront(
size_t count = 1) const size_t count = 1) const
{ {
Span retVal; Span retVal;
if (count < NumElements()) if (count < NumElements())
{ {
retVal = Subspan(count, size_t(-1)); retVal = Subspan(count, size_t(-1));
} }
return retVal; return retVal;
} }
/// Returns a subspan dropping the specified number (default 1) of elements from the back. /// Returns a subspan dropping the specified number (default 1) of elements from the back.
/// Returns an empty Span if there were no more elements than that to start with. /// Returns an empty Span if there were no more elements than that to start with.
/// ///
/// @param count Number of elements to drop from the back /// @param count Number of elements to drop from the back
/// ///
/// @returns The subspan /// @returns The subspan
constexpr Span DropBack( constexpr Span DropBack(
size_t count = 1) const size_t count = 1) const
{ {
Span retVal; Span retVal;
if (count < NumElements()) if (count < NumElements())
{ {
retVal = Subspan(0, NumElements() - count); retVal = Subspan(0, NumElements() - count);
} }
return retVal; return retVal;
} }
///@{ ///@{
/// @internal Satisfies concept `range_expression`, using T* as `iterator` and 32-bit size and difference types /// @internal Satisfies concept `range_expression`, using T* as `iterator` and 32-bit size and difference types
/// ///
/// @note - These are a convenience intended to be used by c++ language features such as `range for`. /// @note - These are a convenience intended to be used by c++ language features such as `range for`.
/// These should not be called directly as they do not adhere to PAL coding standards. /// These should not be called directly as they do not adhere to PAL coding standards.
using value_type = T; using value_type = T;
using reference = T&; using reference = T&;
using iterator = T*; using iterator = T*;
using difference_type = size_t; using difference_type = size_t;
using size_type = size_t; using size_type = size_t;
constexpr iterator begin() const noexcept { return m_pData; } constexpr iterator begin() const noexcept { return m_pData; }
constexpr iterator end() const noexcept { return (m_pData + m_numElements); } constexpr iterator end() const noexcept { return (m_pData + m_numElements); }
constexpr bool empty() const noexcept { return IsEmpty(); } constexpr bool empty() const noexcept { return IsEmpty(); }
constexpr size_type size() const noexcept { return m_numElements; } constexpr size_type size() const noexcept { return m_numElements; }
///@} ///@}
protected: protected:
template<typename U = T, typename R = std::conditional_t<std::is_void_v<U>, char, U>> template<typename U = T, typename R = std::conditional_t<std::is_void_v<U>, char, U>>
static constexpr size_t ElementSize() { return sizeof(R); } static constexpr size_t ElementSize() { return sizeof(R); }
template<typename R = T, bool Condition = true> template<typename R = T, bool Condition = true>
using IfConst = std::enable_if_t<std::is_const_v<R> == Condition>; using IfConst = std::enable_if_t<std::is_const_v<R> == Condition>;
template<typename R = T, bool Condition = true> template<typename R = T, bool Condition = true>
using IfPtr = std::enable_if_t<std::is_pointer_v<R> == Condition>; using IfPtr = std::enable_if_t<std::is_pointer_v<R> == Condition>;
T* m_pData; // Pointer to the current data. T* m_pData; // Pointer to the current data.
size_t m_numElements; // Number of elements present. size_t m_numElements; // Number of elements present.
}; };
/// ==================================================================================================================== /// ====================================================================================================================
/// Span template specialization for const void byte buffers. /// Span template specialization for const void byte buffers.
template<> template<>
class Span<const void> : public Span<const char> class Span<const void> : public Span<const char>
{ {
using Byte = const char; using Byte = const char;
using Base = Span<Byte>; using Base = Span<Byte>;
public: public:
/// Constructor from nothing. This allows you to use {} to mean an empty Span. /// Constructor from nothing. This allows you to use {} to mean an empty Span.
constexpr Span() : Base() {} constexpr Span() : Base() {}
/// Template constructor from any pointer and length /// Template constructor from any pointer and length
/// ///
/// @param [in] data Pointer to the start of the buffer or array /// @param [in] data Pointer to the start of the buffer or array
/// @param numElements Number of bytes or elements in the buffer or array /// @param numElements Number of bytes or elements in the buffer or array
template<typename T> template<typename T>
Span(const T* pData, size_t numElements) : Base(reinterpret_cast<Byte*>(pData), ElementSize<T>() * numElements) {} Span(const T* pData, size_t numElements) : Base(reinterpret_cast<Byte*>(pData), ElementSize<T>() * numElements) {}
/// Template copy constructor /// Template copy constructor
/// ///
/// @param [in] src Other Span<T> to copy from /// @param [in] src Other Span<T> to copy from
template<typename T = const void> template<typename T = const void>
Span(const Span<T>& src) : Span(src.Data(), src.NumElements()) {} Span(const Span<T>& src) : Span(src.Data(), src.NumElements()) {}
/// Template constructor from any C++ array /// Template constructor from any C++ array
/// ///
/// @param [in] src C++ array /// @param [in] src C++ array
template<typename T, size_t NumElements> template<typename T, size_t NumElements>
Span(const T(& src)[NumElements]) : Span(&src[0], NumElements) {} Span(const T(& src)[NumElements]) : Span(&src[0], NumElements) {}
/// Constructor from any single element /// Constructor from any single element
/// ///
/// @param [in] src Single element /// @param [in] src Single element
template<typename T, typename Enabled = IfPtr<T, false>> template<typename T, typename Enabled = IfPtr<T, false>>
Span(const T& src) : Span(&src, 1) {} Span(const T& src) : Span(&src, 1) {}
/// Templated conversion of this typeless Span to a typed Subspan /// Templated conversion of this typeless Span to a typed Subspan
/// ///
/// @returns A subspan with typed elemeents and NumElements truncated down to the nearest sizeof(type) /// @returns A subspan with typed elemeents and NumElements truncated down to the nearest sizeof(type)
template<typename T> template<typename T>
operator Span<const T>() const operator Span<const T>() const
{ return Span<const T>(static_cast<const T*>(Data()), SizeInBytes() / ElementSize<T>()); } { return Span<const T>(static_cast<const T*>(Data()), SizeInBytes() / ElementSize<T>()); }
/// Returns the element at the location specified. /// Returns the element at the location specified.
/// ///
/// @param [in] index Integer location of the element needed. /// @param [in] index Integer location of the element needed.
/// ///
/// @returns The element at location specified by index by reference /// @returns The element at location specified by index by reference
template<typename T = Byte> template<typename T = Byte>
const T& At(size_t index) const { return reinterpret_cast<const T&>(Base::At(index)); } const T& At(size_t index) const { return reinterpret_cast<const T&>(Base::At(index)); }
/// Returns pointer to the underlying buffer serving as data storage. /// Returns pointer to the underlying buffer serving as data storage.
/// ///
/// @returns Pointer to the underlying data storage. /// @returns Pointer to the underlying data storage.
/// For a non-empty span, the returned pointer contains address of the first element. /// For a non-empty span, the returned pointer contains address of the first element.
/// For an empty span, the returned pointer may or may not be a null pointer. /// For an empty span, the returned pointer may or may not be a null pointer.
template<typename T = void> template<typename T = void>
constexpr const T* Data() const { return reinterpret_cast<const T*>(Base::Data()); } constexpr const T* Data() const { return reinterpret_cast<const T*>(Base::Data()); }
/// Returns a "subspan", a view over a subset range of the elements. /// Returns a "subspan", a view over a subset range of the elements.
/// ///
/// @warning Behavior is undefined if either /// @warning Behavior is undefined if either
/// - offset is greater than NumElements(), or /// - offset is greater than NumElements(), or
/// - count is not size_t(-1) and is greater than NumElements()-offset. /// - count is not size_t(-1) and is greater than NumElements()-offset.
/// ///
/// Note that size_t(-1) is equivalent to C++20 std::dynamic_extent, which the C++20 std::span::subspan uses /// Note that size_t(-1) is equivalent to C++20 std::dynamic_extent, which the C++20 std::span::subspan uses
/// in the same way to mean "take the remainder of the elements from offset". /// in the same way to mean "take the remainder of the elements from offset".
/// ///
/// @param offset Zero-based offset to start the subspan at /// @param offset Zero-based offset to start the subspan at
/// @param count Number of elements in the subspan, or size_t(-1) for the remainder of the elements from offset /// @param count Number of elements in the subspan, or size_t(-1) for the remainder of the elements from offset
/// ///
/// @returns The subspan /// @returns The subspan
template<typename T = void> template<typename T = void>
Span<const T> Subspan(size_t offset, size_t count) const { return Span<const void>(Base::Subspan(offset, count)); } Span<const T> Subspan(size_t offset, size_t count) const { return Span<const void>(Base::Subspan(offset, count)); }
/// Returns a subspan dropping the specified number (default 1) of elements from the front. /// Returns a subspan dropping the specified number (default 1) of elements from the front.
/// Returns an empty Span if there were no more elements than that to start with. /// Returns an empty Span if there were no more elements than that to start with.
/// ///
/// @param count Number of elements to drop from the front /// @param count Number of elements to drop from the front
/// ///
/// @returns The subspan /// @returns The subspan
template<typename T = void> template<typename T = void>
Span<const T> DropFront(size_t count = 1) const { return Span<const void>(Base::DropFront(count)); } Span<const T> DropFront(size_t count = 1) const { return Span<const void>(Base::DropFront(count)); }
/// Returns a subspan dropping the specified number (default 1) of elements from the back. /// Returns a subspan dropping the specified number (default 1) of elements from the back.
/// Returns an empty Span if there were no more elements than that to start with. /// Returns an empty Span if there were no more elements than that to start with.
/// ///
/// @param count Number of elements to drop from the back /// @param count Number of elements to drop from the back
/// ///
/// @returns The subspan /// @returns The subspan
template<typename T = void> template<typename T = void>
Span<const T> DropBack(size_t count = 1) const { return Span<const void>(Base::DropBack(count)); } Span<const T> DropBack(size_t count = 1) const { return Span<const void>(Base::DropBack(count)); }
}; };
/// ==================================================================================================================== /// ====================================================================================================================
/// Span template specialization for mutable void byte buffers. /// Span template specialization for mutable void byte buffers.
template<> template<>
class Span<void> : public Span<char> class Span<void> : public Span<char>
{ {
using Byte = char; using Byte = char;
using Base = Span<Byte>; using Base = Span<Byte>;
public: public:
/// Constructor from nothing. This allows you to use {} to mean an empty Span. /// Constructor from nothing. This allows you to use {} to mean an empty Span.
constexpr Span() : Base() {} constexpr Span() : Base() {}
/// Template constructor from any pointer and length /// Template constructor from any pointer and length
/// ///
/// @param [in] data Pointer to the start of the buffer or array /// @param [in] data Pointer to the start of the buffer or array
/// @param sizeInBytes,numElements Number of bytes or elements in the buffer or array /// @param sizeInBytes,numElements Number of bytes or elements in the buffer or array
template<typename T, typename Enabled = IfConst<T, false>> template<typename T, typename Enabled = IfConst<T, false>>
Span(T* pData, size_t numElements) : Base(reinterpret_cast<Byte*>(pData), ElementSize<T>() * numElements) { } Span(T* pData, size_t numElements) : Base(reinterpret_cast<Byte*>(pData), ElementSize<T>() * numElements) { }
/// Template copy constructor /// Template copy constructor
/// ///
/// @param [in] src Other Span<T> to copy from /// @param [in] src Other Span<T> to copy from
template<typename T = void, typename Enabled = IfConst<T, false>> template<typename T = void, typename Enabled = IfConst<T, false>>
Span(const Span<T>& src) : Span(src.Data(), src.NumElements()) {} Span(const Span<T>& src) : Span(src.Data(), src.NumElements()) {}
/// Template constructor from any C++ array /// Template constructor from any C++ array
/// ///
/// @param [in] src C++ array /// @param [in] src C++ array
template<typename T, size_t NumElements, typename Enabled = IfConst<T, false>> template<typename T, size_t NumElements, typename Enabled = IfConst<T, false>>
Span(T(& src)[NumElements]) : Span(&src[0], NumElements) {} Span(T(& src)[NumElements]) : Span(&src[0], NumElements) {}
/// Constructor from any single element /// Constructor from any single element
/// ///
/// @param [in] src Single element /// @param [in] src Single element
template<typename T, typename Enabled = IfConst<T, false>, typename = IfPtr<T, false>> template<typename T, typename Enabled = IfConst<T, false>, typename = IfPtr<T, false>>
Span(T& src) : Span(&src, 1) {} Span(T& src) : Span(&src, 1) {}
/// Templated conversion of this typeless Span to a typed Subspan /// Templated conversion of this typeless Span to a typed Subspan
/// ///
/// @returns A subspan with typed elemeents and NumElements truncated down to the nearest sizeof(type) /// @returns A subspan with typed elemeents and NumElements truncated down to the nearest sizeof(type)
template<typename T> template<typename T>
operator Span<T>() const { return Span<T>(static_cast<T*>(Data()), SizeInBytes() / ElementSize<T>()); } operator Span<T>() const { return Span<T>(static_cast<T*>(Data()), SizeInBytes() / ElementSize<T>()); }
/// Returns the element at the location specified. /// Returns the element at the location specified.
/// ///
/// @param [in] index Integer location of the element needed. /// @param [in] index Integer location of the element needed.
/// ///
/// @returns The element at location specified by index by reference /// @returns The element at location specified by index by reference
template<typename T = Byte> template<typename T = Byte>
T& At(size_t index) const { return reinterpret_cast<T&>(Base::At(index)); } T& At(size_t index) const { return reinterpret_cast<T&>(Base::At(index)); }
/// Returns pointer to the underlying buffer serving as data storage /// Returns pointer to the underlying buffer serving as data storage
/// ///
/// @returns Pointer to the underlying data storage. /// @returns Pointer to the underlying data storage.
/// For a non-empty span, the returned pointer contains address of the first element. /// For a non-empty span, the returned pointer contains address of the first element.
/// For an empty span, the returned pointer may or may not be a null pointer. /// For an empty span, the returned pointer may or may not be a null pointer.
template<typename T = void> template<typename T = void>
constexpr T* Data() const { return reinterpret_cast<T*>(Base::Data()); } constexpr T* Data() const { return reinterpret_cast<T*>(Base::Data()); }
/// Implicitly convert this void Span to its const void equivalent /// Implicitly convert this void Span to its const void equivalent
/// ///
/// @returns The same span, but of const void type /// @returns The same span, but of const void type
operator Span<const void>() const { return Span<const void>(Data(), NumElements()); } operator Span<const void>() const { return Span<const void>(Data(), NumElements()); }
/// Returns a "subspan", a view over a subset range of the elements. /// Returns a "subspan", a view over a subset range of the elements.
/// ///
/// @warning Behavior is undefined if either /// @warning Behavior is undefined if either
/// - offset is greater than NumElements(), or /// - offset is greater than NumElements(), or
/// - count is not size_t(-1) and is greater than NumElements()-offset. /// - count is not size_t(-1) and is greater than NumElements()-offset.
/// ///
/// Note that size_t(-1) is equivalent to C++20 std::dynamic_extent, which the C++20 std::span::subspan uses /// Note that size_t(-1) is equivalent to C++20 std::dynamic_extent, which the C++20 std::span::subspan uses
/// in the same way to mean "take the remainder of the elements from offset". /// in the same way to mean "take the remainder of the elements from offset".
/// ///
/// @param offset Zero-based offset to start the subspan at /// @param offset Zero-based offset to start the subspan at
/// @param count Number of elements in the subspan, or size_t(-1) for the remainder of the elements from offset /// @param count Number of elements in the subspan, or size_t(-1) for the remainder of the elements from offset
/// ///
/// @returns The subspan /// @returns The subspan
template<typename T = void> template<typename T = void>
Span<T> Subspan(size_t offset, size_t count) const { return Span<void>(Base::Subspan(offset, count)); } Span<T> Subspan(size_t offset, size_t count) const { return Span<void>(Base::Subspan(offset, count)); }
/// Returns a subspan dropping the specified number (default 1) of elements from the front. /// Returns a subspan dropping the specified number (default 1) of elements from the front.
/// Returns an empty Span if there were no more elements than that to start with. /// Returns an empty Span if there were no more elements than that to start with.
/// ///
/// @param count Number of elements to drop from the front /// @param count Number of elements to drop from the front
/// ///
/// @returns The subspan /// @returns The subspan
template<typename T = void> template<typename T = void>
Span<T> DropFront(size_t count = 1) const { return Span<void>(Base::DropFront(count)); } Span<T> DropFront(size_t count = 1) const { return Span<void>(Base::DropFront(count)); }
/// Returns a subspan dropping the specified number (default 1) of elements from the back. /// Returns a subspan dropping the specified number (default 1) of elements from the back.
/// Returns an empty Span if there were no more elements than that to start with. /// Returns an empty Span if there were no more elements than that to start with.
/// ///
/// @param count Number of elements to drop from the back /// @param count Number of elements to drop from the back
/// ///
/// @returns The subspan /// @returns The subspan
template<typename T = void> template<typename T = void>
Span<T> DropBack(size_t count = 1) const { return Span<void>(Base::DropBack(count)); } Span<T> DropBack(size_t count = 1) const { return Span<void>(Base::DropBack(count)); }
}; };
} // Util } // Util
+188 -188
파일 보기
@@ -1,188 +1,188 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2020-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2020-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palStringUtil.h * @file palStringUtil.h
* @brief PAL String utility collection functions. * @brief PAL String utility collection functions.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include <cstring> #include <cstring>
#include <cwchar> #include <cwchar>
#include <type_traits> #include <type_traits>
#include "palUtil.h" #include "palUtil.h"
namespace Util namespace Util
{ {
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 919 #if PAL_CLIENT_INTERFACE_MAJOR_VERSION < 919
/// Returns the length of a wchar_t based string. /// Returns the length of a wchar_t based string.
/// ///
/// @param [in] wide string to query /// @param [in] wide string to query
/// ///
/// @returns The length of the given string in wide characters /// @returns The length of the given string in wide characters
extern size_t PalWcslen( extern size_t PalWcslen(
const wchar_t* pWideStr); const wchar_t* pWideStr);
/// Performs a reverse string find of wide character wc. /// Performs a reverse string find of wide character wc.
/// ///
/// @param [in] wide string to scan /// @param [in] wide string to scan
/// @param [in] wide character to find /// @param [in] wide character to find
/// ///
/// @returns The matching character at the end of the string or nullptr if not found. /// @returns The matching character at the end of the string or nullptr if not found.
extern wchar_t* PalWcsrchr( extern wchar_t* PalWcsrchr(
wchar_t *pStr, wchar_t *pStr,
wchar_t wc); wchar_t wc);
#endif #endif
/// When the -fshort-char compiler option is specified, wchar_t is 16 bits, but mbstowcs still treats the dest /// When the -fshort-char compiler option is specified, wchar_t is 16 bits, but mbstowcs still treats the dest
/// as 32 bit so we provide our own implementation. /// as 32 bit so we provide our own implementation.
/// ///
/// @param [out] dst string /// @param [out] dst string
/// @param [in] src string /// @param [in] src string
/// @param [in] size of the destination buffer in words /// @param [in] size of the destination buffer in words
/// ///
/// @returns Returns whether or not the conversion was successful. /// @returns Returns whether or not the conversion was successful.
extern bool ConvertCharStringToUtf16( extern bool ConvertCharStringToUtf16(
wchar_t* pDst, wchar_t* pDst,
const char* pSrc, const char* pSrc,
size_t dstSizeInWords); size_t dstSizeInWords);
/// When the -fshort-char compiler option is specified, wchar_t is 16 bits, but wcstombs still treats the src /// When the -fshort-char compiler option is specified, wchar_t is 16 bits, but wcstombs still treats the src
/// as 32 bit so we provide our own implementation. /// as 32 bit so we provide our own implementation.
/// ///
/// @param [out] dst string /// @param [out] dst string
/// @param [in] src string /// @param [in] src string
/// @param [in] size of the destination buffer in bytes /// @param [in] size of the destination buffer in bytes
/// ///
/// @returns Returns whether or not the conversion was successful. /// @returns Returns whether or not the conversion was successful.
extern bool ConvertUtf16StringToUtf8( extern bool ConvertUtf16StringToUtf8(
char* pDst, char* pDst,
const wchar_t* pSrc, const wchar_t* pSrc,
size_t dstSizeInBytes); size_t dstSizeInBytes);
/// Convert wchar_t string to UTF-8 string. Works whether wchar_t is 16 or 32 bits. /// Convert wchar_t string to UTF-8 string. Works whether wchar_t is 16 or 32 bits.
/// If wchar_t is 16 bits, this decodes UTF-16. /// If wchar_t is 16 bits, this decodes UTF-16.
/// ///
/// @param [out] dst string /// @param [out] dst string
/// @param [in] src string /// @param [in] src string
/// @param [in] size of the destination buffer in bytes /// @param [in] size of the destination buffer in bytes
/// ///
/// @returns Returns whether or not the conversion was successful. /// @returns Returns whether or not the conversion was successful.
bool ConvertWcharStringToUtf8(char* pDst, const wchar_t* pSrc, size_t dstSizeInBytes); bool ConvertWcharStringToUtf8(char* pDst, const wchar_t* pSrc, size_t dstSizeInBytes);
/// When the -fshort-char compiler option is specified, wchar_t is 16 bits, but wcsncpy still treats its arguments /// When the -fshort-char compiler option is specified, wchar_t is 16 bits, but wcsncpy still treats its arguments
/// as 32 bit so we provide our own implementation. /// as 32 bit so we provide our own implementation.
/// ///
/// @param [out] pDst Destination string. /// @param [out] pDst Destination string.
/// @param [in] pSrc Source string to copy. /// @param [in] pSrc Source string to copy.
/// @param [in] dstSize Length of the destination buffer, in wchar_t's. /// @param [in] dstSize Length of the destination buffer, in wchar_t's.
extern void CopyUtf16String( extern void CopyUtf16String(
wchar_t* pDst, wchar_t* pDst,
const wchar_t* pSrc, const wchar_t* pSrc,
size_t dstSize); size_t dstSize);
/// A shared helper function which takes an arbitrary blob of data and formats it into a human readable "memory view" /// A shared helper function which takes an arbitrary blob of data and formats it into a human readable "memory view"
/// string. This is intended to be used by logging code. /// string. This is intended to be used by logging code.
/// ///
/// Imagine your input buffer is: { 0xef, 0xbe, 0xad, 0xde, 0x78, 0x56, 0x34, 0x12, 0xab }, then the string looks like /// Imagine your input buffer is: { 0xef, 0xbe, 0xad, 0xde, 0x78, 0x56, 0x34, 0x12, 0xab }, then the string looks like
/// this with a blockSize of 4: "0xdeadbeef 0x12345678 0xab". So the block size determines how many bytes are combined /// this with a blockSize of 4: "0xdeadbeef 0x12345678 0xab". So the block size determines how many bytes are combined
/// into one "0x" character block. The whole block is effetively cast into an integer of that size and printed in big /// into one "0x" character block. The whole block is effetively cast into an integer of that size and printed in big
/// endian. Trailing bytes are printed without being size-extended. If a block won't fit at the end of the string it /// endian. Trailing bytes are printed without being size-extended. If a block won't fit at the end of the string it
/// is skipped (update your buffer pointer and call again to continue). /// is skipped (update your buffer pointer and call again to continue).
/// ///
/// The return value is the number of bytes consumed from pBuffer. The idea is that you can loop until the full size /// The return value is the number of bytes consumed from pBuffer. The idea is that you can loop until the full size
/// is consumed, printing a new line for each call. /// is consumed, printing a new line for each call.
/// ///
/// @param [out] pDst The caller-provided destination string. /// @param [out] pDst The caller-provided destination string.
/// @param [in] dstSize The length of pDst in bytes. /// @param [in] dstSize The length of pDst in bytes.
/// @param [in] pBuffer The arbitrary data blob to turn into a string. /// @param [in] pBuffer The arbitrary data blob to turn into a string.
/// @param [in] bufferSize The length of pBuffer in bytes. /// @param [in] bufferSize The length of pBuffer in bytes.
/// @param [in] blockSize How many bytes to combine into one hexidecimal big endian string. /// @param [in] blockSize How many bytes to combine into one hexidecimal big endian string.
/// ///
/// @returns The number of bytes from pBuffer that were formatted into pDst. /// @returns The number of bytes from pBuffer that were formatted into pDst.
extern size_t BytesToStr( extern size_t BytesToStr(
char* pDst, char* pDst,
size_t dstSize, size_t dstSize,
const void* pBuffer, const void* pBuffer,
size_t bufferSize, size_t bufferSize,
size_t blockSize); size_t blockSize);
/// Returns the length of the string. /// Returns the length of the string.
/// ///
/// @returns String length. /// @returns String length.
constexpr uint32 StringLength( constexpr uint32 StringLength(
const char* pString) const char* pString)
{ {
// TODO: On C++23 we can replace this with consteval-if. // TODO: On C++23 we can replace this with consteval-if.
// TODO: When we upgrade PAL_CPLUSPLUS then we can rely that std::is_constant_evaluated() is always defined. // TODO: When we upgrade PAL_CPLUSPLUS then we can rely that std::is_constant_evaluated() is always defined.
#if defined(__cpp_lib_is_constant_evaluated) #if defined(__cpp_lib_is_constant_evaluated)
if (std::is_constant_evaluated()) if (std::is_constant_evaluated())
#else #else
if (__builtin_is_constant_evaluated()) if (__builtin_is_constant_evaluated())
#endif #endif
{ {
uint32 length = 0; uint32 length = 0;
while (pString[length] != '\0') while (pString[length] != '\0')
{ {
length++; length++;
} }
return length; return length;
} }
else else
{ {
return uint32(std::strlen(pString)); return uint32(std::strlen(pString));
} }
} }
/// Returns the length of the string. /// Returns the length of the string.
/// ///
/// @returns String length. /// @returns String length.
constexpr uint32 StringLength( constexpr uint32 StringLength(
const wchar_t* pString) const wchar_t* pString)
{ {
// TODO: On C++23 we can replace this with consteval-if. // TODO: On C++23 we can replace this with consteval-if.
// TODO: When we upgrade PAL_CPLUSPLUS then we can rely that std::is_constant_evaluated() is always defined. // TODO: When we upgrade PAL_CPLUSPLUS then we can rely that std::is_constant_evaluated() is always defined.
#if defined(__cpp_lib_is_constant_evaluated) #if defined(__cpp_lib_is_constant_evaluated)
if (std::is_constant_evaluated()) if (std::is_constant_evaluated())
#else #else
if (__builtin_is_constant_evaluated()) if (__builtin_is_constant_evaluated())
#endif #endif
{ {
uint32 length = 0; uint32 length = 0;
while (pString[length] != L'\0') while (pString[length] != L'\0')
{ {
length++; length++;
} }
return length; return length;
} }
else else
{ {
return uint32(std::wcslen(pString)); return uint32(std::wcslen(pString));
} }
} }
} // Util } // Util
+228 -228
파일 보기
@@ -1,228 +1,228 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palStringView.h * @file palStringView.h
* @brief PAL utility collection string view declaration. * @brief PAL utility collection string view declaration.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palAssert.h" #include "palAssert.h"
#include "palInlineFuncs.h" #include "palInlineFuncs.h"
#include "palStringUtil.h" #include "palStringUtil.h"
#include "palUtil.h" #include "palUtil.h"
#include <type_traits> #include <type_traits>
namespace Util namespace Util
{ {
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief String view. * @brief String view.
* *
* A StringView is a templated view over a constant contiguous sequence of characters. * A StringView is a templated view over a constant contiguous sequence of characters.
* *
* @warning The string view assumes that its lifetime does not extend past that of the pointed-to character sequence. * @warning The string view assumes that its lifetime does not extend past that of the pointed-to character sequence.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template<typename CharT> template<typename CharT>
class StringView class StringView
{ {
static_assert((std::is_same<CharT, char>::value || std::is_same<CharT, wchar_t>::value), static_assert((std::is_same<CharT, char>::value || std::is_same<CharT, wchar_t>::value),
"StringView type T must be either char or wchar_t."); "StringView type T must be either char or wchar_t.");
public: public:
/// Constructs an empty StringView. /// Constructs an empty StringView.
constexpr StringView() constexpr StringView()
: :
m_pData{}, m_pData{},
m_length{} m_length{}
{} {}
constexpr StringView( constexpr StringView(
const CharT* s, const CharT* s,
uint32 count) uint32 count)
: :
m_pData{s}, m_pData{s},
m_length{count} m_length{count}
{ {
PAL_CONSTEXPR_ASSERT((s != nullptr) || (count == 0)); PAL_CONSTEXPR_ASSERT((s != nullptr) || (count == 0));
} }
StringView( StringView(
const CharT* s) const CharT* s)
: :
StringView() StringView()
{ {
if (s != nullptr) if (s != nullptr)
{ {
m_length = StringLength(s); m_length = StringLength(s);
m_pData = s; m_pData = s;
} }
} }
constexpr StringView(std::nullptr_t) = delete; constexpr StringView(std::nullptr_t) = delete;
///@{ ///@{
/// Returns the element at the location specified. /// Returns the element at the location specified.
/// ///
/// @warning Calling this function with an out-of-bounds index will cause an access violation! /// @warning Calling this function with an out-of-bounds index will cause an access violation!
/// ///
/// @param [in] index Integer location of the element needed. /// @param [in] index Integer location of the element needed.
/// ///
/// @returns The element at location specified by index by reference /// @returns The element at location specified by index by reference
constexpr const CharT& At(uint32 index) const constexpr const CharT& At(uint32 index) const
{ {
PAL_CONSTEXPR_ASSERT(index < Length()); PAL_CONSTEXPR_ASSERT(index < Length());
return m_pData[index]; return m_pData[index];
} }
constexpr const CharT& operator[](uint32 index) const { return At(index); } constexpr const CharT& operator[](uint32 index) const { return At(index); }
///@} ///@}
/// Returns pointer to the underlying string serving as data storage. /// Returns pointer to the underlying string serving as data storage.
/// The returned pointer defines always valid range [Data(), Data() + Length()), /// The returned pointer defines always valid range [Data(), Data() + Length()),
/// even if the view does not point to any data storage (Data() is not dereferenceable in that case). /// even if the view does not point to any data storage (Data() is not dereferenceable in that case).
/// ///
/// @warning Dereferencing pointer returned by Data() from a view that does not point to a data storage will cause /// @warning Dereferencing pointer returned by Data() from a view that does not point to a data storage will cause
/// an access violation! /// an access violation!
/// ///
/// @returns Pointer to the underlying data storage for read access. /// @returns Pointer to the underlying data storage for read access.
/// For a view to a valid data storage, the returned pointer contains address of the first element. /// For a view to a valid data storage, the returned pointer contains address of the first element.
/// For a view without a valid data storage, the returned pointer will be a @c nullptr. /// For a view without a valid data storage, the returned pointer will be a @c nullptr.
constexpr const CharT* Data() const noexcept { return m_pData; } constexpr const CharT* Data() const noexcept { return m_pData; }
/// Returns the data at the front of the view. /// Returns the data at the front of the view.
/// ///
/// @warning Calling this function on an empty view will cause an access violation! /// @warning Calling this function on an empty view will cause an access violation!
/// ///
/// @returns The data at the front of the view. /// @returns The data at the front of the view.
constexpr const CharT& Front() const constexpr const CharT& Front() const
{ {
PAL_CONSTEXPR_ASSERT(IsEmpty() == false); PAL_CONSTEXPR_ASSERT(IsEmpty() == false);
return m_pData[0]; return m_pData[0];
} }
/// Returns the data at the back of the view. /// Returns the data at the back of the view.
/// ///
/// @warning Calling this function on an empty view will cause an access violation! /// @warning Calling this function on an empty view will cause an access violation!
/// ///
/// @returns The data at the back of the view. /// @returns The data at the back of the view.
constexpr const CharT& Back() const constexpr const CharT& Back() const
{ {
PAL_CONSTEXPR_ASSERT(IsEmpty() == false); PAL_CONSTEXPR_ASSERT(IsEmpty() == false);
return m_pData[Length() - 1]; return m_pData[Length() - 1];
} }
/// Returns the length of the string. /// Returns the length of the string.
/// ///
/// @returns An unsigned integer equal to the length of the string. /// @returns An unsigned integer equal to the length of the string.
constexpr uint32 Length() const { return m_length; } constexpr uint32 Length() const { return m_length; }
/// Returns true if the number of characters the view points to is equal to zero. /// Returns true if the number of characters the view points to is equal to zero.
/// ///
/// @returns True if the view points to an empty or non-existing data storage. /// @returns True if the view points to an empty or non-existing data storage.
constexpr bool IsEmpty() const { return (m_length == 0); } constexpr bool IsEmpty() const { return (m_length == 0); }
///@{ ///@{
/// @internal Satisfies concept `range_expression`, using CharT* as `iterator`. /// @internal Satisfies concept `range_expression`, using CharT* as `iterator`.
/// ///
/// @note - These are a convenience intended to be used by C++ language features such as `range-based for`. /// @note - These are a convenience intended to be used by C++ language features such as `range-based for`.
/// These should not be called directly as they do not adhere to PAL coding standards. /// These should not be called directly as they do not adhere to PAL coding standards.
using const_iterator = const CharT*; using const_iterator = const CharT*;
constexpr const_iterator begin() const noexcept { return m_pData; } constexpr const_iterator begin() const noexcept { return m_pData; }
constexpr const_iterator end() const noexcept { return m_pData + Length(); } constexpr const_iterator end() const noexcept { return m_pData + Length(); }
///@} ///@}
private: private:
const CharT* m_pData; const CharT* m_pData;
uint32 m_length; uint32 m_length;
}; };
// ===================================================================================================================== // =====================================================================================================================
template<typename CharT> template<typename CharT>
constexpr bool operator==( constexpr bool operator==(
StringView<CharT> x, StringView<CharT> x,
StringView<CharT> y) StringView<CharT> y)
{ {
bool equal = (x.Length() == y.Length()); bool equal = (x.Length() == y.Length());
if (equal) if (equal)
{ {
if (x.Data() != y.Data()) if (x.Data() != y.Data())
{ {
// they are not pointing to the same storage, so we need to compare the contents // they are not pointing to the same storage, so we need to compare the contents
for (uint32 index = 0; equal && (index < x.Length()); ++index) for (uint32 index = 0; equal && (index < x.Length()); ++index)
{ {
equal = (x[index] == y[index]); equal = (x[index] == y[index]);
} }
} }
} }
return equal; return equal;
} }
// ===================================================================================================================== // =====================================================================================================================
template<typename CharT> template<typename CharT>
constexpr bool operator!=(StringView<CharT> x, StringView<CharT> y) { return (x == y) == false; } constexpr bool operator!=(StringView<CharT> x, StringView<CharT> y) { return (x == y) == false; }
// ===================================================================================================================== // =====================================================================================================================
template<typename CharT> template<typename CharT>
bool operator<( bool operator<(
StringView<CharT> x, StringView<CharT> x,
StringView<CharT> y) StringView<CharT> y)
{ {
const uint32 minLength = Min(x.Length(), y.Length()); const uint32 minLength = Min(x.Length(), y.Length());
int compare = strncmp(x.Data(), y.Data(), minLength); int compare = strncmp(x.Data(), y.Data(), minLength);
if (compare == 0) if (compare == 0)
{ {
// strings are equal up to minLength, so check which is shorter // strings are equal up to minLength, so check which is shorter
compare = int(x.Length()) - int(y.Length()); compare = int(x.Length()) - int(y.Length());
} }
return compare < 0; return compare < 0;
} }
// ===================================================================================================================== // =====================================================================================================================
template<typename CharT> template<typename CharT>
bool operator<=(StringView<CharT> x, StringView<CharT> y) { return (y < x) == false; } bool operator<=(StringView<CharT> x, StringView<CharT> y) { return (y < x) == false; }
// ===================================================================================================================== // =====================================================================================================================
template<typename CharT> template<typename CharT>
bool operator>(StringView<CharT> x, StringView<CharT> y) { return y < x; } bool operator>(StringView<CharT> x, StringView<CharT> y) { return y < x; }
// ===================================================================================================================== // =====================================================================================================================
template<typename CharT> template<typename CharT>
bool operator>=(StringView<CharT> x, StringView<CharT> y) { return (x < y) == false; } bool operator>=(StringView<CharT> x, StringView<CharT> y) { return (x < y) == false; }
/// Specialization of @ref HashString(const char*,size_t) for @ref StringView. /// Specialization of @ref HashString(const char*,size_t) for @ref StringView.
template<typename T> template<typename T>
constexpr uint32 HashString( constexpr uint32 HashString(
StringView<T> sv) StringView<T> sv)
{ {
return HashString(sv.Data(), sv.Length()); return HashString(sv.Data(), sv.Length());
} }
} // Util } // Util
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+87 -87
파일 보기
@@ -1,87 +1,87 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palTime.h * @file palTime.h
* @brief PAL time-related utility collection. * @brief PAL time-related utility collection.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include <chrono> #include <chrono>
namespace Util namespace Util
{ {
/// Specifies a class that implements a timestamp. /// Specifies a class that implements a timestamp.
class Timestamp class Timestamp
{ {
public: public:
/// Creates a new timestamp object that records the time it was created. /// Creates a new timestamp object that records the time it was created.
Timestamp(); Timestamp();
/// Returns the timestamp as a C-string. /// Returns the timestamp as a C-string.
const char* CStr() const { return m_data; } const char* CStr() const { return m_data; }
private: private:
char m_data[64]; char m_data[64];
}; };
#if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 873 #if PAL_CLIENT_INTERFACE_MAJOR_VERSION >= 873
/// Seconds stored as a float instead of an integer. /// Seconds stored as a float instead of an integer.
using fseconds = std::chrono::duration<float>; using fseconds = std::chrono::duration<float>;
/// Milliseconds stored as a float instead of an integer. /// Milliseconds stored as a float instead of an integer.
using fmilliseconds = std::chrono::duration<float, std::milli>; using fmilliseconds = std::chrono::duration<float, std::milli>;
/// Microseconds stored as a float instead of an integer. /// Microseconds stored as a float instead of an integer.
using fmicroseconds = std::chrono::duration<float, std::micro>; using fmicroseconds = std::chrono::duration<float, std::micro>;
/// Nanoseconds stored as a float instead of an integer. /// Nanoseconds stored as a float instead of an integer.
using fnanoseconds = std::chrono::duration<float, std::nano>; using fnanoseconds = std::chrono::duration<float, std::nano>;
/// A time_point who's epoch is January 1st 1970 and uses seconds for the duration. /// A time_point who's epoch is January 1st 1970 and uses seconds for the duration.
/// C++20 guarantees us that system_clock's epoch is always January 1st 1970 on all platforms. /// C++20 guarantees us that system_clock's epoch is always January 1st 1970 on all platforms.
/// system_clock's internal duration is still implementation defined. /// system_clock's internal duration is still implementation defined.
/// On Windows it's hundreds-of-nanoseconds and on Linux it's seconds. /// On Windows it's hundreds-of-nanoseconds and on Linux it's seconds.
/// However time_point has it's own duration type. /// However time_point has it's own duration type.
/// As long as we go through the time_point to interpret the duration then everything should be in terms of seconds. /// As long as we go through the time_point to interpret the duration then everything should be in terms of seconds.
using SecondsSinceEpoch = std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>; using SecondsSinceEpoch = std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>;
/// Like std::chrono::duration_cast, but it preserves the special 'infinite' value used in timeouts. /// Like std::chrono::duration_cast, but it preserves the special 'infinite' value used in timeouts.
template<class DestDuration, class Rep, class Period> template<class DestDuration, class Rep, class Period>
constexpr DestDuration TimeoutCast( constexpr DestDuration TimeoutCast(
const std::chrono::duration<Rep, Period>& d) const std::chrono::duration<Rep, Period>& d)
{ {
if (d == (std::chrono::duration<Rep, Period>::max)()) if (d == (std::chrono::duration<Rep, Period>::max)())
{ {
return (DestDuration::max)(); return (DestDuration::max)();
} }
else else
{ {
return std::chrono::duration_cast<DestDuration, Rep, Period>(d); return std::chrono::duration_cast<DestDuration, Rep, Period>(d);
} }
} }
#endif #endif
} // Util } // Util
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
+455 -455
파일 보기
@@ -1,455 +1,455 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @file palVector.h * @file palVector.h
* @brief PAL utility collection Vector and VectorIterator class declarations. * @brief PAL utility collection Vector and VectorIterator class declarations.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
#pragma once #pragma once
#include "palUtil.h" #include "palUtil.h"
#include "palAssert.h" #include "palAssert.h"
#include "palSpan.h" #include "palSpan.h"
#include "palSysMemory.h" #include "palSysMemory.h"
#include <type_traits> #include <type_traits>
namespace Util namespace Util
{ {
// Forward declarations. // Forward declarations.
template<typename T, uint32 defaultCapacity, typename Allocator> class Vector; template<typename T, uint32 defaultCapacity, typename Allocator> class Vector;
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Iterator for traversal of elements in Vector. * @brief Iterator for traversal of elements in Vector.
* *
* Supports forward traversal. * Supports forward traversal.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template<typename T, uint32 defaultCapacity, typename Allocator> template<typename T, uint32 defaultCapacity, typename Allocator>
class VectorIterator class VectorIterator
{ {
public: public:
/// Checks if the current index is within bounds of the number of elements in the vector. /// Checks if the current index is within bounds of the number of elements in the vector.
/// ///
/// @returns True if the current element this iterator is pointing to is within the permitted range. /// @returns True if the current element this iterator is pointing to is within the permitted range.
bool IsValid() const { return (m_curIndex < m_srcVector.m_numElements); } bool IsValid() const { return (m_curIndex < m_srcVector.m_numElements); }
/// Returns the element the iterator is currently pointing to as a reference. /// Returns the element the iterator is currently pointing to as a reference.
/// ///
/// @warning This may cause an access violation if the iterator is not valid. /// @warning This may cause an access violation if the iterator is not valid.
/// ///
/// @returns The element the iterator is currently pointing to. /// @returns The element the iterator is currently pointing to.
T& Get() const T& Get() const
{ {
PAL_ASSERT(IsValid()); PAL_ASSERT(IsValid());
return (*(m_srcVector.m_pData + m_curIndex)); return (*(m_srcVector.m_pData + m_curIndex));
} }
/// Advances the iterator to point to the next element. /// Advances the iterator to point to the next element.
/// ///
/// @warning Does not do bounds checking. /// @warning Does not do bounds checking.
void Next() { ++m_curIndex; } void Next() { ++m_curIndex; }
/// Retrieves the current vector position of this iterator. /// Retrieves the current vector position of this iterator.
/// ///
/// @returns The location in the vector of the element the iterator is currently pointing to. /// @returns The location in the vector of the element the iterator is currently pointing to.
uint32 Position() const { return m_curIndex; } uint32 Position() const { return m_curIndex; }
private: private:
VectorIterator(uint32 index, const Vector<T, defaultCapacity, Allocator>& srcVec); VectorIterator(uint32 index, const Vector<T, defaultCapacity, Allocator>& srcVec);
uint32 m_curIndex; // The current index of the vector iterator. uint32 m_curIndex; // The current index of the vector iterator.
const Vector<T, defaultCapacity, Allocator>& m_srcVector; // The vector container this iterator is used for. const Vector<T, defaultCapacity, Allocator>& m_srcVector; // The vector container this iterator is used for.
PAL_DISALLOW_DEFAULT_CTOR(VectorIterator); PAL_DISALLOW_DEFAULT_CTOR(VectorIterator);
// Although this is a transgression of coding standards, it means that Vector does not need to have a public // Although this is a transgression of coding standards, it means that Vector does not need to have a public
// interface specifically to implement this class. The added encapsulation this provides is worthwhile. // interface specifically to implement this class. The added encapsulation this provides is worthwhile.
friend class Vector<T, defaultCapacity, Allocator>; friend class Vector<T, defaultCapacity, Allocator>;
}; };
/** /**
*********************************************************************************************************************** ***********************************************************************************************************************
* @brief Vector container. * @brief Vector container.
* *
* Vector is a templated array based storage that starts with a default-size allocation in the stack. If more space is * Vector is a templated array based storage that starts with a default-size allocation in the stack. If more space is
* needed it then resorts to dynamic allocation by doubling the size every time the capacity is exceeded. * needed it then resorts to dynamic allocation by doubling the size every time the capacity is exceeded.
* Operations which this class supports are: * Operations which this class supports are:
* *
* - Insertion at the end of the array. * - Insertion at the end of the array.
* - Forward iteration. * - Forward iteration.
* - Random access. * - Random access.
* *
* @warning This class is not thread-safe. * @warning This class is not thread-safe.
*********************************************************************************************************************** ***********************************************************************************************************************
*/ */
template<typename T, uint32 defaultCapacity, typename Allocator> template<typename T, uint32 defaultCapacity, typename Allocator>
class Vector class Vector
{ {
public: public:
/// A convenient shorthand for VectorIterator. /// A convenient shorthand for VectorIterator.
typedef VectorIterator<T, defaultCapacity, Allocator> Iter; typedef VectorIterator<T, defaultCapacity, Allocator> Iter;
/// When this allocates, it doubles the old size of memory /// When this allocates, it doubles the old size of memory
static constexpr uint32 GrowthFactor = 2; static constexpr uint32 GrowthFactor = 2;
/// Constructor. /// Constructor.
/// ///
/// @param [in] pAllocator The allocator that will allocate memory if required. /// @param [in] pAllocator The allocator that will allocate memory if required.
Vector(Allocator*const pAllocator); Vector(Allocator*const pAllocator);
/// Destructor. /// Destructor.
~Vector(); ~Vector();
/// Move constructor. /// Move constructor.
/// ///
/// @param [in] vector Reference to a dying vector, from which resources will be stolen. /// @param [in] vector Reference to a dying vector, from which resources will be stolen.
Vector(Vector&& vector); Vector(Vector&& vector);
/// Increases maximal capacity to value greater or equal to the newCapacity. /// Increases maximal capacity to value greater or equal to the newCapacity.
/// If newCapacity is greater than the maximal capacity, new storage is allocated, /// If newCapacity is greater than the maximal capacity, new storage is allocated,
/// otherwise the method does nothing. /// otherwise the method does nothing.
/// ///
/// @note All existing iterators will not get invalidated, even in case new storage is allocated, /// @note All existing iterators will not get invalidated, even in case new storage is allocated,
/// because iterators are referencing vector, rather than elements of that vector. /// because iterators are referencing vector, rather than elements of that vector.
/// ///
/// @warning All pointers and references to elements of a vector will be invalidated, /// @warning All pointers and references to elements of a vector will be invalidated,
/// in case new storage is allocated. /// in case new storage is allocated.
/// ///
/// @param [in] newCapacity The new capacity of a vector, which is lower limit of the maximal capacity. /// @param [in] newCapacity The new capacity of a vector, which is lower limit of the maximal capacity.
/// ///
/// @returns Result ErrorOutOfMemory if the operation failed. /// @returns Result ErrorOutOfMemory if the operation failed.
Result Reserve(uint32 newCapacity); Result Reserve(uint32 newCapacity);
/// Increases maximum capacity to the number of elements in the vector, plus the specified increment amount. /// Increases maximum capacity to the number of elements in the vector, plus the specified increment amount.
/// Equivalent to this->Reserve(this->NumElements() + amount); /// Equivalent to this->Reserve(this->NumElements() + amount);
/// ///
/// @param [in] amount Number of items beyond the current element count to increas the capacity to. /// @param [in] amount Number of items beyond the current element count to increas the capacity to.
/// ///
/// @returns Result ErrorOutOfMemory if the operation failed. /// @returns Result ErrorOutOfMemory if the operation failed.
Result Grow(uint32 amount) { return Reserve(NumElements() + amount); } Result Grow(uint32 amount) { return Reserve(NumElements() + amount); }
/// Set size to newSize. /// Set size to newSize.
/// If size is decreased, elements at the end of the vector will be removed. /// If size is decreased, elements at the end of the vector will be removed.
/// If size is increased, new elements will be set to newVal. /// If size is increased, new elements will be set to newVal.
/// If newSize requires a higher capacity, a new allocation is made. See notes on Reserve. /// If newSize requires a higher capacity, a new allocation is made. See notes on Reserve.
/// ///
/// @note If size is decreased, any iterators referencing removed elements will become invalid. All other /// @note If size is decreased, any iterators referencing removed elements will become invalid. All other
/// iterators will remain valid. Otherwise, all iterators will still be valid. /// iterators will remain valid. Otherwise, all iterators will still be valid.
/// ///
/// @warning All pointers and references to elements of a vector will be invalidated, /// @warning All pointers and references to elements of a vector will be invalidated,
/// in case new storage is allocated. /// in case new storage is allocated.
/// ///
/// @param [in] newSize The new size of a vector. /// @param [in] newSize The new size of a vector.
/// ///
/// @returns Result ErrorOutOfMemory if the operation failed. /// @returns Result ErrorOutOfMemory if the operation failed.
Result Resize(uint32 newSize, const T& newVal = T()); Result Resize(uint32 newSize, const T& newVal = T());
/// Copy/Move an element to end of the vector. If not enough space is available, new space will be allocated and /// Copy/Move an element to end of the vector. If not enough space is available, new space will be allocated and
/// the old data will be copied to the new space. /// the old data will be copied to the new space.
/// ///
/// @param [in] data The element to be pushed to the vector. The element will become the last element. /// @param [in] data The element to be pushed to the vector. The element will become the last element.
/// ///
/// @returns Result ErrorOutOfMemory if the operation failed. /// @returns Result ErrorOutOfMemory if the operation failed.
Result PushBack(const T& data); Result PushBack(const T& data);
Result PushBack(T&& data); Result PushBack(T&& data);
/// Constructs an object in-place at the end of the vector. If not enough space is available, new space will be /// Constructs an object in-place at the end of the vector. If not enough space is available, new space will be
/// allocated and the old data will be copied to the new space. /// allocated and the old data will be copied to the new space.
/// ///
/// @param [in] args... The arguments passed to the constructor /// @param [in] args... The arguments passed to the constructor
/// ///
/// @returns Result ErrorOutOfMemory if the operation failed. /// @returns Result ErrorOutOfMemory if the operation failed.
template <typename... Args> template <typename... Args>
Result EmplaceBack(Args&&... args); Result EmplaceBack(Args&&... args);
/// Returns the element at the end of the vector and destroys it. /// Returns the element at the end of the vector and destroys it.
/// ///
/// @param [out] pData The element at the end of the vector. /// @param [out] pData The element at the end of the vector.
/// It is expected that pData is uninitialized as it will be overwritten and not destructed. /// It is expected that pData is uninitialized as it will be overwritten and not destructed.
void PopBack(T* pData); void PopBack(T* pData);
/// Destroys all elements stored in the vector. All dynamically allocated memory will be saved for reuse. /// Destroys all elements stored in the vector. All dynamically allocated memory will be saved for reuse.
void Clear(); void Clear();
///@{ ///@{
/// Returns the element at the location specified. /// Returns the element at the location specified.
/// ///
/// @warning Calling this function with an out-of-bounds index will cause an access violation! /// @warning Calling this function with an out-of-bounds index will cause an access violation!
/// ///
/// @param [in] index Integer location of the element needed. /// @param [in] index Integer location of the element needed.
/// ///
/// @returns The element at location specified by index by reference /// @returns The element at location specified by index by reference
T& At(uint32 index) T& At(uint32 index)
{ {
PAL_ASSERT(index < m_numElements); PAL_ASSERT(index < m_numElements);
return *(m_pData + index); return *(m_pData + index);
} }
const T& At(uint32 index) const const T& At(uint32 index) const
{ {
PAL_ASSERT(index < m_numElements); PAL_ASSERT(index < m_numElements);
return *(m_pData + index); return *(m_pData + index);
} }
T& operator[](uint32 index) noexcept { return At(index); } T& operator[](uint32 index) noexcept { return At(index); }
const T& operator[](uint32 index) const noexcept { return At(index); } const T& operator[](uint32 index) const noexcept { return At(index); }
///@} ///@}
/// Returns the data at the front of the vector. /// Returns the data at the front of the vector.
/// ///
/// @warning Calling this function on an empty vector will cause an access violation! /// @warning Calling this function on an empty vector will cause an access violation!
/// ///
/// @returns The data at the front of the vector. /// @returns The data at the front of the vector.
T& Front() const T& Front() const
{ {
PAL_ASSERT(IsEmpty() == false); PAL_ASSERT(IsEmpty() == false);
return *m_pData; return *m_pData;
} }
/// Returns the data at the back of the vector. /// Returns the data at the back of the vector.
/// ///
/// @warning Calling this function on an empty vector will cause an access violation! /// @warning Calling this function on an empty vector will cause an access violation!
/// ///
/// @returns The data at the back of the vector. /// @returns The data at the back of the vector.
T& Back() const T& Back() const
{ {
PAL_ASSERT(IsEmpty() == false); PAL_ASSERT(IsEmpty() == false);
return *(m_pData + (m_numElements - 1)); return *(m_pData + (m_numElements - 1));
} }
/// Returns an iterator to the first element of the vector. /// Returns an iterator to the first element of the vector.
/// ///
/// @warning Accessing an element using an iterator of an empty vector will cause an access violation! /// @warning Accessing an element using an iterator of an empty vector will cause an access violation!
/// ///
/// @returns An iterator to first element of the vector. /// @returns An iterator to first element of the vector.
Iter Begin() const { return Iter(0, *this); } Iter Begin() const { return Iter(0, *this); }
/// Returns an iterator to the last element of the vector. /// Returns an iterator to the last element of the vector.
/// ///
/// @warning Accessing an element using an iterator of an empty vector will cause an access violation! /// @warning Accessing an element using an iterator of an empty vector will cause an access violation!
/// ///
/// @returns VectorIterator An iterator to last element of the vector. /// @returns VectorIterator An iterator to last element of the vector.
Iter End() const { return Iter((m_numElements - 1), *this); } Iter End() const { return Iter((m_numElements - 1), *this); }
///@{ ///@{
/// Implicitly gets the current contents of the vector as a Span. /// Implicitly gets the current contents of the vector as a Span.
/// ///
/// @returns The contents of the vector as a Span; same as Span<T>(Data(), NumElements()). /// @returns The contents of the vector as a Span; same as Span<T>(Data(), NumElements()).
operator Span<T>() { return Span<T>(Data(), NumElements()); } operator Span<T>() { return Span<T>(Data(), NumElements()); }
operator Span<const T>() const { return Span<const T>(Data(), NumElements()); } operator Span<const T>() const { return Span<const T>(Data(), NumElements()); }
///@} ///@}
/// Returns pointer to the underlying buffer serving as data storage. /// Returns pointer to the underlying buffer serving as data storage.
/// The returned pointer defines always valid range [Data(), Data() + NumElements()), /// The returned pointer defines always valid range [Data(), Data() + NumElements()),
/// even if the container is empty (Data() is not dereferenceable in that case). /// even if the container is empty (Data() is not dereferenceable in that case).
/// ///
/// @warning Dereferencing pointer returned by Data() from an empty vector will cause an access violation! /// @warning Dereferencing pointer returned by Data() from an empty vector will cause an access violation!
/// ///
/// @returns Pointer to the underlying data storage for read & write access. /// @returns Pointer to the underlying data storage for read & write access.
/// For a non-empty vector, the returned pointer contains address of the first element. /// For a non-empty vector, the returned pointer contains address of the first element.
/// For an empty vector, the returned pointer may or may not be a null pointer. /// For an empty vector, the returned pointer may or may not be a null pointer.
T* Data() { return m_pData; } T* Data() { return m_pData; }
/// Returns pointer to the underlying buffer serving as data storage. /// Returns pointer to the underlying buffer serving as data storage.
/// The returned pointer defines always valid range [Data(), Data() + NumElements()), /// The returned pointer defines always valid range [Data(), Data() + NumElements()),
/// even if the container is empty (Data() is not dereferenceable in that case). /// even if the container is empty (Data() is not dereferenceable in that case).
/// ///
/// @warning Dereferencing pointer returned by Data() from an empty vector will cause an access violation! /// @warning Dereferencing pointer returned by Data() from an empty vector will cause an access violation!
/// ///
/// @returns Pointer to the underlying data storage for read only access. /// @returns Pointer to the underlying data storage for read only access.
/// For a non-empty vector, the returned pointer contains address of the first element. /// For a non-empty vector, the returned pointer contains address of the first element.
/// For an empty vector, the returned pointer may or may not be a null pointer. /// For an empty vector, the returned pointer may or may not be a null pointer.
const T* Data() const { return m_pData; } const T* Data() const { return m_pData; }
/// Returns the size of the vector. /// Returns the size of the vector.
/// ///
/// @returns An unsigned integer equal to the number of elements currently present in the vector. /// @returns An unsigned integer equal to the number of elements currently present in the vector.
uint32 NumElements() const { return m_numElements; } uint32 NumElements() const { return m_numElements; }
/// Returns true if the number of elements present in the vector is equal to zero. /// Returns true if the number of elements present in the vector is equal to zero.
/// ///
/// @returns True if the vector is empty. /// @returns True if the vector is empty.
bool IsEmpty() const { return (m_numElements == 0); } bool IsEmpty() const { return (m_numElements == 0); }
/// Returns a pointer to the allocator used for this container's memory management. /// Returns a pointer to the allocator used for this container's memory management.
/// ///
/// @returns Allocator pointer. /// @returns Allocator pointer.
Allocator* GetAllocator() const { return m_pAllocator; } Allocator* GetAllocator() const { return m_pAllocator; }
///@{ ///@{
/// @internal Satisfies concept `range_expression`, using T* as `iterator` and 32-bit size and difference types /// @internal Satisfies concept `range_expression`, using T* as `iterator` and 32-bit size and difference types
/// ///
/// @note - These are a convenience intended to be used by c++ language features such as `range for`. /// @note - These are a convenience intended to be used by c++ language features such as `range for`.
/// These should not be called directly as they do not adhere to PAL coding standards. /// These should not be called directly as they do not adhere to PAL coding standards.
using value_type = T; using value_type = T;
using reference = T&; using reference = T&;
using const_reference = const T&; using const_reference = const T&;
using iterator = T*; using iterator = T*;
using const_iterator = const T*; using const_iterator = const T*;
using difference_type = int32; using difference_type = int32;
using size_type = uint32; using size_type = uint32;
iterator begin() noexcept { return m_pData; } iterator begin() noexcept { return m_pData; }
iterator end() noexcept { return (m_pData + m_numElements); } iterator end() noexcept { return (m_pData + m_numElements); }
const_iterator begin() const noexcept { return m_pData; } const_iterator begin() const noexcept { return m_pData; }
const_iterator end() const noexcept { return (m_pData + m_numElements); } const_iterator end() const noexcept { return (m_pData + m_numElements); }
const_iterator cbegin() const noexcept { return m_pData; } const_iterator cbegin() const noexcept { return m_pData; }
const_iterator cend() const noexcept { return (m_pData + m_numElements); } const_iterator cend() const noexcept { return (m_pData + m_numElements); }
[[nodiscard]] bool empty() const noexcept { return IsEmpty(); } [[nodiscard]] bool empty() const noexcept { return IsEmpty(); }
size_type size() const noexcept { return m_numElements; } size_type size() const noexcept { return m_numElements; }
///@} ///@}
/// Erases the element at the specified iterator. /// Erases the element at the specified iterator.
void Erase(Iter it); void Erase(Iter it);
/// Erases the element at the specified iterator. /// Erases the element at the specified iterator.
void Erase(iterator it); void Erase(iterator it);
/// Erases the element at the specified index. /// Erases the element at the specified index.
void Erase(uint32 index); void Erase(uint32 index);
/// Erase the element at the specified iterator, and swap last element to that position. /// Erase the element at the specified iterator, and swap last element to that position.
/// If the element to erase is the last element, erase directly and no swap operation. /// If the element to erase is the last element, erase directly and no swap operation.
void EraseAndSwapLast(Iter it); void EraseAndSwapLast(Iter it);
/// Erase the element at the specified iterator, and swap last element to that position. /// Erase the element at the specified iterator, and swap last element to that position.
/// If the element to erase is the last element, erase directly and no swap operation. /// If the element to erase is the last element, erase directly and no swap operation.
void EraseAndSwapLast(iterator it); void EraseAndSwapLast(iterator it);
/// Erases the element at the specified index, and swap last element to that position. /// Erases the element at the specified index, and swap last element to that position.
/// If the element to erase is the last element, erase directly and no swap operation. /// If the element to erase is the last element, erase directly and no swap operation.
void EraseAndSwapLast(uint32 index); void EraseAndSwapLast(uint32 index);
private: private:
// This is a POD-type that exactly fits one T value. // This is a POD-type that exactly fits one T value.
typedef typename std::aligned_storage<sizeof(T), alignof(T)>::type ValueStorage; typedef typename std::aligned_storage<sizeof(T), alignof(T)>::type ValueStorage;
ValueStorage m_data[defaultCapacity]; // The initial data buffer stored within the vector object. ValueStorage m_data[defaultCapacity]; // The initial data buffer stored within the vector object.
T* m_pData; // Pointer to the current data buffer. T* m_pData; // Pointer to the current data buffer.
uint32 m_numElements; // Number of elements present. uint32 m_numElements; // Number of elements present.
uint32 m_maxCapacity; // Maximum size it can hold. uint32 m_maxCapacity; // Maximum size it can hold.
Allocator*const m_pAllocator; // Allocator for this Vector. Allocator*const m_pAllocator; // Allocator for this Vector.
PAL_DISALLOW_COPY_AND_ASSIGN(Vector); PAL_DISALLOW_COPY_AND_ASSIGN(Vector);
// Although this is a transgression of coding standards, it prevents VectorIterator requiring a public constructor; // Although this is a transgression of coding standards, it prevents VectorIterator requiring a public constructor;
// constructing a 'bare' VectorIterator (i.e. without calling Vector::GetIterator) can never be a legal operation, // constructing a 'bare' VectorIterator (i.e. without calling Vector::GetIterator) can never be a legal operation,
// so this means that these two classes are much safer to use. // so this means that these two classes are much safer to use.
friend class VectorIterator<T, defaultCapacity, Allocator>; friend class VectorIterator<T, defaultCapacity, Allocator>;
}; };
// ===================================================================================================================== // =====================================================================================================================
template<typename T, uint32 defaultCapacity, typename Allocator> template<typename T, uint32 defaultCapacity, typename Allocator>
VectorIterator<T, defaultCapacity, Allocator>::VectorIterator( VectorIterator<T, defaultCapacity, Allocator>::VectorIterator(
uint32 index, uint32 index,
const Vector<T, defaultCapacity, Allocator>& srcVec) const Vector<T, defaultCapacity, Allocator>& srcVec)
: :
m_curIndex(index), m_curIndex(index),
m_srcVector(srcVec) m_srcVector(srcVec)
{ {
} }
// ===================================================================================================================== // =====================================================================================================================
template<typename T, uint32 defaultCapacity, typename Allocator> template<typename T, uint32 defaultCapacity, typename Allocator>
Vector<T, defaultCapacity, Allocator>::Vector( Vector<T, defaultCapacity, Allocator>::Vector(
Allocator*const pAllocator) Allocator*const pAllocator)
: :
m_pData(reinterpret_cast<T*>(m_data)), m_pData(reinterpret_cast<T*>(m_data)),
m_numElements(0), m_numElements(0),
m_maxCapacity(defaultCapacity), m_maxCapacity(defaultCapacity),
m_pAllocator(pAllocator) m_pAllocator(pAllocator)
{ {
} }
// ===================================================================================================================== // =====================================================================================================================
template<typename T, uint32 defaultCapacity, typename Allocator> template<typename T, uint32 defaultCapacity, typename Allocator>
Vector<T, defaultCapacity, Allocator>::~Vector() Vector<T, defaultCapacity, Allocator>::~Vector()
{ {
// Explicitly destroy all non-trivial types. // Explicitly destroy all non-trivial types.
if (!std::is_trivial<T>::value) if (!std::is_trivial<T>::value)
{ {
for (uint32 idx = 0; idx < m_numElements; ++idx) for (uint32 idx = 0; idx < m_numElements; ++idx)
{ {
m_pData[idx].~T(); m_pData[idx].~T();
} }
} }
// Check if we have dynamically allocated memory. // Check if we have dynamically allocated memory.
if (m_pData != reinterpret_cast<T*>(m_data)) if (m_pData != reinterpret_cast<T*>(m_data))
{ {
// Free the memory that was allocated dynamically. // Free the memory that was allocated dynamically.
PAL_FREE(m_pData, m_pAllocator); PAL_FREE(m_pData, m_pAllocator);
} }
} }
// ===================================================================================================================== // =====================================================================================================================
// Steals allocation from a dying vector, if data buffer uses storage from heap allocation. // Steals allocation from a dying vector, if data buffer uses storage from heap allocation.
// Moves objects between local buffers of new and dying vectors (for non-trivial types) or // Moves objects between local buffers of new and dying vectors (for non-trivial types) or
// copies local buffer from a dying vector to a new vector (for trivial types), // copies local buffer from a dying vector to a new vector (for trivial types),
// if data buffer uses storage from local buffer. // if data buffer uses storage from local buffer.
template<typename T, uint32 defaultCapacity, typename Allocator> template<typename T, uint32 defaultCapacity, typename Allocator>
Vector<T, defaultCapacity, Allocator>::Vector( Vector<T, defaultCapacity, Allocator>::Vector(
Vector&& vector) Vector&& vector)
: :
m_numElements(vector.m_numElements), m_numElements(vector.m_numElements),
m_maxCapacity(vector.m_maxCapacity), m_maxCapacity(vector.m_maxCapacity),
m_pAllocator(vector.m_pAllocator) m_pAllocator(vector.m_pAllocator)
{ {
if (vector.m_pData == reinterpret_cast<T*>(vector.m_data)) // Local buffer if (vector.m_pData == reinterpret_cast<T*>(vector.m_data)) // Local buffer
{ {
// Data buffer will be using storage from local buffer. // Data buffer will be using storage from local buffer.
m_pData = reinterpret_cast<T*>(m_data); m_pData = reinterpret_cast<T*>(m_data);
if (std::is_trivial<T>::value) if (std::is_trivial<T>::value)
{ {
// Optimize trivial types by copying local buffer. // Optimize trivial types by copying local buffer.
std::memcpy(m_pData, vector.m_pData, sizeof(T) * m_numElements); std::memcpy(m_pData, vector.m_pData, sizeof(T) * m_numElements);
} }
else else
{ {
// Move objects from local buffer of a dying vector to local buffer of a new vector. // Move objects from local buffer of a dying vector to local buffer of a new vector.
for (uint32 idx = 0; idx < m_numElements; ++idx) for (uint32 idx = 0; idx < m_numElements; ++idx)
{ {
PAL_PLACEMENT_NEW(m_pData + idx) T(Move(vector.m_pData[idx])); PAL_PLACEMENT_NEW(m_pData + idx) T(Move(vector.m_pData[idx]));
} }
} }
} }
else // Heap allocation else // Heap allocation
{ {
// Steal heap allocation from dying vector. // Steal heap allocation from dying vector.
m_pData = vector.m_pData; m_pData = vector.m_pData;
// After the allocation has been stolen, dying vector is just an empty shell. // After the allocation has been stolen, dying vector is just an empty shell.
vector.m_pData = nullptr; vector.m_pData = nullptr;
vector.m_numElements = 0; vector.m_numElements = 0;
vector.m_maxCapacity = 0; vector.m_maxCapacity = 0;
} }
} }
} // Util } // Util
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: fd5f7481a122f40f73d1f638e3b9b027 - md5: 99a0c403b1f71c5d5837c25874f0a270
size: 16738 size: 130
hash: md5 hash: md5
path: DriverUtilsService.lib path: DriverUtilsService.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: e09dbb1896128ac2b2bcac2b35878a40 - md5: b8765422699642586b41f2f346b89236
size: 9460 size: 129
hash: md5 hash: md5
path: SettingsRpcService2.lib path: SettingsRpcService2.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 364bc94b5b81ef5bb337e6afb0060c55 - md5: 559a03f0105295747eea440ad9ad1e32
size: 13912 size: 130
hash: md5 hash: md5
path: UberTraceService.lib path: UberTraceService.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 56362998d9feb9b0ce6ccad8441bf1c8 - md5: fb0920f5343de93cd4530c145e3f35f3
size: 820446 size: 131
hash: md5 hash: md5
path: addrlib.lib path: addrlib.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 35af646710d883bfe6184113cb88e96a - md5: 08d2d9b8535d06b5b621f4c40b3b9393
size: 702568 size: 131
hash: md5 hash: md5
path: amdrdf.lib path: amdrdf.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 06c7697ce380a8127e7478041aed7fc8 - md5: 37d5258a4bb3e9cf7cffc3c1569503a8
size: 27894 size: 130
hash: md5 hash: md5
path: cwpack.lib path: cwpack.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 7c6ba83c44ee8bd70397a1458dbea7e0 - md5: 8b15abd3b8618e8b70ee2549a9002dcf
size: 82210 size: 130
hash: md5 hash: md5
path: ddCommon.lib path: ddCommon.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 32f4aa9943ab5fde0da6f09bcbacf9be - md5: 33f2d4ac9e29e04077530848f5be2de6
size: 72778 size: 130
hash: md5 hash: md5
path: ddCore.lib path: ddCore.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 09fc5ce2eb8653cbd8ddda5d983ce836 - md5: c8aeab161984f07a0b9eaaf4f17b538c
size: 137794 size: 131
hash: md5 hash: md5
path: ddEventClient.lib path: ddEventClient.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 2f5e7eb06485bebea0ec2779d8df9f97 - md5: 1b8d22c521cdbaec139a6fd3113b9169
size: 46862 size: 130
hash: md5 hash: md5
path: ddEventParser.lib path: ddEventParser.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: bdb3738c5bbd4ac6abd3a805930b89fe - md5: 08ee8eb3d02ba8e3e504f5a42c626d1b
size: 30582 size: 130
hash: md5 hash: md5
path: ddEventServer.lib path: ddEventServer.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 43ea2bd7328593fab054754f9fd1a7c9 - md5: 92252e55f1a9b12383238b05223cbdfa
size: 35768 size: 130
hash: md5 hash: md5
path: ddEventStreamer.lib path: ddEventStreamer.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: d91f19ed479fd51b481f6b25566dfd31 - md5: bc9348766c22907da6c9a093b40c8f82
size: 13230 size: 130
hash: md5 hash: md5
path: ddNet.lib path: ddNet.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 5b37ae9cc29dfaba3cb0d08a30bd684a - md5: e26c24d78e41cfef26378c731c0dd4e9
size: 23224 size: 130
hash: md5 hash: md5
path: ddRpcClient.lib path: ddRpcClient.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: b3f63ef6d9a9d6bfb3e5934a9a34465e - md5: 06759abda0390d9712fd2b9514a07c43
size: 179024 size: 131
hash: md5 hash: md5
path: ddRpcServer.lib path: ddRpcServer.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: db87375bafb0d667ac054dbf7dc0dc36 - md5: c1064f8b6bbae1c8ee5b4324f5286335
size: 16268 size: 130
hash: md5 hash: md5
path: ddRpcShared.lib path: ddRpcShared.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: f88897c7d989d95f0352cf6e1a21df99 - md5: 60adefcf279bce2d512b72e64e913566
size: 106228 size: 131
hash: md5 hash: md5
path: ddSocket.lib path: ddSocket.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 4d64cf4c3b034f09a8a3abd1b7e657b4 - md5: a4cddc4b38e2972ecac0ee31cd5bfba9
size: 35902 size: 130
hash: md5 hash: md5
path: ddYaml.lib path: ddYaml.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 2394b7141b71f0b738dd3ad024dcbfc0 - md5: 7de1910b7130cdf3ba928dbfcdddabdb
size: 661222 size: 131
hash: md5 hash: md5
path: dd_common.lib path: dd_common.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 2b9f0af04b216527b49338cc1b8fa1a5 - md5: 19e5d9fead8533ecaa00c98194f45bfd
size: 264022 size: 131
hash: md5 hash: md5
path: dd_libyaml.lib path: dd_libyaml.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: d9a1105679db9411bf2365aae2b6d2a5 - md5: 8d67e1aa63cbc171631ef1723ca8cfef
size: 212936 size: 131
hash: md5 hash: md5
path: dd_settings.lib path: dd_settings.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 18e7d04c4ecc9fb872de2e0ac9dffd61 - md5: 0609a7a43f6d10f3e5baae8a7b371935
size: 2700190 size: 132
hash: md5 hash: md5
path: devdriver.lib path: devdriver.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 64dbdb1c2d7c68e7ae3083ea35878a83 - md5: 562ddbd333acbb87399ea93e1c276c7b
size: 28682 size: 130
hash: md5 hash: md5
path: metrohash.lib path: metrohash.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 43f91cf1e53eef1411a6e4a40776cd79 - md5: a0b7fd219e03be6ac7a411503da22da1
size: 218874 size: 131
hash: md5 hash: md5
path: mpack.lib path: mpack.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 852e161ac4115309a2591db0b80f13dd - md5: d7c2fd5ef188ad35c1d4c69933e73883
size: 24025742 size: 133
hash: md5 hash: md5
path: pal.lib path: pal.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: a929ad3103021925d382e419b0e5343d - md5: b81c7e445969441fb8995a815e3b20a4
size: 433780 size: 131
hash: md5 hash: md5
path: palCompilerDeps.lib path: palCompilerDeps.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 3cca5923fa12cf564360058254c2c6db - md5: d5c6cc0e882e43c3f0b6438a13238dd4
size: 799750 size: 131
hash: md5 hash: md5
path: palUtil.lib path: palUtil.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 36731971681f4a89f4e89b5ad44473ac - md5: a111eae8bf916115055a36750ed885c8
size: 291664 size: 131
hash: md5 hash: md5
path: pal_lz4.lib path: pal_lz4.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 1ad5de7ebbb13b41f7d7dc0367d7d1d8 - md5: e374e100d7140ba4f0c71a4d891f15e7
size: 3460 size: 129
hash: md5 hash: md5
path: pal_uuid.lib path: pal_uuid.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: b2a1cd0f59d07aaa0cf21afa9235dbda - md5: cd8f26e0b9083b607ac0aa145138c759
size: 25990 size: 130
hash: md5 hash: md5
path: stb_sprintf.lib path: stb_sprintf.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 02784ea9d25a9a9c94c20acca001456c - md5: d99dd374e9774cc79137a5fa724d29f0
size: 215198 size: 131
hash: md5 hash: md5
path: vam.lib path: vam.lib
+2 -2
파일 보기
@@ -1,5 +1,5 @@
outs: outs:
- md5: 6a1ac31db298434da1573cda69d9e4d3 - md5: 81d0c624f04a25bb31115c45a4fe9d7c
size: 1356642 size: 132
hash: md5 hash: md5
path: zstd.lib path: zstd.lib
+269 -269
파일 보기
@@ -1,269 +1,269 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
#pragma once #pragma once
#include <ddLegacyDefs.h> #include <ddLegacyDefs.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
// Macros for conditional language support. // Macros for conditional language support.
#ifdef _MSVC_LANG #ifdef _MSVC_LANG
#define DD_CPLUSPLUS _MSVC_LANG #define DD_CPLUSPLUS _MSVC_LANG
#else #else
#define DD_CPLUSPLUS __cplusplus #define DD_CPLUSPLUS __cplusplus
#endif #endif
// Denotes versions of the C++ standard from __cplusplus. // Denotes versions of the C++ standard from __cplusplus.
#define CPP98 (199711L) #define CPP98 (199711L)
#define CPP11 (201103L) #define CPP11 (201103L)
#define CPP14 (201402L) #define CPP14 (201402L)
#define CPP17 (201703L) #define CPP17 (201703L)
#define CPP20 (202002L) #define CPP20 (202002L)
#define DD_CPLUSPLUS_SUPPORTS(x) (DD_CPLUSPLUS >= (x)) #define DD_CPLUSPLUS_SUPPORTS(x) (DD_CPLUSPLUS >= (x))
static_assert(DD_CPLUSPLUS_SUPPORTS(CPP11), "C++11 is required to build devdriver."); static_assert(DD_CPLUSPLUS_SUPPORTS(CPP11), "C++11 is required to build devdriver.");
#if defined(_MSC_VER) #if defined(_MSC_VER)
#define DD_ALIGNAS(x)__declspec(align(x)) #define DD_ALIGNAS(x)__declspec(align(x))
#if _MSC_VER < 1900 #if _MSC_VER < 1900
#define DD_STATIC_CONST static const #define DD_STATIC_CONST static const
#else #else
#define DD_STATIC_CONST static constexpr #define DD_STATIC_CONST static constexpr
#endif #endif
#ifndef va_copy #ifndef va_copy
#define va_copy(d,s) ((d) = (s)) #define va_copy(d,s) ((d) = (s))
#endif #endif
#endif #endif
#if !defined(DD_STATIC_CONST) #if !defined(DD_STATIC_CONST)
#if defined(__cplusplus) && __cplusplus >= 201103L #if defined(__cplusplus) && __cplusplus >= 201103L
#define DD_STATIC_CONST static constexpr #define DD_STATIC_CONST static constexpr
#else #else
#define DD_STATIC_CONST static const #define DD_STATIC_CONST static const
#endif #endif
#endif #endif
#if DD_CPLUSPLUS_SUPPORTS(CPP14) #if DD_CPLUSPLUS_SUPPORTS(CPP14)
#define DD_CPP14_CONSTEXPR_FN constexpr #define DD_CPP14_CONSTEXPR_FN constexpr
#define DD_CPP14_STATIC_ASSERT(a, b) static_assert(a, b) #define DD_CPP14_STATIC_ASSERT(a, b) static_assert(a, b)
#else #else
#define DD_CPP14_CONSTEXPR_FN inline #define DD_CPP14_CONSTEXPR_FN inline
#define DD_CPP14_STATIC_ASSERT(a, b) #define DD_CPP14_STATIC_ASSERT(a, b)
#endif #endif
#if !defined(DD_ALIGNAS) #if !defined(DD_ALIGNAS)
#if defined(__cplusplus) && __cplusplus >= 201103L #if defined(__cplusplus) && __cplusplus >= 201103L
#define DD_ALIGNAS(x) alignas(x) #define DD_ALIGNAS(x) alignas(x)
#else #else
static_assert(false, "Error: unsupported compiler detected. Support is required to build."); static_assert(false, "Error: unsupported compiler detected. Support is required to build.");
#endif #endif
#endif #endif
/// Remove the __FILE__ macro for release builds /// Remove the __FILE__ macro for release builds
#ifndef DD_FILE #ifndef DD_FILE
#ifdef NDEBUG #ifdef NDEBUG
#define DD_FILE "" #define DD_FILE ""
#else #else
#define DD_FILE __FILE__ #define DD_FILE __FILE__
#endif #endif
#endif #endif
// Creates a structure with the specified name and alignment. // Creates a structure with the specified name and alignment.
#define DD_ALIGNED_STRUCT(name, alignment) struct DD_ALIGNAS(alignment) name #define DD_ALIGNED_STRUCT(name, alignment) struct DD_ALIGNAS(alignment) name
// Creates a structure with the specified alignment, and mark it as final to ensure it cannot be used as a parent class // Creates a structure with the specified alignment, and mark it as final to ensure it cannot be used as a parent class
#define DD_NETWORK_STRUCT(name, alignment) struct DD_ALIGNAS(alignment) name final #define DD_NETWORK_STRUCT(name, alignment) struct DD_ALIGNAS(alignment) name final
#define DD_CHECK_SIZE(x, size) static_assert(sizeof(x) == size_t(size), "sizeof(" # x ") should be " # size " bytes but has changed recently") #define DD_CHECK_SIZE(x, size) static_assert(sizeof(x) == size_t(size), "sizeof(" # x ") should be " # size " bytes but has changed recently")
#define DD_UNUSED(x) (static_cast<void>(x)) #define DD_UNUSED(x) (static_cast<void>(x))
#define _DD_STRINGIFY(str) #str #define _DD_STRINGIFY(str) #str
#define DD_STRINGIFY(x) _DD_STRINGIFY(x) #define DD_STRINGIFY(x) _DD_STRINGIFY(x)
#if DD_CPLUSPLUS_SUPPORTS(CPP17) #if DD_CPLUSPLUS_SUPPORTS(CPP17)
// Require that a function's return value, or an entire type, be used. // Require that a function's return value, or an entire type, be used.
#define DD_NODISCARD [[nodiscard]] #define DD_NODISCARD [[nodiscard]]
// Do not warn about switch statement cases falling through. Place this macro as the case body, e.g. // Do not warn about switch statement cases falling through. Place this macro as the case body, e.g.
// switch (x) // switch (x)
// { // {
// case 0: DD_FALLTHROUGH(); // case 0: DD_FALLTHROUGH();
// case 1: DD_FALLTHROUGH(); // case 1: DD_FALLTHROUGH();
// case 2: // case 2:
// printf("0, 1, or 2"); // printf("0, 1, or 2");
// break; // break;
// } // }
// //
#define DD_FALLTHROUGH() [[fallthrough]] #define DD_FALLTHROUGH() [[fallthrough]]
#else #else
// Require that a function's return value, or an entire type, be used. // Require that a function's return value, or an entire type, be used.
// This option is aggressive enough that we do not enable it when C++17 is not enabled // This option is aggressive enough that we do not enable it when C++17 is not enabled
#define DD_NODISCARD #define DD_NODISCARD
// Do not warn about switch statement cases falling through. Place this macro as the case body, e.g. // Do not warn about switch statement cases falling through. Place this macro as the case body, e.g.
// switch (x) // switch (x)
// { // {
// case 0: DD_FALLTHROUGH(); // case 0: DD_FALLTHROUGH();
// case 1: DD_FALLTHROUGH(); // case 1: DD_FALLTHROUGH();
// case 2: // case 2:
// printf("0, 1, or 2"); // printf("0, 1, or 2");
// break; // break;
// } // }
// //
#if defined(__clang__) #if defined(__clang__)
#define DD_FALLTHROUGH() [[clang::fallthrough]] #define DD_FALLTHROUGH() [[clang::fallthrough]]
#elif defined(__GNUC__) #elif defined(__GNUC__)
#if __GNUC__ >= 7 #if __GNUC__ >= 7
// gnu::fallthrough isn't supported until GCC 7+ // gnu::fallthrough isn't supported until GCC 7+
#define DD_FALLTHROUGH() [[gnu::fallthrough]] #define DD_FALLTHROUGH() [[gnu::fallthrough]]
#else #else
// Not supported on older versions of GCC // Not supported on older versions of GCC
#define DD_FALLTHROUGH() #define DD_FALLTHROUGH()
#endif #endif
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
// Not supported on MSVC - who doesn't warn about this issue in the first place. // Not supported on MSVC - who doesn't warn about this issue in the first place.
#define DD_FALLTHROUGH() #define DD_FALLTHROUGH()
#else #else
// We don't know what compiler this is, so just no-op the macro. // We don't know what compiler this is, so just no-op the macro.
#define DD_FALLTHROUGH() #define DD_FALLTHROUGH()
#endif #endif
#endif #endif
// Include in the private section of a class declaration in order to disallow use of the copy and assignment operator // Include in the private section of a class declaration in order to disallow use of the copy and assignment operator
#define DD_DISALLOW_COPY_AND_ASSIGN(_typename) \ #define DD_DISALLOW_COPY_AND_ASSIGN(_typename) \
_typename(const _typename&); \ _typename(const _typename&); \
_typename& operator =(const _typename&); _typename& operator =(const _typename&);
// Include in the private section of a class declaration in order to disallow use of the default constructor // Include in the private section of a class declaration in order to disallow use of the default constructor
#define DD_DISALLOW_DEFAULT_CTOR(_typename) \ #define DD_DISALLOW_DEFAULT_CTOR(_typename) \
_typename(); _typename();
// Detect the CPU architecture for the target. // Detect the CPU architecture for the target.
// These are often evaluated during the preprocessor stage, so it's important that we don't rely on things like sizeof. // These are often evaluated during the preprocessor stage, so it's important that we don't rely on things like sizeof.
#if UINTPTR_MAX == 0xFFFFFFFF #if UINTPTR_MAX == 0xFFFFFFFF
#define DEVDRIVER_ARCHITECTURE_BITS 32 #define DEVDRIVER_ARCHITECTURE_BITS 32
#elif UINTPTR_MAX == 0xFFFFFFFFFFFFFFFF #elif UINTPTR_MAX == 0xFFFFFFFFFFFFFFFF
#define DEVDRIVER_ARCHITECTURE_BITS 64 #define DEVDRIVER_ARCHITECTURE_BITS 64
#else #else
static_assert(false, "Unknown or unsupported target architecture."); static_assert(false, "Unknown or unsupported target architecture.");
#endif #endif
static_assert(DEVDRIVER_ARCHITECTURE_BITS == (8 * sizeof(void*)), // Assume 8-bits-per-byte. static_assert(DEVDRIVER_ARCHITECTURE_BITS == (8 * sizeof(void*)), // Assume 8-bits-per-byte.
"DEVDRIVER_ARCHITECTURE_BITS does not match sizeof(void*)."); "DEVDRIVER_ARCHITECTURE_BITS does not match sizeof(void*).");
// Add a detailed function name macro // Add a detailed function name macro
// These vary across platforms, so we'll just pick the first one that's defined // These vary across platforms, so we'll just pick the first one that's defined
#if defined(__FUNCSIG__) #if defined(__FUNCSIG__)
#define DD_FUNCTION_NAME __FUNCSIG__ #define DD_FUNCTION_NAME __FUNCSIG__
#elif defined(__PRETTY_FUNCTION__) #elif defined(__PRETTY_FUNCTION__)
#define DD_FUNCTION_NAME __PRETTY_FUNCTION__ #define DD_FUNCTION_NAME __PRETTY_FUNCTION__
#else #else
#define DD_FUNCTION_NAME __FUNCTION__ #define DD_FUNCTION_NAME __FUNCTION__
#endif #endif
// Common Typedefs // Common Typedefs
// These types are shared between all platforms, // These types are shared between all platforms,
// and need to be defined before including a specific platform header. // and need to be defined before including a specific platform header.
namespace DevDriver namespace DevDriver
{ {
typedef int8_t int8; ///< 8-bit integer. typedef int8_t int8; ///< 8-bit integer.
typedef int16_t int16; ///< 16-bit integer. typedef int16_t int16; ///< 16-bit integer.
typedef int32_t int32; ///< 32-bit integer. typedef int32_t int32; ///< 32-bit integer.
typedef int64_t int64; ///< 64-bit integer. typedef int64_t int64; ///< 64-bit integer.
typedef uint8_t uint8; ///< Unsigned 8-bit integer. typedef uint8_t uint8; ///< Unsigned 8-bit integer.
typedef uint16_t uint16; ///< Unsigned 16-bit integer. typedef uint16_t uint16; ///< Unsigned 16-bit integer.
typedef uint32_t uint32; ///< Unsigned 32-bit integer. typedef uint32_t uint32; ///< Unsigned 32-bit integer.
typedef uint64_t uint64; ///< Unsigned 64-bit integer. typedef uint64_t uint64; ///< Unsigned 64-bit integer.
typedef uint32_t ProcessId; typedef uint32_t ProcessId;
typedef uint32_t Size; typedef uint32_t Size;
typedef uint64_t Handle; typedef uint64_t Handle;
DD_STATIC_CONST Handle kNullPtr = 0; DD_STATIC_CONST Handle kNullPtr = 0;
DD_STATIC_CONST Handle kInvalidHandle = 0; DD_STATIC_CONST Handle kInvalidHandle = 0;
//////////////////////////// ////////////////////////////
// Common result codes // Common result codes
enum struct Result : uint32 enum struct Result : uint32
{ {
//// Generic Result Code //// //// Generic Result Code ////
Success = 0, Success = 0,
Error = 1, Error = 1,
NotReady = 2, NotReady = 2,
VersionMismatch = 3, VersionMismatch = 3,
Unavailable = 4, Unavailable = 4,
Rejected = 5, Rejected = 5,
EndOfStream = 6, EndOfStream = 6,
Aborted = 7, Aborted = 7,
InsufficientMemory = 8, InsufficientMemory = 8,
InvalidParameter = 9, InvalidParameter = 9,
InvalidClientId = 10, InvalidClientId = 10,
ConnectionExists = 11, ConnectionExists = 11,
FileNotFound = 12, FileNotFound = 12,
FunctionNotFound = 13, FunctionNotFound = 13,
InterfaceNotFound = 14, InterfaceNotFound = 14,
EntryExists = 15, EntryExists = 15,
FileAccessError = 16, FileAccessError = 16,
FileIoError = 17, FileIoError = 17,
LimitReached = 18, LimitReached = 18,
MemoryOverLimit = 19, MemoryOverLimit = 19,
//// URI PROTOCOL //// //// URI PROTOCOL ////
UriServiceRegistrationError = 1000, UriServiceRegistrationError = 1000,
UriStringParseError = 1001, UriStringParseError = 1001,
UriInvalidParameters = 1002, UriInvalidParameters = 1002,
UriInvalidPostDataBlock = 1003, UriInvalidPostDataBlock = 1003,
UriInvalidPostDataSize = 1004, UriInvalidPostDataSize = 1004,
UriFailedToAcquirePostBlock = 1005, UriFailedToAcquirePostBlock = 1005,
UriFailedToOpenResponseBlock = 1006, UriFailedToOpenResponseBlock = 1006,
UriRequestFailed = 1007, UriRequestFailed = 1007,
UriPendingRequestError = 1008, UriPendingRequestError = 1008,
UriInvalidChar = 1009, UriInvalidChar = 1009,
UriInvalidJson = 1010, UriInvalidJson = 1010,
//// Settings URI Service //// //// Settings URI Service ////
SettingsUriInvalidComponent = 2000, SettingsUriInvalidComponent = 2000,
SettingsUriInvalidSettingName = 2001, SettingsUriInvalidSettingName = 2001,
SettingsUriInvalidSettingValue = 2002, SettingsUriInvalidSettingValue = 2002,
SettingsUriInvalidSettingValueSize = 2003, SettingsUriInvalidSettingValueSize = 2003,
//// Info URI Service //// //// Info URI Service ////
InfoUriSourceNameInvalid = 3000, InfoUriSourceNameInvalid = 3000,
InfoUriSourceCallbackInvalid = 3001, InfoUriSourceCallbackInvalid = 3001,
InfoUriSourceAlreadyRegistered = 3002, InfoUriSourceAlreadyRegistered = 3002,
InfoUriSourceWriteFailed = 3003, InfoUriSourceWriteFailed = 3003,
//// Settings Service //// //// Settings Service ////
SettingsInvalidComponent = 4000, SettingsInvalidComponent = 4000,
SettingsInvalidSettingName = 4001, SettingsInvalidSettingName = 4001,
SettingsInvalidSettingValue = 4002, SettingsInvalidSettingValue = 4002,
SettingsInsufficientValueSize = 4003, SettingsInsufficientValueSize = 4003,
SettingsInvalidSettingValueSize = 4004, SettingsInvalidSettingValueSize = 4004,
}; };
} // namespace DevDriver } // namespace DevDriver
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Diff 로드
@@ -1,378 +1,378 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
#pragma once #pragma once
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
#include <type_traits> #include <type_traits>
#endif #endif
namespace DevDriver namespace DevDriver
{ {
namespace Platform namespace Platform
{ {
/// Templated LockGuard class. Works with any type that implements Lock() and Unlock() /// Templated LockGuard class. Works with any type that implements Lock() and Unlock()
template <typename T> template <typename T>
class LockGuard class LockGuard
{ {
public: public:
explicit LockGuard(T &lock) : m_lock(lock) { lock.Lock(); } explicit LockGuard(T &lock) : m_lock(lock) { lock.Lock(); }
~LockGuard() { m_lock.Unlock(); } ~LockGuard() { m_lock.Unlock(); }
private: private:
T &m_lock; T &m_lock;
}; };
/// Computes the base-2 logarithm of an unsigned 64-bit integer. /// Computes the base-2 logarithm of an unsigned 64-bit integer.
/// ///
/// If the given integer is not a power of 2, this function will not provide an exact answer. /// If the given integer is not a power of 2, this function will not provide an exact answer.
/// ///
/// @returns log_2(u) /// @returns log_2(u)
template<typename T> template<typename T>
inline uint32 Log2(T u) ///< Value to compute the logarithm of. inline uint32 Log2(T u) ///< Value to compute the logarithm of.
{ {
uint32 logValue = 0; uint32 logValue = 0;
while (u > 1) while (u > 1)
{ {
++logValue; ++logValue;
u >>= 1; u >>= 1;
} }
return logValue; return logValue;
} }
/// Computes the base-2 logarithm of an unsigned 64-bit integer. /// Computes the base-2 logarithm of an unsigned 64-bit integer.
/// ///
/// If the given integer is not a power of 2, this function will not provide an exact answer. /// If the given integer is not a power of 2, this function will not provide an exact answer.
/// ///
/// @returns log_2(u) /// @returns log_2(u)
template<typename T> template<typename T>
inline constexpr uint32 _ConstLog2(T u, uint32 logValue) ///< Value to compute the logarithm of. inline constexpr uint32 _ConstLog2(T u, uint32 logValue) ///< Value to compute the logarithm of.
{ {
return (u > 1) ? _ConstLog2(u >> 1, logValue + 1) : logValue; return (u > 1) ? _ConstLog2(u >> 1, logValue + 1) : logValue;
} }
/// Computes the base-2 logarithm of an unsigned 64-bit integer. /// Computes the base-2 logarithm of an unsigned 64-bit integer.
/// ///
/// If the given integer is not a power of 2, this function will not provide an exact answer. /// If the given integer is not a power of 2, this function will not provide an exact answer.
/// ///
/// @returns log_2(u) /// @returns log_2(u)
template<typename T> template<typename T>
inline constexpr uint32 ConstLog2(T u) ///< Value to compute the logarithm of. inline constexpr uint32 ConstLog2(T u) ///< Value to compute the logarithm of.
{ {
return _ConstLog2(u, 0); return _ConstLog2(u, 0);
} }
static_assert(ConstLog2(1) == 0, "ConstLog2 failure"); static_assert(ConstLog2(1) == 0, "ConstLog2 failure");
static_assert(ConstLog2(2) == 1, "ConstLog2 failure"); static_assert(ConstLog2(2) == 1, "ConstLog2 failure");
static_assert(ConstLog2(128) == 7, "ConstLog2 failure"); static_assert(ConstLog2(128) == 7, "ConstLog2 failure");
static_assert(ConstLog2(255) == 7, "ConstLog2 failure"); static_assert(ConstLog2(255) == 7, "ConstLog2 failure");
/// Computes 2 ^ value provided /// Computes 2 ^ value provided
/// ///
/// @returns 2 ^ (u) /// @returns 2 ^ (u)
template<typename T> template<typename T>
inline constexpr T Pow2(T u) inline constexpr T Pow2(T u)
{ {
return ((T)1 << u); return ((T)1 << u);
} }
static_assert(Pow2(0) == 1, "Pow2 failure"); static_assert(Pow2(0) == 1, "Pow2 failure");
static_assert(Pow2(1) == 2, "Pow2 failure"); static_assert(Pow2(1) == 2, "Pow2 failure");
static_assert(Pow2(7) == 128, "Pow2 failure"); static_assert(Pow2(7) == 128, "Pow2 failure");
/// Determines if a value is a power of two. /// Determines if a value is a power of two.
/// ///
/// @returns True if it is a power of two, false otherwise. /// @returns True if it is a power of two, false otherwise.
inline constexpr bool IsPowerOfTwo(uint64 value) inline constexpr bool IsPowerOfTwo(uint64 value)
{ {
return (value == 0) ? false : ((value & (value - 1)) == 0); return (value == 0) ? false : ((value & (value - 1)) == 0);
} }
/// Rounds the specified uint 'value' up to the nearest value meeting the specified 'alignment'. Only power of 2 /// Rounds the specified uint 'value' up to the nearest value meeting the specified 'alignment'. Only power of 2
/// alignments are supported by this function. /// alignments are supported by this function.
/// ///
/// returns Aligned value. /// returns Aligned value.
template<typename T> template<typename T>
inline constexpr T Pow2Align( inline constexpr T Pow2Align(
T value, ///< Value to align. T value, ///< Value to align.
uint64 alignment) ///< Desired alignment (must be a power of 2). uint64 alignment) ///< Desired alignment (must be a power of 2).
{ {
return ((value + static_cast<T>(alignment) - 1) & ~(static_cast<T>(alignment) - 1)); return ((value + static_cast<T>(alignment) - 1) & ~(static_cast<T>(alignment) - 1));
} }
/// Rounds the specified uint 'value' up to the nearest power of 2 /// Rounds the specified uint 'value' up to the nearest power of 2
/// ///
/// @returns Power of 2 padded value. /// @returns Power of 2 padded value.
template<typename T> template<typename T>
inline T Pow2Pad(T value) ///< Value to pad. inline T Pow2Pad(T value) ///< Value to pad.
{ {
T ret = 1; T ret = 1;
if (IsPowerOfTwo(value)) if (IsPowerOfTwo(value))
{ {
ret = value; ret = value;
} }
else else
{ {
while (ret < value) while (ret < value)
{ {
ret <<= 1; ret <<= 1;
} }
} }
return ret; return ret;
} }
/// Rounds the specified uint 'value' up to the nearest power of 2. Constexpr varient. /// Rounds the specified uint 'value' up to the nearest power of 2. Constexpr varient.
/// ///
/// @returns Power of 2 padded value. /// @returns Power of 2 padded value.
template<typename T> template<typename T>
inline constexpr T _ConstPow2Pad(T value, T padded) ///< Value to pad. inline constexpr T _ConstPow2Pad(T value, T padded) ///< Value to pad.
{ {
return (padded < value) ? _ConstPow2Pad(value, padded << 1) : padded; return (padded < value) ? _ConstPow2Pad(value, padded << 1) : padded;
} }
/// Rounds the specified uint 'value' up to the nearest power of 2. Constexpr varient. /// Rounds the specified uint 'value' up to the nearest power of 2. Constexpr varient.
/// ///
/// @returns Power of 2 padded value. /// @returns Power of 2 padded value.
template<typename T> template<typename T>
inline constexpr T ConstPow2Pad(T value) ///< Value to pad. inline constexpr T ConstPow2Pad(T value) ///< Value to pad.
{ {
return (IsPowerOfTwo(value)) ? value : _ConstPow2Pad(value, (T)1); return (IsPowerOfTwo(value)) ? value : _ConstPow2Pad(value, (T)1);
} }
static_assert(ConstPow2Pad(512) == 512, "ConstPow2Pad failure"); static_assert(ConstPow2Pad(512) == 512, "ConstPow2Pad failure");
static_assert(ConstPow2Pad(511) == 512, "ConstPow2Pad failure"); static_assert(ConstPow2Pad(511) == 512, "ConstPow2Pad failure");
static_assert(ConstPow2Pad(257) == 512, "ConstPow2Pad failure"); static_assert(ConstPow2Pad(257) == 512, "ConstPow2Pad failure");
/// Finds the smallest of two values /// Finds the smallest of two values
/// ///
/// @returns a if a < b, otherwise b. /// @returns a if a < b, otherwise b.
template <typename T> template <typename T>
inline constexpr T Min(const T &a, const T &b) inline constexpr T Min(const T &a, const T &b)
{ {
return ((a < b) ? a : b); return ((a < b) ? a : b);
} }
/// Finds the larger of two values /// Finds the larger of two values
/// ///
/// @returns a if a > b, otherwise b. /// @returns a if a > b, otherwise b.
template <typename T> template <typename T>
inline constexpr T Max(const T &a, const T &b) inline constexpr T Max(const T &a, const T &b)
{ {
return ((a > b) ? a : b); return ((a > b) ? a : b);
} }
// Given a type T, set Type equal to T // Given a type T, set Type equal to T
template <typename T> template <typename T>
struct RemoveRef struct RemoveRef
{ {
typedef T Type; typedef T Type;
}; };
// Given a type T&, set Type equal to T // Given a type T&, set Type equal to T
template <typename T> template <typename T>
struct RemoveRef<T &> struct RemoveRef<T &>
{ {
typedef T Type; typedef T Type;
}; };
// Given a type T&&, set Type equal to T // Given a type T&&, set Type equal to T
template <typename T> template <typename T>
struct RemoveRef<T &&> struct RemoveRef<T &&>
{ {
typedef T Type; typedef T Type;
}; };
// std::move equivalent // std::move equivalent
template <typename T> template <typename T>
inline typename RemoveRef<T>::Type&& Move(T&& obj) inline typename RemoveRef<T>::Type&& Move(T&& obj)
{ {
return static_cast<typename RemoveRef<T>::Type&&>(obj); return static_cast<typename RemoveRef<T>::Type&&>(obj);
} }
// std::forward equivalent // std::forward equivalent
template <typename T> template <typename T>
inline T&& Forward(typename RemoveRef<T>::Type&& args) inline T&& Forward(typename RemoveRef<T>::Type&& args)
{ {
return static_cast<T&&>(args); return static_cast<T&&>(args);
} }
// std::forward equivalent // std::forward equivalent
template <typename T> template <typename T>
inline T&& Forward(typename RemoveRef<T>::Type& args) inline T&& Forward(typename RemoveRef<T>::Type& args)
{ {
return static_cast<T&&>(args); return static_cast<T&&>(args);
} }
// Returns the contents of Value in a new variable, and assign newValue into the memory occupied by value. // Returns the contents of Value in a new variable, and assign newValue into the memory occupied by value.
template <typename T, typename U = T> template <typename T, typename U = T>
inline T Exchange(T& value, U&& newValue) inline T Exchange(T& value, U&& newValue)
{ {
T oldValue = Move(value); T oldValue = Move(value);
value = Forward<U>(newValue); value = Forward<U>(newValue);
return (oldValue); return (oldValue);
} }
// Convenience structure that defined Value as either true or false, and Type as either TrueType or FalseType // Convenience structure that defined Value as either true or false, and Type as either TrueType or FalseType
template <bool value> template <bool value>
struct BoolType struct BoolType
{ {
static const bool Value = value; static const bool Value = value;
using Type = BoolType<value>; using Type = BoolType<value>;
}; };
using FalseType = BoolType<false>; using FalseType = BoolType<false>;
using TrueType = BoolType<true>; using TrueType = BoolType<true>;
// Struct whose ::Type member is undefined if the first condition is not true // Struct whose ::Type member is undefined if the first condition is not true
template<bool Enable, template<bool Enable,
class Type = void> class Type = void>
struct EnableIf struct EnableIf
{ {
}; };
// Struct whose ::Type member is equal to T if the first condition is true. // Struct whose ::Type member is equal to T if the first condition is true.
template<class T> template<class T>
struct EnableIf<true, T> struct EnableIf<true, T>
{ {
typedef T Type; typedef T Type;
}; };
template <class T> template <class T>
struct IsPointer : FalseType struct IsPointer : FalseType
{ {
}; };
template <class T> template <class T>
struct IsPointer<T*> : TrueType struct IsPointer<T*> : TrueType
{ {
}; };
#if defined(_MSC_VER) #if defined(_MSC_VER)
// If we are building with MSVC we want to use the compiler intrinsics here. This is primarily because building with // If we are building with MSVC we want to use the compiler intrinsics here. This is primarily because building with
// the /kernel precludes the use of the C++ type traits library. For all other compilers we simply implement this // the /kernel precludes the use of the C++ type traits library. For all other compilers we simply implement this
// using the standard C++ library. // using the standard C++ library.
// Struct whose ::Value member is equal to true if you can cast from T to U, and false otherwise. // Struct whose ::Value member is equal to true if you can cast from T to U, and false otherwise.
template <class T, class U> template <class T, class U>
struct IsConvertible : BoolType<__is_convertible_to(T, U)> struct IsConvertible : BoolType<__is_convertible_to(T, U)>
{ {
}; };
// Struct whose ::Value member is equal to true if you can construct an object of type T using the arguments // Struct whose ::Value member is equal to true if you can construct an object of type T using the arguments
// provided. // provided.
template<typename T, typename... Args> template<typename T, typename... Args>
struct IsConstructible : BoolType<__is_constructible(T, Args...)> struct IsConstructible : BoolType<__is_constructible(T, Args...)>
{ {
}; };
// Struct whose ::Value member is equal to true if T is an abstract class, and false otherwise. // Struct whose ::Value member is equal to true if T is an abstract class, and false otherwise.
template<typename T> template<typename T>
struct IsAbstract : BoolType<__is_abstract(T)> struct IsAbstract : BoolType<__is_abstract(T)>
{ {
}; };
// Struct whose ::Value member is equal to true if T is an abstract class, and false otherwise. // Struct whose ::Value member is equal to true if T is an abstract class, and false otherwise.
template<typename T> template<typename T>
struct IsPod : BoolType<__is_pod(T)> struct IsPod : BoolType<__is_pod(T)>
{ {
}; };
// Struct whose ::Value member is equal to true if T is has a standard layout, and false otherwise. // Struct whose ::Value member is equal to true if T is has a standard layout, and false otherwise.
template<typename T> template<typename T>
struct IsStandardLayout : BoolType<__is_standard_layout(T)> struct IsStandardLayout : BoolType<__is_standard_layout(T)>
{ {
}; };
// Struct whose ::Value member is equal to true if T is trivially destructable, and false otherwise. // Struct whose ::Value member is equal to true if T is trivially destructable, and false otherwise.
template<typename T> template<typename T>
struct IsTriviallyDestructible : BoolType<__is_trivially_destructible(T)> struct IsTriviallyDestructible : BoolType<__is_trivially_destructible(T)>
{ {
}; };
// Struct whose ::Value member is equal to true if T is an enumeration type, and false otherwise. // Struct whose ::Value member is equal to true if T is an enumeration type, and false otherwise.
template<typename T> template<typename T>
struct IsEnum : BoolType<__is_enum(T)> struct IsEnum : BoolType<__is_enum(T)>
{ {
}; };
#else #else
// Struct whose ::Value member is equal to true if you can cast from T to U, and false otherwise. // Struct whose ::Value member is equal to true if you can cast from T to U, and false otherwise.
template <class T, class U> template <class T, class U>
struct IsConvertible : BoolType<std::is_convertible<T, U>::value> struct IsConvertible : BoolType<std::is_convertible<T, U>::value>
{ {
}; };
// Struct whose ::Value member is equal to true if you can construct an object of type T using the arguments // Struct whose ::Value member is equal to true if you can construct an object of type T using the arguments
// provided. // provided.
template<typename T, typename... Args> template<typename T, typename... Args>
struct IsConstructible : BoolType<std::is_constructible<T, Args...>::value> struct IsConstructible : BoolType<std::is_constructible<T, Args...>::value>
{ {
}; };
// Struct whose ::Value member is equal to true if T is an abstract class, and false otherwise. // Struct whose ::Value member is equal to true if T is an abstract class, and false otherwise.
template<typename T> template<typename T>
struct IsAbstract : BoolType<std::is_abstract<T>::value> struct IsAbstract : BoolType<std::is_abstract<T>::value>
{ {
}; };
// Struct whose ::Value member is equal to true if T is an abstract class, and false otherwise. // Struct whose ::Value member is equal to true if T is an abstract class, and false otherwise.
template<typename T> template<typename T>
struct IsPod : BoolType<std::is_trivial<T>::value> struct IsPod : BoolType<std::is_trivial<T>::value>
{ {
}; };
// Struct whose ::Value member is equal to true if T is has a standard layout, and false otherwise. // Struct whose ::Value member is equal to true if T is has a standard layout, and false otherwise.
template<typename T> template<typename T>
struct IsStandardLayout : BoolType<std::is_standard_layout<T>::value> struct IsStandardLayout : BoolType<std::is_standard_layout<T>::value>
{ {
}; };
// Struct whose ::Value member is equal to true if T is trivially destructable, and false otherwise. // Struct whose ::Value member is equal to true if T is trivially destructable, and false otherwise.
template<typename T> template<typename T>
struct IsTriviallyDestructible : BoolType<std::is_trivially_destructible<T>::value> struct IsTriviallyDestructible : BoolType<std::is_trivially_destructible<T>::value>
{ {
}; };
// Struct whose ::Value member is equal to true if T is an enumeration type, and false otherwise. // Struct whose ::Value member is equal to true if T is an enumeration type, and false otherwise.
template<typename T> template<typename T>
struct IsEnum : BoolType<std::is_enum<T>::value> struct IsEnum : BoolType<std::is_enum<T>::value>
{ {
}; };
#endif #endif
} }
} // DevDriver } // DevDriver
@@ -1,115 +1,115 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
#pragma once #pragma once
#if defined(_KERNEL_MODE) #if defined(_KERNEL_MODE)
static_assert(false, "This header is for user mode windows, and it does not work in kernel mode."); static_assert(false, "This header is for user mode windows, and it does not work in kernel mode.");
#endif #endif
// Our code expects these defined before including Windows.h. // Our code expects these defined before including Windows.h.
// However, we need to guard against clients defining them too. // However, we need to guard against clients defining them too.
#ifndef _CRT_RAND_S #ifndef _CRT_RAND_S
#define _CRT_RAND_S #define _CRT_RAND_S
#endif #endif
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif
#ifndef NOMINMAX #ifndef NOMINMAX
#define NOMINMAX #define NOMINMAX
#endif #endif
// WIN32_NO_STATUS makes Windows.h not include macro definitions from winnt.h // WIN32_NO_STATUS makes Windows.h not include macro definitions from winnt.h
// which collide with those from ntstatus.h. This avoids compilation errors // which collide with those from ntstatus.h. This avoids compilation errors
// when other files that include ntstatus.h also include this file. // when other files that include ntstatus.h also include this file.
#define WIN32_NO_STATUS #define WIN32_NO_STATUS
#include <Windows.h> #include <Windows.h>
#undef WIN32_NO_STATUS #undef WIN32_NO_STATUS
#include <intrin.h> #include <intrin.h>
#define DD_RESTRICT __restrict #define DD_RESTRICT __restrict
#define DD_DEBUG_BREAK() __debugbreak() #define DD_DEBUG_BREAK() __debugbreak()
namespace DevDriver namespace DevDriver
{ {
namespace Platform namespace Platform
{ {
/* platform functions for performing atomic operations */ /* platform functions for performing atomic operations */
typedef volatile LONG Atomic; typedef volatile LONG Atomic;
DD_CHECK_SIZE(Atomic, sizeof(int32)); DD_CHECK_SIZE(Atomic, sizeof(int32));
typedef volatile LONG64 Atomic64; typedef volatile LONG64 Atomic64;
DD_CHECK_SIZE(Atomic64, sizeof(int64)); DD_CHECK_SIZE(Atomic64, sizeof(int64));
struct EmptyStruct {}; struct EmptyStruct {};
struct MutexStorage struct MutexStorage
{ {
CRITICAL_SECTION criticalSection; CRITICAL_SECTION criticalSection;
#if !defined(NDEBUG) #if !defined(NDEBUG)
Atomic lockCount; Atomic lockCount;
#endif #endif
}; };
typedef Handle SemaphoreStorage; typedef Handle SemaphoreStorage;
typedef HANDLE EventStorage; typedef HANDLE EventStorage;
typedef HANDLE ThreadHandle; typedef HANDLE ThreadHandle;
typedef DWORD ThreadReturnType; typedef DWORD ThreadReturnType;
typedef HMODULE LibraryHandle; typedef HMODULE LibraryHandle;
constexpr ThreadHandle kInvalidThreadHandle = NULL; constexpr ThreadHandle kInvalidThreadHandle = NULL;
// Maximum supported size for thread names, including NULL byte // Maximum supported size for thread names, including NULL byte
// This exists because some platforms have hard limits on thread name size. // This exists because some platforms have hard limits on thread name size.
// Windows doesn't seem to have a thread name size limit, but we use this variable to control // Windows doesn't seem to have a thread name size limit, but we use this variable to control
// a formatting buffer as well and we want to keep it reasonably small since it's stack allocated. // a formatting buffer as well and we want to keep it reasonably small since it's stack allocated.
static constexpr size_t kThreadNameMaxLength = 64; static constexpr size_t kThreadNameMaxLength = 64;
#define DD_APIENTRY APIENTRY #define DD_APIENTRY APIENTRY
namespace Windows namespace Windows
{ {
// Windows specific functions required for in-memory communication // Windows specific functions required for in-memory communication
Handle CreateSharedSemaphore(uint32 initialCount, uint32 maxCount); Handle CreateSharedSemaphore(uint32 initialCount, uint32 maxCount);
Handle CopySemaphoreFromProcess(ProcessId processId, Handle hObject); Handle CopySemaphoreFromProcess(ProcessId processId, Handle hObject);
Result SignalSharedSemaphore(Handle pSemaphore); Result SignalSharedSemaphore(Handle pSemaphore);
Result WaitSharedSemaphore(Handle pSemaphore, uint32 millisecTimeout); Result WaitSharedSemaphore(Handle pSemaphore, uint32 millisecTimeout);
void CloseSharedSemaphore(Handle pSemaphore); void CloseSharedSemaphore(Handle pSemaphore);
Handle CreateSharedBuffer(Size bufferSizeInBytes); Handle CreateSharedBuffer(Size bufferSizeInBytes);
void CloseSharedBuffer(Handle hSharedBuffer); void CloseSharedBuffer(Handle hSharedBuffer);
Handle MapSystemBufferView(Handle hBuffer, Size bufferSizeInBytes); Handle MapSystemBufferView(Handle hBuffer, Size bufferSizeInBytes);
Handle MapProcessBufferView(Handle hBuffer, ProcessId processId); Handle MapProcessBufferView(Handle hBuffer, ProcessId processId);
void UnmapBufferView(Handle hSharedBuffer, Handle hSharedBufferView); void UnmapBufferView(Handle hSharedBuffer, Handle hSharedBufferView);
// Whether or not the user has enabled Windows Developer Mode on their system // Whether or not the user has enabled Windows Developer Mode on their system
// See: https://github.com/MicrosoftDocs/windows-uwp/blob/docs/hub/apps/get-started/enable-your-device-for-development.md // See: https://github.com/MicrosoftDocs/windows-uwp/blob/docs/hub/apps/get-started/enable-your-device-for-development.md
bool IsWin10DeveloperModeEnabled(); bool IsWin10DeveloperModeEnabled();
} }
} }
} }
@@ -1,62 +1,62 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
#pragma once #pragma once
#include "protocolServer.h" #include "protocolServer.h"
namespace DevDriver namespace DevDriver
{ {
class IMsgChannel; class IMsgChannel;
class BaseProtocolServer : public IProtocolServer class BaseProtocolServer : public IProtocolServer
{ {
public: public:
virtual ~BaseProtocolServer(); virtual ~BaseProtocolServer();
Protocol GetProtocol() const override final { return m_protocol; }; Protocol GetProtocol() const override final { return m_protocol; };
SessionType GetType() const override final { return SessionType::Server; }; SessionType GetType() const override final { return SessionType::Server; };
Version GetMinVersion() const override final { return m_minVersion; }; Version GetMinVersion() const override final { return m_minVersion; };
Version GetMaxVersion() const override final { return m_maxVersion; }; Version GetMaxVersion() const override final { return m_maxVersion; };
bool GetSupportedVersion(Version minVersion, Version maxVersion, Version * version) const override final; bool GetSupportedVersion(Version minVersion, Version maxVersion, Version * version) const override final;
virtual void Finalize() override; virtual void Finalize() override;
protected: protected:
BaseProtocolServer(IMsgChannel* pMsgChannel, Protocol protocol, Version minVersion, Version maxVersion); BaseProtocolServer(IMsgChannel* pMsgChannel, Protocol protocol, Version minVersion, Version maxVersion);
// Helper functions for working with SizedPayloadContainers // Helper functions for working with SizedPayloadContainers
Result SendPayload(ISession* pSession, const SizedPayloadContainer* pPayload, uint32 timeoutInMs); Result SendPayload(ISession* pSession, const SizedPayloadContainer* pPayload, uint32 timeoutInMs);
Result ReceivePayload(ISession* pSession, SizedPayloadContainer* pPayload, uint32 timeoutInMs); Result ReceivePayload(ISession* pSession, SizedPayloadContainer* pPayload, uint32 timeoutInMs);
IMsgChannel* const m_pMsgChannel; IMsgChannel* const m_pMsgChannel;
const Protocol m_protocol; const Protocol m_protocol;
const Version m_minVersion; const Version m_minVersion;
const Version m_maxVersion; const Version m_maxVersion;
bool m_isFinalized; bool m_isFinalized;
}; };
} // DevDriver } // DevDriver
+28 -28
파일 보기
@@ -1,28 +1,28 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
#pragma once #pragma once
#include "../core/inc/ddcDefs.h" #include "../core/inc/ddcDefs.h"
@@ -1,48 +1,48 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
#pragma once #pragma once
#ifndef DD_PLATFORM_WINDOWS_UM #ifndef DD_PLATFORM_WINDOWS_UM
#if _WIN32 && !_KERNEL_MODE #if _WIN32 && !_KERNEL_MODE
#define DD_PLATFORM_WINDOWS_UM 1 #define DD_PLATFORM_WINDOWS_UM 1
#define DD_PLATFORM_IS_UM 1 #define DD_PLATFORM_IS_UM 1
#endif #endif
#endif #endif
#ifndef DD_PLATFORM_WINDOWS_KM #ifndef DD_PLATFORM_WINDOWS_KM
#if _WIN32 && _KERNEL_MODE #if _WIN32 && _KERNEL_MODE
#define DD_PLATFORM_WINDOWS_KM 1 #define DD_PLATFORM_WINDOWS_KM 1
#define DD_PLATFORM_IS_KM 1 #define DD_PLATFORM_IS_KM 1
#endif #endif
#endif #endif
#ifndef DD_PLATFORM_LINUX_UM #ifndef DD_PLATFORM_LINUX_UM
#ifdef __linux__ #ifdef __linux__
#define DD_PLATFORM_LINUX_UM 1 #define DD_PLATFORM_LINUX_UM 1
#define DD_PLATFORM_IS_UM 1 #define DD_PLATFORM_IS_UM 1
#define DD_PLATFORM_IS_GNU 1 #define DD_PLATFORM_IS_GNU 1
#endif #endif
#endif #endif
+28 -28
파일 보기
@@ -1,28 +1,28 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
#pragma once #pragma once
#include "../core/inc/ddcPlatform.h" #include "../core/inc/ddcPlatform.h"
+28 -28
파일 보기
@@ -1,28 +1,28 @@
/* /*
*********************************************************************************************************************** ***********************************************************************************************************************
* *
* Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved. * Copyright (c) 2021-2025 Advanced Micro Devices, Inc. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
* *
**********************************************************************************************************************/ **********************************************************************************************************************/
#pragma once #pragma once
#include "../core/inc/ddcTemplate.h" #include "../core/inc/ddcTemplate.h"

이 Diff에서 너무 많은 파일이 변경되어 일부 파일이 표시되지 않았습니다 더 보기