Null: implement fake async BufferMapRead
We want to test BufferMapRead validation using the null backend. To get closer to conditions on a real backend, we call the callback only on the next Queue::Submit. This is because on real backends, we would have to wait for the GPU to be finished with the buffer, to be sure the correct data is read.
This commit is contained in:
parent
c863b1c26f
commit
43bfaae340
|
@ -89,6 +89,13 @@ namespace null {
|
|||
return new TextureViewBase(builder);
|
||||
}
|
||||
|
||||
void Device::AddPendingOperation(std::unique_ptr<PendingOperation> operation) {
|
||||
pendingOperations.emplace_back(std::move(operation));
|
||||
}
|
||||
std::vector<std::unique_ptr<PendingOperation>> Device::AcquirePendingOperations() {
|
||||
return std::move(pendingOperations);
|
||||
}
|
||||
|
||||
void Device::Reference() {
|
||||
}
|
||||
|
||||
|
@ -97,22 +104,49 @@ namespace null {
|
|||
|
||||
// Buffer
|
||||
|
||||
struct BufferMapReadOperation : PendingOperation {
|
||||
virtual void Execute() {
|
||||
buffer->MapReadOperationCompleted(serial, ptr);
|
||||
}
|
||||
|
||||
Ref<Buffer> buffer;
|
||||
const void* ptr;
|
||||
uint32_t serial;
|
||||
};
|
||||
|
||||
Buffer::Buffer(BufferBuilder* builder)
|
||||
: BufferBase(builder) {
|
||||
if (GetAllowedUsage() & (nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::MapWrite)) {
|
||||
backingData = std::unique_ptr<char[]>(new char[GetSize()]);
|
||||
}
|
||||
}
|
||||
|
||||
Buffer::~Buffer() {
|
||||
}
|
||||
|
||||
void Buffer::MapReadOperationCompleted(uint32_t serial, const void* ptr) {
|
||||
CallMapReadCallback(serial, NXT_BUFFER_MAP_READ_STATUS_SUCCESS, ptr);
|
||||
}
|
||||
|
||||
void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) {
|
||||
ASSERT(start + count <= GetSize());
|
||||
ASSERT(backingData);
|
||||
memcpy(backingData.get() + start, data, count);
|
||||
}
|
||||
|
||||
void Buffer::MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) {
|
||||
// TODO(cwallez@chromium.org): Implement Map Read for the null backend
|
||||
ASSERT(start + count <= GetSize());
|
||||
ASSERT(backingData);
|
||||
|
||||
auto operation = new BufferMapReadOperation;
|
||||
operation->buffer = this;
|
||||
operation->ptr = backingData.get() + start;
|
||||
operation->serial = serial;
|
||||
|
||||
ToBackend(GetDevice())->AddPendingOperation(std::unique_ptr<PendingOperation>(operation));
|
||||
}
|
||||
|
||||
void Buffer::UnmapImpl() {
|
||||
// TODO(cwallez@chromium.org): Implement Map Read for the null backend
|
||||
}
|
||||
|
||||
// Queue
|
||||
|
@ -125,6 +159,13 @@ namespace null {
|
|||
}
|
||||
|
||||
void Queue::Submit(uint32_t numCommands, CommandBuffer* const * commands) {
|
||||
auto operations = ToBackend(GetDevice())->AcquirePendingOperations();
|
||||
|
||||
for (auto& operation : operations) {
|
||||
operation->Execute();
|
||||
}
|
||||
|
||||
operations.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -80,6 +80,11 @@ namespace null {
|
|||
return ToBackendBase<NullBackendTraits>(common);
|
||||
}
|
||||
|
||||
struct PendingOperation {
|
||||
virtual ~PendingOperation() = default;
|
||||
virtual void Execute() = 0;
|
||||
};
|
||||
|
||||
class Device : public DeviceBase {
|
||||
public:
|
||||
Device();
|
||||
|
@ -102,9 +107,15 @@ namespace null {
|
|||
TextureBase* CreateTexture(TextureBuilder* builder) override;
|
||||
TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override;
|
||||
|
||||
void AddPendingOperation(std::unique_ptr<PendingOperation> operation);
|
||||
std::vector<std::unique_ptr<PendingOperation>> AcquirePendingOperations();
|
||||
|
||||
// NXT API
|
||||
void Reference();
|
||||
void Release();
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<PendingOperation>> pendingOperations;
|
||||
};
|
||||
|
||||
class Buffer : public BufferBase {
|
||||
|
@ -112,10 +123,14 @@ namespace null {
|
|||
Buffer(BufferBuilder* builder);
|
||||
~Buffer();
|
||||
|
||||
void MapReadOperationCompleted(uint32_t serial, const void* ptr);
|
||||
|
||||
private:
|
||||
void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override;
|
||||
void MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) override;
|
||||
void UnmapImpl() override;
|
||||
|
||||
std::unique_ptr<char[]> backingData;
|
||||
};
|
||||
|
||||
class Queue : public QueueBase {
|
||||
|
|
Loading…
Reference in New Issue