1#include "ReadbackTask.h"
3#include "Rendering/IGraphicsDevice.h"
4#include "Rendering/IContext.h"
6#include "Foundation/Logging/Logger.h"
8#include "Services/Time.h"
10#include "Renderer/RenderBuffer.h"
11#include "Renderer/RenderList.h"
12#include "Renderer/RenderTarget.h"
21void Cogs::Core::ReadbackTask::apply(RenderTaskContext * renderContext)
23 RenderInstrumentationScope(renderContext->device->getImmediateContext(), SCOPE_RENDERING,
"ReadbackTask::apply");
25 auto device = renderContext->device;
26 auto deviceContext = device->getImmediateContext();
28 if (size > std::numeric_limits<uint32_t>::max()) {
29 LOG_ERROR(logger,
"Invalid readback size %zd.", size.getValue());
33 auto source = input.get(RenderResourceType::RenderBuffer);
36 LOG_ERROR(logger,
"No input resource bound for readback.");
40 auto inputBuffer = source->renderBuffer;
42 if (size > inputBuffer->size) {
43 LOG_ERROR(logger,
"Readback size (%zd) larger than buffer size %zd.", size.getValue(), inputBuffer->size);
47 if (size % inputBuffer->elementSize != 0) {
48 LOG_WARNING(logger,
"Readback size %zd not multiple of input element size %zd.", size.getValue(), inputBuffer->elementSize.getValue());
51 auto bufferHandle = inputBuffer->getHandle(bufferIndex);
54 LOG_ERROR(logger,
"Invalid buffer handle for buffer: %.*s, index: %zd.", StringViewFormat(inputBuffer->getName()), bufferIndex.getValue());
58 auto mappedData = deviceContext->map(bufferHandle,
MapMode::Read);
61 LOG_ERROR(logger,
"Could not map resource for readback.");
65 hostBuffer.resize(size,
false);
66 std::memcpy(hostBuffer.data(), mappedData, size);
67 deviceContext->unmap(bufferHandle);
68 uint32_t frame = inputBuffer->getFrame(bufferIndex);
70 bool published =
false;
71 const auto * list = input.get(RenderResourceType::RenderList);
72 for (
auto it : renderContext->context->callbacks.readbackCallbackInternal) {
73 (*it)(renderContext->context, list ? list->renderList->viewportData :
nullptr, frame, key.data(), hostBuffer.data(), (int)hostBuffer.size());
77 if (renderContext->context->callbacks.readbackCallback) {
78 renderContext->context->callbacks.readbackCallback(renderContext->context, key.data(), hostBuffer.data(), (int)hostBuffer.size());
85 else if (!errorState) {
86 LOG_WARNING(logger,
"Performed readback of %.*s without callback.", StringViewFormat(inputBuffer->getName()));
Log implementation class.
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
constexpr Log getLogger(const char(&name)[LEN]) noexcept