[GL] track buffer usage
With this CL, GL backend and other backends will use the similar way to track buffer usage, so the GL MapAsync(Write) will not synchronize GL commands anymore. Change-Id: I9f8dfeb58faaed09ed62550371a30a680cd607d5 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/118140 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Peng Huang <penghuang@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
fc2083a616
commit
fd1e8a44f2
|
@ -456,11 +456,7 @@ void BufferBase::APIMapAsync(wgpu::MapMode mode,
|
|||
std::make_unique<MapRequestTask>(GetDevice()->GetPlatform(), this, mLastMapID);
|
||||
TRACE_EVENT1(GetDevice()->GetPlatform(), General, "Buffer::APIMapAsync", "serial",
|
||||
uint64_t(mLastUsageSerial));
|
||||
if (mLastUsageSerial != kMaxExecutionSerial) {
|
||||
GetDevice()->GetQueue()->TrackTask(std::move(request), mLastUsageSerial);
|
||||
} else {
|
||||
GetDevice()->GetQueue()->TrackTaskAfterEventualFlush(std::move(request));
|
||||
}
|
||||
GetDevice()->GetQueue()->TrackTask(std::move(request), mLastUsageSerial);
|
||||
}
|
||||
|
||||
void* BufferBase::APIGetMappedRange(size_t offset, size_t size) {
|
||||
|
|
|
@ -39,8 +39,6 @@ ResultOrError<Ref<Buffer>> Buffer::CreateInternalBuffer(Device* device,
|
|||
|
||||
Buffer::Buffer(Device* device, const BufferDescriptor* descriptor)
|
||||
: BufferBase(device, descriptor) {
|
||||
// TODO(penghuang): track usage for GL.
|
||||
mLastUsageSerial = kMaxExecutionSerial;
|
||||
const OpenGLFunctions& gl = device->GetGL();
|
||||
// Allocate at least 4 bytes so clamped accesses are always in bounds.
|
||||
mAllocatedSize = std::max(GetSize(), uint64_t(4u));
|
||||
|
@ -55,9 +53,10 @@ Buffer::Buffer(Device* device, const BufferDescriptor* descriptor)
|
|||
std::vector<uint8_t> clearValues(mAllocatedSize, 1u);
|
||||
gl.BufferData(GL_ARRAY_BUFFER, mAllocatedSize, clearValues.data(), GL_STATIC_DRAW);
|
||||
} else {
|
||||
// Buffers start zeroed if you pass nullptr to glBufferData.
|
||||
// Buffers start uninitialized if you pass nullptr to glBufferData.
|
||||
gl.BufferData(GL_ARRAY_BUFFER, mAllocatedSize, nullptr, GL_STATIC_DRAW);
|
||||
}
|
||||
TrackUsage();
|
||||
}
|
||||
|
||||
Buffer::Buffer(Device* device, const BufferDescriptor* descriptor, bool shouldLazyClear)
|
||||
|
@ -122,6 +121,7 @@ void Buffer::InitializeToZero() {
|
|||
gl.BufferSubData(GL_ARRAY_BUFFER, 0, size, clearValues.data());
|
||||
device->IncrementLazyClearCountForTesting();
|
||||
|
||||
TrackUsage();
|
||||
SetIsDataInitialized();
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,8 @@ MaybeError Buffer::MapAsyncImpl(wgpu::MapMode mode, size_t offset, size_t size)
|
|||
mappedData = gl.MapBufferRange(GL_ARRAY_BUFFER, offset, size, GL_MAP_READ_BIT);
|
||||
} else {
|
||||
ASSERT(mode & wgpu::MapMode::Write);
|
||||
mappedData = gl.MapBufferRange(GL_ARRAY_BUFFER, offset, size, GL_MAP_WRITE_BIT);
|
||||
mappedData = gl.MapBufferRange(GL_ARRAY_BUFFER, offset, size,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
}
|
||||
|
||||
// The frontend asks that the pointer returned by GetMappedPointer is from the start of
|
||||
|
|
|
@ -37,6 +37,8 @@ class Buffer final : public BufferBase {
|
|||
bool EnsureDataInitializedAsDestination(uint64_t offset, uint64_t size);
|
||||
bool EnsureDataInitializedAsDestination(const CopyTextureToBufferCmd* copy);
|
||||
|
||||
void TrackUsage() { MarkUsedInPendingCommands(); }
|
||||
|
||||
private:
|
||||
Buffer(Device* device, const BufferDescriptor* descriptor, bool shouldLazyClear);
|
||||
~Buffer() override;
|
||||
|
|
|
@ -520,6 +520,9 @@ MaybeError CommandBuffer::Execute() {
|
|||
|
||||
gl.BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
ToBackend(copy->source)->TrackUsage();
|
||||
ToBackend(copy->destination)->TrackUsage();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -560,6 +563,8 @@ MaybeError CommandBuffer::Execute() {
|
|||
copy->copySize);
|
||||
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
ToBackend(dst.texture)->Touch();
|
||||
|
||||
buffer->TrackUsage();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -666,6 +671,8 @@ MaybeError CommandBuffer::Execute() {
|
|||
|
||||
gl.BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
gl.DeleteFramebuffers(1, &readFBO);
|
||||
|
||||
buffer->TrackUsage();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -720,6 +727,7 @@ MaybeError CommandBuffer::Execute() {
|
|||
gl.BufferSubData(GL_ARRAY_BUFFER, cmd->offset, cmd->size, clearValues.data());
|
||||
}
|
||||
|
||||
dstBuffer->TrackUsage();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -756,6 +764,8 @@ MaybeError CommandBuffer::Execute() {
|
|||
|
||||
gl.BindBuffer(GL_ARRAY_BUFFER, dstBuffer->GetHandle());
|
||||
gl.BufferSubData(GL_ARRAY_BUFFER, offset, size, data);
|
||||
|
||||
dstBuffer->TrackUsage();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -799,6 +809,8 @@ MaybeError CommandBuffer::ExecuteComputePass() {
|
|||
gl.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, indirectBuffer->GetHandle());
|
||||
gl.DispatchComputeIndirect(static_cast<GLintptr>(indirectBufferOffset));
|
||||
gl.MemoryBarrier(GL_ALL_BARRIER_BITS);
|
||||
|
||||
indirectBuffer->TrackUsage();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1056,6 +1068,7 @@ MaybeError CommandBuffer::ExecuteRenderPass(BeginRenderPassCmd* renderPass) {
|
|||
gl.DrawArraysIndirect(
|
||||
lastPipeline->GetGLPrimitiveTopology(),
|
||||
reinterpret_cast<void*>(static_cast<intptr_t>(indirectBufferOffset)));
|
||||
indirectBuffer->TrackUsage();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1072,6 +1085,7 @@ MaybeError CommandBuffer::ExecuteRenderPass(BeginRenderPassCmd* renderPass) {
|
|||
gl.DrawElementsIndirect(
|
||||
lastPipeline->GetGLPrimitiveTopology(), indexBufferFormat,
|
||||
reinterpret_cast<void*>(static_cast<intptr_t>(draw->indirectOffset)));
|
||||
indirectBuffer->TrackUsage();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1112,6 +1126,7 @@ MaybeError CommandBuffer::ExecuteRenderPass(BeginRenderPassCmd* renderPass) {
|
|||
indexBufferFormat = IndexFormatType(cmd->format);
|
||||
indexFormatSize = IndexFormatSize(cmd->format);
|
||||
vertexStateBufferBindingTracker.OnSetIndexBuffer(cmd->buffer.Get());
|
||||
ToBackend(cmd->buffer)->TrackUsage();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1119,6 +1134,7 @@ MaybeError CommandBuffer::ExecuteRenderPass(BeginRenderPassCmd* renderPass) {
|
|||
SetVertexBufferCmd* cmd = iter->NextCommand<SetVertexBufferCmd>();
|
||||
vertexStateBufferBindingTracker.OnSetVertexBuffer(cmd->slot, cmd->buffer.Get(),
|
||||
cmd->offset);
|
||||
ToBackend(cmd->buffer)->TrackUsage();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -315,10 +315,17 @@ ResultOrError<Ref<TextureViewBase>> Device::CreateTextureViewImpl(
|
|||
}
|
||||
|
||||
void Device::SubmitFenceSync() {
|
||||
if (!mHasPendingCommands) {
|
||||
return;
|
||||
}
|
||||
|
||||
const OpenGLFunctions& gl = GetGL();
|
||||
GLsync sync = gl.FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
IncrementLastSubmittedCommandSerial();
|
||||
mFencesInFlight.emplace(sync, GetLastSubmittedCommandSerial());
|
||||
|
||||
// Reset mHasPendingCommands after GetGL() which will set mHasPendingCommands to true.
|
||||
mHasPendingCommands = false;
|
||||
}
|
||||
|
||||
MaybeError Device::ValidateEGLImageCanBeWrapped(const TextureDescriptor* descriptor,
|
||||
|
@ -381,6 +388,7 @@ TextureBase* Device::CreateTextureWrappingEGLImage(const ExternalImageDescriptor
|
|||
}
|
||||
|
||||
MaybeError Device::TickImpl() {
|
||||
SubmitFenceSync();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -442,9 +450,7 @@ MaybeError Device::WaitForIdleForDestruction() {
|
|||
}
|
||||
|
||||
bool Device::HasPendingCommands() const {
|
||||
// Technically we could have scheduled commands inside the GL driver that are waiting for a
|
||||
// glFlush but we can't know for sure so we might as well pretend there are no commands.
|
||||
return false;
|
||||
return mHasPendingCommands;
|
||||
}
|
||||
|
||||
uint32_t Device::GetOptimalBytesPerRowAlignment() const {
|
||||
|
@ -465,6 +471,7 @@ const OpenGLFunctions& Device::GetGL() const {
|
|||
if (mContext) {
|
||||
mContext->MakeCurrent();
|
||||
}
|
||||
mHasPendingCommands = true;
|
||||
return mGL;
|
||||
}
|
||||
|
||||
|
|
|
@ -140,6 +140,8 @@ class Device final : public DeviceBase {
|
|||
|
||||
GLFormatTable mFormatTable;
|
||||
std::unique_ptr<Context> mContext = nullptr;
|
||||
// Has pending GL commands which are not associated with a fence.
|
||||
mutable bool mHasPendingCommands = false;
|
||||
};
|
||||
|
||||
} // namespace dawn::native::opengl
|
||||
|
|
|
@ -48,6 +48,7 @@ MaybeError Queue::WriteBufferImpl(BufferBase* buffer,
|
|||
|
||||
gl.BindBuffer(GL_ARRAY_BUFFER, ToBackend(buffer)->GetHandle());
|
||||
gl.BufferSubData(GL_ARRAY_BUFFER, bufferOffset, size, data);
|
||||
buffer->MarkUsedInPendingCommands();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue