/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include #include #include #include #include #include #include #include namespace AZ { namespace RPI { AZStd::string GetMetricsFilePath() { char shaderMetricPath[AZ_MAX_PATH_LEN]; AZ::Utils::GetExecutableDirectory(shaderMetricPath, AZ_MAX_PATH_LEN); return AZStd::string(shaderMetricPath) + AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING + "ShaderMetrics.json"; } ShaderMetricsSystemInterface* ShaderMetricsSystemInterface::Get() { return Interface::Get(); } void ShaderMetricsSystem::Reflect(ReflectContext* context) { ShaderVariantRequest::Reflect(context); ShaderVariantMetrics::Reflect(context); } void ShaderMetricsSystem::Init() { // Register the system to the interface. Interface::Register(this); ReadLog(); } void ShaderMetricsSystem::Shutdown() { WriteLog(); // Unregister the system to the interface. Interface::Unregister(this); } void ShaderMetricsSystem::Reset() { m_metrics.m_requests.clear(); } void ShaderMetricsSystem::ReadLog() { const AZStd::string metricsFilePath = GetMetricsFilePath(); if (AZ::IO::LocalFileIO::GetInstance()->Exists(metricsFilePath.c_str())) { auto loadResult = AZ::JsonSerializationUtils::LoadObjectFromFile(m_metrics, metricsFilePath.c_str()); if (!loadResult.IsSuccess()) { AZ_Error("ShaderMetrics", false, "Unable to read %s file", metricsFilePath.c_str()); return; } } } void ShaderMetricsSystem::WriteLog() { const AZStd::string metricsFilePath = GetMetricsFilePath(); auto saveResult = AZ::JsonSerializationUtils::SaveObjectToFile(&m_metrics, metricsFilePath.c_str()); if (!saveResult.IsSuccess()) { AZ_Error("ShaderMetrics", false, "Unable to write %s file", metricsFilePath.c_str()); return; } } bool ShaderMetricsSystem::IsEnabled() const { return m_isEnabled; } void ShaderMetricsSystem::SetEnabled(bool value) { m_isEnabled = value; } const ShaderVariantMetrics& ShaderMetricsSystem::GetMetrics() const { return m_metrics; } void ShaderMetricsSystem::RequestShaderVariant(const ShaderAsset* shader, const ShaderVariantId& shaderVariantId, const ShaderVariantSearchResult& result) { if (!m_isEnabled) { return; } AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender); AZStd::lock_guard lock(m_metricsMutex); // Log a new request ShaderVariantRequest newRequest; newRequest.m_shaderId = shader->GetId(); newRequest.m_shaderName = shader->GetName(); newRequest.m_shaderVariantId = shaderVariantId; newRequest.m_shaderVariantStableId = result.GetStableId(); newRequest.m_dynamicOptionCount = result.GetDynamicOptionCount(); newRequest.m_requestCount = 1; // Check if the specific shader variant was already requested to increase its request count for (auto request = m_metrics.m_requests.begin(); request != m_metrics.m_requests.end(); ++request) { if (request->m_shaderId == newRequest.m_shaderId && request->m_shaderVariantId == newRequest.m_shaderVariantId) { request->m_requestCount++; return; } } // Otherwise, add a new request m_metrics.m_requests.push_back(newRequest); } }; // namespace RPI }; // namespace AZ