mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-21 02:39:11 +00:00
Support setting bind groups before pipeline for all backends
This is to match WebGPU semantics. Bug: dawn:201 Change-Id: I2aab671fc389edf1d2765395814a9c831afc653e Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/11080 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
617e356580
commit
7f3f331ce6
@@ -15,6 +15,7 @@
|
||||
#include "dawn_native/opengl/CommandBufferGL.h"
|
||||
|
||||
#include "dawn_native/BindGroup.h"
|
||||
#include "dawn_native/BindGroupTracker.h"
|
||||
#include "dawn_native/CommandEncoder.h"
|
||||
#include "dawn_native/Commands.h"
|
||||
#include "dawn_native/RenderBundle.h"
|
||||
@@ -215,88 +216,109 @@ namespace dawn_native { namespace opengl {
|
||||
RenderPipelineBase* mLastPipeline = nullptr;
|
||||
};
|
||||
|
||||
// Handles SetBindGroup commands with the specifics of translating to OpenGL texture and
|
||||
// buffer units
|
||||
void ApplyBindGroup(const OpenGLFunctions& gl,
|
||||
uint32_t index,
|
||||
BindGroupBase* group,
|
||||
PipelineLayout* pipelineLayout,
|
||||
PipelineGL* pipeline,
|
||||
uint32_t dynamicOffsetCount,
|
||||
uint64_t* dynamicOffsets) {
|
||||
const auto& indices = pipelineLayout->GetBindingIndexInfo()[index];
|
||||
const auto& layout = group->GetLayout()->GetBindingInfo();
|
||||
uint32_t currentDynamicIndex = 0;
|
||||
class BindGroupTracker : public BindGroupTrackerBase<BindGroupBase*, false> {
|
||||
public:
|
||||
void OnSetPipeline(RenderPipeline* pipeline) {
|
||||
BindGroupTrackerBase::OnSetPipeline(pipeline);
|
||||
mPipeline = pipeline;
|
||||
}
|
||||
|
||||
for (uint32_t bindingIndex : IterateBitSet(layout.mask)) {
|
||||
switch (layout.types[bindingIndex]) {
|
||||
case dawn::BindingType::UniformBuffer: {
|
||||
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
|
||||
GLuint buffer = ToBackend(binding.buffer)->GetHandle();
|
||||
GLuint uboIndex = indices[bindingIndex];
|
||||
GLuint offset = binding.offset;
|
||||
void OnSetPipeline(ComputePipeline* pipeline) {
|
||||
BindGroupTrackerBase::OnSetPipeline(pipeline);
|
||||
mPipeline = pipeline;
|
||||
}
|
||||
|
||||
if (layout.dynamic[bindingIndex]) {
|
||||
offset += dynamicOffsets[currentDynamicIndex];
|
||||
++currentDynamicIndex;
|
||||
}
|
||||
void Apply(const OpenGLFunctions& gl) {
|
||||
for (uint32_t index : IterateBitSet(mDirtyBindGroupsObjectChangedOrIsDynamic)) {
|
||||
ApplyBindGroup(gl, index, mBindGroups[index], mDynamicOffsetCounts[index],
|
||||
mDynamicOffsets[index].data());
|
||||
}
|
||||
DidApply();
|
||||
}
|
||||
|
||||
gl.BindBufferRange(GL_UNIFORM_BUFFER, uboIndex, buffer, offset,
|
||||
binding.size);
|
||||
} break;
|
||||
private:
|
||||
void ApplyBindGroup(const OpenGLFunctions& gl,
|
||||
uint32_t index,
|
||||
BindGroupBase* group,
|
||||
uint32_t dynamicOffsetCount,
|
||||
uint64_t* dynamicOffsets) {
|
||||
const auto& indices = ToBackend(mPipelineLayout)->GetBindingIndexInfo()[index];
|
||||
const auto& layout = group->GetLayout()->GetBindingInfo();
|
||||
uint32_t currentDynamicIndex = 0;
|
||||
|
||||
case dawn::BindingType::Sampler: {
|
||||
Sampler* sampler = ToBackend(group->GetBindingAsSampler(bindingIndex));
|
||||
GLuint samplerIndex = indices[bindingIndex];
|
||||
for (uint32_t bindingIndex : IterateBitSet(layout.mask)) {
|
||||
switch (layout.types[bindingIndex]) {
|
||||
case dawn::BindingType::UniformBuffer: {
|
||||
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
|
||||
GLuint buffer = ToBackend(binding.buffer)->GetHandle();
|
||||
GLuint uboIndex = indices[bindingIndex];
|
||||
GLuint offset = binding.offset;
|
||||
|
||||
for (PipelineGL::SamplerUnit unit :
|
||||
pipeline->GetTextureUnitsForSampler(samplerIndex)) {
|
||||
// Only use filtering for certain texture units, because int and uint
|
||||
// texture are only complete without filtering
|
||||
if (unit.shouldUseFiltering) {
|
||||
gl.BindSampler(unit.unit, sampler->GetFilteringHandle());
|
||||
} else {
|
||||
gl.BindSampler(unit.unit, sampler->GetNonFilteringHandle());
|
||||
if (layout.dynamic[bindingIndex]) {
|
||||
offset += dynamicOffsets[currentDynamicIndex];
|
||||
++currentDynamicIndex;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case dawn::BindingType::SampledTexture: {
|
||||
TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
|
||||
GLuint handle = view->GetHandle();
|
||||
GLenum target = view->GetGLTarget();
|
||||
GLuint viewIndex = indices[bindingIndex];
|
||||
gl.BindBufferRange(GL_UNIFORM_BUFFER, uboIndex, buffer, offset,
|
||||
binding.size);
|
||||
} break;
|
||||
|
||||
for (auto unit : pipeline->GetTextureUnitsForTextureView(viewIndex)) {
|
||||
gl.ActiveTexture(GL_TEXTURE0 + unit);
|
||||
gl.BindTexture(target, handle);
|
||||
}
|
||||
} break;
|
||||
case dawn::BindingType::Sampler: {
|
||||
Sampler* sampler = ToBackend(group->GetBindingAsSampler(bindingIndex));
|
||||
GLuint samplerIndex = indices[bindingIndex];
|
||||
|
||||
case dawn::BindingType::StorageBuffer: {
|
||||
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
|
||||
GLuint buffer = ToBackend(binding.buffer)->GetHandle();
|
||||
GLuint ssboIndex = indices[bindingIndex];
|
||||
GLuint offset = binding.offset;
|
||||
for (PipelineGL::SamplerUnit unit :
|
||||
mPipeline->GetTextureUnitsForSampler(samplerIndex)) {
|
||||
// Only use filtering for certain texture units, because int and
|
||||
// uint texture are only complete without filtering
|
||||
if (unit.shouldUseFiltering) {
|
||||
gl.BindSampler(unit.unit, sampler->GetFilteringHandle());
|
||||
} else {
|
||||
gl.BindSampler(unit.unit, sampler->GetNonFilteringHandle());
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
if (layout.dynamic[bindingIndex]) {
|
||||
offset += dynamicOffsets[currentDynamicIndex];
|
||||
++currentDynamicIndex;
|
||||
}
|
||||
case dawn::BindingType::SampledTexture: {
|
||||
TextureView* view =
|
||||
ToBackend(group->GetBindingAsTextureView(bindingIndex));
|
||||
GLuint handle = view->GetHandle();
|
||||
GLenum target = view->GetGLTarget();
|
||||
GLuint viewIndex = indices[bindingIndex];
|
||||
|
||||
gl.BindBufferRange(GL_SHADER_STORAGE_BUFFER, ssboIndex, buffer, offset,
|
||||
binding.size);
|
||||
} break;
|
||||
for (auto unit : mPipeline->GetTextureUnitsForTextureView(viewIndex)) {
|
||||
gl.ActiveTexture(GL_TEXTURE0 + unit);
|
||||
gl.BindTexture(target, handle);
|
||||
}
|
||||
} break;
|
||||
|
||||
case dawn::BindingType::StorageTexture:
|
||||
case dawn::BindingType::ReadonlyStorageBuffer:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case dawn::BindingType::StorageBuffer: {
|
||||
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
|
||||
GLuint buffer = ToBackend(binding.buffer)->GetHandle();
|
||||
GLuint ssboIndex = indices[bindingIndex];
|
||||
GLuint offset = binding.offset;
|
||||
|
||||
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset.
|
||||
if (layout.dynamic[bindingIndex]) {
|
||||
offset += dynamicOffsets[currentDynamicIndex];
|
||||
++currentDynamicIndex;
|
||||
}
|
||||
|
||||
gl.BindBufferRange(GL_SHADER_STORAGE_BUFFER, ssboIndex, buffer, offset,
|
||||
binding.size);
|
||||
} break;
|
||||
|
||||
case dawn::BindingType::StorageTexture:
|
||||
case dawn::BindingType::ReadonlyStorageBuffer:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
// TODO(shaobo.yan@intel.com): Implement dynamic buffer offset.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PipelineGL* mPipeline = nullptr;
|
||||
};
|
||||
|
||||
void ResolveMultisampledRenderTargets(const OpenGLFunctions& gl,
|
||||
const BeginRenderPassCmd* renderPass) {
|
||||
@@ -608,6 +630,7 @@ namespace dawn_native { namespace opengl {
|
||||
void CommandBuffer::ExecuteComputePass() {
|
||||
const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
|
||||
ComputePipeline* lastPipeline = nullptr;
|
||||
BindGroupTracker bindGroupTracker = {};
|
||||
|
||||
Command type;
|
||||
while (mCommands.NextCommandId(&type)) {
|
||||
@@ -619,6 +642,8 @@ namespace dawn_native { namespace opengl {
|
||||
|
||||
case Command::Dispatch: {
|
||||
DispatchCmd* dispatch = mCommands.NextCommand<DispatchCmd>();
|
||||
bindGroupTracker.Apply(gl);
|
||||
|
||||
gl.DispatchCompute(dispatch->x, dispatch->y, dispatch->z);
|
||||
// TODO(cwallez@chromium.org): add barriers to the API
|
||||
gl.MemoryBarrier(GL_ALL_BARRIER_BITS);
|
||||
@@ -626,6 +651,7 @@ namespace dawn_native { namespace opengl {
|
||||
|
||||
case Command::DispatchIndirect: {
|
||||
DispatchIndirectCmd* dispatch = mCommands.NextCommand<DispatchIndirectCmd>();
|
||||
bindGroupTracker.Apply(gl);
|
||||
|
||||
uint64_t indirectBufferOffset = dispatch->indirectOffset;
|
||||
Buffer* indirectBuffer = ToBackend(dispatch->indirectBuffer.Get());
|
||||
@@ -640,6 +666,8 @@ namespace dawn_native { namespace opengl {
|
||||
SetComputePipelineCmd* cmd = mCommands.NextCommand<SetComputePipelineCmd>();
|
||||
lastPipeline = ToBackend(cmd->pipeline).Get();
|
||||
lastPipeline->ApplyNow();
|
||||
|
||||
bindGroupTracker.OnSetPipeline(lastPipeline);
|
||||
} break;
|
||||
|
||||
case Command::SetBindGroup: {
|
||||
@@ -648,9 +676,8 @@ namespace dawn_native { namespace opengl {
|
||||
if (cmd->dynamicOffsetCount > 0) {
|
||||
dynamicOffsets = mCommands.NextData<uint64_t>(cmd->dynamicOffsetCount);
|
||||
}
|
||||
ApplyBindGroup(gl, cmd->index, cmd->group.Get(),
|
||||
ToBackend(lastPipeline->GetLayout()), lastPipeline,
|
||||
cmd->dynamicOffsetCount, dynamicOffsets);
|
||||
bindGroupTracker.OnSetBindGroup(cmd->index, cmd->group.Get(),
|
||||
cmd->dynamicOffsetCount, dynamicOffsets);
|
||||
} break;
|
||||
|
||||
case Command::InsertDebugMarker:
|
||||
@@ -802,12 +829,14 @@ namespace dawn_native { namespace opengl {
|
||||
uint64_t indexBufferBaseOffset = 0;
|
||||
|
||||
InputBufferTracker inputBuffers;
|
||||
BindGroupTracker bindGroupTracker = {};
|
||||
|
||||
auto DoRenderBundleCommand = [&](CommandIterator* iter, Command type) {
|
||||
switch (type) {
|
||||
case Command::Draw: {
|
||||
DrawCmd* draw = iter->NextCommand<DrawCmd>();
|
||||
inputBuffers.Apply(gl);
|
||||
bindGroupTracker.Apply(gl);
|
||||
|
||||
if (draw->firstInstance > 0) {
|
||||
gl.DrawArraysInstancedBaseInstance(
|
||||
@@ -824,6 +853,7 @@ namespace dawn_native { namespace opengl {
|
||||
case Command::DrawIndexed: {
|
||||
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
||||
inputBuffers.Apply(gl);
|
||||
bindGroupTracker.Apply(gl);
|
||||
|
||||
dawn::IndexFormat indexFormat =
|
||||
lastPipeline->GetVertexInputDescriptor()->indexFormat;
|
||||
@@ -849,6 +879,7 @@ namespace dawn_native { namespace opengl {
|
||||
case Command::DrawIndirect: {
|
||||
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
||||
inputBuffers.Apply(gl);
|
||||
bindGroupTracker.Apply(gl);
|
||||
|
||||
uint64_t indirectBufferOffset = draw->indirectOffset;
|
||||
Buffer* indirectBuffer = ToBackend(draw->indirectBuffer.Get());
|
||||
@@ -862,6 +893,7 @@ namespace dawn_native { namespace opengl {
|
||||
case Command::DrawIndexedIndirect: {
|
||||
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
||||
inputBuffers.Apply(gl);
|
||||
bindGroupTracker.Apply(gl);
|
||||
|
||||
dawn::IndexFormat indexFormat =
|
||||
lastPipeline->GetVertexInputDescriptor()->indexFormat;
|
||||
@@ -890,6 +922,7 @@ namespace dawn_native { namespace opengl {
|
||||
lastPipeline->ApplyNow(persistentPipelineState);
|
||||
|
||||
inputBuffers.OnSetPipeline(lastPipeline);
|
||||
bindGroupTracker.OnSetPipeline(lastPipeline);
|
||||
} break;
|
||||
|
||||
case Command::SetBindGroup: {
|
||||
@@ -898,9 +931,8 @@ namespace dawn_native { namespace opengl {
|
||||
if (cmd->dynamicOffsetCount > 0) {
|
||||
dynamicOffsets = iter->NextData<uint64_t>(cmd->dynamicOffsetCount);
|
||||
}
|
||||
ApplyBindGroup(gl, cmd->index, cmd->group.Get(),
|
||||
ToBackend(lastPipeline->GetLayout()), lastPipeline,
|
||||
cmd->dynamicOffsetCount, dynamicOffsets);
|
||||
bindGroupTracker.OnSetBindGroup(cmd->index, cmd->group.Get(),
|
||||
cmd->dynamicOffsetCount, dynamicOffsets);
|
||||
} break;
|
||||
|
||||
case Command::SetIndexBuffer: {
|
||||
|
||||
Reference in New Issue
Block a user