|
1 | | -using System.Runtime.CompilerServices; |
| 1 | +using System.Diagnostics; |
| 2 | +using System.Runtime.CompilerServices; |
2 | 3 | using System.Runtime.InteropServices; |
3 | 4 | using Coplt.Graphics.Native; |
4 | 5 |
|
@@ -28,6 +29,7 @@ public sealed unsafe class CommandList |
28 | 29 | internal readonly HashSet<object> m_objects = new(); |
29 | 30 | internal readonly List<byte> m_payload = new(); |
30 | 31 | internal GpuOutput? m_current_output; |
| 32 | + internal ShaderPipeline? m_current_pipeline; |
31 | 33 |
|
32 | 34 | #endregion |
33 | 35 |
|
@@ -337,7 +339,7 @@ public void SetViewportScissor( |
337 | 339 |
|
338 | 340 | public void SetPipeline(ShaderPipeline Pipeline, CommandFlags Flags = CommandFlags.None) |
339 | 341 | { |
340 | | - AddObject(Pipeline); |
| 342 | + AddObject(m_current_pipeline = Pipeline); |
341 | 343 | var cmd = new FCommandSetPipeline |
342 | 344 | { |
343 | 345 | Pipeline = Pipeline.m_ptr, |
@@ -425,6 +427,14 @@ public void SetMeshBuffers( |
425 | 427 | SetMeshBuffers = cmd, |
426 | 428 | } |
427 | 429 | ); |
| 430 | + if (IndexBuffer.HasValue) |
| 431 | + { |
| 432 | + IndexBuffer.Value.Buffer.UnsafeChangeState(FResourceState.IndexBuffer); |
| 433 | + } |
| 434 | + foreach (var buffer in VertexBuffers) |
| 435 | + { |
| 436 | + buffer.Buffer.UnsafeChangeState(FResourceState.VertexBuffer); |
| 437 | + } |
428 | 438 | } |
429 | 439 |
|
430 | 440 | #endregion |
@@ -466,10 +476,17 @@ public void Draw( |
466 | 476 | { |
467 | 477 | if (Pipeline != null) |
468 | 478 | { |
| 479 | + m_current_pipeline = Pipeline; |
469 | 480 | if (!Pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Vertex)) |
470 | 481 | throw new ArgumentException("Non Vertex pipelines cannot use Draw"); |
471 | 482 | AddObject(Pipeline); |
472 | 483 | } |
| 484 | + else |
| 485 | + { |
| 486 | + if (m_current_pipeline == null) throw new InvalidOperationException("Pipeline is not set"); |
| 487 | + if (!m_current_pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Vertex)) |
| 488 | + throw new ArgumentException("Non Vertex pipelines cannot use Draw"); |
| 489 | + } |
473 | 490 | var cmd = new FCommandDraw |
474 | 491 | { |
475 | 492 | Pipeline = Pipeline == null ? null : Pipeline.m_ptr, |
@@ -518,17 +535,42 @@ public void Dispatch( |
518 | 535 | { |
519 | 536 | if (Pipeline != null) |
520 | 537 | { |
| 538 | + m_current_pipeline = Pipeline; |
521 | 539 | if (!Pipeline.Shader.Stages.HasAnyFlags(ShaderStageFlags.Compute | ShaderStageFlags.Mesh)) |
522 | 540 | throw new ArgumentException("Non Mesh and Compute pipelines cannot use Dispatch"); |
523 | 541 | AddObject(Pipeline); |
| 542 | + if (Type == DispatchType.Auto) |
| 543 | + { |
| 544 | + if (Pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Compute)) Type = DispatchType.Compute; |
| 545 | + else if (Pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Mesh)) Type = DispatchType.Mesh; |
| 546 | + else throw new UnreachableException(); |
| 547 | + } |
| 548 | + } |
| 549 | + else |
| 550 | + { |
| 551 | + if (m_current_pipeline == null) throw new InvalidOperationException("Pipeline is not set"); |
| 552 | + if (!m_current_pipeline.Shader.Stages.HasAnyFlags(ShaderStageFlags.Compute | ShaderStageFlags.Mesh)) |
| 553 | + throw new ArgumentException("Non Mesh and Compute pipelines cannot use Dispatch"); |
| 554 | + if (Type == DispatchType.Auto) |
| 555 | + { |
| 556 | + if (m_current_pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Compute)) Type = DispatchType.Compute; |
| 557 | + else if (m_current_pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Mesh)) Type = DispatchType.Mesh; |
| 558 | + else throw new UnreachableException(); |
| 559 | + } |
524 | 560 | } |
525 | 561 | var cmd = new FCommandDispatch |
526 | 562 | { |
527 | 563 | Pipeline = Pipeline == null ? null : Pipeline.m_ptr, |
528 | 564 | GroupCountX = GroupCountX, |
529 | 565 | GroupCountY = GroupCountY, |
530 | 566 | GroupCountZ = GroupCountZ, |
531 | | - Type = (FDispatchType)Type, |
| 567 | + Type = Type switch |
| 568 | + { |
| 569 | + DispatchType.Auto => throw new UnreachableException(), |
| 570 | + DispatchType.Compute => FDispatchType.Compute, |
| 571 | + DispatchType.Mesh => FDispatchType.Mesh, |
| 572 | + _ => throw new ArgumentOutOfRangeException(nameof(Type), Type, null) |
| 573 | + }, |
532 | 574 | }; |
533 | 575 | m_commands.Add( |
534 | 576 | new() |
|
0 commit comments