Implementation of Debug Marker APIs
Introduces pushDebugGroup, popDebugGroup, and insertDebugMarker implementations for Vulkan and Metal using VK_EXT_debug_marker and XCode, respectively. Bug: dawn:44 Change-Id: I0ae56c4d67aa832123f27a1fcdddf65746261e57 Reviewed-on: https://dawn-review.googlesource.com/c/4241 Commit-Queue: Brandon Jones <brandon1.jones@intel.com> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
938811eef9
commit
11d32c8095
2
BUILD.gn
2
BUILD.gn
|
@ -944,6 +944,7 @@ test("dawn_unittests") {
|
|||
"src/tests/unittests/validation/CommandBufferValidationTests.cpp",
|
||||
"src/tests/unittests/validation/ComputeValidationTests.cpp",
|
||||
"src/tests/unittests/validation/CopyCommandsValidationTests.cpp",
|
||||
"src/tests/unittests/validation/DebugMarkerValidationTests.cpp",
|
||||
"src/tests/unittests/validation/DynamicStateCommandValidationTests.cpp",
|
||||
"src/tests/unittests/validation/FenceValidationTests.cpp",
|
||||
"src/tests/unittests/validation/InputStateValidationTests.cpp",
|
||||
|
@ -1002,6 +1003,7 @@ test("dawn_end2end_tests") {
|
|||
"src/tests/end2end/ColorStateTests.cpp",
|
||||
"src/tests/end2end/ComputeCopyStorageBufferTests.cpp",
|
||||
"src/tests/end2end/CopyTests.cpp",
|
||||
"src/tests/end2end/DebugMarkerTests.cpp",
|
||||
"src/tests/end2end/DepthStencilStateTests.cpp",
|
||||
"src/tests/end2end/DrawIndexedTests.cpp",
|
||||
"src/tests/end2end/DrawTests.cpp",
|
||||
|
|
32
dawn.json
32
dawn.json
|
@ -336,6 +336,22 @@
|
|||
"compute pass encoder": {
|
||||
"category": "object",
|
||||
"methods": [
|
||||
{
|
||||
"name": "insert debug marker",
|
||||
"args": [
|
||||
{"name": "group label", "type": "char", "annotation": "const*", "length": "strlen"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pop debug group",
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"name": "push debug group",
|
||||
"args": [
|
||||
{"name": "group label", "type": "char", "annotation": "const*", "length": "strlen"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set pipeline",
|
||||
"args": [
|
||||
|
@ -804,6 +820,22 @@
|
|||
{"name": "first instance", "type": "uint32_t"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "insert debug marker",
|
||||
"args": [
|
||||
{"name": "group label", "type": "char", "annotation": "const*", "length": "strlen"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pop debug group",
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"name": "push debug group",
|
||||
"args": [
|
||||
{"name": "group label", "type": "char", "annotation": "const*", "length": "strlen"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set stencil reference",
|
||||
"args": [
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
# Debug Markers
|
||||
|
||||
Dawn provides debug tooling integration for each backend.
|
||||
|
||||
Debugging markers are exposed through this API:
|
||||
```
|
||||
partial GPUProgrammablePassEncoder {
|
||||
void pushDebugGroup(const char * markerLabel);
|
||||
void popDebugGroup();
|
||||
void insertDebugMarker(const char * markerLabel);
|
||||
};
|
||||
```
|
||||
|
||||
These APIs will result in silent no-ops if they are used without setting up
|
||||
the execution environment properly. Each backend has a specific process
|
||||
for setting up this environment.
|
||||
|
||||
## D3D12
|
||||
|
||||
Debug markers are currently unimplemented on D3D12 pending resolution of a licensing issue.
|
||||
|
||||
## Vulkan
|
||||
|
||||
Debug markers on Vulkan are implemented with [VK_EXT_debug_marker](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VK_EXT_debug_marker).
|
||||
|
||||
To enable marker functionality, you must launch your application from your debugging tool. Attaching to an already running application is not supported.
|
||||
|
||||
Vulkan markers have been tested with [RenderDoc](https://renderdoc.org/).
|
||||
|
||||
## Metal
|
||||
|
||||
Debug markers on Metal are used with the XCode debugger.
|
||||
|
||||
To enable marker functionality, you must launch your application from XCode and use [GPU Frame Capture](https://developer.apple.com/documentation/metal/tools_profiling_and_debugging/metal_gpu_capture).
|
||||
|
||||
## OpenGL
|
||||
|
||||
Debug markers on OpenGL are not implemented and will result in a silent no-op. This is due to low adoption of the GL_EXT_debug_marker extension in Linux device drivers.
|
|
@ -94,6 +94,29 @@ namespace dawn_native {
|
|||
return {};
|
||||
}
|
||||
|
||||
inline MaybeError PushDebugMarkerStack(unsigned int* counter) {
|
||||
*counter += 1;
|
||||
return {};
|
||||
}
|
||||
|
||||
inline MaybeError PopDebugMarkerStack(unsigned int* counter) {
|
||||
if (*counter == 0) {
|
||||
return DAWN_VALIDATION_ERROR("Pop must be balanced by a corresponding Push.");
|
||||
} else {
|
||||
*counter -= 1;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
inline MaybeError ValidateDebugGroups(const unsigned int counter) {
|
||||
if (counter != 0) {
|
||||
return DAWN_VALIDATION_ERROR("Each Push must be balanced by a corresponding Pop.");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
MaybeError ComputeTextureCopyBufferSize(const Extent3D& copySize,
|
||||
uint32_t rowPitch,
|
||||
uint32_t imageHeight,
|
||||
|
@ -635,6 +658,8 @@ namespace dawn_native {
|
|||
case Command::EndComputePass: {
|
||||
mIterator.NextCommand<EndComputePassCmd>();
|
||||
|
||||
DAWN_TRY(ValidateDebugGroups(mDebugGroupStackSize));
|
||||
|
||||
DAWN_TRY(usageTracker.ValidateUsages(PassType::Compute));
|
||||
mResourceUsages.perPass.push_back(usageTracker.AcquireResourceUsage());
|
||||
return {};
|
||||
|
@ -645,6 +670,22 @@ namespace dawn_native {
|
|||
DAWN_TRY(persistentState.ValidateCanDispatch());
|
||||
} break;
|
||||
|
||||
case Command::InsertDebugMarker: {
|
||||
InsertDebugMarkerCmd* cmd = mIterator.NextCommand<InsertDebugMarkerCmd>();
|
||||
mIterator.NextData<char>(cmd->length + 1);
|
||||
} break;
|
||||
|
||||
case Command::PopDebugGroup: {
|
||||
mIterator.NextCommand<PopDebugGroupCmd>();
|
||||
DAWN_TRY(PopDebugMarkerStack(&mDebugGroupStackSize));
|
||||
} break;
|
||||
|
||||
case Command::PushDebugGroup: {
|
||||
PushDebugGroupCmd* cmd = mIterator.NextCommand<PushDebugGroupCmd>();
|
||||
mIterator.NextData<char>(cmd->length + 1);
|
||||
DAWN_TRY(PushDebugMarkerStack(&mDebugGroupStackSize));
|
||||
} break;
|
||||
|
||||
case Command::SetComputePipeline: {
|
||||
SetComputePipelineCmd* cmd = mIterator.NextCommand<SetComputePipelineCmd>();
|
||||
ComputePipelineBase* pipeline = cmd->pipeline.Get();
|
||||
|
@ -701,6 +742,8 @@ namespace dawn_native {
|
|||
case Command::EndRenderPass: {
|
||||
mIterator.NextCommand<EndRenderPassCmd>();
|
||||
|
||||
DAWN_TRY(ValidateDebugGroups(mDebugGroupStackSize));
|
||||
|
||||
DAWN_TRY(usageTracker.ValidateUsages(PassType::Render));
|
||||
mResourceUsages.perPass.push_back(usageTracker.AcquireResourceUsage());
|
||||
return {};
|
||||
|
@ -716,6 +759,22 @@ namespace dawn_native {
|
|||
DAWN_TRY(persistentState.ValidateCanDrawIndexed());
|
||||
} break;
|
||||
|
||||
case Command::InsertDebugMarker: {
|
||||
InsertDebugMarkerCmd* cmd = mIterator.NextCommand<InsertDebugMarkerCmd>();
|
||||
mIterator.NextData<char>(cmd->length + 1);
|
||||
} break;
|
||||
|
||||
case Command::PopDebugGroup: {
|
||||
mIterator.NextCommand<PopDebugGroupCmd>();
|
||||
DAWN_TRY(PopDebugMarkerStack(&mDebugGroupStackSize));
|
||||
} break;
|
||||
|
||||
case Command::PushDebugGroup: {
|
||||
PushDebugGroupCmd* cmd = mIterator.NextCommand<PushDebugGroupCmd>();
|
||||
mIterator.NextData<char>(cmd->length + 1);
|
||||
DAWN_TRY(PushDebugMarkerStack(&mDebugGroupStackSize));
|
||||
} break;
|
||||
|
||||
case Command::SetRenderPipeline: {
|
||||
SetRenderPipelineCmd* cmd = mIterator.NextCommand<SetRenderPipelineCmd>();
|
||||
RenderPipelineBase* pipeline = cmd->pipeline.Get();
|
||||
|
|
|
@ -87,6 +87,8 @@ namespace dawn_native {
|
|||
bool mWereResourceUsagesAcquired = false;
|
||||
CommandBufferResourceUsage mResourceUsages;
|
||||
|
||||
unsigned int mDebugGroupStackSize = 0;
|
||||
|
||||
bool mGotError = false;
|
||||
std::string mErrorMessage;
|
||||
};
|
||||
|
|
|
@ -69,6 +69,20 @@ namespace dawn_native {
|
|||
EndRenderPassCmd* cmd = commands->NextCommand<EndRenderPassCmd>();
|
||||
cmd->~EndRenderPassCmd();
|
||||
} break;
|
||||
case Command::InsertDebugMarker: {
|
||||
InsertDebugMarkerCmd* cmd = commands->NextCommand<InsertDebugMarkerCmd>();
|
||||
commands->NextData<char>(cmd->length + 1);
|
||||
cmd->~InsertDebugMarkerCmd();
|
||||
} break;
|
||||
case Command::PopDebugGroup: {
|
||||
PopDebugGroupCmd* cmd = commands->NextCommand<PopDebugGroupCmd>();
|
||||
cmd->~PopDebugGroupCmd();
|
||||
} break;
|
||||
case Command::PushDebugGroup: {
|
||||
PushDebugGroupCmd* cmd = commands->NextCommand<PushDebugGroupCmd>();
|
||||
commands->NextData<char>(cmd->length + 1);
|
||||
cmd->~PushDebugGroupCmd();
|
||||
} break;
|
||||
case Command::SetComputePipeline: {
|
||||
SetComputePipelineCmd* cmd = commands->NextCommand<SetComputePipelineCmd>();
|
||||
cmd->~SetComputePipelineCmd();
|
||||
|
@ -158,6 +172,20 @@ namespace dawn_native {
|
|||
commands->NextCommand<EndRenderPassCmd>();
|
||||
break;
|
||||
|
||||
case Command::InsertDebugMarker: {
|
||||
InsertDebugMarkerCmd* cmd = commands->NextCommand<InsertDebugMarkerCmd>();
|
||||
commands->NextData<char>(cmd->length + 1);
|
||||
} break;
|
||||
|
||||
case Command::PopDebugGroup:
|
||||
commands->NextCommand<PopDebugGroupCmd>();
|
||||
break;
|
||||
|
||||
case Command::PushDebugGroup: {
|
||||
PushDebugGroupCmd* cmd = commands->NextCommand<PushDebugGroupCmd>();
|
||||
commands->NextData<char>(cmd->length + 1);
|
||||
} break;
|
||||
|
||||
case Command::SetComputePipeline:
|
||||
commands->NextCommand<SetComputePipelineCmd>();
|
||||
break;
|
||||
|
|
|
@ -41,6 +41,9 @@ namespace dawn_native {
|
|||
DrawIndexed,
|
||||
EndComputePass,
|
||||
EndRenderPass,
|
||||
InsertDebugMarker,
|
||||
PopDebugGroup,
|
||||
PushDebugGroup,
|
||||
SetComputePipeline,
|
||||
SetRenderPipeline,
|
||||
SetPushConstants,
|
||||
|
@ -140,6 +143,16 @@ namespace dawn_native {
|
|||
|
||||
struct EndRenderPassCmd {};
|
||||
|
||||
struct InsertDebugMarkerCmd {
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
struct PopDebugGroupCmd {};
|
||||
|
||||
struct PushDebugGroupCmd {
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
struct SetComputePipelineCmd {
|
||||
Ref<ComputePipelineBase> pipeline;
|
||||
};
|
||||
|
|
|
@ -38,6 +38,30 @@ namespace dawn_native {
|
|||
mAllocator = nullptr;
|
||||
}
|
||||
|
||||
void ProgrammablePassEncoder::InsertDebugMarker(const char* groupLabel) {
|
||||
InsertDebugMarkerCmd* cmd =
|
||||
mAllocator->Allocate<InsertDebugMarkerCmd>(Command::InsertDebugMarker);
|
||||
new (cmd) InsertDebugMarkerCmd;
|
||||
cmd->length = strlen(groupLabel);
|
||||
|
||||
char* label = mAllocator->AllocateData<char>(cmd->length + 1);
|
||||
memcpy(label, groupLabel, cmd->length + 1);
|
||||
}
|
||||
|
||||
void ProgrammablePassEncoder::PopDebugGroup() {
|
||||
PopDebugGroupCmd* cmd = mAllocator->Allocate<PopDebugGroupCmd>(Command::PopDebugGroup);
|
||||
new (cmd) PopDebugGroupCmd;
|
||||
}
|
||||
|
||||
void ProgrammablePassEncoder::PushDebugGroup(const char* groupLabel) {
|
||||
PushDebugGroupCmd* cmd = mAllocator->Allocate<PushDebugGroupCmd>(Command::PushDebugGroup);
|
||||
new (cmd) PushDebugGroupCmd;
|
||||
cmd->length = strlen(groupLabel);
|
||||
|
||||
char* label = mAllocator->AllocateData<char>(cmd->length + 1);
|
||||
memcpy(label, groupLabel, cmd->length + 1);
|
||||
}
|
||||
|
||||
void ProgrammablePassEncoder::SetBindGroup(uint32_t groupIndex, BindGroupBase* group) {
|
||||
if (mTopLevelEncoder->ConsumedError(ValidateCanRecordCommands()) ||
|
||||
mTopLevelEncoder->ConsumedError(GetDevice()->ValidateObject(group))) {
|
||||
|
|
|
@ -35,6 +35,10 @@ namespace dawn_native {
|
|||
|
||||
void EndPass();
|
||||
|
||||
void InsertDebugMarker(const char* groupLabel);
|
||||
void PopDebugGroup();
|
||||
void PushDebugGroup(const char* groupLabel);
|
||||
|
||||
void SetBindGroup(uint32_t groupIndex, BindGroupBase* group);
|
||||
void SetPushConstants(dawn::ShaderStageBit stages,
|
||||
uint32_t offset,
|
||||
|
|
|
@ -696,6 +696,14 @@ namespace dawn_native { namespace d3d12 {
|
|||
draw->firstInstance);
|
||||
} break;
|
||||
|
||||
case Command::InsertDebugMarker:
|
||||
case Command::PopDebugGroup:
|
||||
case Command::PushDebugGroup: {
|
||||
// TODO(brandon1.jones@intel.com): Implement debug markers after PIX licensing
|
||||
// issue is resolved.
|
||||
SkipCommand(&mCommands, type);
|
||||
} break;
|
||||
|
||||
case Command::SetRenderPipeline: {
|
||||
SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
|
||||
RenderPipeline* pipeline = ToBackend(cmd->pipeline).Get();
|
||||
|
|
|
@ -435,6 +435,30 @@ namespace dawn_native { namespace metal {
|
|||
}
|
||||
} break;
|
||||
|
||||
case Command::InsertDebugMarker: {
|
||||
InsertDebugMarkerCmd* cmd = mCommands.NextCommand<InsertDebugMarkerCmd>();
|
||||
auto label = mCommands.NextData<char>(cmd->length + 1);
|
||||
NSString* mtlLabel = [[NSString alloc] initWithUTF8String:label];
|
||||
|
||||
[encoder insertDebugSignpost:mtlLabel];
|
||||
[mtlLabel release];
|
||||
} break;
|
||||
|
||||
case Command::PopDebugGroup: {
|
||||
mCommands.NextCommand<PopDebugGroupCmd>();
|
||||
|
||||
[encoder popDebugGroup];
|
||||
} break;
|
||||
|
||||
case Command::PushDebugGroup: {
|
||||
PushDebugGroupCmd* cmd = mCommands.NextCommand<PushDebugGroupCmd>();
|
||||
auto label = mCommands.NextData<char>(cmd->length + 1);
|
||||
NSString* mtlLabel = [[NSString alloc] initWithUTF8String:label];
|
||||
|
||||
[encoder pushDebugGroup:mtlLabel];
|
||||
[mtlLabel release];
|
||||
} break;
|
||||
|
||||
case Command::SetRenderPipeline: {
|
||||
SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
|
||||
lastPipeline = ToBackend(cmd->pipeline).Get();
|
||||
|
|
|
@ -637,6 +637,14 @@ namespace dawn_native { namespace opengl {
|
|||
}
|
||||
} break;
|
||||
|
||||
case Command::InsertDebugMarker:
|
||||
case Command::PopDebugGroup:
|
||||
case Command::PushDebugGroup: {
|
||||
// Due to lack of linux driver support for GL_EXT_debug_marker
|
||||
// extension these functions are skipped.
|
||||
SkipCommand(&mCommands, type);
|
||||
} break;
|
||||
|
||||
case Command::SetRenderPipeline: {
|
||||
SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
|
||||
lastPipeline = ToBackend(cmd->pipeline).Get();
|
||||
|
|
|
@ -432,6 +432,53 @@ namespace dawn_native { namespace vulkan {
|
|||
draw->firstInstance);
|
||||
} break;
|
||||
|
||||
case Command::InsertDebugMarker: {
|
||||
if (device->GetDeviceInfo().debugMarker) {
|
||||
InsertDebugMarkerCmd* cmd = mCommands.NextCommand<InsertDebugMarkerCmd>();
|
||||
const char* label = mCommands.NextData<char>(cmd->length + 1);
|
||||
VkDebugMarkerMarkerInfoEXT markerInfo;
|
||||
markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
||||
markerInfo.pNext = nullptr;
|
||||
markerInfo.pMarkerName = label;
|
||||
// Default color to black
|
||||
markerInfo.color[0] = 0.0;
|
||||
markerInfo.color[1] = 0.0;
|
||||
markerInfo.color[2] = 0.0;
|
||||
markerInfo.color[3] = 1.0;
|
||||
device->fn.CmdDebugMarkerInsertEXT(commands, &markerInfo);
|
||||
} else {
|
||||
SkipCommand(&mCommands, Command::InsertDebugMarker);
|
||||
}
|
||||
} break;
|
||||
|
||||
case Command::PopDebugGroup: {
|
||||
if (device->GetDeviceInfo().debugMarker) {
|
||||
mCommands.NextCommand<PopDebugGroupCmd>();
|
||||
device->fn.CmdDebugMarkerEndEXT(commands);
|
||||
} else {
|
||||
SkipCommand(&mCommands, Command::PopDebugGroup);
|
||||
}
|
||||
} break;
|
||||
|
||||
case Command::PushDebugGroup: {
|
||||
if (device->GetDeviceInfo().debugMarker) {
|
||||
PushDebugGroupCmd* cmd = mCommands.NextCommand<PushDebugGroupCmd>();
|
||||
const char* label = mCommands.NextData<char>(cmd->length + 1);
|
||||
VkDebugMarkerMarkerInfoEXT markerInfo;
|
||||
markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
||||
markerInfo.pNext = nullptr;
|
||||
markerInfo.pMarkerName = label;
|
||||
// Default color to black
|
||||
markerInfo.color[0] = 0.0;
|
||||
markerInfo.color[1] = 0.0;
|
||||
markerInfo.color[2] = 0.0;
|
||||
markerInfo.color[3] = 1.0;
|
||||
device->fn.CmdDebugMarkerBeginEXT(commands, &markerInfo);
|
||||
} else {
|
||||
SkipCommand(&mCommands, Command::PushDebugGroup);
|
||||
}
|
||||
} break;
|
||||
|
||||
case Command::SetBindGroup: {
|
||||
SetBindGroupCmd* cmd = mCommands.NextCommand<SetBindGroupCmd>();
|
||||
VkDescriptorSet set = ToBackend(cmd->group.Get())->GetHandle();
|
||||
|
|
|
@ -331,6 +331,11 @@ namespace dawn_native { namespace vulkan {
|
|||
std::vector<const char*> extensionsToRequest;
|
||||
std::vector<VkDeviceQueueCreateInfo> queuesToRequest;
|
||||
|
||||
if (mDeviceInfo.debugMarker) {
|
||||
extensionsToRequest.push_back(kExtensionNameExtDebugMarker);
|
||||
usedKnobs.debugMarker = true;
|
||||
}
|
||||
|
||||
if (mDeviceInfo.swapchain) {
|
||||
extensionsToRequest.push_back(kExtensionNameKhrSwapchain);
|
||||
usedKnobs.swapchain = true;
|
||||
|
|
|
@ -208,6 +208,12 @@ namespace dawn_native { namespace vulkan {
|
|||
GET_DEVICE_PROC(UpdateDescriptorSets);
|
||||
GET_DEVICE_PROC(WaitForFences);
|
||||
|
||||
if (usedKnobs.debugMarker) {
|
||||
GET_DEVICE_PROC(CmdDebugMarkerBeginEXT);
|
||||
GET_DEVICE_PROC(CmdDebugMarkerEndEXT);
|
||||
GET_DEVICE_PROC(CmdDebugMarkerInsertEXT);
|
||||
}
|
||||
|
||||
if (usedKnobs.swapchain) {
|
||||
GET_DEVICE_PROC(CreateSwapchainKHR);
|
||||
GET_DEVICE_PROC(DestroySwapchainKHR);
|
||||
|
|
|
@ -204,6 +204,11 @@ namespace dawn_native { namespace vulkan {
|
|||
PFN_vkUpdateDescriptorSets UpdateDescriptorSets = nullptr;
|
||||
PFN_vkWaitForFences WaitForFences = nullptr;
|
||||
|
||||
// VK_EXT_debug_marker
|
||||
PFN_vkCmdDebugMarkerBeginEXT CmdDebugMarkerBeginEXT = nullptr;
|
||||
PFN_vkCmdDebugMarkerEndEXT CmdDebugMarkerEndEXT = nullptr;
|
||||
PFN_vkCmdDebugMarkerInsertEXT CmdDebugMarkerInsertEXT = nullptr;
|
||||
|
||||
// VK_KHR_swapchain
|
||||
PFN_vkCreateSwapchainKHR CreateSwapchainKHR = nullptr;
|
||||
PFN_vkDestroySwapchainKHR DestroySwapchainKHR = nullptr;
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace dawn_native { namespace vulkan {
|
|||
const char kLayerNameLunargVKTrace[] = "VK_LAYER_LUNARG_vktrace";
|
||||
const char kLayerNameRenderDocCapture[] = "VK_LAYER_RENDERDOC_Capture";
|
||||
|
||||
const char kExtensionNameExtDebugMarker[] = "VK_EXT_debug_marker";
|
||||
const char kExtensionNameExtDebugReport[] = "VK_EXT_debug_report";
|
||||
const char kExtensionNameMvkMacosSurface[] = "VK_MVK_macos_surface";
|
||||
const char kExtensionNameKhrSurface[] = "VK_KHR_surface";
|
||||
|
@ -207,6 +208,10 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
|
||||
for (const auto& extension : info.extensions) {
|
||||
if (IsExtensionName(extension, kExtensionNameExtDebugMarker)) {
|
||||
info.debugMarker = true;
|
||||
}
|
||||
|
||||
if (IsExtensionName(extension, kExtensionNameKhrSwapchain)) {
|
||||
info.swapchain = true;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace dawn_native { namespace vulkan {
|
|||
extern const char kLayerNameLunargVKTrace[];
|
||||
extern const char kLayerNameRenderDocCapture[];
|
||||
|
||||
extern const char kExtensionNameExtDebugMarker[];
|
||||
extern const char kExtensionNameExtDebugReport[];
|
||||
extern const char kExtensionNameMvkMacosSurface[];
|
||||
extern const char kExtensionNameKhrSurface[];
|
||||
|
@ -66,6 +67,7 @@ namespace dawn_native { namespace vulkan {
|
|||
VkPhysicalDeviceFeatures features;
|
||||
|
||||
// Extensions
|
||||
bool debugMarker = false;
|
||||
bool swapchain = false;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
// 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/DawnHelpers.h"
|
||||
|
||||
class DebugMarkerTests : public DawnTest {};
|
||||
|
||||
// Make sure that calling a marker API without a debugging tool attached doesn't cause a failure.
|
||||
TEST_P(DebugMarkerTests, NoFailureWithoutDebugToolAttached) {
|
||||
utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 4, 4);
|
||||
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
{
|
||||
dawn::RenderPassEncoder pass = encoder.BeginRenderPass(renderPass.renderPassInfo);
|
||||
pass.PushDebugGroup("Event Start");
|
||||
pass.InsertDebugMarker("Marker");
|
||||
pass.PopDebugGroup();
|
||||
pass.EndPass();
|
||||
}
|
||||
|
||||
dawn::CommandBuffer commands = encoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(DebugMarkerTests, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend)
|
|
@ -0,0 +1,117 @@
|
|||
// 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/unittests/validation/ValidationTest.h"
|
||||
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
class DebugMarkerValidationTest : public ValidationTest {};
|
||||
|
||||
// Correct usage of debug markers should succeed in render pass.
|
||||
TEST_F(DebugMarkerValidationTest, RenderSuccess) {
|
||||
utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 4, 4);
|
||||
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
{
|
||||
dawn::RenderPassEncoder pass = encoder.BeginRenderPass(renderPass.renderPassInfo);
|
||||
pass.PushDebugGroup("Event Start");
|
||||
pass.PushDebugGroup("Event Start");
|
||||
pass.InsertDebugMarker("Marker");
|
||||
pass.PopDebugGroup();
|
||||
pass.PopDebugGroup();
|
||||
pass.EndPass();
|
||||
}
|
||||
|
||||
encoder.Finish();
|
||||
}
|
||||
|
||||
// A PushDebugGroup call without a following PopDebugGroup produces an error in render pass.
|
||||
TEST_F(DebugMarkerValidationTest, RenderUnbalancedPush) {
|
||||
utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 4, 4);
|
||||
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
{
|
||||
dawn::RenderPassEncoder pass = encoder.BeginRenderPass(renderPass.renderPassInfo);
|
||||
pass.PushDebugGroup("Event Start");
|
||||
pass.PushDebugGroup("Event Start");
|
||||
pass.InsertDebugMarker("Marker");
|
||||
pass.PopDebugGroup();
|
||||
pass.EndPass();
|
||||
}
|
||||
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
||||
|
||||
// A PopDebugGroup call without a preceding PushDebugGroup produces an error in render pass.
|
||||
TEST_F(DebugMarkerValidationTest, RenderUnbalancedPop) {
|
||||
utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 4, 4);
|
||||
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
{
|
||||
dawn::RenderPassEncoder pass = encoder.BeginRenderPass(renderPass.renderPassInfo);
|
||||
pass.PushDebugGroup("Event Start");
|
||||
pass.InsertDebugMarker("Marker");
|
||||
pass.PopDebugGroup();
|
||||
pass.PopDebugGroup();
|
||||
pass.EndPass();
|
||||
}
|
||||
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
||||
|
||||
// Correct usage of debug markers should succeed in compute pass.
|
||||
TEST_F(DebugMarkerValidationTest, ComputeSuccess) {
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
{
|
||||
dawn::ComputePassEncoder pass = encoder.BeginComputePass();
|
||||
pass.PushDebugGroup("Event Start");
|
||||
pass.PushDebugGroup("Event Start");
|
||||
pass.InsertDebugMarker("Marker");
|
||||
pass.PopDebugGroup();
|
||||
pass.PopDebugGroup();
|
||||
pass.EndPass();
|
||||
}
|
||||
|
||||
encoder.Finish();
|
||||
}
|
||||
|
||||
// A PushDebugGroup call without a following PopDebugGroup produces an error in compute pass.
|
||||
TEST_F(DebugMarkerValidationTest, ComputeUnbalancedPush) {
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
{
|
||||
dawn::ComputePassEncoder pass = encoder.BeginComputePass();
|
||||
pass.PushDebugGroup("Event Start");
|
||||
pass.PushDebugGroup("Event Start");
|
||||
pass.InsertDebugMarker("Marker");
|
||||
pass.PopDebugGroup();
|
||||
pass.EndPass();
|
||||
}
|
||||
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
||||
|
||||
// A PopDebugGroup call without a preceding PushDebugGroup produces an error in compute pass.
|
||||
TEST_F(DebugMarkerValidationTest, ComputeUnbalancedPop) {
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
{
|
||||
dawn::ComputePassEncoder pass = encoder.BeginComputePass();
|
||||
pass.PushDebugGroup("Event Start");
|
||||
pass.InsertDebugMarker("Marker");
|
||||
pass.PopDebugGroup();
|
||||
pass.PopDebugGroup();
|
||||
pass.EndPass();
|
||||
}
|
||||
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
Loading…
Reference in New Issue