Deprecate ShaderModuleDescriptor.code in favor of chained descriptor
This also adds the definition of the WGSL sub descriptor but forbids using it for now. Bug: dawn:22 Change-Id: I0514eec95bbcda28911547d6bda4d5257b62432b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/19865 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Ryan Harrison <rharrison@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
21744d0fb8
commit
fee2783cb0
21
dawn.json
21
dawn.json
|
@ -1273,10 +1273,25 @@
|
||||||
"extensible": true,
|
"extensible": true,
|
||||||
"members": [
|
"members": [
|
||||||
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
|
{"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
|
||||||
|
{"name": "code size", "type": "uint32_t", "default": 0},
|
||||||
|
{"name": "code", "type": "uint32_t", "annotation": "const*", "length": "code size", "optional": true}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"shader module SPIRV descriptor": {
|
||||||
|
"category": "structure",
|
||||||
|
"chained": true,
|
||||||
|
"members": [
|
||||||
{"name": "code size", "type": "uint32_t"},
|
{"name": "code size", "type": "uint32_t"},
|
||||||
{"name": "code", "type": "uint32_t", "annotation": "const*", "length": "code size"}
|
{"name": "code", "type": "uint32_t", "annotation": "const*", "length": "code size"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"shader module WGSL descriptor": {
|
||||||
|
"category": "structure",
|
||||||
|
"chained": true,
|
||||||
|
"members": [
|
||||||
|
{"name": "source", "type": "char", "annotation": "const*", "length": "strlen"}
|
||||||
|
]
|
||||||
|
},
|
||||||
"shader stage": {
|
"shader stage": {
|
||||||
"category": "bitmask",
|
"category": "bitmask",
|
||||||
"values": [
|
"values": [
|
||||||
|
@ -1390,8 +1405,10 @@
|
||||||
{"value": 2, "name": "surface descriptor from windows HWND"},
|
{"value": 2, "name": "surface descriptor from windows HWND"},
|
||||||
{"value": 3, "name": "surface descriptor from xlib"},
|
{"value": 3, "name": "surface descriptor from xlib"},
|
||||||
{"value": 4, "name": "surface descriptor from HTML canvas id"},
|
{"value": 4, "name": "surface descriptor from HTML canvas id"},
|
||||||
{"value": 5, "name": "sampler descriptor dummy anisotropic filtering"},
|
{"value": 5, "name": "shader module SPIRV descriptor"},
|
||||||
{"value": 6, "name": "render pipeline descriptor dummy extension"}
|
{"value": 6, "name": "shader module WGSL descriptor"},
|
||||||
|
{"value": 7, "name": "sampler descriptor dummy anisotropic filtering"},
|
||||||
|
{"value": 8, "name": "render pipeline descriptor dummy extension"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"texture": {
|
"texture": {
|
||||||
|
|
|
@ -282,12 +282,7 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
MaybeError ValidateShaderModuleDescriptor(DeviceBase*,
|
MaybeError ValidateSpirv(DeviceBase*, const uint32_t* code, uint32_t codeSize) {
|
||||||
const ShaderModuleDescriptor* descriptor) {
|
|
||||||
if (descriptor->nextInChain != nullptr) {
|
|
||||||
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
|
|
||||||
}
|
|
||||||
|
|
||||||
spvtools::SpirvTools spirvTools(SPV_ENV_VULKAN_1_1);
|
spvtools::SpirvTools spirvTools(SPV_ENV_VULKAN_1_1);
|
||||||
|
|
||||||
std::ostringstream errorStream;
|
std::ostringstream errorStream;
|
||||||
|
@ -314,17 +309,68 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!spirvTools.Validate(descriptor->code, descriptor->codeSize)) {
|
if (!spirvTools.Validate(code, codeSize)) {
|
||||||
return DAWN_VALIDATION_ERROR(errorStream.str().c_str());
|
return DAWN_VALIDATION_ERROR(errorStream.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
MaybeError ValidateShaderModuleDescriptor(DeviceBase* device,
|
||||||
|
const ShaderModuleDescriptor* descriptor) {
|
||||||
|
if (descriptor->codeSize != 0) {
|
||||||
|
if (descriptor->nextInChain != nullptr) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Cannot set both code/codeSize and nextInChain");
|
||||||
|
}
|
||||||
|
|
||||||
|
device->EmitDeprecationWarning(
|
||||||
|
"ShaderModuleDescriptor::code/codeSize is deprecated, chain "
|
||||||
|
"ShaderModuleSPIRVDescriptor instead.");
|
||||||
|
return ValidateSpirv(device, descriptor->code, descriptor->codeSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For now only a single SPIRV or WGSL subdescriptor is allowed.
|
||||||
|
const ChainedStruct* chainedDescriptor = descriptor->nextInChain;
|
||||||
|
if (chainedDescriptor->nextInChain != nullptr) {
|
||||||
|
return DAWN_VALIDATION_ERROR("chained nextInChain must be nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (chainedDescriptor->sType) {
|
||||||
|
case wgpu::SType::ShaderModuleSPIRVDescriptor: {
|
||||||
|
const ShaderModuleSPIRVDescriptor* spirvDesc =
|
||||||
|
static_cast<const ShaderModuleSPIRVDescriptor*>(chainedDescriptor);
|
||||||
|
DAWN_TRY(ValidateSpirv(device, spirvDesc->code, spirvDesc->codeSize));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case wgpu::SType::ShaderModuleWGSLDescriptor: {
|
||||||
|
return DAWN_VALIDATION_ERROR("WGSL not supported (yet)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return DAWN_VALIDATION_ERROR("Unsupported sType");
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// ShaderModuleBase
|
// ShaderModuleBase
|
||||||
|
|
||||||
ShaderModuleBase::ShaderModuleBase(DeviceBase* device, const ShaderModuleDescriptor* descriptor)
|
ShaderModuleBase::ShaderModuleBase(DeviceBase* device, const ShaderModuleDescriptor* descriptor)
|
||||||
: CachedObject(device), mSpirv(descriptor->code, descriptor->code + descriptor->codeSize) {
|
: CachedObject(device) {
|
||||||
|
// Extract the correct SPIRV from the descriptor.
|
||||||
|
if (descriptor->codeSize != 0) {
|
||||||
|
mSpirv.assign(descriptor->code, descriptor->code + descriptor->codeSize);
|
||||||
|
} else {
|
||||||
|
ASSERT(descriptor->nextInChain != nullptr);
|
||||||
|
ASSERT(descriptor->nextInChain->sType == wgpu::SType::ShaderModuleSPIRVDescriptor);
|
||||||
|
|
||||||
|
const ShaderModuleSPIRVDescriptor* spirvDesc =
|
||||||
|
static_cast<const ShaderModuleSPIRVDescriptor*>(descriptor->nextInChain);
|
||||||
|
mSpirv.assign(spirvDesc->code, spirvDesc->code + spirvDesc->codeSize);
|
||||||
|
}
|
||||||
|
|
||||||
mFragmentOutputFormatBaseTypes.fill(Format::Other);
|
mFragmentOutputFormatBaseTypes.fill(Format::Other);
|
||||||
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvcParser)) {
|
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvcParser)) {
|
||||||
mSpvcContext.SetUseSpvcParser(true);
|
mSpvcContext.SetUseSpvcParser(true);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "tests/DawnTest.h"
|
#include "tests/DawnTest.h"
|
||||||
|
|
||||||
|
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||||
#include "utils/WGPUHelpers.h"
|
#include "utils/WGPUHelpers.h"
|
||||||
|
|
||||||
class DeprecationTests : public DawnTest {
|
class DeprecationTests : public DawnTest {
|
||||||
|
@ -307,6 +308,70 @@ TEST_P(DeprecationTests, BGDescBindingStateTracking) {
|
||||||
EXPECT_DEPRECATION_WARNING(ASSERT_DEVICE_ERROR(device.CreateBindGroup(&bgDesc)));
|
EXPECT_DEPRECATION_WARNING(ASSERT_DEVICE_ERROR(device.CreateBindGroup(&bgDesc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests for ShaderModuleDescriptor.code/codeSize -> ShaderModuleSPIRVDescriptor
|
||||||
|
|
||||||
|
static const char kEmptyShader[] = R"(#version 450
|
||||||
|
void main() {
|
||||||
|
})";
|
||||||
|
|
||||||
|
// That creating a ShaderModule without the chained descriptor gives a warning.
|
||||||
|
TEST_P(DeprecationTests, ShaderModuleNoSubDescriptorIsDeprecated) {
|
||||||
|
std::vector<uint32_t> spirv =
|
||||||
|
CompileGLSLToSpirv(utils::SingleShaderStage::Compute, kEmptyShader);
|
||||||
|
|
||||||
|
wgpu::ShaderModuleDescriptor descriptor = {
|
||||||
|
.codeSize = static_cast<uint32_t>(spirv.size()),
|
||||||
|
.code = spirv.data(),
|
||||||
|
};
|
||||||
|
EXPECT_DEPRECATION_WARNING(device.CreateShaderModule(&descriptor));
|
||||||
|
}
|
||||||
|
|
||||||
|
// That creating a ShaderModule with both inline code and the chained descriptor is an error.
|
||||||
|
TEST_P(DeprecationTests, ShaderModuleBothInlinedAndChainedIsInvalid) {
|
||||||
|
std::vector<uint32_t> spirv =
|
||||||
|
CompileGLSLToSpirv(utils::SingleShaderStage::Compute, kEmptyShader);
|
||||||
|
|
||||||
|
wgpu::ShaderModuleSPIRVDescriptor spirvDesc;
|
||||||
|
spirvDesc.codeSize = static_cast<uint32_t>(spirv.size());
|
||||||
|
spirvDesc.code = spirv.data();
|
||||||
|
|
||||||
|
wgpu::ShaderModuleDescriptor descriptor = {
|
||||||
|
.nextInChain = &spirvDesc,
|
||||||
|
.codeSize = static_cast<uint32_t>(spirv.size()),
|
||||||
|
.code = spirv.data(),
|
||||||
|
};
|
||||||
|
ASSERT_DEVICE_ERROR(device.CreateShaderModule(&descriptor));
|
||||||
|
}
|
||||||
|
|
||||||
|
// That creating a ShaderModule with both inline code still does correct state tracking
|
||||||
|
TEST_P(DeprecationTests, ShaderModuleInlinedCodeStateTracking) {
|
||||||
|
std::vector<uint32_t> spirv =
|
||||||
|
CompileGLSLToSpirv(utils::SingleShaderStage::Compute, kEmptyShader);
|
||||||
|
|
||||||
|
wgpu::ShaderModuleDescriptor descriptor = {
|
||||||
|
.codeSize = static_cast<uint32_t>(spirv.size()),
|
||||||
|
.code = spirv.data(),
|
||||||
|
};
|
||||||
|
wgpu::ShaderModule module;
|
||||||
|
EXPECT_DEPRECATION_WARNING(module = device.CreateShaderModule(&descriptor));
|
||||||
|
|
||||||
|
// Creating a compute pipeline works, because it is a compute module.
|
||||||
|
wgpu::ComputePipelineDescriptor computePipelineDesc = {
|
||||||
|
.computeStage =
|
||||||
|
{
|
||||||
|
.module = module,
|
||||||
|
.entryPoint = "main",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
device.CreateComputePipeline(&computePipelineDesc);
|
||||||
|
|
||||||
|
utils::ComboRenderPipelineDescriptor renderPipelineDesc(device);
|
||||||
|
renderPipelineDesc.vertexStage.module =
|
||||||
|
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, kEmptyShader);
|
||||||
|
renderPipelineDesc.cFragmentStage.module = module;
|
||||||
|
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&renderPipelineDesc));
|
||||||
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(DeprecationTests,
|
DAWN_INSTANTIATE_TEST(DeprecationTests,
|
||||||
D3D12Backend(),
|
D3D12Backend(),
|
||||||
MetalBackend(),
|
MetalBackend(),
|
||||||
|
|
|
@ -96,7 +96,6 @@ TEST_F(WireArgumentTests, ValueArrayArgument) {
|
||||||
TEST_F(WireArgumentTests, CStringArgument) {
|
TEST_F(WireArgumentTests, CStringArgument) {
|
||||||
// Create shader module
|
// Create shader module
|
||||||
WGPUShaderModuleDescriptor vertexDescriptor = {};
|
WGPUShaderModuleDescriptor vertexDescriptor = {};
|
||||||
vertexDescriptor.codeSize = 0;
|
|
||||||
WGPUShaderModule vsModule = wgpuDeviceCreateShaderModule(device, &vertexDescriptor);
|
WGPUShaderModule vsModule = wgpuDeviceCreateShaderModule(device, &vertexDescriptor);
|
||||||
WGPUShaderModule apiVsModule = api.GetNewShaderModule();
|
WGPUShaderModule apiVsModule = api.GetNewShaderModule();
|
||||||
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiVsModule));
|
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiVsModule));
|
||||||
|
|
|
@ -66,7 +66,6 @@ TEST_F(WireOptionalTests, OptionalObjectValue) {
|
||||||
TEST_F(WireOptionalTests, OptionalStructPointer) {
|
TEST_F(WireOptionalTests, OptionalStructPointer) {
|
||||||
// Create shader module
|
// Create shader module
|
||||||
WGPUShaderModuleDescriptor vertexDescriptor = {};
|
WGPUShaderModuleDescriptor vertexDescriptor = {};
|
||||||
vertexDescriptor.codeSize = 0;
|
|
||||||
WGPUShaderModule vsModule = wgpuDeviceCreateShaderModule(device, &vertexDescriptor);
|
WGPUShaderModule vsModule = wgpuDeviceCreateShaderModule(device, &vertexDescriptor);
|
||||||
WGPUShaderModule apiVsModule = api.GetNewShaderModule();
|
WGPUShaderModule apiVsModule = api.GetNewShaderModule();
|
||||||
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiVsModule));
|
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiVsModule));
|
||||||
|
|
|
@ -51,9 +51,13 @@ namespace utils {
|
||||||
ptrdiff_t resultSize = resultEnd - resultBegin;
|
ptrdiff_t resultSize = resultEnd - resultBegin;
|
||||||
// SetSource takes data as uint32_t*.
|
// SetSource takes data as uint32_t*.
|
||||||
|
|
||||||
|
wgpu::ShaderModuleSPIRVDescriptor spirvDesc;
|
||||||
|
spirvDesc.codeSize = static_cast<uint32_t>(resultSize);
|
||||||
|
spirvDesc.code = result.cbegin();
|
||||||
|
|
||||||
wgpu::ShaderModuleDescriptor descriptor;
|
wgpu::ShaderModuleDescriptor descriptor;
|
||||||
descriptor.codeSize = static_cast<uint32_t>(resultSize);
|
descriptor.nextInChain = &spirvDesc;
|
||||||
descriptor.code = result.cbegin();
|
|
||||||
return device.CreateShaderModule(&descriptor);
|
return device.CreateShaderModule(&descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +117,18 @@ namespace utils {
|
||||||
return CreateShaderModuleFromResult(device, result);
|
return CreateShaderModuleFromResult(device, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t> CompileGLSLToSpirv(SingleShaderStage stage, const char* source) {
|
||||||
|
shaderc_shader_kind kind = ShadercShaderKind(stage);
|
||||||
|
|
||||||
|
shaderc::Compiler compiler;
|
||||||
|
auto result = compiler.CompileGlslToSpv(source, strlen(source), kind, "myshader?");
|
||||||
|
if (result.GetCompilationStatus() != shaderc_compilation_status_success) {
|
||||||
|
dawn::ErrorLog() << result.GetErrorMessage();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return {result.cbegin(), result.cend()};
|
||||||
|
}
|
||||||
|
|
||||||
wgpu::Buffer CreateBufferFromData(const wgpu::Device& device,
|
wgpu::Buffer CreateBufferFromData(const wgpu::Device& device,
|
||||||
const void* data,
|
const void* data,
|
||||||
uint64_t size,
|
uint64_t size,
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace utils {
|
||||||
SingleShaderStage stage,
|
SingleShaderStage stage,
|
||||||
const char* source);
|
const char* source);
|
||||||
wgpu::ShaderModule CreateShaderModuleFromASM(const wgpu::Device& device, const char* source);
|
wgpu::ShaderModule CreateShaderModuleFromASM(const wgpu::Device& device, const char* source);
|
||||||
|
std::vector<uint32_t> CompileGLSLToSpirv(SingleShaderStage stage, const char* source);
|
||||||
|
|
||||||
wgpu::Buffer CreateBufferFromData(const wgpu::Device& device,
|
wgpu::Buffer CreateBufferFromData(const wgpu::Device& device,
|
||||||
const void* data,
|
const void* data,
|
||||||
|
|
Loading…
Reference in New Issue