mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-15 20:01:22 +00:00
[spirv-writer] Emit spec constants for non-constructor scalars.
In WGSL you can provide a constant_id variable without a constructor. In SPIR-V we must synthesize a constant to attach the SpecId too. This CL adds that variable creation. Bug: tint:254 Change-Id: I2f25fdc3cb7e2c9c0f9e2129885865bd24298416 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/29200 Commit-Queue: Sarah Mashayekhi <sarahmashay@google.com> Reviewed-by: Sarah Mashayekhi <sarahmashay@google.com>
This commit is contained in:
parent
d2d7ce6e31
commit
00000b57e8
@ -683,12 +683,39 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
|
|||||||
if (var->has_constructor()) {
|
if (var->has_constructor()) {
|
||||||
ops.push_back(Operand::Int(init_id));
|
ops.push_back(Operand::Int(init_id));
|
||||||
} else if (!var->type()->IsTexture() && !var->type()->IsSampler()) {
|
} else if (!var->type()->IsTexture() && !var->type()->IsSampler()) {
|
||||||
// If we don't have a constructor and we're an Output or Private variable
|
// Certain cases require us to generate a constructor value.
|
||||||
// then WGSL requires an initializer.
|
//
|
||||||
if (var->storage_class() == ast::StorageClass::kPrivate ||
|
// 1- ConstantId's must be attached to the OpConstant, if we have a
|
||||||
var->storage_class() == ast::StorageClass::kNone ||
|
// variable with a constant_id that doesn't have a constructor we make
|
||||||
var->storage_class() == ast::StorageClass::kOutput) {
|
// one
|
||||||
ast::NullLiteral nl(var->type()->UnwrapPtrIfNeeded());
|
// 2- If we don't have a constructor and we're an Output or Private variable
|
||||||
|
// then WGSL requires an initializer.
|
||||||
|
auto* type = var->type()->UnwrapPtrIfNeeded();
|
||||||
|
if (var->IsDecorated() && var->AsDecorated()->HasConstantIdDecoration()) {
|
||||||
|
if (type->IsF32()) {
|
||||||
|
ast::FloatLiteral l(type, 0.0f);
|
||||||
|
init_id = GenerateLiteralIfNeeded(var, &l);
|
||||||
|
} else if (type->IsU32()) {
|
||||||
|
ast::UintLiteral l(type, 0);
|
||||||
|
init_id = GenerateLiteralIfNeeded(var, &l);
|
||||||
|
} else if (type->IsI32()) {
|
||||||
|
ast::SintLiteral l(type, 0);
|
||||||
|
init_id = GenerateLiteralIfNeeded(var, &l);
|
||||||
|
} else if (type->IsBool()) {
|
||||||
|
ast::BoolLiteral l(type, false);
|
||||||
|
init_id = GenerateLiteralIfNeeded(var, &l);
|
||||||
|
} else {
|
||||||
|
error_ = "invalid type for constant_id, must be scalar";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (init_id == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ops.push_back(Operand::Int(init_id));
|
||||||
|
} else if (var->storage_class() == ast::StorageClass::kPrivate ||
|
||||||
|
var->storage_class() == ast::StorageClass::kNone ||
|
||||||
|
var->storage_class() == ast::StorageClass::kOutput) {
|
||||||
|
ast::NullLiteral nl(type);
|
||||||
init_id = GenerateLiteralIfNeeded(var, &nl);
|
init_id = GenerateLiteralIfNeeded(var, &nl);
|
||||||
if (init_id == 0) {
|
if (init_id == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include "src/ast/storage_class.h"
|
#include "src/ast/storage_class.h"
|
||||||
#include "src/ast/type/bool_type.h"
|
#include "src/ast/type/bool_type.h"
|
||||||
#include "src/ast/type/f32_type.h"
|
#include "src/ast/type/f32_type.h"
|
||||||
|
#include "src/ast/type/i32_type.h"
|
||||||
|
#include "src/ast/type/u32_type.h"
|
||||||
#include "src/ast/type/vector_type.h"
|
#include "src/ast/type/vector_type.h"
|
||||||
#include "src/ast/type_constructor_expression.h"
|
#include "src/ast/type_constructor_expression.h"
|
||||||
#include "src/ast/variable.h"
|
#include "src/ast/variable.h"
|
||||||
@ -389,6 +391,30 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Bool) {
|
|||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(BuilderTest, GlobalVar_ConstantId_Bool_NoConstructor) {
|
||||||
|
ast::type::BoolType bool_type;
|
||||||
|
|
||||||
|
ast::VariableDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::ConstantIdDecoration>(1200));
|
||||||
|
|
||||||
|
ast::DecoratedVariable v(std::make_unique<ast::Variable>(
|
||||||
|
"var", ast::StorageClass::kNone, &bool_type));
|
||||||
|
v.set_decorations(std::move(decos));
|
||||||
|
|
||||||
|
ast::Module mod;
|
||||||
|
Builder b(&mod);
|
||||||
|
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
||||||
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
|
)");
|
||||||
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %4 SpecId 1200
|
||||||
|
)");
|
||||||
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeBool
|
||||||
|
%2 = OpTypePointer Private %3
|
||||||
|
%4 = OpSpecConstantFalse %3
|
||||||
|
%1 = OpVariable %2 Private %4
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar) {
|
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar) {
|
||||||
ast::type::F32Type f32;
|
ast::type::F32Type f32;
|
||||||
|
|
||||||
@ -415,6 +441,78 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar) {
|
|||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_F32_NoConstructor) {
|
||||||
|
ast::type::F32Type f32;
|
||||||
|
|
||||||
|
ast::VariableDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0));
|
||||||
|
|
||||||
|
ast::DecoratedVariable v(
|
||||||
|
std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &f32));
|
||||||
|
v.set_decorations(std::move(decos));
|
||||||
|
|
||||||
|
ast::Module mod;
|
||||||
|
Builder b(&mod);
|
||||||
|
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
||||||
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
|
)");
|
||||||
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %4 SpecId 0
|
||||||
|
)");
|
||||||
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
|
||||||
|
%2 = OpTypePointer Private %3
|
||||||
|
%4 = OpSpecConstant %3 0
|
||||||
|
%1 = OpVariable %2 Private %4
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_I32_NoConstructor) {
|
||||||
|
ast::type::I32Type i32;
|
||||||
|
|
||||||
|
ast::VariableDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0));
|
||||||
|
|
||||||
|
ast::DecoratedVariable v(
|
||||||
|
std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &i32));
|
||||||
|
v.set_decorations(std::move(decos));
|
||||||
|
|
||||||
|
ast::Module mod;
|
||||||
|
Builder b(&mod);
|
||||||
|
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
||||||
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
|
)");
|
||||||
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %4 SpecId 0
|
||||||
|
)");
|
||||||
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
|
||||||
|
%2 = OpTypePointer Private %3
|
||||||
|
%4 = OpSpecConstant %3 0
|
||||||
|
%1 = OpVariable %2 Private %4
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_U32_NoConstructor) {
|
||||||
|
ast::type::U32Type u32;
|
||||||
|
|
||||||
|
ast::VariableDecorationList decos;
|
||||||
|
decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0));
|
||||||
|
|
||||||
|
ast::DecoratedVariable v(
|
||||||
|
std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &u32));
|
||||||
|
v.set_decorations(std::move(decos));
|
||||||
|
|
||||||
|
ast::Module mod;
|
||||||
|
Builder b(&mod);
|
||||||
|
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
|
||||||
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
|
||||||
|
)");
|
||||||
|
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %4 SpecId 0
|
||||||
|
)");
|
||||||
|
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 0
|
||||||
|
%2 = OpTypePointer Private %3
|
||||||
|
%4 = OpSpecConstant %3 0
|
||||||
|
%1 = OpVariable %2 Private %4
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
struct BuiltinData {
|
struct BuiltinData {
|
||||||
ast::Builtin builtin;
|
ast::Builtin builtin;
|
||||||
SpvBuiltIn result;
|
SpvBuiltIn result;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user