@@ -404,6 +404,7 @@ public void CreateBuffers()
404404 private readonly BufferResource [ ] indexBuffers = new BufferResource [ ushort . MaxValue - 1 ] ;
405405 private readonly Dictionary < VertexLayout , TransientEntry > transientBuffers = [ ] ;
406406 private readonly TextureResource [ ] textures = new TextureResource [ ushort . MaxValue - 1 ] ;
407+ private RenderTarget currentRenderTarget ;
407408
408409 private bool iteratingCommands = false ;
409410 private int commandIndex ;
@@ -711,9 +712,11 @@ public void EndFrame()
711712
712713 if ( commandBuffer != nint . Zero )
713714 {
714- var fences = new nint [ SDL . SDL_SubmitGPUCommandBufferAndAcquireFence ( commandBuffer ) ] ;
715+ var fences = new nint [ 1 ] ;
715716
716- if ( SDL . SDL_WaitForGPUFences ( device , true , fences . AsSpan ( ) , ( uint ) fences . Length ) == false )
717+ fences [ 0 ] = SDL . SDL_SubmitGPUCommandBufferAndAcquireFence ( commandBuffer ) ;
718+
719+ if ( SDL . SDL_WaitForGPUFences ( device , true , fences . AsSpan ( ) , ( uint ) fences . Length ) == false )
717720 {
718721 Log . Error ( $ "[SDL GPU] Failed to wait for GPU Fences: { SDL . SDL_GetError ( ) } ") ;
719722 }
@@ -756,6 +759,14 @@ public void EndFrame()
756759
757760 commandBuffer = nint . Zero ;
758761 }
762+
763+ if ( currentRenderTarget != null )
764+ {
765+ currentRenderTarget = null ;
766+
767+ Screen . Width = window . Size . X ;
768+ Screen . Height = window . Size . Y ;
769+ }
759770 }
760771
761772 internal void UpdateDepthTextureIfNeeded ( bool force )
@@ -888,13 +899,24 @@ internal void ResumeRenderPass()
888899 public void BeginRenderPass ( RenderTarget target , CameraClearMode clear , Color clearColor , Vector4 viewport ,
889900 in Matrix4x4 view , in Matrix4x4 projection )
890901 {
891- viewData . renderTarget = target ;
902+ viewData . renderTarget = currentRenderTarget = target ;
892903 viewData . clearMode = clear ;
893904 viewData . clearColor = clearColor ;
894905 viewData . viewport = viewport ;
895906 viewData . renderData . view = view ;
896907 viewData . renderData . projection = projection ;
897908
909+ if ( target != null )
910+ {
911+ Screen . Width = target . width ;
912+ Screen . Height = target . height ;
913+ }
914+ else
915+ {
916+ Screen . Width = window . Size . X ;
917+ Screen . Height = window . Size . Y ;
918+ }
919+
898920 AddCommand ( new SDLGPUBeginRenderPassCommand ( target , clear , clearColor , viewport , view , projection ) ) ;
899921 }
900922
@@ -1179,74 +1201,122 @@ instance.program is not SDLGPUShaderProgram shader ||
11791201 _ => throw new ArgumentOutOfRangeException ( nameof ( state . destinationBlend ) , "Invalid blend mode" ) ,
11801202 } ;
11811203
1182- var colorTargetDescription = new SDL . SDL_GPUColorTargetDescription ( )
1204+ var colorTargetDescriptions = new List < SDL . SDL_GPUColorTargetDescription > ( ) ;
1205+
1206+ if ( state . renderTarget == null || state . renderTarget . Disposed )
11831207 {
1184- format = SDL . SDL_GetGPUSwapchainTextureFormat ( device , window . window ) ,
1185- blend_state = new ( )
1208+ var colorTargetDescription = new SDL . SDL_GPUColorTargetDescription ( )
11861209 {
1187- enable_blend = state . sourceBlend != BlendMode . Off && state . destinationBlend != BlendMode . Off ,
1188- color_blend_op = SDL . SDL_GPUBlendOp . SDL_GPU_BLENDOP_ADD ,
1189- alpha_blend_op = SDL . SDL_GPUBlendOp . SDL_GPU_BLENDOP_ADD ,
1190- src_color_blendfactor = sourceBlend ,
1191- src_alpha_blendfactor = sourceBlend ,
1192- dst_color_blendfactor = destinationBlend ,
1193- dst_alpha_blendfactor = destinationBlend ,
1210+ format = SDL . SDL_GetGPUSwapchainTextureFormat ( device , window . window ) ,
1211+ blend_state = new ( )
1212+ {
1213+ enable_blend = state . sourceBlend != BlendMode . Off && state . destinationBlend != BlendMode . Off ,
1214+ color_blend_op = SDL . SDL_GPUBlendOp . SDL_GPU_BLENDOP_ADD ,
1215+ alpha_blend_op = SDL . SDL_GPUBlendOp . SDL_GPU_BLENDOP_ADD ,
1216+ src_color_blendfactor = sourceBlend ,
1217+ src_alpha_blendfactor = sourceBlend ,
1218+ dst_color_blendfactor = destinationBlend ,
1219+ dst_alpha_blendfactor = destinationBlend ,
1220+ }
1221+ } ;
1222+
1223+ colorTargetDescriptions . Add ( colorTargetDescription ) ;
1224+ }
1225+ else
1226+ {
1227+ foreach ( var texture in state . renderTarget . colorTextures )
1228+ {
1229+ if ( texture . Disposed )
1230+ {
1231+ continue ;
1232+ }
1233+
1234+ if ( TryGetTextureFormat ( texture . impl . Format , state . renderTarget . flags | TextureFlags . ColorTarget , out var textureFormat ) )
1235+ {
1236+ var colorTargetDescription = new SDL . SDL_GPUColorTargetDescription ( )
1237+ {
1238+ format = textureFormat ,
1239+ blend_state = new ( )
1240+ {
1241+ enable_blend = state . sourceBlend != BlendMode . Off && state . destinationBlend != BlendMode . Off ,
1242+ color_blend_op = SDL . SDL_GPUBlendOp . SDL_GPU_BLENDOP_ADD ,
1243+ alpha_blend_op = SDL . SDL_GPUBlendOp . SDL_GPU_BLENDOP_ADD ,
1244+ src_color_blendfactor = sourceBlend ,
1245+ src_alpha_blendfactor = sourceBlend ,
1246+ dst_color_blendfactor = destinationBlend ,
1247+ dst_alpha_blendfactor = destinationBlend ,
1248+ }
1249+ } ;
1250+
1251+ colorTargetDescriptions . Add ( colorTargetDescription ) ;
1252+ }
11941253 }
1195- } ;
11961254
1197- SDL . SDL_GPUVertexBufferDescription [ ] vertexDescriptions = [ vertexDescription ] ;
1255+ if ( state . renderTarget . DepthTexture != null &&
1256+ state . renderTarget . DepthTexture . Disposed == false &&
1257+ TryGetTextureFormat ( state . renderTarget . DepthTexture . impl . Format , state . renderTarget . flags | TextureFlags . DepthStencilTarget ,
1258+ out var depthFormat ) )
1259+ {
1260+ sdlDepthFormat = depthFormat ;
1261+ }
1262+ }
11981263
1199- fixed ( SDL . SDL_GPUVertexBufferDescription * descriptions = vertexDescriptions )
1264+ fixed( SDL . SDL_GPUColorTargetDescription * colorTargetDescriptionsPtr = CollectionsMarshal . AsSpan ( colorTargetDescriptions ) )
12001265 {
1201- var info = new SDL . SDL_GPUGraphicsPipelineCreateInfo ( )
1266+ SDL . SDL_GPUVertexBufferDescription [ ] vertexDescriptions = [ vertexDescription ] ;
1267+
1268+ fixed ( SDL . SDL_GPUVertexBufferDescription * descriptions = vertexDescriptions )
12021269 {
1203- primitive_type = state . primitiveType switch
1270+ var info = new SDL . SDL_GPUGraphicsPipelineCreateInfo ( )
12041271 {
1205- MeshTopology . TriangleStrip => SDL . SDL_GPUPrimitiveType . SDL_GPU_PRIMITIVETYPE_TRIANGLESTRIP ,
1206- MeshTopology . Triangles => SDL . SDL_GPUPrimitiveType . SDL_GPU_PRIMITIVETYPE_TRIANGLELIST ,
1207- MeshTopology . Lines => SDL . SDL_GPUPrimitiveType . SDL_GPU_PRIMITIVETYPE_LINELIST ,
1208- MeshTopology . LineStrip => SDL . SDL_GPUPrimitiveType . SDL_GPU_PRIMITIVETYPE_LINESTRIP ,
1209- _ => throw new ArgumentOutOfRangeException ( "Invalid value for primitive type" , nameof ( state . primitiveType ) ) ,
1210- } ,
1211- vertex_shader = shader . vertex ,
1212- fragment_shader = shader . fragment ,
1213- rasterizer_state = new ( )
1214- {
1215- cull_mode = state . cull switch
1272+ primitive_type = state . primitiveType switch
12161273 {
1217- CullingMode . None => SDL . SDL_GPUCullMode . SDL_GPU_CULLMODE_NONE ,
1218- CullingMode . Front => SDL . SDL_GPUCullMode . SDL_GPU_CULLMODE_FRONT ,
1219- CullingMode . Back => SDL . SDL_GPUCullMode . SDL_GPU_CULLMODE_BACK ,
1220- _ => throw new ArgumentOutOfRangeException ( "Invalid value for cull" , nameof ( state . cull ) ) ,
1274+ MeshTopology . TriangleStrip => SDL . SDL_GPUPrimitiveType . SDL_GPU_PRIMITIVETYPE_TRIANGLESTRIP ,
1275+ MeshTopology . Triangles => SDL . SDL_GPUPrimitiveType . SDL_GPU_PRIMITIVETYPE_TRIANGLELIST ,
1276+ MeshTopology . Lines => SDL . SDL_GPUPrimitiveType . SDL_GPU_PRIMITIVETYPE_LINELIST ,
1277+ MeshTopology . LineStrip => SDL . SDL_GPUPrimitiveType . SDL_GPU_PRIMITIVETYPE_LINESTRIP ,
1278+ _ => throw new ArgumentOutOfRangeException ( "Invalid value for primitive type" , nameof ( state . primitiveType ) ) ,
12211279 } ,
1222- fill_mode = state . wireframe ? SDL . SDL_GPUFillMode . SDL_GPU_FILLMODE_LINE : SDL . SDL_GPUFillMode . SDL_GPU_FILLMODE_FILL ,
1223- front_face = SDL . SDL_GPUFrontFace . SDL_GPU_FRONTFACE_CLOCKWISE ,
1224- } ,
1225- depth_stencil_state = new ( )
1226- {
1227- enable_depth_test = state . enableDepth ,
1228- enable_depth_write = state . depthWrite ,
1229- compare_op = SDL . SDL_GPUCompareOp . SDL_GPU_COMPAREOP_LESS_OR_EQUAL ,
1230- } ,
1231- vertex_input_state = new ( )
1232- {
1233- num_vertex_buffers = 1 ,
1234- num_vertex_attributes = ( uint ) attributesSpan . Length ,
1235- vertex_attributes = attributes ,
1236- vertex_buffer_descriptions = descriptions ,
1237- } ,
1238- target_info = new ( )
1239- {
1240- num_color_targets = 1 ,
1241- color_target_descriptions = & colorTargetDescription ,
1242- has_depth_stencil_target = state . enableDepth && depthStencilFormat . HasValue ,
1243- depth_stencil_format = sdlDepthFormat ,
1244- }
1245- } ;
1280+ vertex_shader = shader . vertex ,
1281+ fragment_shader = shader . fragment ,
1282+ rasterizer_state = new ( )
1283+ {
1284+ cull_mode = state . cull switch
1285+ {
1286+ CullingMode . None => SDL . SDL_GPUCullMode . SDL_GPU_CULLMODE_NONE ,
1287+ CullingMode . Front => SDL . SDL_GPUCullMode . SDL_GPU_CULLMODE_FRONT ,
1288+ CullingMode . Back => SDL . SDL_GPUCullMode . SDL_GPU_CULLMODE_BACK ,
1289+ _ => throw new ArgumentOutOfRangeException ( "Invalid value for cull" , nameof ( state . cull ) ) ,
1290+ } ,
1291+ fill_mode = state . wireframe ? SDL . SDL_GPUFillMode . SDL_GPU_FILLMODE_LINE : SDL . SDL_GPUFillMode . SDL_GPU_FILLMODE_FILL ,
1292+ front_face = SDL . SDL_GPUFrontFace . SDL_GPU_FRONTFACE_CLOCKWISE ,
1293+ } ,
1294+ depth_stencil_state = new ( )
1295+ {
1296+ enable_depth_test = state . enableDepth ,
1297+ enable_depth_write = state . depthWrite ,
1298+ compare_op = SDL . SDL_GPUCompareOp . SDL_GPU_COMPAREOP_LESS_OR_EQUAL ,
1299+ } ,
1300+ vertex_input_state = new ( )
1301+ {
1302+ num_vertex_buffers = 1 ,
1303+ num_vertex_attributes = ( uint ) attributesSpan . Length ,
1304+ vertex_attributes = attributes ,
1305+ vertex_buffer_descriptions = descriptions ,
1306+ } ,
1307+ target_info = new ( )
1308+ {
1309+ num_color_targets = ( uint ) colorTargetDescriptions . Count ,
1310+ color_target_descriptions = colorTargetDescriptionsPtr ,
1311+ has_depth_stencil_target = depthStencilFormat . HasValue ,
1312+ depth_stencil_format = sdlDepthFormat ,
1313+ }
1314+ } ;
12461315
1247- pipeline = SDL . SDL_CreateGPUGraphicsPipeline ( device , in info ) ;
1316+ pipeline = SDL . SDL_CreateGPUGraphicsPipeline ( device , in info ) ;
12481317
1249- graphicsPipelines . Add ( hash , pipeline ) ;
1318+ graphicsPipelines . Add ( hash , pipeline ) ;
1319+ }
12501320 }
12511321 }
12521322 }
@@ -1262,7 +1332,9 @@ instance.program is not SDLGPUShaderProgram shader ||
12621332
12631333 public void Render ( RenderState state )
12641334 {
1265- if ( state . shader == null ||
1335+ state . renderTarget = currentRenderTarget ;
1336+
1337+ if ( state . shader == null ||
12661338 state . shaderVariant == null ||
12671339 state . shader . instances . TryGetValue ( state . shaderVariant , out var instance ) == false ||
12681340 instance . program is not SDLGPUShaderProgram shader ||
@@ -1343,6 +1415,8 @@ state.indexBuffer is not SDLGPUIndexBuffer index ||
13431415 public void RenderTransient < T > ( Span < T > vertices , VertexLayout layout , Span < ushort > indices , RenderState state )
13441416 where T : unmanaged
13451417 {
1418+ state . renderTarget = currentRenderTarget ;
1419+
13461420 if ( layout is not SDLGPUVertexLayout vertexLayout ||
13471421 state . shaderVariant == null ||
13481422 state . shader == null ||
@@ -1484,6 +1558,8 @@ instance.program is not SDLGPUShaderProgram shader ||
14841558 public void RenderTransient < T > ( Span < T > vertices , VertexLayout layout , Span < uint > indices , RenderState state )
14851559 where T : unmanaged
14861560 {
1561+ state . renderTarget = currentRenderTarget ;
1562+
14871563 if ( layout is not SDLGPUVertexLayout vertexLayout ||
14881564 state . shaderVariant == null ||
14891565 state . shader == null ||
0 commit comments