rendering: remove builtin authoring register annotations
This commit is contained in:
@@ -5,13 +5,13 @@ Shader "Builtin Color Scale Post Process"
|
|||||||
_ColorScale ("Color Scale", Color) = (0.65,0.80,1.00,1.0)
|
_ColorScale ("Color Scale", Color) = (0.65,0.80,1.00,1.0)
|
||||||
}
|
}
|
||||||
HLSLINCLUDE
|
HLSLINCLUDE
|
||||||
cbuffer PostProcessConstants : register(b0)
|
cbuffer PostProcessConstants
|
||||||
{
|
{
|
||||||
float4 gColorScale;
|
float4 gColorScale;
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture2D gSourceColorTexture : register(t0);
|
Texture2D gSourceColorTexture;
|
||||||
SamplerState gLinearClampSampler : register(s0);
|
SamplerState gLinearClampSampler;
|
||||||
|
|
||||||
struct VSOutput
|
struct VSOutput
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,21 +7,21 @@ Shader "Builtin Depth Only"
|
|||||||
_MainTex ("Base Map", 2D) = "white" [Semantic(BaseColorTexture)]
|
_MainTex ("Base Map", 2D) = "white" [Semantic(BaseColorTexture)]
|
||||||
}
|
}
|
||||||
HLSLINCLUDE
|
HLSLINCLUDE
|
||||||
cbuffer PerObjectConstants : register(b0)
|
cbuffer PerObjectConstants
|
||||||
{
|
{
|
||||||
float4x4 gProjectionMatrix;
|
float4x4 gProjectionMatrix;
|
||||||
float4x4 gViewMatrix;
|
float4x4 gViewMatrix;
|
||||||
float4x4 gModelMatrix;
|
float4x4 gModelMatrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
cbuffer MaterialConstants : register(b1)
|
cbuffer MaterialConstants
|
||||||
{
|
{
|
||||||
float4 gBaseColorFactor;
|
float4 gBaseColorFactor;
|
||||||
float4 gAlphaCutoffParams;
|
float4 gAlphaCutoffParams;
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture2D BaseColorTexture : register(t0);
|
Texture2D BaseColorTexture;
|
||||||
SamplerState LinearClampSampler : register(s0);
|
SamplerState LinearClampSampler;
|
||||||
|
|
||||||
struct VSInput
|
struct VSInput
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ Shader "Builtin Final Color"
|
|||||||
_ToneMappingMode ("Tone Mapping Mode", Float) = 0.0
|
_ToneMappingMode ("Tone Mapping Mode", Float) = 0.0
|
||||||
}
|
}
|
||||||
HLSLINCLUDE
|
HLSLINCLUDE
|
||||||
cbuffer FinalColorConstants : register(b0)
|
cbuffer FinalColorConstants
|
||||||
{
|
{
|
||||||
float4 gColorScale;
|
float4 gColorScale;
|
||||||
float4 gFinalColorParams;
|
float4 gFinalColorParams;
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture2D gSourceColorTexture : register(t0);
|
Texture2D gSourceColorTexture;
|
||||||
SamplerState gLinearClampSampler : register(s0);
|
SamplerState gLinearClampSampler;
|
||||||
|
|
||||||
struct VSOutput
|
struct VSOutput
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Shader "Builtin Forward Lit"
|
|||||||
_MainTex ("Base Map", 2D) = "white" [Semantic(BaseColorTexture)]
|
_MainTex ("Base Map", 2D) = "white" [Semantic(BaseColorTexture)]
|
||||||
}
|
}
|
||||||
HLSLINCLUDE
|
HLSLINCLUDE
|
||||||
cbuffer PerObjectConstants : register(b0)
|
cbuffer PerObjectConstants
|
||||||
{
|
{
|
||||||
float4x4 gProjectionMatrix;
|
float4x4 gProjectionMatrix;
|
||||||
float4x4 gViewMatrix;
|
float4x4 gViewMatrix;
|
||||||
@@ -25,7 +25,7 @@ Shader "Builtin Forward Lit"
|
|||||||
float4 spotAnglesAndFlags;
|
float4 spotAnglesAndFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
cbuffer LightingConstants : register(b1)
|
cbuffer LightingConstants
|
||||||
{
|
{
|
||||||
float4 gMainLightDirectionAndIntensity;
|
float4 gMainLightDirectionAndIntensity;
|
||||||
float4 gMainLightColorAndFlags;
|
float4 gMainLightColorAndFlags;
|
||||||
@@ -33,23 +33,23 @@ Shader "Builtin Forward Lit"
|
|||||||
AdditionalLightData gAdditionalLights[XC_MAX_ADDITIONAL_LIGHTS];
|
AdditionalLightData gAdditionalLights[XC_MAX_ADDITIONAL_LIGHTS];
|
||||||
};
|
};
|
||||||
|
|
||||||
cbuffer MaterialConstants : register(b2)
|
cbuffer MaterialConstants
|
||||||
{
|
{
|
||||||
float4 gBaseColorFactor;
|
float4 gBaseColorFactor;
|
||||||
float4 gAlphaCutoffParams;
|
float4 gAlphaCutoffParams;
|
||||||
};
|
};
|
||||||
|
|
||||||
cbuffer ShadowReceiverConstants : register(b3)
|
cbuffer ShadowReceiverConstants
|
||||||
{
|
{
|
||||||
float4x4 gWorldToShadowMatrix;
|
float4x4 gWorldToShadowMatrix;
|
||||||
float4 gShadowBiasAndTexelSize;
|
float4 gShadowBiasAndTexelSize;
|
||||||
float4 gShadowOptions;
|
float4 gShadowOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture2D BaseColorTexture : register(t0);
|
Texture2D BaseColorTexture;
|
||||||
SamplerState LinearClampSampler : register(s0);
|
SamplerState LinearClampSampler;
|
||||||
Texture2D ShadowMapTexture : register(t1);
|
Texture2D ShadowMapTexture;
|
||||||
SamplerState ShadowMapSampler : register(s1);
|
SamplerState ShadowMapSampler;
|
||||||
|
|
||||||
struct VSInput
|
struct VSInput
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Shader "Builtin Object Id"
|
|||||||
#pragma target 4.5
|
#pragma target 4.5
|
||||||
#pragma vertex MainVS
|
#pragma vertex MainVS
|
||||||
#pragma fragment MainPS
|
#pragma fragment MainPS
|
||||||
cbuffer PerObjectConstants : register(b0)
|
cbuffer PerObjectConstants
|
||||||
{
|
{
|
||||||
float4x4 gProjectionMatrix;
|
float4x4 gProjectionMatrix;
|
||||||
float4x4 gViewMatrix;
|
float4x4 gViewMatrix;
|
||||||
|
|||||||
@@ -7,21 +7,21 @@ Shader "Builtin Shadow Caster"
|
|||||||
_MainTex ("Base Map", 2D) = "white" [Semantic(BaseColorTexture)]
|
_MainTex ("Base Map", 2D) = "white" [Semantic(BaseColorTexture)]
|
||||||
}
|
}
|
||||||
HLSLINCLUDE
|
HLSLINCLUDE
|
||||||
cbuffer PerObjectConstants : register(b0)
|
cbuffer PerObjectConstants
|
||||||
{
|
{
|
||||||
float4x4 gProjectionMatrix;
|
float4x4 gProjectionMatrix;
|
||||||
float4x4 gViewMatrix;
|
float4x4 gViewMatrix;
|
||||||
float4x4 gModelMatrix;
|
float4x4 gModelMatrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
cbuffer MaterialConstants : register(b1)
|
cbuffer MaterialConstants
|
||||||
{
|
{
|
||||||
float4 gBaseColorFactor;
|
float4 gBaseColorFactor;
|
||||||
float4 gAlphaCutoffParams;
|
float4 gAlphaCutoffParams;
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture2D BaseColorTexture : register(t0);
|
Texture2D BaseColorTexture;
|
||||||
SamplerState LinearClampSampler : register(s0);
|
SamplerState LinearClampSampler;
|
||||||
|
|
||||||
struct VSInput
|
struct VSInput
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Shader "Builtin Skybox"
|
|||||||
_Tex ("Cubemap (HDR)", Cube) = "white" [Semantic(SkyboxTexture)]
|
_Tex ("Cubemap (HDR)", Cube) = "white" [Semantic(SkyboxTexture)]
|
||||||
}
|
}
|
||||||
HLSLINCLUDE
|
HLSLINCLUDE
|
||||||
cbuffer EnvironmentConstants : register(b0)
|
cbuffer EnvironmentConstants
|
||||||
{
|
{
|
||||||
float4 gSkyboxTopColor;
|
float4 gSkyboxTopColor;
|
||||||
float4 gSkyboxHorizonColor;
|
float4 gSkyboxHorizonColor;
|
||||||
@@ -19,15 +19,15 @@ Shader "Builtin Skybox"
|
|||||||
float4 gCameraForwardAndUnused;
|
float4 gCameraForwardAndUnused;
|
||||||
};
|
};
|
||||||
|
|
||||||
cbuffer MaterialConstants : register(b1)
|
cbuffer MaterialConstants
|
||||||
{
|
{
|
||||||
float4 gSkyboxTintAndExposure;
|
float4 gSkyboxTintAndExposure;
|
||||||
float4 gSkyboxRotationAndMode;
|
float4 gSkyboxRotationAndMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture2D SkyboxPanoramicTexture : register(t0);
|
Texture2D SkyboxPanoramicTexture;
|
||||||
TextureCube SkyboxTexture : register(t1);
|
TextureCube SkyboxTexture;
|
||||||
SamplerState LinearClampSampler : register(s0);
|
SamplerState LinearClampSampler;
|
||||||
|
|
||||||
struct VSOutput
|
struct VSOutput
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Shader "Builtin Unlit"
|
|||||||
#pragma target 4.5
|
#pragma target 4.5
|
||||||
#pragma vertex MainVS
|
#pragma vertex MainVS
|
||||||
#pragma fragment MainPS
|
#pragma fragment MainPS
|
||||||
cbuffer PerObjectConstants : register(b0)
|
cbuffer PerObjectConstants
|
||||||
{
|
{
|
||||||
float4x4 gProjectionMatrix;
|
float4x4 gProjectionMatrix;
|
||||||
float4x4 gViewMatrix;
|
float4x4 gViewMatrix;
|
||||||
@@ -26,13 +26,13 @@ Shader "Builtin Unlit"
|
|||||||
float4x4 gNormalMatrix;
|
float4x4 gNormalMatrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
cbuffer MaterialConstants : register(b1)
|
cbuffer MaterialConstants
|
||||||
{
|
{
|
||||||
float4 gBaseColorFactor;
|
float4 gBaseColorFactor;
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture2D BaseColorTexture : register(t0);
|
Texture2D BaseColorTexture;
|
||||||
SamplerState LinearClampSampler : register(s0);
|
SamplerState LinearClampSampler;
|
||||||
|
|
||||||
struct VSInput
|
struct VSInput
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -190,10 +190,10 @@ void CollectHlslTextureRegisterBindings(
|
|||||||
std::unordered_map<std::string, GLint>& outTextureUnits,
|
std::unordered_map<std::string, GLint>& outTextureUnits,
|
||||||
std::unordered_set<std::string>& outSamplerNames) {
|
std::unordered_set<std::string>& outSamplerNames) {
|
||||||
static const std::regex kTexturePattern(
|
static const std::regex kTexturePattern(
|
||||||
R"(((?:Texture2D|TextureCube)\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*register\s*\(\s*t([0-9]+)))",
|
R"(((?:Texture2D|TextureCube)\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*register\s*\(\s*t([0-9]+)(?:\s*,\s*space[0-9]+)?\s*\)))",
|
||||||
std::regex::ECMAScript);
|
std::regex::ECMAScript);
|
||||||
static const std::regex kSamplerPattern(
|
static const std::regex kSamplerPattern(
|
||||||
R"(((?:SamplerState|SamplerComparisonState)\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*register\s*\(\s*s([0-9]+)))",
|
R"(((?:SamplerState|SamplerComparisonState)\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*register\s*\(\s*s([0-9]+)(?:\s*,\s*space[0-9]+)?\s*\)))",
|
||||||
std::regex::ECMAScript);
|
std::regex::ECMAScript);
|
||||||
|
|
||||||
for (std::sregex_iterator it(sourceText.begin(), sourceText.end(), kTexturePattern), end; it != end; ++it) {
|
for (std::sregex_iterator it(sourceText.begin(), sourceText.end(), kTexturePattern), end; it != end; ++it) {
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
#include <XCEngine/Core/Containers/String.h>
|
#include <XCEngine/Core/Containers/String.h>
|
||||||
#include <XCEngine/RHI/RHIEnums.h>
|
#include <XCEngine/RHI/RHIEnums.h>
|
||||||
#include <XCEngine/RHI/RHIPipelineState.h>
|
#include <XCEngine/RHI/RHIPipelineState.h>
|
||||||
|
#include <XCEngine/Rendering/Builtin/BuiltinPassLayoutUtils.h>
|
||||||
#include <XCEngine/Resources/Shader/Shader.h>
|
#include <XCEngine/Resources/Shader/Shader.h>
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
@@ -44,6 +46,316 @@ inline std::wstring ToWideAscii(const Containers::String& value) {
|
|||||||
return wide;
|
return wide;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::string ToStdString(const Containers::String& value) {
|
||||||
|
return std::string(value.CStr(), value.Length());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string EscapeRegexLiteral(const Containers::String& value) {
|
||||||
|
std::string escaped;
|
||||||
|
escaped.reserve(value.Length() * 2u);
|
||||||
|
for (size_t index = 0; index < value.Length(); ++index) {
|
||||||
|
const char ch = value[index];
|
||||||
|
switch (ch) {
|
||||||
|
case '\\':
|
||||||
|
case '^':
|
||||||
|
case '$':
|
||||||
|
case '.':
|
||||||
|
case '|':
|
||||||
|
case '?':
|
||||||
|
case '*':
|
||||||
|
case '+':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
case '{':
|
||||||
|
case '}':
|
||||||
|
escaped.push_back('\\');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
escaped.push_back(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
return escaped;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool TryCollectShaderPassResourceBindings(
|
||||||
|
const Resources::ShaderPass& pass,
|
||||||
|
Containers::Array<Resources::ShaderResourceBindingDesc>& outBindings) {
|
||||||
|
outBindings.Clear();
|
||||||
|
|
||||||
|
if (!pass.resources.Empty()) {
|
||||||
|
outBindings.Reserve(pass.resources.Size());
|
||||||
|
for (const Resources::ShaderResourceBindingDesc& binding : pass.resources) {
|
||||||
|
outBindings.PushBack(binding);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TryBuildImplicitBuiltinPassResourceBindings(pass, outBindings);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Containers::String ResolveLegacyHlslBindingDeclarationAlias(
|
||||||
|
const Resources::ShaderResourceBindingDesc& binding) {
|
||||||
|
switch (ResolveBuiltinPassResourceSemantic(binding)) {
|
||||||
|
case BuiltinPassResourceSemantic::BaseColorTexture:
|
||||||
|
return "gBaseColorTexture";
|
||||||
|
case BuiltinPassResourceSemantic::ShadowMapTexture:
|
||||||
|
return "gShadowMapTexture";
|
||||||
|
case BuiltinPassResourceSemantic::LinearClampSampler:
|
||||||
|
return "gLinearSampler";
|
||||||
|
case BuiltinPassResourceSemantic::ShadowMapSampler:
|
||||||
|
return "gShadowMapSampler";
|
||||||
|
case BuiltinPassResourceSemantic::Unknown:
|
||||||
|
default:
|
||||||
|
return Containers::String();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool TryRewriteHlslRegisterBindingWithName(
|
||||||
|
std::string& sourceText,
|
||||||
|
const Containers::String& declarationName,
|
||||||
|
const char* registerPrefix,
|
||||||
|
Core::uint32 bindingIndex,
|
||||||
|
Core::uint32 setIndex,
|
||||||
|
bool includeRegisterSpace,
|
||||||
|
Resources::ShaderResourceType resourceType) {
|
||||||
|
if (declarationName.Empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string registerClause =
|
||||||
|
includeRegisterSpace
|
||||||
|
? std::string("register(") + registerPrefix +
|
||||||
|
std::to_string(bindingIndex) +
|
||||||
|
", space" +
|
||||||
|
std::to_string(setIndex) +
|
||||||
|
")"
|
||||||
|
: std::string("register(") + registerPrefix +
|
||||||
|
std::to_string(bindingIndex) +
|
||||||
|
")";
|
||||||
|
const std::string escapedName = EscapeRegexLiteral(declarationName);
|
||||||
|
|
||||||
|
if (resourceType == Resources::ShaderResourceType::ConstantBuffer) {
|
||||||
|
const std::regex pattern(
|
||||||
|
"(cbuffer\\s+" + escapedName + "\\s*)(:\\s*register\\s*\\([^\\)]*\\))?(\\s*\\{)",
|
||||||
|
std::regex::ECMAScript);
|
||||||
|
const std::string rewritten =
|
||||||
|
std::regex_replace(sourceText, pattern, "$1: " + registerClause + "$3");
|
||||||
|
if (rewritten != sourceText) {
|
||||||
|
sourceText = rewritten;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::regex pattern(
|
||||||
|
"((?:Texture2D|TextureCube|SamplerState|SamplerComparisonState)\\s+" + escapedName +
|
||||||
|
"\\s*)(:\\s*register\\s*\\([^\\)]*\\))?(\\s*;)",
|
||||||
|
std::regex::ECMAScript);
|
||||||
|
const std::string rewritten =
|
||||||
|
std::regex_replace(sourceText, pattern, "$1: " + registerClause + "$3");
|
||||||
|
if (rewritten != sourceText) {
|
||||||
|
sourceText = rewritten;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char* TryGetHlslRegisterPrefix(Resources::ShaderResourceType type) {
|
||||||
|
switch (type) {
|
||||||
|
case Resources::ShaderResourceType::ConstantBuffer:
|
||||||
|
return "b";
|
||||||
|
case Resources::ShaderResourceType::Texture2D:
|
||||||
|
case Resources::ShaderResourceType::TextureCube:
|
||||||
|
return "t";
|
||||||
|
case Resources::ShaderResourceType::Sampler:
|
||||||
|
return "s";
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool TryRewriteHlslRegisterBinding(
|
||||||
|
std::string& sourceText,
|
||||||
|
const Resources::ShaderResourceBindingDesc& binding,
|
||||||
|
bool includeRegisterSpace) {
|
||||||
|
const char* registerPrefix = TryGetHlslRegisterPrefix(binding.type);
|
||||||
|
if (registerPrefix == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryRewriteHlslRegisterBindingWithName(
|
||||||
|
sourceText,
|
||||||
|
binding.name,
|
||||||
|
registerPrefix,
|
||||||
|
binding.binding,
|
||||||
|
binding.set,
|
||||||
|
includeRegisterSpace,
|
||||||
|
binding.type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Containers::String legacyAlias = ResolveLegacyHlslBindingDeclarationAlias(binding);
|
||||||
|
if (legacyAlias != binding.name &&
|
||||||
|
TryRewriteHlslRegisterBindingWithName(
|
||||||
|
sourceText,
|
||||||
|
legacyAlias,
|
||||||
|
registerPrefix,
|
||||||
|
binding.binding,
|
||||||
|
binding.set,
|
||||||
|
includeRegisterSpace,
|
||||||
|
binding.type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((binding.type == Resources::ShaderResourceType::Texture2D ||
|
||||||
|
binding.type == Resources::ShaderResourceType::TextureCube ||
|
||||||
|
binding.type == Resources::ShaderResourceType::Sampler)) {
|
||||||
|
const Containers::String prefixedName = Containers::String("g") + binding.name;
|
||||||
|
if (prefixedName != binding.name &&
|
||||||
|
prefixedName != legacyAlias &&
|
||||||
|
TryRewriteHlslRegisterBindingWithName(
|
||||||
|
sourceText,
|
||||||
|
prefixedName,
|
||||||
|
registerPrefix,
|
||||||
|
binding.binding,
|
||||||
|
binding.set,
|
||||||
|
includeRegisterSpace,
|
||||||
|
binding.type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool TryBuildRuntimeShaderBindings(
|
||||||
|
const Resources::ShaderPass& pass,
|
||||||
|
Resources::ShaderBackend backend,
|
||||||
|
Containers::Array<Resources::ShaderResourceBindingDesc>& outBindings,
|
||||||
|
bool& outIncludeRegisterSpace) {
|
||||||
|
outBindings.Clear();
|
||||||
|
outIncludeRegisterSpace = false;
|
||||||
|
|
||||||
|
if (backend == Resources::ShaderBackend::Vulkan) {
|
||||||
|
outIncludeRegisterSpace = true;
|
||||||
|
return TryCollectShaderPassResourceBindings(pass, outBindings);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backend != Resources::ShaderBackend::D3D12 &&
|
||||||
|
backend != Resources::ShaderBackend::OpenGL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pass.resources.Empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TryBuildImplicitBuiltinPassResourceBindings(pass, outBindings)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Core::uint32 nextConstantBufferRegister = 0;
|
||||||
|
Core::uint32 nextTextureRegister = 0;
|
||||||
|
Core::uint32 nextSamplerRegister = 0;
|
||||||
|
Core::uint32 nextUnorderedAccessRegister = 0;
|
||||||
|
for (Resources::ShaderResourceBindingDesc& binding : outBindings) {
|
||||||
|
binding.set = 0;
|
||||||
|
switch (binding.type) {
|
||||||
|
case Resources::ShaderResourceType::ConstantBuffer:
|
||||||
|
binding.binding = nextConstantBufferRegister++;
|
||||||
|
break;
|
||||||
|
case Resources::ShaderResourceType::Texture2D:
|
||||||
|
case Resources::ShaderResourceType::TextureCube:
|
||||||
|
binding.binding = nextTextureRegister++;
|
||||||
|
break;
|
||||||
|
case Resources::ShaderResourceType::Sampler:
|
||||||
|
binding.binding = nextSamplerRegister++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
binding.binding = nextUnorderedAccessRegister++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string BuildRuntimeShaderSource(
|
||||||
|
const Resources::ShaderPass& pass,
|
||||||
|
Resources::ShaderBackend backend,
|
||||||
|
const Resources::ShaderStageVariant& variant) {
|
||||||
|
std::string sourceText = ToStdString(variant.sourceCode);
|
||||||
|
|
||||||
|
if (variant.language != Resources::ShaderLanguage::HLSL ||
|
||||||
|
backend == Resources::ShaderBackend::Generic) {
|
||||||
|
return sourceText;
|
||||||
|
}
|
||||||
|
|
||||||
|
Containers::Array<Resources::ShaderResourceBindingDesc> bindings;
|
||||||
|
bool includeRegisterSpace = false;
|
||||||
|
if (!TryBuildRuntimeShaderBindings(pass, backend, bindings, includeRegisterSpace)) {
|
||||||
|
return sourceText;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const Resources::ShaderResourceBindingDesc& binding : bindings) {
|
||||||
|
TryRewriteHlslRegisterBinding(sourceText, binding, includeRegisterSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sourceText;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void AddShaderCompileMacro(
|
||||||
|
RHI::ShaderCompileDesc& compileDesc,
|
||||||
|
const wchar_t* name,
|
||||||
|
const wchar_t* definition = L"1") {
|
||||||
|
if (name == nullptr || *name == L'\0') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const RHI::ShaderCompileMacro& existingMacro : compileDesc.macros) {
|
||||||
|
if (existingMacro.name == name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RHI::ShaderCompileMacro macro = {};
|
||||||
|
macro.name = name;
|
||||||
|
macro.definition = definition != nullptr ? definition : L"";
|
||||||
|
compileDesc.macros.push_back(std::move(macro));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void InjectUnityStyleBackendMacros(
|
||||||
|
Resources::ShaderBackend backend,
|
||||||
|
RHI::ShaderCompileDesc& compileDesc) {
|
||||||
|
switch (backend) {
|
||||||
|
case Resources::ShaderBackend::OpenGL:
|
||||||
|
AddShaderCompileMacro(compileDesc, L"SHADER_API_GLCORE");
|
||||||
|
AddShaderCompileMacro(compileDesc, L"UNITY_UV_STARTS_AT_TOP", L"0");
|
||||||
|
AddShaderCompileMacro(compileDesc, L"UNITY_NEAR_CLIP_VALUE", L"-1");
|
||||||
|
break;
|
||||||
|
case Resources::ShaderBackend::Vulkan:
|
||||||
|
AddShaderCompileMacro(compileDesc, L"SHADER_API_VULKAN");
|
||||||
|
AddShaderCompileMacro(compileDesc, L"UNITY_UV_STARTS_AT_TOP", L"1");
|
||||||
|
AddShaderCompileMacro(compileDesc, L"UNITY_NEAR_CLIP_VALUE", L"0");
|
||||||
|
break;
|
||||||
|
case Resources::ShaderBackend::D3D12:
|
||||||
|
AddShaderCompileMacro(compileDesc, L"SHADER_API_D3D12");
|
||||||
|
AddShaderCompileMacro(compileDesc, L"UNITY_UV_STARTS_AT_TOP", L"1");
|
||||||
|
AddShaderCompileMacro(compileDesc, L"UNITY_NEAR_CLIP_VALUE", L"0");
|
||||||
|
break;
|
||||||
|
case Resources::ShaderBackend::Generic:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void ApplyShaderStageVariant(
|
inline void ApplyShaderStageVariant(
|
||||||
const Resources::ShaderStageVariant& variant,
|
const Resources::ShaderStageVariant& variant,
|
||||||
RHI::ShaderCompileDesc& compileDesc) {
|
RHI::ShaderCompileDesc& compileDesc) {
|
||||||
@@ -55,6 +367,19 @@ inline void ApplyShaderStageVariant(
|
|||||||
compileDesc.profile = ToWideAscii(variant.profile);
|
compileDesc.profile = ToWideAscii(variant.profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void ApplyShaderStageVariant(
|
||||||
|
const Resources::ShaderPass& pass,
|
||||||
|
Resources::ShaderBackend backend,
|
||||||
|
const Resources::ShaderStageVariant& variant,
|
||||||
|
RHI::ShaderCompileDesc& compileDesc) {
|
||||||
|
const std::string sourceText = BuildRuntimeShaderSource(pass, backend, variant);
|
||||||
|
compileDesc.source.assign(sourceText.begin(), sourceText.end());
|
||||||
|
compileDesc.sourceLanguage = ToRHIShaderLanguage(variant.language);
|
||||||
|
compileDesc.entryPoint = ToWideAscii(variant.entryPoint);
|
||||||
|
compileDesc.profile = ToWideAscii(variant.profile);
|
||||||
|
InjectUnityStyleBackendMacros(backend, compileDesc);
|
||||||
|
}
|
||||||
|
|
||||||
inline Containers::String BuildShaderKeywordSignature(
|
inline Containers::String BuildShaderKeywordSignature(
|
||||||
const Resources::ShaderKeywordSet& keywordSet) {
|
const Resources::ShaderKeywordSet& keywordSet) {
|
||||||
Resources::ShaderKeywordSet normalizedKeywords = keywordSet;
|
Resources::ShaderKeywordSet normalizedKeywords = keywordSet;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include <XCEngine/RHI/ShaderCompiler/SpirvShaderCompiler.h>
|
#include <XCEngine/RHI/ShaderCompiler/SpirvShaderCompiler.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <regex>
|
||||||
|
|
||||||
using namespace XCEngine::Rendering::Pipelines;
|
using namespace XCEngine::Rendering::Pipelines;
|
||||||
using namespace XCEngine::Rendering::Passes;
|
using namespace XCEngine::Rendering::Passes;
|
||||||
@@ -24,6 +24,58 @@ using namespace XCEngine::Containers;
|
|||||||
using namespace XCEngine::Resources;
|
using namespace XCEngine::Resources;
|
||||||
using namespace XCEngine::RHI;
|
using namespace XCEngine::RHI;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::string EscapeRegexLiteralForTest(const std::string& value) {
|
||||||
|
std::string escaped;
|
||||||
|
escaped.reserve(value.size() * 2u);
|
||||||
|
for (const char ch : value) {
|
||||||
|
switch (ch) {
|
||||||
|
case '\\':
|
||||||
|
case '^':
|
||||||
|
case '$':
|
||||||
|
case '.':
|
||||||
|
case '|':
|
||||||
|
case '?':
|
||||||
|
case '*':
|
||||||
|
case '+':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
case '{':
|
||||||
|
case '}':
|
||||||
|
escaped.push_back('\\');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
escaped.push_back(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
return escaped;
|
||||||
|
}
|
||||||
|
|
||||||
|
::testing::AssertionResult SourceContainsRegisterBinding(
|
||||||
|
const std::string& source,
|
||||||
|
const std::string& declaration,
|
||||||
|
const std::string& registerClause) {
|
||||||
|
const std::regex pattern(
|
||||||
|
EscapeRegexLiteralForTest(declaration) + "\\s*:\\s*" +
|
||||||
|
EscapeRegexLiteralForTest(registerClause),
|
||||||
|
std::regex::ECMAScript);
|
||||||
|
if (std::regex_search(source, pattern)) {
|
||||||
|
return ::testing::AssertionSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ::testing::AssertionFailure()
|
||||||
|
<< "Missing binding '" << declaration << " : " << registerClause << "' in source:\n"
|
||||||
|
<< source;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
TEST(BuiltinForwardPipeline_Test, UsesFloat3PositionInputLayoutForStaticMeshVertices) {
|
TEST(BuiltinForwardPipeline_Test, UsesFloat3PositionInputLayoutForStaticMeshVertices) {
|
||||||
const InputLayoutDesc inputLayout = BuiltinForwardPipeline::BuildInputLayout();
|
const InputLayoutDesc inputLayout = BuiltinForwardPipeline::BuildInputLayout();
|
||||||
|
|
||||||
@@ -81,6 +133,15 @@ TEST(BuiltinForwardPipeline_Test, BuiltinForwardShaderUsesUnityStyleSingleSource
|
|||||||
EXPECT_TRUE(pass->fixedFunctionState.depthWriteEnable);
|
EXPECT_TRUE(pass->fixedFunctionState.depthWriteEnable);
|
||||||
EXPECT_EQ(pass->fixedFunctionState.depthFunc, MaterialComparisonFunc::LessEqual);
|
EXPECT_EQ(pass->fixedFunctionState.depthFunc, MaterialComparisonFunc::LessEqual);
|
||||||
|
|
||||||
|
const ShaderStageVariant* fragmentVariant = shader->FindVariant(
|
||||||
|
"ForwardLit",
|
||||||
|
XCEngine::Resources::ShaderType::Fragment,
|
||||||
|
XCEngine::Resources::ShaderBackend::D3D12);
|
||||||
|
ASSERT_NE(fragmentVariant, nullptr);
|
||||||
|
EXPECT_EQ(
|
||||||
|
std::string(fragmentVariant->sourceCode.CStr()).find("register("),
|
||||||
|
std::string::npos);
|
||||||
|
|
||||||
delete shader;
|
delete shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,6 +162,15 @@ TEST(BuiltinForwardPipeline_Test, BuiltinUnlitShaderUsesUnityStyleSingleSourceSu
|
|||||||
EXPECT_TRUE(pass->fixedFunctionState.depthWriteEnable);
|
EXPECT_TRUE(pass->fixedFunctionState.depthWriteEnable);
|
||||||
EXPECT_EQ(pass->fixedFunctionState.depthFunc, MaterialComparisonFunc::LessEqual);
|
EXPECT_EQ(pass->fixedFunctionState.depthFunc, MaterialComparisonFunc::LessEqual);
|
||||||
|
|
||||||
|
const ShaderStageVariant* fragmentVariant = shader->FindVariant(
|
||||||
|
"Unlit",
|
||||||
|
XCEngine::Resources::ShaderType::Fragment,
|
||||||
|
XCEngine::Resources::ShaderBackend::D3D12);
|
||||||
|
ASSERT_NE(fragmentVariant, nullptr);
|
||||||
|
EXPECT_EQ(
|
||||||
|
std::string(fragmentVariant->sourceCode.CStr()).find("register("),
|
||||||
|
std::string::npos);
|
||||||
|
|
||||||
delete shader;
|
delete shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,9 +199,10 @@ TEST(BuiltinForwardPipeline_Test, BuiltinUnlitShaderBuildsVulkanRuntimeSourceWit
|
|||||||
XCEngine::Resources::ShaderBackend::Vulkan,
|
XCEngine::Resources::ShaderBackend::Vulkan,
|
||||||
*fragmentVariant);
|
*fragmentVariant);
|
||||||
|
|
||||||
EXPECT_NE(
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
runtimeSource.find("cbuffer MaterialConstants : register(b0, space1)"),
|
runtimeSource,
|
||||||
std::string::npos);
|
"cbuffer MaterialConstants",
|
||||||
|
"register(b0, space1)"));
|
||||||
EXPECT_NE(runtimeSource.find("BaseColorTexture"), std::string::npos);
|
EXPECT_NE(runtimeSource.find("BaseColorTexture"), std::string::npos);
|
||||||
EXPECT_NE(runtimeSource.find("space2"), std::string::npos);
|
EXPECT_NE(runtimeSource.find("space2"), std::string::npos);
|
||||||
EXPECT_NE(runtimeSource.find("LinearClampSampler"), std::string::npos);
|
EXPECT_NE(runtimeSource.find("LinearClampSampler"), std::string::npos);
|
||||||
@@ -167,10 +238,18 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesUnityStyleUnli
|
|||||||
const std::string d3d12Source(
|
const std::string d3d12Source(
|
||||||
reinterpret_cast<const char*>(d3d12CompileDesc.source.data()),
|
reinterpret_cast<const char*>(d3d12CompileDesc.source.data()),
|
||||||
d3d12CompileDesc.source.size());
|
d3d12CompileDesc.source.size());
|
||||||
EXPECT_NE(d3d12Source.find("BaseColorTexture"), std::string::npos);
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
EXPECT_NE(d3d12Source.find("LinearClampSampler"), std::string::npos);
|
d3d12Source,
|
||||||
EXPECT_EQ(d3d12Source.find("space2"), std::string::npos);
|
"cbuffer MaterialConstants",
|
||||||
EXPECT_EQ(d3d12Source.find("space3"), std::string::npos);
|
"register(b1)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"Texture2D BaseColorTexture",
|
||||||
|
"register(t0)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"SamplerState LinearClampSampler",
|
||||||
|
"register(s0)"));
|
||||||
|
|
||||||
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
|
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
|
||||||
"Unlit",
|
"Unlit",
|
||||||
@@ -187,7 +266,10 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesUnityStyleUnli
|
|||||||
const std::string vulkanSource(
|
const std::string vulkanSource(
|
||||||
reinterpret_cast<const char*>(vulkanCompileDesc.source.data()),
|
reinterpret_cast<const char*>(vulkanCompileDesc.source.data()),
|
||||||
vulkanCompileDesc.source.size());
|
vulkanCompileDesc.source.size());
|
||||||
EXPECT_NE(vulkanSource.find("cbuffer MaterialConstants : register(b0, space1)"), std::string::npos);
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
vulkanSource,
|
||||||
|
"cbuffer MaterialConstants",
|
||||||
|
"register(b0, space1)"));
|
||||||
EXPECT_NE(vulkanSource.find("BaseColorTexture"), std::string::npos);
|
EXPECT_NE(vulkanSource.find("BaseColorTexture"), std::string::npos);
|
||||||
EXPECT_NE(vulkanSource.find("space2"), std::string::npos);
|
EXPECT_NE(vulkanSource.find("space2"), std::string::npos);
|
||||||
EXPECT_NE(vulkanSource.find("LinearClampSampler"), std::string::npos);
|
EXPECT_NE(vulkanSource.find("LinearClampSampler"), std::string::npos);
|
||||||
@@ -227,10 +309,40 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesUnityStyleForw
|
|||||||
const std::string d3d12Source(
|
const std::string d3d12Source(
|
||||||
reinterpret_cast<const char*>(d3d12CompileDesc.source.data()),
|
reinterpret_cast<const char*>(d3d12CompileDesc.source.data()),
|
||||||
d3d12CompileDesc.source.size());
|
d3d12CompileDesc.source.size());
|
||||||
EXPECT_NE(d3d12Source.find("cbuffer LightingConstants : register(b1)"), std::string::npos);
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
EXPECT_NE(d3d12Source.find("Texture2D ShadowMapTexture : register(t1)"), std::string::npos);
|
d3d12Source,
|
||||||
|
"cbuffer PerObjectConstants",
|
||||||
|
"register(b0)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"cbuffer LightingConstants",
|
||||||
|
"register(b1)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"cbuffer MaterialConstants",
|
||||||
|
"register(b2)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"cbuffer ShadowReceiverConstants",
|
||||||
|
"register(b3)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"Texture2D BaseColorTexture",
|
||||||
|
"register(t0)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"SamplerState LinearClampSampler",
|
||||||
|
"register(s0)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"Texture2D ShadowMapTexture",
|
||||||
|
"register(t1)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"SamplerState ShadowMapSampler",
|
||||||
|
"register(s1)"));
|
||||||
|
EXPECT_EQ(d3d12Source.find("space0"), std::string::npos);
|
||||||
EXPECT_EQ(d3d12Source.find("space1"), std::string::npos);
|
EXPECT_EQ(d3d12Source.find("space1"), std::string::npos);
|
||||||
EXPECT_EQ(d3d12Source.find("space6"), std::string::npos);
|
|
||||||
|
|
||||||
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
|
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
|
||||||
"ForwardLit",
|
"ForwardLit",
|
||||||
@@ -248,14 +360,38 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesUnityStyleForw
|
|||||||
const std::string vulkanSource(
|
const std::string vulkanSource(
|
||||||
reinterpret_cast<const char*>(vulkanCompileDesc.source.data()),
|
reinterpret_cast<const char*>(vulkanCompileDesc.source.data()),
|
||||||
vulkanCompileDesc.source.size());
|
vulkanCompileDesc.source.size());
|
||||||
EXPECT_NE(vulkanSource.find("cbuffer PerObjectConstants : register(b0, space0)"), std::string::npos);
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
EXPECT_NE(vulkanSource.find("cbuffer LightingConstants : register(b0, space1)"), std::string::npos);
|
vulkanSource,
|
||||||
EXPECT_NE(vulkanSource.find("cbuffer MaterialConstants : register(b0, space2)"), std::string::npos);
|
"cbuffer PerObjectConstants",
|
||||||
EXPECT_NE(vulkanSource.find("cbuffer ShadowReceiverConstants : register(b0, space3)"), std::string::npos);
|
"register(b0, space0)"));
|
||||||
EXPECT_NE(vulkanSource.find("Texture2D BaseColorTexture : register(t0, space4)"), std::string::npos);
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
EXPECT_NE(vulkanSource.find("SamplerState LinearClampSampler : register(s0, space5)"), std::string::npos);
|
vulkanSource,
|
||||||
EXPECT_NE(vulkanSource.find("Texture2D ShadowMapTexture : register(t0, space6)"), std::string::npos);
|
"cbuffer LightingConstants",
|
||||||
EXPECT_NE(vulkanSource.find("SamplerState ShadowMapSampler : register(s0, space7)"), std::string::npos);
|
"register(b0, space1)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
vulkanSource,
|
||||||
|
"cbuffer MaterialConstants",
|
||||||
|
"register(b0, space2)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
vulkanSource,
|
||||||
|
"cbuffer ShadowReceiverConstants",
|
||||||
|
"register(b0, space3)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
vulkanSource,
|
||||||
|
"Texture2D BaseColorTexture",
|
||||||
|
"register(t0, space4)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
vulkanSource,
|
||||||
|
"SamplerState LinearClampSampler",
|
||||||
|
"register(s0, space5)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
vulkanSource,
|
||||||
|
"Texture2D ShadowMapTexture",
|
||||||
|
"register(t0, space6)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
vulkanSource,
|
||||||
|
"SamplerState ShadowMapSampler",
|
||||||
|
"register(s0, space7)"));
|
||||||
|
|
||||||
delete shader;
|
delete shader;
|
||||||
}
|
}
|
||||||
@@ -664,11 +800,20 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesUnityStyleFina
|
|||||||
const std::string d3d12Source(
|
const std::string d3d12Source(
|
||||||
reinterpret_cast<const char*>(d3d12CompileDesc.source.data()),
|
reinterpret_cast<const char*>(d3d12CompileDesc.source.data()),
|
||||||
d3d12CompileDesc.source.size());
|
d3d12CompileDesc.source.size());
|
||||||
EXPECT_NE(d3d12Source.find("cbuffer FinalColorConstants : register(b0)"), std::string::npos);
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
EXPECT_NE(d3d12Source.find("Texture2D gSourceColorTexture : register(t0)"), std::string::npos);
|
d3d12Source,
|
||||||
EXPECT_NE(d3d12Source.find("SamplerState gLinearClampSampler : register(s0)"), std::string::npos);
|
"cbuffer FinalColorConstants",
|
||||||
|
"register(b0)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"Texture2D gSourceColorTexture",
|
||||||
|
"register(t0)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"SamplerState gLinearClampSampler",
|
||||||
|
"register(s0)"));
|
||||||
|
EXPECT_EQ(d3d12Source.find("space0"), std::string::npos);
|
||||||
EXPECT_EQ(d3d12Source.find("space1"), std::string::npos);
|
EXPECT_EQ(d3d12Source.find("space1"), std::string::npos);
|
||||||
EXPECT_EQ(d3d12Source.find("space2"), std::string::npos);
|
|
||||||
|
|
||||||
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
|
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
|
||||||
"FinalColor",
|
"FinalColor",
|
||||||
@@ -681,15 +826,18 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesUnityStyleFina
|
|||||||
*pass,
|
*pass,
|
||||||
XCEngine::Resources::ShaderBackend::Vulkan,
|
XCEngine::Resources::ShaderBackend::Vulkan,
|
||||||
*vulkanFragment);
|
*vulkanFragment);
|
||||||
EXPECT_NE(
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
runtimeSource.find("cbuffer FinalColorConstants : register(b0, space0)"),
|
runtimeSource,
|
||||||
std::string::npos);
|
"cbuffer FinalColorConstants",
|
||||||
EXPECT_NE(
|
"register(b0, space0)"));
|
||||||
runtimeSource.find("Texture2D gSourceColorTexture : register(t0, space1)"),
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
std::string::npos);
|
runtimeSource,
|
||||||
EXPECT_NE(
|
"Texture2D gSourceColorTexture",
|
||||||
runtimeSource.find("SamplerState gLinearClampSampler : register(s0, space2)"),
|
"register(t0, space1)"));
|
||||||
std::string::npos);
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
runtimeSource,
|
||||||
|
"SamplerState gLinearClampSampler",
|
||||||
|
"register(s0, space2)"));
|
||||||
|
|
||||||
ShaderCompileDesc vulkanCompileDesc = {};
|
ShaderCompileDesc vulkanCompileDesc = {};
|
||||||
::XCEngine::Rendering::Detail::ApplyShaderStageVariant(
|
::XCEngine::Rendering::Detail::ApplyShaderStageVariant(
|
||||||
@@ -778,11 +926,20 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesUnityStyleColo
|
|||||||
const std::string d3d12Source(
|
const std::string d3d12Source(
|
||||||
reinterpret_cast<const char*>(d3d12CompileDesc.source.data()),
|
reinterpret_cast<const char*>(d3d12CompileDesc.source.data()),
|
||||||
d3d12CompileDesc.source.size());
|
d3d12CompileDesc.source.size());
|
||||||
EXPECT_NE(d3d12Source.find("cbuffer PostProcessConstants : register(b0)"), std::string::npos);
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
EXPECT_NE(d3d12Source.find("Texture2D gSourceColorTexture : register(t0)"), std::string::npos);
|
d3d12Source,
|
||||||
EXPECT_NE(d3d12Source.find("SamplerState gLinearClampSampler : register(s0)"), std::string::npos);
|
"cbuffer PostProcessConstants",
|
||||||
|
"register(b0)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"Texture2D gSourceColorTexture",
|
||||||
|
"register(t0)"));
|
||||||
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
d3d12Source,
|
||||||
|
"SamplerState gLinearClampSampler",
|
||||||
|
"register(s0)"));
|
||||||
|
EXPECT_EQ(d3d12Source.find("space0"), std::string::npos);
|
||||||
EXPECT_EQ(d3d12Source.find("space1"), std::string::npos);
|
EXPECT_EQ(d3d12Source.find("space1"), std::string::npos);
|
||||||
EXPECT_EQ(d3d12Source.find("space2"), std::string::npos);
|
|
||||||
|
|
||||||
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
|
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
|
||||||
"ColorScale",
|
"ColorScale",
|
||||||
@@ -795,15 +952,18 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesUnityStyleColo
|
|||||||
*pass,
|
*pass,
|
||||||
XCEngine::Resources::ShaderBackend::Vulkan,
|
XCEngine::Resources::ShaderBackend::Vulkan,
|
||||||
*vulkanFragment);
|
*vulkanFragment);
|
||||||
EXPECT_NE(
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
runtimeSource.find("cbuffer PostProcessConstants : register(b0, space0)"),
|
runtimeSource,
|
||||||
std::string::npos);
|
"cbuffer PostProcessConstants",
|
||||||
EXPECT_NE(
|
"register(b0, space0)"));
|
||||||
runtimeSource.find("Texture2D gSourceColorTexture : register(t0, space1)"),
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
std::string::npos);
|
runtimeSource,
|
||||||
EXPECT_NE(
|
"Texture2D gSourceColorTexture",
|
||||||
runtimeSource.find("SamplerState gLinearClampSampler : register(s0, space2)"),
|
"register(t0, space1)"));
|
||||||
std::string::npos);
|
EXPECT_TRUE(SourceContainsRegisterBinding(
|
||||||
|
runtimeSource,
|
||||||
|
"SamplerState gLinearClampSampler",
|
||||||
|
"register(s0, space2)"));
|
||||||
|
|
||||||
ShaderCompileDesc vulkanCompileDesc = {};
|
ShaderCompileDesc vulkanCompileDesc = {};
|
||||||
::XCEngine::Rendering::Detail::ApplyShaderStageVariant(
|
::XCEngine::Rendering::Detail::ApplyShaderStageVariant(
|
||||||
|
|||||||
Reference in New Issue
Block a user