Add instance step mode to vertex pulling transform
Bug: dawn:480 Change-Id: Icf650b7f340528e6a49d68d155fd9becc212e623 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/26440 Reviewed-by: dan sinclair <dsinclair@chromium.org> Commit-Queue: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
63551e3b2f
commit
ef6a4af7b5
|
@ -48,6 +48,7 @@ static const char kVertexBufferNamePrefix[] = "tint_pulling_vertex_buffer_";
|
||||||
static const char kStructBufferName[] = "data";
|
static const char kStructBufferName[] = "data";
|
||||||
static const char kPullingPosVarName[] = "tint_pulling_pos";
|
static const char kPullingPosVarName[] = "tint_pulling_pos";
|
||||||
static const char kDefaultVertexIndexName[] = "tint_pulling_vertex_index";
|
static const char kDefaultVertexIndexName[] = "tint_pulling_vertex_index";
|
||||||
|
static const char kDefaultInstanceIndexName[] = "tint_pulling_instance_index";
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
VertexPullingTransform::VertexPullingTransform(Context* ctx, Module* mod)
|
VertexPullingTransform::VertexPullingTransform(Context* ctx, Module* mod)
|
||||||
|
@ -100,7 +101,8 @@ bool VertexPullingTransform::Run() {
|
||||||
// TODO(idanr): Make sure we covered all error cases, to guarantee the
|
// TODO(idanr): Make sure we covered all error cases, to guarantee the
|
||||||
// following stages will pass
|
// following stages will pass
|
||||||
|
|
||||||
FindOrInsertVertexIndex();
|
FindOrInsertVertexIndexIfUsed();
|
||||||
|
FindOrInsertInstanceIndexIfUsed();
|
||||||
ConvertVertexInputVariablesToPrivate();
|
ConvertVertexInputVariablesToPrivate();
|
||||||
AddVertexStorageBuffers();
|
AddVertexStorageBuffers();
|
||||||
AddVertexPullingPreamble(vertex_func);
|
AddVertexPullingPreamble(vertex_func);
|
||||||
|
@ -116,7 +118,19 @@ std::string VertexPullingTransform::GetVertexBufferName(uint32_t index) {
|
||||||
return kVertexBufferNamePrefix + std::to_string(index);
|
return kVertexBufferNamePrefix + std::to_string(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexPullingTransform::FindOrInsertVertexIndex() {
|
void VertexPullingTransform::FindOrInsertVertexIndexIfUsed() {
|
||||||
|
bool uses_vertex_step_mode = false;
|
||||||
|
for (const VertexBufferLayoutDescriptor& buffer_layout :
|
||||||
|
vertex_state_->vertex_buffers) {
|
||||||
|
if (buffer_layout.step_mode == InputStepMode::kVertex) {
|
||||||
|
uses_vertex_step_mode = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!uses_vertex_step_mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Look for an existing vertex index builtin
|
// Look for an existing vertex index builtin
|
||||||
for (auto& v : mod_->global_variables()) {
|
for (auto& v : mod_->global_variables()) {
|
||||||
if (!v->IsDecorated() || v->storage_class() != StorageClass::kInput) {
|
if (!v->IsDecorated() || v->storage_class() != StorageClass::kInput) {
|
||||||
|
@ -145,6 +159,47 @@ void VertexPullingTransform::FindOrInsertVertexIndex() {
|
||||||
mod_->AddGlobalVariable(std::move(var));
|
mod_->AddGlobalVariable(std::move(var));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VertexPullingTransform::FindOrInsertInstanceIndexIfUsed() {
|
||||||
|
bool uses_instance_step_mode = false;
|
||||||
|
for (const VertexBufferLayoutDescriptor& buffer_layout :
|
||||||
|
vertex_state_->vertex_buffers) {
|
||||||
|
if (buffer_layout.step_mode == InputStepMode::kInstance) {
|
||||||
|
uses_instance_step_mode = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!uses_instance_step_mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for an existing instance index builtin
|
||||||
|
for (auto& v : mod_->global_variables()) {
|
||||||
|
if (!v->IsDecorated() || v->storage_class() != StorageClass::kInput) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& d : v->AsDecorated()->decorations()) {
|
||||||
|
if (d->IsBuiltin() && d->AsBuiltin()->value() == Builtin::kInstanceIdx) {
|
||||||
|
instance_index_name_ = v->name();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We didn't find an instance index builtin, so create one
|
||||||
|
instance_index_name_ = kDefaultInstanceIndexName;
|
||||||
|
|
||||||
|
auto var = std::make_unique<DecoratedVariable>(std::make_unique<Variable>(
|
||||||
|
instance_index_name_, StorageClass::kInput, GetI32Type()));
|
||||||
|
|
||||||
|
VariableDecorationList decorations;
|
||||||
|
decorations.push_back(
|
||||||
|
std::make_unique<BuiltinDecoration>(Builtin::kInstanceIdx));
|
||||||
|
|
||||||
|
var->set_decorations(std::move(decorations));
|
||||||
|
mod_->AddGlobalVariable(std::move(var));
|
||||||
|
}
|
||||||
|
|
||||||
void VertexPullingTransform::ConvertVertexInputVariablesToPrivate() {
|
void VertexPullingTransform::ConvertVertexInputVariablesToPrivate() {
|
||||||
for (auto& v : mod_->global_variables()) {
|
for (auto& v : mod_->global_variables()) {
|
||||||
if (!v->IsDecorated() || v->storage_class() != StorageClass::kInput) {
|
if (!v->IsDecorated() || v->storage_class() != StorageClass::kInput) {
|
||||||
|
@ -228,12 +283,17 @@ void VertexPullingTransform::AddVertexPullingPreamble(Function* vertex_func) {
|
||||||
}
|
}
|
||||||
auto* v = it->second;
|
auto* v = it->second;
|
||||||
|
|
||||||
|
// Identifier to index by
|
||||||
|
auto index_identifier = std::make_unique<IdentifierExpression>(
|
||||||
|
buffer_layout.step_mode == InputStepMode::kVertex
|
||||||
|
? vertex_index_name_
|
||||||
|
: instance_index_name_);
|
||||||
|
|
||||||
// An expression for the start of the read in the buffer in bytes
|
// An expression for the start of the read in the buffer in bytes
|
||||||
auto pos_value = std::make_unique<BinaryExpression>(
|
auto pos_value = std::make_unique<BinaryExpression>(
|
||||||
BinaryOp::kAdd,
|
BinaryOp::kAdd,
|
||||||
std::make_unique<BinaryExpression>(
|
std::make_unique<BinaryExpression>(
|
||||||
BinaryOp::kMultiply,
|
BinaryOp::kMultiply, std::move(index_identifier),
|
||||||
std::make_unique<IdentifierExpression>(vertex_index_name_),
|
|
||||||
GenUint(static_cast<uint32_t>(buffer_layout.array_stride))),
|
GenUint(static_cast<uint32_t>(buffer_layout.array_stride))),
|
||||||
GenUint(static_cast<uint32_t>(attribute_desc.offset)));
|
GenUint(static_cast<uint32_t>(attribute_desc.offset)));
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,10 @@ class VertexPullingTransform {
|
||||||
std::string GetVertexBufferName(uint32_t index);
|
std::string GetVertexBufferName(uint32_t index);
|
||||||
|
|
||||||
/// Inserts vertex_idx binding, or finds the existing one
|
/// Inserts vertex_idx binding, or finds the existing one
|
||||||
void FindOrInsertVertexIndex();
|
void FindOrInsertVertexIndexIfUsed();
|
||||||
|
|
||||||
|
/// Inserts instance_idx binding, or finds the existing one
|
||||||
|
void FindOrInsertInstanceIndexIfUsed();
|
||||||
|
|
||||||
/// Converts var<in> with a location decoration to var<private>
|
/// Converts var<in> with a location decoration to var<private>
|
||||||
void ConvertVertexInputVariablesToPrivate();
|
void ConvertVertexInputVariablesToPrivate();
|
||||||
|
@ -237,6 +240,7 @@ class VertexPullingTransform {
|
||||||
std::string error_;
|
std::string error_;
|
||||||
|
|
||||||
std::string vertex_index_name_;
|
std::string vertex_index_name_;
|
||||||
|
std::string instance_index_name_;
|
||||||
|
|
||||||
std::unordered_map<uint32_t, Variable*> location_to_var_;
|
std::unordered_map<uint32_t, Variable*> location_to_var_;
|
||||||
std::unique_ptr<VertexStateDescriptor> vertex_state_;
|
std::unique_ptr<VertexStateDescriptor> vertex_state_;
|
||||||
|
|
|
@ -201,15 +201,97 @@ TEST_F(VertexPullingTransformTest, OneAttribute) {
|
||||||
mod()->to_str());
|
mod()->to_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// We expect the transform to use an existing vertex_idx builtin variable if it
|
TEST_F(VertexPullingTransformTest, OneInstancedAttribute) {
|
||||||
// finds one
|
|
||||||
TEST_F(VertexPullingTransformTest, ExistingVertexIndex) {
|
|
||||||
InitBasicModule();
|
InitBasicModule();
|
||||||
|
|
||||||
type::F32Type f32;
|
type::F32Type f32;
|
||||||
AddVertexInputVariable(0, "var_a", &f32);
|
AddVertexInputVariable(0, "var_a", &f32);
|
||||||
|
|
||||||
|
InitTransform(
|
||||||
|
{{{4, InputStepMode::kInstance, {{VertexFormat::kF32, 0, 0}}}}});
|
||||||
|
|
||||||
|
EXPECT_TRUE(transform()->Run());
|
||||||
|
|
||||||
|
EXPECT_EQ(R"(Module{
|
||||||
|
Variable{
|
||||||
|
var_a
|
||||||
|
private
|
||||||
|
__f32
|
||||||
|
}
|
||||||
|
DecoratedVariable{
|
||||||
|
Decorations{
|
||||||
|
BuiltinDecoration{instance_idx}
|
||||||
|
}
|
||||||
|
tint_pulling_instance_index
|
||||||
|
in
|
||||||
|
__i32
|
||||||
|
}
|
||||||
|
DecoratedVariable{
|
||||||
|
Decorations{
|
||||||
|
BindingDecoration{0}
|
||||||
|
SetDecoration{0}
|
||||||
|
}
|
||||||
|
tint_pulling_vertex_buffer_0
|
||||||
|
storage_buffer
|
||||||
|
__struct_
|
||||||
|
}
|
||||||
|
EntryPoint{vertex as main = vtx_main}
|
||||||
|
Function vtx_main -> __void
|
||||||
|
()
|
||||||
|
{
|
||||||
|
Block{
|
||||||
|
VariableDeclStatement{
|
||||||
|
Variable{
|
||||||
|
tint_pulling_pos
|
||||||
|
function
|
||||||
|
__i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assignment{
|
||||||
|
Identifier{tint_pulling_pos}
|
||||||
|
Binary{
|
||||||
|
Binary{
|
||||||
|
Identifier{tint_pulling_instance_index}
|
||||||
|
multiply
|
||||||
|
ScalarConstructor{4}
|
||||||
|
}
|
||||||
|
add
|
||||||
|
ScalarConstructor{0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assignment{
|
||||||
|
Identifier{var_a}
|
||||||
|
As<__f32>{
|
||||||
|
ArrayAccessor{
|
||||||
|
MemberAccessor{
|
||||||
|
Identifier{tint_pulling_vertex_buffer_0}
|
||||||
|
Identifier{data}
|
||||||
|
}
|
||||||
|
Binary{
|
||||||
|
Identifier{tint_pulling_pos}
|
||||||
|
divide
|
||||||
|
ScalarConstructor{4}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)",
|
||||||
|
mod()->to_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// We expect the transform to use an existing builtin variables if it finds them
|
||||||
|
TEST_F(VertexPullingTransformTest, ExistingVertexIndexAndInstanceIndex) {
|
||||||
|
InitBasicModule();
|
||||||
|
|
||||||
|
type::F32Type f32;
|
||||||
|
AddVertexInputVariable(0, "var_a", &f32);
|
||||||
|
AddVertexInputVariable(1, "var_b", &f32);
|
||||||
|
|
||||||
type::I32Type i32;
|
type::I32Type i32;
|
||||||
|
{
|
||||||
auto vertex_index_var =
|
auto vertex_index_var =
|
||||||
std::make_unique<DecoratedVariable>(std::make_unique<Variable>(
|
std::make_unique<DecoratedVariable>(std::make_unique<Variable>(
|
||||||
"custom_vertex_index", StorageClass::kInput, &i32));
|
"custom_vertex_index", StorageClass::kInput, &i32));
|
||||||
|
@ -220,8 +302,24 @@ TEST_F(VertexPullingTransformTest, ExistingVertexIndex) {
|
||||||
|
|
||||||
vertex_index_var->set_decorations(std::move(decorations));
|
vertex_index_var->set_decorations(std::move(decorations));
|
||||||
mod()->AddGlobalVariable(std::move(vertex_index_var));
|
mod()->AddGlobalVariable(std::move(vertex_index_var));
|
||||||
|
}
|
||||||
|
|
||||||
InitTransform({{{4, InputStepMode::kVertex, {{VertexFormat::kF32, 0, 0}}}}});
|
{
|
||||||
|
auto instance_index_var =
|
||||||
|
std::make_unique<DecoratedVariable>(std::make_unique<Variable>(
|
||||||
|
"custom_instance_index", StorageClass::kInput, &i32));
|
||||||
|
|
||||||
|
VariableDecorationList decorations;
|
||||||
|
decorations.push_back(
|
||||||
|
std::make_unique<BuiltinDecoration>(Builtin::kInstanceIdx));
|
||||||
|
|
||||||
|
instance_index_var->set_decorations(std::move(decorations));
|
||||||
|
mod()->AddGlobalVariable(std::move(instance_index_var));
|
||||||
|
}
|
||||||
|
|
||||||
|
InitTransform(
|
||||||
|
{{{4, InputStepMode::kVertex, {{VertexFormat::kF32, 0, 0}}},
|
||||||
|
{4, InputStepMode::kInstance, {{VertexFormat::kF32, 0, 1}}}}});
|
||||||
|
|
||||||
EXPECT_TRUE(transform()->Run());
|
EXPECT_TRUE(transform()->Run());
|
||||||
|
|
||||||
|
@ -231,6 +329,11 @@ TEST_F(VertexPullingTransformTest, ExistingVertexIndex) {
|
||||||
private
|
private
|
||||||
__f32
|
__f32
|
||||||
}
|
}
|
||||||
|
Variable{
|
||||||
|
var_b
|
||||||
|
private
|
||||||
|
__f32
|
||||||
|
}
|
||||||
DecoratedVariable{
|
DecoratedVariable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BuiltinDecoration{vertex_idx}
|
BuiltinDecoration{vertex_idx}
|
||||||
|
@ -239,6 +342,14 @@ TEST_F(VertexPullingTransformTest, ExistingVertexIndex) {
|
||||||
in
|
in
|
||||||
__i32
|
__i32
|
||||||
}
|
}
|
||||||
|
DecoratedVariable{
|
||||||
|
Decorations{
|
||||||
|
BuiltinDecoration{instance_idx}
|
||||||
|
}
|
||||||
|
custom_instance_index
|
||||||
|
in
|
||||||
|
__i32
|
||||||
|
}
|
||||||
DecoratedVariable{
|
DecoratedVariable{
|
||||||
Decorations{
|
Decorations{
|
||||||
BindingDecoration{0}
|
BindingDecoration{0}
|
||||||
|
@ -248,6 +359,15 @@ TEST_F(VertexPullingTransformTest, ExistingVertexIndex) {
|
||||||
storage_buffer
|
storage_buffer
|
||||||
__struct_
|
__struct_
|
||||||
}
|
}
|
||||||
|
DecoratedVariable{
|
||||||
|
Decorations{
|
||||||
|
BindingDecoration{1}
|
||||||
|
SetDecoration{0}
|
||||||
|
}
|
||||||
|
tint_pulling_vertex_buffer_1
|
||||||
|
storage_buffer
|
||||||
|
__struct_
|
||||||
|
}
|
||||||
EntryPoint{vertex as main = vtx_main}
|
EntryPoint{vertex as main = vtx_main}
|
||||||
Function vtx_main -> __void
|
Function vtx_main -> __void
|
||||||
()
|
()
|
||||||
|
@ -288,6 +408,34 @@ TEST_F(VertexPullingTransformTest, ExistingVertexIndex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Assignment{
|
||||||
|
Identifier{tint_pulling_pos}
|
||||||
|
Binary{
|
||||||
|
Binary{
|
||||||
|
Identifier{custom_instance_index}
|
||||||
|
multiply
|
||||||
|
ScalarConstructor{4}
|
||||||
|
}
|
||||||
|
add
|
||||||
|
ScalarConstructor{0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assignment{
|
||||||
|
Identifier{var_b}
|
||||||
|
As<__f32>{
|
||||||
|
ArrayAccessor{
|
||||||
|
MemberAccessor{
|
||||||
|
Identifier{tint_pulling_vertex_buffer_1}
|
||||||
|
Identifier{data}
|
||||||
|
}
|
||||||
|
Binary{
|
||||||
|
Identifier{tint_pulling_pos}
|
||||||
|
divide
|
||||||
|
ScalarConstructor{4}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue