Add Labels For Pipelines and ShaderModule for D3D12/Vk
Adds labels for Pipelines and ShaderModule. Includes tests. Backend
functionality is implemented for Pipelines, and completed to best effort
for ShaderModule.
Bug: dawn:840
Change-Id: I55024a83f66d9fc2fc0e8b79e4b9a7ebc6f3cf1c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/62860
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Brandon Jones (Intel) <brandon1.jones@intel.com>
diff --git a/src/dawn_native/ComputePipeline.cpp b/src/dawn_native/ComputePipeline.cpp
index ca173a5..d1a4a8d 100644
--- a/src/dawn_native/ComputePipeline.cpp
+++ b/src/dawn_native/ComputePipeline.cpp
@@ -76,6 +76,7 @@
const ComputePipelineDescriptor* descriptor)
: PipelineBase(device,
descriptor->layout,
+ descriptor->label,
{{SingleShaderStage::Compute, descriptor->compute.module,
descriptor->compute.entryPoint}}) {
}
diff --git a/src/dawn_native/Pipeline.cpp b/src/dawn_native/Pipeline.cpp
index d1aa665..77dd79e 100644
--- a/src/dawn_native/Pipeline.cpp
+++ b/src/dawn_native/Pipeline.cpp
@@ -50,8 +50,9 @@
PipelineBase::PipelineBase(DeviceBase* device,
PipelineLayoutBase* layout,
+ const char* label,
std::vector<StageAndDescriptor> stages)
- : CachedObject(device, kLabelNotImplemented), mLayout(layout) {
+ : CachedObject(device, label), mLayout(layout) {
ASSERT(!stages.empty());
for (const StageAndDescriptor& stage : stages) {
diff --git a/src/dawn_native/Pipeline.h b/src/dawn_native/Pipeline.h
index 3ed80f1..baa2b2f 100644
--- a/src/dawn_native/Pipeline.h
+++ b/src/dawn_native/Pipeline.h
@@ -62,6 +62,7 @@
protected:
PipelineBase(DeviceBase* device,
PipelineLayoutBase* layout,
+ const char* label,
std::vector<StageAndDescriptor> stages);
PipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag);
diff --git a/src/dawn_native/RenderPipeline.cpp b/src/dawn_native/RenderPipeline.cpp
index decde9c..0e8da0b 100644
--- a/src/dawn_native/RenderPipeline.cpp
+++ b/src/dawn_native/RenderPipeline.cpp
@@ -473,6 +473,7 @@
const RenderPipelineDescriptor* descriptor)
: PipelineBase(device,
descriptor->layout,
+ descriptor->label,
{{SingleShaderStage::Vertex, descriptor->vertex.module,
descriptor->vertex.entryPoint},
{SingleShaderStage::Fragment, descriptor->fragment->module,
diff --git a/src/dawn_native/ShaderModule.cpp b/src/dawn_native/ShaderModule.cpp
index 4d9f173..f821606 100644
--- a/src/dawn_native/ShaderModule.cpp
+++ b/src/dawn_native/ShaderModule.cpp
@@ -1124,7 +1124,7 @@
// ShaderModuleBase
ShaderModuleBase::ShaderModuleBase(DeviceBase* device, const ShaderModuleDescriptor* descriptor)
- : CachedObject(device, kLabelNotImplemented), mType(Type::Undefined) {
+ : CachedObject(device, descriptor->label), mType(Type::Undefined) {
ASSERT(descriptor->nextInChain != nullptr);
const ShaderModuleSPIRVDescriptor* spirvDesc = nullptr;
FindInChain(descriptor->nextInChain, &spirvDesc);
diff --git a/src/dawn_native/d3d12/ComputePipelineD3D12.cpp b/src/dawn_native/d3d12/ComputePipelineD3D12.cpp
index 0682fd1..6649a47 100644
--- a/src/dawn_native/d3d12/ComputePipelineD3D12.cpp
+++ b/src/dawn_native/d3d12/ComputePipelineD3D12.cpp
@@ -57,6 +57,9 @@
DAWN_TRY(CheckHRESULT(
d3d12Device->CreateComputePipelineState(&d3dDesc, IID_PPV_ARGS(&mPipelineState)),
"D3D12 creating pipeline state"));
+
+ SetLabelImpl();
+
return {};
}
@@ -68,6 +71,11 @@
return mPipelineState.Get();
}
+ void ComputePipeline::SetLabelImpl() {
+ SetDebugName(ToBackend(GetDevice()), GetPipelineState(), "Dawn_ComputePipeline",
+ GetLabel());
+ }
+
void ComputePipeline::CreateAsync(Device* device,
std::unique_ptr<FlatComputePipelineDescriptor> descriptor,
size_t blueprintHash,
diff --git a/src/dawn_native/d3d12/ComputePipelineD3D12.h b/src/dawn_native/d3d12/ComputePipelineD3D12.h
index 089c7af..ddb3ea0 100644
--- a/src/dawn_native/d3d12/ComputePipelineD3D12.h
+++ b/src/dawn_native/d3d12/ComputePipelineD3D12.h
@@ -37,6 +37,9 @@
ID3D12PipelineState* GetPipelineState() const;
+ // Dawn API
+ void SetLabelImpl() override;
+
private:
~ComputePipeline() override;
using ComputePipelineBase::ComputePipelineBase;
diff --git a/src/dawn_native/d3d12/RenderPipelineD3D12.cpp b/src/dawn_native/d3d12/RenderPipelineD3D12.cpp
index d55e96b..20ef8c2 100644
--- a/src/dawn_native/d3d12/RenderPipelineD3D12.cpp
+++ b/src/dawn_native/d3d12/RenderPipelineD3D12.cpp
@@ -426,6 +426,9 @@
DAWN_TRY(CheckHRESULT(device->GetD3D12Device()->CreateGraphicsPipelineState(
&descriptorD3D12, IID_PPV_ARGS(&mPipelineState)),
"D3D12 create graphics pipeline state"));
+
+ SetLabelImpl();
+
return {};
}
@@ -445,6 +448,10 @@
return mFirstOffsetInfo;
}
+ void RenderPipeline::SetLabelImpl() {
+ SetDebugName(ToBackend(GetDevice()), GetPipelineState(), "Dawn_RenderPipeline", GetLabel());
+ }
+
D3D12_INPUT_LAYOUT_DESC RenderPipeline::ComputeInputLayout(
std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes>* inputElementDescriptors) {
unsigned int count = 0;
diff --git a/src/dawn_native/d3d12/RenderPipelineD3D12.h b/src/dawn_native/d3d12/RenderPipelineD3D12.h
index c99d0a1..67222f4 100644
--- a/src/dawn_native/d3d12/RenderPipelineD3D12.h
+++ b/src/dawn_native/d3d12/RenderPipelineD3D12.h
@@ -36,6 +36,9 @@
const FirstOffsetInfo& GetFirstOffsetInfo() const;
+ // Dawn API
+ void SetLabelImpl() override;
+
private:
~RenderPipeline() override;
using RenderPipelineBase::RenderPipelineBase;
diff --git a/src/dawn_native/vulkan/ComputePipelineVk.cpp b/src/dawn_native/vulkan/ComputePipelineVk.cpp
index 90b2369..4cabbb1 100644
--- a/src/dawn_native/vulkan/ComputePipelineVk.cpp
+++ b/src/dawn_native/vulkan/ComputePipelineVk.cpp
@@ -68,10 +68,19 @@
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT);
}
- return CheckVkSuccess(
+ DAWN_TRY(CheckVkSuccess(
device->fn.CreateComputePipelines(device->GetVkDevice(), ::VK_NULL_HANDLE, 1,
&createInfo, nullptr, &*mHandle),
- "CreateComputePipeline");
+ "CreateComputePipeline"));
+
+ SetLabelImpl();
+
+ return {};
+ }
+
+ void ComputePipeline::SetLabelImpl() {
+ SetDebugName(ToBackend(GetDevice()), VK_OBJECT_TYPE_PIPELINE,
+ reinterpret_cast<uint64_t&>(mHandle), "Dawn_ComputePipeline", GetLabel());
}
ComputePipeline::~ComputePipeline() {
diff --git a/src/dawn_native/vulkan/ComputePipelineVk.h b/src/dawn_native/vulkan/ComputePipelineVk.h
index 221a358..7afe9cf 100644
--- a/src/dawn_native/vulkan/ComputePipelineVk.h
+++ b/src/dawn_native/vulkan/ComputePipelineVk.h
@@ -37,6 +37,9 @@
VkPipeline GetHandle() const;
+ // Dawn API
+ void SetLabelImpl() override;
+
private:
~ComputePipeline() override;
using ComputePipelineBase::ComputePipelineBase;
diff --git a/src/dawn_native/vulkan/RenderPipelineVk.cpp b/src/dawn_native/vulkan/RenderPipelineVk.cpp
index 79dbb40..74a2a88 100644
--- a/src/dawn_native/vulkan/RenderPipelineVk.cpp
+++ b/src/dawn_native/vulkan/RenderPipelineVk.cpp
@@ -515,10 +515,19 @@
createInfo.basePipelineHandle = VkPipeline{};
createInfo.basePipelineIndex = -1;
- return CheckVkSuccess(
+ DAWN_TRY(CheckVkSuccess(
device->fn.CreateGraphicsPipelines(device->GetVkDevice(), VkPipelineCache{}, 1,
&createInfo, nullptr, &*mHandle),
- "CreateGraphicsPipeline");
+ "CreateGraphicsPipeline"));
+
+ SetLabelImpl();
+
+ return {};
+ }
+
+ void RenderPipeline::SetLabelImpl() {
+ SetDebugName(ToBackend(GetDevice()), VK_OBJECT_TYPE_PIPELINE,
+ reinterpret_cast<uint64_t&>(mHandle), "Dawn_RenderPipeline", GetLabel());
}
VkPipelineVertexInputStateCreateInfo RenderPipeline::ComputeVertexInputDesc(
diff --git a/src/dawn_native/vulkan/RenderPipelineVk.h b/src/dawn_native/vulkan/RenderPipelineVk.h
index 7dfc468..9339bb6 100644
--- a/src/dawn_native/vulkan/RenderPipelineVk.h
+++ b/src/dawn_native/vulkan/RenderPipelineVk.h
@@ -32,6 +32,9 @@
VkPipeline GetHandle() const;
+ // Dawn API
+ void SetLabelImpl() override;
+
private:
~RenderPipeline() override;
using RenderPipelineBase::RenderPipelineBase;
diff --git a/src/dawn_native/vulkan/ShaderModuleVk.cpp b/src/dawn_native/vulkan/ShaderModuleVk.cpp
index 798424e..cbc004b 100644
--- a/src/dawn_native/vulkan/ShaderModuleVk.cpp
+++ b/src/dawn_native/vulkan/ShaderModuleVk.cpp
@@ -20,6 +20,7 @@
#include "dawn_native/vulkan/DeviceVk.h"
#include "dawn_native/vulkan/FencedDeleter.h"
#include "dawn_native/vulkan/PipelineLayoutVk.h"
+#include "dawn_native/vulkan/UtilsVulkan.h"
#include "dawn_native/vulkan/VulkanError.h"
#include <tint/tint.h>
@@ -187,6 +188,9 @@
mTransformedShaderModuleCache.AddOrGetCachedShaderModule(cacheKey, newHandle);
}
+ SetDebugName(ToBackend(GetDevice()), VK_OBJECT_TYPE_SHADER_MODULE,
+ reinterpret_cast<uint64_t&>(newHandle), "Dawn_ShaderModule", GetLabel());
+
return newHandle;
}
diff --git a/src/tests/unittests/validation/LabelTests.cpp b/src/tests/unittests/validation/LabelTests.cpp
index 4cb2a24..0208876 100644
--- a/src/tests/unittests/validation/LabelTests.cpp
+++ b/src/tests/unittests/validation/LabelTests.cpp
@@ -8,12 +8,14 @@
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WvecANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// 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 <string>
#include "tests/unittests/validation/ValidationTest.h"
+#include "utils/ComboRenderPipelineDescriptor.h"
+#include "utils/WGPUHelpers.h"
class LabelTest : public ValidationTest {};
@@ -83,4 +85,120 @@
std::string readbackLabel = dawn_native::GetObjectLabelForTesting(texture.Get());
ASSERT_EQ(label, readbackLabel);
}
+}
+
+TEST_F(LabelTest, RenderPipeline) {
+ DAWN_SKIP_TEST_IF(UsesWire());
+ std::string label = "test";
+
+ wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
+ [[stage(vertex)]] fn main() -> [[builtin(position)]] vec4<f32> {
+ return vec4<f32>(0.0, 0.0, 0.0, 1.0);
+ })");
+
+ wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
+ [[stage(fragment)]] fn main() -> [[location(0)]] vec4<f32> {
+ return vec4<f32>(0.0, 1.0, 0.0, 1.0);
+ })");
+
+ utils::ComboRenderPipelineDescriptor descriptor;
+ descriptor.vertex.module = vsModule;
+ descriptor.cFragment.module = fsModule;
+
+ // The label should be empty if one was not set.
+ {
+ wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
+ std::string readbackLabel = dawn_native::GetObjectLabelForTesting(pipeline.Get());
+ ASSERT_TRUE(readbackLabel.empty());
+ }
+
+ // Test setting a label through API
+ {
+ wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
+ pipeline.SetLabel(label.c_str());
+ std::string readbackLabel = dawn_native::GetObjectLabelForTesting(pipeline.Get());
+ ASSERT_EQ(label, readbackLabel);
+ }
+
+ // Test setting a label through the descriptor.
+ {
+ descriptor.label = label.c_str();
+ wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
+ std::string readbackLabel = dawn_native::GetObjectLabelForTesting(pipeline.Get());
+ ASSERT_EQ(label, readbackLabel);
+ }
+}
+
+TEST_F(LabelTest, ComputePipeline) {
+ DAWN_SKIP_TEST_IF(UsesWire());
+ std::string label = "test";
+
+ wgpu::ShaderModule computeModule = utils::CreateShaderModule(device, R"(
+ [[stage(compute), workgroup_size(1)]] fn main() {
+ })");
+ wgpu::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, nullptr);
+ wgpu::ComputePipelineDescriptor descriptor;
+ descriptor.layout = pl;
+ descriptor.compute.module = computeModule;
+ descriptor.compute.entryPoint = "main";
+
+ // The label should be empty if one was not set.
+ {
+ wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&descriptor);
+ std::string readbackLabel = dawn_native::GetObjectLabelForTesting(pipeline.Get());
+ ASSERT_TRUE(readbackLabel.empty());
+ }
+
+ // Test setting a label through API
+ {
+ wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&descriptor);
+ pipeline.SetLabel(label.c_str());
+ std::string readbackLabel = dawn_native::GetObjectLabelForTesting(pipeline.Get());
+ ASSERT_EQ(label, readbackLabel);
+ }
+
+ // Test setting a label through the descriptor.
+ {
+ descriptor.label = label.c_str();
+ wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&descriptor);
+ std::string readbackLabel = dawn_native::GetObjectLabelForTesting(pipeline.Get());
+ ASSERT_EQ(label, readbackLabel);
+ }
+}
+
+TEST_F(LabelTest, ShaderModule) {
+ DAWN_SKIP_TEST_IF(UsesWire());
+ std::string label = "test";
+
+ const char* source = R"(
+ [[stage(compute), workgroup_size(1)]] fn main() {
+ })";
+
+ wgpu::ShaderModuleWGSLDescriptor wgslDesc;
+ wgslDesc.source = source;
+ wgpu::ShaderModuleDescriptor descriptor;
+ descriptor.nextInChain = &wgslDesc;
+
+ // The label should be empty if one was not set.
+ {
+ wgpu::ShaderModule shaderModule = device.CreateShaderModule(&descriptor);
+ std::string readbackLabel = dawn_native::GetObjectLabelForTesting(shaderModule.Get());
+ ASSERT_TRUE(readbackLabel.empty());
+ }
+
+ // Test setting a label through API
+ {
+ wgpu::ShaderModule shaderModule = device.CreateShaderModule(&descriptor);
+ shaderModule.SetLabel(label.c_str());
+ std::string readbackLabel = dawn_native::GetObjectLabelForTesting(shaderModule.Get());
+ ASSERT_EQ(label, readbackLabel);
+ }
+
+ // Test setting a label through the descriptor.
+ {
+ descriptor.label = label.c_str();
+ wgpu::ShaderModule shaderModule = device.CreateShaderModule(&descriptor);
+ std::string readbackLabel = dawn_native::GetObjectLabelForTesting(shaderModule.Get());
+ ASSERT_EQ(label, readbackLabel);
+ }
}
\ No newline at end of file