From 2d789b9139c133847584aec83f7349e4ff13e254 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 1 Jun 2024 22:57:48 -0500 Subject: [PATCH] VideoCommon: add material asset utility function to set material properties from a shader --- .../VideoCommon/Assets/MaterialAssetUtils.cpp | 200 ++++++++++++++++++ .../VideoCommon/Assets/MaterialAssetUtils.h | 19 ++ 2 files changed, 219 insertions(+) create mode 100644 Source/Core/VideoCommon/Assets/MaterialAssetUtils.cpp create mode 100644 Source/Core/VideoCommon/Assets/MaterialAssetUtils.h diff --git a/Source/Core/VideoCommon/Assets/MaterialAssetUtils.cpp b/Source/Core/VideoCommon/Assets/MaterialAssetUtils.cpp new file mode 100644 index 0000000000..741000d9cb --- /dev/null +++ b/Source/Core/VideoCommon/Assets/MaterialAssetUtils.cpp @@ -0,0 +1,200 @@ +// Copyright 2024 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "VideoCommon/Assets/MaterialAssetUtils.h" + +#include "Common/VariantUtil.h" + +#include "VideoCommon/Assets/MaterialAsset.h" +#include "VideoCommon/Assets/ShaderAsset.h" + +namespace VideoCommon +{ +void SetMaterialPropertiesFromShader(const VideoCommon::PixelShaderData& shader, + VideoCommon::MaterialData* material) +{ + material->properties.clear(); + for (const auto& entry : shader.m_properties) + { + // C++20: error with capturing structured bindings for our version of clang + const auto& name = entry.first; + const auto& shader_property = entry.second; + std::visit(overloaded{[&](const VideoCommon::ShaderProperty::Sampler2D& default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value.value; + material->properties.push_back(std::move(property)); + }, + [&](const VideoCommon::ShaderProperty::Sampler2DArray& default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value.value; + material->properties.push_back(std::move(property)); + }, + [&](const VideoCommon::ShaderProperty::SamplerCube& default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value.value; + material->properties.push_back(std::move(property)); + }, + [&](s32 default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value; + material->properties.push_back(std::move(property)); + }, + [&](const std::array& default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value; + material->properties.push_back(std::move(property)); + }, + [&](const std::array& default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value; + material->properties.push_back(std::move(property)); + }, + [&](const std::array& default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value; + material->properties.push_back(std::move(property)); + }, + [&](float default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value; + material->properties.push_back(std::move(property)); + }, + [&](const std::array& default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value; + material->properties.push_back(std::move(property)); + }, + [&](const std::array& default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value; + material->properties.push_back(std::move(property)); + }, + [&](const std::array& default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value; + material->properties.push_back(std::move(property)); + }, + [&](const VideoCommon::ShaderProperty::RGB& default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value.value; + material->properties.push_back(std::move(property)); + }, + [&](const VideoCommon::ShaderProperty::RGBA& default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value.value; + material->properties.push_back(std::move(property)); + }, + [&](bool default_value) { + VideoCommon::MaterialProperty property; + property.m_code_name = name; + property.m_value = default_value; + material->properties.push_back(std::move(property)); + }}, + shader_property.m_default); + } +} + +void SetMaterialPropertiesFromShader(const RasterShaderData& shader, RasterMaterialData* material) +{ + material->vertex_properties.clear(); + material->pixel_properties.clear(); + + const auto set_properties = [&](const std::map& shader_properties, + std::vector* material_properties) { + for (const auto& entry : shader_properties) + { + // C++20: error with capturing structured bindings for our version of clang + // const auto& name = entry.first; + const auto& shader_property = entry.second; + std::visit(overloaded{[&](s32 default_value) { + VideoCommon::MaterialProperty2 property; + property.m_value = default_value; + material_properties->push_back(std::move(property)); + }, + [&](const std::array& default_value) { + VideoCommon::MaterialProperty2 property; + property.m_value = default_value; + material_properties->push_back(std::move(property)); + }, + [&](const std::array& default_value) { + VideoCommon::MaterialProperty2 property; + property.m_value = default_value; + material_properties->push_back(std::move(property)); + }, + [&](const std::array& default_value) { + VideoCommon::MaterialProperty2 property; + property.m_value = default_value; + material_properties->push_back(std::move(property)); + }, + [&](float default_value) { + VideoCommon::MaterialProperty2 property; + property.m_value = default_value; + material_properties->push_back(std::move(property)); + }, + [&](const std::array& default_value) { + VideoCommon::MaterialProperty2 property; + property.m_value = default_value; + material_properties->push_back(std::move(property)); + }, + [&](const std::array& default_value) { + VideoCommon::MaterialProperty2 property; + property.m_value = default_value; + material_properties->push_back(std::move(property)); + }, + [&](const std::array& default_value) { + VideoCommon::MaterialProperty2 property; + property.m_value = default_value; + material_properties->push_back(std::move(property)); + }, + [&](const VideoCommon::ShaderProperty2::RGB& default_value) { + VideoCommon::MaterialProperty2 property; + property.m_value = default_value.value; + material_properties->push_back(std::move(property)); + }, + [&](const VideoCommon::ShaderProperty2::RGBA& default_value) { + VideoCommon::MaterialProperty2 property; + property.m_value = default_value.value; + material_properties->push_back(std::move(property)); + }, + [&](bool default_value) { + VideoCommon::MaterialProperty2 property; + property.m_value = default_value; + material_properties->push_back(std::move(property)); + }}, + shader_property.m_default); + } + }; + + set_properties(shader.m_vertex_properties, &material->vertex_properties); + set_properties(shader.m_pixel_properties, &material->pixel_properties); +} + +void SetMaterialTexturesFromShader(const RasterShaderData& shader, RasterMaterialData* material) +{ + material->pixel_textures.clear(); + + const auto set_textures = [&](const std::vector& shader_samplers, + std::vector* material_textures) { + for (std::size_t i = 0; i < shader_samplers.size(); i++) + { + TextureSamplerValue sampler_value; + material_textures->push_back(std::move(sampler_value)); + } + }; + + set_textures(shader.m_pixel_samplers, &material->pixel_textures); +} +} // namespace VideoCommon diff --git a/Source/Core/VideoCommon/Assets/MaterialAssetUtils.h b/Source/Core/VideoCommon/Assets/MaterialAssetUtils.h new file mode 100644 index 0000000000..efff764525 --- /dev/null +++ b/Source/Core/VideoCommon/Assets/MaterialAssetUtils.h @@ -0,0 +1,19 @@ +// Copyright 2024 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +struct MaterialData; +struct PixelShaderData; +struct RasterMaterialData; +struct RasterShaderData; + +namespace VideoCommon +{ +void SetMaterialPropertiesFromShader(const PixelShaderData& shader, MaterialData* material); +void SetMaterialPropertiesFromShader(const RasterShaderData& shader, RasterMaterialData* material); +void SetMaterialTexturesFromShader(const RasterShaderData& shader, RasterMaterialData* material); +} // namespace VideoCommon