From cba2231977d24ee78dfc8b28a77fb4528d9559b3 Mon Sep 17 00:00:00 2001 From: bernatx Date: Fri, 13 Jan 2023 16:27:25 +0100 Subject: [PATCH] texture data on DirectX has some extra bytes that we need to remove before sending data --- .../Source/Carla/Sensor/AsyncDataStream.h | 2 +- .../Carla/Source/Carla/Sensor/PixelReader.cpp | 24 +----------- .../Carla/Source/Carla/Sensor/PixelReader.h | 38 ++++++++++++++++++- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/AsyncDataStream.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/AsyncDataStream.h index 33b832364..e96a0b859 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/AsyncDataStream.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/AsyncDataStream.h @@ -66,7 +66,7 @@ public: { if (HeaderStr->frame != FrameNumber) { - carla::log_debug("Re-framing sensor type ", HeaderStr->sensor_type, " from ", HeaderStr->frame, " to ", FrameNumber); + carla::log_info("Re-framing sensor type ", HeaderStr->sensor_type, " from ", HeaderStr->frame, " to ", FrameNumber); HeaderStr->frame = FrameNumber; } } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp index 1764ac419..7da6424b4 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp @@ -12,27 +12,6 @@ #include "HighResScreenshot.h" #include "Runtime/ImageWriteQueue/Public/ImageWriteQueue.h" -// ============================================================================= -// -- Local variables and types ------------------------------------------------ -// ============================================================================= - -struct LockTexture -{ - LockTexture(FRHITexture2D *InTexture, uint32 &Stride) - : Texture(InTexture), - Source(reinterpret_cast( - RHILockTexture2D(Texture, 0, RLM_ReadOnly, Stride, false))) {} - - ~LockTexture() - { - RHIUnlockTexture2D(Texture, 0, false); - } - - FRHITexture2D *Texture; - - const uint8 *Source; -}; - // ============================================================================= // -- FPixelReader ------------------------------------------------------------- // ============================================================================= @@ -86,11 +65,12 @@ void FPixelReader::WritePixelsToBuffer( } FPixelFormatInfo PixelFormat = GPixelFormats[BackBufferPixelFormat]; + uint32 ExpectedRowBytes = BackBufferSize.X * PixelFormat.BlockBytes; int32 Size = (BackBufferSize.Y * (PixelFormat.BlockBytes * BackBufferSize.X)); void* LockedData = Readback->Lock(Size); if (LockedData) { - FuncForSending(LockedData, Size, Offset); + FuncForSending(LockedData, Size, Offset, ExpectedRowBytes); } Readback->Unlock(); Readback.reset(); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.h index ca6578393..962374cea 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.h @@ -10,6 +10,11 @@ #include "Engine/TextureRenderTarget2D.h" #include "Runtime/ImageWriteQueue/Public/ImagePixelData.h" +#ifdef PLATFORM_WINDOWS + #define WIN32_LEAN_AND_MEAN + #include +#endif + #include "Carla/Game/CarlaEngine.h" #include @@ -29,7 +34,7 @@ class FPixelReader { public: - using Payload = std::function; + using Payload = std::function; /// Copy the pixels in @a RenderTarget into @a BitMap. /// @@ -111,7 +116,7 @@ void FPixelReader::SendPixelsInRenderThread(TSensor &Sensor, bool use16BitFormat if (!Sensor.IsPendingKill()) { FPixelReader::Payload FuncForSending = - [&Sensor, Frame = FCarlaEngine::GetFrameCounter(), Conversor = std::move(Conversor)](void *LockedData, uint32 Size, uint32 Offset) + [&Sensor, Frame = FCarlaEngine::GetFrameCounter(), Conversor = std::move(Conversor)](void *LockedData, uint32 Size, uint32 Offset, uint32 ExpectedRowBytes) { if (Sensor.IsPendingKill()) return; @@ -129,11 +134,40 @@ void FPixelReader::SendPixelsInRenderThread(TSensor &Sensor, bool use16BitFormat auto Stream = Sensor.GetDataStream(Sensor); Stream.SetFrameNumber(Frame); auto Buffer = Stream.PopBufferFromPool(); + + uint32 CurrentRowBytes = ExpectedRowBytes; +#ifdef PLATFORM_WINDOWS + // DirectX uses additional bytes to align each row to 256 boundry, + // so we need to remove that extra data + if (IsD3DPlatform(GMaxRHIShaderPlatform, false)) { + CurrentRowBytes = Align(ExpectedRowBytes, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); + if (ExpectedRowBytes != CurrentRowBytes) + { + TRACE_CPUPROFILER_EVENT_SCOPE_STR("Buffer Copy (windows, row by row)"); + Buffer.reset(Offset + Size); + auto DstRow = Buffer.begin() + Offset; + const uint8 *SrcRow = reinterpret_cast(LockedData); + uint32 i = 0; + while (i < Size) + { + FMemory::Memcpy(DstRow, SrcRow, ExpectedRowBytes); + DstRow += ExpectedRowBytes; + SrcRow += CurrentRowBytes; + i += ExpectedRowBytes; + } + } + } +#endif // PLATFORM_WINDOWS + + if (ExpectedRowBytes == CurrentRowBytes) + { + check(ExpectedRowBytes == CurrentRowBytes); TRACE_CPUPROFILER_EVENT_SCOPE_STR("Buffer Copy"); Buffer.copy_from(Offset, boost::asio::buffer(LockedData, Size)); } + { // send TRACE_CPUPROFILER_EVENT_SCOPE_STR("Sending buffer");