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>
This commit is contained in:
Brandon Jones 2021-09-02 18:39:53 +00:00 committed by Dawn LUCI CQ
parent 71f2214e14
commit c1bcbbf357
16 changed files with 200 additions and 7 deletions

View File

@ -618,6 +618,13 @@
"args": [
{"name": "group index", "type": "uint32_t"}
]
},
{
"name": "set label",
"returns": "void",
"args": [
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen"}
]
}
]
},
@ -1547,7 +1554,15 @@
"args": [
{"name": "group index", "type": "uint32_t"}
]
},
{
"name": "set label",
"returns": "void",
"args": [
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen"}
]
}
]
},
@ -1679,6 +1694,13 @@
{"name": "callback", "type": "compilation info callback"},
{"name": "userdata", "type": "void", "annotation": "*"}
]
},
{
"name": "set label",
"returns": "void",
"args": [
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen"}
]
}
]
},

View File

@ -76,6 +76,7 @@ namespace dawn_native {
const ComputePipelineDescriptor* descriptor)
: PipelineBase(device,
descriptor->layout,
descriptor->label,
{{SingleShaderStage::Compute, descriptor->compute.module,
descriptor->compute.entryPoint}}) {
}

View File

@ -50,8 +50,9 @@ namespace dawn_native {
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) {

View File

@ -62,6 +62,7 @@ namespace dawn_native {
protected:
PipelineBase(DeviceBase* device,
PipelineLayoutBase* layout,
const char* label,
std::vector<StageAndDescriptor> stages);
PipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag);

View File

@ -473,6 +473,7 @@ namespace dawn_native {
const RenderPipelineDescriptor* descriptor)
: PipelineBase(device,
descriptor->layout,
descriptor->label,
{{SingleShaderStage::Vertex, descriptor->vertex.module,
descriptor->vertex.entryPoint},
{SingleShaderStage::Fragment, descriptor->fragment->module,

View File

@ -1124,7 +1124,7 @@ namespace dawn_native {
// 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);

View File

@ -57,6 +57,9 @@ namespace dawn_native { namespace d3d12 {
DAWN_TRY(CheckHRESULT(
d3d12Device->CreateComputePipelineState(&d3dDesc, IID_PPV_ARGS(&mPipelineState)),
"D3D12 creating pipeline state"));
SetLabelImpl();
return {};
}
@ -68,6 +71,11 @@ namespace dawn_native { namespace d3d12 {
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,

View File

@ -37,6 +37,9 @@ namespace dawn_native { namespace d3d12 {
ID3D12PipelineState* GetPipelineState() const;
// Dawn API
void SetLabelImpl() override;
private:
~ComputePipeline() override;
using ComputePipelineBase::ComputePipelineBase;

View File

@ -426,6 +426,9 @@ namespace dawn_native { namespace d3d12 {
DAWN_TRY(CheckHRESULT(device->GetD3D12Device()->CreateGraphicsPipelineState(
&descriptorD3D12, IID_PPV_ARGS(&mPipelineState)),
"D3D12 create graphics pipeline state"));
SetLabelImpl();
return {};
}
@ -445,6 +448,10 @@ namespace dawn_native { namespace d3d12 {
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;

View File

@ -36,6 +36,9 @@ namespace dawn_native { namespace d3d12 {
const FirstOffsetInfo& GetFirstOffsetInfo() const;
// Dawn API
void SetLabelImpl() override;
private:
~RenderPipeline() override;
using RenderPipelineBase::RenderPipelineBase;

View File

@ -68,10 +68,19 @@ namespace dawn_native { namespace vulkan {
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() {

View File

@ -37,6 +37,9 @@ namespace dawn_native { namespace vulkan {
VkPipeline GetHandle() const;
// Dawn API
void SetLabelImpl() override;
private:
~ComputePipeline() override;
using ComputePipelineBase::ComputePipelineBase;

View File

@ -515,10 +515,19 @@ namespace dawn_native { namespace vulkan {
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(

View File

@ -32,6 +32,9 @@ namespace dawn_native { namespace vulkan {
VkPipeline GetHandle() const;
// Dawn API
void SetLabelImpl() override;
private:
~RenderPipeline() override;
using RenderPipelineBase::RenderPipelineBase;

View File

@ -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 @@ namespace dawn_native { namespace vulkan {
mTransformedShaderModuleCache.AddOrGetCachedShaderModule(cacheKey, newHandle);
}
SetDebugName(ToBackend(GetDevice()), VK_OBJECT_TYPE_SHADER_MODULE,
reinterpret_cast<uint64_t&>(newHandle), "Dawn_ShaderModule", GetLabel());
return newHandle;
}

View File

@ -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 {};
@ -84,3 +86,119 @@ TEST_F(LabelTest, Texture) {
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);
}
}