Skip to content
SiteEmail

In version 1.40, Gameface introduces GPU memory tracking. This comes with the ability to extract detailed information about the allocated GPU memory in the Library and the ability to reset the GPU memory peaks. That makes it easier to check the memory statistics of the allocated resources.

NOTE This API is only available in a Developer configuration.

This page provides details about the feature, a list of everything we track, a sample of how to obtain the information, as well as a few general considerations for extracting the information.

We have developed a structure to hold the GPU memory data called GPUMemoryInfo, which can be filled with all the tracked information using the help of the GetGPUMemoryStats() method found in the Library. As for user textures, which are tracked separately from the rest of the GPU memory, the cohtml::UserGPUMemoryInfo* Library::GetUserGPUMemoryStats() method can be used to retrieve their information, which is encapsulated in a different structure called UserGPUMemoryInfo. The GPUMemoryInfo::Release() method must be called on the returned cohtml::GPUMemoryInfo* or cohtml::UserGPUMemoryInfo* pointer to free its allocated memory. The statistics from the Library include all shared resources across the Views. A list of every member in the GPUMemoryInfo and UserGPUMemoryInfo structures along with a description of what each member tracks is provided below.

In order to reset the accumulated memory peaks to match the current state, the ResetGPUMemoryTrackerPeaks() method of the Library needs to be invoked. Resetting the peaks of the Library will also reset the user textures’ peaks.

The extracted GPU statistics can be used to monitor how frequently specific textures are used. The relevant fields provide the following information:

  1. LastRenderingExecutionID - The ID of the most recent rendering execution.
  2. LastUsedID - The ID of the rendering execution in which a specific texture was last accessed.
  3. TimesUsed - The number of rendering executions in which a specific texture has been used.

Refer to the LastUsedID, TimesUsed and LastRenderingExecutionID fields in the statistics below.

A list of all the monitored GPU memory data

Section titled “A list of all the monitored GPU memory data”
MemberDescription
size_t TotalBytes;The total GPU memory
size_t PeakBytes;The highest GPU memory reached
size_t LastRenderingExecutionID;The ID of the last rendering execution
TextureInfo TexturesInformation[renoir::domains::TextureType::TT_Count];An array of TextureInfo objects containing all tracked textures’ information separated by their TextureType. Only the color textures’ (TT_ColorTexture) info is stored here
TextureResources DSTexturesInformation;A TextureResources object containing all tracked Depth-Stencil textures’ information
BufferInfo BuffersInformation[renoir::domains::BufferType::BT_Count];An array of BufferInfo objects containing all tracked buffers’ information separated by their BufferType
ExtraColorImageTexturesInfo ExtraColorImageTexturesInformation;An array of additional information about the texture, like it’s name and which views it is used in. The ArraySize member is equal to TexturesInformation[renoir::domains::TextureType::TT_ColorTexture].ResourceArray[renoir::domains::TextureDomain::T_ImageTexture].ArraySize, so the index used to iterate the image color textures can be directly used to iterate the extra information.

In-depth description of TexturesInformation’s members

Section titled “In-depth description of TexturesInformation’s members”
MemberDescription
TexturesInformation[TT_ColorTexture]Color texture statistics.
TexturesInformation[TT_DepthTexture]Deprecated field, which used to store Depth-Stencil texture statistics. Now stored in DSTexturesInformation
TexturesInformation[TT_ColorTexture].Total.BytesThe total GPU memory of all color textures
TexturesInformation[TT_ColorTexture].Total.CountThe count of all current color textures
TexturesInformation[TT_ColorTexture].Peak.BytesThe highest reached GPU memory of all color textures
TexturesInformation[TT_ColorTexture].Peak.CountThe highest reached count of all color textures
TexturesInformation[TT_ColorTexture].ResourceArray[TextureDomain]Color texture statistics by TextureDomain. Array size is TextureDomain::T_Count
TexturesInformation[TT_ColorTexture].ResourceArray[TextureDomain].Total.BytesThe total GPU memory of all color textures from the specified TextureDomain
TexturesInformation[TT_ColorTexture].ResourceArray[TextureDomain].Total.CountThe count of all current color textures from the specified TextureDomain
TexturesInformation[TT_ColorTexture].ResourceArray[TextureDomain].Peak.BytesThe highest reached GPU memory of all color textures from the specified TextureDomain
TexturesInformation[TT_ColorTexture].ResourceArray[TextureDomain].Peak.CountThe highest reached count of all color textures from the specified TextureDomain
TexturesInformation[TT_ColorTexture].ResourceArray[TextureDomain].ArrayTexture statistics of all current color textures from the specified TextureDomain
TexturesInformation[TT_ColorTexture].ResourceArray[TextureDomain].ArraySizeThe Array size. Same as TexturesInformation[renoir::domains::TextureType::TT_ColorTexture].ResourceArray[TextureDomain].Total.Count
TexturesInformation[TT_ColorTexture].ResourceArray[TextureDomain].Array[ind].IdThe color texture’s ID
TexturesInformation[TT_ColorTexture].ResourceArray[TextureDomain].Array[ind].BytesThe color texture’s size
TexturesInformation[TT_ColorTexture].ResourceArray[TextureDomain].Array[ind].OwnerIdThe color texture’s scene ID. If it instead belongs to the Library, the ID will equal unsigned(-1) aka RENOIR_INVALID
TexturesInformation[TT_ColorTexture].ResourceArray[TextureDomain].Array[ind].LastUsedIDID of the rendering execution, this texture was last used in
TexturesInformation[TT_ColorTexture].ResourceArray[TextureDomain].Array[ind].TimesUsedTotal amount of rendering executions, this texture has been used in

In-depth description of DSTexturesInformation’s members

Section titled “In-depth description of DSTexturesInformation’s members”
MemberDescription
DSTexturesInformationDepth-Stencil texture statistics
DSTexturesInformation.Total.BytesThe total GPU memory of all Depth-Stencil textures
DSTexturesInformation.Total.CountThe count of all current Depth-Stencil textures
DSTexturesInformation.Peak.BytesThe highest reached GPU memory of all Depth-Stencil textures
DSTexturesInformation.Peak.CountThe highest reached count of all Depth-Stencil textures
DSTexturesInformation.ArrayDepth-Stencil texture statistics of all current Depth-Stencil textures
DSTexturesInformation.ArraySizeThe Array size. Same as DSTexturesInformation.Total.Count
DSTexturesInformation.Array[ind].IdThe Depth-Stencil texture’s ID
DSTexturesInformation.Array[ind].BytesThe Depth-Stencil texture’s size
DSTexturesInformation.Array[ind].OwnerIdThe Depth-Stencil texture’s owner. All DS textures belong to the Library, so the ID equals unsigned(-1) aka RENOIR_INVALID
DSTexturesInformation.Array[ind].LastUsedIDID of the rendering execution, this Depth-Stencil texture was last used in
DSTexturesInformation.Array[ind].TimesUsedTotal amount of rendering executions, this Depth-Stencil texture has been used in

In-depth description of BuffersInformation’s members

Section titled “In-depth description of BuffersInformation’s members”
MemberDescription
BuffersInformation[BufferType]Buffer statistics by BufferType. Array size is BufferType::BT_Count
BuffersInformation[BufferType].Total.BytesThe total GPU memory of all buffers from the specified BufferType
BuffersInformation[BufferType].Total.CountThe count of all current buffers from the specified BufferType
BuffersInformation[BufferType].Peak.BytesThe highest reached GPU memory of all buffers from the specified BufferType
BuffersInformation[BufferType].Peak.CountThe highest reached count of all buffers from the specified BufferType
BuffersInformation[BufferType].ResourceArray[MAX_BUFFER_DOMAIN_COUNT]Buffer statistics by domain for the specified BufferType. Size is indicated by the buffer domain’s count (IB_Count, VB_Count, CB_Count)
BuffersInformation[BufferType].ResourceArray[BufferDomain].Total.BytesThe total GPU memory of all buffers from the specified BufferDomain and BufferType
BuffersInformation[BufferType].ResourceArray[BufferDomain].Total.CountThe count of all current buffers from the specified BufferDomain and BufferType
BuffersInformation[BufferType].ResourceArray[BufferDomain].Peak.BytesThe highest reached allocated GPU memory of all buffers from the specified BufferDomain and BufferType
BuffersInformation[BufferType].ResourceArray[BufferDomain].Peak.CountThe highest reached count of all buffers from the specified BufferDomain and BufferType
BuffersInformation[BufferType].ResourceArray[BufferDomain].ArrayBuffer statistics of all current buffers from the specified BufferDomain and BufferType
BuffersInformation[BufferType].ResourceArray[BufferDomain].ArraySizeThe Array size. Same as BuffersInformation[BufferType].ResourceArray[BufferDomain].Total.Count
BuffersInformation[BufferType].ResourceArray[BufferDomain].Array[ind].IdThe buffer’s ID
BuffersInformation[BufferType].ResourceArray[BufferDomain].Array[ind].BytesThe buffer’s allocated size
BuffersInformation[BufferType].ResourceArray[BufferDomain].Array[ind].PeakUsageBytesThe highest amount of bytes used from the buffer’s allocated memory
BuffersInformation[BufferType].ResourceArray[BufferDomain].Array[ind].OwnerIdThe buffer’s scene ID. If it instead belongs to the Library, the ID will equal unsigned(-1) aka RENOIR_INVALID
BuffersInformation[BufferType].ResourceArray[BufferDomain].Array[ind].LastUsedIDCurrently unused field. Defaults to 0.
BuffersInformation[BufferType].ResourceArray[BufferDomain].Array[ind].TimesUsedCurrently unused field. Defaults to 0.

In-depth description of ExtraColorImageTexturesInformation’s members

Section titled “In-depth description of ExtraColorImageTexturesInformation’s members”
MemberDescription
ExtraColorImageTexturesInformation.Array[ind].NameThe name of the texture
ExtraColorImageTexturesInformation.Array[ind].ViewClientsCountThe total amount of views this texture is registered in
ExtraColorImageTexturesInformation.Array[ind].ViewClientsThe array of views this texture is registered in
MemberDescription
size_t TotalBytes;The total User GPU memory
size_t PeakBytes;The highest User GPU memory reached
size_t LastRenderingExecutionID;ID of the last rendering execution
UserTexturesInfo UserTextureInformationContains information for all tracked user textures
RenderTargetInfo RenderTargetInformation[renoir::domains::TextureType::TT_Count]An array of RenderTargetInfo objects containing all tracked render targets’ information separated by their TextureType
ExtraUserImageInfo ExtraUserImageInformationContains additional information about an image, such as it’s name and how many views it is used in

In-depth description of the UserTexturesInfo’s members

Section titled “In-depth description of the UserTexturesInfo’s members”
MemberDescription
GPUMemoryInfo::MemoryInfo TotalUsageTotal GPU memory used by user images (TotalUsage.Bytes), based on their content size, and the user images’ current count (TotalUsage.Count)
GPUMemoryInfo::MemoryInfo PeakUsagePeak GPU memory used by user images - highest recorded value of TotalUsage.Bytes and TotalUsage.Count
GPUMemoryInfo::MemoryInfo TotalTotal GPU memory used by unique user objects (Total.Bytes) and their current count (Total.Count). Each user object is counted only once, even if reused across multiple user images
GPUMemoryInfo::MemoryInfo PeakPeak GPU memory used by unique user objects - highest recorded value of Total.Bytes and Total.Count
size_t ArraySizeSize of Array
UserTextureInformation.Array[ind].IdThe user texture’s ID
UserTextureInformation.Array[ind].OwnerIdThe user texture’s owner. All user textures belong to the Library, so the ID equals unsigned(-1) aka RENOIR_INVALID
UserTextureInformation.Array[ind].BytesThe size of the user texture in bytes
UserTextureInformation.Array[ind].UserObjectThe user object data itself
UserTextureInformation.Array[ind].LastUsedIDID of the rendering execution, this user texture was last used in
UserTextureInformation.Array[ind].TimesUsedTotal amount of rendering executions, this user texture has been used in
UserTextureInformation.Array[ind].UserObjectBytesThe size of the user object data in bytes

In-depth description of the RenderTargetInfo’s members

Section titled “In-depth description of the RenderTargetInfo’s members”
MemberDescription
GPUMemoryInfo::MemoryInfo TotalThe total render targets’ GPU memory (Total.Bytes) and their current count (Total.Count)
GPUMemoryInfo::MemoryInfo PeakThe highest reached render targets’ GPU memory (Peak.Bytes) and the highest reached peaks count (Peak.Count)
size_t ArraySize;Size of Array
RenderTargetInformation.Array[ind].IdThe render target’s ID
RenderTargetInformation.Array[ind].OwnerIdThe render target’s owner
RenderTargetInformation.Array[ind].BytesThe size of the render target in bytes
RenderTargetInformation.Array[ind].UserObjectThe actual data
RenderTargetInformation.Array[ind].WidthThe width of the render target
RenderTargetInformation.Array[ind].HeightThe height of the render target
RenderTargetInformation.Array[ind].SamplesCountThe sample count

In-depth description of the ExtraUserImageInfo’s members

Section titled “In-depth description of the ExtraUserImageInfo’s members”
MemberDescription
size_t ArraySize;Size of Array
ExtraUserImageInformation.Array[ind].NameThe name of the user image
ExtraUserImageInformation.Array[ind].ViewClientsCountThe total amount of views this user image is registered in
ExtraUserImageInformation.Array[ind].ViewClientsThe array of views this user image is registered in
namespace domains
{
enum TextureType
{
TT_ColorTexture = 0,
TT_DepthTexture,
TT_Count
};
enum BufferType
{
BT_IndexBuffer = 0,
BT_VertexBuffer,
BT_ConstantBuffer,
BT_Count
};
enum TextureDomain
{
T_ScratchTexture = 0,
T_LayerTexture,
T_ImageTexture,
T_SurfaceTexture,
T_CompositorTexture,
T_GlyphAtlas,
T_GradientCacheTexture,
T_Count
};
enum VBDomain // Vertex Buffer Domain
{
VB_GeometryBuffer = 0,
VB_PathBuffer,
VB_GlyphBuffer,
VB_Count
};
enum IBDomain // Index Buffer Domain
{
IB_GeometryBuffer = 0,
IB_PathBuffer,
IB_GlyphBuffer,
IB_Count
};
enum CBDomain // Constant Buffer Domain (same as CBType)
{
// Vertex shader CBs
CB_DataVS,
// Pixel shader CBs
CB_DataPS,
CB_Count
};
}

Example GPU memory information extraction and display

Section titled “Example GPU memory information extraction and display”

Below are example functions that show how to display GPU memory information.

void PrintToLog(const cohtml::GPUMemoryInfo* memoryStats)
{
std::ostringstream oss;
oss << "---------- Total GPU Memory Stats ----------" << std::endl;
oss << "\tLast rendering execution ID: " << memoryStats->LastRenderingExecutionID << std::endl;
oss << "\tTotal GPU Memory: " << memoryStats->TotalBytes << " bytes" << std::endl;
oss << "\tPeak GPU Memory: " << memoryStats->PeakBytes << " bytes" << std::endl;
oss << "\t> Main textures memory info:" << std::endl;
oss << "\tTotal color textures memory: " << memoryStats->TexturesInformation[renoir::domains::TT_ColorTexture].Total.Bytes << " bytes" << std::endl;
oss << "\tTotal depth textures memory: " << memoryStats->DSTexturesInformation.Total.Bytes << " bytes" << std::endl;
oss << "\tPeak color textures memory: " << memoryStats->TexturesInformation[renoir::domains::TT_ColorTexture].Peak.Bytes << " bytes" << std::endl;
oss << "\tPeak depth textures memory: " << memoryStats->DSTexturesInformation.Peak.Bytes << " bytes" << std::endl;
oss << "\t> Main buffers memory info:" << std::endl;
oss << "\tTotal Index Buffers memory: " << memoryStats->BuffersInformation[renoir::domains::BT_IndexBuffer].Total.Bytes << " bytes" << std::endl;
oss << "\tTotal Vertex Buffers memory: " << memoryStats->BuffersInformation[renoir::domains::BT_VertexBuffer].Total.Bytes << " bytes" << std::endl;
oss << "\tTotal Constant Buffers memory: " << memoryStats->BuffersInformation[renoir::domains::BT_ConstantBuffer].Total.Bytes << " bytes" << std::endl;
oss << "\tPeak Index Buffers memory: " << memoryStats->BuffersInformation[renoir::domains::BT_IndexBuffer].Peak.Bytes << " bytes" << std::endl;
oss << "\tPeak Vertex Buffers memory: " << memoryStats->BuffersInformation[renoir::domains::BT_VertexBuffer].Peak.Bytes << " bytes" << std::endl;
oss << "\tPeak Constant Buffers memory: " << memoryStats->BuffersInformation[renoir::domains::BT_ConstantBuffer].Peak.Bytes << " bytes" << std::endl;
oss << "\t> Textures count info:" << std::endl;
oss << "\tTotal count of color textures: " << memoryStats->TexturesInformation[renoir::domains::TT_ColorTexture].Total.Count << std::endl;
oss << "\tTotal count of depth textures: " << memoryStats->DSTexturesInformation.Total.Count << std::endl;
oss << "\tPeak count of color textures: " << memoryStats->TexturesInformation[renoir::domains::TT_ColorTexture].Peak.Count << std::endl;
oss << "\tPeak count of depth textures: " << memoryStats->DSTexturesInformation.Peak.Count << std::endl;
oss << "\t> Buffers count info:" << std::endl;
oss << "\tTotal count of Index Buffers: " << memoryStats->BuffersInformation[renoir::domains::BT_IndexBuffer].Total.Count << std::endl;
oss << "\tTotal count of Vertex Buffers: " << memoryStats->BuffersInformation[renoir::domains::BT_VertexBuffer].Total.Count << std::endl;
oss << "\tTotal count of Constant Buffers: " << memoryStats->BuffersInformation[renoir::domains::BT_ConstantBuffer].Total.Count << std::endl;
oss << "\tPeak count of Index Buffers: " << memoryStats->BuffersInformation[renoir::domains::BT_IndexBuffer].Peak.Count << std::endl;
oss << "\tPeak count of Vertex Buffers: " << memoryStats->BuffersInformation[renoir::domains::BT_VertexBuffer].Peak.Count << std::endl;
oss << "\tPeak count of Constant Buffers: " << memoryStats->BuffersInformation[renoir::domains::BT_ConstantBuffer].Peak.Count << std::endl;
const char* textureStrings[] = { "Scratch Texture", "Layer Texture", "Image Texture", "Surface Texture", "Compositor Texture", "Glyph Atlase", "Gradient Cache Texture" };
const char* bufferStrings[] = { "Index Geometry Buffer", "Index Path Buffer", "Index Glyph Buffer",
"Vertex Geometry Buffer", "Vertex Path Buffer", "Vertex Path Instance Data Buffer", "Vertex Glyph Buffer",
"VS Data Constant Buffer", "PS Data Constant Buffer" };
APP_LOG_GENERAL(Info, oss.str().c_str());
oss.str("");
for (size_t texDomain = 0; texDomain < renoir::domains::TextureDomain::T_Count; ++texDomain)
{
oss << "\t> Color " << textureStrings[texDomain] << "s:" << std::endl;
auto& domainInfo = memoryStats->TexturesInformation[renoir::domains::TT_ColorTexture].ResourceArray[texDomain];
oss << "\tTotal memory: " << domainInfo.Total.Bytes << " bytes" << std::endl;
oss << "\tTotal count: " << domainInfo.Total.Count << std::endl;
oss << "\tPeak memory: " << domainInfo.Peak.Bytes << " bytes" << std::endl;
oss << "\tPeak count: " << domainInfo.Peak.Count << std::endl;
for (size_t i = 0; i < domainInfo.ArraySize; i++)
{
oss << "\tID: " << domainInfo.Array[i].Id << "; Owner: ";
if (domainInfo.Array[i].OwnerId == RENOIR_INVALID)
{
oss << "Shared";
}
else
{
oss << domainInfo.Array[i].OwnerId;
}
oss << "; Size: " << domainInfo.Array[i].Bytes << " bytes";
oss << "; Times used: " << domainInfo.Array[i].TimesUsed;
oss << "; Last used in execution ID #" << domainInfo.Array[i].LastUsedID;
if (texDomain == renoir::domains::TextureDomain::T_ImageTexture &&
memoryStats->ExtraColorImageTexturesInformation.Array[i].Name)
{
oss << "; View client IDs:";
for (size_t viewCount = 0; viewCount < memoryStats->ExtraColorImageTexturesInformation.Array[i].ViewClientsCount; ++viewCount)
{
oss << " " << memoryStats->ExtraColorImageTexturesInformation.Array[i].ViewClients[viewCount];
}
oss << std::endl << "\t\tTexture Name: " << memoryStats->ExtraColorImageTexturesInformation.Array[i].Name << std::endl;
}
else
{
oss << std::endl;
}
}
APP_LOG_GENERAL(Info, oss.str().c_str());
oss.str("");
}
oss << "\t> Depth Stencil Textures: " << std::endl;
oss << "\tTotal memory: " << memoryStats->DSTexturesInformation.Total.Bytes << " bytes" << std::endl;
oss << "\tTotal count: " << memoryStats->DSTexturesInformation.Total.Count << std::endl;
oss << "\tPeak memory: " << memoryStats->DSTexturesInformation.Peak.Bytes << " bytes" << std::endl;
oss << "\tPeak count: " << memoryStats->DSTexturesInformation.Peak.Count << std::endl;
for (size_t i = 0; i < memoryStats->DSTexturesInformation.ArraySize; i++)
{
oss << "\tID: " << memoryStats->DSTexturesInformation.Array[i].Id << "; Owner: ";
if (memoryStats->DSTexturesInformation.Array[i].OwnerId == RENOIR_INVALID)
{
oss << "Shared";
}
else
{
oss << memoryStats->DSTexturesInformation.Array[i].OwnerId;
}
oss << "; Size: " << memoryStats->DSTexturesInformation.Array[i].Bytes << " bytes";
oss << "; Times used: " << memoryStats->DSTexturesInformation.Array[i].TimesUsed;
oss << "; Last used in execution ID #" << memoryStats->DSTexturesInformation.Array[i].LastUsedID << std::endl;
}
APP_LOG_GENERAL(Info, oss.str().c_str());
oss.str("");
for (size_t buffType = 0; buffType < renoir::domains::BufferType::BT_Count; ++buffType)
{
size_t buffDomainSize = buffType == renoir::domains::BufferType::BT_IndexBuffer ? renoir::domains::IB_Count :
buffType == renoir::domains::BufferType::BT_VertexBuffer ? renoir::domains::VB_Count : renoir::CB_Count;
size_t buffStringsStart = buffType == renoir::domains::BufferType::BT_IndexBuffer ? 0 :
buffType == renoir::domains::BufferType::BT_VertexBuffer ? renoir::domains::IB_Count : renoir::domains::IB_Count + renoir::domains::VB_Count;
for (size_t buffDomain = 0; buffDomain < buffDomainSize; buffDomain++)
{
oss << "\t> " << bufferStrings[buffStringsStart + buffDomain] << "s:" << std::endl;
auto& domainInfo = memoryStats->BuffersInformation[buffType].ResourceArray[buffDomain];
oss << "\tTotal memory: " << domainInfo.Total.Bytes << " bytes" << std::endl;
oss << "\tTotal count: " << domainInfo.Total.Count << std::endl;
oss << "\tPeak memory: " << domainInfo.Peak.Bytes << " bytes" << std::endl;
oss << "\tPeak count: " << domainInfo.Peak.Count << std::endl;
for (size_t i = 0; i < domainInfo.ArraySize; i++)
{
oss << "\tID: " << domainInfo.Array[i].Id << "; Owner: ";
if (domainInfo.Array[i].OwnerId == RENOIR_INVALID)
{
oss << "Shared";
}
else
{
oss << domainInfo.Array[i].OwnerId;
}
oss << "; Size: " << domainInfo.Array[i].Bytes << " bytes";
oss << "; Peak usage: " << domainInfo.Array[i].PeakUsageBytes << " bytes" << std::endl;
}
APP_LOG_GENERAL(Info, oss.str().c_str());
oss.str("");
}
}
}
void PrintToLog(const cohtml::UserGPUMemoryInfo* memoryStats)
{
TmpOSStream oss;
oss << "\t---------- User GPU Memory Stats ----------" << std::endl;
oss << "\tLast rendering execution ID: " << memoryStats->LastRenderingExecutionID << std::endl;
oss << "\tTotal GPU Memory: " << memoryStats->Total.Bytes << " bytes" << std::endl;
oss << "\tPeak GPU Memory: " << memoryStats->Peak.Bytes << " bytes" << std::endl;
oss << "\tTotal texture count: " << memoryStats->Total.Count << std::endl;
oss << "\tPeak texture count: " << memoryStats->Peak.Count << std::endl;
if (memoryStats->ArraySize > 0)
{
oss << "\t---------- Textures ----------" << std::endl;
}
for (size_t i = 0; i < memoryStats->ArraySize; i++)
{
const auto& texture = memoryStats->Array[i];
oss << "\tID: " << texture.Id << ";\tSize: " << texture.Bytes << " bytes";
oss << ";\tTimes used: " << texture.TimesUsed;
+ oss << ";\tLast used in execution ID #" << texture.LastUsedID<< std::endl;
oss << "\tName: " << texture.Name << std::endl;
oss << "\tView Clients Count: " << texture.ViewClientsCount << std::endl;
for (size_t viewCount = 0; viewCount < texture.ViewClientsCount; ++viewCount)
{
oss << "\tView Client Id: " << texture.ViewClients[viewCount] << std::endl;
}
}
APP_LOG_GENERAL(Info, oss.str().c_str());
}

We have already implemented them and they can be used like this

void PrintGPUMemoryStats()
{
auto combinedMemoryStats = m_CohtmlApp->GetLibrary()->GetGPUMemoryStats();
if (combinedMemoryStats)
{
combinedMemoryStats->PrintToLog();
combinedMemoryStats->Release();
}
}
void PrintUserGPUMemoryStats()
{
auto userMemoryStats = m_CohtmlApp->GetLibrary()->GetUserGPUMemoryStats();
if (userMemoryStats)
{
userMemoryStats->PrintToLog();
userMemoryStats->Release();
}
}