Implement discard semantics
Implement new transform UnwindDiscardFunctions that replaces discard statements with setting a module-level bool, adds a check and return for this bool after every function call that may discard, and finally invokes a single function that executes a discard from top-level functions. Regenerated tests and remove HLSL ones that used to fail FXC because it had difficulty with discard. Bug: tint:1478 Bug: chromium:1118 Change-Id: I09d680f59e2d5d0cad907bfbbdd426aae76d4bf3 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/84221 Reviewed-by: James Price <jrprice@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
ade4e74ec4
commit
66d6668372
|
@ -487,6 +487,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"transform/transform.h",
|
||||
"transform/unshadow.cc",
|
||||
"transform/unshadow.h",
|
||||
"transform/unwind_discard_functions.cc",
|
||||
"transform/unwind_discard_functions.h",
|
||||
"transform/utils/hoist_to_decl_before.cc",
|
||||
"transform/utils/hoist_to_decl_before.h",
|
||||
"transform/var_for_dynamic_index.cc",
|
||||
|
|
|
@ -365,6 +365,8 @@ set(TINT_LIB_SRCS
|
|||
transform/transform.h
|
||||
transform/unshadow.cc
|
||||
transform/unshadow.h
|
||||
transform/unwind_discard_functions.cc
|
||||
transform/unwind_discard_functions.h
|
||||
transform/vectorize_scalar_matrix_constructors.cc
|
||||
transform/vectorize_scalar_matrix_constructors.h
|
||||
transform/var_for_dynamic_index.cc
|
||||
|
@ -1031,6 +1033,7 @@ if(TINT_BUILD_TESTS)
|
|||
transform/single_entry_point_test.cc
|
||||
transform/test_helper.h
|
||||
transform/unshadow_test.cc
|
||||
transform/unwind_discard_functions_test.cc
|
||||
transform/var_for_dynamic_index_test.cc
|
||||
transform/vectorize_scalar_matrix_constructors_test.cc
|
||||
transform/vertex_pulling_test.cc
|
||||
|
|
|
@ -40,5 +40,9 @@ ElseStatement::ElseStatement(const ast::ElseStatement* declaration,
|
|||
|
||||
ElseStatement::~ElseStatement() = default;
|
||||
|
||||
const ast::ElseStatement* ElseStatement::Declaration() const {
|
||||
return static_cast<const ast::ElseStatement*>(Base::Declaration());
|
||||
}
|
||||
|
||||
} // namespace sem
|
||||
} // namespace tint
|
||||
|
|
|
@ -73,6 +73,9 @@ class ElseStatement final : public Castable<ElseStatement, CompoundStatement> {
|
|||
/// Destructor
|
||||
~ElseStatement() override;
|
||||
|
||||
/// @returns the AST node
|
||||
const ast::ElseStatement* Declaration() const;
|
||||
|
||||
/// @returns the else-statement condition expression
|
||||
const Expression* Condition() const { return condition_; }
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "src/tint/transform/simplify_pointers.h"
|
||||
#include "src/tint/transform/single_entry_point.h"
|
||||
#include "src/tint/transform/unshadow.h"
|
||||
#include "src/tint/transform/unwind_discard_functions.h"
|
||||
#include "src/tint/transform/zero_init_workgroup_memory.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::Glsl);
|
||||
|
@ -84,6 +85,7 @@ Output Glsl::Run(const Program* in, const DataMap& inputs) const {
|
|||
}
|
||||
manager.Add<CanonicalizeEntryPointIO>();
|
||||
manager.Add<PromoteSideEffectsToDecl>();
|
||||
manager.Add<UnwindDiscardFunctions>();
|
||||
manager.Add<SimplifyPointers>();
|
||||
|
||||
manager.Add<RemovePhonies>();
|
||||
|
|
|
@ -118,7 +118,8 @@ class TransformTestBase : public BASE {
|
|||
template <typename TRANSFORM>
|
||||
bool ShouldRun(Program&& program, const DataMap& data = {}) {
|
||||
EXPECT_TRUE(program.IsValid()) << program.Diagnostics().str();
|
||||
return TRANSFORM().ShouldRun(&program, data);
|
||||
const Transform& t = TRANSFORM();
|
||||
return t.ShouldRun(&program, data);
|
||||
}
|
||||
|
||||
/// @param in the input WGSL source
|
||||
|
|
|
@ -0,0 +1,432 @@
|
|||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/tint/transform/unwind_discard_functions.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "src/tint/ast/discard_statement.h"
|
||||
#include "src/tint/ast/return_statement.h"
|
||||
#include "src/tint/ast/traverse_expressions.h"
|
||||
#include "src/tint/sem/block_statement.h"
|
||||
#include "src/tint/sem/call.h"
|
||||
#include "src/tint/sem/for_loop_statement.h"
|
||||
#include "src/tint/sem/function.h"
|
||||
#include "src/tint/sem/if_statement.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::UnwindDiscardFunctions);
|
||||
|
||||
namespace tint::transform {
|
||||
namespace {
|
||||
|
||||
class State {
|
||||
private:
|
||||
CloneContext& ctx;
|
||||
ProgramBuilder& b;
|
||||
const sem::Info& sem;
|
||||
Symbol module_discard_var_name; // Use ModuleDiscardVarName() to read
|
||||
Symbol module_discard_func_name; // Use ModuleDiscardFuncName() to read
|
||||
|
||||
// For the input statement, returns the block and statement within that
|
||||
// block to insert before/after.
|
||||
std::pair<const sem::BlockStatement*, const ast::Statement*>
|
||||
GetInsertionPoint(const ast::Statement* stmt) {
|
||||
using RetType =
|
||||
std::pair<const sem::BlockStatement*, const ast::Statement*>;
|
||||
|
||||
if (auto* sem_stmt = sem.Get(stmt)) {
|
||||
auto* parent = sem_stmt->Parent();
|
||||
return Switch(
|
||||
parent,
|
||||
[&](const sem::BlockStatement* block) -> RetType {
|
||||
// Common case, just insert in the current block above the input
|
||||
// statement.
|
||||
return {block, stmt};
|
||||
},
|
||||
[&](const sem::ForLoopStatement* fl) -> RetType {
|
||||
// `stmt` is either the for loop initializer or the continuing
|
||||
// statement of a for-loop.
|
||||
if (fl->Declaration()->initializer == stmt) {
|
||||
// For loop init, insert above the for loop itself.
|
||||
return {fl->Block(), fl->Declaration()};
|
||||
}
|
||||
|
||||
TINT_ICE(Transform, b.Diagnostics())
|
||||
<< "cannot insert before or after continuing statement of a "
|
||||
"for-loop";
|
||||
return {};
|
||||
},
|
||||
[&](Default) -> RetType {
|
||||
TINT_ICE(Transform, b.Diagnostics())
|
||||
<< "expected parent of statement to be either a block or for "
|
||||
"loop";
|
||||
return {};
|
||||
});
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// If `block`'s parent is of type TO, returns pointer to it.
|
||||
template <typename TO>
|
||||
const TO* ParentAs(const ast::BlockStatement* block) {
|
||||
if (auto* sem_block = sem.Get(block)) {
|
||||
return As<TO>(sem_block->Parent());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Returns true if `sem_expr` contains a call expression that may
|
||||
// (transitively) execute a discard statement.
|
||||
bool MayDiscard(const sem::Expression* sem_expr) {
|
||||
return sem_expr && sem_expr->Behaviors().Contains(sem::Behavior::kDiscard);
|
||||
}
|
||||
|
||||
// Lazily creates and returns the name of the module bool variable for whether
|
||||
// to discard: "tint_discard".
|
||||
Symbol ModuleDiscardVarName() {
|
||||
if (!module_discard_var_name.IsValid()) {
|
||||
module_discard_var_name = b.Symbols().New("tint_discard");
|
||||
ctx.dst->Global(module_discard_var_name, b.ty.bool_(), b.Expr(false),
|
||||
ast::StorageClass::kPrivate);
|
||||
}
|
||||
return module_discard_var_name;
|
||||
}
|
||||
|
||||
// Lazily creates and returns the name of the function that contains a single
|
||||
// discard statement: "tint_discard_func".
|
||||
// We do this to avoid having multiple discard statements in a single program,
|
||||
// which causes problems in certain backends (see crbug.com/1118).
|
||||
Symbol ModuleDiscardFuncName() {
|
||||
if (!module_discard_func_name.IsValid()) {
|
||||
module_discard_func_name = b.Symbols().New("tint_discard_func");
|
||||
b.Func(module_discard_func_name, {}, b.ty.void_(), {b.Discard()});
|
||||
}
|
||||
return module_discard_func_name;
|
||||
}
|
||||
|
||||
// Creates "return <default return value>;" based on the return type of
|
||||
// `stmt`'s owning function.
|
||||
const ast::ReturnStatement* Return(const ast::Statement* stmt) {
|
||||
const ast::Expression* ret_val = nullptr;
|
||||
auto* ret_type = sem.Get(stmt)->Function()->Declaration()->return_type;
|
||||
if (!ret_type->Is<ast::Void>()) {
|
||||
ret_val = b.Construct(ctx.Clone(ret_type));
|
||||
}
|
||||
return b.Return(ret_val);
|
||||
}
|
||||
|
||||
// Returns true if the function `stmt` is in is an entry point
|
||||
bool IsInEntryPointFunc(const ast::Statement* stmt) {
|
||||
return sem.Get(stmt)->Function()->Declaration()->IsEntryPoint();
|
||||
}
|
||||
|
||||
// Creates "tint_discard_func();"
|
||||
const ast::CallStatement* CallDiscardFunc() {
|
||||
auto func_name = ModuleDiscardFuncName();
|
||||
return b.CallStmt(b.Call(func_name));
|
||||
}
|
||||
|
||||
// Creates and returns a new if-statement of the form:
|
||||
//
|
||||
// if (tint_discard) {
|
||||
// return <default value>;
|
||||
// }
|
||||
//
|
||||
// or if `stmt` is in a entry point function:
|
||||
//
|
||||
// if (tint_discard) {
|
||||
// tint_discard_func();
|
||||
// return <default value>;
|
||||
// }
|
||||
//
|
||||
const ast::IfStatement* IfDiscardReturn(const ast::Statement* stmt) {
|
||||
ast::StatementList stmts;
|
||||
|
||||
// For entry point functions, also emit the discard statement
|
||||
if (IsInEntryPointFunc(stmt)) {
|
||||
stmts.emplace_back(CallDiscardFunc());
|
||||
}
|
||||
|
||||
stmts.emplace_back(Return(stmt));
|
||||
|
||||
auto var_name = ModuleDiscardVarName();
|
||||
return b.If(var_name, b.Block(stmts));
|
||||
}
|
||||
|
||||
// Hoists `sem_expr` to a let followed by an `IfDiscardReturn` before `stmt`.
|
||||
// For example, if `stmt` is:
|
||||
//
|
||||
// return f();
|
||||
//
|
||||
// This function will transform this to:
|
||||
//
|
||||
// let t1 = f();
|
||||
// if (tint_discard) {
|
||||
// return;
|
||||
// }
|
||||
// return t1;
|
||||
//
|
||||
const ast::Statement* HoistAndInsertBefore(const ast::Statement* stmt,
|
||||
const sem::Expression* sem_expr) {
|
||||
auto* expr = sem_expr->Declaration();
|
||||
|
||||
auto ip = GetInsertionPoint(stmt);
|
||||
auto var_name = b.Sym();
|
||||
auto* decl = b.Decl(b.Var(var_name, nullptr, ctx.Clone(expr)));
|
||||
ctx.InsertBefore(ip.first->Declaration()->statements, ip.second, decl);
|
||||
|
||||
ctx.InsertBefore(ip.first->Declaration()->statements, ip.second,
|
||||
IfDiscardReturn(stmt));
|
||||
|
||||
auto* var_expr = b.Expr(var_name);
|
||||
|
||||
// Special handling for CallStatement as we can only replace its expression
|
||||
// with a CallExpression.
|
||||
if (stmt->Is<ast::CallStatement>()) {
|
||||
// We could replace the call statement with no statement, but we can't do
|
||||
// that with transforms (yet), so just return a phony assignment.
|
||||
return b.Assign(b.Phony(), var_expr);
|
||||
}
|
||||
|
||||
ctx.Replace(expr, var_expr);
|
||||
return ctx.CloneWithoutTransform(stmt);
|
||||
}
|
||||
|
||||
// Returns true if `stmt` is a for-loop initializer statement.
|
||||
bool IsForLoopInitStatement(const ast::Statement* stmt) {
|
||||
if (auto* sem_stmt = sem.Get(stmt)) {
|
||||
if (auto* sem_fl = As<sem::ForLoopStatement>(sem_stmt->Parent())) {
|
||||
return sem_fl->Declaration()->initializer == stmt;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Inserts an `IfDiscardReturn` after `stmt` if possible (i.e. `stmt` is not
|
||||
// in a for-loop init), otherwise falls back to HoistAndInsertBefore, hoisting
|
||||
// `sem_expr` to a let followed by an `IfDiscardReturn` before `stmt`.
|
||||
//
|
||||
// For example, if `stmt` is:
|
||||
//
|
||||
// let r = f();
|
||||
//
|
||||
// This function will transform this to:
|
||||
//
|
||||
// let r = f();
|
||||
// if (tint_discard) {
|
||||
// return;
|
||||
// }
|
||||
const ast::Statement* TryInsertAfter(const ast::Statement* stmt,
|
||||
const sem::Expression* sem_expr) {
|
||||
// If `stmt` is the init of a for-loop, hoist and insert before instead.
|
||||
if (IsForLoopInitStatement(stmt)) {
|
||||
return HoistAndInsertBefore(stmt, sem_expr);
|
||||
}
|
||||
|
||||
auto ip = GetInsertionPoint(stmt);
|
||||
ctx.InsertAfter(ip.first->Declaration()->statements, ip.second,
|
||||
IfDiscardReturn(stmt));
|
||||
return nullptr; // Don't replace current statement
|
||||
}
|
||||
|
||||
// Replaces the input discard statement with either setting the module level
|
||||
// discard bool ("tint_discard = true"), or calling the discard function
|
||||
// ("tint_discard_func()"), followed by a default return statement.
|
||||
//
|
||||
// Replaces "discard;" with:
|
||||
//
|
||||
// tint_discard = true;
|
||||
// return;
|
||||
//
|
||||
// Or if `stmt` is a entry point function, replaces with:
|
||||
//
|
||||
// tint_discard_func();
|
||||
// return;
|
||||
//
|
||||
const ast::Statement* ReplaceDiscardStatement(
|
||||
const ast::DiscardStatement* stmt) {
|
||||
const ast::Statement* to_insert = nullptr;
|
||||
if (IsInEntryPointFunc(stmt)) {
|
||||
to_insert = CallDiscardFunc();
|
||||
} else {
|
||||
auto var_name = ModuleDiscardVarName();
|
||||
to_insert = b.Assign(var_name, true);
|
||||
}
|
||||
|
||||
auto ip = GetInsertionPoint(stmt);
|
||||
ctx.InsertBefore(ip.first->Declaration()->statements, ip.second, to_insert);
|
||||
return Return(stmt);
|
||||
}
|
||||
|
||||
// Handle statement
|
||||
const ast::Statement* Statement(const ast::Statement* stmt) {
|
||||
return Switch(
|
||||
stmt,
|
||||
[&](const ast::DiscardStatement* s) -> const ast::Statement* {
|
||||
return ReplaceDiscardStatement(s);
|
||||
},
|
||||
[&](const ast::AssignmentStatement* s) -> const ast::Statement* {
|
||||
auto* sem_lhs = sem.Get(s->lhs);
|
||||
auto* sem_rhs = sem.Get(s->rhs);
|
||||
if (MayDiscard(sem_lhs)) {
|
||||
if (MayDiscard(sem_rhs)) {
|
||||
TINT_ICE(Transform, b.Diagnostics())
|
||||
<< "Unexpected: both sides of assignment statement may "
|
||||
"discard. Make sure transform::PromoteSideEffectsToDecl "
|
||||
"was run first.";
|
||||
}
|
||||
return TryInsertAfter(s, sem_lhs);
|
||||
} else if (MayDiscard(sem_rhs)) {
|
||||
return TryInsertAfter(s, sem_rhs);
|
||||
}
|
||||
return nullptr;
|
||||
},
|
||||
[&](const ast::CallStatement* s) -> const ast::Statement* {
|
||||
auto* sem_expr = sem.Get(s->expr);
|
||||
if (!MayDiscard(sem_expr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return TryInsertAfter(s, sem_expr);
|
||||
},
|
||||
[&](const ast::ElseStatement* s) -> const ast::Statement* {
|
||||
if (MayDiscard(sem.Get(s->condition))) {
|
||||
TINT_ICE(Transform, b.Diagnostics())
|
||||
<< "Unexpected ElseIf condition that may discard. Make sure "
|
||||
"transform::PromoteSideEffectsToDecl was run first.";
|
||||
}
|
||||
return nullptr;
|
||||
},
|
||||
[&](const ast::ForLoopStatement* s) -> const ast::Statement* {
|
||||
if (MayDiscard(sem.Get(s->condition))) {
|
||||
TINT_ICE(Transform, b.Diagnostics())
|
||||
<< "Unexpected ForLoopStatement condition that may discard. "
|
||||
"Make sure transform::PromoteSideEffectsToDecl was run "
|
||||
"first.";
|
||||
}
|
||||
return nullptr;
|
||||
},
|
||||
[&](const ast::IfStatement* s) -> const ast::Statement* {
|
||||
auto* sem_expr = sem.Get(s->condition);
|
||||
if (!MayDiscard(sem_expr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return HoistAndInsertBefore(s, sem_expr);
|
||||
},
|
||||
[&](const ast::ReturnStatement* s) -> const ast::Statement* {
|
||||
auto* sem_expr = sem.Get(s->value);
|
||||
if (!MayDiscard(sem_expr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return HoistAndInsertBefore(s, sem_expr);
|
||||
},
|
||||
[&](const ast::SwitchStatement* s) -> const ast::Statement* {
|
||||
auto* sem_expr = sem.Get(s->condition);
|
||||
if (!MayDiscard(sem_expr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return HoistAndInsertBefore(s, sem_expr);
|
||||
},
|
||||
[&](const ast::VariableDeclStatement* s) -> const ast::Statement* {
|
||||
auto* var = s->variable;
|
||||
if (!var->constructor) {
|
||||
return nullptr;
|
||||
}
|
||||
auto* sem_expr = sem.Get(var->constructor);
|
||||
if (!MayDiscard(sem_expr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return TryInsertAfter(s, sem_expr);
|
||||
});
|
||||
}
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param ctx_in the context
|
||||
explicit State(CloneContext& ctx_in)
|
||||
: ctx(ctx_in), b(*ctx_in.dst), sem(ctx_in.src->Sem()) {}
|
||||
|
||||
/// Runs the transform
|
||||
void Run() {
|
||||
ctx.ReplaceAll(
|
||||
[&](const ast::BlockStatement* block) -> const ast::Statement* {
|
||||
// If this block is for an else-if statement, process the else-if now
|
||||
// before processing its block statements.
|
||||
// NOTE: we can't replace else statements at this point - this would
|
||||
// need to be done when replacing the parent if-statement. However, in
|
||||
// this transform, we don't ever expect to need to do this as else-ifs
|
||||
// are converted to else { if } by PromoteSideEffectsToDecl, so this
|
||||
// is only for validation.
|
||||
if (auto* sem_else = ParentAs<sem::ElseStatement>(block)) {
|
||||
if (auto* new_stmt = Statement(sem_else->Declaration())) {
|
||||
TINT_ASSERT(Transform, new_stmt == nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate block statements and replace them as needed.
|
||||
for (auto* stmt : block->statements) {
|
||||
if (auto* new_stmt = Statement(stmt)) {
|
||||
ctx.Replace(stmt, new_stmt);
|
||||
}
|
||||
|
||||
// Handle for loops, as they are the only other AST node that
|
||||
// contains statements outside of BlockStatements.
|
||||
if (auto* fl = stmt->As<ast::ForLoopStatement>()) {
|
||||
if (auto* new_stmt = Statement(fl->initializer)) {
|
||||
ctx.Replace(fl->initializer, new_stmt);
|
||||
}
|
||||
if (auto* new_stmt = Statement(fl->continuing)) {
|
||||
// NOTE: Should never reach here as we cannot discard in a
|
||||
// continuing block.
|
||||
ctx.Replace(fl->continuing, new_stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
ctx.Clone();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
UnwindDiscardFunctions::UnwindDiscardFunctions() = default;
|
||||
UnwindDiscardFunctions::~UnwindDiscardFunctions() = default;
|
||||
|
||||
void UnwindDiscardFunctions::Run(CloneContext& ctx,
|
||||
const DataMap&,
|
||||
DataMap&) const {
|
||||
State state(ctx);
|
||||
state.Run();
|
||||
}
|
||||
|
||||
bool UnwindDiscardFunctions::ShouldRun(const Program* program,
|
||||
const DataMap& /*data*/) const {
|
||||
auto& sem = program->Sem();
|
||||
for (auto* f : program->AST().Functions()) {
|
||||
if (sem.Get(f)->Behaviors().Contains(sem::Behavior::kDiscard)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace tint::transform
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_TINT_TRANSFORM_UNWIND_DISCARD_FUNCTIONS_H_
|
||||
#define SRC_TINT_TRANSFORM_UNWIND_DISCARD_FUNCTIONS_H_
|
||||
|
||||
#include "src/tint/transform/transform.h"
|
||||
|
||||
namespace tint::transform {
|
||||
|
||||
/// This transform is responsible for implementing discard semantics as per the
|
||||
/// WGSL specification: https://gpuweb.github.io/gpuweb/wgsl/#discard-statement
|
||||
///
|
||||
/// Not all backend languages implement discard this way (e.g. HLSL), so this
|
||||
/// transform does the following:
|
||||
///
|
||||
/// * Replaces discard statements with setting a module-level boolean
|
||||
/// "tint_discard" to true and returning immediately.
|
||||
/// * Wherever calls are made to discarding functions (directly or
|
||||
/// transitively), it inserts a check afterwards for if "tint_discard" is true,
|
||||
/// to return immediately.
|
||||
/// * Finally, entry point functions that call discarding functions
|
||||
/// emit a call to "tint_discard_func()" that contains the sole discard
|
||||
/// statement.
|
||||
///
|
||||
/// @note Depends on the following transforms to have been run first:
|
||||
/// * PromoteSideEffectsToDecl
|
||||
class UnwindDiscardFunctions
|
||||
: public Castable<UnwindDiscardFunctions, Transform> {
|
||||
public:
|
||||
/// Constructor
|
||||
UnwindDiscardFunctions();
|
||||
|
||||
/// Destructor
|
||||
~UnwindDiscardFunctions() override;
|
||||
|
||||
protected:
|
||||
/// Runs the transform using the CloneContext built for transforming a
|
||||
/// program. Run() is responsible for calling Clone() on the CloneContext.
|
||||
/// @param ctx the CloneContext primed with the input program and
|
||||
/// ProgramBuilder
|
||||
/// @param inputs optional extra transform-specific input data
|
||||
/// @param outputs optional extra transform-specific output data
|
||||
void Run(CloneContext& ctx,
|
||||
const DataMap& inputs,
|
||||
DataMap& outputs) const override;
|
||||
|
||||
/// @param program the program to inspect
|
||||
/// @param data optional extra transform-specific input data
|
||||
/// @returns true if this transform should be run for the given program
|
||||
bool ShouldRun(const Program* program,
|
||||
const DataMap& data = {}) const override;
|
||||
};
|
||||
|
||||
} // namespace tint::transform
|
||||
|
||||
#endif // SRC_TINT_TRANSFORM_UNWIND_DISCARD_FUNCTIONS_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -62,6 +62,7 @@
|
|||
#include "src/tint/transform/remove_phonies.h"
|
||||
#include "src/tint/transform/simplify_pointers.h"
|
||||
#include "src/tint/transform/unshadow.h"
|
||||
#include "src/tint/transform/unwind_discard_functions.h"
|
||||
#include "src/tint/transform/zero_init_workgroup_memory.h"
|
||||
#include "src/tint/utils/defer.h"
|
||||
#include "src/tint/utils/map.h"
|
||||
|
@ -187,6 +188,7 @@ SanitizedResult Sanitize(
|
|||
// only accessed directly via member accessors.
|
||||
manager.Add<transform::NumWorkgroupsFromUniform>();
|
||||
manager.Add<transform::PromoteSideEffectsToDecl>();
|
||||
manager.Add<transform::UnwindDiscardFunctions>();
|
||||
manager.Add<transform::SimplifyPointers>();
|
||||
manager.Add<transform::RemovePhonies>();
|
||||
// ArrayLengthFromUniform must come after InlinePointerLets and Simplify, as
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include "src/tint/transform/remove_phonies.h"
|
||||
#include "src/tint/transform/simplify_pointers.h"
|
||||
#include "src/tint/transform/unshadow.h"
|
||||
#include "src/tint/transform/unwind_discard_functions.h"
|
||||
#include "src/tint/transform/vectorize_scalar_matrix_constructors.h"
|
||||
#include "src/tint/transform/wrap_arrays_in_structs.h"
|
||||
#include "src/tint/transform/zero_init_workgroup_memory.h"
|
||||
|
@ -174,6 +175,7 @@ SanitizedResult Sanitize(
|
|||
}
|
||||
manager.Add<transform::CanonicalizeEntryPointIO>();
|
||||
manager.Add<transform::PromoteSideEffectsToDecl>();
|
||||
manager.Add<transform::UnwindDiscardFunctions>();
|
||||
manager.Add<transform::PromoteInitializersToConstVar>();
|
||||
|
||||
manager.Add<transform::VectorizeScalarMatrixConstructors>();
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "src/tint/transform/remove_unreachable_statements.h"
|
||||
#include "src/tint/transform/simplify_pointers.h"
|
||||
#include "src/tint/transform/unshadow.h"
|
||||
#include "src/tint/transform/unwind_discard_functions.h"
|
||||
#include "src/tint/transform/var_for_dynamic_index.h"
|
||||
#include "src/tint/transform/vectorize_scalar_matrix_constructors.h"
|
||||
#include "src/tint/transform/zero_init_workgroup_memory.h"
|
||||
|
@ -278,6 +279,7 @@ SanitizedResult Sanitize(const Program* in,
|
|||
}
|
||||
manager.Add<transform::RemoveUnreachableStatements>();
|
||||
manager.Add<transform::PromoteSideEffectsToDecl>();
|
||||
manager.Add<transform::UnwindDiscardFunctions>();
|
||||
manager.Add<transform::SimplifyPointers>(); // Required for arrayLength()
|
||||
manager.Add<transform::FoldConstants>();
|
||||
manager.Add<transform::VectorizeScalarMatrixConstructors>();
|
||||
|
|
|
@ -338,6 +338,7 @@ tint_unittests_source_set("tint_unittests_transform_src") {
|
|||
"../../src/tint/transform/test_helper.h",
|
||||
"../../src/tint/transform/transform_test.cc",
|
||||
"../../src/tint/transform/unshadow_test.cc",
|
||||
"../../src/tint/transform/unwind_discard_functions_test.cc",
|
||||
"../../src/tint/transform/utils/hoist_to_decl_before_test.cc",
|
||||
"../../src/tint/transform/var_for_dynamic_index_test.cc",
|
||||
"../../src/tint/transform/vectorize_scalar_matrix_constructors_test.cc",
|
||||
|
|
|
@ -52,19 +52,29 @@ struct VertexOutputs {
|
|||
vec4 position;
|
||||
};
|
||||
|
||||
bool tint_discard = false;
|
||||
uniform highp sampler2D myTexture_mySampler;
|
||||
|
||||
vec4 fs_main(vec2 texcoord) {
|
||||
vec2 clampedTexcoord = clamp(texcoord, vec2(0.0f, 0.0f), vec2(1.0f, 1.0f));
|
||||
if (!(all(equal(clampedTexcoord, texcoord)))) {
|
||||
discard;
|
||||
tint_discard = true;
|
||||
return vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
vec4 srcColor = texture(myTexture_mySampler, texcoord);
|
||||
return srcColor;
|
||||
}
|
||||
|
||||
void tint_discard_func() {
|
||||
discard;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 inner_result = fs_main(texcoord_1);
|
||||
if (tint_discard) {
|
||||
tint_discard_func();
|
||||
return;
|
||||
}
|
||||
value = inner_result;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -45,21 +45,29 @@ struct tint_symbol_5 {
|
|||
float4 value : SV_Target0;
|
||||
};
|
||||
|
||||
static bool tint_discard = false;
|
||||
|
||||
float4 fs_main_inner(float2 texcoord) {
|
||||
if (true) {
|
||||
float2 clampedTexcoord = clamp(texcoord, float2(0.0f, 0.0f), float2(1.0f, 1.0f));
|
||||
if (!(all((clampedTexcoord == texcoord)))) {
|
||||
discard;
|
||||
tint_discard = true;
|
||||
return float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
float4 srcColor = myTexture.Sample(mySampler, texcoord);
|
||||
return srcColor;
|
||||
}
|
||||
float4 unused;
|
||||
return unused;
|
||||
|
||||
void tint_discard_func() {
|
||||
discard;
|
||||
}
|
||||
|
||||
tint_symbol_5 fs_main(tint_symbol_4 tint_symbol_3) {
|
||||
const float4 inner_result_1 = fs_main_inner(tint_symbol_3.texcoord);
|
||||
if (tint_discard) {
|
||||
tint_discard_func();
|
||||
const tint_symbol_5 tint_symbol_8 = (tint_symbol_5)0;
|
||||
return tint_symbol_8;
|
||||
}
|
||||
tint_symbol_5 wrapper_result_1 = (tint_symbol_5)0;
|
||||
wrapper_result_1.value = inner_result_1;
|
||||
return wrapper_result_1;
|
||||
|
|
|
@ -20,21 +20,21 @@ struct tint_array_wrapper {
|
|||
float2 arr[3];
|
||||
};
|
||||
|
||||
VertexOutputs vs_main_inner(uint VertexIndex, const constant Uniforms* const tint_symbol_4) {
|
||||
VertexOutputs vs_main_inner(uint VertexIndex, const constant Uniforms* const tint_symbol_5) {
|
||||
tint_array_wrapper texcoord = {.arr={float2(-0.5f, 0.0f), float2(1.5f, 0.0f), float2(0.5f, 2.0f)}};
|
||||
VertexOutputs output = {};
|
||||
output.position = float4(((texcoord.arr[VertexIndex] * 2.0f) - float2(1.0f, 1.0f)), 0.0f, 1.0f);
|
||||
bool flipY = ((*(tint_symbol_4)).u_scale[1] < 0.0f);
|
||||
bool flipY = ((*(tint_symbol_5)).u_scale[1] < 0.0f);
|
||||
if (flipY) {
|
||||
output.texcoords = ((((texcoord.arr[VertexIndex] * (*(tint_symbol_4)).u_scale) + (*(tint_symbol_4)).u_offset) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
|
||||
output.texcoords = ((((texcoord.arr[VertexIndex] * (*(tint_symbol_5)).u_scale) + (*(tint_symbol_5)).u_offset) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
|
||||
} else {
|
||||
output.texcoords = ((((texcoord.arr[VertexIndex] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * (*(tint_symbol_4)).u_scale) + (*(tint_symbol_4)).u_offset);
|
||||
output.texcoords = ((((texcoord.arr[VertexIndex] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * (*(tint_symbol_5)).u_scale) + (*(tint_symbol_5)).u_offset);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
vertex tint_symbol vs_main(const constant Uniforms* tint_symbol_5 [[buffer(0)]], uint VertexIndex [[vertex_id]]) {
|
||||
VertexOutputs const inner_result = vs_main_inner(VertexIndex, tint_symbol_5);
|
||||
vertex tint_symbol vs_main(const constant Uniforms* tint_symbol_6 [[buffer(0)]], uint VertexIndex [[vertex_id]]) {
|
||||
VertexOutputs const inner_result = vs_main_inner(VertexIndex, tint_symbol_6);
|
||||
tint_symbol wrapper_result = {};
|
||||
wrapper_result.texcoords = inner_result.texcoords;
|
||||
wrapper_result.position = inner_result.position;
|
||||
|
@ -49,17 +49,28 @@ struct tint_symbol_3 {
|
|||
float4 value [[color(0)]];
|
||||
};
|
||||
|
||||
float4 fs_main_inner(float2 texcoord, texture2d<float, access::sample> tint_symbol_6, sampler tint_symbol_7) {
|
||||
float4 fs_main_inner(float2 texcoord, thread bool* const tint_symbol_7, texture2d<float, access::sample> tint_symbol_8, sampler tint_symbol_9) {
|
||||
float2 clampedTexcoord = clamp(texcoord, float2(0.0f, 0.0f), float2(1.0f, 1.0f));
|
||||
if (!(all((clampedTexcoord == texcoord)))) {
|
||||
discard_fragment();
|
||||
*(tint_symbol_7) = true;
|
||||
return float4();
|
||||
}
|
||||
float4 srcColor = tint_symbol_6.sample(tint_symbol_7, texcoord);
|
||||
float4 srcColor = tint_symbol_8.sample(tint_symbol_9, texcoord);
|
||||
return srcColor;
|
||||
}
|
||||
|
||||
fragment tint_symbol_3 fs_main(texture2d<float, access::sample> tint_symbol_8 [[texture(0)]], sampler tint_symbol_9 [[sampler(0)]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
|
||||
float4 const inner_result_1 = fs_main_inner(tint_symbol_1.texcoord, tint_symbol_8, tint_symbol_9);
|
||||
void tint_discard_func() {
|
||||
discard_fragment();
|
||||
}
|
||||
|
||||
fragment tint_symbol_3 fs_main(texture2d<float, access::sample> tint_symbol_11 [[texture(0)]], sampler tint_symbol_12 [[sampler(0)]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
|
||||
thread bool tint_symbol_10 = false;
|
||||
float4 const inner_result_1 = fs_main_inner(tint_symbol_1.texcoord, &(tint_symbol_10), tint_symbol_11, tint_symbol_12);
|
||||
if (tint_symbol_10) {
|
||||
tint_discard_func();
|
||||
tint_symbol_3 const tint_symbol_4 = {};
|
||||
return tint_symbol_4;
|
||||
}
|
||||
tint_symbol_3 wrapper_result_1 = {};
|
||||
wrapper_result_1.value = inner_result_1;
|
||||
return wrapper_result_1;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 137
|
||||
; Bound: 140
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%116 = OpExtInstImport "GLSL.std.450"
|
||||
%118 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %vs_main "vs_main" %VertexIndex_1 %texcoords_1 %position_1 %vertex_point_size
|
||||
OpEntryPoint Fragment %fs_main "fs_main" %texcoord_1 %value
|
||||
|
@ -30,6 +30,7 @@
|
|||
OpName %output "output"
|
||||
OpName %flipY "flipY"
|
||||
OpName %vs_main "vs_main"
|
||||
OpName %tint_discard_func "tint_discard_func"
|
||||
OpName %fs_main_inner "fs_main_inner"
|
||||
OpName %texcoord_0 "texcoord"
|
||||
OpName %clampedTexcoord "clampedTexcoord"
|
||||
|
@ -114,10 +115,10 @@
|
|||
%89 = OpConstantComposite %v2float %float_0 %float_1
|
||||
%void = OpTypeVoid
|
||||
%103 = OpTypeFunction %void
|
||||
%111 = OpTypeFunction %v4float %v2float
|
||||
%117 = OpConstantComposite %v2float %float_0 %float_0
|
||||
%113 = OpTypeFunction %v4float %v2float
|
||||
%119 = OpConstantComposite %v2float %float_0 %float_0
|
||||
%v2bool = OpTypeVector %bool 2
|
||||
%129 = OpTypeSampledImage %27
|
||||
%132 = OpTypeSampledImage %27
|
||||
%vs_main_inner = OpFunction %VertexOutputs None %28
|
||||
%VertexIndex = OpFunctionParameter %uint
|
||||
%32 = OpLabel
|
||||
|
@ -184,34 +185,39 @@
|
|||
OpStore %vertex_point_size %float_1
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%fs_main_inner = OpFunction %v4float None %111
|
||||
%tint_discard_func = OpFunction %void None %103
|
||||
%112 = OpLabel
|
||||
OpKill
|
||||
OpFunctionEnd
|
||||
%fs_main_inner = OpFunction %v4float None %113
|
||||
%texcoord_0 = OpFunctionParameter %v2float
|
||||
%114 = OpLabel
|
||||
%116 = OpLabel
|
||||
%clampedTexcoord = OpVariable %_ptr_Function_v2float Function %8
|
||||
%srcColor = OpVariable %_ptr_Function_v4float Function %12
|
||||
%115 = OpExtInst %v2float %116 NClamp %texcoord_0 %117 %58
|
||||
OpStore %clampedTexcoord %115
|
||||
%121 = OpLoad %v2float %clampedTexcoord
|
||||
%122 = OpFOrdEqual %v2bool %121 %texcoord_0
|
||||
%120 = OpAll %bool %122
|
||||
%119 = OpLogicalNot %bool %120
|
||||
OpSelectionMerge %124 None
|
||||
OpBranchConditional %119 %125 %124
|
||||
%125 = OpLabel
|
||||
OpKill
|
||||
%124 = OpLabel
|
||||
%127 = OpLoad %24 %mySampler
|
||||
%128 = OpLoad %27 %myTexture
|
||||
%130 = OpSampledImage %129 %128 %127
|
||||
%126 = OpImageSampleImplicitLod %v4float %130 %texcoord_0
|
||||
OpStore %srcColor %126
|
||||
%132 = OpLoad %v4float %srcColor
|
||||
OpReturnValue %132
|
||||
%117 = OpExtInst %v2float %118 NClamp %texcoord_0 %119 %58
|
||||
OpStore %clampedTexcoord %117
|
||||
%123 = OpLoad %v2float %clampedTexcoord
|
||||
%124 = OpFOrdEqual %v2bool %123 %texcoord_0
|
||||
%122 = OpAll %bool %124
|
||||
%121 = OpLogicalNot %bool %122
|
||||
OpSelectionMerge %126 None
|
||||
OpBranchConditional %121 %127 %126
|
||||
%127 = OpLabel
|
||||
%128 = OpFunctionCall %void %tint_discard_func
|
||||
OpReturnValue %12
|
||||
%126 = OpLabel
|
||||
%130 = OpLoad %24 %mySampler
|
||||
%131 = OpLoad %27 %myTexture
|
||||
%133 = OpSampledImage %132 %131 %130
|
||||
%129 = OpImageSampleImplicitLod %v4float %133 %texcoord_0
|
||||
OpStore %srcColor %129
|
||||
%135 = OpLoad %v4float %srcColor
|
||||
OpReturnValue %135
|
||||
OpFunctionEnd
|
||||
%fs_main = OpFunction %void None %103
|
||||
%134 = OpLabel
|
||||
%136 = OpLoad %v2float %texcoord_1
|
||||
%135 = OpFunctionCall %v4float %fs_main_inner %136
|
||||
OpStore %value %135
|
||||
%137 = OpLabel
|
||||
%139 = OpLoad %v2float %texcoord_1
|
||||
%138 = OpFunctionCall %v4float %fs_main_inner %139
|
||||
OpStore %value %138
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
|
|
|
@ -3,9 +3,11 @@ precision mediump float;
|
|||
|
||||
layout(location = 1) flat in ivec3 x_1;
|
||||
layout(location = 2) out int value;
|
||||
bool tint_discard = false;
|
||||
int f(int x) {
|
||||
if ((x == 10)) {
|
||||
discard;
|
||||
tint_discard = true;
|
||||
return 0;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
@ -14,6 +16,9 @@ int tint_symbol(ivec3 x) {
|
|||
int y = x.x;
|
||||
while (true) {
|
||||
int r = f(y);
|
||||
if (tint_discard) {
|
||||
return 0;
|
||||
}
|
||||
if ((r == 0)) {
|
||||
break;
|
||||
}
|
||||
|
@ -21,8 +26,16 @@ int tint_symbol(ivec3 x) {
|
|||
return y;
|
||||
}
|
||||
|
||||
void tint_discard_func() {
|
||||
discard;
|
||||
}
|
||||
|
||||
void main() {
|
||||
int inner_result = tint_symbol(x_1);
|
||||
if (tint_discard) {
|
||||
tint_discard_func();
|
||||
return;
|
||||
}
|
||||
value = inner_result;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
static bool tint_discard = false;
|
||||
|
||||
int f(int x) {
|
||||
if (true) {
|
||||
if ((x == 10)) {
|
||||
discard;
|
||||
tint_discard = true;
|
||||
return 0;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
int unused;
|
||||
return unused;
|
||||
}
|
||||
|
||||
struct tint_symbol_1 {
|
||||
nointerpolation int3 x : TEXCOORD1;
|
||||
|
@ -20,6 +19,9 @@ int main_inner(int3 x) {
|
|||
int y = x.x;
|
||||
[loop] while (true) {
|
||||
const int r = f(y);
|
||||
if (tint_discard) {
|
||||
return 0;
|
||||
}
|
||||
if ((r == 0)) {
|
||||
break;
|
||||
}
|
||||
|
@ -27,8 +29,17 @@ int main_inner(int3 x) {
|
|||
return y;
|
||||
}
|
||||
|
||||
void tint_discard_func() {
|
||||
discard;
|
||||
}
|
||||
|
||||
tint_symbol_2 main(tint_symbol_1 tint_symbol) {
|
||||
const int inner_result = main_inner(tint_symbol.x);
|
||||
if (tint_discard) {
|
||||
tint_discard_func();
|
||||
const tint_symbol_2 tint_symbol_3 = (tint_symbol_2)0;
|
||||
return tint_symbol_3;
|
||||
}
|
||||
tint_symbol_2 wrapper_result = (tint_symbol_2)0;
|
||||
wrapper_result.value = inner_result;
|
||||
return wrapper_result;
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
int f(int x) {
|
||||
int f(int x, thread bool* const tint_symbol_5) {
|
||||
if ((x == 10)) {
|
||||
discard_fragment();
|
||||
*(tint_symbol_5) = true;
|
||||
return int();
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
@ -16,10 +17,13 @@ struct tint_symbol_3 {
|
|||
int value [[color(2)]];
|
||||
};
|
||||
|
||||
int tint_symbol_inner(int3 x) {
|
||||
int tint_symbol_inner(int3 x, thread bool* const tint_symbol_6) {
|
||||
int y = x[0];
|
||||
while (true) {
|
||||
int const r = f(y);
|
||||
int const r = f(y, tint_symbol_6);
|
||||
if (*(tint_symbol_6)) {
|
||||
return int();
|
||||
}
|
||||
if ((r == 0)) {
|
||||
break;
|
||||
}
|
||||
|
@ -27,8 +31,18 @@ int tint_symbol_inner(int3 x) {
|
|||
return y;
|
||||
}
|
||||
|
||||
void tint_discard_func() {
|
||||
discard_fragment();
|
||||
}
|
||||
|
||||
fragment tint_symbol_3 tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
|
||||
int const inner_result = tint_symbol_inner(tint_symbol_1.x);
|
||||
thread bool tint_symbol_7 = false;
|
||||
int const inner_result = tint_symbol_inner(tint_symbol_1.x, &(tint_symbol_7));
|
||||
if (tint_symbol_7) {
|
||||
tint_discard_func();
|
||||
tint_symbol_3 const tint_symbol_4 = {};
|
||||
return tint_symbol_4;
|
||||
}
|
||||
tint_symbol_3 wrapper_result = {};
|
||||
wrapper_result.value = inner_result;
|
||||
return wrapper_result;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 41
|
||||
; Bound: 51
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
|
@ -9,8 +9,10 @@
|
|||
OpExecutionMode %main OriginUpperLeft
|
||||
OpName %x_1 "x_1"
|
||||
OpName %value "value"
|
||||
OpName %tint_discard "tint_discard"
|
||||
OpName %f "f"
|
||||
OpName %x "x"
|
||||
OpName %tint_discard_func "tint_discard_func"
|
||||
OpName %main_inner "main_inner"
|
||||
OpName %x_0 "x"
|
||||
OpName %y "y"
|
||||
|
@ -25,55 +27,71 @@
|
|||
%_ptr_Output_int = OpTypePointer Output %int
|
||||
%7 = OpConstantNull %int
|
||||
%value = OpVariable %_ptr_Output_int Output %7
|
||||
%8 = OpTypeFunction %int %int
|
||||
%int_10 = OpConstant %int 10
|
||||
%bool = OpTypeBool
|
||||
%17 = OpTypeFunction %int %v3int
|
||||
%false = OpConstantFalse %bool
|
||||
%_ptr_Private_bool = OpTypePointer Private %bool
|
||||
%tint_discard = OpVariable %_ptr_Private_bool Private %false
|
||||
%12 = OpTypeFunction %int %int
|
||||
%int_10 = OpConstant %int 10
|
||||
%true = OpConstantTrue %bool
|
||||
%void = OpTypeVoid
|
||||
%21 = OpTypeFunction %void
|
||||
%25 = OpTypeFunction %int %v3int
|
||||
%_ptr_Function_int = OpTypePointer Function %int
|
||||
%int_0 = OpConstant %int 0
|
||||
%void = OpTypeVoid
|
||||
%35 = OpTypeFunction %void
|
||||
%f = OpFunction %int None %8
|
||||
%f = OpFunction %int None %12
|
||||
%x = OpFunctionParameter %int
|
||||
%11 = OpLabel
|
||||
%13 = OpIEqual %bool %x %int_10
|
||||
OpSelectionMerge %15 None
|
||||
OpBranchConditional %13 %16 %15
|
||||
%16 = OpLabel
|
||||
OpKill
|
||||
%15 = OpLabel
|
||||
%17 = OpIEqual %bool %x %int_10
|
||||
OpSelectionMerge %18 None
|
||||
OpBranchConditional %17 %19 %18
|
||||
%19 = OpLabel
|
||||
OpStore %tint_discard %true
|
||||
OpReturnValue %7
|
||||
%18 = OpLabel
|
||||
OpReturnValue %x
|
||||
OpFunctionEnd
|
||||
%main_inner = OpFunction %int None %17
|
||||
%x_0 = OpFunctionParameter %v3int
|
||||
%20 = OpLabel
|
||||
%y = OpVariable %_ptr_Function_int Function %7
|
||||
%21 = OpCompositeExtract %int %x_0 0
|
||||
OpStore %y %21
|
||||
OpBranch %24
|
||||
%tint_discard_func = OpFunction %void None %21
|
||||
%24 = OpLabel
|
||||
OpLoopMerge %25 %26 None
|
||||
OpBranch %27
|
||||
%27 = OpLabel
|
||||
%29 = OpLoad %int %y
|
||||
%28 = OpFunctionCall %int %f %29
|
||||
%31 = OpIEqual %bool %28 %int_0
|
||||
OpSelectionMerge %32 None
|
||||
OpBranchConditional %31 %33 %32
|
||||
%33 = OpLabel
|
||||
OpBranch %25
|
||||
%32 = OpLabel
|
||||
OpBranch %26
|
||||
%26 = OpLabel
|
||||
OpBranch %24
|
||||
%25 = OpLabel
|
||||
%34 = OpLoad %int %y
|
||||
OpReturnValue %34
|
||||
OpKill
|
||||
OpFunctionEnd
|
||||
%main = OpFunction %void None %35
|
||||
%38 = OpLabel
|
||||
%40 = OpLoad %v3int %x_1
|
||||
%39 = OpFunctionCall %int %main_inner %40
|
||||
OpStore %value %39
|
||||
%main_inner = OpFunction %int None %25
|
||||
%x_0 = OpFunctionParameter %v3int
|
||||
%28 = OpLabel
|
||||
%y = OpVariable %_ptr_Function_int Function %7
|
||||
%29 = OpCompositeExtract %int %x_0 0
|
||||
OpStore %y %29
|
||||
OpBranch %32
|
||||
%32 = OpLabel
|
||||
OpLoopMerge %33 %34 None
|
||||
OpBranch %35
|
||||
%35 = OpLabel
|
||||
%37 = OpLoad %int %y
|
||||
%36 = OpFunctionCall %int %f %37
|
||||
%38 = OpLoad %bool %tint_discard
|
||||
OpSelectionMerge %39 None
|
||||
OpBranchConditional %38 %40 %39
|
||||
%40 = OpLabel
|
||||
%41 = OpFunctionCall %void %tint_discard_func
|
||||
OpReturnValue %7
|
||||
%39 = OpLabel
|
||||
%43 = OpIEqual %bool %36 %int_0
|
||||
OpSelectionMerge %44 None
|
||||
OpBranchConditional %43 %45 %44
|
||||
%45 = OpLabel
|
||||
OpBranch %33
|
||||
%44 = OpLabel
|
||||
OpBranch %34
|
||||
%34 = OpLabel
|
||||
OpBranch %32
|
||||
%33 = OpLabel
|
||||
%46 = OpLoad %int %y
|
||||
OpReturnValue %46
|
||||
OpFunctionEnd
|
||||
%main = OpFunction %void None %21
|
||||
%48 = OpLabel
|
||||
%50 = OpLoad %v3int %x_1
|
||||
%49 = OpFunctionCall %int %main_inner %50
|
||||
OpStore %value %49
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
|
|
|
@ -39,6 +39,7 @@ layout(binding = 2) uniform Mesh_1 {
|
|||
} x_137;
|
||||
|
||||
vec4 glFragColor = vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
bool tint_discard = false;
|
||||
void main_1() {
|
||||
vec3 viewDirectionW = vec3(0.0f, 0.0f, 0.0f);
|
||||
vec4 baseColor = vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
@ -57,10 +58,12 @@ void main_1() {
|
|||
vec3 finalSpecular = vec3(0.0f, 0.0f, 0.0f);
|
||||
vec4 color = vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
if ((fClipDistance3 > 0.0f)) {
|
||||
discard;
|
||||
tint_discard = true;
|
||||
return;
|
||||
}
|
||||
if ((fClipDistance4 > 0.0f)) {
|
||||
discard;
|
||||
tint_discard = true;
|
||||
return;
|
||||
}
|
||||
vec4 x_34 = x_29.vEyePosition;
|
||||
vec3 x_38 = vec3(0.0f, 0.0f, 0.0f);
|
||||
|
@ -115,12 +118,24 @@ main_out tint_symbol(float fClipDistance3_param, float fClipDistance4_param) {
|
|||
fClipDistance3 = fClipDistance3_param;
|
||||
fClipDistance4 = fClipDistance4_param;
|
||||
main_1();
|
||||
main_out tint_symbol_1 = main_out(glFragColor);
|
||||
if (tint_discard) {
|
||||
main_out tint_symbol_1 = main_out(vec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
return tint_symbol_1;
|
||||
}
|
||||
main_out tint_symbol_2 = main_out(glFragColor);
|
||||
return tint_symbol_2;
|
||||
}
|
||||
|
||||
void tint_discard_func() {
|
||||
discard;
|
||||
}
|
||||
|
||||
void main() {
|
||||
main_out inner_result = tint_symbol(fClipDistance3_param_1, fClipDistance4_param_1);
|
||||
if (tint_discard) {
|
||||
tint_discard_func();
|
||||
return;
|
||||
}
|
||||
glFragColor_1_1 = inner_result.glFragColor_1;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
SKIP: FAILED
|
||||
|
||||
static float fClipDistance3 = 0.0f;
|
||||
static float fClipDistance4 = 0.0f;
|
||||
cbuffer cbuffer_x_29 : register(b0, space0) {
|
||||
|
@ -12,6 +10,7 @@ cbuffer cbuffer_x_137 : register(b2, space0) {
|
|||
uint4 x_137[1];
|
||||
};
|
||||
static float4 glFragColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
static bool tint_discard = false;
|
||||
|
||||
void main_1() {
|
||||
float3 viewDirectionW = float3(0.0f, 0.0f, 0.0f);
|
||||
|
@ -31,10 +30,12 @@ void main_1() {
|
|||
float3 finalSpecular = float3(0.0f, 0.0f, 0.0f);
|
||||
float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
if ((fClipDistance3 > 0.0f)) {
|
||||
discard;
|
||||
tint_discard = true;
|
||||
return;
|
||||
}
|
||||
if ((fClipDistance4 > 0.0f)) {
|
||||
discard;
|
||||
tint_discard = true;
|
||||
return;
|
||||
}
|
||||
const float4 x_34 = asfloat(x_29[0]);
|
||||
const float3 x_38 = float3(0.0f, 0.0f, 0.0f);
|
||||
|
@ -96,15 +97,26 @@ main_out main_inner(float fClipDistance3_param, float fClipDistance4_param) {
|
|||
fClipDistance3 = fClipDistance3_param;
|
||||
fClipDistance4 = fClipDistance4_param;
|
||||
main_1();
|
||||
const main_out tint_symbol_8 = {glFragColor};
|
||||
if (tint_discard) {
|
||||
const main_out tint_symbol_8 = (main_out)0;
|
||||
return tint_symbol_8;
|
||||
}
|
||||
const main_out tint_symbol_9 = {glFragColor};
|
||||
return tint_symbol_9;
|
||||
}
|
||||
|
||||
void tint_discard_func() {
|
||||
discard;
|
||||
}
|
||||
|
||||
tint_symbol_2 main(tint_symbol_1 tint_symbol) {
|
||||
const main_out inner_result = main_inner(tint_symbol.fClipDistance3_param, tint_symbol.fClipDistance4_param);
|
||||
if (tint_discard) {
|
||||
tint_discard_func();
|
||||
const tint_symbol_2 tint_symbol_10 = (tint_symbol_2)0;
|
||||
return tint_symbol_10;
|
||||
}
|
||||
tint_symbol_2 wrapper_result = (tint_symbol_2)0;
|
||||
wrapper_result.glFragColor_1 = inner_result.glFragColor_1;
|
||||
return wrapper_result;
|
||||
}
|
||||
Internal error: unread predicate
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ struct Mesh {
|
|||
/* 0x0000 */ float visibility;
|
||||
};
|
||||
|
||||
void main_1(thread float* const tint_symbol_5, thread float* const tint_symbol_6, const constant Scene* const tint_symbol_7, const constant Material* const tint_symbol_8, const constant Mesh* const tint_symbol_9, thread float4* const tint_symbol_10) {
|
||||
void main_1(thread float* const tint_symbol_7, thread bool* const tint_symbol_8, thread float* const tint_symbol_9, const constant Scene* const tint_symbol_10, const constant Material* const tint_symbol_11, const constant Mesh* const tint_symbol_12, thread float4* const tint_symbol_13) {
|
||||
float3 viewDirectionW = 0.0f;
|
||||
float4 baseColor = 0.0f;
|
||||
float3 diffuseColor = 0.0f;
|
||||
|
@ -45,21 +45,23 @@ void main_1(thread float* const tint_symbol_5, thread float* const tint_symbol_6
|
|||
float3 finalDiffuse = 0.0f;
|
||||
float3 finalSpecular = 0.0f;
|
||||
float4 color = 0.0f;
|
||||
float const x_9 = *(tint_symbol_5);
|
||||
float const x_9 = *(tint_symbol_7);
|
||||
if ((x_9 > 0.0f)) {
|
||||
discard_fragment();
|
||||
*(tint_symbol_8) = true;
|
||||
return;
|
||||
}
|
||||
float const x_17 = *(tint_symbol_6);
|
||||
float const x_17 = *(tint_symbol_9);
|
||||
if ((x_17 > 0.0f)) {
|
||||
discard_fragment();
|
||||
*(tint_symbol_8) = true;
|
||||
return;
|
||||
}
|
||||
float4 const x_34 = (*(tint_symbol_7)).vEyePosition;
|
||||
float4 const x_34 = (*(tint_symbol_10)).vEyePosition;
|
||||
float3 const x_38 = float3(0.0f, 0.0f, 0.0f);
|
||||
viewDirectionW = normalize((float3(x_34[0], x_34[1], x_34[2]) - x_38));
|
||||
baseColor = float4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
float4 const x_52 = (*(tint_symbol_8)).vDiffuseColor;
|
||||
float4 const x_52 = (*(tint_symbol_11)).vDiffuseColor;
|
||||
diffuseColor = float3(x_52[0], x_52[1], x_52[2]);
|
||||
float const x_60 = (*(tint_symbol_8)).vDiffuseColor[3];
|
||||
float const x_60 = (*(tint_symbol_11)).vDiffuseColor[3];
|
||||
alpha = x_60;
|
||||
float3 const x_62 = float3(0.0f, 0.0f, 0.0f);
|
||||
float3 const x_64 = float3(0.0f, 0.0f, 0.0f);
|
||||
|
@ -76,12 +78,12 @@ void main_1(thread float* const tint_symbol_5, thread float* const tint_symbol_6
|
|||
shadow = 1.0f;
|
||||
refractionColor = float4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
reflectionColor = float4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
float3 const x_94 = (*(tint_symbol_8)).vEmissiveColor;
|
||||
float3 const x_94 = (*(tint_symbol_11)).vEmissiveColor;
|
||||
emissiveColor = x_94;
|
||||
float3 const x_96 = diffuseBase;
|
||||
float3 const x_97 = diffuseColor;
|
||||
float3 const x_99 = emissiveColor;
|
||||
float3 const x_103 = (*(tint_symbol_8)).vAmbientColor;
|
||||
float3 const x_103 = (*(tint_symbol_11)).vAmbientColor;
|
||||
float4 const x_108 = baseColor;
|
||||
finalDiffuse = (clamp((((x_96 * x_97) + x_99) + x_103), float3(0.0f, 0.0f, 0.0f), float3(1.0f, 1.0f, 1.0f)) * float3(x_108[0], x_108[1], x_108[2]));
|
||||
finalSpecular = float3(0.0f, 0.0f, 0.0f);
|
||||
|
@ -97,11 +99,11 @@ void main_1(thread float* const tint_symbol_5, thread float* const tint_symbol_6
|
|||
float3 const x_132 = fmax(float3(x_129[0], x_129[1], x_129[2]), float3(0.0f, 0.0f, 0.0f));
|
||||
float4 const x_133 = color;
|
||||
color = float4(x_132[0], x_132[1], x_132[2], x_133[3]);
|
||||
float const x_140 = (*(tint_symbol_9)).visibility;
|
||||
float const x_140 = (*(tint_symbol_12)).visibility;
|
||||
float const x_142 = color[3];
|
||||
color[3] = (x_142 * x_140);
|
||||
float4 const x_147 = color;
|
||||
*(tint_symbol_10) = x_147;
|
||||
*(tint_symbol_13) = x_147;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -118,19 +120,33 @@ struct tint_symbol_3 {
|
|||
float4 glFragColor_1 [[color(0)]];
|
||||
};
|
||||
|
||||
main_out tint_symbol_inner(float fClipDistance3_param, float fClipDistance4_param, thread float* const tint_symbol_11, thread float* const tint_symbol_12, const constant Scene* const tint_symbol_13, const constant Material* const tint_symbol_14, const constant Mesh* const tint_symbol_15, thread float4* const tint_symbol_16) {
|
||||
*(tint_symbol_11) = fClipDistance3_param;
|
||||
*(tint_symbol_12) = fClipDistance4_param;
|
||||
main_1(tint_symbol_11, tint_symbol_12, tint_symbol_13, tint_symbol_14, tint_symbol_15, tint_symbol_16);
|
||||
main_out const tint_symbol_4 = {.glFragColor_1=*(tint_symbol_16)};
|
||||
main_out tint_symbol_inner(float fClipDistance3_param, float fClipDistance4_param, thread float* const tint_symbol_14, thread float* const tint_symbol_15, thread bool* const tint_symbol_16, const constant Scene* const tint_symbol_17, const constant Material* const tint_symbol_18, const constant Mesh* const tint_symbol_19, thread float4* const tint_symbol_20) {
|
||||
*(tint_symbol_14) = fClipDistance3_param;
|
||||
*(tint_symbol_15) = fClipDistance4_param;
|
||||
main_1(tint_symbol_14, tint_symbol_16, tint_symbol_15, tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_20);
|
||||
if (*(tint_symbol_16)) {
|
||||
main_out const tint_symbol_4 = {};
|
||||
return tint_symbol_4;
|
||||
}
|
||||
main_out const tint_symbol_5 = {.glFragColor_1=*(tint_symbol_20)};
|
||||
return tint_symbol_5;
|
||||
}
|
||||
|
||||
fragment tint_symbol_3 tint_symbol(const constant Scene* tint_symbol_19 [[buffer(0)]], const constant Material* tint_symbol_20 [[buffer(1)]], const constant Mesh* tint_symbol_21 [[buffer(2)]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
|
||||
thread float tint_symbol_17 = 0.0f;
|
||||
thread float tint_symbol_18 = 0.0f;
|
||||
thread float4 tint_symbol_22 = 0.0f;
|
||||
main_out const inner_result = tint_symbol_inner(tint_symbol_1.fClipDistance3_param, tint_symbol_1.fClipDistance4_param, &(tint_symbol_17), &(tint_symbol_18), tint_symbol_19, tint_symbol_20, tint_symbol_21, &(tint_symbol_22));
|
||||
void tint_discard_func() {
|
||||
discard_fragment();
|
||||
}
|
||||
|
||||
fragment tint_symbol_3 tint_symbol(const constant Scene* tint_symbol_24 [[buffer(0)]], const constant Material* tint_symbol_25 [[buffer(1)]], const constant Mesh* tint_symbol_26 [[buffer(2)]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
|
||||
thread float tint_symbol_21 = 0.0f;
|
||||
thread float tint_symbol_22 = 0.0f;
|
||||
thread bool tint_symbol_23 = false;
|
||||
thread float4 tint_symbol_27 = 0.0f;
|
||||
main_out const inner_result = tint_symbol_inner(tint_symbol_1.fClipDistance3_param, tint_symbol_1.fClipDistance4_param, &(tint_symbol_21), &(tint_symbol_22), &(tint_symbol_23), tint_symbol_24, tint_symbol_25, tint_symbol_26, &(tint_symbol_27));
|
||||
if (tint_symbol_23) {
|
||||
tint_discard_func();
|
||||
tint_symbol_3 const tint_symbol_6 = {};
|
||||
return tint_symbol_6;
|
||||
}
|
||||
tint_symbol_3 wrapper_result = {};
|
||||
wrapper_result.glFragColor_1 = inner_result.glFragColor_1;
|
||||
return wrapper_result;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 187
|
||||
; Bound: 198
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%69 = OpExtInstImport "GLSL.std.450"
|
||||
%73 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main" %fClipDistance3_param_1 %fClipDistance4_param_1 %glFragColor_1_1
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
|
@ -27,6 +27,7 @@
|
|||
OpMemberName %Mesh 0 "visibility"
|
||||
OpName %x_137 "x_137"
|
||||
OpName %glFragColor "glFragColor"
|
||||
OpName %tint_discard "tint_discard"
|
||||
OpName %main_1 "main_1"
|
||||
OpName %viewDirectionW "viewDirectionW"
|
||||
OpName %baseColor "baseColor"
|
||||
|
@ -44,6 +45,7 @@
|
|||
OpName %finalDiffuse "finalDiffuse"
|
||||
OpName %finalSpecular "finalSpecular"
|
||||
OpName %color "color"
|
||||
OpName %tint_discard_func "tint_discard_func"
|
||||
OpName %main_out "main_out"
|
||||
OpMemberName %main_out 0 "glFragColor_1"
|
||||
OpName %main_inner "main_inner"
|
||||
|
@ -97,199 +99,217 @@
|
|||
%x_137 = OpVariable %_ptr_Uniform_Mesh Uniform
|
||||
%_ptr_Private_v4float = OpTypePointer Private %v4float
|
||||
%glFragColor = OpVariable %_ptr_Private_v4float Private %8
|
||||
%bool = OpTypeBool
|
||||
%false = OpConstantFalse %bool
|
||||
%_ptr_Private_bool = OpTypePointer Private %bool
|
||||
%tint_discard = OpVariable %_ptr_Private_bool Private %false
|
||||
%void = OpTypeVoid
|
||||
%25 = OpTypeFunction %void
|
||||
%29 = OpTypeFunction %void
|
||||
%_ptr_Function_v3float = OpTypePointer Function %v3float
|
||||
%31 = OpConstantNull %v3float
|
||||
%35 = OpConstantNull %v3float
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%_ptr_Function_float = OpTypePointer Function %float
|
||||
%v2float = OpTypeVector %float 2
|
||||
%_ptr_Function_v2float = OpTypePointer Function %v2float
|
||||
%41 = OpConstantNull %v2float
|
||||
%45 = OpConstantNull %v2float
|
||||
%float_0 = OpConstant %float 0
|
||||
%bool = OpTypeBool
|
||||
%true = OpConstantTrue %bool
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
|
||||
%67 = OpConstantComposite %v3float %float_0 %float_0 %float_0
|
||||
%71 = OpConstantComposite %v3float %float_0 %float_0 %float_0
|
||||
%float_1 = OpConstant %float 1
|
||||
%76 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
|
||||
%80 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
|
||||
%uint_3 = OpConstant %uint 3
|
||||
%_ptr_Uniform_float = OpTypePointer Uniform %float
|
||||
%92 = OpConstantComposite %v2float %float_0 %float_0
|
||||
%93 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
|
||||
%110 = OpConstantComposite %v3float %float_1 %float_1 %float_1
|
||||
%111 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
|
||||
%96 = OpConstantComposite %v2float %float_0 %float_0
|
||||
%97 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
|
||||
%114 = OpConstantComposite %v3float %float_1 %float_1 %float_1
|
||||
%115 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
|
||||
%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
|
||||
%uint_1 = OpConstant %uint 1
|
||||
%main_out = OpTypeStruct %v4float
|
||||
%172 = OpTypeFunction %main_out %float %float
|
||||
%main_1 = OpFunction %void None %25
|
||||
%28 = OpLabel
|
||||
%viewDirectionW = OpVariable %_ptr_Function_v3float Function %31
|
||||
%178 = OpTypeFunction %main_out %float %float
|
||||
%189 = OpConstantNull %main_out
|
||||
%main_1 = OpFunction %void None %29
|
||||
%32 = OpLabel
|
||||
%viewDirectionW = OpVariable %_ptr_Function_v3float Function %35
|
||||
%baseColor = OpVariable %_ptr_Function_v4float Function %8
|
||||
%diffuseColor = OpVariable %_ptr_Function_v3float Function %31
|
||||
%diffuseColor = OpVariable %_ptr_Function_v3float Function %35
|
||||
%alpha = OpVariable %_ptr_Function_float Function %11
|
||||
%normalW = OpVariable %_ptr_Function_v3float Function %31
|
||||
%uvOffset = OpVariable %_ptr_Function_v2float Function %41
|
||||
%baseAmbientColor = OpVariable %_ptr_Function_v3float Function %31
|
||||
%normalW = OpVariable %_ptr_Function_v3float Function %35
|
||||
%uvOffset = OpVariable %_ptr_Function_v2float Function %45
|
||||
%baseAmbientColor = OpVariable %_ptr_Function_v3float Function %35
|
||||
%glossiness = OpVariable %_ptr_Function_float Function %11
|
||||
%diffuseBase = OpVariable %_ptr_Function_v3float Function %31
|
||||
%diffuseBase = OpVariable %_ptr_Function_v3float Function %35
|
||||
%shadow = OpVariable %_ptr_Function_float Function %11
|
||||
%refractionColor = OpVariable %_ptr_Function_v4float Function %8
|
||||
%reflectionColor = OpVariable %_ptr_Function_v4float Function %8
|
||||
%emissiveColor = OpVariable %_ptr_Function_v3float Function %31
|
||||
%finalDiffuse = OpVariable %_ptr_Function_v3float Function %31
|
||||
%finalSpecular = OpVariable %_ptr_Function_v3float Function %31
|
||||
%emissiveColor = OpVariable %_ptr_Function_v3float Function %35
|
||||
%finalDiffuse = OpVariable %_ptr_Function_v3float Function %35
|
||||
%finalSpecular = OpVariable %_ptr_Function_v3float Function %35
|
||||
%color = OpVariable %_ptr_Function_v4float Function %8
|
||||
%52 = OpLoad %float %fClipDistance3
|
||||
%54 = OpFOrdGreaterThan %bool %52 %float_0
|
||||
OpSelectionMerge %56 None
|
||||
OpBranchConditional %54 %57 %56
|
||||
%57 = OpLabel
|
||||
OpKill
|
||||
%56 = OpLabel
|
||||
%58 = OpLoad %float %fClipDistance4
|
||||
%59 = OpFOrdGreaterThan %bool %58 %float_0
|
||||
OpSelectionMerge %60 None
|
||||
OpBranchConditional %59 %61 %60
|
||||
%61 = OpLabel
|
||||
OpKill
|
||||
%56 = OpLoad %float %fClipDistance3
|
||||
%58 = OpFOrdGreaterThan %bool %56 %float_0
|
||||
OpSelectionMerge %59 None
|
||||
OpBranchConditional %58 %60 %59
|
||||
%60 = OpLabel
|
||||
%65 = OpAccessChain %_ptr_Uniform_v4float %x_29 %uint_0
|
||||
%66 = OpLoad %v4float %65
|
||||
%70 = OpCompositeExtract %float %66 0
|
||||
%71 = OpCompositeExtract %float %66 1
|
||||
%72 = OpCompositeExtract %float %66 2
|
||||
%73 = OpCompositeConstruct %v3float %70 %71 %72
|
||||
%74 = OpFSub %v3float %73 %67
|
||||
%68 = OpExtInst %v3float %69 Normalize %74
|
||||
OpStore %viewDirectionW %68
|
||||
OpStore %baseColor %76
|
||||
%77 = OpAccessChain %_ptr_Uniform_v4float %x_49 %uint_0
|
||||
%78 = OpLoad %v4float %77
|
||||
%79 = OpCompositeExtract %float %78 0
|
||||
%80 = OpCompositeExtract %float %78 1
|
||||
%81 = OpCompositeExtract %float %78 2
|
||||
%82 = OpCompositeConstruct %v3float %79 %80 %81
|
||||
OpStore %diffuseColor %82
|
||||
%85 = OpAccessChain %_ptr_Uniform_float %x_49 %uint_0 %uint_3
|
||||
%86 = OpLoad %float %85
|
||||
OpStore %alpha %86
|
||||
%90 = OpDPdx %v3float %67
|
||||
%91 = OpDPdy %v3float %67
|
||||
%89 = OpExtInst %v3float %69 Cross %90 %91
|
||||
%88 = OpFNegate %v3float %89
|
||||
%87 = OpExtInst %v3float %69 Normalize %88
|
||||
OpStore %normalW %87
|
||||
OpStore %uvOffset %92
|
||||
%94 = OpLoad %v4float %baseColor
|
||||
%95 = OpCompositeExtract %float %94 0
|
||||
%96 = OpCompositeExtract %float %94 1
|
||||
%97 = OpCompositeExtract %float %94 2
|
||||
%98 = OpCompositeConstruct %v3float %95 %96 %97
|
||||
%99 = OpCompositeExtract %float %93 0
|
||||
%100 = OpCompositeExtract %float %93 1
|
||||
%101 = OpCompositeExtract %float %93 2
|
||||
OpStore %tint_discard %true
|
||||
OpReturn
|
||||
%59 = OpLabel
|
||||
%62 = OpLoad %float %fClipDistance4
|
||||
%63 = OpFOrdGreaterThan %bool %62 %float_0
|
||||
OpSelectionMerge %64 None
|
||||
OpBranchConditional %63 %65 %64
|
||||
%65 = OpLabel
|
||||
OpStore %tint_discard %true
|
||||
OpReturn
|
||||
%64 = OpLabel
|
||||
%69 = OpAccessChain %_ptr_Uniform_v4float %x_29 %uint_0
|
||||
%70 = OpLoad %v4float %69
|
||||
%74 = OpCompositeExtract %float %70 0
|
||||
%75 = OpCompositeExtract %float %70 1
|
||||
%76 = OpCompositeExtract %float %70 2
|
||||
%77 = OpCompositeConstruct %v3float %74 %75 %76
|
||||
%78 = OpFSub %v3float %77 %71
|
||||
%72 = OpExtInst %v3float %73 Normalize %78
|
||||
OpStore %viewDirectionW %72
|
||||
OpStore %baseColor %80
|
||||
%81 = OpAccessChain %_ptr_Uniform_v4float %x_49 %uint_0
|
||||
%82 = OpLoad %v4float %81
|
||||
%83 = OpCompositeExtract %float %82 0
|
||||
%84 = OpCompositeExtract %float %82 1
|
||||
%85 = OpCompositeExtract %float %82 2
|
||||
%86 = OpCompositeConstruct %v3float %83 %84 %85
|
||||
OpStore %diffuseColor %86
|
||||
%89 = OpAccessChain %_ptr_Uniform_float %x_49 %uint_0 %uint_3
|
||||
%90 = OpLoad %float %89
|
||||
OpStore %alpha %90
|
||||
%94 = OpDPdx %v3float %71
|
||||
%95 = OpDPdy %v3float %71
|
||||
%93 = OpExtInst %v3float %73 Cross %94 %95
|
||||
%92 = OpFNegate %v3float %93
|
||||
%91 = OpExtInst %v3float %73 Normalize %92
|
||||
OpStore %normalW %91
|
||||
OpStore %uvOffset %96
|
||||
%98 = OpLoad %v4float %baseColor
|
||||
%99 = OpCompositeExtract %float %98 0
|
||||
%100 = OpCompositeExtract %float %98 1
|
||||
%101 = OpCompositeExtract %float %98 2
|
||||
%102 = OpCompositeConstruct %v3float %99 %100 %101
|
||||
%103 = OpFMul %v3float %98 %102
|
||||
%104 = OpLoad %v4float %baseColor
|
||||
%105 = OpCompositeExtract %float %103 0
|
||||
%106 = OpCompositeExtract %float %103 1
|
||||
%107 = OpCompositeExtract %float %103 2
|
||||
%108 = OpCompositeExtract %float %104 3
|
||||
%109 = OpCompositeConstruct %v4float %105 %106 %107 %108
|
||||
OpStore %baseColor %109
|
||||
OpStore %baseAmbientColor %110
|
||||
%103 = OpCompositeExtract %float %97 0
|
||||
%104 = OpCompositeExtract %float %97 1
|
||||
%105 = OpCompositeExtract %float %97 2
|
||||
%106 = OpCompositeConstruct %v3float %103 %104 %105
|
||||
%107 = OpFMul %v3float %102 %106
|
||||
%108 = OpLoad %v4float %baseColor
|
||||
%109 = OpCompositeExtract %float %107 0
|
||||
%110 = OpCompositeExtract %float %107 1
|
||||
%111 = OpCompositeExtract %float %107 2
|
||||
%112 = OpCompositeExtract %float %108 3
|
||||
%113 = OpCompositeConstruct %v4float %109 %110 %111 %112
|
||||
OpStore %baseColor %113
|
||||
OpStore %baseAmbientColor %114
|
||||
OpStore %glossiness %float_0
|
||||
OpStore %diffuseBase %67
|
||||
OpStore %diffuseBase %71
|
||||
OpStore %shadow %float_1
|
||||
OpStore %refractionColor %111
|
||||
OpStore %reflectionColor %111
|
||||
%113 = OpAccessChain %_ptr_Uniform_v3float %x_49 %uint_3
|
||||
%114 = OpLoad %v3float %113
|
||||
OpStore %emissiveColor %114
|
||||
%115 = OpLoad %v3float %diffuseBase
|
||||
%116 = OpLoad %v3float %diffuseColor
|
||||
%117 = OpLoad %v3float %emissiveColor
|
||||
%119 = OpAccessChain %_ptr_Uniform_v3float %x_49 %uint_1
|
||||
%120 = OpLoad %v3float %119
|
||||
%121 = OpLoad %v4float %baseColor
|
||||
%123 = OpFMul %v3float %115 %116
|
||||
%124 = OpFAdd %v3float %123 %117
|
||||
%125 = OpFAdd %v3float %124 %120
|
||||
%122 = OpExtInst %v3float %69 NClamp %125 %67 %110
|
||||
%126 = OpCompositeExtract %float %121 0
|
||||
%127 = OpCompositeExtract %float %121 1
|
||||
%128 = OpCompositeExtract %float %121 2
|
||||
%129 = OpCompositeConstruct %v3float %126 %127 %128
|
||||
%130 = OpFMul %v3float %122 %129
|
||||
OpStore %finalDiffuse %130
|
||||
OpStore %finalSpecular %67
|
||||
%131 = OpLoad %v3float %finalDiffuse
|
||||
%132 = OpLoad %v3float %baseAmbientColor
|
||||
%133 = OpLoad %v3float %finalSpecular
|
||||
%134 = OpLoad %v4float %reflectionColor
|
||||
%135 = OpLoad %v4float %refractionColor
|
||||
%136 = OpFMul %v3float %131 %132
|
||||
%137 = OpFAdd %v3float %136 %133
|
||||
%138 = OpCompositeExtract %float %134 0
|
||||
%139 = OpCompositeExtract %float %134 1
|
||||
%140 = OpCompositeExtract %float %134 2
|
||||
%141 = OpCompositeConstruct %v3float %138 %139 %140
|
||||
%142 = OpFAdd %v3float %137 %141
|
||||
%143 = OpCompositeExtract %float %135 0
|
||||
%144 = OpCompositeExtract %float %135 1
|
||||
%145 = OpCompositeExtract %float %135 2
|
||||
%146 = OpCompositeConstruct %v3float %143 %144 %145
|
||||
%147 = OpFAdd %v3float %142 %146
|
||||
%148 = OpLoad %float %alpha
|
||||
%149 = OpCompositeExtract %float %147 0
|
||||
%150 = OpCompositeExtract %float %147 1
|
||||
%151 = OpCompositeExtract %float %147 2
|
||||
%152 = OpCompositeConstruct %v4float %149 %150 %151 %148
|
||||
OpStore %color %152
|
||||
%153 = OpLoad %v4float %color
|
||||
%155 = OpCompositeExtract %float %153 0
|
||||
%156 = OpCompositeExtract %float %153 1
|
||||
%157 = OpCompositeExtract %float %153 2
|
||||
%158 = OpCompositeConstruct %v3float %155 %156 %157
|
||||
%154 = OpExtInst %v3float %69 NMax %158 %67
|
||||
%159 = OpLoad %v4float %color
|
||||
%160 = OpCompositeExtract %float %154 0
|
||||
%161 = OpCompositeExtract %float %154 1
|
||||
%162 = OpCompositeExtract %float %154 2
|
||||
%163 = OpCompositeExtract %float %159 3
|
||||
%164 = OpCompositeConstruct %v4float %160 %161 %162 %163
|
||||
OpStore %color %164
|
||||
%165 = OpAccessChain %_ptr_Uniform_float %x_137 %uint_0
|
||||
%166 = OpLoad %float %165
|
||||
%167 = OpAccessChain %_ptr_Function_float %color %uint_3
|
||||
%168 = OpLoad %float %167
|
||||
%169 = OpAccessChain %_ptr_Function_float %color %uint_3
|
||||
%170 = OpFMul %float %168 %166
|
||||
OpStore %169 %170
|
||||
%171 = OpLoad %v4float %color
|
||||
OpStore %glFragColor %171
|
||||
OpStore %refractionColor %115
|
||||
OpStore %reflectionColor %115
|
||||
%117 = OpAccessChain %_ptr_Uniform_v3float %x_49 %uint_3
|
||||
%118 = OpLoad %v3float %117
|
||||
OpStore %emissiveColor %118
|
||||
%119 = OpLoad %v3float %diffuseBase
|
||||
%120 = OpLoad %v3float %diffuseColor
|
||||
%121 = OpLoad %v3float %emissiveColor
|
||||
%123 = OpAccessChain %_ptr_Uniform_v3float %x_49 %uint_1
|
||||
%124 = OpLoad %v3float %123
|
||||
%125 = OpLoad %v4float %baseColor
|
||||
%127 = OpFMul %v3float %119 %120
|
||||
%128 = OpFAdd %v3float %127 %121
|
||||
%129 = OpFAdd %v3float %128 %124
|
||||
%126 = OpExtInst %v3float %73 NClamp %129 %71 %114
|
||||
%130 = OpCompositeExtract %float %125 0
|
||||
%131 = OpCompositeExtract %float %125 1
|
||||
%132 = OpCompositeExtract %float %125 2
|
||||
%133 = OpCompositeConstruct %v3float %130 %131 %132
|
||||
%134 = OpFMul %v3float %126 %133
|
||||
OpStore %finalDiffuse %134
|
||||
OpStore %finalSpecular %71
|
||||
%135 = OpLoad %v3float %finalDiffuse
|
||||
%136 = OpLoad %v3float %baseAmbientColor
|
||||
%137 = OpLoad %v3float %finalSpecular
|
||||
%138 = OpLoad %v4float %reflectionColor
|
||||
%139 = OpLoad %v4float %refractionColor
|
||||
%140 = OpFMul %v3float %135 %136
|
||||
%141 = OpFAdd %v3float %140 %137
|
||||
%142 = OpCompositeExtract %float %138 0
|
||||
%143 = OpCompositeExtract %float %138 1
|
||||
%144 = OpCompositeExtract %float %138 2
|
||||
%145 = OpCompositeConstruct %v3float %142 %143 %144
|
||||
%146 = OpFAdd %v3float %141 %145
|
||||
%147 = OpCompositeExtract %float %139 0
|
||||
%148 = OpCompositeExtract %float %139 1
|
||||
%149 = OpCompositeExtract %float %139 2
|
||||
%150 = OpCompositeConstruct %v3float %147 %148 %149
|
||||
%151 = OpFAdd %v3float %146 %150
|
||||
%152 = OpLoad %float %alpha
|
||||
%153 = OpCompositeExtract %float %151 0
|
||||
%154 = OpCompositeExtract %float %151 1
|
||||
%155 = OpCompositeExtract %float %151 2
|
||||
%156 = OpCompositeConstruct %v4float %153 %154 %155 %152
|
||||
OpStore %color %156
|
||||
%157 = OpLoad %v4float %color
|
||||
%159 = OpCompositeExtract %float %157 0
|
||||
%160 = OpCompositeExtract %float %157 1
|
||||
%161 = OpCompositeExtract %float %157 2
|
||||
%162 = OpCompositeConstruct %v3float %159 %160 %161
|
||||
%158 = OpExtInst %v3float %73 NMax %162 %71
|
||||
%163 = OpLoad %v4float %color
|
||||
%164 = OpCompositeExtract %float %158 0
|
||||
%165 = OpCompositeExtract %float %158 1
|
||||
%166 = OpCompositeExtract %float %158 2
|
||||
%167 = OpCompositeExtract %float %163 3
|
||||
%168 = OpCompositeConstruct %v4float %164 %165 %166 %167
|
||||
OpStore %color %168
|
||||
%169 = OpAccessChain %_ptr_Uniform_float %x_137 %uint_0
|
||||
%170 = OpLoad %float %169
|
||||
%171 = OpAccessChain %_ptr_Function_float %color %uint_3
|
||||
%172 = OpLoad %float %171
|
||||
%173 = OpAccessChain %_ptr_Function_float %color %uint_3
|
||||
%174 = OpFMul %float %172 %170
|
||||
OpStore %173 %174
|
||||
%175 = OpLoad %v4float %color
|
||||
OpStore %glFragColor %175
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%main_inner = OpFunction %main_out None %172
|
||||
%tint_discard_func = OpFunction %void None %29
|
||||
%177 = OpLabel
|
||||
OpKill
|
||||
OpFunctionEnd
|
||||
%main_inner = OpFunction %main_out None %178
|
||||
%fClipDistance3_param = OpFunctionParameter %float
|
||||
%fClipDistance4_param = OpFunctionParameter %float
|
||||
%177 = OpLabel
|
||||
%183 = OpLabel
|
||||
OpStore %fClipDistance3 %fClipDistance3_param
|
||||
OpStore %fClipDistance4 %fClipDistance4_param
|
||||
%178 = OpFunctionCall %void %main_1
|
||||
%179 = OpLoad %v4float %glFragColor
|
||||
%180 = OpCompositeConstruct %main_out %179
|
||||
OpReturnValue %180
|
||||
%184 = OpFunctionCall %void %main_1
|
||||
%185 = OpLoad %bool %tint_discard
|
||||
OpSelectionMerge %186 None
|
||||
OpBranchConditional %185 %187 %186
|
||||
%187 = OpLabel
|
||||
%188 = OpFunctionCall %void %tint_discard_func
|
||||
OpReturnValue %189
|
||||
%186 = OpLabel
|
||||
%190 = OpLoad %v4float %glFragColor
|
||||
%191 = OpCompositeConstruct %main_out %190
|
||||
OpReturnValue %191
|
||||
OpFunctionEnd
|
||||
%main = OpFunction %void None %25
|
||||
%182 = OpLabel
|
||||
%184 = OpLoad %float %fClipDistance3_param_1
|
||||
%185 = OpLoad %float %fClipDistance4_param_1
|
||||
%183 = OpFunctionCall %main_out %main_inner %184 %185
|
||||
%186 = OpCompositeExtract %v4float %183 0
|
||||
OpStore %glFragColor_1_1 %186
|
||||
%main = OpFunction %void None %29
|
||||
%193 = OpLabel
|
||||
%195 = OpLoad %float %fClipDistance3_param_1
|
||||
%196 = OpLoad %float %fClipDistance4_param_1
|
||||
%194 = OpFunctionCall %main_out %main_inner %195 %196
|
||||
%197 = OpCompositeExtract %v4float %194 0
|
||||
OpStore %glFragColor_1_1 %197
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
|
|
|
@ -9,17 +9,30 @@ bug/tint/1369.wgsl:9:9 warning: code is unreachable
|
|||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
bool tint_discard = false;
|
||||
bool call_discard() {
|
||||
discard;
|
||||
tint_discard = true;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void f() {
|
||||
bool v = call_discard();
|
||||
if (tint_discard) {
|
||||
return;
|
||||
}
|
||||
bool also_unreachable = false;
|
||||
}
|
||||
|
||||
void tint_discard_func() {
|
||||
discard;
|
||||
}
|
||||
|
||||
void main() {
|
||||
f();
|
||||
if (tint_discard) {
|
||||
tint_discard_func();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -6,17 +6,24 @@ bug/tint/1369.wgsl:9:9 warning: code is unreachable
|
|||
var also_unreachable : bool;
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
static bool tint_discard = false;
|
||||
|
||||
bool call_discard() {
|
||||
if (true) {
|
||||
discard;
|
||||
tint_discard = true;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool unused;
|
||||
return unused;
|
||||
|
||||
void tint_discard_func() {
|
||||
discard;
|
||||
}
|
||||
|
||||
void f() {
|
||||
bool v = call_discard();
|
||||
if (tint_discard) {
|
||||
tint_discard_func();
|
||||
return;
|
||||
}
|
||||
bool also_unreachable = false;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -9,13 +9,23 @@ bug/tint/1369.wgsl:9:9 warning: code is unreachable
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
bool call_discard() {
|
||||
discard_fragment();
|
||||
bool call_discard(thread bool* const tint_symbol) {
|
||||
*(tint_symbol) = true;
|
||||
return bool();
|
||||
return true;
|
||||
}
|
||||
|
||||
void tint_discard_func() {
|
||||
discard_fragment();
|
||||
}
|
||||
|
||||
fragment void f() {
|
||||
bool v = call_discard();
|
||||
thread bool tint_symbol_1 = false;
|
||||
bool v = call_discard(&(tint_symbol_1));
|
||||
if (tint_symbol_1) {
|
||||
tint_discard_func();
|
||||
return;
|
||||
}
|
||||
bool also_unreachable = false;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -9,29 +9,47 @@ bug/tint/1369.wgsl:9:9 warning: code is unreachable
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 13
|
||||
; Bound: 23
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %f "f"
|
||||
OpExecutionMode %f OriginUpperLeft
|
||||
OpName %tint_discard "tint_discard"
|
||||
OpName %call_discard "call_discard"
|
||||
OpName %tint_discard_func "tint_discard_func"
|
||||
OpName %f "f"
|
||||
OpName %v "v"
|
||||
%bool = OpTypeBool
|
||||
%1 = OpTypeFunction %bool
|
||||
%false = OpConstantFalse %bool
|
||||
%_ptr_Private_bool = OpTypePointer Private %bool
|
||||
%tint_discard = OpVariable %_ptr_Private_bool Private %false
|
||||
%5 = OpTypeFunction %bool
|
||||
%true = OpConstantTrue %bool
|
||||
%9 = OpConstantNull %bool
|
||||
%void = OpTypeVoid
|
||||
%5 = OpTypeFunction %void
|
||||
%10 = OpTypeFunction %void
|
||||
%_ptr_Function_bool = OpTypePointer Function %bool
|
||||
%12 = OpConstantNull %bool
|
||||
%call_discard = OpFunction %bool None %1
|
||||
%4 = OpLabel
|
||||
%call_discard = OpFunction %bool None %5
|
||||
%7 = OpLabel
|
||||
OpStore %tint_discard %true
|
||||
OpReturnValue %9
|
||||
OpFunctionEnd
|
||||
%tint_discard_func = OpFunction %void None %10
|
||||
%13 = OpLabel
|
||||
OpKill
|
||||
OpFunctionEnd
|
||||
%f = OpFunction %void None %5
|
||||
%8 = OpLabel
|
||||
%v = OpVariable %_ptr_Function_bool Function %12
|
||||
%9 = OpFunctionCall %bool %call_discard
|
||||
OpStore %v %9
|
||||
%f = OpFunction %void None %10
|
||||
%15 = OpLabel
|
||||
%v = OpVariable %_ptr_Function_bool Function %9
|
||||
%16 = OpFunctionCall %bool %call_discard
|
||||
OpStore %v %16
|
||||
%19 = OpLoad %bool %tint_discard
|
||||
OpSelectionMerge %20 None
|
||||
OpBranchConditional %19 %21 %20
|
||||
%21 = OpLabel
|
||||
%22 = OpFunctionCall %void %tint_discard_func
|
||||
OpReturn
|
||||
%20 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
warning: code is unreachable
|
||||
static uint var_1 = 0u;
|
||||
|
||||
void main_1() {
|
||||
[loop] while (true) {
|
||||
discard;
|
||||
}
|
||||
discard;
|
||||
}
|
||||
|
||||
void main() {
|
||||
main_1();
|
||||
return;
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
cbuffer cbuffer_x_6 : register(b0, space0) {
|
||||
uint4 x_6[1];
|
||||
};
|
||||
static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
void func_() {
|
||||
const float x_28 = asfloat(x_6[0].x);
|
||||
if ((1.0f > x_28)) {
|
||||
discard;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void main_1() {
|
||||
x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
[loop] while (true) {
|
||||
func_();
|
||||
if (false) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
struct main_out {
|
||||
float4 x_GLF_color_1;
|
||||
};
|
||||
struct tint_symbol {
|
||||
float4 x_GLF_color_1 : SV_Target0;
|
||||
};
|
||||
|
||||
main_out main_inner() {
|
||||
main_1();
|
||||
const main_out tint_symbol_2 = {x_GLF_color};
|
||||
return tint_symbol_2;
|
||||
}
|
||||
|
||||
tint_symbol main() {
|
||||
const main_out inner_result = main_inner();
|
||||
tint_symbol wrapper_result = (tint_symbol)0;
|
||||
wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
|
||||
return wrapper_result;
|
||||
}
|
||||
C:\src\tint\test\Shader@0x0000016102DC2B30(16,10-21): warning X3557: loop only executes for 0 iteration(s), consider removing [loop]
|
||||
C:\src\tint\test\Shader@0x0000016102DC2B30(8,15-18): internal error: invalid access of unbound variable
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
cbuffer cbuffer_x_6 : register(b0, space0) {
|
||||
uint4 x_6[1];
|
||||
};
|
||||
static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
void func_() {
|
||||
const float x_28 = asfloat(x_6[0].x);
|
||||
if ((1.0f > x_28)) {
|
||||
discard;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void main_1() {
|
||||
x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
[loop] while (true) {
|
||||
func_();
|
||||
if (false) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
struct main_out {
|
||||
float4 x_GLF_color_1;
|
||||
};
|
||||
struct tint_symbol {
|
||||
float4 x_GLF_color_1 : SV_Target0;
|
||||
};
|
||||
|
||||
main_out main_inner() {
|
||||
main_1();
|
||||
const main_out tint_symbol_2 = {x_GLF_color};
|
||||
return tint_symbol_2;
|
||||
}
|
||||
|
||||
tint_symbol main() {
|
||||
const main_out inner_result = main_inner();
|
||||
tint_symbol wrapper_result = (tint_symbol)0;
|
||||
wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
|
||||
return wrapper_result;
|
||||
}
|
||||
C:\src\tint\test\Shader@0x0000026A3937ED10(16,10-21): warning X3557: loop only executes for 0 iteration(s), consider removing [loop]
|
||||
C:\src\tint\test\Shader@0x0000026A3937ED10(8,15-18): internal error: invalid access of unbound variable
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,64 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
cbuffer cbuffer_x_7 : register(b0, space0) {
|
||||
uint4 x_7[1];
|
||||
};
|
||||
static float4 gl_FragCoord = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
float3 computePoint_() {
|
||||
if (true) {
|
||||
const float x_48 = asfloat(x_7[0].x);
|
||||
const float x_50 = asfloat(x_7[0].y);
|
||||
if ((x_48 > x_50)) {
|
||||
discard;
|
||||
}
|
||||
return float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
float3 unused;
|
||||
return unused;
|
||||
}
|
||||
|
||||
void main_1() {
|
||||
bool x_34 = false;
|
||||
[loop] while (true) {
|
||||
const float3 x_36 = computePoint_();
|
||||
const float x_41 = gl_FragCoord.x;
|
||||
if ((x_41 < 0.0f)) {
|
||||
x_34 = true;
|
||||
break;
|
||||
}
|
||||
const float3 x_45 = computePoint_();
|
||||
x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
x_34 = true;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
struct main_out {
|
||||
float4 x_GLF_color_1;
|
||||
};
|
||||
struct tint_symbol_1 {
|
||||
float4 gl_FragCoord_param : SV_Position;
|
||||
};
|
||||
struct tint_symbol_2 {
|
||||
float4 x_GLF_color_1 : SV_Target0;
|
||||
};
|
||||
|
||||
main_out main_inner(float4 gl_FragCoord_param) {
|
||||
gl_FragCoord = gl_FragCoord_param;
|
||||
main_1();
|
||||
const main_out tint_symbol_4 = {x_GLF_color};
|
||||
return tint_symbol_4;
|
||||
}
|
||||
|
||||
tint_symbol_2 main(tint_symbol_1 tint_symbol) {
|
||||
const main_out inner_result = main_inner(tint_symbol.gl_FragCoord_param);
|
||||
tint_symbol_2 wrapper_result = (tint_symbol_2)0;
|
||||
wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
|
||||
return wrapper_result;
|
||||
}
|
||||
C:\src\tint\test\Shader@0x0000014F8C58FE70(22,10-21): warning X3557: loop only executes for 0 iteration(s), consider removing [loop]
|
||||
C:\src\tint\test\Shader@0x0000014F8C58FE70(11,10-13): internal error: invalid access of unbound variable
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
cbuffer cbuffer_x_7 : register(b0, space0) {
|
||||
uint4 x_7[1];
|
||||
};
|
||||
static float4 gl_FragCoord = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
float3 computePoint_() {
|
||||
if (true) {
|
||||
const float x_48 = asfloat(x_7[0].x);
|
||||
const float x_50 = asfloat(x_7[0].y);
|
||||
if ((x_48 > x_50)) {
|
||||
discard;
|
||||
}
|
||||
return float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
float3 unused;
|
||||
return unused;
|
||||
}
|
||||
|
||||
void main_1() {
|
||||
bool x_34 = false;
|
||||
[loop] while (true) {
|
||||
const float3 x_36 = computePoint_();
|
||||
const float x_41 = gl_FragCoord.x;
|
||||
if ((x_41 < 0.0f)) {
|
||||
x_34 = true;
|
||||
break;
|
||||
}
|
||||
const float3 x_45 = computePoint_();
|
||||
x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
x_34 = true;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
struct main_out {
|
||||
float4 x_GLF_color_1;
|
||||
};
|
||||
struct tint_symbol_1 {
|
||||
float4 gl_FragCoord_param : SV_Position;
|
||||
};
|
||||
struct tint_symbol_2 {
|
||||
float4 x_GLF_color_1 : SV_Target0;
|
||||
};
|
||||
|
||||
main_out main_inner(float4 gl_FragCoord_param) {
|
||||
gl_FragCoord = gl_FragCoord_param;
|
||||
main_1();
|
||||
const main_out tint_symbol_4 = {x_GLF_color};
|
||||
return tint_symbol_4;
|
||||
}
|
||||
|
||||
tint_symbol_2 main(tint_symbol_1 tint_symbol) {
|
||||
const main_out inner_result = main_inner(tint_symbol.gl_FragCoord_param);
|
||||
tint_symbol_2 wrapper_result = (tint_symbol_2)0;
|
||||
wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
|
||||
return wrapper_result;
|
||||
}
|
||||
C:\src\tint\test\Shader@0x0000017E3AA920C0(22,10-21): warning X3557: loop only executes for 0 iteration(s), consider removing [loop]
|
||||
C:\src\tint\test\Shader@0x0000017E3AA920C0(11,10-13): internal error: invalid access of unbound variable
|
||||
|
Loading…
Reference in New Issue