writer/hlsl: Implement atomics
Storage buffers are emitted as `ByteAddressBuffer`s in HLSL, so we have to jump through hoops to support atomic ops on storage buffer atomics. Workgroup atomics are far more conventional, but very little code can be shared between these two code paths. Bug: tint:892 Change-Id: If10ea866e3b67a093e87aca689d34065fd49b705 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/54651 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
0a32a724f4
commit
e6d171ac66
|
@ -88,6 +88,19 @@ bool IsBarrierIntrinsic(IntrinsicType i) {
|
|||
i == IntrinsicType::kStorageBarrier;
|
||||
}
|
||||
|
||||
bool IsAtomicIntrinsic(IntrinsicType i) {
|
||||
return i == sem::IntrinsicType::kAtomicLoad ||
|
||||
i == sem::IntrinsicType::kAtomicStore ||
|
||||
i == sem::IntrinsicType::kAtomicAdd ||
|
||||
i == sem::IntrinsicType::kAtomicMax ||
|
||||
i == sem::IntrinsicType::kAtomicMin ||
|
||||
i == sem::IntrinsicType::kAtomicAnd ||
|
||||
i == sem::IntrinsicType::kAtomicOr ||
|
||||
i == sem::IntrinsicType::kAtomicXor ||
|
||||
i == sem::IntrinsicType::kAtomicExchange ||
|
||||
i == sem::IntrinsicType::kAtomicCompareExchangeWeak;
|
||||
}
|
||||
|
||||
Intrinsic::Intrinsic(IntrinsicType type,
|
||||
sem::Type* return_type,
|
||||
const ParameterList& parameters,
|
||||
|
@ -136,5 +149,9 @@ bool Intrinsic::IsBarrier() const {
|
|||
return IsBarrierIntrinsic(type_);
|
||||
}
|
||||
|
||||
bool Intrinsic::IsAtomic() const {
|
||||
return IsAtomicIntrinsic(type_);
|
||||
}
|
||||
|
||||
} // namespace sem
|
||||
} // namespace tint
|
||||
|
|
|
@ -69,6 +69,11 @@ bool IsDataUnpackingIntrinsic(IntrinsicType i);
|
|||
/// @returns true if the given `i` is a barrier intrinsic
|
||||
bool IsBarrierIntrinsic(IntrinsicType i);
|
||||
|
||||
/// Determines if the given `i` is a atomic intrinsic
|
||||
/// @param i the intrinsic
|
||||
/// @returns true if the given `i` is a atomic intrinsic
|
||||
bool IsAtomicIntrinsic(IntrinsicType i);
|
||||
|
||||
/// Intrinsic holds the semantic information for an intrinsic function.
|
||||
class Intrinsic : public Castable<Intrinsic, CallTarget> {
|
||||
public:
|
||||
|
@ -129,6 +134,9 @@ class Intrinsic : public Castable<Intrinsic, CallTarget> {
|
|||
/// @returns true if intrinsic is a barrier intrinsic
|
||||
bool IsBarrier() const;
|
||||
|
||||
/// @returns true if intrinsic is a atomic intrinsic
|
||||
bool IsAtomic() const;
|
||||
|
||||
private:
|
||||
IntrinsicType const type_;
|
||||
PipelineStageSet const supported_stages_;
|
||||
|
|
|
@ -25,8 +25,10 @@
|
|||
#include "src/ast/disable_validation_decoration.h"
|
||||
#include "src/ast/scalar_constructor_expression.h"
|
||||
#include "src/ast/type_name.h"
|
||||
#include "src/ast/unary_op.h"
|
||||
#include "src/program_builder.h"
|
||||
#include "src/sem/array.h"
|
||||
#include "src/sem/atomic_type.h"
|
||||
#include "src/sem/call.h"
|
||||
#include "src/sem/member_accessor_expression.h"
|
||||
#include "src/sem/reference_type.h"
|
||||
|
@ -175,16 +177,31 @@ std::unique_ptr<Offset> Mul(LHS&& lhs_, RHS&& rhs_) {
|
|||
return out;
|
||||
}
|
||||
|
||||
/// TypePair is a pair of types that can be used as a unordered map or set key.
|
||||
struct TypePair {
|
||||
sem::Type const* first;
|
||||
sem::Type const* second;
|
||||
bool operator==(const TypePair& rhs) const {
|
||||
return first == rhs.first && second == rhs.second;
|
||||
/// LoadStoreKey is the unordered map key to a load or store intrinsic.
|
||||
struct LoadStoreKey {
|
||||
sem::Type const* buf_ty; // buffer type
|
||||
sem::Type const* el_ty; // element type
|
||||
bool operator==(const LoadStoreKey& rhs) const {
|
||||
return buf_ty == rhs.buf_ty && el_ty == rhs.el_ty;
|
||||
}
|
||||
struct Hasher {
|
||||
inline std::size_t operator()(const TypePair& u) const {
|
||||
return utils::Hash(u.first, u.second);
|
||||
inline std::size_t operator()(const LoadStoreKey& u) const {
|
||||
return utils::Hash(u.buf_ty, u.el_ty);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/// AtomicKey is the unordered map key to an atomic intrinsic.
|
||||
struct AtomicKey {
|
||||
sem::Type const* buf_ty; // buffer type
|
||||
sem::Type const* el_ty; // element type
|
||||
sem::IntrinsicType const op; // atomic op
|
||||
bool operator==(const AtomicKey& rhs) const {
|
||||
return buf_ty == rhs.buf_ty && el_ty == rhs.el_ty && op == rhs.op;
|
||||
}
|
||||
struct Hasher {
|
||||
inline std::size_t operator()(const AtomicKey& u) const {
|
||||
return utils::Hash(u.buf_ty, u.el_ty, u.op);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -200,122 +217,145 @@ uint32_t MatrixColumnStride(const sem::Matrix* mat) {
|
|||
return ScalarSize(mat->type()) * ((mat->rows() == 2) ? 2 : 4);
|
||||
}
|
||||
|
||||
/// @returns a DecomposeStorageAccess::Intrinsic decoration that can be applied
|
||||
/// to a stub function to load the type `ty`.
|
||||
DecomposeStorageAccess::Intrinsic* IntrinsicLoadFor(ProgramBuilder* builder,
|
||||
const sem::Type* ty) {
|
||||
using Intrinsic = DecomposeStorageAccess::Intrinsic;
|
||||
|
||||
auto intrinsic = [builder](Intrinsic::Type type) {
|
||||
return builder->ASTNodes().Create<Intrinsic>(builder->ID(), type);
|
||||
};
|
||||
|
||||
bool IntrinsicDataTypeFor(const sem::Type* ty,
|
||||
DecomposeStorageAccess::Intrinsic::DataType& out) {
|
||||
if (ty->Is<sem::I32>()) {
|
||||
return intrinsic(Intrinsic::kLoadI32);
|
||||
out = DecomposeStorageAccess::Intrinsic::DataType::kI32;
|
||||
return true;
|
||||
}
|
||||
if (ty->Is<sem::U32>()) {
|
||||
return intrinsic(Intrinsic::kLoadU32);
|
||||
out = DecomposeStorageAccess::Intrinsic::DataType::kU32;
|
||||
return true;
|
||||
}
|
||||
if (ty->Is<sem::F32>()) {
|
||||
return intrinsic(Intrinsic::kLoadF32);
|
||||
out = DecomposeStorageAccess::Intrinsic::DataType::kF32;
|
||||
return true;
|
||||
}
|
||||
if (auto* vec = ty->As<sem::Vector>()) {
|
||||
switch (vec->size()) {
|
||||
case 2:
|
||||
if (vec->type()->Is<sem::I32>()) {
|
||||
return intrinsic(Intrinsic::kLoadVec2I32);
|
||||
out = DecomposeStorageAccess::Intrinsic::DataType::kVec2I32;
|
||||
return true;
|
||||
}
|
||||
if (vec->type()->Is<sem::U32>()) {
|
||||
return intrinsic(Intrinsic::kLoadVec2U32);
|
||||
out = DecomposeStorageAccess::Intrinsic::DataType::kVec2U32;
|
||||
return true;
|
||||
}
|
||||
if (vec->type()->Is<sem::F32>()) {
|
||||
return intrinsic(Intrinsic::kLoadVec2F32);
|
||||
out = DecomposeStorageAccess::Intrinsic::DataType::kVec2F32;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (vec->type()->Is<sem::I32>()) {
|
||||
return intrinsic(Intrinsic::kLoadVec3I32);
|
||||
out = DecomposeStorageAccess::Intrinsic::DataType::kVec3I32;
|
||||
return true;
|
||||
}
|
||||
if (vec->type()->Is<sem::U32>()) {
|
||||
return intrinsic(Intrinsic::kLoadVec3U32);
|
||||
out = DecomposeStorageAccess::Intrinsic::DataType::kVec3U32;
|
||||
return true;
|
||||
}
|
||||
if (vec->type()->Is<sem::F32>()) {
|
||||
return intrinsic(Intrinsic::kLoadVec3F32);
|
||||
out = DecomposeStorageAccess::Intrinsic::DataType::kVec3F32;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (vec->type()->Is<sem::I32>()) {
|
||||
return intrinsic(Intrinsic::kLoadVec4I32);
|
||||
out = DecomposeStorageAccess::Intrinsic::DataType::kVec4I32;
|
||||
return true;
|
||||
}
|
||||
if (vec->type()->Is<sem::U32>()) {
|
||||
return intrinsic(Intrinsic::kLoadVec4U32);
|
||||
out = DecomposeStorageAccess::Intrinsic::DataType::kVec4U32;
|
||||
return true;
|
||||
}
|
||||
if (vec->type()->Is<sem::F32>()) {
|
||||
return intrinsic(Intrinsic::kLoadVec4F32);
|
||||
out = DecomposeStorageAccess::Intrinsic::DataType::kVec4F32;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// @returns a DecomposeStorageAccess::Intrinsic decoration that can be applied
|
||||
/// to a stub function to load the type `ty`.
|
||||
DecomposeStorageAccess::Intrinsic* IntrinsicLoadFor(ProgramBuilder* builder,
|
||||
const sem::Type* ty) {
|
||||
DecomposeStorageAccess::Intrinsic::DataType type;
|
||||
if (!IntrinsicDataTypeFor(ty, type)) {
|
||||
return nullptr;
|
||||
}
|
||||
return builder->ASTNodes().Create<DecomposeStorageAccess::Intrinsic>(
|
||||
builder->ID(), DecomposeStorageAccess::Intrinsic::Op::kLoad, type);
|
||||
}
|
||||
|
||||
/// @returns a DecomposeStorageAccess::Intrinsic decoration that can be applied
|
||||
/// to a stub function to store the type `ty`.
|
||||
DecomposeStorageAccess::Intrinsic* IntrinsicStoreFor(ProgramBuilder* builder,
|
||||
const sem::Type* ty) {
|
||||
using Intrinsic = DecomposeStorageAccess::Intrinsic;
|
||||
DecomposeStorageAccess::Intrinsic::DataType type;
|
||||
if (!IntrinsicDataTypeFor(ty, type)) {
|
||||
return nullptr;
|
||||
}
|
||||
return builder->ASTNodes().Create<DecomposeStorageAccess::Intrinsic>(
|
||||
builder->ID(), DecomposeStorageAccess::Intrinsic::Op::kStore, type);
|
||||
}
|
||||
|
||||
auto intrinsic = [builder](Intrinsic::Type type) {
|
||||
return builder->ASTNodes().Create<Intrinsic>(builder->ID(), type);
|
||||
};
|
||||
/// @returns a DecomposeStorageAccess::Intrinsic decoration that can be applied
|
||||
/// to a stub function for the atomic op and the type `ty`.
|
||||
DecomposeStorageAccess::Intrinsic* IntrinsicAtomicFor(ProgramBuilder* builder,
|
||||
sem::IntrinsicType ity,
|
||||
const sem::Type* ty) {
|
||||
auto op = DecomposeStorageAccess::Intrinsic::Op::kAtomicLoad;
|
||||
switch (ity) {
|
||||
case sem::IntrinsicType::kAtomicLoad:
|
||||
op = DecomposeStorageAccess::Intrinsic::Op::kAtomicLoad;
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicStore:
|
||||
op = DecomposeStorageAccess::Intrinsic::Op::kAtomicStore;
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicAdd:
|
||||
op = DecomposeStorageAccess::Intrinsic::Op::kAtomicAdd;
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicMax:
|
||||
op = DecomposeStorageAccess::Intrinsic::Op::kAtomicMax;
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicMin:
|
||||
op = DecomposeStorageAccess::Intrinsic::Op::kAtomicMin;
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicAnd:
|
||||
op = DecomposeStorageAccess::Intrinsic::Op::kAtomicAnd;
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicOr:
|
||||
op = DecomposeStorageAccess::Intrinsic::Op::kAtomicOr;
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicXor:
|
||||
op = DecomposeStorageAccess::Intrinsic::Op::kAtomicXor;
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicExchange:
|
||||
op = DecomposeStorageAccess::Intrinsic::Op::kAtomicExchange;
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicCompareExchangeWeak:
|
||||
op = DecomposeStorageAccess::Intrinsic::Op::kAtomicCompareExchangeWeak;
|
||||
break;
|
||||
default:
|
||||
TINT_ICE(builder->Diagnostics())
|
||||
<< "invalid IntrinsicType for DecomposeStorageAccess::Intrinsic: "
|
||||
<< ty->type_name();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ty->Is<sem::I32>()) {
|
||||
return intrinsic(Intrinsic::kStoreI32);
|
||||
DecomposeStorageAccess::Intrinsic::DataType type;
|
||||
if (!IntrinsicDataTypeFor(ty, type)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (ty->Is<sem::U32>()) {
|
||||
return intrinsic(Intrinsic::kStoreU32);
|
||||
}
|
||||
if (ty->Is<sem::F32>()) {
|
||||
return intrinsic(Intrinsic::kStoreF32);
|
||||
}
|
||||
if (auto* vec = ty->As<sem::Vector>()) {
|
||||
switch (vec->size()) {
|
||||
case 2:
|
||||
if (vec->type()->Is<sem::I32>()) {
|
||||
return intrinsic(Intrinsic::kStoreVec2U32);
|
||||
}
|
||||
if (vec->type()->Is<sem::U32>()) {
|
||||
return intrinsic(Intrinsic::kStoreVec2F32);
|
||||
}
|
||||
if (vec->type()->Is<sem::F32>()) {
|
||||
return intrinsic(Intrinsic::kStoreVec2I32);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (vec->type()->Is<sem::I32>()) {
|
||||
return intrinsic(Intrinsic::kStoreVec3U32);
|
||||
}
|
||||
if (vec->type()->Is<sem::U32>()) {
|
||||
return intrinsic(Intrinsic::kStoreVec3F32);
|
||||
}
|
||||
if (vec->type()->Is<sem::F32>()) {
|
||||
return intrinsic(Intrinsic::kStoreVec3I32);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (vec->type()->Is<sem::I32>()) {
|
||||
return intrinsic(Intrinsic::kStoreVec4U32);
|
||||
}
|
||||
if (vec->type()->Is<sem::U32>()) {
|
||||
return intrinsic(Intrinsic::kStoreVec4F32);
|
||||
}
|
||||
if (vec->type()->Is<sem::F32>()) {
|
||||
return intrinsic(Intrinsic::kStoreVec4I32);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
return builder->ASTNodes().Create<DecomposeStorageAccess::Intrinsic>(
|
||||
builder->ID(), op, type);
|
||||
}
|
||||
|
||||
/// Inserts `node` before `insert_after` in the global declarations of
|
||||
|
@ -374,9 +414,11 @@ struct DecomposeStorageAccess::State {
|
|||
/// The visited order of AST expressions (superset of #accesses)
|
||||
std::vector<ast::Expression*> expression_order;
|
||||
/// [buffer-type, element-type] -> load function name
|
||||
std::unordered_map<TypePair, Symbol, TypePair::Hasher> load_funcs;
|
||||
std::unordered_map<LoadStoreKey, Symbol, LoadStoreKey::Hasher> load_funcs;
|
||||
/// [buffer-type, element-type] -> store function name
|
||||
std::unordered_map<TypePair, Symbol, TypePair::Hasher> store_funcs;
|
||||
std::unordered_map<LoadStoreKey, Symbol, LoadStoreKey::Hasher> store_funcs;
|
||||
/// [buffer-type, element-type, atomic-op] -> load function name
|
||||
std::unordered_map<AtomicKey, Symbol, AtomicKey::Hasher> atomic_funcs;
|
||||
/// List of storage buffer writes
|
||||
std::vector<Store> stores;
|
||||
|
||||
|
@ -419,7 +461,7 @@ struct DecomposeStorageAccess::State {
|
|||
const sem::Type* buf_ty,
|
||||
const sem::Type* el_ty,
|
||||
const sem::VariableUser* var_user) {
|
||||
return utils::GetOrCreate(load_funcs, TypePair{buf_ty, el_ty}, [&] {
|
||||
return utils::GetOrCreate(load_funcs, LoadStoreKey{buf_ty, el_ty}, [&] {
|
||||
auto* buf_ast_ty = CreateASTTypeFor(&ctx, buf_ty);
|
||||
|
||||
ast::VariableList params = {
|
||||
|
@ -495,7 +537,7 @@ struct DecomposeStorageAccess::State {
|
|||
const sem::Type* buf_ty,
|
||||
const sem::Type* el_ty,
|
||||
const sem::VariableUser* var_user) {
|
||||
return utils::GetOrCreate(store_funcs, TypePair{buf_ty, el_ty}, [&] {
|
||||
return utils::GetOrCreate(store_funcs, LoadStoreKey{buf_ty, el_ty}, [&] {
|
||||
auto* buf_ast_ty = CreateASTTypeFor(&ctx, buf_ty);
|
||||
auto* el_ast_ty = CreateASTTypeFor(&ctx, el_ty);
|
||||
ast::VariableList params{
|
||||
|
@ -560,69 +602,161 @@ struct DecomposeStorageAccess::State {
|
|||
return func->symbol();
|
||||
});
|
||||
}
|
||||
|
||||
/// AtomicFunc() returns a symbol to an intrinsic function that performs an
|
||||
/// atomic operation from a storage buffer of type `buf_ty`. The function has
|
||||
/// the signature:
|
||||
// `fn atomic_op(buf : buf_ty, offset : u32, ...) -> T`
|
||||
/// @param ctx the CloneContext
|
||||
/// @param insert_after the user-declared type to insert the function after
|
||||
/// @param buf_ty the storage buffer type
|
||||
/// @param el_ty the storage buffer element type
|
||||
/// @param intrinsic the atomic intrinsic
|
||||
/// @param var_user the variable user
|
||||
/// @return the name of the function that performs the load
|
||||
Symbol AtomicFunc(CloneContext& ctx,
|
||||
const ast::TypeDecl* insert_after,
|
||||
const sem::Type* buf_ty,
|
||||
const sem::Type* el_ty,
|
||||
const sem::Intrinsic* intrinsic,
|
||||
const sem::VariableUser* var_user) {
|
||||
auto op = intrinsic->Type();
|
||||
return utils::GetOrCreate(atomic_funcs, AtomicKey{buf_ty, el_ty, op}, [&] {
|
||||
auto* buf_ast_ty = CreateASTTypeFor(&ctx, buf_ty);
|
||||
|
||||
// The first parameter to all WGSL atomics is the expression to the
|
||||
// atomic. This is replaced with two parameters: the buffer and offset.
|
||||
|
||||
ast::VariableList params = {
|
||||
// Note: The buffer parameter requires the kStorage StorageClass in
|
||||
// order for HLSL to emit this as a ByteAddressBuffer.
|
||||
ctx.dst->create<ast::Variable>(
|
||||
ctx.dst->Sym("buffer"), ast::StorageClass::kStorage,
|
||||
var_user->Variable()->Access(), buf_ast_ty, true, nullptr,
|
||||
ast::DecorationList{}),
|
||||
ctx.dst->Param("offset", ctx.dst->ty.u32()),
|
||||
};
|
||||
|
||||
// Other parameters are copied as-is:
|
||||
for (size_t i = 1; i < intrinsic->Parameters().size(); i++) {
|
||||
auto& param = intrinsic->Parameters()[i];
|
||||
auto* ty = CreateASTTypeFor(&ctx, param.type);
|
||||
params.emplace_back(ctx.dst->Param("param_" + std::to_string(i), ty));
|
||||
}
|
||||
|
||||
auto* atomic = IntrinsicAtomicFor(ctx.dst, op, el_ty);
|
||||
if (atomic == nullptr) {
|
||||
TINT_ICE(ctx.dst->Diagnostics())
|
||||
<< "IntrinsicAtomicFor() returned nullptr for op " << op
|
||||
<< " and type " << el_ty->type_name();
|
||||
}
|
||||
|
||||
auto* ret_ty = CreateASTTypeFor(&ctx, intrinsic->ReturnType());
|
||||
auto* func = ctx.dst->create<ast::Function>(
|
||||
ctx.dst->Sym(), params, ret_ty, nullptr,
|
||||
ast::DecorationList{
|
||||
atomic,
|
||||
ctx.dst->ASTNodes().Create<ast::DisableValidationDecoration>(
|
||||
ctx.dst->ID(), ast::DisabledValidation::kFunctionHasNoBody),
|
||||
},
|
||||
ast::DecorationList{});
|
||||
|
||||
InsertGlobal(ctx, insert_after, func);
|
||||
return func->symbol();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
DecomposeStorageAccess::Intrinsic::Intrinsic(ProgramID program_id, Type ty)
|
||||
: Base(program_id), type(ty) {}
|
||||
DecomposeStorageAccess::Intrinsic::Intrinsic(ProgramID program_id,
|
||||
Op o,
|
||||
DataType ty)
|
||||
: Base(program_id), op(o), type(ty) {}
|
||||
DecomposeStorageAccess::Intrinsic::~Intrinsic() = default;
|
||||
std::string DecomposeStorageAccess::Intrinsic::InternalName() const {
|
||||
switch (type) {
|
||||
case kLoadU32:
|
||||
return "intrinsic_load_u32";
|
||||
case kLoadF32:
|
||||
return "intrinsic_load_f32";
|
||||
case kLoadI32:
|
||||
return "intrinsic_load_i32";
|
||||
case kLoadVec2U32:
|
||||
return "intrinsic_load_vec2_u32";
|
||||
case kLoadVec2F32:
|
||||
return "intrinsic_load_vec2_f32";
|
||||
case kLoadVec2I32:
|
||||
return "intrinsic_load_vec2_i32";
|
||||
case kLoadVec3U32:
|
||||
return "intrinsic_load_vec3_u32";
|
||||
case kLoadVec3F32:
|
||||
return "intrinsic_load_vec3_f32";
|
||||
case kLoadVec3I32:
|
||||
return "intrinsic_load_vec3_i32";
|
||||
case kLoadVec4U32:
|
||||
return "intrinsic_load_vec4_u32";
|
||||
case kLoadVec4F32:
|
||||
return "intrinsic_load_vec4_f32";
|
||||
case kLoadVec4I32:
|
||||
return "intrinsic_load_vec4_i32";
|
||||
case kStoreU32:
|
||||
return "intrinsic_store_u32";
|
||||
case kStoreF32:
|
||||
return "intrinsic_store_f32";
|
||||
case kStoreI32:
|
||||
return "intrinsic_store_i32";
|
||||
case kStoreVec2U32:
|
||||
return "intrinsic_store_vec2_u32";
|
||||
case kStoreVec2F32:
|
||||
return "intrinsic_store_vec2_f32";
|
||||
case kStoreVec2I32:
|
||||
return "intrinsic_store_vec2_i32";
|
||||
case kStoreVec3U32:
|
||||
return "intrinsic_store_vec3_u32";
|
||||
case kStoreVec3F32:
|
||||
return "intrinsic_store_vec3_f32";
|
||||
case kStoreVec3I32:
|
||||
return "intrinsic_store_vec3_i32";
|
||||
case kStoreVec4U32:
|
||||
return "intrinsic_store_vec4_u32";
|
||||
case kStoreVec4F32:
|
||||
return "intrinsic_store_vec4_f32";
|
||||
case kStoreVec4I32:
|
||||
return "intrinsic_store_vec4_i32";
|
||||
std::stringstream ss;
|
||||
switch (op) {
|
||||
case Op::kLoad:
|
||||
ss << "intrinsic_load_";
|
||||
break;
|
||||
case Op::kStore:
|
||||
ss << "intrinsic_store_";
|
||||
break;
|
||||
case Op::kAtomicLoad:
|
||||
ss << "intrinsic_atomic_load_";
|
||||
break;
|
||||
case Op::kAtomicStore:
|
||||
ss << "intrinsic_atomic_store_";
|
||||
break;
|
||||
case Op::kAtomicAdd:
|
||||
ss << "intrinsic_atomic_add_";
|
||||
break;
|
||||
case Op::kAtomicMax:
|
||||
ss << "intrinsic_atomic_max_";
|
||||
break;
|
||||
case Op::kAtomicMin:
|
||||
ss << "intrinsic_atomic_min_";
|
||||
break;
|
||||
case Op::kAtomicAnd:
|
||||
ss << "intrinsic_atomic_and_";
|
||||
break;
|
||||
case Op::kAtomicOr:
|
||||
ss << "intrinsic_atomic_or_";
|
||||
break;
|
||||
case Op::kAtomicXor:
|
||||
ss << "intrinsic_atomic_xor_";
|
||||
break;
|
||||
case Op::kAtomicExchange:
|
||||
ss << "intrinsic_atomic_exchange_";
|
||||
break;
|
||||
case Op::kAtomicCompareExchangeWeak:
|
||||
ss << "intrinsic_atomic_compare_exchange_weak_";
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
switch (type) {
|
||||
case DataType::kU32:
|
||||
ss << "u32";
|
||||
break;
|
||||
case DataType::kF32:
|
||||
ss << "f32";
|
||||
break;
|
||||
case DataType::kI32:
|
||||
ss << "i32";
|
||||
break;
|
||||
case DataType::kVec2U32:
|
||||
ss << "vec2_u32";
|
||||
break;
|
||||
case DataType::kVec2F32:
|
||||
ss << "vec2_f32";
|
||||
break;
|
||||
case DataType::kVec2I32:
|
||||
ss << "vec2_i32";
|
||||
break;
|
||||
case DataType::kVec3U32:
|
||||
ss << "vec3_u32";
|
||||
break;
|
||||
case DataType::kVec3F32:
|
||||
ss << "vec3_f32";
|
||||
break;
|
||||
case DataType::kVec3I32:
|
||||
ss << "vec3_i32";
|
||||
break;
|
||||
case DataType::kVec4U32:
|
||||
ss << "vec4_u32";
|
||||
break;
|
||||
case DataType::kVec4F32:
|
||||
ss << "vec4_f32";
|
||||
break;
|
||||
case DataType::kVec4I32:
|
||||
ss << "vec4_i32";
|
||||
break;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
DecomposeStorageAccess::Intrinsic* DecomposeStorageAccess::Intrinsic::Clone(
|
||||
CloneContext* ctx) const {
|
||||
return ctx->dst->ASTNodes().Create<DecomposeStorageAccess::Intrinsic>(
|
||||
ctx->dst->ID(), type);
|
||||
ctx->dst->ID(), op, type);
|
||||
}
|
||||
|
||||
DecomposeStorageAccess::DecomposeStorageAccess() = default;
|
||||
|
@ -728,6 +862,18 @@ Output DecomposeStorageAccess::Run(const Program* in, const DataMap&) {
|
|||
}
|
||||
}
|
||||
|
||||
if (auto* op = node->As<ast::UnaryOpExpression>()) {
|
||||
if (op->op() == ast::UnaryOp::kAddressOf) {
|
||||
// &X
|
||||
if (auto access = state.TakeAccess(op->expr())) {
|
||||
// HLSL does not support pointers, so just take the access from the
|
||||
// reference and place it on the pointer.
|
||||
state.AddAccess(op, std::move(access));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto* assign = node->As<ast::AssignmentStatement>()) {
|
||||
// X = Y
|
||||
// Move the LHS access to a store.
|
||||
|
@ -741,16 +887,31 @@ Output DecomposeStorageAccess::Run(const Program* in, const DataMap&) {
|
|||
if (auto* intrinsic = call->Target()->As<sem::Intrinsic>()) {
|
||||
if (intrinsic->Type() == sem::IntrinsicType::kArrayLength) {
|
||||
// arrayLength(X)
|
||||
// Don't convert X into a load, this actually requires the real
|
||||
// reference.
|
||||
auto* arg = call_expr->params()[0];
|
||||
// Don't convert X into a load, this intrinsic actually requires the
|
||||
// real pointer.
|
||||
state.TakeAccess(call_expr->params()[0]);
|
||||
}
|
||||
if (intrinsic->IsAtomic()) {
|
||||
if (auto access = state.TakeAccess(call_expr->params()[0])) {
|
||||
// atomic___(X)
|
||||
|
||||
// TODO(crbug.com/tint/806): Once the deprecated arrayLength()
|
||||
// overload is removed, this can safely assume a pointer arg.
|
||||
if (auto* address_of = arg->As<ast::UnaryOpExpression>()) {
|
||||
arg = address_of->expr();
|
||||
auto* buf = access.var->Declaration();
|
||||
auto* offset = access.offset->Build(ctx);
|
||||
auto* buf_ty = access.var->Type()->UnwrapRef();
|
||||
auto* el_ty = access.type->UnwrapRef()->As<sem::Atomic>()->Type();
|
||||
auto* insert_after = TypeDeclOf(access.var->Type());
|
||||
Symbol func =
|
||||
state.AtomicFunc(ctx, insert_after, buf_ty, el_ty, intrinsic,
|
||||
access.var->As<sem::VariableUser>());
|
||||
|
||||
ast::ExpressionList args{ctx.Clone(buf), offset};
|
||||
for (size_t i = 1; i < call_expr->params().size(); i++) {
|
||||
auto* arg = call_expr->params()[i];
|
||||
args.emplace_back(ctx.Clone(arg));
|
||||
}
|
||||
|
||||
ctx.Replace(call_expr, ctx.dst->Call(func, args));
|
||||
}
|
||||
state.TakeAccess(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,8 @@ class CloneContext;
|
|||
namespace transform {
|
||||
|
||||
/// DecomposeStorageAccess is a transform used to replace storage buffer
|
||||
/// accesses with a combination of load / store functions on primitive types.
|
||||
/// accesses with a combination of load, store or atomic functions on primitive
|
||||
/// types.
|
||||
class DecomposeStorageAccess : public Transform {
|
||||
public:
|
||||
/// Intrinsic is an InternalDecoration that's used to decorate a stub function
|
||||
|
@ -37,38 +38,43 @@ class DecomposeStorageAccess : public Transform {
|
|||
/// with a possible cast.
|
||||
class Intrinsic : public Castable<Intrinsic, ast::InternalDecoration> {
|
||||
public:
|
||||
/// Storage access intrinsic type
|
||||
enum Type {
|
||||
kLoadU32, // `[RW]ByteAddressBuffer.Load()`
|
||||
kLoadF32, // `asfloat([RW]ByteAddressBuffer.Load())`
|
||||
kLoadI32, // `asint([RW]ByteAddressBuffer.Load())`
|
||||
kLoadVec2U32, // `[RW]ByteAddressBuffer.Load2()`
|
||||
kLoadVec2F32, // `asfloat([RW]ByteAddressBuffer.Load2())`
|
||||
kLoadVec2I32, // `asint([RW]ByteAddressBuffer.Load2())`
|
||||
kLoadVec3U32, // `[RW]ByteAddressBuffer.Load3()`
|
||||
kLoadVec3F32, // `asfloat([RW]ByteAddressBuffer.Load3())`
|
||||
kLoadVec3I32, // `asint([RW]ByteAddressBuffer.Load3())`
|
||||
kLoadVec4U32, // `[RW]ByteAddressBuffer.Load4()`
|
||||
kLoadVec4F32, // `asfloat([RW]ByteAddressBuffer.Load4())`
|
||||
kLoadVec4I32, // `asint([RW]ByteAddressBuffer.Load4())`
|
||||
kStoreU32, // `RWByteAddressBuffer.Store()`
|
||||
kStoreF32, // `asfloat(RWByteAddressBuffer.Store())`
|
||||
kStoreI32, // `asint(RWByteAddressBuffer.Store())`
|
||||
kStoreVec2U32, // `RWByteAddressBuffer.Store2()`
|
||||
kStoreVec2F32, // `asfloat(RWByteAddressBuffer.Store2())`
|
||||
kStoreVec2I32, // `asint(RWByteAddressBuffer.Store2())`
|
||||
kStoreVec3U32, // `RWByteAddressBuffer.Store3()`
|
||||
kStoreVec3F32, // `asfloat(RWByteAddressBuffer.Store3())`
|
||||
kStoreVec3I32, // `asint(RWByteAddressBuffer.Store3())`
|
||||
kStoreVec4U32, // `RWByteAddressBuffer.Store4()`
|
||||
kStoreVec4F32, // `asfloat(RWByteAddressBuffer.Store4())`
|
||||
kStoreVec4I32, // `asint(RWByteAddressBuffer.Store4())`
|
||||
/// Intrinsic op
|
||||
enum class Op {
|
||||
kLoad,
|
||||
kStore,
|
||||
kAtomicLoad,
|
||||
kAtomicStore,
|
||||
kAtomicAdd,
|
||||
kAtomicMax,
|
||||
kAtomicMin,
|
||||
kAtomicAnd,
|
||||
kAtomicOr,
|
||||
kAtomicXor,
|
||||
kAtomicExchange,
|
||||
kAtomicCompareExchangeWeak,
|
||||
};
|
||||
|
||||
/// Intrinsic data type
|
||||
enum class DataType {
|
||||
kU32,
|
||||
kF32,
|
||||
kI32,
|
||||
kVec2U32,
|
||||
kVec2F32,
|
||||
kVec2I32,
|
||||
kVec3U32,
|
||||
kVec3F32,
|
||||
kVec3I32,
|
||||
kVec4U32,
|
||||
kVec4F32,
|
||||
kVec4I32,
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
/// @param program_id the identifier of the program that owns this node
|
||||
/// @param ty the type of the intrinsic
|
||||
Intrinsic(ProgramID program_id, Type ty);
|
||||
/// @param o the op of the intrinsic
|
||||
/// @param ty the data type of the intrinsic
|
||||
Intrinsic(ProgramID program_id, Op o, DataType ty);
|
||||
/// Destructor
|
||||
~Intrinsic() override;
|
||||
|
||||
|
@ -81,8 +87,11 @@ class DecomposeStorageAccess : public Transform {
|
|||
/// @return the newly cloned object
|
||||
Intrinsic* Clone(CloneContext* ctx) const override;
|
||||
|
||||
/// The op of the intrinsic
|
||||
Op const op;
|
||||
|
||||
/// The type of the intrinsic
|
||||
Type const type;
|
||||
DataType const type;
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
|
|
|
@ -309,31 +309,31 @@ fn tint_symbol_1(buffer : SB, offset : u32, value : u32)
|
|||
[[internal(intrinsic_store_f32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_2(buffer : SB, offset : u32, value : f32)
|
||||
|
||||
[[internal(intrinsic_store_vec2_u32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec2_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_3(buffer : SB, offset : u32, value : vec2<i32>)
|
||||
|
||||
[[internal(intrinsic_store_vec2_f32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec2_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_4(buffer : SB, offset : u32, value : vec2<u32>)
|
||||
|
||||
[[internal(intrinsic_store_vec2_i32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec2_f32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_5(buffer : SB, offset : u32, value : vec2<f32>)
|
||||
|
||||
[[internal(intrinsic_store_vec3_u32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec3_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_6(buffer : SB, offset : u32, value : vec3<i32>)
|
||||
|
||||
[[internal(intrinsic_store_vec3_f32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec3_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_7(buffer : SB, offset : u32, value : vec3<u32>)
|
||||
|
||||
[[internal(intrinsic_store_vec3_i32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec3_f32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_8(buffer : SB, offset : u32, value : vec3<f32>)
|
||||
|
||||
[[internal(intrinsic_store_vec4_u32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec4_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_9(buffer : SB, offset : u32, value : vec4<i32>)
|
||||
|
||||
[[internal(intrinsic_store_vec4_f32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec4_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_10(buffer : SB, offset : u32, value : vec4<u32>)
|
||||
|
||||
[[internal(intrinsic_store_vec4_i32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec4_f32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_11(buffer : SB, offset : u32, value : vec4<f32>)
|
||||
|
||||
fn tint_symbol_12(buffer : SB, offset : u32, value : mat2x2<f32>) {
|
||||
|
@ -657,31 +657,31 @@ fn tint_symbol_1(buffer : SB, offset : u32, value : u32)
|
|||
[[internal(intrinsic_store_f32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_2(buffer : SB, offset : u32, value : f32)
|
||||
|
||||
[[internal(intrinsic_store_vec2_u32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec2_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_3(buffer : SB, offset : u32, value : vec2<i32>)
|
||||
|
||||
[[internal(intrinsic_store_vec2_f32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec2_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_4(buffer : SB, offset : u32, value : vec2<u32>)
|
||||
|
||||
[[internal(intrinsic_store_vec2_i32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec2_f32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_5(buffer : SB, offset : u32, value : vec2<f32>)
|
||||
|
||||
[[internal(intrinsic_store_vec3_u32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec3_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_6(buffer : SB, offset : u32, value : vec3<i32>)
|
||||
|
||||
[[internal(intrinsic_store_vec3_f32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec3_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_7(buffer : SB, offset : u32, value : vec3<u32>)
|
||||
|
||||
[[internal(intrinsic_store_vec3_i32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec3_f32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_8(buffer : SB, offset : u32, value : vec3<f32>)
|
||||
|
||||
[[internal(intrinsic_store_vec4_u32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec4_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_9(buffer : SB, offset : u32, value : vec4<i32>)
|
||||
|
||||
[[internal(intrinsic_store_vec4_f32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec4_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_10(buffer : SB, offset : u32, value : vec4<u32>)
|
||||
|
||||
[[internal(intrinsic_store_vec4_i32), internal(disable_validation__function_has_no_body)]]
|
||||
[[internal(intrinsic_store_vec4_f32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_11(buffer : SB, offset : u32, value : vec4<f32>)
|
||||
|
||||
fn tint_symbol_12(buffer : SB, offset : u32, value : mat2x2<f32>) {
|
||||
|
@ -1011,6 +1011,185 @@ fn main() {
|
|||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(DecomposeStorageAccessTest, StorageBufferAtomics) {
|
||||
auto* src = R"(
|
||||
[[block]]
|
||||
struct SB {
|
||||
padding : vec4<f32>;
|
||||
a : atomic<i32>;
|
||||
b : atomic<u32>;
|
||||
};
|
||||
|
||||
[[group(0), binding(0)]] var<storage, read_write> sb : SB;
|
||||
|
||||
[[stage(compute)]]
|
||||
fn main() {
|
||||
atomicStore(&sb.a, 123);
|
||||
ignore(atomicLoad(&sb.a));
|
||||
ignore(atomicAdd(&sb.a, 123));
|
||||
ignore(atomicMax(&sb.a, 123));
|
||||
ignore(atomicMin(&sb.a, 123));
|
||||
ignore(atomicAnd(&sb.a, 123));
|
||||
ignore(atomicOr(&sb.a, 123));
|
||||
ignore(atomicXor(&sb.a, 123));
|
||||
ignore(atomicExchange(&sb.a, 123));
|
||||
ignore(atomicCompareExchangeWeak(&sb.a, 123, 345));
|
||||
|
||||
atomicStore(&sb.b, 123u);
|
||||
ignore(atomicLoad(&sb.b));
|
||||
ignore(atomicAdd(&sb.b, 123u));
|
||||
ignore(atomicMax(&sb.b, 123u));
|
||||
ignore(atomicMin(&sb.b, 123u));
|
||||
ignore(atomicAnd(&sb.b, 123u));
|
||||
ignore(atomicOr(&sb.b, 123u));
|
||||
ignore(atomicXor(&sb.b, 123u));
|
||||
ignore(atomicExchange(&sb.b, 123u));
|
||||
ignore(atomicCompareExchangeWeak(&sb.b, 123u, 345u));
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
[[block]]
|
||||
struct SB {
|
||||
padding : vec4<f32>;
|
||||
a : atomic<i32>;
|
||||
b : atomic<u32>;
|
||||
};
|
||||
|
||||
[[internal(intrinsic_atomic_store_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol(buffer : SB, offset : u32, param_1 : i32)
|
||||
|
||||
[[internal(intrinsic_atomic_load_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_1(buffer : SB, offset : u32) -> i32
|
||||
|
||||
[[internal(intrinsic_atomic_add_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_2(buffer : SB, offset : u32, param_1 : i32) -> i32
|
||||
|
||||
[[internal(intrinsic_atomic_max_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_3(buffer : SB, offset : u32, param_1 : i32) -> i32
|
||||
|
||||
[[internal(intrinsic_atomic_min_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_4(buffer : SB, offset : u32, param_1 : i32) -> i32
|
||||
|
||||
[[internal(intrinsic_atomic_and_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_5(buffer : SB, offset : u32, param_1 : i32) -> i32
|
||||
|
||||
[[internal(intrinsic_atomic_or_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_6(buffer : SB, offset : u32, param_1 : i32) -> i32
|
||||
|
||||
[[internal(intrinsic_atomic_xor_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_7(buffer : SB, offset : u32, param_1 : i32) -> i32
|
||||
|
||||
[[internal(intrinsic_atomic_exchange_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_8(buffer : SB, offset : u32, param_1 : i32) -> i32
|
||||
|
||||
[[internal(intrinsic_atomic_compare_exchange_weak_i32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_9(buffer : SB, offset : u32, param_1 : i32, param_2 : i32) -> vec2<i32>
|
||||
|
||||
[[internal(intrinsic_atomic_store_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_10(buffer : SB, offset : u32, param_1 : u32)
|
||||
|
||||
[[internal(intrinsic_atomic_load_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_11(buffer : SB, offset : u32) -> u32
|
||||
|
||||
[[internal(intrinsic_atomic_add_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_12(buffer : SB, offset : u32, param_1 : u32) -> u32
|
||||
|
||||
[[internal(intrinsic_atomic_max_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_13(buffer : SB, offset : u32, param_1 : u32) -> u32
|
||||
|
||||
[[internal(intrinsic_atomic_min_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_14(buffer : SB, offset : u32, param_1 : u32) -> u32
|
||||
|
||||
[[internal(intrinsic_atomic_and_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_15(buffer : SB, offset : u32, param_1 : u32) -> u32
|
||||
|
||||
[[internal(intrinsic_atomic_or_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_16(buffer : SB, offset : u32, param_1 : u32) -> u32
|
||||
|
||||
[[internal(intrinsic_atomic_xor_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_17(buffer : SB, offset : u32, param_1 : u32) -> u32
|
||||
|
||||
[[internal(intrinsic_atomic_exchange_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_18(buffer : SB, offset : u32, param_1 : u32) -> u32
|
||||
|
||||
[[internal(intrinsic_atomic_compare_exchange_weak_u32), internal(disable_validation__function_has_no_body)]]
|
||||
fn tint_symbol_19(buffer : SB, offset : u32, param_1 : u32, param_2 : u32) -> vec2<u32>
|
||||
|
||||
[[group(0), binding(0)]] var<storage, read_write> sb : SB;
|
||||
|
||||
[[stage(compute)]]
|
||||
fn main() {
|
||||
tint_symbol(sb, 16u, 123);
|
||||
ignore(tint_symbol_1(sb, 16u));
|
||||
ignore(tint_symbol_2(sb, 16u, 123));
|
||||
ignore(tint_symbol_3(sb, 16u, 123));
|
||||
ignore(tint_symbol_4(sb, 16u, 123));
|
||||
ignore(tint_symbol_5(sb, 16u, 123));
|
||||
ignore(tint_symbol_6(sb, 16u, 123));
|
||||
ignore(tint_symbol_7(sb, 16u, 123));
|
||||
ignore(tint_symbol_8(sb, 16u, 123));
|
||||
ignore(tint_symbol_9(sb, 16u, 123, 345));
|
||||
tint_symbol_10(sb, 20u, 123u);
|
||||
ignore(tint_symbol_11(sb, 20u));
|
||||
ignore(tint_symbol_12(sb, 20u, 123u));
|
||||
ignore(tint_symbol_13(sb, 20u, 123u));
|
||||
ignore(tint_symbol_14(sb, 20u, 123u));
|
||||
ignore(tint_symbol_15(sb, 20u, 123u));
|
||||
ignore(tint_symbol_16(sb, 20u, 123u));
|
||||
ignore(tint_symbol_17(sb, 20u, 123u));
|
||||
ignore(tint_symbol_18(sb, 20u, 123u));
|
||||
ignore(tint_symbol_19(sb, 20u, 123u, 345u));
|
||||
}
|
||||
)";
|
||||
|
||||
auto got = Run<DecomposeStorageAccess>(src);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(DecomposeStorageAccessTest, WorkgroupBufferAtomics) {
|
||||
auto* src = R"(
|
||||
struct S {
|
||||
padding : vec4<f32>;
|
||||
a : atomic<i32>;
|
||||
b : atomic<u32>;
|
||||
};
|
||||
|
||||
var<workgroup> w : S;
|
||||
|
||||
[[stage(compute)]]
|
||||
fn main() {
|
||||
atomicStore(&(w.a), 123);
|
||||
ignore(atomicLoad(&(w.a)));
|
||||
ignore(atomicAdd(&(w.a), 123));
|
||||
ignore(atomicMax(&(w.a), 123));
|
||||
ignore(atomicMin(&(w.a), 123));
|
||||
ignore(atomicAnd(&(w.a), 123));
|
||||
ignore(atomicOr(&(w.a), 123));
|
||||
ignore(atomicXor(&(w.a), 123));
|
||||
ignore(atomicExchange(&(w.a), 123));
|
||||
ignore(atomicCompareExchangeWeak(&(w.a), 123, 345));
|
||||
atomicStore(&(w.b), 123u);
|
||||
ignore(atomicLoad(&(w.b)));
|
||||
ignore(atomicAdd(&(w.b), 123u));
|
||||
ignore(atomicMax(&(w.b), 123u));
|
||||
ignore(atomicMin(&(w.b), 123u));
|
||||
ignore(atomicAnd(&(w.b), 123u));
|
||||
ignore(atomicOr(&(w.b), 123u));
|
||||
ignore(atomicXor(&(w.b), 123u));
|
||||
ignore(atomicExchange(&(w.b), 123u));
|
||||
ignore(atomicCompareExchangeWeak(&(w.b), 123u, 345u));
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = src;
|
||||
|
||||
auto got = Run<DecomposeStorageAccess>(src);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace transform
|
||||
} // namespace tint
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include "src/program_builder.h"
|
||||
#include "src/sem/atomic_type.h"
|
||||
#include "src/sem/reference_type.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::Data);
|
||||
|
@ -111,6 +112,9 @@ ast::Type* Transform::CreateASTTypeFor(CloneContext* ctx, const sem::Type* ty) {
|
|||
if (auto* s = ty->As<sem::Reference>()) {
|
||||
return CreateASTTypeFor(ctx, s->StoreType());
|
||||
}
|
||||
if (auto* a = ty->As<sem::Atomic>()) {
|
||||
return ctx->dst->create<ast::Atomic>(CreateASTTypeFor(ctx, a->Type()));
|
||||
}
|
||||
if (auto* t = ty->As<sem::DepthTexture>()) {
|
||||
return ctx->dst->create<ast::DepthTexture>(t->dim());
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "src/ast/override_decoration.h"
|
||||
#include "src/ast/variable_decl_statement.h"
|
||||
#include "src/sem/array.h"
|
||||
#include "src/sem/atomic_type.h"
|
||||
#include "src/sem/call.h"
|
||||
#include "src/sem/depth_texture_type.h"
|
||||
#include "src/sem/function.h"
|
||||
|
@ -35,7 +36,6 @@
|
|||
#include "src/sem/struct.h"
|
||||
#include "src/sem/variable.h"
|
||||
#include "src/transform/calculate_array_length.h"
|
||||
#include "src/transform/decompose_storage_access.h"
|
||||
#include "src/utils/scoped_assignment.h"
|
||||
#include "src/writer/append_vector.h"
|
||||
#include "src/writer/float_to_string.h"
|
||||
|
@ -431,99 +431,7 @@ bool GeneratorImpl::EmitCall(std::ostream& pre,
|
|||
if (auto* intrinsic =
|
||||
ast::GetDecoration<transform::DecomposeStorageAccess::Intrinsic>(
|
||||
func->Declaration()->decorations())) {
|
||||
auto load = [&](const char* cast, int n) {
|
||||
if (cast) {
|
||||
out << cast << "(";
|
||||
}
|
||||
if (!EmitExpression(pre, out, params[0])) { // buffer
|
||||
return false;
|
||||
}
|
||||
out << ".Load";
|
||||
if (n > 1) {
|
||||
out << n;
|
||||
}
|
||||
ScopedParen sp(out);
|
||||
if (!EmitExpression(pre, out, params[1])) { // offset
|
||||
return false;
|
||||
}
|
||||
if (cast) {
|
||||
out << ")";
|
||||
}
|
||||
return true;
|
||||
};
|
||||
auto store = [&](int n) {
|
||||
if (!EmitExpression(pre, out, params[0])) { // buffer
|
||||
return false;
|
||||
}
|
||||
out << ".Store";
|
||||
if (n > 1) {
|
||||
out << n;
|
||||
}
|
||||
ScopedParen sp1(out);
|
||||
if (!EmitExpression(pre, out, params[1])) { // offset
|
||||
return false;
|
||||
}
|
||||
out << ", asuint";
|
||||
ScopedParen sp2(out);
|
||||
if (!EmitExpression(pre, out, params[2])) { // value
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
switch (intrinsic->type) {
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kLoadU32:
|
||||
return load(nullptr, 1);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kLoadF32:
|
||||
return load("asfloat", 1);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kLoadI32:
|
||||
return load("asint", 1);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kLoadVec2U32:
|
||||
return load(nullptr, 2);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kLoadVec2F32:
|
||||
return load("asfloat", 2);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kLoadVec2I32:
|
||||
return load("asint", 2);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kLoadVec3U32:
|
||||
return load(nullptr, 3);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kLoadVec3F32:
|
||||
return load("asfloat", 3);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kLoadVec3I32:
|
||||
return load("asint", 3);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kLoadVec4U32:
|
||||
return load(nullptr, 4);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kLoadVec4F32:
|
||||
return load("asfloat", 4);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kLoadVec4I32:
|
||||
return load("asint", 4);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kStoreU32:
|
||||
return store(1);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kStoreF32:
|
||||
return store(1);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kStoreI32:
|
||||
return store(1);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kStoreVec2U32:
|
||||
return store(2);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kStoreVec2F32:
|
||||
return store(2);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kStoreVec2I32:
|
||||
return store(2);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kStoreVec3U32:
|
||||
return store(3);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kStoreVec3F32:
|
||||
return store(3);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kStoreVec3I32:
|
||||
return store(3);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kStoreVec4U32:
|
||||
return store(4);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kStoreVec4F32:
|
||||
return store(4);
|
||||
case transform::DecomposeStorageAccess::Intrinsic::kStoreVec4I32:
|
||||
return store(4);
|
||||
}
|
||||
|
||||
TINT_UNIMPLEMENTED(diagnostics_) << static_cast<int>(intrinsic->type);
|
||||
return false;
|
||||
return EmitDecomposeStorageAccessIntrinsic(pre, out, expr, intrinsic);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -544,6 +452,8 @@ bool GeneratorImpl::EmitCall(std::ostream& pre,
|
|||
return EmitDataUnpackingCall(pre, out, expr, intrinsic);
|
||||
} else if (intrinsic->IsBarrier()) {
|
||||
return EmitBarrierCall(pre, out, intrinsic);
|
||||
} else if (intrinsic->IsAtomic()) {
|
||||
return EmitWorkgroupAtomicCall(pre, out, expr, intrinsic);
|
||||
}
|
||||
auto name = generate_builtin_name(intrinsic);
|
||||
if (name.empty()) {
|
||||
|
@ -597,6 +507,486 @@ bool GeneratorImpl::EmitCall(std::ostream& pre,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitDecomposeStorageAccessIntrinsic(
|
||||
std::ostream& pre,
|
||||
std::ostream& out,
|
||||
ast::CallExpression* expr,
|
||||
const transform::DecomposeStorageAccess::Intrinsic* intrinsic) {
|
||||
const auto& params = expr->params();
|
||||
|
||||
using Op = transform::DecomposeStorageAccess::Intrinsic::Op;
|
||||
using DataType = transform::DecomposeStorageAccess::Intrinsic::DataType;
|
||||
switch (intrinsic->op) {
|
||||
case Op::kLoad: {
|
||||
auto load = [&](const char* cast, int n) {
|
||||
if (cast) {
|
||||
out << cast << "(";
|
||||
}
|
||||
if (!EmitExpression(pre, out, params[0])) { // buffer
|
||||
return false;
|
||||
}
|
||||
out << ".Load";
|
||||
if (n > 1) {
|
||||
out << n;
|
||||
}
|
||||
ScopedParen sp(out);
|
||||
if (!EmitExpression(pre, out, params[1])) { // offset
|
||||
return false;
|
||||
}
|
||||
if (cast) {
|
||||
out << ")";
|
||||
}
|
||||
return true;
|
||||
};
|
||||
switch (intrinsic->type) {
|
||||
case DataType::kU32:
|
||||
return load(nullptr, 1);
|
||||
case DataType::kF32:
|
||||
return load("asfloat", 1);
|
||||
case DataType::kI32:
|
||||
return load("asint", 1);
|
||||
case DataType::kVec2U32:
|
||||
return load(nullptr, 2);
|
||||
case DataType::kVec2F32:
|
||||
return load("asfloat", 2);
|
||||
case DataType::kVec2I32:
|
||||
return load("asint", 2);
|
||||
case DataType::kVec3U32:
|
||||
return load(nullptr, 3);
|
||||
case DataType::kVec3F32:
|
||||
return load("asfloat", 3);
|
||||
case DataType::kVec3I32:
|
||||
return load("asint", 3);
|
||||
case DataType::kVec4U32:
|
||||
return load(nullptr, 4);
|
||||
case DataType::kVec4F32:
|
||||
return load("asfloat", 4);
|
||||
case DataType::kVec4I32:
|
||||
return load("asint", 4);
|
||||
}
|
||||
TINT_UNREACHABLE(diagnostics_)
|
||||
<< "unsupported DecomposeStorageAccess::Intrinsic::DataType: "
|
||||
<< static_cast<int>(intrinsic->type);
|
||||
return false;
|
||||
}
|
||||
|
||||
case Op::kStore: {
|
||||
auto store = [&](int n) {
|
||||
if (!EmitExpression(pre, out, params[0])) { // buffer
|
||||
return false;
|
||||
}
|
||||
out << ".Store";
|
||||
if (n > 1) {
|
||||
out << n;
|
||||
}
|
||||
ScopedParen sp1(out);
|
||||
if (!EmitExpression(pre, out, params[1])) { // offset
|
||||
return false;
|
||||
}
|
||||
out << ", asuint";
|
||||
ScopedParen sp2(out);
|
||||
if (!EmitExpression(pre, out, params[2])) { // value
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
switch (intrinsic->type) {
|
||||
case DataType::kU32:
|
||||
return store(1);
|
||||
case DataType::kF32:
|
||||
return store(1);
|
||||
case DataType::kI32:
|
||||
return store(1);
|
||||
case DataType::kVec2U32:
|
||||
return store(2);
|
||||
case DataType::kVec2F32:
|
||||
return store(2);
|
||||
case DataType::kVec2I32:
|
||||
return store(2);
|
||||
case DataType::kVec3U32:
|
||||
return store(3);
|
||||
case DataType::kVec3F32:
|
||||
return store(3);
|
||||
case DataType::kVec3I32:
|
||||
return store(3);
|
||||
case DataType::kVec4U32:
|
||||
return store(4);
|
||||
case DataType::kVec4F32:
|
||||
return store(4);
|
||||
case DataType::kVec4I32:
|
||||
return store(4);
|
||||
}
|
||||
TINT_UNREACHABLE(diagnostics_)
|
||||
<< "unsupported DecomposeStorageAccess::Intrinsic::DataType: "
|
||||
<< static_cast<int>(intrinsic->type);
|
||||
return false;
|
||||
}
|
||||
|
||||
case Op::kAtomicLoad:
|
||||
case Op::kAtomicStore:
|
||||
case Op::kAtomicAdd:
|
||||
case Op::kAtomicMax:
|
||||
case Op::kAtomicMin:
|
||||
case Op::kAtomicAnd:
|
||||
case Op::kAtomicOr:
|
||||
case Op::kAtomicXor:
|
||||
case Op::kAtomicExchange:
|
||||
case Op::kAtomicCompareExchangeWeak:
|
||||
return EmitStorageAtomicCall(pre, out, expr, intrinsic->op);
|
||||
}
|
||||
|
||||
TINT_UNREACHABLE(diagnostics_)
|
||||
<< "unsupported DecomposeStorageAccess::Intrinsic::Op: "
|
||||
<< static_cast<int>(intrinsic->op);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitStorageAtomicCall(
|
||||
std::ostream& pre,
|
||||
std::ostream& out,
|
||||
ast::CallExpression* expr,
|
||||
transform::DecomposeStorageAccess::Intrinsic::Op op) {
|
||||
using Op = transform::DecomposeStorageAccess::Intrinsic::Op;
|
||||
|
||||
std::stringstream ss;
|
||||
std::string result = generate_name("atomic_result");
|
||||
|
||||
auto* result_ty = TypeOf(expr);
|
||||
if (!result_ty->Is<sem::Void>()) {
|
||||
if (!EmitType(ss, TypeOf(expr), ast::StorageClass::kNone,
|
||||
ast::Access::kUndefined, "")) {
|
||||
return false;
|
||||
}
|
||||
ss << " " << result << " = ";
|
||||
if (!EmitZeroValue(ss, result_ty)) {
|
||||
return false;
|
||||
}
|
||||
make_indent(ss << ";" << std::endl);
|
||||
}
|
||||
|
||||
auto* buffer = expr->params()[0];
|
||||
auto* offset = expr->params()[1];
|
||||
|
||||
switch (op) {
|
||||
case Op::kAtomicLoad: {
|
||||
// HLSL does not have an InterlockedLoad, so we emulate it with
|
||||
// InterlockedOr using 0 as the OR value
|
||||
if (!EmitExpression(pre, ss, buffer)) {
|
||||
return false;
|
||||
}
|
||||
ss << ".InterlockedOr";
|
||||
{
|
||||
ScopedParen sp(ss);
|
||||
if (!EmitExpression(pre, ss, offset)) {
|
||||
return false;
|
||||
}
|
||||
ss << ", 0, " << result;
|
||||
}
|
||||
|
||||
make_indent(ss << ";" << std::endl);
|
||||
pre << ss.str();
|
||||
out << result;
|
||||
return true;
|
||||
}
|
||||
case Op::kAtomicStore: {
|
||||
// HLSL does not have an InterlockedStore, so we emulate it with
|
||||
// InterlockedExchange and discard the returned value
|
||||
auto* value = expr->params()[2];
|
||||
auto* value_ty = TypeOf(value);
|
||||
if (!EmitType(pre, value_ty, ast::StorageClass::kNone,
|
||||
ast::Access::kUndefined, "")) {
|
||||
return false;
|
||||
}
|
||||
pre << " " << result << " = ";
|
||||
if (!EmitZeroValue(pre, value_ty)) {
|
||||
return false;
|
||||
}
|
||||
make_indent(pre << ";" << std::endl);
|
||||
|
||||
if (!EmitExpression(pre, out, buffer)) {
|
||||
return false;
|
||||
}
|
||||
out << ".InterlockedExchange";
|
||||
{
|
||||
ScopedParen sp(out);
|
||||
if (!EmitExpression(pre, out, offset)) {
|
||||
return false;
|
||||
}
|
||||
out << ", ";
|
||||
if (!EmitExpression(pre, out, value)) {
|
||||
return false;
|
||||
}
|
||||
out << ", " << result;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Op::kAtomicCompareExchangeWeak: {
|
||||
auto* compare_value = expr->params()[2];
|
||||
auto* value = expr->params()[3];
|
||||
|
||||
std::string compare = generate_name("atomic_compare_value");
|
||||
if (!EmitType(ss, TypeOf(compare_value), ast::StorageClass::kNone,
|
||||
ast::Access::kUndefined, "")) {
|
||||
return false;
|
||||
}
|
||||
ss << " " << compare << " = ";
|
||||
if (!EmitExpression(pre, ss, compare_value)) {
|
||||
return false;
|
||||
}
|
||||
make_indent(ss << ";" << std::endl);
|
||||
|
||||
if (!EmitExpression(pre, ss, buffer)) {
|
||||
return false;
|
||||
}
|
||||
ss << ".InterlockedCompareExchange";
|
||||
{
|
||||
ScopedParen sp(ss);
|
||||
if (!EmitExpression(pre, ss, offset)) {
|
||||
return false;
|
||||
}
|
||||
ss << ", " << compare << ", ";
|
||||
if (!EmitExpression(pre, ss, value)) {
|
||||
return false;
|
||||
}
|
||||
ss << ", " << result << ".x";
|
||||
}
|
||||
make_indent(ss << ";" << std::endl);
|
||||
|
||||
ss << result << ".y = " << result << ".x == " << compare;
|
||||
make_indent(ss << ";" << std::endl);
|
||||
|
||||
pre << ss.str();
|
||||
out << result;
|
||||
return true;
|
||||
}
|
||||
|
||||
case Op::kAtomicAdd:
|
||||
if (!EmitExpression(pre, ss, buffer)) {
|
||||
return false;
|
||||
}
|
||||
ss << ".InterlockedAdd";
|
||||
break;
|
||||
case Op::kAtomicMax:
|
||||
if (!EmitExpression(pre, ss, buffer)) {
|
||||
return false;
|
||||
}
|
||||
ss << ".InterlockedMax";
|
||||
break;
|
||||
case Op::kAtomicMin:
|
||||
if (!EmitExpression(pre, ss, buffer)) {
|
||||
return false;
|
||||
}
|
||||
ss << ".InterlockedMin";
|
||||
break;
|
||||
case Op::kAtomicAnd:
|
||||
if (!EmitExpression(pre, ss, buffer)) {
|
||||
return false;
|
||||
}
|
||||
ss << ".InterlockedAnd";
|
||||
break;
|
||||
case Op::kAtomicOr:
|
||||
if (!EmitExpression(pre, ss, buffer)) {
|
||||
return false;
|
||||
}
|
||||
ss << ".InterlockedOr";
|
||||
break;
|
||||
case Op::kAtomicXor:
|
||||
if (!EmitExpression(pre, ss, buffer)) {
|
||||
return false;
|
||||
}
|
||||
ss << ".InterlockedXor";
|
||||
break;
|
||||
case Op::kAtomicExchange:
|
||||
if (!EmitExpression(pre, ss, buffer)) {
|
||||
return false;
|
||||
}
|
||||
ss << ".InterlockedExchange";
|
||||
break;
|
||||
|
||||
default:
|
||||
TINT_UNREACHABLE(diagnostics_)
|
||||
<< "unsupported atomic DecomposeStorageAccess::Intrinsic::Op: "
|
||||
<< static_cast<int>(op);
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
ScopedParen sp(ss);
|
||||
if (!EmitExpression(pre, ss, offset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < expr->params().size() - 1; i++) {
|
||||
auto* arg = expr->params()[i];
|
||||
ss << ", ";
|
||||
if (!EmitExpression(pre, ss, arg)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ss << ", " << result;
|
||||
}
|
||||
|
||||
make_indent(ss << ";" << std::endl);
|
||||
pre << ss.str();
|
||||
out << result;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& pre,
|
||||
std::ostream& out,
|
||||
ast::CallExpression* expr,
|
||||
const sem::Intrinsic* intrinsic) {
|
||||
std::stringstream ss;
|
||||
std::string result = generate_name("atomic_result");
|
||||
|
||||
if (!intrinsic->ReturnType()->Is<sem::Void>()) {
|
||||
if (!EmitType(ss, intrinsic->ReturnType(), ast::StorageClass::kNone,
|
||||
ast::Access::kUndefined, "")) {
|
||||
return false;
|
||||
}
|
||||
ss << " " << result << " = ";
|
||||
if (!EmitZeroValue(ss, intrinsic->ReturnType())) {
|
||||
return false;
|
||||
}
|
||||
make_indent(ss << ";" << std::endl);
|
||||
}
|
||||
|
||||
switch (intrinsic->Type()) {
|
||||
case sem::IntrinsicType::kAtomicLoad: {
|
||||
// HLSL does not have an InterlockedLoad, so we emulate it with
|
||||
// InterlockedOr using 0 as the OR value
|
||||
ss << "InterlockedOr";
|
||||
{
|
||||
ScopedParen sp(ss);
|
||||
if (!EmitExpression(pre, ss, expr->params()[0])) {
|
||||
return false;
|
||||
}
|
||||
ss << ", 0, " << result;
|
||||
}
|
||||
make_indent(ss << ";" << std::endl);
|
||||
|
||||
pre << ss.str();
|
||||
out << result;
|
||||
return true;
|
||||
}
|
||||
case sem::IntrinsicType::kAtomicStore: {
|
||||
// HLSL does not have an InterlockedStore, so we emulate it with
|
||||
// InterlockedExchange and discard the returned value
|
||||
auto* value_ty = intrinsic->Parameters()[1].type;
|
||||
if (!EmitType(pre, value_ty, ast::StorageClass::kNone,
|
||||
ast::Access::kUndefined, "")) {
|
||||
return false;
|
||||
}
|
||||
pre << " " << result << " = ";
|
||||
if (!EmitZeroValue(pre, value_ty)) {
|
||||
return false;
|
||||
}
|
||||
make_indent(pre << ";" << std::endl);
|
||||
|
||||
out << "InterlockedExchange";
|
||||
{
|
||||
ScopedParen sp(out);
|
||||
if (!EmitExpression(pre, out, expr->params()[0])) {
|
||||
return false;
|
||||
}
|
||||
out << ", ";
|
||||
if (!EmitExpression(pre, out, expr->params()[1])) {
|
||||
return false;
|
||||
}
|
||||
out << ", " << result;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case sem::IntrinsicType::kAtomicCompareExchangeWeak: {
|
||||
auto* dest = expr->params()[0];
|
||||
auto* compare_value = expr->params()[1];
|
||||
auto* value = expr->params()[2];
|
||||
|
||||
std::string compare = generate_name("atomic_compare_value");
|
||||
if (!EmitType(ss, TypeOf(compare_value), ast::StorageClass::kNone,
|
||||
ast::Access::kUndefined, "")) {
|
||||
return false;
|
||||
}
|
||||
ss << " " << compare << " = ";
|
||||
if (!EmitExpression(pre, ss, compare_value)) {
|
||||
return false;
|
||||
}
|
||||
make_indent(ss << ";" << std::endl);
|
||||
|
||||
ss << "InterlockedCompareExchange";
|
||||
{
|
||||
ScopedParen sp(ss);
|
||||
if (!EmitExpression(pre, ss, dest)) {
|
||||
return false;
|
||||
}
|
||||
ss << ", " << compare << ", ";
|
||||
if (!EmitExpression(pre, ss, value)) {
|
||||
return false;
|
||||
}
|
||||
ss << ", " << result << ".x";
|
||||
}
|
||||
make_indent(ss << ";" << std::endl);
|
||||
|
||||
ss << result << ".y = " << result << ".x == " << compare;
|
||||
make_indent(ss << ";" << std::endl);
|
||||
|
||||
pre << ss.str();
|
||||
out << result;
|
||||
return true;
|
||||
}
|
||||
|
||||
case sem::IntrinsicType::kAtomicAdd:
|
||||
ss << "InterlockedAdd";
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicMax:
|
||||
ss << "InterlockedMax";
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicMin:
|
||||
ss << "InterlockedMin";
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicAnd:
|
||||
ss << "InterlockedAnd";
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicOr:
|
||||
ss << "InterlockedOr";
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicXor:
|
||||
ss << "InterlockedXor";
|
||||
break;
|
||||
case sem::IntrinsicType::kAtomicExchange:
|
||||
ss << "InterlockedExchange";
|
||||
break;
|
||||
|
||||
default:
|
||||
TINT_UNREACHABLE(diagnostics_)
|
||||
<< "unsupported atomic intrinsic: " << intrinsic->Type();
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
ScopedParen sp(ss);
|
||||
for (size_t i = 0; i < expr->params().size(); i++) {
|
||||
auto* arg = expr->params()[i];
|
||||
if (i > 0) {
|
||||
ss << ", ";
|
||||
}
|
||||
if (!EmitExpression(pre, ss, arg)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ss << ", " << result;
|
||||
}
|
||||
make_indent(ss << ";" << std::endl);
|
||||
|
||||
pre << ss.str();
|
||||
out << result;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitSelectCall(std::ostream& pre,
|
||||
std::ostream& out,
|
||||
ast::CallExpression* expr) {
|
||||
|
@ -1153,11 +1543,10 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre,
|
|||
}
|
||||
|
||||
return true;
|
||||
} // namespace hlsl
|
||||
}
|
||||
|
||||
std::string GeneratorImpl::generate_builtin_name(
|
||||
const sem::Intrinsic* intrinsic) {
|
||||
std::string out;
|
||||
switch (intrinsic->Type()) {
|
||||
case sem::IntrinsicType::kAbs:
|
||||
case sem::IntrinsicType::kAcos:
|
||||
|
@ -1198,71 +1587,51 @@ std::string GeneratorImpl::generate_builtin_name(
|
|||
case sem::IntrinsicType::kTanh:
|
||||
case sem::IntrinsicType::kTranspose:
|
||||
case sem::IntrinsicType::kTrunc:
|
||||
out = intrinsic->str();
|
||||
break;
|
||||
return intrinsic->str();
|
||||
case sem::IntrinsicType::kCountOneBits:
|
||||
out = "countbits";
|
||||
break;
|
||||
return "countbits";
|
||||
case sem::IntrinsicType::kDpdx:
|
||||
out = "ddx";
|
||||
break;
|
||||
return "ddx";
|
||||
case sem::IntrinsicType::kDpdxCoarse:
|
||||
out = "ddx_coarse";
|
||||
break;
|
||||
return "ddx_coarse";
|
||||
case sem::IntrinsicType::kDpdxFine:
|
||||
out = "ddx_fine";
|
||||
break;
|
||||
return "ddx_fine";
|
||||
case sem::IntrinsicType::kDpdy:
|
||||
out = "ddy";
|
||||
break;
|
||||
return "ddy";
|
||||
case sem::IntrinsicType::kDpdyCoarse:
|
||||
out = "ddy_coarse";
|
||||
break;
|
||||
return "ddy_coarse";
|
||||
case sem::IntrinsicType::kDpdyFine:
|
||||
out = "ddy_fine";
|
||||
break;
|
||||
return "ddy_fine";
|
||||
case sem::IntrinsicType::kFaceForward:
|
||||
out = "faceforward";
|
||||
break;
|
||||
return "faceforward";
|
||||
case sem::IntrinsicType::kFract:
|
||||
out = "frac";
|
||||
break;
|
||||
return "frac";
|
||||
case sem::IntrinsicType::kFma:
|
||||
out = "mad";
|
||||
break;
|
||||
return "mad";
|
||||
case sem::IntrinsicType::kFwidth:
|
||||
case sem::IntrinsicType::kFwidthCoarse:
|
||||
case sem::IntrinsicType::kFwidthFine:
|
||||
out = "fwidth";
|
||||
break;
|
||||
return "fwidth";
|
||||
case sem::IntrinsicType::kInverseSqrt:
|
||||
out = "rsqrt";
|
||||
break;
|
||||
return "rsqrt";
|
||||
case sem::IntrinsicType::kIsFinite:
|
||||
out = "isfinite";
|
||||
break;
|
||||
return "isfinite";
|
||||
case sem::IntrinsicType::kIsInf:
|
||||
out = "isinf";
|
||||
break;
|
||||
return "isinf";
|
||||
case sem::IntrinsicType::kIsNan:
|
||||
out = "isnan";
|
||||
break;
|
||||
return "isnan";
|
||||
case sem::IntrinsicType::kMix:
|
||||
out = "lerp";
|
||||
break;
|
||||
return "lerp";
|
||||
case sem::IntrinsicType::kReverseBits:
|
||||
out = "reversebits";
|
||||
break;
|
||||
return "reversebits";
|
||||
case sem::IntrinsicType::kSmoothStep:
|
||||
out = "smoothstep";
|
||||
break;
|
||||
return "smoothstep";
|
||||
default:
|
||||
diagnostics_.add_error("Unknown builtin method: " +
|
||||
std::string(intrinsic->str()));
|
||||
return "";
|
||||
}
|
||||
|
||||
return out;
|
||||
return "";
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitCase(std::ostream& out, ast::CaseStatement* stmt) {
|
||||
|
@ -2237,6 +2606,10 @@ bool GeneratorImpl::EmitType(std::ostream& out,
|
|||
}
|
||||
out << ", " << size << ">";
|
||||
}
|
||||
} else if (auto* atomic = type->As<sem::Atomic>()) {
|
||||
if (!EmitType(out, atomic->Type(), storage_class, access, name)) {
|
||||
return false;
|
||||
}
|
||||
} else if (type->Is<sem::Void>()) {
|
||||
out << "void";
|
||||
} else {
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "src/ast/unary_op_expression.h"
|
||||
#include "src/program_builder.h"
|
||||
#include "src/scope_stack.h"
|
||||
#include "src/transform/decompose_storage_access.h"
|
||||
#include "src/writer/text_generator.h"
|
||||
|
||||
namespace tint {
|
||||
|
@ -115,6 +116,18 @@ class GeneratorImpl : public TextGenerator {
|
|||
bool EmitCall(std::ostream& pre,
|
||||
std::ostream& out,
|
||||
ast::CallExpression* expr);
|
||||
/// Handles generating a call expression to a
|
||||
/// transform::DecomposeStorageAccess::Intrinsic
|
||||
/// @param pre the preamble for the expression stream
|
||||
/// @param out the output of the expression stream
|
||||
/// @param expr the call expression
|
||||
/// @param intrinsic the transform::DecomposeStorageAccess::Intrinsic
|
||||
/// @returns true if the call expression is emitted
|
||||
bool EmitDecomposeStorageAccessIntrinsic(
|
||||
std::ostream& pre,
|
||||
std::ostream& out,
|
||||
ast::CallExpression* expr,
|
||||
const transform::DecomposeStorageAccess::Intrinsic* intrinsic);
|
||||
/// Handles generating a barrier intrinsic call
|
||||
/// @param pre the preamble for the expression stream
|
||||
/// @param out the output of the expression stream
|
||||
|
@ -123,6 +136,27 @@ class GeneratorImpl : public TextGenerator {
|
|||
bool EmitBarrierCall(std::ostream& pre,
|
||||
std::ostream& out,
|
||||
const sem::Intrinsic* intrinsic);
|
||||
/// Handles generating an atomic intrinsic call for a storage buffer variable
|
||||
/// @param pre the preamble for the expression stream
|
||||
/// @param out the output of the expression stream
|
||||
/// @param expr the call expression
|
||||
/// @param op the atomic op
|
||||
/// @returns true if the call expression is emitted
|
||||
bool EmitStorageAtomicCall(
|
||||
std::ostream& pre,
|
||||
std::ostream& out,
|
||||
ast::CallExpression* expr,
|
||||
transform::DecomposeStorageAccess::Intrinsic::Op op);
|
||||
/// Handles generating an atomic intrinsic call for a workgroup variable
|
||||
/// @param pre the preamble for the expression stream
|
||||
/// @param out the output of the expression stream
|
||||
/// @param expr the call expression
|
||||
/// @param intrinsic the semantic information for the atomic intrinsic
|
||||
/// @returns true if the call expression is emitted
|
||||
bool EmitWorkgroupAtomicCall(std::ostream& pre,
|
||||
std::ostream& out,
|
||||
ast::CallExpression* expr,
|
||||
const sem::Intrinsic* intrinsic);
|
||||
/// Handles generating a call to a texture function (`textureSample`,
|
||||
/// `textureSampleGrad`, etc)
|
||||
/// @param pre the preamble for the expression stream
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared int arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<i32>;
|
||||
|
||||
fn atomicAdd_794055() {
|
||||
var res : i32 = atomicAdd(&(arg_0), 1);
|
||||
void atomicAdd_794055() {
|
||||
int atomic_result = 0;
|
||||
InterlockedAdd(arg_0, 1, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicAdd_794055();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicAdd_794055(tint_symbol : ptr<workgroup, atomic<i32>>) {
|
||||
var res : i32 = atomicAdd(&(*(tint_symbol)), 1);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
|
||||
atomicAdd_794055(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicAdd_8a199a() {
|
||||
uint atomic_result = 0u;
|
||||
sb_rw.InterlockedAdd(0u, 0u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicAdd_8a199a();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicAdd_8a199a();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicAdd_d32fe4() {
|
||||
int atomic_result = 0;
|
||||
sb_rw.InterlockedAdd(0u, 0u, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicAdd_d32fe4();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicAdd_d32fe4();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared uint arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<u32>;
|
||||
|
||||
fn atomicAdd_d5db1d() {
|
||||
var res : u32 = atomicAdd(&(arg_0), 1u);
|
||||
void atomicAdd_d5db1d() {
|
||||
uint atomic_result = 0u;
|
||||
InterlockedAdd(arg_0, 1u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicAdd_d5db1d();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicAdd_d5db1d(tint_symbol : ptr<workgroup, atomic<u32>>) {
|
||||
var res : u32 = atomicAdd(&(*(tint_symbol)), 1u);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
|
||||
atomicAdd_d5db1d(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicAnd_152966() {
|
||||
int atomic_result = 0;
|
||||
sb_rw.InterlockedAnd(0u, 0u, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicAnd_152966();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicAnd_152966();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared uint arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<u32>;
|
||||
|
||||
fn atomicAnd_34edd3() {
|
||||
var res : u32 = atomicAnd(&(arg_0), 1u);
|
||||
void atomicAnd_34edd3() {
|
||||
uint atomic_result = 0u;
|
||||
InterlockedAnd(arg_0, 1u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicAnd_34edd3();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicAnd_34edd3(tint_symbol : ptr<workgroup, atomic<u32>>) {
|
||||
var res : u32 = atomicAnd(&(*(tint_symbol)), 1u);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
|
||||
atomicAnd_34edd3(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared int arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<i32>;
|
||||
|
||||
fn atomicAnd_45a819() {
|
||||
var res : i32 = atomicAnd(&(arg_0), 1);
|
||||
void atomicAnd_45a819() {
|
||||
int atomic_result = 0;
|
||||
InterlockedAnd(arg_0, 1, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicAnd_45a819();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicAnd_45a819(tint_symbol : ptr<workgroup, atomic<i32>>) {
|
||||
var res : i32 = atomicAnd(&(*(tint_symbol)), 1);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
|
||||
atomicAnd_45a819(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicAnd_85a8d9() {
|
||||
uint atomic_result = 0u;
|
||||
sb_rw.InterlockedAnd(0u, 0u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicAnd_85a8d9();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicAnd_85a8d9();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicCompareExchangeWeak_12871c() {
|
||||
int2 atomic_result = int2(0, 0);
|
||||
int atomic_compare_value = 1;
|
||||
sb_rw.InterlockedCompareExchange(0u, atomic_compare_value, 1, atomic_result.x);
|
||||
atomic_result.y = atomic_result.x == atomic_compare_value;
|
||||
int2 res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicCompareExchangeWeak_12871c();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicCompareExchangeWeak_12871c();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicCompareExchangeWeak_6673da() {
|
||||
uint2 atomic_result = uint2(0u, 0u);
|
||||
uint atomic_compare_value = 1u;
|
||||
sb_rw.InterlockedCompareExchange(0u, atomic_compare_value, 1u, atomic_result.x);
|
||||
atomic_result.y = atomic_result.x == atomic_compare_value;
|
||||
uint2 res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicCompareExchangeWeak_6673da();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicCompareExchangeWeak_6673da();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
SKIP: FAILED
|
||||
groupshared int arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<i32>;
|
||||
|
||||
fn atomicCompareExchangeWeak_89ea3b() {
|
||||
var res : vec2<i32> = atomicCompareExchangeWeak(&(arg_0), 1, 1);
|
||||
void atomicCompareExchangeWeak_89ea3b() {
|
||||
int2 atomic_result = int2(0, 0);
|
||||
int atomic_compare_value = 1;
|
||||
InterlockedCompareExchange(arg_0, atomic_compare_value, 1, atomic_result.x);
|
||||
atomic_result.y = atomic_result.x == atomic_compare_value;
|
||||
int2 res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicCompareExchangeWeak_89ea3b();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicCompareExchangeWeak_89ea3b(tint_symbol : ptr<workgroup, atomic<i32>>) {
|
||||
var res : vec2<i32> = atomicCompareExchangeWeak(&(*(tint_symbol)), 1, 1);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
|
||||
atomicCompareExchangeWeak_89ea3b(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
SKIP: FAILED
|
||||
groupshared uint arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<u32>;
|
||||
|
||||
fn atomicCompareExchangeWeak_b2ab2c() {
|
||||
var res : vec2<u32> = atomicCompareExchangeWeak(&(arg_0), 1u, 1u);
|
||||
void atomicCompareExchangeWeak_b2ab2c() {
|
||||
uint2 atomic_result = uint2(0u, 0u);
|
||||
uint atomic_compare_value = 1u;
|
||||
InterlockedCompareExchange(arg_0, atomic_compare_value, 1u, atomic_result.x);
|
||||
atomic_result.y = atomic_result.x == atomic_compare_value;
|
||||
uint2 res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicCompareExchangeWeak_b2ab2c();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicCompareExchangeWeak_b2ab2c(tint_symbol : ptr<workgroup, atomic<u32>>) {
|
||||
var res : vec2<u32> = atomicCompareExchangeWeak(&(*(tint_symbol)), 1u, 1u);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
|
||||
atomicCompareExchangeWeak_b2ab2c(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared uint arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<u32>;
|
||||
|
||||
fn atomicExchange_0a5dca() {
|
||||
var res : u32 = atomicExchange(&(arg_0), 1u);
|
||||
void atomicExchange_0a5dca() {
|
||||
uint atomic_result = 0u;
|
||||
InterlockedExchange(arg_0, 1u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicExchange_0a5dca();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicExchange_0a5dca(tint_symbol : ptr<workgroup, atomic<u32>>) {
|
||||
var res : u32 = atomicExchange(&(*(tint_symbol)), 1u);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
|
||||
atomicExchange_0a5dca(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicExchange_d59712() {
|
||||
uint atomic_result = 0u;
|
||||
sb_rw.InterlockedExchange(0u, 0u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicExchange_d59712();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicExchange_d59712();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared int arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<i32>;
|
||||
|
||||
fn atomicExchange_e114ba() {
|
||||
var res : i32 = atomicExchange(&(arg_0), 1);
|
||||
void atomicExchange_e114ba() {
|
||||
int atomic_result = 0;
|
||||
InterlockedExchange(arg_0, 1, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicExchange_e114ba();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicExchange_e114ba(tint_symbol : ptr<workgroup, atomic<i32>>) {
|
||||
var res : i32 = atomicExchange(&(*(tint_symbol)), 1);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
|
||||
atomicExchange_e114ba(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicExchange_f2e22f() {
|
||||
int atomic_result = 0;
|
||||
sb_rw.InterlockedExchange(0u, 0u, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicExchange_f2e22f();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicExchange_f2e22f();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicLoad_0806ad() {
|
||||
int atomic_result = 0;
|
||||
sb_rw.InterlockedOr(0u, 0, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicLoad_0806ad();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicLoad_0806ad();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared uint arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<u32>;
|
||||
|
||||
fn atomicLoad_361bf1() {
|
||||
var res : u32 = atomicLoad(&(arg_0));
|
||||
void atomicLoad_361bf1() {
|
||||
uint atomic_result = 0u;
|
||||
InterlockedOr(arg_0, 0, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicLoad_361bf1();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicLoad_361bf1(tint_symbol : ptr<workgroup, atomic<u32>>) {
|
||||
var res : u32 = atomicLoad(&(*(tint_symbol)));
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
|
||||
atomicLoad_361bf1(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared int arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<i32>;
|
||||
|
||||
fn atomicLoad_afcc03() {
|
||||
var res : i32 = atomicLoad(&(arg_0));
|
||||
void atomicLoad_afcc03() {
|
||||
int atomic_result = 0;
|
||||
InterlockedOr(arg_0, 0, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicLoad_afcc03();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicLoad_afcc03(tint_symbol : ptr<workgroup, atomic<i32>>) {
|
||||
var res : i32 = atomicLoad(&(*(tint_symbol)));
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
|
||||
atomicLoad_afcc03(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicLoad_fe6cc3() {
|
||||
uint atomic_result = 0u;
|
||||
sb_rw.InterlockedOr(0u, 0, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicLoad_fe6cc3();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicLoad_fe6cc3();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicMax_51b9be() {
|
||||
uint atomic_result = 0u;
|
||||
sb_rw.InterlockedMax(0u, 0u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicMax_51b9be();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicMax_51b9be();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicMax_92aa72() {
|
||||
int atomic_result = 0;
|
||||
sb_rw.InterlockedMax(0u, 0u, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicMax_92aa72();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicMax_92aa72();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared int arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<i32>;
|
||||
|
||||
fn atomicMax_a89cc3() {
|
||||
var res : i32 = atomicMax(&(arg_0), 1);
|
||||
void atomicMax_a89cc3() {
|
||||
int atomic_result = 0;
|
||||
InterlockedMax(arg_0, 1, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicMax_a89cc3();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicMax_a89cc3(tint_symbol : ptr<workgroup, atomic<i32>>) {
|
||||
var res : i32 = atomicMax(&(*(tint_symbol)), 1);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
|
||||
atomicMax_a89cc3(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared uint arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<u32>;
|
||||
|
||||
fn atomicMax_beccfc() {
|
||||
var res : u32 = atomicMax(&(arg_0), 1u);
|
||||
void atomicMax_beccfc() {
|
||||
uint atomic_result = 0u;
|
||||
InterlockedMax(arg_0, 1u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicMax_beccfc();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicMax_beccfc(tint_symbol : ptr<workgroup, atomic<u32>>) {
|
||||
var res : u32 = atomicMax(&(*(tint_symbol)), 1u);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
|
||||
atomicMax_beccfc(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared int arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<i32>;
|
||||
|
||||
fn atomicMin_278235() {
|
||||
var res : i32 = atomicMin(&(arg_0), 1);
|
||||
void atomicMin_278235() {
|
||||
int atomic_result = 0;
|
||||
InterlockedMin(arg_0, 1, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicMin_278235();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicMin_278235(tint_symbol : ptr<workgroup, atomic<i32>>) {
|
||||
var res : i32 = atomicMin(&(*(tint_symbol)), 1);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
|
||||
atomicMin_278235(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared uint arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<u32>;
|
||||
|
||||
fn atomicMin_69d383() {
|
||||
var res : u32 = atomicMin(&(arg_0), 1u);
|
||||
void atomicMin_69d383() {
|
||||
uint atomic_result = 0u;
|
||||
InterlockedMin(arg_0, 1u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicMin_69d383();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicMin_69d383(tint_symbol : ptr<workgroup, atomic<u32>>) {
|
||||
var res : u32 = atomicMin(&(*(tint_symbol)), 1u);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
|
||||
atomicMin_69d383(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicMin_8e38dc() {
|
||||
int atomic_result = 0;
|
||||
sb_rw.InterlockedMin(0u, 0u, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicMin_8e38dc();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicMin_8e38dc();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicMin_c67a74() {
|
||||
uint atomic_result = 0u;
|
||||
sb_rw.InterlockedMin(0u, 0u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicMin_c67a74();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicMin_c67a74();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared uint arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<u32>;
|
||||
|
||||
fn atomicOr_5e3d61() {
|
||||
var res : u32 = atomicOr(&(arg_0), 1u);
|
||||
void atomicOr_5e3d61() {
|
||||
uint atomic_result = 0u;
|
||||
InterlockedOr(arg_0, 1u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicOr_5e3d61();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicOr_5e3d61(tint_symbol : ptr<workgroup, atomic<u32>>) {
|
||||
var res : u32 = atomicOr(&(*(tint_symbol)), 1u);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
|
||||
atomicOr_5e3d61(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicOr_5e95d4() {
|
||||
uint atomic_result = 0u;
|
||||
sb_rw.InterlockedOr(0u, 0u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicOr_5e95d4();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicOr_5e95d4();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicOr_8d96a0() {
|
||||
int atomic_result = 0;
|
||||
sb_rw.InterlockedOr(0u, 0u, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicOr_8d96a0();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicOr_8d96a0();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared int arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<i32>;
|
||||
|
||||
fn atomicOr_d09248() {
|
||||
var res : i32 = atomicOr(&(arg_0), 1);
|
||||
void atomicOr_d09248() {
|
||||
int atomic_result = 0;
|
||||
InterlockedOr(arg_0, 1, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicOr_d09248();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicOr_d09248(tint_symbol : ptr<workgroup, atomic<i32>>) {
|
||||
var res : i32 = atomicOr(&(*(tint_symbol)), 1);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
|
||||
atomicOr_d09248(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
SKIP: FAILED
|
||||
groupshared uint arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<u32>;
|
||||
|
||||
fn atomicStore_726882() {
|
||||
atomicStore(&(arg_0), 1u);
|
||||
void atomicStore_726882() {
|
||||
uint atomic_result = 0u;
|
||||
InterlockedExchange(arg_0, 1u, atomic_result);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicStore_726882();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicStore_726882(tint_symbol : ptr<workgroup, atomic<u32>>) {
|
||||
atomicStore(&(*(tint_symbol)), 1u);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
|
||||
atomicStore_726882(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
SKIP: FAILED
|
||||
groupshared int arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<i32>;
|
||||
|
||||
fn atomicStore_8bea94() {
|
||||
atomicStore(&(arg_0), 1);
|
||||
void atomicStore_8bea94() {
|
||||
int atomic_result = 0;
|
||||
InterlockedExchange(arg_0, 1, atomic_result);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicStore_8bea94();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicStore_8bea94(tint_symbol : ptr<workgroup, atomic<i32>>) {
|
||||
atomicStore(&(*(tint_symbol)), 1);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
|
||||
atomicStore_8bea94(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicStore_cdc29e() {
|
||||
uint atomic_result = 0u;
|
||||
sb_rw.InterlockedExchange(0u, 1u, atomic_result);
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicStore_cdc29e();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicStore_cdc29e();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicStore_d1e9a6() {
|
||||
int atomic_result = 0;
|
||||
sb_rw.InterlockedExchange(0u, 1, atomic_result);
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicStore_d1e9a6();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicStore_d1e9a6();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicXor_54510e() {
|
||||
uint atomic_result = 0u;
|
||||
sb_rw.InterlockedXor(0u, 0u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicXor_54510e();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicXor_54510e();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared int arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<i32>;
|
||||
|
||||
fn atomicXor_75dc95() {
|
||||
var res : i32 = atomicXor(&(arg_0), 1);
|
||||
void atomicXor_75dc95() {
|
||||
int atomic_result = 0;
|
||||
InterlockedXor(arg_0, 1, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicXor_75dc95();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicXor_75dc95(tint_symbol : ptr<workgroup, atomic<i32>>) {
|
||||
var res : i32 = atomicXor(&(*(tint_symbol)), 1);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
|
||||
atomicXor_75dc95(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
SKIP: FAILED
|
||||
RWByteAddressBuffer sb_rw : register(u0, space0);
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
void atomicXor_c1b78c() {
|
||||
int atomic_result = 0;
|
||||
sb_rw.InterlockedXor(0u, 0u, atomic_result);
|
||||
int res = atomic_result;
|
||||
}
|
||||
|
||||
void fragment_main() {
|
||||
atomicXor_c1b78c();
|
||||
return;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicXor_c1b78c();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
SKIP: FAILED
|
||||
groupshared uint arg_0;
|
||||
|
||||
|
||||
var<workgroup> arg_0 : atomic<u32>;
|
||||
|
||||
fn atomicXor_c8e6be() {
|
||||
var res : u32 = atomicXor(&(arg_0), 1u);
|
||||
void atomicXor_c8e6be() {
|
||||
uint atomic_result = 0u;
|
||||
InterlockedXor(arg_0, 1u, atomic_result);
|
||||
uint res = atomic_result;
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[numthreads(1, 1, 1)]
|
||||
void compute_main() {
|
||||
atomicXor_c8e6be();
|
||||
return;
|
||||
}
|
||||
|
||||
Failed to generate: error: unknown type in EmitType
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
SKIP: FAILED
|
||||
|
||||
../src/transform/transform.cc:133 internal compiler error: TINT_UNREACHABLE Unhandled type: tint::sem::Atomic
|
||||
********************************************************************
|
||||
* The tint shader compiler has encountered an unexpected error. *
|
||||
* *
|
||||
* Please help us fix this issue by submitting a bug report at *
|
||||
* crbug.com/tint with the source program that triggered the bug. *
|
||||
********************************************************************
|
||||
|
||||
fn atomicXor_c8e6be(tint_symbol : ptr<workgroup, atomic<u32>>) {
|
||||
var res : u32 = atomicXor(&(*(tint_symbol)), 1u);
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn compute_main() {
|
||||
[[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
|
||||
atomicXor_c8e6be(&(tint_symbol_1));
|
||||
}
|
||||
|
||||
error: cannot declare an atomic var in a function scope
|
||||
|
|
Loading…
Reference in New Issue