Align managed raster RenderGraph authoring with URP

This commit is contained in:
2026-04-26 23:32:09 +08:00
parent 09b1289338
commit 3b38d65ab8
13 changed files with 430 additions and 123 deletions

View File

@@ -129,6 +129,14 @@ Guardrails:
## Past Execution
- Removed fullscreen-kernel-specific authoring from the public managed
RenderGraph / URP pass surface. Public C# pass authors now use
`AddRasterPass(...)`, resource declarations, and `SetRenderFunc(...)`;
`ColorScaleFullscreen`, `ShaderVectorFullscreen`, and `FinalColorFullscreen`
execution setters are internal implementation hooks for URP's built-in
passes. Native now records generic managed raster passes as declared callback
graph work in any stage, while true deferred managed command-buffer execution
remains the next capability gap.
- Made the public managed
`ScriptableRenderPass.RecordRenderGraph(RenderGraph, ContextContainer)` path
receive real URP frame data. `RenderingData`, `CameraData`, `LightingData`,

View File

@@ -116,6 +116,7 @@ struct ManagedScriptableRenderContextState {
struct RasterPassRecordRequest {
Containers::String passName = {};
Rendering::FullscreenPassDesc passDesc = {};
bool usesManagedRenderFuncExecution = false;
Rendering::RenderGraphTextureHandle sourceColorTexture = {};
std::vector<Rendering::RenderGraphTextureHandle> readTextures = {};
std::vector<Rendering::RenderGraphTextureHandle> readDepthTextures = {};
@@ -346,6 +347,13 @@ ResolveManagedPrimaryColorTarget(
: Rendering::RenderGraphTextureHandle{};
}
bool HasManagedRasterWriteTarget(
const ManagedScriptableRenderContextState::RasterPassRecordRequest&
request) {
return ResolveManagedPrimaryColorTarget(request.colorTargets).IsValid() ||
request.depthTarget.IsValid();
}
Rendering::RenderGraphTextureHandle
ResolveManagedScriptableRenderContextPrimaryColorTarget(
const ManagedScriptableRenderContextState* state) {
@@ -474,6 +482,58 @@ bool RecordManagedFullscreenRasterPass(
std::move(textureBindings));
}
bool RecordManagedRenderFuncRasterPass(
const Rendering::RenderPipelineStageRenderGraphContext& stageContext,
Rendering::RenderGraphTextureHandle sourceColorTexture,
std::vector<Rendering::RenderGraphTextureHandle> colorTargets,
std::vector<Rendering::RenderGraphTextureHandle> additionalReadTextures,
std::vector<Rendering::RenderGraphTextureHandle> additionalReadDepthTextures,
std::vector<Rendering::RenderPassGraphTextureBindingRequest>
textureBindings,
Rendering::RenderGraphTextureHandle depthTarget,
const Containers::String& passName) {
if (!ResolveManagedPrimaryColorTarget(colorTargets).IsValid() &&
!depthTarget.IsValid()) {
return false;
}
const Rendering::RenderGraphRecordingContext baseContext =
Rendering::BuildRenderGraphRecordingContext(stageContext);
Rendering::RenderGraphRecordingContextBuildParams params = {};
if (!passName.Empty()) {
params.passName = &passName;
}
params.overrideSourceBinding = true;
if (sourceColorTexture.IsValid()) {
params.sourceBinding =
BuildManagedScriptableRenderContextSourceBinding(
stageContext,
sourceColorTexture);
}
params.overrideColorTargets = true;
params.colorTargets = std::move(colorTargets);
params.overrideDepthTarget = true;
params.depthTarget = depthTarget;
const Rendering::RenderGraphRecordingContext recordingContext =
Rendering::BuildRenderGraphRecordingContext(
baseContext,
std::move(params));
const Rendering::RenderPassRenderGraphContext renderGraphContext =
Rendering::BuildRenderPassRenderGraphContext(recordingContext);
const Rendering::RenderPassGraphIO io =
Rendering::BuildDeclaredRasterPassGraphIO(renderGraphContext);
return Rendering::RecordCallbackRasterRenderPass(
renderGraphContext,
io,
[](const Rendering::RenderPassContext&) {
return true;
},
std::move(additionalReadTextures),
std::move(additionalReadDepthTextures),
std::move(textureBindings));
}
bool RecordManagedFullscreenPassToTexture(
const Rendering::RenderPipelineStageRenderGraphContext& stageContext,
Rendering::RenderPass& pass,
@@ -1956,9 +2016,6 @@ private:
if (managedContextState.rasterPassRequests.empty()) {
return true;
}
if (!Rendering::IsCameraFrameFullscreenSequenceStage(context.stage)) {
return false;
}
Rendering::RenderGraphTextureHandle currentSourceColor =
ResolveManagedScriptableRenderContextSourceColorTexture(
@@ -1966,16 +2023,50 @@ private:
const Rendering::RenderGraphTextureHandle finalOutputColor =
ResolveManagedScriptableRenderContextPrimaryColorTarget(
&managedContextState);
if (!currentSourceColor.IsValid() ||
!finalOutputColor.IsValid()) {
return false;
}
for (size_t passIndex = 0u;
passIndex < managedContextState.rasterPassRequests.size();
++passIndex) {
const ManagedScriptableRenderContextState::RasterPassRecordRequest&
request = managedContextState.rasterPassRequests[passIndex];
const Containers::String resolvedPassName =
!request.passName.Empty()
? request.passName
: managedContextState.rasterPassRequests.size() == 1u
? context.passName
: Rendering::BuildRenderGraphSequencePassName(
context.passName,
passIndex);
if (request.usesManagedRenderFuncExecution) {
if (!RecordManagedRenderFuncRasterPass(
context,
request.sourceColorTexture,
request.colorTargets,
request.readTextures,
request.readDepthTextures,
request.textureBindings,
request.depthTarget,
resolvedPassName)) {
return false;
}
const Rendering::RenderGraphTextureHandle
resolvedOutputColor =
ResolveManagedPrimaryColorTarget(
request.colorTargets);
if (resolvedOutputColor.IsValid()) {
currentSourceColor = resolvedOutputColor;
}
continue;
}
if (!Rendering::IsCameraFrameFullscreenSequenceStage(
context.stage) ||
!currentSourceColor.IsValid() ||
!finalOutputColor.IsValid()) {
return false;
}
Rendering::RenderPass* const pass =
ConfigureManagedFullscreenPass(
m_fullscreenPassPool,
@@ -1985,14 +2076,6 @@ private:
return false;
}
const Containers::String resolvedPassName =
!request.passName.Empty()
? request.passName
: managedContextState.rasterPassRequests.size() == 1u
? context.passName
: Rendering::BuildRenderGraphSequencePassName(
context.passName,
passIndex);
const Rendering::RenderGraphTextureHandle resolvedSourceColor =
request.sourceColorTexture.IsValid()
? request.sourceColorTexture
@@ -4717,8 +4800,7 @@ uint64_t InternalCall_Rendering_ScriptableRenderContext_BeginRasterPass(
ManagedScriptableRenderContextState* const state =
FindManagedScriptableRenderContextState(nativeHandle);
if (state == nullptr ||
state->graphContext == nullptr ||
!Rendering::IsCameraFrameFullscreenSequenceStage(state->stage)) {
state->graphContext == nullptr) {
return 0u;
}
@@ -4961,10 +5043,13 @@ InternalCall_Rendering_ScriptableRenderContext_SetRasterPassColorScaleFullscreen
state,
rasterPassHandle);
if (request == nullptr ||
state == nullptr ||
!Rendering::IsCameraFrameFullscreenSequenceStage(state->stage) ||
vectorPayload == nullptr) {
return 0;
}
request->usesManagedRenderFuncExecution = false;
request->passDesc =
Rendering::FullscreenPassDesc::MakeColorScale(
*vectorPayload);
@@ -4986,6 +5071,8 @@ InternalCall_Rendering_ScriptableRenderContext_SetRasterPassShaderVectorFullscre
state,
rasterPassHandle);
if (request == nullptr ||
state == nullptr ||
!Rendering::IsCameraFrameFullscreenSequenceStage(state->stage) ||
vectorPayload == nullptr) {
return 0;
}
@@ -4996,6 +5083,7 @@ InternalCall_Rendering_ScriptableRenderContext_SetRasterPassShaderVectorFullscre
return 0;
}
request->usesManagedRenderFuncExecution = false;
request->passDesc =
Rendering::FullscreenPassDesc::MakeShaderVector(
shaderPathString,
@@ -5019,10 +5107,13 @@ InternalCall_Rendering_ScriptableRenderContext_SetRasterPassFinalColorFullscreen
state,
rasterPassHandle);
if (request == nullptr ||
state == nullptr ||
!Rendering::IsCameraFrameFullscreenSequenceStage(state->stage) ||
settingsData == nullptr) {
return 0;
}
request->usesManagedRenderFuncExecution = false;
request->passDesc =
Rendering::FullscreenPassDesc::MakeFinalColor(
BuildManagedFinalColorSettings(
@@ -5032,14 +5123,33 @@ InternalCall_Rendering_ScriptableRenderContext_SetRasterPassFinalColorFullscreen
: 0;
}
mono_bool
InternalCall_Rendering_ScriptableRenderContext_SetRasterPassManagedRenderFuncExecution(
uint64_t nativeHandle,
uint64_t rasterPassHandle) {
ManagedScriptableRenderContextState* const state =
FindManagedScriptableRenderContextState(nativeHandle);
ManagedScriptableRenderContextState::RasterPassRecordRequest*
const request =
FindPendingManagedRasterPassRecordRequest(
state,
rasterPassHandle);
if (request == nullptr) {
return 0;
}
request->usesManagedRenderFuncExecution = true;
request->passDesc = {};
return 1;
}
mono_bool InternalCall_Rendering_ScriptableRenderContext_CommitRasterPass(
uint64_t nativeHandle,
uint64_t rasterPassHandle) {
ManagedScriptableRenderContextState* const state =
FindManagedScriptableRenderContextState(nativeHandle);
if (state == nullptr ||
state->graphContext == nullptr ||
!Rendering::IsCameraFrameFullscreenSequenceStage(state->stage)) {
state->graphContext == nullptr) {
return 0;
}
@@ -5053,9 +5163,13 @@ mono_bool InternalCall_Rendering_ScriptableRenderContext_CommitRasterPass(
ManagedScriptableRenderContextState::RasterPassRecordRequest
request = std::move(it->second);
state->pendingRasterPassRequests.erase(it);
if (!request.passDesc.IsValid() ||
!ResolveManagedPrimaryColorTarget(request.colorTargets)
.IsValid()) {
if (request.usesManagedRenderFuncExecution) {
if (!HasManagedRasterWriteTarget(request)) {
return 0;
}
} else if (!request.passDesc.IsValid() ||
!ResolveManagedPrimaryColorTarget(request.colorTargets)
.IsValid()) {
return 0;
}
@@ -6499,6 +6613,7 @@ void RegisterInternalCalls() {
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_SetRasterPassColorScaleFullscreenExecution", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_SetRasterPassColorScaleFullscreenExecution));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_SetRasterPassShaderVectorFullscreenExecution", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_SetRasterPassShaderVectorFullscreenExecution));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_SetRasterPassFinalColorFullscreenExecution", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_SetRasterPassFinalColorFullscreenExecution));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_SetRasterPassManagedRenderFuncExecution", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_SetRasterPassManagedRenderFuncExecution));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_CommitRasterPass", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_CommitRasterPass));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetStageColorSource", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetStageColorSource));
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetStageUsesGraphManagedOutputColor", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetStageUsesGraphManagedOutputColor));

View File

@@ -7,12 +7,6 @@ using XCEngine.Rendering.Universal;
namespace Gameplay
{
internal static class BuiltinShaderPaths
{
public const string ColorScalePostProcess =
"builtin://shaders/color-scale-post-process";
}
internal static class ProbeFinalColorSettingsFactory
{
public static FinalColorSettings Create()
@@ -141,12 +135,6 @@ namespace Gameplay
Transparent
}
internal enum FullscreenPassKind
{
ColorScale,
ShaderVector
}
internal sealed class ScenePhasePass : ScriptableRenderPass
{
private readonly ScenePhaseKind m_phaseKind;
@@ -197,9 +185,6 @@ namespace Gameplay
internal sealed class FullscreenPass : ScriptableRenderPass
{
private readonly FullscreenPassKind m_passKind;
private readonly Vector4 m_vectorPayload;
private readonly string m_shaderPath;
private readonly string m_passName;
public FullscreenPass(
@@ -207,22 +192,14 @@ namespace Gameplay
Vector4 colorScale)
{
renderPassEvent = passEvent;
m_passKind = FullscreenPassKind.ColorScale;
m_vectorPayload = colorScale;
m_shaderPath = string.Empty;
m_passName = string.Empty;
}
public FullscreenPass(
RenderPassEvent passEvent,
string shaderPath,
Vector4 vectorPayload,
string passName = null)
string passName)
{
renderPassEvent = passEvent;
m_passKind = FullscreenPassKind.ShaderVector;
m_vectorPayload = vectorPayload;
m_shaderPath = shaderPath ?? string.Empty;
m_passName = passName ?? string.Empty;
}
@@ -238,21 +215,32 @@ namespace Gameplay
private bool RecordFullscreen(
ScriptableRenderContext context)
{
switch (m_passKind)
RenderGraphTextureHandle sourceColor =
context.sourceColorTexture;
RenderGraphTextureHandle outputColor =
context.primaryColorTarget;
if (!sourceColor.isValid ||
!outputColor.isValid)
{
case FullscreenPassKind.ColorScale:
return RecordColorScaleFullscreenPass(
context,
m_vectorPayload);
case FullscreenPassKind.ShaderVector:
return RecordShaderVectorFullscreenPass(
context,
m_shaderPath,
m_vectorPayload,
m_passName);
default:
return false;
return false;
}
return context
.AddRasterPass(ResolvePassName())
.UseColorSource(sourceColor)
.SetColorAttachment(outputColor)
.SetRenderFunc(
rasterContext =>
{
})
.Commit();
}
private string ResolvePassName()
{
return string.IsNullOrEmpty(m_passName)
? "Gameplay.GenericFullscreenRasterPass"
: m_passName;
}
}
@@ -535,14 +523,10 @@ namespace Gameplay
new FullscreenFeature(
new FullscreenPass(
RenderPassEvent.BeforeRenderingPostProcessing,
BuiltinShaderPaths.ColorScalePostProcess,
firstVectorPayload,
"ColorScale"),
"ManagedPostProcess.First"),
new FullscreenPass(
RenderPassEvent.AfterRenderingPostProcessing,
BuiltinShaderPaths.ColorScalePostProcess,
secondVectorPayload,
"ColorScale")));
"ManagedPostProcess.Second")));
}
}
@@ -554,10 +538,10 @@ namespace Gameplay
{
AddFeature(new DefaultSceneFeature(onOpaqueRecorded));
AddFeature(
new FullscreenFeature(
new FullscreenPass(
RenderPassEvent.BeforeRenderingPostProcessing,
postProcessScale)));
new ColorScalePostProcessRendererFeature
{
colorScale = postProcessScale
});
}
}
@@ -2131,8 +2115,6 @@ namespace Gameplay
new FullscreenFeature(
new FullscreenPass(
RenderPassEvent.BeforeRenderingPostProcessing,
BuiltinShaderPaths.ColorScalePostProcess,
new Vector4(1.05f, 1.0f, 0.95f, 1.0f),
"ManagedCameraOverridePostProcess")));
}
}
@@ -2607,11 +2589,13 @@ namespace Gameplay
return context != null &&
context
.AddRasterPass(
"Managed.InvalidMainSceneRasterPass")
"Managed.MainSceneGenericRasterPass")
.SetColorAttachment(
context.primaryColorTarget)
.SetColorScaleFullscreenExecution(
new Vector4(1.0f, 1.0f, 1.0f, 1.0f))
.SetRenderFunc(
rasterContext =>
{
})
.Commit();
}
}

View File

@@ -69,9 +69,13 @@ namespace Gameplay
public bool HasRenderGraphRasterPassBuilderUseColorSource;
public bool HasRenderGraphRasterPassBuilderUseTexture;
public bool HasRenderGraphRasterPassBuilderSetColorAttachment;
public bool HasRenderGraphRasterPassBuilderSetRenderFunc;
public bool HasRenderGraphRasterPassBuilderSetColorScaleFullscreenExecution;
public bool HasRenderGraphRasterPassBuilderSetShaderVectorFullscreenExecution;
public bool HasRenderGraphRasterPassBuilderSetFinalColorFullscreenExecution;
public bool HasRenderGraphRasterPassBuilderCommit;
public bool HasRenderGraphRasterContextType;
public bool HasRenderGraphRasterContextCommandBuffer;
public bool HasSceneRenderPhaseType;
public bool HasSceneRenderInjectionPointType;
public bool HasRendererListType;
@@ -105,6 +109,9 @@ namespace Gameplay
public bool HasRenderGraphType;
public bool HasRenderGraphAddRasterPass;
public bool HasRenderPassPublicRecordRenderGraph;
public bool HasRenderPassProtectedRecordColorScaleFullscreenPass;
public bool HasRenderPassProtectedRecordShaderVectorFullscreenPass;
public bool HasRenderPassProtectedRecordFinalColorFullscreenPass;
public bool HasRenderPassComparisonOperators;
public bool HasRenderPassEventUnityNumericOrder;
public bool HasRenderPassEventEngineExtensionOrder;
@@ -172,6 +179,8 @@ namespace Gameplay
"XCEngine.ScriptableObject");
System.Type rasterPassBuilderType =
typeof(RenderGraphRasterPassBuilder);
System.Type rasterPassContextType =
typeof(RenderGraphRasterContext);
System.Type rendererFeatureType =
typeof(ScriptableRendererFeature);
System.Type rendererDataType =
@@ -476,10 +485,18 @@ namespace Gameplay
rasterPassBuilderType.GetMethod(
"SetColorAttachment",
PublicInstanceMethodFlags) != null;
HasRenderGraphRasterPassBuilderSetRenderFunc =
rasterPassBuilderType.GetMethod(
"SetRenderFunc",
PublicInstanceMethodFlags) != null;
HasRenderGraphRasterPassBuilderSetColorScaleFullscreenExecution =
rasterPassBuilderType.GetMethod(
"SetColorScaleFullscreenExecution",
PublicInstanceMethodFlags) != null;
HasRenderGraphRasterPassBuilderSetShaderVectorFullscreenExecution =
rasterPassBuilderType.GetMethod(
"SetShaderVectorFullscreenExecution",
PublicInstanceMethodFlags) != null;
HasRenderGraphRasterPassBuilderSetFinalColorFullscreenExecution =
rasterPassBuilderType.GetMethod(
"SetFinalColorFullscreenExecution",
@@ -488,6 +505,13 @@ namespace Gameplay
rasterPassBuilderType.GetMethod(
"Commit",
PublicInstanceMethodFlags) != null;
HasRenderGraphRasterContextType =
rasterPassContextType != null;
HasRenderGraphRasterContextCommandBuffer =
rasterPassContextType.GetProperty(
"cmd",
BindingFlags.Instance |
BindingFlags.Public) != null;
HasSceneRenderPhaseType =
contextType.Assembly.GetType(
"XCEngine.Rendering.SceneRenderPhase") != null;
@@ -640,6 +664,21 @@ namespace Gameplay
typeof(ContextContainer)
},
null) != null;
HasRenderPassProtectedRecordColorScaleFullscreenPass =
renderPassType.GetMethod(
"RecordColorScaleFullscreenPass",
BindingFlags.Instance |
BindingFlags.NonPublic) != null;
HasRenderPassProtectedRecordShaderVectorFullscreenPass =
renderPassType.GetMethod(
"RecordShaderVectorFullscreenPass",
BindingFlags.Instance |
BindingFlags.NonPublic) != null;
HasRenderPassProtectedRecordFinalColorFullscreenPass =
renderPassType.GetMethod(
"RecordFinalColorFullscreenPass",
BindingFlags.Instance |
BindingFlags.NonPublic) != null;
HasRenderPassComparisonOperators =
renderPassType.GetMethod(
"op_GreaterThan",

View File

@@ -20,7 +20,7 @@ namespace XCEngine.Rendering.Universal
renderingData != null &&
renderingData.isFinalOutputStage &&
(!renderingData.finalColorData.requiresProcessing ||
RecordFinalColorFullscreenPass(
RecordInternalFinalColorFullscreenPass(
context,
renderingData.finalColorData.settings,
"Universal.BuiltinFinalColor"));

View File

@@ -35,7 +35,7 @@ namespace XCEngine.Rendering.Universal
return false;
}
return RecordColorScaleFullscreenPass(
return RecordInternalColorScaleFullscreenPass(
context,
context.sourceColorTexture,
context.primaryColorTarget,

View File

@@ -170,7 +170,7 @@ namespace XCEngine.Rendering.Universal
rhs) < 0;
}
protected bool RecordColorScaleFullscreenPass(
internal static bool RecordInternalColorScaleFullscreenPass(
ScriptableRenderContext context,
Vector4 colorScale)
{
@@ -180,14 +180,14 @@ namespace XCEngine.Rendering.Universal
context,
out sourceColor,
out outputColor) &&
RecordColorScaleFullscreenPass(
RecordInternalColorScaleFullscreenPass(
context,
sourceColor,
outputColor,
colorScale);
}
protected bool RecordColorScaleFullscreenPass(
internal static bool RecordInternalColorScaleFullscreenPass(
ScriptableRenderContext context,
RenderGraphTextureHandle sourceColor,
RenderGraphTextureHandle outputColor,
@@ -216,7 +216,7 @@ namespace XCEngine.Rendering.Universal
.Commit();
}
protected bool RecordShaderVectorFullscreenPass(
internal static bool RecordInternalShaderVectorFullscreenPass(
ScriptableRenderContext context,
string shaderPath,
Vector4 vectorPayload,
@@ -235,7 +235,7 @@ namespace XCEngine.Rendering.Universal
context,
out sourceColor,
out outputColor) &&
RecordShaderVectorFullscreenPass(
RecordInternalShaderVectorFullscreenPass(
context,
sourceColor,
outputColor,
@@ -244,7 +244,7 @@ namespace XCEngine.Rendering.Universal
passName: passName);
}
protected bool RecordShaderVectorFullscreenPass(
internal static bool RecordInternalShaderVectorFullscreenPass(
ScriptableRenderContext context,
RenderGraphTextureHandle sourceColor,
RenderGraphTextureHandle outputColor,
@@ -285,7 +285,7 @@ namespace XCEngine.Rendering.Universal
.Commit();
}
protected bool RecordFinalColorFullscreenPass(
internal static bool RecordInternalFinalColorFullscreenPass(
ScriptableRenderContext context,
FinalColorSettings settings,
string passName = null)
@@ -296,7 +296,7 @@ namespace XCEngine.Rendering.Universal
context,
out sourceColor,
out outputColor) &&
RecordFinalColorFullscreenPass(
RecordInternalFinalColorFullscreenPass(
context,
sourceColor,
outputColor,
@@ -304,7 +304,7 @@ namespace XCEngine.Rendering.Universal
passName);
}
protected bool RecordFinalColorFullscreenPass(
internal static bool RecordInternalFinalColorFullscreenPass(
ScriptableRenderContext context,
RenderGraphTextureHandle sourceColor,
RenderGraphTextureHandle outputColor,

View File

@@ -540,6 +540,12 @@ namespace XCEngine
ulong rasterPassHandle,
ref Rendering.FinalColorSettings settings);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool
Rendering_ScriptableRenderContext_SetRasterPassManagedRenderFuncExecution(
ulong nativeHandle,
ulong rasterPassHandle);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool
Rendering_ScriptableRenderContext_CommitRasterPass(

View File

@@ -164,9 +164,9 @@ namespace XCEngine.Rendering
name));
}
// SRP v1 wrapper over managed fullscreen raster requests. Commit only
// succeeds on fullscreen sequence stages and the execution kinds remain
// limited to the built-in fullscreen pass family.
// Public RenderGraph raster authoring entry point. Built-in fullscreen
// kernels are internal URP implementation details, not public context
// shortcuts.
public RenderGraphRasterPassBuilder AddRasterPass(
string passName)
{

View File

@@ -9,12 +9,24 @@ namespace XCEngine.Rendering
None = 0,
ColorScaleFullscreen = 1,
ShaderVectorFullscreen = 2,
FinalColorFullscreen = 3
FinalColorFullscreen = 3,
ManagedRenderFunc = 4
}
// Managed SRP v1 raster recording is intentionally narrow: this builder
// only describes fullscreen raster passes that map onto the built-in
// ColorScale / ShaderVector / FinalColor executions.
public sealed class RenderGraphRasterContext
{
internal RenderGraphRasterContext(
CommandBuffer commandBuffer)
{
cmd = commandBuffer ?? new CommandBuffer();
}
public CommandBuffer cmd { get; private set; }
}
// Public raster pass authoring follows the RenderGraph shape: declare
// resources, then provide a render func. Built-in fullscreen kernels are
// kept as internal execution details for URP.
public sealed class RenderGraphRasterPassBuilder
{
private struct TextureBindingRequest
@@ -40,6 +52,7 @@ namespace XCEngine.Rendering
private string m_shaderPath = string.Empty;
private string m_shaderPassName = string.Empty;
private FinalColorSettings m_finalColorSettings;
private Action<RenderGraphRasterContext> m_renderFunc;
private RenderGraphRasterPassExecutionKind m_executionKind;
private bool m_finalized;
@@ -70,19 +83,6 @@ namespace XCEngine.Rendering
return this;
}
public RenderGraphRasterPassBuilder
SetFinalColorFullscreenExecution(
FinalColorSettings settings)
{
m_executionKind =
RenderGraphRasterPassExecutionKind
.FinalColorFullscreen;
m_finalColorSettings = settings;
m_shaderPath = string.Empty;
m_shaderPassName = string.Empty;
return this;
}
public RenderGraphRasterPassBuilder UseTexture(
RenderGraphTextureHandle texture)
{
@@ -150,7 +150,37 @@ namespace XCEngine.Rendering
return this;
}
public RenderGraphRasterPassBuilder
public RenderGraphRasterPassBuilder SetRenderFunc(
Action<RenderGraphRasterContext> renderFunc)
{
if (renderFunc == null)
{
throw new ArgumentNullException(nameof(renderFunc));
}
m_executionKind =
RenderGraphRasterPassExecutionKind.ManagedRenderFunc;
m_renderFunc = renderFunc;
m_shaderPath = string.Empty;
m_shaderPassName = string.Empty;
return this;
}
internal RenderGraphRasterPassBuilder
SetFinalColorFullscreenExecution(
FinalColorSettings settings)
{
m_executionKind =
RenderGraphRasterPassExecutionKind
.FinalColorFullscreen;
m_finalColorSettings = settings;
m_renderFunc = null;
m_shaderPath = string.Empty;
m_shaderPassName = string.Empty;
return this;
}
internal RenderGraphRasterPassBuilder
SetColorScaleFullscreenExecution(
Vector4 colorScale)
{
@@ -158,12 +188,13 @@ namespace XCEngine.Rendering
RenderGraphRasterPassExecutionKind
.ColorScaleFullscreen;
m_vectorPayload = colorScale;
m_renderFunc = null;
m_shaderPath = string.Empty;
m_shaderPassName = string.Empty;
return this;
}
public RenderGraphRasterPassBuilder
internal RenderGraphRasterPassBuilder
SetShaderVectorFullscreenExecution(
string shaderPath,
Vector4 vectorPayload,
@@ -180,6 +211,7 @@ namespace XCEngine.Rendering
RenderGraphRasterPassExecutionKind
.ShaderVectorFullscreen;
m_vectorPayload = vectorPayload;
m_renderFunc = null;
m_shaderPath = shaderPath;
m_shaderPassName = shaderPassName ?? string.Empty;
return this;
@@ -187,11 +219,9 @@ namespace XCEngine.Rendering
public bool Commit()
{
// Native bridge rejects raster pass recording outside the
// fullscreen sequence stages.
if (m_finalized ||
!HasExecutionConfigured() ||
!HasAnyColorAttachment())
!HasRequiredAttachments())
{
return false;
}
@@ -341,6 +371,20 @@ namespace XCEngine.Rendering
nativePassHandle,
ref m_finalColorSettings);
break;
case RenderGraphRasterPassExecutionKind
.ManagedRenderFunc:
// Managed command buffers are not bridged into native
// graph execution yet, so the render func is invoked
// during recording while native records the declared IO.
m_renderFunc(
new RenderGraphRasterContext(
new CommandBuffer(m_passName)));
configuredExecution =
InternalCalls
.Rendering_ScriptableRenderContext_SetRasterPassManagedRenderFuncExecution(
m_context.nativeHandle,
nativePassHandle);
break;
default:
configuredExecution = false;
break;
@@ -359,6 +403,18 @@ namespace XCEngine.Rendering
RenderGraphRasterPassExecutionKind.None;
}
private bool HasRequiredAttachments()
{
if (m_executionKind ==
RenderGraphRasterPassExecutionKind.ManagedRenderFunc)
{
return HasAnyColorAttachment() ||
m_depthAttachment.isValid;
}
return HasAnyColorAttachment();
}
private void AddReadTexture(
RenderGraphTextureHandle texture,
bool isDepth)

View File

@@ -46,12 +46,24 @@ namespace ProjectScripts
ScriptableRenderContext context,
RenderingData renderingData)
{
return context != null &&
renderingData != null &&
renderingData.isPostProcessStage &&
RecordColorScaleFullscreenPass(
context,
new Vector4(1.15f, 0.95f, 1.05f, 1.0f));
if (context == null ||
renderingData == null ||
!renderingData.isPostProcessStage ||
!context.sourceColorTexture.isValid ||
!context.primaryColorTarget.isValid)
{
return false;
}
return context
.AddRasterPass("Project.PostProcessColorScale")
.UseColorSource(context.sourceColorTexture)
.SetColorAttachment(context.primaryColorTarget)
.SetRenderFunc(
rasterContext =>
{
})
.Commit();
}
}

View File

@@ -1457,6 +1457,20 @@ TEST_F(
bool hasRendererRecordRenderer = false;
bool hasPublicRendererSupportsStageRenderGraph = false;
bool hasPublicRendererRecordStageRenderGraph = false;
bool hasRenderGraphRasterPassBuilderType = false;
bool hasRenderGraphRasterPassBuilderUseColorSource = false;
bool hasRenderGraphRasterPassBuilderUseTexture = false;
bool hasRenderGraphRasterPassBuilderSetColorAttachment = false;
bool hasRenderGraphRasterPassBuilderSetRenderFunc = false;
bool hasRenderGraphRasterPassBuilderSetColorScaleFullscreenExecution = false;
bool hasRenderGraphRasterPassBuilderSetShaderVectorFullscreenExecution = false;
bool hasRenderGraphRasterPassBuilderSetFinalColorFullscreenExecution = false;
bool hasRenderGraphRasterPassBuilderCommit = false;
bool hasRenderGraphRasterContextType = false;
bool hasRenderGraphRasterContextCommandBuffer = false;
bool hasRenderPassProtectedRecordColorScaleFullscreenPass = false;
bool hasRenderPassProtectedRecordShaderVectorFullscreenPass = false;
bool hasRenderPassProtectedRecordFinalColorFullscreenPass = false;
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
@@ -1606,6 +1620,62 @@ TEST_F(
selectionScript,
"HasPublicRendererRecordStageRenderGraph",
hasPublicRendererRecordStageRenderGraph));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderGraphRasterPassBuilderType",
hasRenderGraphRasterPassBuilderType));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderGraphRasterPassBuilderUseColorSource",
hasRenderGraphRasterPassBuilderUseColorSource));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderGraphRasterPassBuilderUseTexture",
hasRenderGraphRasterPassBuilderUseTexture));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderGraphRasterPassBuilderSetColorAttachment",
hasRenderGraphRasterPassBuilderSetColorAttachment));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderGraphRasterPassBuilderSetRenderFunc",
hasRenderGraphRasterPassBuilderSetRenderFunc));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderGraphRasterPassBuilderSetColorScaleFullscreenExecution",
hasRenderGraphRasterPassBuilderSetColorScaleFullscreenExecution));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderGraphRasterPassBuilderSetShaderVectorFullscreenExecution",
hasRenderGraphRasterPassBuilderSetShaderVectorFullscreenExecution));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderGraphRasterPassBuilderSetFinalColorFullscreenExecution",
hasRenderGraphRasterPassBuilderSetFinalColorFullscreenExecution));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderGraphRasterPassBuilderCommit",
hasRenderGraphRasterPassBuilderCommit));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderGraphRasterContextType",
hasRenderGraphRasterContextType));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderGraphRasterContextCommandBuffer",
hasRenderGraphRasterContextCommandBuffer));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderPassProtectedRecordColorScaleFullscreenPass",
hasRenderPassProtectedRecordColorScaleFullscreenPass));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderPassProtectedRecordShaderVectorFullscreenPass",
hasRenderPassProtectedRecordShaderVectorFullscreenPass));
EXPECT_TRUE(runtime->TryGetFieldValue(
selectionScript,
"HasRenderPassProtectedRecordFinalColorFullscreenPass",
hasRenderPassProtectedRecordFinalColorFullscreenPass));
EXPECT_FALSE(hasPublicContextRecordScene);
EXPECT_FALSE(hasPublicContextRecordScenePhase);
@@ -1644,6 +1714,20 @@ TEST_F(
EXPECT_TRUE(hasRendererRecordRenderer);
EXPECT_FALSE(hasPublicRendererSupportsStageRenderGraph);
EXPECT_FALSE(hasPublicRendererRecordStageRenderGraph);
EXPECT_TRUE(hasRenderGraphRasterPassBuilderType);
EXPECT_TRUE(hasRenderGraphRasterPassBuilderUseColorSource);
EXPECT_TRUE(hasRenderGraphRasterPassBuilderUseTexture);
EXPECT_TRUE(hasRenderGraphRasterPassBuilderSetColorAttachment);
EXPECT_TRUE(hasRenderGraphRasterPassBuilderSetRenderFunc);
EXPECT_FALSE(hasRenderGraphRasterPassBuilderSetColorScaleFullscreenExecution);
EXPECT_FALSE(hasRenderGraphRasterPassBuilderSetShaderVectorFullscreenExecution);
EXPECT_FALSE(hasRenderGraphRasterPassBuilderSetFinalColorFullscreenExecution);
EXPECT_TRUE(hasRenderGraphRasterPassBuilderCommit);
EXPECT_TRUE(hasRenderGraphRasterContextType);
EXPECT_TRUE(hasRenderGraphRasterContextCommandBuffer);
EXPECT_FALSE(hasRenderPassProtectedRecordColorScaleFullscreenPass);
EXPECT_FALSE(hasRenderPassProtectedRecordShaderVectorFullscreenPass);
EXPECT_FALSE(hasRenderPassProtectedRecordFinalColorFullscreenPass);
}
TEST_F(
@@ -4315,7 +4399,7 @@ TEST_F(
TEST_F(
MonoScriptRuntimeTest,
ManagedStageRecorderRecordsShaderVectorPostProcessThroughScriptableRenderContext) {
ManagedStageRecorderRecordsGenericPostProcessRasterPassesThroughRenderGraph) {
const auto bridge =
XCEngine::Rendering::Pipelines::GetManagedRenderPipelineBridge();
ASSERT_NE(bridge, nullptr);
@@ -4400,17 +4484,17 @@ TEST_F(
ASSERT_EQ(compiledGraph.GetPassCount(), 2u);
EXPECT_STREQ(
compiledGraph.GetPassName(0).CStr(),
"ColorScale");
"ManagedPostProcess.First");
EXPECT_STREQ(
compiledGraph.GetPassName(1).CStr(),
"ColorScale");
"ManagedPostProcess.Second");
recorder->Shutdown();
}
TEST_F(
MonoScriptRuntimeTest,
ManagedStageRecorderRejectsRasterPassRecordingOutsideFullscreenStages) {
ManagedStageRecorderRecordsGenericRasterPassOutsideFullscreenStages) {
const auto bridge =
XCEngine::Rendering::Pipelines::GetManagedRenderPipelineBridge();
ASSERT_NE(bridge, nullptr);
@@ -4480,7 +4564,7 @@ TEST_F(
&blackboard
};
EXPECT_FALSE(recorder->RecordStageRenderGraph(graphContext));
EXPECT_TRUE(recorder->RecordStageRenderGraph(graphContext));
XCEngine::Rendering::CompiledRenderGraph compiledGraph = {};
XCEngine::Containers::String errorMessage;
@@ -4490,7 +4574,10 @@ TEST_F(
compiledGraph,
&errorMessage))
<< errorMessage.CStr();
EXPECT_EQ(compiledGraph.GetPassCount(), 0u);
ASSERT_EQ(compiledGraph.GetPassCount(), 1u);
EXPECT_STREQ(
compiledGraph.GetPassName(0).CStr(),
"Managed.MainSceneGenericRasterPass");
recorder->Shutdown();
}

View File

@@ -381,7 +381,7 @@ TEST_F(
ASSERT_EQ(compiledGraph.GetPassCount(), 1u);
EXPECT_STREQ(
compiledGraph.GetPassName(0).CStr(),
"Universal.ColorScaleFullscreen");
"Project.PostProcessColorScale");
recorder->Shutdown();
}