Skip to content

Commit 10d0c0f

Browse files
committed
Add source code for RMV 1.4 release.
1 parent 1ff78f3 commit 10d0c0f

40 files changed

+638
-152
lines changed

source/backend/rmt_adapter_info.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,28 @@ const char* RmtAdapterInfoGetVideoMemoryType(const RmtAdapterInfo* adapter_info)
1616
{
1717
case kRmtAdapterInfoMemoryTypeUnknown:
1818
return "Unknown";
19-
case kRmtAdapterInfoMemoryTypeDdR2:
19+
case kRmtAdapterInfoMemoryTypeDdr2:
2020
return "DDR2";
21-
case kRmtAdapterInfoMemoryTypeDdR3:
21+
case kRmtAdapterInfoMemoryTypeDdr3:
2222
return "DDR3";
23-
case kRmtAdapterInfoMemoryTypeDdR4:
23+
case kRmtAdapterInfoMemoryTypeDdr4:
2424
return "DDR4";
25-
case kRmtAdapterInfoMemoryTypeGddR5:
25+
case kRmtAdapterInfoMemoryTypeDdr5:
26+
return "DDR5";
27+
case kRmtAdapterInfoMemoryTypeGddr5:
2628
return "GDDR5";
27-
case kRmtAdapterInfoMemoryTypeGddR6:
29+
case kRmtAdapterInfoMemoryTypeGddr6:
2830
return "GDDR6";
2931
case kRmtAdapterInfoMemoryTypeHbm:
3032
return "HBM";
3133
case kRmtAdapterInfoMemoryTypeHbm2:
3234
return "HBM2";
3335
case kRmtAdapterInfoMemoryTypeHbm3:
3436
return "HBM3";
37+
case kRmtAdapterInfoMemoryTypeLpddr4:
38+
return "LPDDR4";
39+
case kRmtAdapterInfoMemoryTypeLpddr5:
40+
return "LPDDR5";
3541

3642
default:
3743
return "";

source/backend/rmt_adapter_info.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,24 @@
1717
extern "C" {
1818
#endif // #ifdef __cplusplus
1919

20-
/// An enumeration of memory types that can be used with an adapter.
20+
/// @brief An enumeration of memory types that can be used with an adapter.
2121
typedef enum RmtAdapterInfoMemoryType
2222
{
2323
kRmtAdapterInfoMemoryTypeUnknown = 0, ///< Memory is unknown.
24-
kRmtAdapterInfoMemoryTypeDdR2 = 1, ///<
25-
kRmtAdapterInfoMemoryTypeDdR3 = 2, ///<
26-
kRmtAdapterInfoMemoryTypeDdR4 = 3, ///< .
27-
kRmtAdapterInfoMemoryTypeGddR5 = 4, ///< Graphics DDR 5.
28-
kRmtAdapterInfoMemoryTypeGddR6 = 5, ///< Graphics DDR 6.
24+
kRmtAdapterInfoMemoryTypeDdr2 = 1, ///< System DDR2.
25+
kRmtAdapterInfoMemoryTypeDdr3 = 2, ///< System DDR3.
26+
kRmtAdapterInfoMemoryTypeDdr4 = 3, ///< System DDR4.
27+
kRmtAdapterInfoMemoryTypeGddr5 = 4, ///< Graphics DDR 5.
28+
kRmtAdapterInfoMemoryTypeGddr6 = 5, ///< Graphics DDR 6.
2929
kRmtAdapterInfoMemoryTypeHbm = 6, ///< First version of High-Bandwidth Memory.
3030
kRmtAdapterInfoMemoryTypeHbm2 = 7, ///< Second version of High-Bandwidth Memory.
31-
kRmtAdapterInfoMemoryTypeHbm3 = 8 ///< Third version of High-Bandwidth Memory.
31+
kRmtAdapterInfoMemoryTypeHbm3 = 8, ///< Third version of High-Bandwidth Memory.
32+
kRmtAdapterInfoMemoryTypeLpddr4 = 9, ///< Low power DDR4.
33+
kRmtAdapterInfoMemoryTypeLpddr5 = 10, ///< Low power DDR5.
34+
kRmtAdapterInfoMemoryTypeDdr5 = 11 ///< System DDR5.
3235
} RmtAdapterInfoMemoryType;
3336

34-
/// A structure encapsulating the information about the adapter.
37+
/// @brief A structure encapsulating the information about the adapter.
3538
typedef struct RmtAdapterInfo
3639
{
3740
char name[RMT_MAX_ADAPTER_NAME_LENGTH]; ///< The name of the adapter as a NULL terminated string.
@@ -48,7 +51,7 @@ typedef struct RmtAdapterInfo
4851
uint32_t maximum_memory_clock; ///< The maximum memory clock (in MHz).
4952
} RmtAdapterInfo;
5053

51-
/// Get the chip type (in string) of the video memory.
54+
/// @brief Get the chip type (in string) of the video memory.
5255
///
5356
/// @param [in] adapter_info A pointer to a <c><i>RmtAdapterInfo</i></c> structure.
5457
///

source/backend/rmt_data_set.cpp

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//=============================================================================
2-
// Copyright (c) 2019-2021 Advanced Micro Devices, Inc. All rights reserved.
2+
// Copyright (c) 2019-2022 Advanced Micro Devices, Inc. All rights reserved.
33
/// @author AMD Developer Tools Team
44
/// @file
55
/// @brief Implementation of functions for working with a data set.
66
//=============================================================================
77

88
#include <map>
9-
#include <set>
9+
#include <unordered_set>
1010
#include <stdlib.h> // for malloc() / free()
1111
#include <string>
1212
#include <string.h> // for memcpy()
@@ -102,7 +102,10 @@ static std::map<RmtCorrelationIdentifier, RmtResourceNameData> resource_name_loo
102102
static std::map<RmtResourceIdentifier, RmtResourceIdentifier> unique_resource_id_lookup_map;
103103

104104
// A list of implicit resources to be removed from a snapshot.
105-
static std::set<RmtResourceIdentifier> implicit_resource_list;
105+
static std::unordered_set<RmtResourceIdentifier> implicit_resource_list;
106+
107+
// The set of created resources at any point in time.
108+
static std::unordered_set<RmtResourceIdentifier> created_resources;
106109

107110
// A flag used to indicate that the list of implicit resources has been created.
108111
// This list is created when the trace is first parsed and the timeline is built.
@@ -407,6 +410,22 @@ static RmtErrorCode ParseChunks(RmtDataSet* data_set)
407410
return kRmtOk;
408411
}
409412

413+
// Check for SAM (Smart access memory) support.
414+
//
415+
// Without SAM support, the local memory size is 256MB. If SAM is enabled, the local memory
416+
// will be the total GPU memory. In addition, the invisible memory available will be 0 bytes.
417+
static void CheckForSAMSupport(RmtDataSet* data_set)
418+
{
419+
if (data_set->segment_info[kRmtHeapTypeInvisible].size == 0)
420+
{
421+
data_set->sam_enabled = true;
422+
}
423+
else
424+
{
425+
data_set->sam_enabled = false;
426+
}
427+
}
428+
410429
static void BuildDataProfileParseUserdata(RmtDataSet* data_set, const RmtToken* current_token)
411430
{
412431
RMT_ASSERT(current_token->type == kRmtTokenTypeUserdata);
@@ -459,10 +478,13 @@ static void BuildDataProfileParseResourceCreate(RmtDataSet* data_set, const RmtT
459478
{
460479
RMT_ASSERT(current_token->type == kRmtTokenTypeResourceCreate);
461480

481+
// Add this resource to the list of created resources, and keep track of the maximum number of concurrent resources.
482+
created_resources.insert(current_token->resource_create_token.resource_identifier);
483+
data_set->data_profile.max_concurrent_resources =
484+
RMT_MAXIMUM(data_set->data_profile.max_concurrent_resources, static_cast<int32_t>(created_resources.size()));
485+
462486
data_set->data_profile.current_resource_count++;
463487
data_set->data_profile.total_resource_count++;
464-
data_set->data_profile.max_concurrent_resources =
465-
RMT_MAXIMUM(data_set->data_profile.max_concurrent_resources, data_set->data_profile.current_resource_count);
466488

467489
// Add one to the allocation count if the resource being created is a shareable image, since we might need to create a dummy allocation token
468490
// if we don't see one in the token stream.
@@ -480,6 +502,11 @@ static void BuildDataProfileParseResourceDestroy(RmtDataSet* data_set, const Rmt
480502
{
481503
RMT_ASSERT(current_token->type == kRmtTokenTypeResourceDestroy);
482504

505+
// Only remove the resource from list of created resources if it has previously been created.
506+
if (created_resources.find(current_token->resource_create_token.resource_identifier) != created_resources.end())
507+
{
508+
created_resources.erase(current_token->resource_create_token.resource_identifier);
509+
}
483510
data_set->data_profile.current_resource_count--;
484511
}
485512

@@ -499,6 +526,8 @@ static RmtErrorCode BuildDataProfile(RmtDataSet* data_set)
499526
RmtProcessMapAddProcess(&data_set->process_map, data_set->process_start_info[current_process_start_index].process_id);
500527
}
501528

529+
created_resources.clear();
530+
502531
// if the heap has something there, then add it.
503532
while (!RmtStreamMergerIsEmpty(&data_set->stream_merger))
504533
{
@@ -542,6 +571,8 @@ static RmtErrorCode BuildDataProfile(RmtDataSet* data_set)
542571
}
543572
}
544573

574+
created_resources.clear();
575+
545576
data_set->cpu_frequency = data_set->streams[0].cpu_frequency;
546577

547578
// Create an allocator for the token heap to use for generating unique resource IDs
@@ -587,7 +618,7 @@ static RmtErrorCode AllocateMemoryForSnapshot(RmtDataSet* data_set, RmtDataSnaps
587618

588619
// Initialize the virtual allocation list.
589620
const size_t virtual_allocation_buffer_size =
590-
RmtVirtualAllocationListGetBufferSize(data_set->data_profile.total_virtual_allocation_count, data_set->data_profile.max_concurrent_resources + 200);
621+
RmtVirtualAllocationListGetBufferSize(data_set->data_profile.total_virtual_allocation_count, data_set->data_profile.max_concurrent_resources);
591622
if (virtual_allocation_buffer_size > 0)
592623
{
593624
out_snapshot->virtual_allocation_buffer = PerformAllocation(data_set, virtual_allocation_buffer_size, sizeof(uint32_t));
@@ -597,14 +628,14 @@ static RmtErrorCode AllocateMemoryForSnapshot(RmtDataSet* data_set, RmtDataSnaps
597628
out_snapshot->virtual_allocation_buffer,
598629
virtual_allocation_buffer_size,
599630
data_set->data_profile.max_virtual_allocation_count,
600-
data_set->data_profile.max_concurrent_resources + 200,
631+
data_set->data_profile.max_concurrent_resources,
601632
data_set->data_profile.total_virtual_allocation_count);
602633
RMT_ASSERT(error_code == kRmtOk);
603634
RMT_RETURN_ON_ERROR(error_code == kRmtOk, error_code);
604635
}
605636

606637
// create the resource list.
607-
const size_t resource_list_buffer_size = RmtResourceListGetBufferSize(data_set->data_profile.max_concurrent_resources + 200);
638+
const size_t resource_list_buffer_size = RmtResourceListGetBufferSize(data_set->data_profile.max_concurrent_resources);
608639
if (resource_list_buffer_size > 0)
609640
{
610641
out_snapshot->resource_list_buffer = PerformAllocation(data_set, resource_list_buffer_size, sizeof(uint32_t));
@@ -614,7 +645,7 @@ static RmtErrorCode AllocateMemoryForSnapshot(RmtDataSet* data_set, RmtDataSnaps
614645
out_snapshot->resource_list_buffer,
615646
resource_list_buffer_size,
616647
&out_snapshot->virtual_allocation_list,
617-
data_set->data_profile.max_concurrent_resources + 200);
648+
data_set->data_profile.max_concurrent_resources);
618649
RMT_ASSERT(error_code == kRmtOk);
619650
RMT_RETURN_ON_ERROR(error_code == kRmtOk, error_code);
620651
}
@@ -793,12 +824,15 @@ static RmtErrorCode ProcessTokenForSnapshot(RmtDataSet* data_set, RmtToken* curr
793824
current_token->resource_bind_token.virtual_address,
794825
(int32_t)(current_token->resource_bind_token.size_in_bytes >> 12),
795826
kDummyHeapPref,
796-
RmtOwnerType::kRmtOwnerTypeClientDriver);
827+
RmtOwnerType::kRmtOwnerTypeClientDriver,
828+
data_set->sam_enabled);
797829
}
798830
else if (error_code == kRmtErrorResourceAlreadyBound)
799831
{
800-
// duplicate the command allocator resource we have at this resource ID this is because command allocators are
801-
// bound to multiple chunks of virtual address space simultaneously.
832+
// Handle the case where the resource is already bound to a virtual memory allocation.
833+
// This can occur for command allocators which can be bound to multiple chunks of virtual
834+
// address space simultaneously or buffer resources already bound to an allocation. These
835+
// resources are implicitly destroyed, created again and bound to a different allocation.
802836
const RmtResource* matching_resource = NULL;
803837
error_code = RmtResourceListGetResourceByResourceId(
804838
&out_snapshot->resource_list, current_token->resource_bind_token.resource_identifier, &matching_resource);
@@ -809,24 +843,40 @@ static RmtErrorCode ProcessTokenForSnapshot(RmtDataSet* data_set, RmtToken* curr
809843
resource_create_token.resource_identifier = matching_resource->identifier;
810844
resource_create_token.owner_type = matching_resource->owner_type;
811845
resource_create_token.commit_type = matching_resource->commit_type;
812-
resource_create_token.resource_type = kRmtResourceTypeCommandAllocator;
846+
resource_create_token.resource_type = matching_resource->resource_type;
813847
memcpy(&resource_create_token.common, &current_token->common, sizeof(RmtTokenCommon));
814-
memcpy(&resource_create_token.command_allocator, &matching_resource->command_allocator, sizeof(RmtResourceDescriptionCommandAllocator));
815848

816-
// Create the resource.
849+
switch (matching_resource->resource_type)
850+
{
851+
case kRmtResourceTypeCommandAllocator:
852+
memcpy(&resource_create_token.command_allocator, &matching_resource->command_allocator, sizeof(RmtResourceDescriptionCommandAllocator));
853+
break;
854+
855+
case kRmtResourceTypeBuffer:
856+
memcpy(&resource_create_token.buffer, &matching_resource->buffer, sizeof(RmtResourceDescriptionBuffer));
857+
break;
858+
859+
default:
860+
// Unexpected resource type.
861+
RMT_ASSERT_FAIL("Re-binding is only supported for buffer and command allocator resource types");
862+
break;
863+
}
864+
865+
// Create the resource. Since the resource already exists, the Create operation will implicitly destroy it first.
817866
error_code = RmtResourceListAddResourceCreate(&out_snapshot->resource_list, &resource_create_token);
818867
RMT_ASSERT(error_code == kRmtOk);
819868

820869
if (!(current_token->resource_bind_token.is_system_memory && current_token->resource_bind_token.virtual_address == 0))
821870
{
871+
// Re-bind the resource to its new virtual memory allocation.
822872
error_code = RmtResourceListAddResourceBind(&out_snapshot->resource_list, &current_token->resource_bind_token);
823873
RMT_ASSERT(error_code == kRmtOk);
824874
}
825875
}
826876
}
827877

828878
RMT_ASSERT(error_code == kRmtOk);
829-
//RMT_RETURN_ON_ERROR(error_code == kRmtOk, error_code);
879+
// RMT_RETURN_ON_ERROR(error_code == kRmtOk, error_code);
830880
}
831881
break;
832882

@@ -877,13 +927,13 @@ static RmtErrorCode ProcessTokenForSnapshot(RmtDataSet* data_set, RmtToken* curr
877927
current_token->virtual_allocate_token.virtual_address,
878928
current_token->virtual_allocate_token.size_in_bytes);
879929
#endif
880-
881930
error_code = RmtVirtualAllocationListAddAllocation(&out_snapshot->virtual_allocation_list,
882931
current_token->common.timestamp,
883932
current_token->virtual_allocate_token.virtual_address,
884933
(int32_t)(current_token->virtual_allocate_token.size_in_bytes >> 12),
885934
current_token->virtual_allocate_token.preference,
886-
current_token->virtual_allocate_token.owner_type);
935+
current_token->virtual_allocate_token.owner_type,
936+
data_set->sam_enabled);
887937
RMT_ASSERT(error_code == kRmtOk);
888938
RMT_RETURN_ON_ERROR(error_code == kRmtOk, error_code);
889939
}
@@ -1064,6 +1114,8 @@ RmtErrorCode RmtDataSetInitialize(const char* path, RmtDataSet* data_set)
10641114
RMT_ASSERT(error_code == kRmtOk);
10651115
RMT_RETURN_ON_ERROR(error_code == kRmtOk, error_code);
10661116

1117+
CheckForSAMSupport(data_set);
1118+
10671119
// construct the data profile for subsequent data parsing.
10681120
error_code = BuildDataProfile(data_set);
10691121
RMT_ASSERT(error_code == kRmtOk);

source/backend/rmt_data_set.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ typedef struct RmtDataSet
6060
void* file_handle; ///< The handle to the RMT file (operates on the temporary).
6161
size_t file_size_in_bytes; ///< The size of the file pointed to by <c><i>fileHandle</i></c> in bytes.
6262
bool read_only; ///< Whether the dataset is loaded as read-only.
63+
bool sam_enabled; ///< Whether the dataset is SAM (smart access memory) enabled.
6364
time_t create_time; ///< The time the trace was created.
6465

6566
RmtDataSetAllocationFunc allocate_func; ///< Allocate memory function pointer.

source/backend/rmt_resource_list.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//=============================================================================
2-
// Copyright (c) 2019-2021 Advanced Micro Devices, Inc. All rights reserved.
2+
// Copyright (c) 2019-2022 Advanced Micro Devices, Inc. All rights reserved.
33
/// @author AMD Developer Tools Team
44
/// @file
55
/// @brief Implementation of the resource list functions.
@@ -751,11 +751,14 @@ RmtErrorCode RmtResourceListAddResourceBind(RmtResourceList* resource_list, cons
751751
// NOTE: We have multiple binds per resource for command buffer allocators,
752752
// This is because they grow in size to accomodate the allocators needs. GPU events
753753
// are often inlined into command buffers, so these are also affected by extension.
754-
// for now we are only handling the command allocator case.
754+
// Buffer resources which have already been bound to a virtual memory allocation are also
755+
// flagged with the kRmtErrorResourceAlreadyBound return value. The caller can then destroy
756+
// the existing resource, create a new resource and re-bind it to a different allocation.
755757
if (resource->bound_allocation != nullptr)
756758
{
757759
switch (resource->resource_type)
758760
{
761+
case kRmtResourceTypeBuffer:
759762
case kRmtResourceTypeCommandAllocator:
760763
return kRmtErrorResourceAlreadyBound;
761764

0 commit comments

Comments
 (0)