mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-06 22:53:35 +00:00
[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);
|
std::make_unique<MapRequestTask>(GetDevice()->GetPlatform(), this, mLastMapID);
|
||||||
TRACE_EVENT1(GetDevice()->GetPlatform(), General, "Buffer::APIMapAsync", "serial",
|
TRACE_EVENT1(GetDevice()->GetPlatform(), General, "Buffer::APIMapAsync", "serial",
|
||||||
uint64_t(mLastUsageSerial));
|
uint64_t(mLastUsageSerial));
|
||||||
if (mLastUsageSerial != kMaxExecutionSerial) {
|
GetDevice()->GetQueue()->TrackTask(std::move(request), mLastUsageSerial);
|
||||||
GetDevice()->GetQueue()->TrackTask(std::move(request), mLastUsageSerial);
|
|
||||||
} else {
|
|
||||||
GetDevice()->GetQueue()->TrackTaskAfterEventualFlush(std::move(request));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* BufferBase::APIGetMappedRange(size_t offset, size_t size) {
|
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)
|
Buffer::Buffer(Device* device, const BufferDescriptor* descriptor)
|
||||||
: BufferBase(device, descriptor) {
|
: BufferBase(device, descriptor) {
|
||||||
// TODO(penghuang): track usage for GL.
|
|
||||||
mLastUsageSerial = kMaxExecutionSerial;
|
|
||||||
const OpenGLFunctions& gl = device->GetGL();
|
const OpenGLFunctions& gl = device->GetGL();
|
||||||
// Allocate at least 4 bytes so clamped accesses are always in bounds.
|
// Allocate at least 4 bytes so clamped accesses are always in bounds.
|
||||||
mAllocatedSize = std::max(GetSize(), uint64_t(4u));
|
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);
|
std::vector<uint8_t> clearValues(mAllocatedSize, 1u);
|
||||||
gl.BufferData(GL_ARRAY_BUFFER, mAllocatedSize, clearValues.data(), GL_STATIC_DRAW);
|
gl.BufferData(GL_ARRAY_BUFFER, mAllocatedSize, clearValues.data(), GL_STATIC_DRAW);
|
||||||
} else {
|
} 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);
|
gl.BufferData(GL_ARRAY_BUFFER, mAllocatedSize, nullptr, GL_STATIC_DRAW);
|
||||||
}
|
}
|
||||||
|
TrackUsage();
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::Buffer(Device* device, const BufferDescriptor* descriptor, bool shouldLazyClear)
|
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());
|
gl.BufferSubData(GL_ARRAY_BUFFER, 0, size, clearValues.data());
|
||||||
device->IncrementLazyClearCountForTesting();
|
device->IncrementLazyClearCountForTesting();
|
||||||
|
|
||||||
|
TrackUsage();
|
||||||
SetIsDataInitialized();
|
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);
|
mappedData = gl.MapBufferRange(GL_ARRAY_BUFFER, offset, size, GL_MAP_READ_BIT);
|
||||||
} else {
|
} else {
|
||||||
ASSERT(mode & wgpu::MapMode::Write);
|
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
|
// 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(uint64_t offset, uint64_t size);
|
||||||
bool EnsureDataInitializedAsDestination(const CopyTextureToBufferCmd* copy);
|
bool EnsureDataInitializedAsDestination(const CopyTextureToBufferCmd* copy);
|
||||||
|
|
||||||
|
void TrackUsage() { MarkUsedInPendingCommands(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Buffer(Device* device, const BufferDescriptor* descriptor, bool shouldLazyClear);
|
Buffer(Device* device, const BufferDescriptor* descriptor, bool shouldLazyClear);
|
||||||
~Buffer() override;
|
~Buffer() override;
|
||||||
|
@ -520,6 +520,9 @@ MaybeError CommandBuffer::Execute() {
|
|||||||
|
|
||||||
gl.BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
gl.BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
|
|
||||||
|
ToBackend(copy->source)->TrackUsage();
|
||||||
|
ToBackend(copy->destination)->TrackUsage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,6 +563,8 @@ MaybeError CommandBuffer::Execute() {
|
|||||||
copy->copySize);
|
copy->copySize);
|
||||||
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
ToBackend(dst.texture)->Touch();
|
ToBackend(dst.texture)->Touch();
|
||||||
|
|
||||||
|
buffer->TrackUsage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,6 +671,8 @@ MaybeError CommandBuffer::Execute() {
|
|||||||
|
|
||||||
gl.BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
gl.BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
gl.DeleteFramebuffers(1, &readFBO);
|
gl.DeleteFramebuffers(1, &readFBO);
|
||||||
|
|
||||||
|
buffer->TrackUsage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -720,6 +727,7 @@ MaybeError CommandBuffer::Execute() {
|
|||||||
gl.BufferSubData(GL_ARRAY_BUFFER, cmd->offset, cmd->size, clearValues.data());
|
gl.BufferSubData(GL_ARRAY_BUFFER, cmd->offset, cmd->size, clearValues.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dstBuffer->TrackUsage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -756,6 +764,8 @@ MaybeError CommandBuffer::Execute() {
|
|||||||
|
|
||||||
gl.BindBuffer(GL_ARRAY_BUFFER, dstBuffer->GetHandle());
|
gl.BindBuffer(GL_ARRAY_BUFFER, dstBuffer->GetHandle());
|
||||||
gl.BufferSubData(GL_ARRAY_BUFFER, offset, size, data);
|
gl.BufferSubData(GL_ARRAY_BUFFER, offset, size, data);
|
||||||
|
|
||||||
|
dstBuffer->TrackUsage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -799,6 +809,8 @@ MaybeError CommandBuffer::ExecuteComputePass() {
|
|||||||
gl.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, indirectBuffer->GetHandle());
|
gl.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, indirectBuffer->GetHandle());
|
||||||
gl.DispatchComputeIndirect(static_cast<GLintptr>(indirectBufferOffset));
|
gl.DispatchComputeIndirect(static_cast<GLintptr>(indirectBufferOffset));
|
||||||
gl.MemoryBarrier(GL_ALL_BARRIER_BITS);
|
gl.MemoryBarrier(GL_ALL_BARRIER_BITS);
|
||||||
|
|
||||||
|
indirectBuffer->TrackUsage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1056,6 +1068,7 @@ MaybeError CommandBuffer::ExecuteRenderPass(BeginRenderPassCmd* renderPass) {
|
|||||||
gl.DrawArraysIndirect(
|
gl.DrawArraysIndirect(
|
||||||
lastPipeline->GetGLPrimitiveTopology(),
|
lastPipeline->GetGLPrimitiveTopology(),
|
||||||
reinterpret_cast<void*>(static_cast<intptr_t>(indirectBufferOffset)));
|
reinterpret_cast<void*>(static_cast<intptr_t>(indirectBufferOffset)));
|
||||||
|
indirectBuffer->TrackUsage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1072,6 +1085,7 @@ MaybeError CommandBuffer::ExecuteRenderPass(BeginRenderPassCmd* renderPass) {
|
|||||||
gl.DrawElementsIndirect(
|
gl.DrawElementsIndirect(
|
||||||
lastPipeline->GetGLPrimitiveTopology(), indexBufferFormat,
|
lastPipeline->GetGLPrimitiveTopology(), indexBufferFormat,
|
||||||
reinterpret_cast<void*>(static_cast<intptr_t>(draw->indirectOffset)));
|
reinterpret_cast<void*>(static_cast<intptr_t>(draw->indirectOffset)));
|
||||||
|
indirectBuffer->TrackUsage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1112,6 +1126,7 @@ MaybeError CommandBuffer::ExecuteRenderPass(BeginRenderPassCmd* renderPass) {
|
|||||||
indexBufferFormat = IndexFormatType(cmd->format);
|
indexBufferFormat = IndexFormatType(cmd->format);
|
||||||
indexFormatSize = IndexFormatSize(cmd->format);
|
indexFormatSize = IndexFormatSize(cmd->format);
|
||||||
vertexStateBufferBindingTracker.OnSetIndexBuffer(cmd->buffer.Get());
|
vertexStateBufferBindingTracker.OnSetIndexBuffer(cmd->buffer.Get());
|
||||||
|
ToBackend(cmd->buffer)->TrackUsage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1119,6 +1134,7 @@ MaybeError CommandBuffer::ExecuteRenderPass(BeginRenderPassCmd* renderPass) {
|
|||||||
SetVertexBufferCmd* cmd = iter->NextCommand<SetVertexBufferCmd>();
|
SetVertexBufferCmd* cmd = iter->NextCommand<SetVertexBufferCmd>();
|
||||||
vertexStateBufferBindingTracker.OnSetVertexBuffer(cmd->slot, cmd->buffer.Get(),
|
vertexStateBufferBindingTracker.OnSetVertexBuffer(cmd->slot, cmd->buffer.Get(),
|
||||||
cmd->offset);
|
cmd->offset);
|
||||||
|
ToBackend(cmd->buffer)->TrackUsage();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,10 +315,17 @@ ResultOrError<Ref<TextureViewBase>> Device::CreateTextureViewImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Device::SubmitFenceSync() {
|
void Device::SubmitFenceSync() {
|
||||||
|
if (!mHasPendingCommands) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const OpenGLFunctions& gl = GetGL();
|
const OpenGLFunctions& gl = GetGL();
|
||||||
GLsync sync = gl.FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
GLsync sync = gl.FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
IncrementLastSubmittedCommandSerial();
|
IncrementLastSubmittedCommandSerial();
|
||||||
mFencesInFlight.emplace(sync, GetLastSubmittedCommandSerial());
|
mFencesInFlight.emplace(sync, GetLastSubmittedCommandSerial());
|
||||||
|
|
||||||
|
// Reset mHasPendingCommands after GetGL() which will set mHasPendingCommands to true.
|
||||||
|
mHasPendingCommands = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError Device::ValidateEGLImageCanBeWrapped(const TextureDescriptor* descriptor,
|
MaybeError Device::ValidateEGLImageCanBeWrapped(const TextureDescriptor* descriptor,
|
||||||
@ -381,6 +388,7 @@ TextureBase* Device::CreateTextureWrappingEGLImage(const ExternalImageDescriptor
|
|||||||
}
|
}
|
||||||
|
|
||||||
MaybeError Device::TickImpl() {
|
MaybeError Device::TickImpl() {
|
||||||
|
SubmitFenceSync();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,9 +450,7 @@ MaybeError Device::WaitForIdleForDestruction() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Device::HasPendingCommands() const {
|
bool Device::HasPendingCommands() const {
|
||||||
// Technically we could have scheduled commands inside the GL driver that are waiting for a
|
return mHasPendingCommands;
|
||||||
// glFlush but we can't know for sure so we might as well pretend there are no commands.
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Device::GetOptimalBytesPerRowAlignment() const {
|
uint32_t Device::GetOptimalBytesPerRowAlignment() const {
|
||||||
@ -465,6 +471,7 @@ const OpenGLFunctions& Device::GetGL() const {
|
|||||||
if (mContext) {
|
if (mContext) {
|
||||||
mContext->MakeCurrent();
|
mContext->MakeCurrent();
|
||||||
}
|
}
|
||||||
|
mHasPendingCommands = true;
|
||||||
return mGL;
|
return mGL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +140,8 @@ class Device final : public DeviceBase {
|
|||||||
|
|
||||||
GLFormatTable mFormatTable;
|
GLFormatTable mFormatTable;
|
||||||
std::unique_ptr<Context> mContext = nullptr;
|
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
|
} // namespace dawn::native::opengl
|
||||||
|
@ -48,6 +48,7 @@ MaybeError Queue::WriteBufferImpl(BufferBase* buffer,
|
|||||||
|
|
||||||
gl.BindBuffer(GL_ARRAY_BUFFER, ToBackend(buffer)->GetHandle());
|
gl.BindBuffer(GL_ARRAY_BUFFER, ToBackend(buffer)->GetHandle());
|
||||||
gl.BufferSubData(GL_ARRAY_BUFFER, bufferOffset, size, data);
|
gl.BufferSubData(GL_ARRAY_BUFFER, bufferOffset, size, data);
|
||||||
|
buffer->MarkUsedInPendingCommands();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user