Check bindingType with shader stage when creating default pipeline layout
This patch intends to fix a crash issue when creating a rendering pipeline with storage buffer declared in vertex shader and pipeline layout is not set. Without this patch, in PipelineLayoutBase::CreateDefault() the bindingSlot.visibility is always set to Fragment and Compute when it is a storage buffer, therefore a crash happens at the failure of the assertion modules->IsCompatibleWithPipelineLayout() when the storage buffer is actually declared in the vertex shader. BUG=dawn:276 TEST=dawn_unittests Change-Id: I56876a97d53ead5ed226dc1b9bbed1a77156b2b2 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/16564 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
parent
7d20b44501
commit
532be50b76
|
@ -23,6 +23,18 @@
|
||||||
|
|
||||||
namespace dawn_native {
|
namespace dawn_native {
|
||||||
|
|
||||||
|
MaybeError ValidateBindingTypeWithShaderStageVisibility(
|
||||||
|
wgpu::BindingType bindingType,
|
||||||
|
wgpu::ShaderStage shaderStageVisibility) {
|
||||||
|
if (bindingType == wgpu::BindingType::StorageBuffer &&
|
||||||
|
(shaderStageVisibility & wgpu::ShaderStage::Vertex) != 0) {
|
||||||
|
return DAWN_VALIDATION_ERROR(
|
||||||
|
"storage buffer binding is not supported in vertex shader");
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase*,
|
MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase*,
|
||||||
const BindGroupLayoutDescriptor* descriptor) {
|
const BindGroupLayoutDescriptor* descriptor) {
|
||||||
if (descriptor->nextInChain != nullptr) {
|
if (descriptor->nextInChain != nullptr) {
|
||||||
|
@ -49,11 +61,8 @@ namespace dawn_native {
|
||||||
return DAWN_VALIDATION_ERROR("some binding index was specified more than once");
|
return DAWN_VALIDATION_ERROR("some binding index was specified more than once");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binding.type == wgpu::BindingType::StorageBuffer &&
|
DAWN_TRY(
|
||||||
(binding.visibility & wgpu::ShaderStage::Vertex) != 0) {
|
ValidateBindingTypeWithShaderStageVisibility(binding.type, binding.visibility));
|
||||||
return DAWN_VALIDATION_ERROR(
|
|
||||||
"storage buffer binding is not supported in vertex shader");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (binding.type) {
|
switch (binding.type) {
|
||||||
case wgpu::BindingType::UniformBuffer:
|
case wgpu::BindingType::UniformBuffer:
|
||||||
|
|
|
@ -30,6 +30,10 @@ namespace dawn_native {
|
||||||
MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase*,
|
MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase*,
|
||||||
const BindGroupLayoutDescriptor* descriptor);
|
const BindGroupLayoutDescriptor* descriptor);
|
||||||
|
|
||||||
|
MaybeError ValidateBindingTypeWithShaderStageVisibility(
|
||||||
|
wgpu::BindingType bindingType,
|
||||||
|
wgpu::ShaderStage shaderStageVisibility);
|
||||||
|
|
||||||
class BindGroupLayoutBase : public CachedObject {
|
class BindGroupLayoutBase : public CachedObject {
|
||||||
public:
|
public:
|
||||||
BindGroupLayoutBase(DeviceBase* device, const BindGroupLayoutDescriptor* descriptor);
|
BindGroupLayoutBase(DeviceBase* device, const BindGroupLayoutDescriptor* descriptor);
|
||||||
|
|
|
@ -132,6 +132,9 @@ namespace dawn_native {
|
||||||
|
|
||||||
BindGroupLayoutBinding bindingSlot;
|
BindGroupLayoutBinding bindingSlot;
|
||||||
bindingSlot.binding = binding;
|
bindingSlot.binding = binding;
|
||||||
|
|
||||||
|
DAWN_TRY(ValidateBindingTypeWithShaderStageVisibility(
|
||||||
|
bindingInfo.type, StageBit(module->GetExecutionModel())));
|
||||||
if (bindingInfo.type == wgpu::BindingType::StorageBuffer) {
|
if (bindingInfo.type == wgpu::BindingType::StorageBuffer) {
|
||||||
bindingSlot.visibility =
|
bindingSlot.visibility =
|
||||||
wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute;
|
wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Compute;
|
||||||
|
|
|
@ -456,3 +456,24 @@ TEST_F(RenderPipelineValidationTest, TextureViewDimensionCompatibility) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that declaring a storage buffer in the vertex shader without setting pipeline layout won't
|
||||||
|
// cause crash.
|
||||||
|
TEST_F(RenderPipelineValidationTest, StorageBufferInVertexShaderNoLayout) {
|
||||||
|
wgpu::ShaderModule vsModuleWithStorageBuffer =
|
||||||
|
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
|
||||||
|
#version 450
|
||||||
|
#define kNumValues 100
|
||||||
|
layout(std430, set = 0, binding = 0) buffer Dst { uint dst[kNumValues]; };
|
||||||
|
void main() {
|
||||||
|
uint index = gl_VertexIndex;
|
||||||
|
dst[index] = 0x1234;
|
||||||
|
gl_Position = vec4(1.f, 0.f, 0.f, 1.f);
|
||||||
|
})");
|
||||||
|
|
||||||
|
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||||
|
descriptor.layout = nullptr;
|
||||||
|
descriptor.vertexStage.module = vsModuleWithStorageBuffer;
|
||||||
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
|
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue