mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-15 11:51:22 +00:00
Implement RenderBundle in the backend
Bug: dawn:154 Change-Id: I45496fb2103150dabe32fbc7cb5856dc40c9339f Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/9222 Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
0ebd54cf38
commit
40618d0b93
1
BUILD.gn
1
BUILD.gn
@ -769,6 +769,7 @@ source_set("dawn_end2end_tests_sources") {
|
|||||||
"src/tests/end2end/ObjectCachingTests.cpp",
|
"src/tests/end2end/ObjectCachingTests.cpp",
|
||||||
"src/tests/end2end/OpArrayLengthTests.cpp",
|
"src/tests/end2end/OpArrayLengthTests.cpp",
|
||||||
"src/tests/end2end/PrimitiveTopologyTests.cpp",
|
"src/tests/end2end/PrimitiveTopologyTests.cpp",
|
||||||
|
"src/tests/end2end/RenderBundleTests.cpp",
|
||||||
"src/tests/end2end/RenderPassLoadOpTests.cpp",
|
"src/tests/end2end/RenderPassLoadOpTests.cpp",
|
||||||
"src/tests/end2end/RenderPassTests.cpp",
|
"src/tests/end2end/RenderPassTests.cpp",
|
||||||
"src/tests/end2end/SamplerTests.cpp",
|
"src/tests/end2end/SamplerTests.cpp",
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "common/Assert.h"
|
#include "common/Assert.h"
|
||||||
#include "dawn_native/CommandEncoder.h"
|
#include "dawn_native/CommandEncoder.h"
|
||||||
#include "dawn_native/Commands.h"
|
#include "dawn_native/Commands.h"
|
||||||
|
#include "dawn_native/RenderBundle.h"
|
||||||
#include "dawn_native/d3d12/BindGroupD3D12.h"
|
#include "dawn_native/d3d12/BindGroupD3D12.h"
|
||||||
#include "dawn_native/d3d12/BindGroupLayoutD3D12.h"
|
#include "dawn_native/d3d12/BindGroupLayoutD3D12.h"
|
||||||
#include "dawn_native/d3d12/BufferD3D12.h"
|
#include "dawn_native/d3d12/BufferD3D12.h"
|
||||||
@ -398,7 +399,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
Command type;
|
Command type;
|
||||||
PipelineLayout* lastLayout = nullptr;
|
PipelineLayout* lastLayout = nullptr;
|
||||||
|
|
||||||
while (commands->NextCommandId(&type)) {
|
auto HandleCommand = [&](CommandIterator* commands, Command type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Command::SetComputePipeline: {
|
case Command::SetComputePipeline: {
|
||||||
SetComputePipelineCmd* cmd =
|
SetComputePipelineCmd* cmd =
|
||||||
@ -431,6 +432,26 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
default:
|
default:
|
||||||
SkipCommand(commands, type);
|
SkipCommand(commands, type);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
while (commands->NextCommandId(&type)) {
|
||||||
|
switch (type) {
|
||||||
|
case Command::ExecuteBundles: {
|
||||||
|
ExecuteBundlesCmd* cmd = commands->NextCommand<ExecuteBundlesCmd>();
|
||||||
|
auto bundles = commands->NextData<Ref<RenderBundleBase>>(cmd->count);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < cmd->count; ++i) {
|
||||||
|
CommandIterator* commands = bundles[i]->GetCommands();
|
||||||
|
commands->Reset();
|
||||||
|
while (commands->NextCommandId(&type)) {
|
||||||
|
HandleCommand(commands, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
HandleCommand(commands, type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commands->Reset();
|
commands->Reset();
|
||||||
@ -987,6 +1008,155 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
PipelineLayout* lastLayout = nullptr;
|
PipelineLayout* lastLayout = nullptr;
|
||||||
VertexBuffersInfo vertexBuffersInfo = {};
|
VertexBuffersInfo vertexBuffersInfo = {};
|
||||||
|
|
||||||
|
auto EncodeRenderBundleCommand = [&](CommandIterator* iter, Command type) {
|
||||||
|
switch (type) {
|
||||||
|
case Command::Draw: {
|
||||||
|
DrawCmd* draw = iter->NextCommand<DrawCmd>();
|
||||||
|
|
||||||
|
FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline);
|
||||||
|
commandList->DrawInstanced(draw->vertexCount, draw->instanceCount,
|
||||||
|
draw->firstVertex, draw->firstInstance);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::DrawIndexed: {
|
||||||
|
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
||||||
|
|
||||||
|
FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline);
|
||||||
|
commandList->DrawIndexedInstanced(draw->indexCount, draw->instanceCount,
|
||||||
|
draw->firstIndex, draw->baseVertex,
|
||||||
|
draw->firstInstance);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::DrawIndirect: {
|
||||||
|
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
||||||
|
|
||||||
|
FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline);
|
||||||
|
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
||||||
|
ComPtr<ID3D12CommandSignature> signature =
|
||||||
|
ToBackend(GetDevice())->GetDrawIndirectSignature();
|
||||||
|
commandList->ExecuteIndirect(signature.Get(), 1,
|
||||||
|
buffer->GetD3D12Resource().Get(),
|
||||||
|
draw->indirectOffset, nullptr, 0);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::DrawIndexedIndirect: {
|
||||||
|
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
||||||
|
|
||||||
|
FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline);
|
||||||
|
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
||||||
|
ComPtr<ID3D12CommandSignature> signature =
|
||||||
|
ToBackend(GetDevice())->GetDrawIndexedIndirectSignature();
|
||||||
|
commandList->ExecuteIndirect(signature.Get(), 1,
|
||||||
|
buffer->GetD3D12Resource().Get(),
|
||||||
|
draw->indirectOffset, nullptr, 0);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::InsertDebugMarker: {
|
||||||
|
InsertDebugMarkerCmd* cmd = iter->NextCommand<InsertDebugMarkerCmd>();
|
||||||
|
const char* label = iter->NextData<char>(cmd->length + 1);
|
||||||
|
|
||||||
|
if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
|
||||||
|
// PIX color is 1 byte per channel in ARGB format
|
||||||
|
constexpr uint64_t kPIXBlackColor = 0xff000000;
|
||||||
|
ToBackend(GetDevice())
|
||||||
|
->GetFunctions()
|
||||||
|
->pixSetMarkerOnCommandList(commandList.Get(), kPIXBlackColor, label);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::PopDebugGroup: {
|
||||||
|
iter->NextCommand<PopDebugGroupCmd>();
|
||||||
|
|
||||||
|
if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
|
||||||
|
ToBackend(GetDevice())
|
||||||
|
->GetFunctions()
|
||||||
|
->pixEndEventOnCommandList(commandList.Get());
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::PushDebugGroup: {
|
||||||
|
PushDebugGroupCmd* cmd = iter->NextCommand<PushDebugGroupCmd>();
|
||||||
|
const char* label = iter->NextData<char>(cmd->length + 1);
|
||||||
|
|
||||||
|
if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
|
||||||
|
// PIX color is 1 byte per channel in ARGB format
|
||||||
|
constexpr uint64_t kPIXBlackColor = 0xff000000;
|
||||||
|
ToBackend(GetDevice())
|
||||||
|
->GetFunctions()
|
||||||
|
->pixBeginEventOnCommandList(commandList.Get(), kPIXBlackColor, label);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::SetRenderPipeline: {
|
||||||
|
SetRenderPipelineCmd* cmd = iter->NextCommand<SetRenderPipelineCmd>();
|
||||||
|
RenderPipeline* pipeline = ToBackend(cmd->pipeline).Get();
|
||||||
|
PipelineLayout* layout = ToBackend(pipeline->GetLayout());
|
||||||
|
|
||||||
|
commandList->SetGraphicsRootSignature(layout->GetRootSignature().Get());
|
||||||
|
commandList->SetPipelineState(pipeline->GetPipelineState().Get());
|
||||||
|
commandList->IASetPrimitiveTopology(pipeline->GetD3D12PrimitiveTopology());
|
||||||
|
|
||||||
|
bindingTracker->SetInheritedBindGroups(commandList, lastLayout, layout);
|
||||||
|
|
||||||
|
lastPipeline = pipeline;
|
||||||
|
lastLayout = layout;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::SetBindGroup: {
|
||||||
|
SetBindGroupCmd* cmd = iter->NextCommand<SetBindGroupCmd>();
|
||||||
|
BindGroup* group = ToBackend(cmd->group.Get());
|
||||||
|
uint64_t* dynamicOffsets = nullptr;
|
||||||
|
|
||||||
|
if (cmd->dynamicOffsetCount > 0) {
|
||||||
|
dynamicOffsets = iter->NextData<uint64_t>(cmd->dynamicOffsetCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingTracker->SetBindGroup(commandList, lastLayout, group, cmd->index,
|
||||||
|
cmd->dynamicOffsetCount, dynamicOffsets);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::SetIndexBuffer: {
|
||||||
|
SetIndexBufferCmd* cmd = iter->NextCommand<SetIndexBufferCmd>();
|
||||||
|
|
||||||
|
Buffer* buffer = ToBackend(cmd->buffer.Get());
|
||||||
|
D3D12_INDEX_BUFFER_VIEW bufferView;
|
||||||
|
bufferView.BufferLocation = buffer->GetVA() + cmd->offset;
|
||||||
|
bufferView.SizeInBytes = buffer->GetSize() - cmd->offset;
|
||||||
|
// TODO(cwallez@chromium.org): Make index buffers lazily applied, right now
|
||||||
|
// this will break if the pipeline is changed for one with a different index
|
||||||
|
// format after SetIndexBuffer
|
||||||
|
bufferView.Format =
|
||||||
|
DXGIIndexFormat(lastPipeline->GetVertexInputDescriptor()->indexFormat);
|
||||||
|
|
||||||
|
commandList->IASetIndexBuffer(&bufferView);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::SetVertexBuffers: {
|
||||||
|
SetVertexBuffersCmd* cmd = iter->NextCommand<SetVertexBuffersCmd>();
|
||||||
|
auto buffers = iter->NextData<Ref<BufferBase>>(cmd->count);
|
||||||
|
auto offsets = iter->NextData<uint64_t>(cmd->count);
|
||||||
|
|
||||||
|
vertexBuffersInfo.startSlot =
|
||||||
|
std::min(vertexBuffersInfo.startSlot, cmd->startSlot);
|
||||||
|
vertexBuffersInfo.endSlot =
|
||||||
|
std::max(vertexBuffersInfo.endSlot, cmd->startSlot + cmd->count);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < cmd->count; ++i) {
|
||||||
|
Buffer* buffer = ToBackend(buffers[i].Get());
|
||||||
|
auto* d3d12BufferView =
|
||||||
|
&vertexBuffersInfo.d3d12BufferViews[cmd->startSlot + i];
|
||||||
|
d3d12BufferView->BufferLocation = buffer->GetVA() + offsets[i];
|
||||||
|
d3d12BufferView->SizeInBytes = buffer->GetSize() - offsets[i];
|
||||||
|
// The bufferView stride is set based on the input state before a draw.
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Command type;
|
Command type;
|
||||||
while (mCommands.NextCommandId(&type)) {
|
while (mCommands.NextCommandId(&type)) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -1001,98 +1171,6 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
return;
|
return;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::Draw: {
|
|
||||||
DrawCmd* draw = mCommands.NextCommand<DrawCmd>();
|
|
||||||
|
|
||||||
FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline);
|
|
||||||
commandList->DrawInstanced(draw->vertexCount, draw->instanceCount,
|
|
||||||
draw->firstVertex, draw->firstInstance);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::DrawIndexed: {
|
|
||||||
DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
|
|
||||||
|
|
||||||
FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline);
|
|
||||||
commandList->DrawIndexedInstanced(draw->indexCount, draw->instanceCount,
|
|
||||||
draw->firstIndex, draw->baseVertex,
|
|
||||||
draw->firstInstance);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::DrawIndirect: {
|
|
||||||
DrawIndirectCmd* draw = mCommands.NextCommand<DrawIndirectCmd>();
|
|
||||||
|
|
||||||
FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline);
|
|
||||||
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
|
||||||
ComPtr<ID3D12CommandSignature> signature =
|
|
||||||
ToBackend(GetDevice())->GetDrawIndirectSignature();
|
|
||||||
commandList->ExecuteIndirect(signature.Get(), 1,
|
|
||||||
buffer->GetD3D12Resource().Get(),
|
|
||||||
draw->indirectOffset, nullptr, 0);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::DrawIndexedIndirect: {
|
|
||||||
DrawIndexedIndirectCmd* draw = mCommands.NextCommand<DrawIndexedIndirectCmd>();
|
|
||||||
|
|
||||||
FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline);
|
|
||||||
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
|
||||||
ComPtr<ID3D12CommandSignature> signature =
|
|
||||||
ToBackend(GetDevice())->GetDrawIndexedIndirectSignature();
|
|
||||||
commandList->ExecuteIndirect(signature.Get(), 1,
|
|
||||||
buffer->GetD3D12Resource().Get(),
|
|
||||||
draw->indirectOffset, nullptr, 0);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::InsertDebugMarker: {
|
|
||||||
InsertDebugMarkerCmd* cmd = mCommands.NextCommand<InsertDebugMarkerCmd>();
|
|
||||||
const char* label = mCommands.NextData<char>(cmd->length + 1);
|
|
||||||
|
|
||||||
if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
|
|
||||||
// PIX color is 1 byte per channel in ARGB format
|
|
||||||
constexpr uint64_t kPIXBlackColor = 0xff000000;
|
|
||||||
ToBackend(GetDevice())
|
|
||||||
->GetFunctions()
|
|
||||||
->pixSetMarkerOnCommandList(commandList.Get(), kPIXBlackColor, label);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::PopDebugGroup: {
|
|
||||||
mCommands.NextCommand<PopDebugGroupCmd>();
|
|
||||||
|
|
||||||
if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
|
|
||||||
ToBackend(GetDevice())
|
|
||||||
->GetFunctions()
|
|
||||||
->pixEndEventOnCommandList(commandList.Get());
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::PushDebugGroup: {
|
|
||||||
PushDebugGroupCmd* cmd = mCommands.NextCommand<PushDebugGroupCmd>();
|
|
||||||
const char* label = mCommands.NextData<char>(cmd->length + 1);
|
|
||||||
|
|
||||||
if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
|
|
||||||
// PIX color is 1 byte per channel in ARGB format
|
|
||||||
constexpr uint64_t kPIXBlackColor = 0xff000000;
|
|
||||||
ToBackend(GetDevice())
|
|
||||||
->GetFunctions()
|
|
||||||
->pixBeginEventOnCommandList(commandList.Get(), kPIXBlackColor, label);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::SetRenderPipeline: {
|
|
||||||
SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
|
|
||||||
RenderPipeline* pipeline = ToBackend(cmd->pipeline).Get();
|
|
||||||
PipelineLayout* layout = ToBackend(pipeline->GetLayout());
|
|
||||||
|
|
||||||
commandList->SetGraphicsRootSignature(layout->GetRootSignature().Get());
|
|
||||||
commandList->SetPipelineState(pipeline->GetPipelineState().Get());
|
|
||||||
commandList->IASetPrimitiveTopology(pipeline->GetD3D12PrimitiveTopology());
|
|
||||||
|
|
||||||
bindingTracker->SetInheritedBindGroups(commandList, lastLayout, layout);
|
|
||||||
|
|
||||||
lastPipeline = pipeline;
|
|
||||||
lastLayout = layout;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::SetStencilReference: {
|
case Command::SetStencilReference: {
|
||||||
SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
|
SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
|
||||||
|
|
||||||
@ -1128,56 +1206,20 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
commandList->OMSetBlendFactor(static_cast<const FLOAT*>(&cmd->color.r));
|
commandList->OMSetBlendFactor(static_cast<const FLOAT*>(&cmd->color.r));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetBindGroup: {
|
case Command::ExecuteBundles: {
|
||||||
SetBindGroupCmd* cmd = mCommands.NextCommand<SetBindGroupCmd>();
|
ExecuteBundlesCmd* cmd = mCommands.NextCommand<ExecuteBundlesCmd>();
|
||||||
BindGroup* group = ToBackend(cmd->group.Get());
|
auto bundles = mCommands.NextData<Ref<RenderBundleBase>>(cmd->count);
|
||||||
uint64_t* dynamicOffsets = nullptr;
|
|
||||||
|
|
||||||
if (cmd->dynamicOffsetCount > 0) {
|
|
||||||
dynamicOffsets = mCommands.NextData<uint64_t>(cmd->dynamicOffsetCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
bindingTracker->SetBindGroup(commandList, lastLayout, group, cmd->index,
|
|
||||||
cmd->dynamicOffsetCount, dynamicOffsets);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::SetIndexBuffer: {
|
|
||||||
SetIndexBufferCmd* cmd = mCommands.NextCommand<SetIndexBufferCmd>();
|
|
||||||
|
|
||||||
Buffer* buffer = ToBackend(cmd->buffer.Get());
|
|
||||||
D3D12_INDEX_BUFFER_VIEW bufferView;
|
|
||||||
bufferView.BufferLocation = buffer->GetVA() + cmd->offset;
|
|
||||||
bufferView.SizeInBytes = buffer->GetSize() - cmd->offset;
|
|
||||||
// TODO(cwallez@chromium.org): Make index buffers lazily applied, right now
|
|
||||||
// this will break if the pipeline is changed for one with a different index
|
|
||||||
// format after SetIndexBuffer
|
|
||||||
bufferView.Format =
|
|
||||||
DXGIIndexFormat(lastPipeline->GetVertexInputDescriptor()->indexFormat);
|
|
||||||
|
|
||||||
commandList->IASetIndexBuffer(&bufferView);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::SetVertexBuffers: {
|
|
||||||
SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>();
|
|
||||||
auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count);
|
|
||||||
auto offsets = mCommands.NextData<uint64_t>(cmd->count);
|
|
||||||
|
|
||||||
vertexBuffersInfo.startSlot =
|
|
||||||
std::min(vertexBuffersInfo.startSlot, cmd->startSlot);
|
|
||||||
vertexBuffersInfo.endSlot =
|
|
||||||
std::max(vertexBuffersInfo.endSlot, cmd->startSlot + cmd->count);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < cmd->count; ++i) {
|
for (uint32_t i = 0; i < cmd->count; ++i) {
|
||||||
Buffer* buffer = ToBackend(buffers[i].Get());
|
CommandIterator* iter = bundles[i]->GetCommands();
|
||||||
auto* d3d12BufferView =
|
iter->Reset();
|
||||||
&vertexBuffersInfo.d3d12BufferViews[cmd->startSlot + i];
|
while (iter->NextCommandId(&type)) {
|
||||||
d3d12BufferView->BufferLocation = buffer->GetVA() + offsets[i];
|
EncodeRenderBundleCommand(iter, type);
|
||||||
d3d12BufferView->SizeInBytes = buffer->GetSize() - offsets[i];
|
}
|
||||||
// The bufferView stride is set based on the input state before a draw.
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: { UNREACHABLE(); } break;
|
default: { EncodeRenderBundleCommand(&mCommands, type); } break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "dawn_native/BindGroup.h"
|
#include "dawn_native/BindGroup.h"
|
||||||
#include "dawn_native/CommandEncoder.h"
|
#include "dawn_native/CommandEncoder.h"
|
||||||
#include "dawn_native/Commands.h"
|
#include "dawn_native/Commands.h"
|
||||||
|
#include "dawn_native/RenderBundle.h"
|
||||||
#include "dawn_native/metal/BufferMTL.h"
|
#include "dawn_native/metal/BufferMTL.h"
|
||||||
#include "dawn_native/metal/ComputePipelineMTL.h"
|
#include "dawn_native/metal/ComputePipelineMTL.h"
|
||||||
#include "dawn_native/metal/DeviceMTL.h"
|
#include "dawn_native/metal/DeviceMTL.h"
|
||||||
@ -871,17 +872,10 @@ namespace dawn_native { namespace metal {
|
|||||||
id<MTLRenderCommandEncoder> encoder =
|
id<MTLRenderCommandEncoder> encoder =
|
||||||
[commandBuffer renderCommandEncoderWithDescriptor:mtlRenderPass];
|
[commandBuffer renderCommandEncoderWithDescriptor:mtlRenderPass];
|
||||||
|
|
||||||
Command type;
|
auto EncodeRenderBundleCommand = [&](CommandIterator* iter, Command type) {
|
||||||
while (mCommands.NextCommandId(&type)) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Command::EndRenderPass: {
|
|
||||||
mCommands.NextCommand<EndRenderPassCmd>();
|
|
||||||
[encoder endEncoding];
|
|
||||||
return;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::Draw: {
|
case Command::Draw: {
|
||||||
DrawCmd* draw = mCommands.NextCommand<DrawCmd>();
|
DrawCmd* draw = iter->NextCommand<DrawCmd>();
|
||||||
|
|
||||||
vertexInputBuffers.Apply(encoder, lastPipeline);
|
vertexInputBuffers.Apply(encoder, lastPipeline);
|
||||||
storageBufferLengths.Apply(lastPipeline, encoder);
|
storageBufferLengths.Apply(lastPipeline, encoder);
|
||||||
@ -897,7 +891,7 @@ namespace dawn_native { namespace metal {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::DrawIndexed: {
|
case Command::DrawIndexed: {
|
||||||
DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
|
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
||||||
size_t formatSize =
|
size_t formatSize =
|
||||||
IndexFormatSize(lastPipeline->GetVertexInputDescriptor()->indexFormat);
|
IndexFormatSize(lastPipeline->GetVertexInputDescriptor()->indexFormat);
|
||||||
|
|
||||||
@ -919,7 +913,7 @@ namespace dawn_native { namespace metal {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::DrawIndirect: {
|
case Command::DrawIndirect: {
|
||||||
DrawIndirectCmd* draw = mCommands.NextCommand<DrawIndirectCmd>();
|
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
||||||
|
|
||||||
vertexInputBuffers.Apply(encoder, lastPipeline);
|
vertexInputBuffers.Apply(encoder, lastPipeline);
|
||||||
storageBufferLengths.Apply(lastPipeline, encoder);
|
storageBufferLengths.Apply(lastPipeline, encoder);
|
||||||
@ -932,7 +926,7 @@ namespace dawn_native { namespace metal {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::DrawIndexedIndirect: {
|
case Command::DrawIndexedIndirect: {
|
||||||
DrawIndirectCmd* draw = mCommands.NextCommand<DrawIndirectCmd>();
|
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
||||||
|
|
||||||
vertexInputBuffers.Apply(encoder, lastPipeline);
|
vertexInputBuffers.Apply(encoder, lastPipeline);
|
||||||
storageBufferLengths.Apply(lastPipeline, encoder);
|
storageBufferLengths.Apply(lastPipeline, encoder);
|
||||||
@ -948,8 +942,8 @@ namespace dawn_native { namespace metal {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::InsertDebugMarker: {
|
case Command::InsertDebugMarker: {
|
||||||
InsertDebugMarkerCmd* cmd = mCommands.NextCommand<InsertDebugMarkerCmd>();
|
InsertDebugMarkerCmd* cmd = iter->NextCommand<InsertDebugMarkerCmd>();
|
||||||
char* label = mCommands.NextData<char>(cmd->length + 1);
|
char* label = iter->NextData<char>(cmd->length + 1);
|
||||||
NSString* mtlLabel = [[NSString alloc] initWithUTF8String:label];
|
NSString* mtlLabel = [[NSString alloc] initWithUTF8String:label];
|
||||||
|
|
||||||
[encoder insertDebugSignpost:mtlLabel];
|
[encoder insertDebugSignpost:mtlLabel];
|
||||||
@ -957,14 +951,14 @@ namespace dawn_native { namespace metal {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::PopDebugGroup: {
|
case Command::PopDebugGroup: {
|
||||||
mCommands.NextCommand<PopDebugGroupCmd>();
|
iter->NextCommand<PopDebugGroupCmd>();
|
||||||
|
|
||||||
[encoder popDebugGroup];
|
[encoder popDebugGroup];
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::PushDebugGroup: {
|
case Command::PushDebugGroup: {
|
||||||
PushDebugGroupCmd* cmd = mCommands.NextCommand<PushDebugGroupCmd>();
|
PushDebugGroupCmd* cmd = iter->NextCommand<PushDebugGroupCmd>();
|
||||||
char* label = mCommands.NextData<char>(cmd->length + 1);
|
char* label = iter->NextData<char>(cmd->length + 1);
|
||||||
NSString* mtlLabel = [[NSString alloc] initWithUTF8String:label];
|
NSString* mtlLabel = [[NSString alloc] initWithUTF8String:label];
|
||||||
|
|
||||||
[encoder pushDebugGroup:mtlLabel];
|
[encoder pushDebugGroup:mtlLabel];
|
||||||
@ -972,7 +966,7 @@ namespace dawn_native { namespace metal {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetRenderPipeline: {
|
case Command::SetRenderPipeline: {
|
||||||
SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
|
SetRenderPipelineCmd* cmd = iter->NextCommand<SetRenderPipelineCmd>();
|
||||||
RenderPipeline* newPipeline = ToBackend(cmd->pipeline).Get();
|
RenderPipeline* newPipeline = ToBackend(cmd->pipeline).Get();
|
||||||
|
|
||||||
vertexInputBuffers.OnSetPipeline(lastPipeline, newPipeline);
|
vertexInputBuffers.OnSetPipeline(lastPipeline, newPipeline);
|
||||||
@ -984,6 +978,49 @@ namespace dawn_native { namespace metal {
|
|||||||
lastPipeline = newPipeline;
|
lastPipeline = newPipeline;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case Command::SetBindGroup: {
|
||||||
|
SetBindGroupCmd* cmd = iter->NextCommand<SetBindGroupCmd>();
|
||||||
|
uint64_t* dynamicOffsets = nullptr;
|
||||||
|
if (cmd->dynamicOffsetCount > 0) {
|
||||||
|
dynamicOffsets = iter->NextData<uint64_t>(cmd->dynamicOffsetCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplyBindGroup(cmd->index, ToBackend(cmd->group.Get()), cmd->dynamicOffsetCount,
|
||||||
|
dynamicOffsets, ToBackend(lastPipeline->GetLayout()),
|
||||||
|
&storageBufferLengths, encoder, nil);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::SetIndexBuffer: {
|
||||||
|
SetIndexBufferCmd* cmd = iter->NextCommand<SetIndexBufferCmd>();
|
||||||
|
auto b = ToBackend(cmd->buffer.Get());
|
||||||
|
indexBuffer = b->GetMTLBuffer();
|
||||||
|
indexBufferBaseOffset = cmd->offset;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::SetVertexBuffers: {
|
||||||
|
SetVertexBuffersCmd* cmd = iter->NextCommand<SetVertexBuffersCmd>();
|
||||||
|
const Ref<BufferBase>* buffers = iter->NextData<Ref<BufferBase>>(cmd->count);
|
||||||
|
const uint64_t* offsets = iter->NextData<uint64_t>(cmd->count);
|
||||||
|
|
||||||
|
vertexInputBuffers.OnSetVertexBuffers(cmd->startSlot, cmd->count, buffers,
|
||||||
|
offsets);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Command type;
|
||||||
|
while (mCommands.NextCommandId(&type)) {
|
||||||
|
switch (type) {
|
||||||
|
case Command::EndRenderPass: {
|
||||||
|
mCommands.NextCommand<EndRenderPassCmd>();
|
||||||
|
[encoder endEncoding];
|
||||||
|
return;
|
||||||
|
} break;
|
||||||
|
|
||||||
case Command::SetStencilReference: {
|
case Command::SetStencilReference: {
|
||||||
SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
|
SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
|
||||||
[encoder setStencilReferenceValue:cmd->reference];
|
[encoder setStencilReferenceValue:cmd->reference];
|
||||||
@ -1030,36 +1067,20 @@ namespace dawn_native { namespace metal {
|
|||||||
alpha:cmd->color.a];
|
alpha:cmd->color.a];
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetBindGroup: {
|
case Command::ExecuteBundles: {
|
||||||
SetBindGroupCmd* cmd = mCommands.NextCommand<SetBindGroupCmd>();
|
ExecuteBundlesCmd* cmd = mCommands.NextCommand<ExecuteBundlesCmd>();
|
||||||
uint64_t* dynamicOffsets = nullptr;
|
auto bundles = mCommands.NextData<Ref<RenderBundleBase>>(cmd->count);
|
||||||
if (cmd->dynamicOffsetCount > 0) {
|
|
||||||
dynamicOffsets = mCommands.NextData<uint64_t>(cmd->dynamicOffsetCount);
|
for (uint32_t i = 0; i < cmd->count; ++i) {
|
||||||
|
CommandIterator* iter = bundles[i]->GetCommands();
|
||||||
|
iter->Reset();
|
||||||
|
while (iter->NextCommandId(&type)) {
|
||||||
|
EncodeRenderBundleCommand(iter, type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyBindGroup(cmd->index, ToBackend(cmd->group.Get()), cmd->dynamicOffsetCount,
|
|
||||||
dynamicOffsets, ToBackend(lastPipeline->GetLayout()),
|
|
||||||
&storageBufferLengths, encoder, nil);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetIndexBuffer: {
|
default: { EncodeRenderBundleCommand(&mCommands, type); } break;
|
||||||
SetIndexBufferCmd* cmd = mCommands.NextCommand<SetIndexBufferCmd>();
|
|
||||||
auto b = ToBackend(cmd->buffer.Get());
|
|
||||||
indexBuffer = b->GetMTLBuffer();
|
|
||||||
indexBufferBaseOffset = cmd->offset;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::SetVertexBuffers: {
|
|
||||||
SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>();
|
|
||||||
const Ref<BufferBase>* buffers =
|
|
||||||
mCommands.NextData<Ref<BufferBase>>(cmd->count);
|
|
||||||
const uint64_t* offsets = mCommands.NextData<uint64_t>(cmd->count);
|
|
||||||
|
|
||||||
vertexInputBuffers.OnSetVertexBuffers(cmd->startSlot, cmd->count, buffers,
|
|
||||||
offsets);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: { UNREACHABLE(); } break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "dawn_native/BindGroup.h"
|
#include "dawn_native/BindGroup.h"
|
||||||
#include "dawn_native/CommandEncoder.h"
|
#include "dawn_native/CommandEncoder.h"
|
||||||
#include "dawn_native/Commands.h"
|
#include "dawn_native/Commands.h"
|
||||||
|
#include "dawn_native/RenderBundle.h"
|
||||||
#include "dawn_native/opengl/BufferGL.h"
|
#include "dawn_native/opengl/BufferGL.h"
|
||||||
#include "dawn_native/opengl/ComputePipelineGL.h"
|
#include "dawn_native/opengl/ComputePipelineGL.h"
|
||||||
#include "dawn_native/opengl/DeviceGL.h"
|
#include "dawn_native/opengl/DeviceGL.h"
|
||||||
@ -735,21 +736,10 @@ namespace dawn_native { namespace opengl {
|
|||||||
|
|
||||||
InputBufferTracker inputBuffers;
|
InputBufferTracker inputBuffers;
|
||||||
|
|
||||||
Command type;
|
auto DoRenderBundleCommand = [&](CommandIterator* iter, Command type) {
|
||||||
while (mCommands.NextCommandId(&type)) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Command::EndRenderPass: {
|
|
||||||
mCommands.NextCommand<EndRenderPassCmd>();
|
|
||||||
|
|
||||||
if (renderPass->attachmentState->GetSampleCount() > 1) {
|
|
||||||
ResolveMultisampledRenderTargets(gl, renderPass);
|
|
||||||
}
|
|
||||||
gl.DeleteFramebuffers(1, &fbo);
|
|
||||||
return;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::Draw: {
|
case Command::Draw: {
|
||||||
DrawCmd* draw = mCommands.NextCommand<DrawCmd>();
|
DrawCmd* draw = iter->NextCommand<DrawCmd>();
|
||||||
inputBuffers.Apply(gl);
|
inputBuffers.Apply(gl);
|
||||||
|
|
||||||
if (draw->firstInstance > 0) {
|
if (draw->firstInstance > 0) {
|
||||||
@ -765,7 +755,7 @@ namespace dawn_native { namespace opengl {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::DrawIndexed: {
|
case Command::DrawIndexed: {
|
||||||
DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
|
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
||||||
inputBuffers.Apply(gl);
|
inputBuffers.Apply(gl);
|
||||||
|
|
||||||
dawn::IndexFormat indexFormat =
|
dawn::IndexFormat indexFormat =
|
||||||
@ -790,7 +780,7 @@ namespace dawn_native { namespace opengl {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::DrawIndirect: {
|
case Command::DrawIndirect: {
|
||||||
DrawIndirectCmd* draw = mCommands.NextCommand<DrawIndirectCmd>();
|
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
||||||
inputBuffers.Apply(gl);
|
inputBuffers.Apply(gl);
|
||||||
|
|
||||||
uint64_t indirectBufferOffset = draw->indirectOffset;
|
uint64_t indirectBufferOffset = draw->indirectOffset;
|
||||||
@ -803,7 +793,7 @@ namespace dawn_native { namespace opengl {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::DrawIndexedIndirect: {
|
case Command::DrawIndexedIndirect: {
|
||||||
DrawIndexedIndirectCmd* draw = mCommands.NextCommand<DrawIndexedIndirectCmd>();
|
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
||||||
inputBuffers.Apply(gl);
|
inputBuffers.Apply(gl);
|
||||||
|
|
||||||
dawn::IndexFormat indexFormat =
|
dawn::IndexFormat indexFormat =
|
||||||
@ -824,17 +814,60 @@ namespace dawn_native { namespace opengl {
|
|||||||
case Command::PushDebugGroup: {
|
case Command::PushDebugGroup: {
|
||||||
// Due to lack of linux driver support for GL_EXT_debug_marker
|
// Due to lack of linux driver support for GL_EXT_debug_marker
|
||||||
// extension these functions are skipped.
|
// extension these functions are skipped.
|
||||||
SkipCommand(&mCommands, type);
|
SkipCommand(iter, type);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetRenderPipeline: {
|
case Command::SetRenderPipeline: {
|
||||||
SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
|
SetRenderPipelineCmd* cmd = iter->NextCommand<SetRenderPipelineCmd>();
|
||||||
lastPipeline = ToBackend(cmd->pipeline).Get();
|
lastPipeline = ToBackend(cmd->pipeline).Get();
|
||||||
lastPipeline->ApplyNow(persistentPipelineState);
|
lastPipeline->ApplyNow(persistentPipelineState);
|
||||||
|
|
||||||
inputBuffers.OnSetPipeline(lastPipeline);
|
inputBuffers.OnSetPipeline(lastPipeline);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case Command::SetBindGroup: {
|
||||||
|
SetBindGroupCmd* cmd = iter->NextCommand<SetBindGroupCmd>();
|
||||||
|
uint64_t* dynamicOffsets = nullptr;
|
||||||
|
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);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::SetIndexBuffer: {
|
||||||
|
SetIndexBufferCmd* cmd = iter->NextCommand<SetIndexBufferCmd>();
|
||||||
|
indexBufferBaseOffset = cmd->offset;
|
||||||
|
inputBuffers.OnSetIndexBuffer(cmd->buffer.Get());
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::SetVertexBuffers: {
|
||||||
|
SetVertexBuffersCmd* cmd = iter->NextCommand<SetVertexBuffersCmd>();
|
||||||
|
auto buffers = iter->NextData<Ref<BufferBase>>(cmd->count);
|
||||||
|
auto offsets = iter->NextData<uint64_t>(cmd->count);
|
||||||
|
inputBuffers.OnSetVertexBuffers(cmd->startSlot, cmd->count, buffers, offsets);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Command type;
|
||||||
|
while (mCommands.NextCommandId(&type)) {
|
||||||
|
switch (type) {
|
||||||
|
case Command::EndRenderPass: {
|
||||||
|
mCommands.NextCommand<EndRenderPassCmd>();
|
||||||
|
|
||||||
|
if (renderPass->attachmentState->GetSampleCount() > 1) {
|
||||||
|
ResolveMultisampledRenderTargets(gl, renderPass);
|
||||||
|
}
|
||||||
|
gl.DeleteFramebuffers(1, &fbo);
|
||||||
|
return;
|
||||||
|
} break;
|
||||||
|
|
||||||
case Command::SetStencilReference: {
|
case Command::SetStencilReference: {
|
||||||
SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
|
SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
|
||||||
persistentPipelineState.SetStencilReference(gl, cmd->reference);
|
persistentPipelineState.SetStencilReference(gl, cmd->reference);
|
||||||
@ -856,31 +889,20 @@ namespace dawn_native { namespace opengl {
|
|||||||
gl.BlendColor(cmd->color.r, cmd->color.g, cmd->color.b, cmd->color.a);
|
gl.BlendColor(cmd->color.r, cmd->color.g, cmd->color.b, cmd->color.a);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetBindGroup: {
|
case Command::ExecuteBundles: {
|
||||||
SetBindGroupCmd* cmd = mCommands.NextCommand<SetBindGroupCmd>();
|
ExecuteBundlesCmd* cmd = mCommands.NextCommand<ExecuteBundlesCmd>();
|
||||||
uint64_t* dynamicOffsets = nullptr;
|
auto bundles = mCommands.NextData<Ref<RenderBundleBase>>(cmd->count);
|
||||||
if (cmd->dynamicOffsetCount > 0) {
|
|
||||||
dynamicOffsets = mCommands.NextData<uint64_t>(cmd->dynamicOffsetCount);
|
for (uint32_t i = 0; i < cmd->count; ++i) {
|
||||||
|
CommandIterator* iter = bundles[i]->GetCommands();
|
||||||
|
iter->Reset();
|
||||||
|
while (iter->NextCommandId(&type)) {
|
||||||
|
DoRenderBundleCommand(iter, type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ApplyBindGroup(gl, cmd->index, cmd->group.Get(),
|
|
||||||
ToBackend(lastPipeline->GetLayout()), lastPipeline,
|
|
||||||
cmd->dynamicOffsetCount, dynamicOffsets);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetIndexBuffer: {
|
default: { DoRenderBundleCommand(&mCommands, type); } break;
|
||||||
SetIndexBufferCmd* cmd = mCommands.NextCommand<SetIndexBufferCmd>();
|
|
||||||
indexBufferBaseOffset = cmd->offset;
|
|
||||||
inputBuffers.OnSetIndexBuffer(cmd->buffer.Get());
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::SetVertexBuffers: {
|
|
||||||
SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>();
|
|
||||||
auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count);
|
|
||||||
auto offsets = mCommands.NextData<uint64_t>(cmd->count);
|
|
||||||
inputBuffers.OnSetVertexBuffers(cmd->startSlot, cmd->count, buffers, offsets);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: { UNREACHABLE(); } break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "dawn_native/CommandEncoder.h"
|
#include "dawn_native/CommandEncoder.h"
|
||||||
#include "dawn_native/Commands.h"
|
#include "dawn_native/Commands.h"
|
||||||
|
#include "dawn_native/RenderBundle.h"
|
||||||
#include "dawn_native/vulkan/BindGroupVk.h"
|
#include "dawn_native/vulkan/BindGroupVk.h"
|
||||||
#include "dawn_native/vulkan/BufferVk.h"
|
#include "dawn_native/vulkan/BufferVk.h"
|
||||||
#include "dawn_native/vulkan/CommandRecordingContext.h"
|
#include "dawn_native/vulkan/CommandRecordingContext.h"
|
||||||
@ -671,17 +672,10 @@ namespace dawn_native { namespace vulkan {
|
|||||||
DescriptorSetTracker descriptorSets;
|
DescriptorSetTracker descriptorSets;
|
||||||
RenderPipeline* lastPipeline = nullptr;
|
RenderPipeline* lastPipeline = nullptr;
|
||||||
|
|
||||||
Command type;
|
auto EncodeRenderBundleCommand = [&](CommandIterator* iter, Command type) {
|
||||||
while (mCommands.NextCommandId(&type)) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Command::EndRenderPass: {
|
|
||||||
mCommands.NextCommand<EndRenderPassCmd>();
|
|
||||||
device->fn.CmdEndRenderPass(commands);
|
|
||||||
return;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::Draw: {
|
case Command::Draw: {
|
||||||
DrawCmd* draw = mCommands.NextCommand<DrawCmd>();
|
DrawCmd* draw = iter->NextCommand<DrawCmd>();
|
||||||
|
|
||||||
descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||||
device->fn.CmdDraw(commands, draw->vertexCount, draw->instanceCount,
|
device->fn.CmdDraw(commands, draw->vertexCount, draw->instanceCount,
|
||||||
@ -689,7 +683,7 @@ namespace dawn_native { namespace vulkan {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::DrawIndexed: {
|
case Command::DrawIndexed: {
|
||||||
DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
|
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
||||||
|
|
||||||
descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||||
device->fn.CmdDrawIndexed(commands, draw->indexCount, draw->instanceCount,
|
device->fn.CmdDrawIndexed(commands, draw->indexCount, draw->instanceCount,
|
||||||
@ -698,7 +692,7 @@ namespace dawn_native { namespace vulkan {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::DrawIndirect: {
|
case Command::DrawIndirect: {
|
||||||
DrawIndirectCmd* draw = mCommands.NextCommand<DrawIndirectCmd>();
|
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
||||||
VkBuffer indirectBuffer = ToBackend(draw->indirectBuffer)->GetHandle();
|
VkBuffer indirectBuffer = ToBackend(draw->indirectBuffer)->GetHandle();
|
||||||
|
|
||||||
descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||||
@ -708,7 +702,7 @@ namespace dawn_native { namespace vulkan {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::DrawIndexedIndirect: {
|
case Command::DrawIndexedIndirect: {
|
||||||
DrawIndirectCmd* draw = mCommands.NextCommand<DrawIndirectCmd>();
|
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
||||||
VkBuffer indirectBuffer = ToBackend(draw->indirectBuffer)->GetHandle();
|
VkBuffer indirectBuffer = ToBackend(draw->indirectBuffer)->GetHandle();
|
||||||
|
|
||||||
descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||||
@ -719,8 +713,8 @@ namespace dawn_native { namespace vulkan {
|
|||||||
|
|
||||||
case Command::InsertDebugMarker: {
|
case Command::InsertDebugMarker: {
|
||||||
if (device->GetDeviceInfo().debugMarker) {
|
if (device->GetDeviceInfo().debugMarker) {
|
||||||
InsertDebugMarkerCmd* cmd = mCommands.NextCommand<InsertDebugMarkerCmd>();
|
InsertDebugMarkerCmd* cmd = iter->NextCommand<InsertDebugMarkerCmd>();
|
||||||
const char* label = mCommands.NextData<char>(cmd->length + 1);
|
const char* label = iter->NextData<char>(cmd->length + 1);
|
||||||
VkDebugMarkerMarkerInfoEXT markerInfo;
|
VkDebugMarkerMarkerInfoEXT markerInfo;
|
||||||
markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
||||||
markerInfo.pNext = nullptr;
|
markerInfo.pNext = nullptr;
|
||||||
@ -732,23 +726,23 @@ namespace dawn_native { namespace vulkan {
|
|||||||
markerInfo.color[3] = 1.0;
|
markerInfo.color[3] = 1.0;
|
||||||
device->fn.CmdDebugMarkerInsertEXT(commands, &markerInfo);
|
device->fn.CmdDebugMarkerInsertEXT(commands, &markerInfo);
|
||||||
} else {
|
} else {
|
||||||
SkipCommand(&mCommands, Command::InsertDebugMarker);
|
SkipCommand(iter, Command::InsertDebugMarker);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::PopDebugGroup: {
|
case Command::PopDebugGroup: {
|
||||||
if (device->GetDeviceInfo().debugMarker) {
|
if (device->GetDeviceInfo().debugMarker) {
|
||||||
mCommands.NextCommand<PopDebugGroupCmd>();
|
iter->NextCommand<PopDebugGroupCmd>();
|
||||||
device->fn.CmdDebugMarkerEndEXT(commands);
|
device->fn.CmdDebugMarkerEndEXT(commands);
|
||||||
} else {
|
} else {
|
||||||
SkipCommand(&mCommands, Command::PopDebugGroup);
|
SkipCommand(iter, Command::PopDebugGroup);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::PushDebugGroup: {
|
case Command::PushDebugGroup: {
|
||||||
if (device->GetDeviceInfo().debugMarker) {
|
if (device->GetDeviceInfo().debugMarker) {
|
||||||
PushDebugGroupCmd* cmd = mCommands.NextCommand<PushDebugGroupCmd>();
|
PushDebugGroupCmd* cmd = iter->NextCommand<PushDebugGroupCmd>();
|
||||||
const char* label = mCommands.NextData<char>(cmd->length + 1);
|
const char* label = iter->NextData<char>(cmd->length + 1);
|
||||||
VkDebugMarkerMarkerInfoEXT markerInfo;
|
VkDebugMarkerMarkerInfoEXT markerInfo;
|
||||||
markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
||||||
markerInfo.pNext = nullptr;
|
markerInfo.pNext = nullptr;
|
||||||
@ -760,35 +754,24 @@ namespace dawn_native { namespace vulkan {
|
|||||||
markerInfo.color[3] = 1.0;
|
markerInfo.color[3] = 1.0;
|
||||||
device->fn.CmdDebugMarkerBeginEXT(commands, &markerInfo);
|
device->fn.CmdDebugMarkerBeginEXT(commands, &markerInfo);
|
||||||
} else {
|
} else {
|
||||||
SkipCommand(&mCommands, Command::PushDebugGroup);
|
SkipCommand(iter, Command::PushDebugGroup);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetBindGroup: {
|
case Command::SetBindGroup: {
|
||||||
SetBindGroupCmd* cmd = mCommands.NextCommand<SetBindGroupCmd>();
|
SetBindGroupCmd* cmd = iter->NextCommand<SetBindGroupCmd>();
|
||||||
VkDescriptorSet set = ToBackend(cmd->group.Get())->GetHandle();
|
VkDescriptorSet set = ToBackend(cmd->group.Get())->GetHandle();
|
||||||
uint64_t* dynamicOffsets = nullptr;
|
uint64_t* dynamicOffsets = nullptr;
|
||||||
if (cmd->dynamicOffsetCount > 0) {
|
if (cmd->dynamicOffsetCount > 0) {
|
||||||
dynamicOffsets = mCommands.NextData<uint64_t>(cmd->dynamicOffsetCount);
|
dynamicOffsets = iter->NextData<uint64_t>(cmd->dynamicOffsetCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptorSets.OnSetBindGroup(cmd->index, set, cmd->dynamicOffsetCount,
|
descriptorSets.OnSetBindGroup(cmd->index, set, cmd->dynamicOffsetCount,
|
||||||
dynamicOffsets);
|
dynamicOffsets);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetBlendColor: {
|
|
||||||
SetBlendColorCmd* cmd = mCommands.NextCommand<SetBlendColorCmd>();
|
|
||||||
float blendConstants[4] = {
|
|
||||||
cmd->color.r,
|
|
||||||
cmd->color.g,
|
|
||||||
cmd->color.b,
|
|
||||||
cmd->color.a,
|
|
||||||
};
|
|
||||||
device->fn.CmdSetBlendConstants(commands, blendConstants);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Command::SetIndexBuffer: {
|
case Command::SetIndexBuffer: {
|
||||||
SetIndexBufferCmd* cmd = mCommands.NextCommand<SetIndexBufferCmd>();
|
SetIndexBufferCmd* cmd = iter->NextCommand<SetIndexBufferCmd>();
|
||||||
VkBuffer indexBuffer = ToBackend(cmd->buffer)->GetHandle();
|
VkBuffer indexBuffer = ToBackend(cmd->buffer)->GetHandle();
|
||||||
|
|
||||||
// TODO(cwallez@chromium.org): get the index type from the last render pipeline
|
// TODO(cwallez@chromium.org): get the index type from the last render pipeline
|
||||||
@ -801,7 +784,7 @@ namespace dawn_native { namespace vulkan {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetRenderPipeline: {
|
case Command::SetRenderPipeline: {
|
||||||
SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
|
SetRenderPipelineCmd* cmd = iter->NextCommand<SetRenderPipelineCmd>();
|
||||||
RenderPipeline* pipeline = ToBackend(cmd->pipeline).Get();
|
RenderPipeline* pipeline = ToBackend(cmd->pipeline).Get();
|
||||||
|
|
||||||
device->fn.CmdBindPipeline(commands, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
device->fn.CmdBindPipeline(commands, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
@ -811,6 +794,50 @@ namespace dawn_native { namespace vulkan {
|
|||||||
descriptorSets.OnPipelineLayoutChange(ToBackend(pipeline->GetLayout()));
|
descriptorSets.OnPipelineLayoutChange(ToBackend(pipeline->GetLayout()));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case Command::SetVertexBuffers: {
|
||||||
|
SetVertexBuffersCmd* cmd = iter->NextCommand<SetVertexBuffersCmd>();
|
||||||
|
auto buffers = iter->NextData<Ref<BufferBase>>(cmd->count);
|
||||||
|
auto offsets = iter->NextData<uint64_t>(cmd->count);
|
||||||
|
|
||||||
|
std::array<VkBuffer, kMaxVertexBuffers> vkBuffers;
|
||||||
|
std::array<VkDeviceSize, kMaxVertexBuffers> vkOffsets;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < cmd->count; ++i) {
|
||||||
|
Buffer* buffer = ToBackend(buffers[i].Get());
|
||||||
|
vkBuffers[i] = buffer->GetHandle();
|
||||||
|
vkOffsets[i] = static_cast<VkDeviceSize>(offsets[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
device->fn.CmdBindVertexBuffers(commands, cmd->startSlot, cmd->count,
|
||||||
|
vkBuffers.data(), vkOffsets.data());
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Command type;
|
||||||
|
while (mCommands.NextCommandId(&type)) {
|
||||||
|
switch (type) {
|
||||||
|
case Command::EndRenderPass: {
|
||||||
|
mCommands.NextCommand<EndRenderPassCmd>();
|
||||||
|
device->fn.CmdEndRenderPass(commands);
|
||||||
|
return;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Command::SetBlendColor: {
|
||||||
|
SetBlendColorCmd* cmd = mCommands.NextCommand<SetBlendColorCmd>();
|
||||||
|
float blendConstants[4] = {
|
||||||
|
cmd->color.r,
|
||||||
|
cmd->color.g,
|
||||||
|
cmd->color.b,
|
||||||
|
cmd->color.a,
|
||||||
|
};
|
||||||
|
device->fn.CmdSetBlendConstants(commands, blendConstants);
|
||||||
|
} break;
|
||||||
|
|
||||||
case Command::SetStencilReference: {
|
case Command::SetStencilReference: {
|
||||||
SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
|
SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
|
||||||
device->fn.CmdSetStencilReference(commands, VK_STENCIL_FRONT_AND_BACK,
|
device->fn.CmdSetStencilReference(commands, VK_STENCIL_FRONT_AND_BACK,
|
||||||
@ -841,25 +868,20 @@ namespace dawn_native { namespace vulkan {
|
|||||||
device->fn.CmdSetScissor(commands, 0, 1, &rect);
|
device->fn.CmdSetScissor(commands, 0, 1, &rect);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetVertexBuffers: {
|
case Command::ExecuteBundles: {
|
||||||
SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>();
|
ExecuteBundlesCmd* cmd = mCommands.NextCommand<ExecuteBundlesCmd>();
|
||||||
auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count);
|
auto bundles = mCommands.NextData<Ref<RenderBundleBase>>(cmd->count);
|
||||||
auto offsets = mCommands.NextData<uint64_t>(cmd->count);
|
|
||||||
|
|
||||||
std::array<VkBuffer, kMaxVertexBuffers> vkBuffers;
|
|
||||||
std::array<VkDeviceSize, kMaxVertexBuffers> vkOffsets;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < cmd->count; ++i) {
|
for (uint32_t i = 0; i < cmd->count; ++i) {
|
||||||
Buffer* buffer = ToBackend(buffers[i].Get());
|
CommandIterator* iter = bundles[i]->GetCommands();
|
||||||
vkBuffers[i] = buffer->GetHandle();
|
iter->Reset();
|
||||||
vkOffsets[i] = static_cast<VkDeviceSize>(offsets[i]);
|
while (iter->NextCommandId(&type)) {
|
||||||
|
EncodeRenderBundleCommand(iter, type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
device->fn.CmdBindVertexBuffers(commands, cmd->startSlot, cmd->count,
|
|
||||||
vkBuffers.data(), vkOffsets.data());
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: { UNREACHABLE(); } break;
|
default: { EncodeRenderBundleCommand(&mCommands, type); } break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
210
src/tests/end2end/RenderBundleTests.cpp
Normal file
210
src/tests/end2end/RenderBundleTests.cpp
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
// Copyright 2019 The Dawn Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "tests/DawnTest.h"
|
||||||
|
|
||||||
|
#include "utils/ComboRenderBundleEncoderDescriptor.h"
|
||||||
|
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||||
|
#include "utils/DawnHelpers.h"
|
||||||
|
|
||||||
|
constexpr uint32_t kRTSize = 4;
|
||||||
|
constexpr RGBA8 kColors[2] = {RGBA8(0, 255, 0, 255), RGBA8(0, 0, 255, 255)};
|
||||||
|
|
||||||
|
// RenderBundleTest tests simple usage of RenderBundles to draw. The implementaiton
|
||||||
|
// of RenderBundle is shared significantly with render pass execution which is
|
||||||
|
// tested in all other rendering tests.
|
||||||
|
class RenderBundleTest : public DawnTest {
|
||||||
|
protected:
|
||||||
|
void SetUp() override {
|
||||||
|
DawnTest::SetUp();
|
||||||
|
|
||||||
|
renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
|
||||||
|
|
||||||
|
dawn::ShaderModule vsModule =
|
||||||
|
utils::CreateShaderModule(device, utils::ShaderStage::Vertex, R"(
|
||||||
|
#version 450
|
||||||
|
layout(location = 0) in vec4 pos;
|
||||||
|
void main() {
|
||||||
|
gl_Position = pos;
|
||||||
|
})");
|
||||||
|
|
||||||
|
dawn::ShaderModule fsModule =
|
||||||
|
utils::CreateShaderModule(device, utils::ShaderStage::Fragment, R"(
|
||||||
|
#version 450
|
||||||
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
layout (set = 0, binding = 0) uniform fragmentUniformBuffer {
|
||||||
|
vec4 color;
|
||||||
|
};
|
||||||
|
void main() {
|
||||||
|
fragColor = color;
|
||||||
|
})");
|
||||||
|
|
||||||
|
dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout(
|
||||||
|
device, {{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}});
|
||||||
|
|
||||||
|
float colors0[] = {kColors[0].r / 255.f, kColors[0].g / 255.f, kColors[0].b / 255.f,
|
||||||
|
kColors[0].a / 255.f};
|
||||||
|
float colors1[] = {kColors[1].r / 255.f, kColors[1].g / 255.f, kColors[1].b / 255.f,
|
||||||
|
kColors[1].a / 255.f};
|
||||||
|
|
||||||
|
dawn::Buffer buffer0 = utils::CreateBufferFromData(device, colors0, 4 * sizeof(float),
|
||||||
|
dawn::BufferUsageBit::Uniform);
|
||||||
|
dawn::Buffer buffer1 = utils::CreateBufferFromData(device, colors1, 4 * sizeof(float),
|
||||||
|
dawn::BufferUsageBit::Uniform);
|
||||||
|
|
||||||
|
bindGroups[0] = utils::MakeBindGroup(device, bgl, {{0, buffer0, 0, 4 * sizeof(float)}});
|
||||||
|
bindGroups[1] = utils::MakeBindGroup(device, bgl, {{0, buffer1, 0, 4 * sizeof(float)}});
|
||||||
|
|
||||||
|
dawn::PipelineLayoutDescriptor pipelineLayoutDesc;
|
||||||
|
pipelineLayoutDesc.bindGroupLayoutCount = 1;
|
||||||
|
pipelineLayoutDesc.bindGroupLayouts = &bgl;
|
||||||
|
|
||||||
|
dawn::PipelineLayout pipelineLayout = device.CreatePipelineLayout(&pipelineLayoutDesc);
|
||||||
|
|
||||||
|
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||||
|
descriptor.layout = pipelineLayout;
|
||||||
|
descriptor.cVertexStage.module = vsModule;
|
||||||
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
|
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
||||||
|
descriptor.cVertexInput.bufferCount = 1;
|
||||||
|
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
||||||
|
descriptor.cVertexInput.cBuffers[0].attributeCount = 1;
|
||||||
|
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
||||||
|
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||||
|
|
||||||
|
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
||||||
|
vertexBuffer = utils::CreateBufferFromData<float>(
|
||||||
|
device, dawn::BufferUsageBit::Vertex,
|
||||||
|
{// The bottom left triangle
|
||||||
|
-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
|
||||||
|
|
||||||
|
// The top right triangle
|
||||||
|
-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::BasicRenderPass renderPass;
|
||||||
|
dawn::RenderPipeline pipeline;
|
||||||
|
dawn::Buffer vertexBuffer;
|
||||||
|
dawn::BindGroup bindGroups[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Basic test of RenderBundle.
|
||||||
|
TEST_P(RenderBundleTest, Basic) {
|
||||||
|
utils::ComboRenderBundleEncoderDescriptor desc = {};
|
||||||
|
desc.colorFormatsCount = 1;
|
||||||
|
desc.cColorFormats[0] = renderPass.colorFormat;
|
||||||
|
|
||||||
|
dawn::RenderBundleEncoder renderBundleEncoder = device.CreateRenderBundleEncoder(&desc);
|
||||||
|
|
||||||
|
uint64_t zeroOffset = 0;
|
||||||
|
renderBundleEncoder.SetPipeline(pipeline);
|
||||||
|
renderBundleEncoder.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
||||||
|
renderBundleEncoder.SetBindGroup(0, bindGroups[0], 0, nullptr);
|
||||||
|
renderBundleEncoder.Draw(6, 1, 0, 0);
|
||||||
|
|
||||||
|
dawn::RenderBundle renderBundle = renderBundleEncoder.Finish();
|
||||||
|
|
||||||
|
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
|
||||||
|
dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
|
||||||
|
pass.ExecuteBundles(1, &renderBundle);
|
||||||
|
pass.EndPass();
|
||||||
|
|
||||||
|
dawn::CommandBuffer commands = encoder.Finish();
|
||||||
|
queue.Submit(1, &commands);
|
||||||
|
|
||||||
|
EXPECT_PIXEL_RGBA8_EQ(kColors[0], renderPass.color, 1, 3);
|
||||||
|
EXPECT_PIXEL_RGBA8_EQ(kColors[0], renderPass.color, 3, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test execution of multiple render bundles
|
||||||
|
TEST_P(RenderBundleTest, MultipleBundles) {
|
||||||
|
utils::ComboRenderBundleEncoderDescriptor desc = {};
|
||||||
|
desc.colorFormatsCount = 1;
|
||||||
|
desc.cColorFormats[0] = renderPass.colorFormat;
|
||||||
|
|
||||||
|
dawn::RenderBundle renderBundles[2];
|
||||||
|
uint64_t zeroOffset = 0;
|
||||||
|
{
|
||||||
|
dawn::RenderBundleEncoder renderBundleEncoder = device.CreateRenderBundleEncoder(&desc);
|
||||||
|
|
||||||
|
renderBundleEncoder.SetPipeline(pipeline);
|
||||||
|
renderBundleEncoder.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
||||||
|
renderBundleEncoder.SetBindGroup(0, bindGroups[0], 0, nullptr);
|
||||||
|
renderBundleEncoder.Draw(3, 1, 0, 0);
|
||||||
|
|
||||||
|
renderBundles[0] = renderBundleEncoder.Finish();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::RenderBundleEncoder renderBundleEncoder = device.CreateRenderBundleEncoder(&desc);
|
||||||
|
|
||||||
|
renderBundleEncoder.SetPipeline(pipeline);
|
||||||
|
renderBundleEncoder.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
||||||
|
renderBundleEncoder.SetBindGroup(0, bindGroups[1], 0, nullptr);
|
||||||
|
renderBundleEncoder.Draw(3, 1, 3, 0);
|
||||||
|
|
||||||
|
renderBundles[1] = renderBundleEncoder.Finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
|
||||||
|
dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
|
||||||
|
pass.ExecuteBundles(2, renderBundles);
|
||||||
|
pass.EndPass();
|
||||||
|
|
||||||
|
dawn::CommandBuffer commands = encoder.Finish();
|
||||||
|
queue.Submit(1, &commands);
|
||||||
|
|
||||||
|
EXPECT_PIXEL_RGBA8_EQ(kColors[0], renderPass.color, 1, 3);
|
||||||
|
EXPECT_PIXEL_RGBA8_EQ(kColors[1], renderPass.color, 3, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test execution of a bundle along with render pass commands.
|
||||||
|
TEST_P(RenderBundleTest, BundleAndRenderPassCommands) {
|
||||||
|
utils::ComboRenderBundleEncoderDescriptor desc = {};
|
||||||
|
desc.colorFormatsCount = 1;
|
||||||
|
desc.cColorFormats[0] = renderPass.colorFormat;
|
||||||
|
|
||||||
|
dawn::RenderBundleEncoder renderBundleEncoder = device.CreateRenderBundleEncoder(&desc);
|
||||||
|
|
||||||
|
uint64_t zeroOffset = 0;
|
||||||
|
renderBundleEncoder.SetPipeline(pipeline);
|
||||||
|
renderBundleEncoder.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
||||||
|
renderBundleEncoder.SetBindGroup(0, bindGroups[0], 0, nullptr);
|
||||||
|
renderBundleEncoder.Draw(3, 1, 0, 0);
|
||||||
|
|
||||||
|
dawn::RenderBundle renderBundle = renderBundleEncoder.Finish();
|
||||||
|
|
||||||
|
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
|
||||||
|
dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
|
||||||
|
pass.ExecuteBundles(1, &renderBundle);
|
||||||
|
|
||||||
|
pass.SetPipeline(pipeline);
|
||||||
|
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
||||||
|
pass.SetBindGroup(0, bindGroups[1], 0, nullptr);
|
||||||
|
pass.Draw(3, 1, 3, 0);
|
||||||
|
|
||||||
|
pass.ExecuteBundles(1, &renderBundle);
|
||||||
|
pass.EndPass();
|
||||||
|
|
||||||
|
dawn::CommandBuffer commands = encoder.Finish();
|
||||||
|
queue.Submit(1, &commands);
|
||||||
|
|
||||||
|
EXPECT_PIXEL_RGBA8_EQ(kColors[0], renderPass.color, 1, 3);
|
||||||
|
EXPECT_PIXEL_RGBA8_EQ(kColors[1], renderPass.color, 3, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
DAWN_INSTANTIATE_TEST(RenderBundleTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
|
Loading…
x
Reference in New Issue
Block a user