/Engine/Source/Runtime/SlateRHIRenderer/Private/SlateUpdatableBuffer.cpp

https://github.com/windystrife/UnrealEngine_NVIDIAGameWorks · C++ · 106 lines · 80 code · 24 blank · 2 comment · 4 complexity · 280cc9aa99934888db1e0109c0c31282 MD5 · raw file

  1. // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
  2. #include "SlateUpdatableBuffer.h"
  3. #include "RenderingThread.h"
  4. DECLARE_CYCLE_STAT(TEXT("UpdateInstanceBuffer Time"), STAT_SlateUpdateInstanceBuffer, STATGROUP_Slate);
  5. struct FSlateUpdateInstanceBufferCommand : public FRHICommand<FSlateUpdateInstanceBufferCommand>
  6. {
  7. FVertexBufferRHIRef VertexBufferRHI;
  8. const TArray<FVector4>& InstanceData;
  9. FSlateUpdateInstanceBufferCommand(TSlateElementVertexBuffer<FVector4>& InInstanceBuffer, const TArray<FVector4>& InInstanceData )
  10. : VertexBufferRHI(InInstanceBuffer.VertexBufferRHI)
  11. , InstanceData(InInstanceData)
  12. {}
  13. void Execute(FRHICommandListBase& CmdList)
  14. {
  15. SCOPE_CYCLE_COUNTER( STAT_SlateUpdateInstanceBuffer );
  16. int32 RequiredVertexBufferSize = InstanceData.Num()*sizeof(FVector4);
  17. uint8* InstanceBufferData = (uint8*)GDynamicRHI->RHILockVertexBuffer( VertexBufferRHI, 0, RequiredVertexBufferSize, RLM_WriteOnly );
  18. FMemory::Memcpy( InstanceBufferData, InstanceData.GetData(), InstanceData.Num()*sizeof(FVector4) );
  19. GDynamicRHI->RHIUnlockVertexBuffer( VertexBufferRHI );
  20. }
  21. };
  22. FSlateUpdatableInstanceBuffer::FSlateUpdatableInstanceBuffer( int32 InitialInstanceCount )
  23. : FreeBufferIndex(0)
  24. {
  25. InstanceBufferResource.Init(InitialInstanceCount);
  26. for( int32 BufferIndex = 0; BufferIndex < SlateRHIConstants::NumBuffers; ++BufferIndex )
  27. {
  28. BufferData[BufferIndex].Reserve( InitialInstanceCount );
  29. }
  30. }
  31. FSlateUpdatableInstanceBuffer::~FSlateUpdatableInstanceBuffer()
  32. {
  33. InstanceBufferResource.Destroy();
  34. FlushRenderingCommands();
  35. }
  36. void FSlateUpdatableInstanceBuffer::BindStreamSource(FRHICommandListImmediate& RHICmdList, int32 StreamIndex, uint32 InstanceOffset)
  37. {
  38. RHICmdList.SetStreamSource(StreamIndex, InstanceBufferResource.VertexBufferRHI, InstanceOffset*sizeof(FVector4));
  39. }
  40. TSharedPtr<class FSlateInstanceBufferUpdate> FSlateUpdatableInstanceBuffer::BeginUpdate()
  41. {
  42. return MakeShareable(new FSlateInstanceBufferUpdate(*this));
  43. }
  44. uint32 FSlateUpdatableInstanceBuffer::GetNumInstances() const
  45. {
  46. return NumInstances;
  47. }
  48. void FSlateUpdatableInstanceBuffer::UpdateRenderingData(int32 NumInstancesToUse)
  49. {
  50. NumInstances = NumInstancesToUse;
  51. if (NumInstances > 0)
  52. {
  53. // Enqueue a command to unlock the draw buffer after all windows have been drawn
  54. ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER( SlateBeginDrawingWindowsCommand,
  55. FSlateUpdatableInstanceBuffer&, Self, *this,
  56. int32, BufferIndex, FreeBufferIndex,
  57. {
  58. Self.UpdateRenderingData_RenderThread(RHICmdList, BufferIndex);
  59. });
  60. FreeBufferIndex = (FreeBufferIndex + 1) % SlateRHIConstants::NumBuffers;
  61. }
  62. }
  63. TArray<FVector4>& FSlateUpdatableInstanceBuffer::GetBufferData()
  64. {
  65. return BufferData[FreeBufferIndex];
  66. }
  67. void FSlateUpdatableInstanceBuffer::UpdateRenderingData_RenderThread(FRHICommandListImmediate& RHICmdList, int32 BufferIndex)
  68. {
  69. SCOPE_CYCLE_COUNTER( STAT_SlateUpdateInstanceBuffer );
  70. const TArray<FVector4>& RenderThreadBufferData = BufferData[BufferIndex];
  71. InstanceBufferResource.PreFillBuffer( RenderThreadBufferData.Num(), false );
  72. if(!IsRunningRHIInSeparateThread() || RHICmdList.Bypass())
  73. {
  74. uint8* InstanceBufferData = (uint8*)InstanceBufferResource.LockBuffer_RenderThread(RenderThreadBufferData.Num());
  75. FMemory::Memcpy(InstanceBufferData, RenderThreadBufferData.GetData(), RenderThreadBufferData.Num()*sizeof(FVector4) );
  76. InstanceBufferResource.UnlockBuffer_RenderThread();
  77. }
  78. else
  79. {
  80. new (RHICmdList.AllocCommand<FSlateUpdateInstanceBufferCommand>()) FSlateUpdateInstanceBufferCommand(InstanceBufferResource, RenderThreadBufferData);
  81. }
  82. }