writer/hlsl: Implement generation of module-scope vars

Implement emission of module scope variables of the private and workgroup storage classes.
Fix tests that were incorrectly emitting these as function-scope variables.

Change-Id: I509a7388794f4a57b06a3859d10afa2611d84991
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/48222
Commit-Queue: Ben Clayton <bclayton@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
Ben Clayton 2021-04-19 15:11:22 +00:00 committed by Commit Bot service account
parent 0c086c8ad0
commit 08031f326c
3 changed files with 47 additions and 37 deletions

View File

@ -1885,16 +1885,33 @@ bool GeneratorImpl::EmitEntryPointData(
continue; // Global already emitted continue; // Global already emitted
} }
if (var->StorageClass() == ast::StorageClass::kWorkgroup) { make_indent(out);
out << "groupshared ";
} else if (!unwrapped_type->IsAnyOf<type::Texture, type::Sampler>()) { std::ostringstream constructor_out;
continue; // Not interested in this type if (auto* constructor = decl->constructor()) {
if (!EmitExpression(out, constructor_out, constructor)) {
return false;
}
} }
if (!EmitType(out, var->DeclaredType(), var->StorageClass(), "")) { switch (var->StorageClass()) {
case ast::StorageClass::kPrivate:
case ast::StorageClass::kUniformConstant:
break;
case ast::StorageClass::kWorkgroup:
out << "groupshared ";
break;
default:
continue; // Not interested in this storage class
}
auto name = builder_.Symbols().NameFor(decl->symbol());
if (!EmitType(out, var->DeclaredType(), var->StorageClass(), name)) {
return false; return false;
} }
out << " " << builder_.Symbols().NameFor(decl->symbol()); if (!var->DeclaredType()->UnwrapAliasIfNeeded()->Is<type::Array>()) {
out << " " << name;
}
const char* register_space = nullptr; const char* register_space = nullptr;
@ -1917,6 +1934,10 @@ bool GeneratorImpl::EmitEntryPointData(
<< ", space" << bp.group->value() << ")"; << ", space" << bp.group->value() << ")";
} }
if (constructor_out.str().length()) {
out << " = " << constructor_out.str();
}
out << ";" << std::endl; out << ";" << std::endl;
add_newline = true; add_newline = true;

View File

@ -139,6 +139,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
float mem; float mem;
}; };
Data str;
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void test_function() { void test_function() {
float tint_symbol = str.mem; float tint_symbol = str.mem;

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "gmock/gmock.h"
#include "src/ast/variable_decl_statement.h" #include "src/ast/variable_decl_statement.h"
#include "src/writer/hlsl/test_helper.h" #include "src/writer/hlsl/test_helper.h"
@ -20,12 +21,14 @@ namespace writer {
namespace hlsl { namespace hlsl {
namespace { namespace {
using ::testing::HasSubstr;
using HlslGeneratorImplTest_VariableDecl = TestHelper; using HlslGeneratorImplTest_VariableDecl = TestHelper;
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement) { TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement) {
auto* var = Global("a", ty.f32(), ast::StorageClass::kInput); auto* var = Var("a", ty.f32(), ast::StorageClass::kFunction);
auto* stmt = create<ast::VariableDeclStatement>(var); auto* stmt = create<ast::VariableDeclStatement>(var);
WrapInFunction(stmt);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -37,7 +40,6 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement) {
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) { TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
auto* var = Const("a", ty.f32()); auto* var = Const("a", ty.f32());
auto* stmt = create<ast::VariableDeclStatement>(var); auto* stmt = create<ast::VariableDeclStatement>(var);
WrapInFunction(stmt); WrapInFunction(stmt);
@ -50,58 +52,43 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
} }
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Array) { TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Array) {
auto* var = Global("a", ty.array<f32, 5>(), ast::StorageClass::kInput); auto* var = Var("a", ty.array<f32, 5>(), ast::StorageClass::kFunction);
auto* stmt = create<ast::VariableDeclStatement>(var); WrapInFunction(var, Expr("a"));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error(); ASSERT_TRUE(gen.Generate(out)) << gen.error();
EXPECT_EQ(result(), " float a[5];\n"); EXPECT_THAT(result(), HasSubstr(" float a[5];\n"));
}
TEST_F(HlslGeneratorImplTest_VariableDecl,
Emit_VariableDeclStatement_Function) {
auto* var = Global("a", ty.f32(), ast::StorageClass::kFunction);
auto* stmt = create<ast::VariableDeclStatement>(var);
GeneratorImpl& gen = Build();
gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error();
EXPECT_EQ(result(), " float a;\n");
} }
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) { TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) {
auto* var = Global("a", ty.f32(), ast::StorageClass::kPrivate); Global("a", ty.f32(), ast::StorageClass::kPrivate);
auto* stmt = create<ast::VariableDeclStatement>(var); WrapInFunction(Expr("a"));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error(); ASSERT_TRUE(gen.Generate(out)) << gen.error();
EXPECT_EQ(result(), " float a;\n"); EXPECT_THAT(result(), HasSubstr(" float a;\n"));
} }
TEST_F(HlslGeneratorImplTest_VariableDecl, TEST_F(HlslGeneratorImplTest_VariableDecl,
Emit_VariableDeclStatement_Initializer_Private) { Emit_VariableDeclStatement_Initializer_Private) {
Global("initializer", ty.f32(), ast::StorageClass::kInput); Global("initializer", ty.f32(), ast::StorageClass::kInput);
auto* var = Global("a", ty.f32(), ast::StorageClass::kPrivate, Expr("initializer"));
Global("a", ty.f32(), ast::StorageClass::kPrivate, Expr("initializer"));
auto* stmt = create<ast::VariableDeclStatement>(var); WrapInFunction(Expr("a"));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitStatement(out, stmt)) << gen.error(); ASSERT_TRUE(gen.Generate(out)) << gen.error();
EXPECT_EQ(result(), R"(float a = initializer; EXPECT_THAT(result(), HasSubstr(R"(float a = initializer;
)"); )"));
} }
TEST_F(HlslGeneratorImplTest_VariableDecl, TEST_F(HlslGeneratorImplTest_VariableDecl,