rj-action-library/Runtime/Rendering/Context/RDContext.cs

297 lines
7.0 KiB
C#
Raw Normal View History

2025-04-23 12:00:43 +00:00
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
2025-04-26 20:04:11 +00:00
public partial class RDContext
2025-04-23 12:00:43 +00:00
{
2025-04-29 19:46:45 +00:00
2025-04-26 20:04:11 +00:00
protected RenderingDevice _renderingDevice;
public RenderingDevice renderingDevice => _renderingDevice;
2025-04-29 19:46:45 +00:00
protected bool _localRenderingDevice;
public bool isLocalRenderingDevice => _localRenderingDevice;
2025-04-23 12:00:43 +00:00
protected RDShader _shader;
public RDShader shader => _shader;
protected RDPipeline _pipeline;
public RDPipeline pipeline => _pipeline;
2025-04-29 19:46:45 +00:00
public static RDContext Local()
{
var ctx = new RDContext();
ctx.Initialize( true );
return ctx;
}
2025-04-26 20:04:11 +00:00
public void Initialize( bool local = false)
2025-04-23 12:00:43 +00:00
{
2025-04-29 19:46:45 +00:00
_localRenderingDevice = local;
2025-04-26 20:04:11 +00:00
_renderingDevice = local ? RenderingServer.Singleton.CreateLocalRenderingDevice():
RenderingServer.Singleton.GetRenderingDevice();
2025-04-29 19:46:45 +00:00
if ( _renderingDevice == null )
{
Error( "Could not initialize rendering device" );
}
2025-04-23 12:00:43 +00:00
}
2025-04-26 20:04:11 +00:00
2025-04-23 12:00:43 +00:00
protected int _view = -1;
public int view => _view;
protected int _effectCallbackType;
public int effectCallbackType => _effectCallbackType;
protected RenderData _renderData;
public RenderData renderData => _renderData;
protected RenderSceneBuffersRD _sceneBuffers;
public RenderSceneBuffersRD sceneBuffers => _sceneBuffers;
protected RenderSceneDataRD _sceneData;
public RenderSceneDataRD sceneData => _sceneData;
protected Vector3I _groups;
public Vector3I groups => _groups;
public Vector2I internalSize => _sceneBuffers.GetInternalSize();
public RDTexture GetScreenColorTexture()
{
return RDTexture.Color( this );
}
public RDTexture GetScreenDepthTexture()
{
return RDTexture.Depth( this );
}
2025-04-29 19:46:45 +00:00
public void SetProgram( RDProgram p )
{
SetShaderAndPipeline( p.shader, p.pipeline );
}
public void SetProgramFromPath( string path )
{
Verbose( "Creating program:", path );
var program = RDProgram.FromPath( this, path );
SetProgram( program );
}
2025-04-26 20:04:11 +00:00
public void SetShaderAndPipeline( RDShader shader, RDPipeline pipeline )
{
if ( shader == null || pipeline == null )
{
_shader = null;
_pipeline = null;
Error( "Shader Pipeline is null", shader, pipeline );
return;
}
Verbose( "Set Shader Pipeline", shader, pipeline );
_shader = shader;
_pipeline = pipeline;
}
2025-04-25 08:13:22 +00:00
public void AssignScreenColorTexture( RDSampler sampler = null, int setIndex = -1 )
2025-04-23 12:00:43 +00:00
{
2025-04-25 08:13:22 +00:00
AssignTexture( GetScreenColorTexture(), sampler, setIndex );
2025-04-23 12:00:43 +00:00
}
2025-04-25 08:13:22 +00:00
public void AssignScreenDepthTexture( RDSampler sampler = null, int setIndex = -1 )
2025-04-23 12:00:43 +00:00
{
2025-04-25 08:13:22 +00:00
AssignTexture( GetScreenDepthTexture(), sampler, setIndex );
2025-04-29 19:46:45 +00:00
}
2025-04-23 12:00:43 +00:00
2025-04-25 08:13:22 +00:00
public void AssignTexture( RDTexture texture, RDSampler sampler = null, int setIndex = -1 )
2025-04-23 12:00:43 +00:00
{
// effect.Verbose( "Incoming Uniform Index", setIndex );
if ( setIndex == -1 )
{
setIndex = _uniformSets.Count;
}
// effect.Verbose( "Set Uniform Index", setIndex );
if ( sampler == null )
{
// effect.Verbose( "Adding Image" );
2025-04-26 20:04:11 +00:00
AddUniformSet( RDUniformSet.Image( this, texture, setIndex ) );
2025-04-23 12:00:43 +00:00
}
else
{
// effect.Verbose( "Adding Sampler" );
2025-04-26 20:04:11 +00:00
AddUniformSet( RDUniformSet.Sampler( this, sampler,texture, setIndex ) );
2025-04-23 12:00:43 +00:00
}
}
List<RDUniformSet> _uniformSets = new List<RDUniformSet>();
public RDPushConstants pushConstants;
public void AddUniformSet( RDUniformSet uniformSet )
{
_uniformSets.Add( uniformSet );
}
2025-04-29 19:46:45 +00:00
public void CreateUniformaSet( params RDUniform[] uniforms )
{
var setIndex = _uniformSets.Count;
_CreateUniformSetRid( setIndex, uniforms );
}
public Rid _CreateUniformSetRid( int index, params RDUniform[] uniforms )
{
var array = new Godot.Collections.Array<RDUniform>();
array.AddRange( uniforms );
if ( ! isLocalRenderingDevice )
{
return UniformSetCacheRD.GetCache( shader.rid, (uint) index, array );
}
else
{
return renderingDevice.UniformSetCreate( array, shader.rid, (uint) index );
}
}
2025-04-23 12:00:43 +00:00
public void Clear()
{
_uniformSets.Clear();
pushConstants = null;
}
2025-04-24 13:39:00 +00:00
2025-04-29 19:46:45 +00:00
public Vector2I computeSize = new Vector2I( 512, 512 );
public Vector2I GetComputeSize()
{
if ( _sceneBuffers != null )
{
return _sceneBuffers.GetInternalSize();
}
return computeSize;
}
2025-04-26 20:04:11 +00:00
public void SetComputeGroups( Vector3I groups )
2025-04-24 13:39:00 +00:00
{
this._groups = groups;
}
2025-04-23 12:00:43 +00:00
2025-04-29 19:46:45 +00:00
public void CalculateSceneComputeGroups( int groupSize )
2025-04-24 13:39:00 +00:00
{
2025-04-29 19:46:45 +00:00
var size = GetComputeSize();
CalculateComputeGroups( new Vector3I( groupSize, groupSize, 0 ), size );
2025-04-24 13:39:00 +00:00
}
2025-04-29 19:46:45 +00:00
public void CalculateSceneComputeGroups( Vector3I groupSize )
2025-04-24 13:39:00 +00:00
{
2025-04-29 19:46:45 +00:00
var size = GetComputeSize();
CalculateComputeGroups( groupSize, size );
}
2025-04-24 13:39:00 +00:00
2025-04-29 19:46:45 +00:00
public void CalculateComputeGroups( int groupSize, Vector2I size )
{
CalculateComputeGroups( new Vector3I( groupSize, groupSize, 0 ), size );
}
public void CalculateComputeGroups( Vector3I groupSize, Vector2I size )
{
2025-04-24 13:39:00 +00:00
var xGroups = Mathf.CeilToInt( size.X / (float) groupSize.X );
var yGroups = groupSize.Y == 0 ? 1 : Mathf.CeilToInt( size.Y / (float) groupSize.Y );
2025-04-29 19:46:45 +00:00
var zGroups = 1;
2025-04-24 13:39:00 +00:00
2025-04-26 20:04:11 +00:00
SetComputeGroups( new Vector3I( xGroups, yGroups, zGroups ) );
2025-04-24 13:39:00 +00:00
}
2025-04-29 19:46:45 +00:00
public void Submit()
{
if ( ! isLocalRenderingDevice )
{
Error( "You can only submit or sync in non-local rendering devices" );
return;
}
renderingDevice.Submit();
}
public void Sync()
{
if ( ! isLocalRenderingDevice )
{
Error( "You can only submit or sync in non-local rendering devices" );
return;
}
renderingDevice.Sync();
}
public void SubmitAndSync()
{
if ( ! isLocalRenderingDevice )
{
Error( "You can only submit or sync in non-local rendering devices" );
return;
}
Submit();
Sync();
}
2025-04-26 20:04:11 +00:00
public void ProcessComputeProgram()
2025-04-23 12:00:43 +00:00
{
try
{
2025-04-26 20:04:11 +00:00
var computeList = RDComputeList.Begin( _renderingDevice );
2025-04-23 12:00:43 +00:00
computeList.BindPipeline( pipeline );
_uniformSets.ForEach(
( u )=>
{
computeList.BindUniformSet( u, u.setIndex );
}
);
if ( pushConstants != null )
{
computeList.SetPushConstants( pushConstants );
}
computeList.Dispatch( groups );
computeList.End();
}
catch( System.Exception e )
{
2025-04-26 20:04:11 +00:00
Error( e );
2025-04-23 12:00:43 +00:00
}
Clear();
}
public void SetRenderData( RenderData renderData, RenderSceneBuffersRD buffers, RenderSceneDataRD sceneData )
{
this._renderData = renderData;
this._sceneBuffers = buffers;
this._sceneData = sceneData;
}
public void SetView( int view )
{
this._view = view;
}
}
}