diff --git a/Source/Engine/Graphics/Models/Mesh.cpp b/Source/Engine/Graphics/Models/Mesh.cpp index e7007f4ec..8285883ae 100644 --- a/Source/Engine/Graphics/Models/Mesh.cpp +++ b/Source/Engine/Graphics/Models/Mesh.cpp @@ -359,8 +359,8 @@ void Mesh::GetDrawCallGeometry(DrawCall& drawCall) const drawCall.Geometry.VertexBuffersOffsets[0] = 0; drawCall.Geometry.VertexBuffersOffsets[1] = 0; drawCall.Geometry.VertexBuffersOffsets[2] = 0; - drawCall.Geometry.StartIndex = 0; - drawCall.Geometry.IndicesCount = _triangles * 3; + drawCall.Draw.StartIndex = 0; + drawCall.Draw.IndicesCount = _triangles * 3; } void Mesh::Render(GPUContext* context) const @@ -386,11 +386,9 @@ void Mesh::Draw(const RenderContext& renderContext, MaterialBase* material, cons drawCall.Geometry.VertexBuffersOffsets[0] = 0; drawCall.Geometry.VertexBuffersOffsets[1] = 0; drawCall.Geometry.VertexBuffersOffsets[2] = 0; - drawCall.Geometry.StartIndex = 0; - drawCall.Geometry.IndicesCount = _triangles * 3; + drawCall.Draw.StartIndex = 0; + drawCall.Draw.IndicesCount = _triangles * 3; drawCall.InstanceCount = 1; - drawCall.IndirectArgsBuffer = nullptr; - drawCall.IndirectArgsOffset = 0; drawCall.Material = material; drawCall.World = world; drawCall.ObjectPosition = drawCall.World.GetTranslation(); @@ -449,11 +447,9 @@ void Mesh::Draw(const RenderContext& renderContext, const DrawInfo& info, float drawCall.Geometry.VertexBuffers[2] = info.VertexColors[_lodIndex]; drawCall.Geometry.VertexBuffersOffsets[2] = vertexOffset * sizeof(VB2ElementType); } - drawCall.Geometry.StartIndex = 0; - drawCall.Geometry.IndicesCount = _triangles * 3; + drawCall.Draw.StartIndex = 0; + drawCall.Draw.IndicesCount = _triangles * 3; drawCall.InstanceCount = 1; - drawCall.IndirectArgsBuffer = nullptr; - drawCall.IndirectArgsOffset = 0; drawCall.Material = material; drawCall.World = *info.World; drawCall.ObjectPosition = drawCall.World.GetTranslation(); diff --git a/Source/Engine/Graphics/Models/SkinnedMesh.cpp b/Source/Engine/Graphics/Models/SkinnedMesh.cpp index e9e7f8438..9e26867ab 100644 --- a/Source/Engine/Graphics/Models/SkinnedMesh.cpp +++ b/Source/Engine/Graphics/Models/SkinnedMesh.cpp @@ -186,11 +186,9 @@ void SkinnedMesh::Draw(const RenderContext& renderContext, const DrawInfo& info, drawCall.Geometry.VertexBuffersOffsets[0] = 0; drawCall.Geometry.VertexBuffersOffsets[1] = 0; drawCall.Geometry.VertexBuffersOffsets[2] = 0; - drawCall.Geometry.StartIndex = 0; - drawCall.Geometry.IndicesCount = _triangles * 3; + drawCall.Draw.StartIndex = 0; + drawCall.Draw.IndicesCount = _triangles * 3; drawCall.InstanceCount = 1; - drawCall.IndirectArgsBuffer = nullptr; - drawCall.IndirectArgsOffset = 0; drawCall.Material = material; drawCall.World = *info.World; drawCall.ObjectPosition = drawCall.World.GetTranslation(); diff --git a/Source/Engine/Level/Actors/SplineModel.cpp b/Source/Engine/Level/Actors/SplineModel.cpp index 2a0972ffa..01118ba6a 100644 --- a/Source/Engine/Level/Actors/SplineModel.cpp +++ b/Source/Engine/Level/Actors/SplineModel.cpp @@ -353,8 +353,6 @@ void SplineModel::Draw(RenderContext& renderContext) // Draw all segments DrawCall drawCall; drawCall.InstanceCount = 1; - drawCall.IndirectArgsBuffer = nullptr; - drawCall.IndirectArgsOffset = 0; drawCall.Deformable.SplineDeformation = _deformationBuffer; drawCall.Deformable.ChunksPerSegment = _chunksPerSegment; drawCall.Deformable.MeshMinZ = _meshMinZ; diff --git a/Source/Engine/Particles/ParticleManager.cpp b/Source/Engine/Particles/ParticleManager.cpp index 429420950..f2e70fee3 100644 --- a/Source/Engine/Particles/ParticleManager.cpp +++ b/Source/Engine/Particles/ParticleManager.cpp @@ -83,8 +83,8 @@ public: drawCall.Geometry.VertexBuffersOffsets[0] = 0; drawCall.Geometry.VertexBuffersOffsets[1] = 0; drawCall.Geometry.VertexBuffersOffsets[2] = 0; - drawCall.Geometry.StartIndex = 0; - drawCall.Geometry.IndicesCount = IndexCount; + drawCall.Draw.StartIndex = 0; + drawCall.Draw.IndicesCount = IndexCount; } }; @@ -173,10 +173,6 @@ void DrawEmitterCPU(RenderContext& renderContext, ParticleBuffer* buffer, DrawCa const auto context = GPUDevice::Instance->GetMainContext(); auto emitter = buffer->Emitter; - drawCall.InstanceCount = 1; - drawCall.IndirectArgsBuffer = nullptr; - drawCall.IndirectArgsOffset = 0; - // Check if need to perform any particles sorting if (emitter->Graph.SortModules.HasItems() && renderContext.View.Pass != DrawPass::Depth) { @@ -516,8 +512,8 @@ void DrawEmitterCPU(RenderContext& renderContext, ParticleBuffer* buffer, DrawCa drawCall.Geometry.VertexBuffersOffsets[0] = 0; drawCall.Geometry.VertexBuffersOffsets[1] = 0; drawCall.Geometry.VertexBuffersOffsets[2] = 0; - drawCall.Geometry.StartIndex = ribbonModulesDrawIndicesStart[ribbonModuleIndex]; - drawCall.Geometry.IndicesCount = ribbonModulesDrawIndicesCount[ribbonModuleIndex]; + drawCall.Draw.StartIndex = ribbonModulesDrawIndicesStart[ribbonModuleIndex]; + drawCall.Draw.IndicesCount = ribbonModulesDrawIndicesCount[ribbonModuleIndex]; drawCall.InstanceCount = 1; renderContext.List->AddDrawCall((DrawPass)(drawModes & moduleDrawModes), staticFlags, drawCall, false); @@ -802,8 +798,8 @@ void DrawEmitterGPU(RenderContext& renderContext, ParticleBuffer* buffer, DrawCa // Submit draw call SpriteRenderer.SetupDrawCall(drawCall); drawCall.InstanceCount = 0; - drawCall.IndirectArgsBuffer = buffer->GPU.IndirectDrawArgsBuffer; - drawCall.IndirectArgsOffset = indirectDrawCallIndex * sizeof(GPUDrawIndexedIndirectArgs); + drawCall.Draw.IndirectArgsBuffer = buffer->GPU.IndirectDrawArgsBuffer; + drawCall.Draw.IndirectArgsOffset = indirectDrawCallIndex * sizeof(GPUDrawIndexedIndirectArgs); renderContext.List->AddDrawCall((DrawPass)(drawModes & moduleDrawModes), staticFlags, drawCall, false); indirectDrawCallIndex++; @@ -830,8 +826,8 @@ void DrawEmitterGPU(RenderContext& renderContext, ParticleBuffer* buffer, DrawCa // Execute draw call mesh.GetDrawCallGeometry(drawCall); drawCall.InstanceCount = 0; - drawCall.IndirectArgsBuffer = buffer->GPU.IndirectDrawArgsBuffer; - drawCall.IndirectArgsOffset = indirectDrawCallIndex * sizeof(GPUDrawIndexedIndirectArgs); + drawCall.Draw.IndirectArgsBuffer = buffer->GPU.IndirectDrawArgsBuffer; + drawCall.Draw.IndirectArgsOffset = indirectDrawCallIndex * sizeof(GPUDrawIndexedIndirectArgs); renderContext.List->AddDrawCall((DrawPass)(drawModes & moduleDrawModes), staticFlags, drawCall, false); indirectDrawCallIndex++; } diff --git a/Source/Engine/Renderer/DrawCall.h b/Source/Engine/Renderer/DrawCall.h index bb25c0a57..036ba26bd 100644 --- a/Source/Engine/Renderer/DrawCall.h +++ b/Source/Engine/Renderer/DrawCall.h @@ -134,16 +134,6 @@ struct DrawCall /// The geometry vertex buffers byte offsets. /// uint32 VertexBuffersOffsets[3]; - - /// - /// The location of the first index read by the GPU from the index buffer. - /// - int32 StartIndex; - - /// - /// The indices count. - /// - int32 IndicesCount; } Geometry; /// @@ -151,15 +141,34 @@ struct DrawCall /// int32 InstanceCount; - /// - /// The indirect draw arguments offset. - /// - uint32 IndirectArgsOffset; + union + { + struct + { + /// + /// The location of the first index read by the GPU from the index buffer. + /// + int32 StartIndex; - /// - /// The indirect draw arguments buffer. - /// - GPUBuffer* IndirectArgsBuffer; + /// + /// The indices count. + /// + int32 IndicesCount; + }; + + struct + { + /// + /// The indirect draw arguments offset. + /// + uint32 IndirectArgsOffset; + + /// + /// The indirect draw arguments buffer. + /// + GPUBuffer* IndirectArgsBuffer; + }; + } Draw; // Per-material shader data packed into union union diff --git a/Source/Engine/Renderer/RenderList.cpp b/Source/Engine/Renderer/RenderList.cpp index dd711a5e0..7056e8737 100644 --- a/Source/Engine/Renderer/RenderList.cpp +++ b/Source/Engine/Renderer/RenderList.cpp @@ -514,8 +514,8 @@ namespace return a.Material == b.Material && a.Material->CanUseInstancing(handler) && Platform::MemoryCompare(&a.Geometry, &b.Geometry, sizeof(a.Geometry)) == 0 && - a.IndirectArgsBuffer == nullptr && - b.IndirectArgsBuffer == nullptr && + a.InstanceCount != 0 && + b.InstanceCount != 0 && a.WorldDeterminantSign == b.WorldDeterminantSign; } } @@ -690,20 +690,20 @@ DRAW: context->BindIB(drawCall.Geometry.IndexBuffer); - if (drawCall.IndirectArgsBuffer) + if (drawCall.InstanceCount == 0) { // No support for batching indirect draw calls ASSERT(batch.BatchSize == 1); context->BindVB(ToSpan(vb, vbCount), vbOffsets); - context->DrawIndexedInstancedIndirect(drawCall.IndirectArgsBuffer, drawCall.IndirectArgsOffset); + context->DrawIndexedInstancedIndirect(drawCall.Draw.IndirectArgsBuffer, drawCall.Draw.IndirectArgsOffset); } else { if (batch.BatchSize == 1) { context->BindVB(ToSpan(vb, vbCount), vbOffsets); - context->DrawIndexedInstanced(drawCall.Geometry.IndicesCount, batch.InstanceCount, 0, 0, drawCall.Geometry.StartIndex); + context->DrawIndexedInstanced(drawCall.Draw.IndicesCount, batch.InstanceCount, 0, 0, drawCall.Draw.StartIndex); } else { @@ -712,7 +712,7 @@ DRAW: vbOffsets[vbCount] = 0; vbCount++; context->BindVB(ToSpan(vb, vbCount), vbOffsets); - context->DrawIndexedInstanced(drawCall.Geometry.IndicesCount, batch.InstanceCount, instanceBufferOffset, 0, drawCall.Geometry.StartIndex); + context->DrawIndexedInstanced(drawCall.Draw.IndicesCount, batch.InstanceCount, instanceBufferOffset, 0, drawCall.Draw.StartIndex); instanceBufferOffset += batch.BatchSize; } @@ -735,13 +735,13 @@ DRAW: context->BindIB(drawCall.Geometry.IndexBuffer); context->BindVB(ToSpan(drawCall.Geometry.VertexBuffers, 3), drawCall.Geometry.VertexBuffersOffsets); - if (drawCall.IndirectArgsBuffer) + if (drawCall.InstanceCount == 0) { - context->DrawIndexedInstancedIndirect(drawCall.IndirectArgsBuffer, drawCall.IndirectArgsOffset); + context->DrawIndexedInstancedIndirect(drawCall.Draw.IndirectArgsBuffer, drawCall.Draw.IndirectArgsOffset); } else { - context->DrawIndexedInstanced(drawCall.Geometry.IndicesCount, drawCall.InstanceCount, 0, 0, drawCall.Geometry.StartIndex); + context->DrawIndexedInstanced(drawCall.Draw.IndicesCount, drawCall.InstanceCount, 0, 0, drawCall.Draw.StartIndex); } } } diff --git a/Source/Engine/ShadowsOfMordor/Builder.Jobs.cpp b/Source/Engine/ShadowsOfMordor/Builder.Jobs.cpp index 7ec466eee..20c2fb325 100644 --- a/Source/Engine/ShadowsOfMordor/Builder.Jobs.cpp +++ b/Source/Engine/ShadowsOfMordor/Builder.Jobs.cpp @@ -173,7 +173,7 @@ void ShadowsOfMordor::Builder::onJobRender(GPUContext* context) context->SetState(_psRenderCacheTerrain); context->BindIB(drawCall.Geometry.IndexBuffer); context->BindVB(ToSpan(drawCall.Geometry.VertexBuffers, 1)); - context->DrawIndexed(drawCall.Geometry.IndicesCount, 0, drawCall.Geometry.StartIndex); + context->DrawIndexed(drawCall.Draw.IndicesCount, 0, drawCall.Draw.StartIndex); break; } diff --git a/Source/Engine/Terrain/TerrainChunk.cpp b/Source/Engine/Terrain/TerrainChunk.cpp index 63a7bb04a..08e5946ee 100644 --- a/Source/Engine/Terrain/TerrainChunk.cpp +++ b/Source/Engine/Terrain/TerrainChunk.cpp @@ -83,8 +83,6 @@ void TerrainChunk::Draw(const RenderContext& renderContext) const if (TerrainManager::GetChunkGeometry(drawCall, chunkSize, lod)) return; drawCall.InstanceCount = 1; - drawCall.IndirectArgsBuffer = nullptr; - drawCall.IndirectArgsOffset = 0; drawCall.Material = _cachedDrawMaterial; drawCall.World = _world; drawCall.ObjectPosition = drawCall.World.GetTranslation(); @@ -140,8 +138,6 @@ void TerrainChunk::Draw(const RenderContext& renderContext, MaterialBase* materi if (TerrainManager::GetChunkGeometry(drawCall, chunkSize, lod)) return; drawCall.InstanceCount = 1; - drawCall.IndirectArgsBuffer = nullptr; - drawCall.IndirectArgsOffset = 0; drawCall.Material = material; drawCall.World = _world; drawCall.ObjectPosition = drawCall.World.GetTranslation(); diff --git a/Source/Engine/Terrain/TerrainManager.cpp b/Source/Engine/Terrain/TerrainManager.cpp index 0638acd45..caf620ff0 100644 --- a/Source/Engine/Terrain/TerrainManager.cpp +++ b/Source/Engine/Terrain/TerrainManager.cpp @@ -37,8 +37,8 @@ public: drawCall.Geometry.VertexBuffersOffsets[0] = 0; drawCall.Geometry.VertexBuffersOffsets[1] = 0; drawCall.Geometry.VertexBuffersOffsets[2] = 0; - drawCall.Geometry.StartIndex = 0; - drawCall.Geometry.IndicesCount = IndicesCount; + drawCall.Draw.StartIndex = 0; + drawCall.Draw.IndicesCount = IndicesCount; } }; diff --git a/Source/Engine/UI/TextRender.cpp b/Source/Engine/UI/TextRender.cpp index 5707b4461..8e00c2cc3 100644 --- a/Source/Engine/UI/TextRender.cpp +++ b/Source/Engine/UI/TextRender.cpp @@ -336,14 +336,12 @@ void TextRender::Draw(RenderContext& renderContext) drawCall.Geometry.VertexBuffersOffsets[1] = 0; drawCall.Geometry.VertexBuffersOffsets[2] = 0; drawCall.InstanceCount = 1; - drawCall.IndirectArgsBuffer = nullptr; - drawCall.IndirectArgsOffset = 0; // Submit draw calls for (const auto& e : _drawChunks) { - drawCall.Geometry.IndicesCount = e.IndicesCount; - drawCall.Geometry.StartIndex = e.StartIndex; + drawCall.Draw.IndicesCount = e.IndicesCount; + drawCall.Draw.StartIndex = e.StartIndex; drawCall.Material = e.Material; renderContext.List->AddDrawCall(drawModes, GetStaticFlags(), drawCall, true); }