314 lines
11 KiB
C++
314 lines
11 KiB
C++
#pragma once
|
|
|
|
#include <XCEngine/Rendering/Builtin/BuiltinPassTypes.h>
|
|
|
|
#include <string>
|
|
|
|
namespace XCEngine {
|
|
namespace Rendering {
|
|
|
|
inline Containers::String NormalizeBuiltinPassMetadataValue(const Containers::String& value) {
|
|
return value.Trim().ToLower();
|
|
}
|
|
|
|
inline const char* GetBuiltinPassCanonicalName(BuiltinMaterialPass pass) {
|
|
switch (pass) {
|
|
case BuiltinMaterialPass::ForwardLit:
|
|
return "forwardlit";
|
|
case BuiltinMaterialPass::Unlit:
|
|
return "unlit";
|
|
case BuiltinMaterialPass::DepthOnly:
|
|
return "depthonly";
|
|
case BuiltinMaterialPass::ShadowCaster:
|
|
return "shadowcaster";
|
|
case BuiltinMaterialPass::ObjectId:
|
|
return "objectid";
|
|
case BuiltinMaterialPass::Skybox:
|
|
return "skybox";
|
|
case BuiltinMaterialPass::Volumetric:
|
|
return "volumetric";
|
|
case BuiltinMaterialPass::PostProcess:
|
|
return "colorscale";
|
|
case BuiltinMaterialPass::FinalColor:
|
|
return "finalcolor";
|
|
default:
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
inline bool MatchesBuiltinPassName(
|
|
const Containers::String& value,
|
|
BuiltinMaterialPass pass) {
|
|
const char* canonicalName = GetBuiltinPassCanonicalName(pass);
|
|
return canonicalName != nullptr &&
|
|
NormalizeBuiltinPassMetadataValue(value) == Containers::String(canonicalName);
|
|
}
|
|
|
|
inline bool ShaderPassHasExplicitBuiltinMetadata(const Resources::ShaderPass& shaderPass) {
|
|
if (!shaderPass.name.Empty() &&
|
|
shaderPass.name != Containers::String("Default")) {
|
|
return true;
|
|
}
|
|
|
|
for (const Resources::ShaderPassTagEntry& tag : shaderPass.tags) {
|
|
if (NormalizeBuiltinPassMetadataValue(tag.name) == Containers::String("lightmode")) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
inline bool ShaderHasExplicitBuiltinMetadata(const Resources::Shader& shader) {
|
|
for (const Resources::ShaderPass& shaderPass : shader.GetPasses()) {
|
|
if (ShaderPassHasExplicitBuiltinMetadata(shaderPass)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
inline bool ShaderPassMatchesBuiltinPass(
|
|
const Resources::ShaderPass& shaderPass,
|
|
BuiltinMaterialPass pass) {
|
|
bool hasMetadata = false;
|
|
|
|
if (!shaderPass.name.Empty() &&
|
|
shaderPass.name != Containers::String("Default")) {
|
|
hasMetadata = true;
|
|
if (!MatchesBuiltinPassName(shaderPass.name, pass)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
for (const Resources::ShaderPassTagEntry& tag : shaderPass.tags) {
|
|
if (NormalizeBuiltinPassMetadataValue(tag.name) != Containers::String("lightmode")) {
|
|
continue;
|
|
}
|
|
|
|
hasMetadata = true;
|
|
if (!MatchesBuiltinPassName(tag.value, pass)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return hasMetadata;
|
|
}
|
|
|
|
inline BuiltinPassResourceSemantic ResolveBuiltinPassResourceSemantic(
|
|
const Resources::ShaderResourceBindingDesc& binding) {
|
|
Containers::String semantic = NormalizeBuiltinPassMetadataValue(binding.semantic);
|
|
if (semantic.Empty()) {
|
|
semantic = NormalizeBuiltinPassMetadataValue(binding.name);
|
|
}
|
|
|
|
if (semantic == Containers::String("perobject") ||
|
|
semantic == Containers::String("perobjectconstants")) {
|
|
return BuiltinPassResourceSemantic::PerObject;
|
|
}
|
|
|
|
if (semantic == Containers::String("material") ||
|
|
semantic == Containers::String("materialconstants")) {
|
|
return BuiltinPassResourceSemantic::Material;
|
|
}
|
|
|
|
if (semantic == Containers::String("materialbuffer")) {
|
|
return BuiltinPassResourceSemantic::MaterialBuffer;
|
|
}
|
|
|
|
if (semantic == Containers::String("lighting") ||
|
|
semantic == Containers::String("lightingconstants")) {
|
|
return BuiltinPassResourceSemantic::Lighting;
|
|
}
|
|
|
|
if (semantic == Containers::String("shadowreceiver") ||
|
|
semantic == Containers::String("shadowreceiverconstants")) {
|
|
return BuiltinPassResourceSemantic::ShadowReceiver;
|
|
}
|
|
|
|
if (semantic == Containers::String("environment") ||
|
|
semantic == Containers::String("environmentconstants")) {
|
|
return BuiltinPassResourceSemantic::Environment;
|
|
}
|
|
|
|
if (semantic == Containers::String("passconstants") ||
|
|
semantic == Containers::String("finalcolorconstants") ||
|
|
semantic == Containers::String("postprocessconstants")) {
|
|
return BuiltinPassResourceSemantic::PassConstants;
|
|
}
|
|
|
|
if (semantic == Containers::String("volumefield") ||
|
|
semantic == Containers::String("volumedata")) {
|
|
return BuiltinPassResourceSemantic::VolumeField;
|
|
}
|
|
|
|
if (semantic == Containers::String("basecolortexture") ||
|
|
semantic == Containers::String("maintex")) {
|
|
return BuiltinPassResourceSemantic::BaseColorTexture;
|
|
}
|
|
|
|
if (semantic == Containers::String("sourcecolortexture")) {
|
|
return BuiltinPassResourceSemantic::SourceColorTexture;
|
|
}
|
|
|
|
if (semantic == Containers::String("skyboxpanoramictexture")) {
|
|
return BuiltinPassResourceSemantic::SkyboxPanoramicTexture;
|
|
}
|
|
|
|
if (semantic == Containers::String("skyboxtexture")) {
|
|
return BuiltinPassResourceSemantic::SkyboxTexture;
|
|
}
|
|
|
|
if (semantic == Containers::String("shadowmaptexture") ||
|
|
semantic == Containers::String("shadowmap")) {
|
|
return BuiltinPassResourceSemantic::ShadowMapTexture;
|
|
}
|
|
|
|
if (semantic == Containers::String("linearclampsampler")) {
|
|
return BuiltinPassResourceSemantic::LinearClampSampler;
|
|
}
|
|
|
|
if (semantic == Containers::String("shadowmapsampler") ||
|
|
semantic == Containers::String("shadowsampler")) {
|
|
return BuiltinPassResourceSemantic::ShadowMapSampler;
|
|
}
|
|
|
|
switch (binding.type) {
|
|
case Resources::ShaderResourceType::StructuredBuffer:
|
|
case Resources::ShaderResourceType::RawBuffer:
|
|
case Resources::ShaderResourceType::RWStructuredBuffer:
|
|
case Resources::ShaderResourceType::RWRawBuffer:
|
|
return BuiltinPassResourceSemantic::MaterialBuffer;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return BuiltinPassResourceSemantic::Unknown;
|
|
}
|
|
|
|
inline const char* BuiltinPassResourceSemanticToString(BuiltinPassResourceSemantic semantic) {
|
|
switch (semantic) {
|
|
case BuiltinPassResourceSemantic::PerObject:
|
|
return "PerObject";
|
|
case BuiltinPassResourceSemantic::Material:
|
|
return "Material";
|
|
case BuiltinPassResourceSemantic::MaterialBuffer:
|
|
return "MaterialBuffer";
|
|
case BuiltinPassResourceSemantic::Lighting:
|
|
return "Lighting";
|
|
case BuiltinPassResourceSemantic::ShadowReceiver:
|
|
return "ShadowReceiver";
|
|
case BuiltinPassResourceSemantic::Environment:
|
|
return "Environment";
|
|
case BuiltinPassResourceSemantic::PassConstants:
|
|
return "PassConstants";
|
|
case BuiltinPassResourceSemantic::VolumeField:
|
|
return "VolumeField";
|
|
case BuiltinPassResourceSemantic::BaseColorTexture:
|
|
return "BaseColorTexture";
|
|
case BuiltinPassResourceSemantic::SourceColorTexture:
|
|
return "SourceColorTexture";
|
|
case BuiltinPassResourceSemantic::SkyboxPanoramicTexture:
|
|
return "SkyboxPanoramicTexture";
|
|
case BuiltinPassResourceSemantic::SkyboxTexture:
|
|
return "SkyboxTexture";
|
|
case BuiltinPassResourceSemantic::ShadowMapTexture:
|
|
return "ShadowMapTexture";
|
|
case BuiltinPassResourceSemantic::LinearClampSampler:
|
|
return "LinearClampSampler";
|
|
case BuiltinPassResourceSemantic::ShadowMapSampler:
|
|
return "ShadowMapSampler";
|
|
case BuiltinPassResourceSemantic::Unknown:
|
|
default:
|
|
return "Unknown";
|
|
}
|
|
}
|
|
|
|
inline const char* ShaderResourceTypeToString(Resources::ShaderResourceType type) {
|
|
switch (type) {
|
|
case Resources::ShaderResourceType::ConstantBuffer:
|
|
return "ConstantBuffer";
|
|
case Resources::ShaderResourceType::Texture2D:
|
|
return "Texture2D";
|
|
case Resources::ShaderResourceType::TextureCube:
|
|
return "TextureCube";
|
|
case Resources::ShaderResourceType::Sampler:
|
|
return "Sampler";
|
|
case Resources::ShaderResourceType::StructuredBuffer:
|
|
return "StructuredBuffer";
|
|
case Resources::ShaderResourceType::RawBuffer:
|
|
return "RawBuffer";
|
|
case Resources::ShaderResourceType::RWStructuredBuffer:
|
|
return "RWStructuredBuffer";
|
|
case Resources::ShaderResourceType::RWRawBuffer:
|
|
return "RWRawBuffer";
|
|
default:
|
|
return "Unknown";
|
|
}
|
|
}
|
|
|
|
inline Containers::String DescribeShaderResourceBinding(
|
|
const Resources::ShaderResourceBindingDesc& binding) {
|
|
const BuiltinPassResourceSemantic resolvedSemantic = ResolveBuiltinPassResourceSemantic(binding);
|
|
return Containers::String("name=") + binding.name +
|
|
", semantic=" + binding.semantic +
|
|
", resolvedSemantic=" + Containers::String(BuiltinPassResourceSemanticToString(resolvedSemantic)) +
|
|
", type=" + Containers::String(ShaderResourceTypeToString(binding.type)) +
|
|
", set=" + Containers::String(std::to_string(binding.set).c_str()) +
|
|
", binding=" + Containers::String(std::to_string(binding.binding).c_str());
|
|
}
|
|
|
|
inline Containers::String DescribeShaderResourceBindings(
|
|
const Containers::Array<Resources::ShaderResourceBindingDesc>& bindings) {
|
|
Containers::String description;
|
|
for (size_t bindingIndex = 0; bindingIndex < bindings.Size(); ++bindingIndex) {
|
|
if (!description.Empty()) {
|
|
description += " | ";
|
|
}
|
|
|
|
description += "[" + Containers::String(std::to_string(bindingIndex).c_str()) + "] ";
|
|
description += DescribeShaderResourceBinding(bindings[bindingIndex]);
|
|
}
|
|
|
|
return description;
|
|
}
|
|
|
|
inline bool IsBuiltinPassResourceTypeCompatible(
|
|
BuiltinPassResourceSemantic semantic,
|
|
Resources::ShaderResourceType type) {
|
|
switch (semantic) {
|
|
case BuiltinPassResourceSemantic::PerObject:
|
|
case BuiltinPassResourceSemantic::Material:
|
|
case BuiltinPassResourceSemantic::Lighting:
|
|
case BuiltinPassResourceSemantic::ShadowReceiver:
|
|
case BuiltinPassResourceSemantic::Environment:
|
|
case BuiltinPassResourceSemantic::PassConstants:
|
|
return type == Resources::ShaderResourceType::ConstantBuffer;
|
|
case BuiltinPassResourceSemantic::MaterialBuffer:
|
|
return type == Resources::ShaderResourceType::StructuredBuffer ||
|
|
type == Resources::ShaderResourceType::RawBuffer ||
|
|
type == Resources::ShaderResourceType::RWStructuredBuffer ||
|
|
type == Resources::ShaderResourceType::RWRawBuffer;
|
|
case BuiltinPassResourceSemantic::VolumeField:
|
|
return type == Resources::ShaderResourceType::StructuredBuffer ||
|
|
type == Resources::ShaderResourceType::RawBuffer;
|
|
case BuiltinPassResourceSemantic::BaseColorTexture:
|
|
case BuiltinPassResourceSemantic::SourceColorTexture:
|
|
case BuiltinPassResourceSemantic::SkyboxPanoramicTexture:
|
|
case BuiltinPassResourceSemantic::ShadowMapTexture:
|
|
return type == Resources::ShaderResourceType::Texture2D;
|
|
case BuiltinPassResourceSemantic::SkyboxTexture:
|
|
return type == Resources::ShaderResourceType::TextureCube;
|
|
case BuiltinPassResourceSemantic::LinearClampSampler:
|
|
case BuiltinPassResourceSemantic::ShadowMapSampler:
|
|
return type == Resources::ShaderResourceType::Sampler;
|
|
case BuiltinPassResourceSemantic::Unknown:
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
} // namespace Rendering
|
|
} // namespace XCEngine
|