GLSL: implement texture sample and store functions.

Change all the texture types to the GLSL equivalents. Note that some
types don't actually exist in GLSL ES, e.g., 1D textures, but this
will be handled later.

Change all the texture functions from HLSL-style to GLSL (e.g.,
texture.Sample(...) -> texture(texture, ...). Note that depth
comparison functions are probably wrong.

Implement writeonly storage texture type and functions.

Samplers are skipped entirely in the GLSL backend, with the assumption
that they will already have been combined into GLSL-style combined
samplers and textures by the client code.

Move the SingleEntryPoint transform above the RemovePhonies pass. This
ensures that texture variables are not optimized out. (Otherwise some
tests produce valid but not very useful results.)

Add the builtin-functions to the GLSL keywords list for renaming.
They're not keywords, but they can't be identifiers either.

Bug: tint:1298, tint:1299

Change-Id: I86c4547fcdd1eba80be98f6c05b939f345fd4c3e
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/69200
Commit-Queue: Stephen White <senorblanco@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
Stephen White 2021-11-15 18:01:54 +00:00 committed by Tint LUCI CQ
parent 6d643deefa
commit bf209ffc9d
5 changed files with 322 additions and 249 deletions

View File

@ -59,6 +59,15 @@ Output Glsl::Run(const Program* in, const DataMap& inputs) {
}
manager.Add<CanonicalizeEntryPointIO>();
manager.Add<InlinePointerLets>();
// Running SingleEntryPoint before RemovePhonies prevents variables
// referenced only by phonies from being optimized out. Strictly
// speaking, that optimization isn't incorrect, but it prevents some
// tests (e.g., types/texture/*) from producing useful results.
if (cfg) {
manager.Add<SingleEntryPoint>();
data.Add<SingleEntryPoint::Config>(cfg->entry_point);
}
manager.Add<RemovePhonies>();
// Simplify cleans up messy `*(&(expr))` expressions from InlinePointerLets.
manager.Add<Simplify>();
@ -72,10 +81,6 @@ Output Glsl::Run(const Program* in, const DataMap& inputs) {
// variables directly.
data.Add<CanonicalizeEntryPointIO::Config>(
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
if (cfg) {
manager.Add<SingleEntryPoint>();
data.Add<SingleEntryPoint::Config>(cfg->entry_point);
}
auto out = manager.Run(in, data);
if (!out.program.IsValid()) {
return out;

View File

@ -33,10 +33,35 @@ namespace {
// This list is used for a binary search and must be kept in sorted order.
const char* kReservedKeywordsGLSL[] = {
"abs",
"acos",
"acosh",
"active",
"all",
"any",
"asin",
"asinh",
"asm",
"atan",
"atanh",
"atomicAdd",
"atomicAnd",
"atomicCompSwap",
"atomicCounter",
"atomicCounterDecrement",
"atomicCounterIncrement",
"atomicExchange",
"atomicMax",
"atomicMin",
"atomicOr",
"atomicXor",
"atomic_uint",
"attribute",
"barrier",
"bitCount",
"bitfieldExtract",
"bitfieldInsert",
"bitfieldReverse",
"bool",
"break",
"buffer",
@ -45,14 +70,24 @@ const char* kReservedKeywordsGLSL[] = {
"bvec4",
"case",
"cast",
"ceil",
"centroid",
"clamp",
"class",
"coherent",
"common",
"const",
"continue",
"cos",
"cosh",
"cross",
"dFdx",
"dFdy",
"default",
"degrees",
"determinant",
"discard",
"distance",
"dmat2",
"dmat2x2",
"dmat2x3",
@ -66,23 +101,36 @@ const char* kReservedKeywordsGLSL[] = {
"dmat4x3",
"dmat4x4",
"do",
"dot",
"double",
"dvec2",
"dvec3",
"dvec4",
"else",
"enum",
"equal",
"exp",
"exp2",
"extern",
"external",
"faceforward",
"false",
"filter",
"findLSB",
"findMSB",
"fixed",
"flat",
"float",
"floatBitsToInt",
"floatBitsToUint",
"floor",
"for",
"fract",
"frexp",
"fvec2",
"fvec3",
"fvec4",
"fwidth",
"gl_BaseInstance",
"gl_BaseVertex",
"gl_ClipDistance",
@ -110,6 +158,9 @@ const char* kReservedKeywordsGLSL[] = {
"gl_WorkGroupID",
"gl_WorkGroupSize",
"goto",
"greaterThan",
"greaterThanEqual",
"groupMemoryBarrier",
"half",
"highp",
"hvec2",
@ -138,13 +189,20 @@ const char* kReservedKeywordsGLSL[] = {
"imageBuffer",
"imageCube",
"imageCubeArray",
"imageLoad",
"imageSize",
"imageStore",
"imulExtended",
"in",
"inline",
"inout",
"input",
"int",
"intBitsToFloat",
"interface",
"invariant",
"inverse",
"inversesqrt",
"isampler1D",
"isampler1DArray",
"isampler2D",
@ -156,10 +214,18 @@ const char* kReservedKeywordsGLSL[] = {
"isamplerBuffer",
"isamplerCube",
"isamplerCubeArray",
"isinf",
"isnan",
"ivec2",
"ivec3",
"ivec4",
"layout",
"ldexp",
"length",
"lessThan",
"lessThanEqual",
"log",
"log2",
"long",
"lowp",
"main",
@ -175,21 +241,47 @@ const char* kReservedKeywordsGLSL[] = {
"mat4x2",
"mat4x3",
"mat4x4",
"matrixCompMult",
"max",
"mediump",
"memoryBarrier",
"memoryBarrierAtomicCounter",
"memoryBarrierBuffer",
"memoryBarrierImage",
"memoryBarrierShared",
"min",
"mix",
"mod",
"modf",
"namespace",
"noinline",
"noperspective",
"normalize",
"not",
"notEqual",
"out",
"outerProduct",
"output",
"packHalf2x16",
"packSnorm2x16",
"packSnorm4x8",
"packUnorm2x16",
"packUnorm4x8",
"partition",
"patch",
"pow",
"precise",
"precision",
"public",
"radians",
"readonly",
"reflect",
"refract",
"resource",
"restrict",
"return",
"round",
"roundEven",
"sample",
"sampler1D",
"sampler1DArray",
@ -212,17 +304,45 @@ const char* kReservedKeywordsGLSL[] = {
"samplerCubeShadow",
"shared",
"short",
"sign",
"sin",
"sinh",
"sizeof",
"smooth",
"smoothstep",
"sqrt",
"static",
"step",
"struct",
"subroutine",
"superp",
"switch",
"tan",
"tanh",
"template",
"texelFetch",
"texelFetchOffset",
"texture",
"textureGather",
"textureGatherOffset",
"textureGrad",
"textureGradOffset",
"textureLod",
"textureLodOffset",
"textureOffset",
"textureProj",
"textureProjGrad",
"textureProjGradOffset",
"textureProjLod",
"textureProjLodOffset",
"textureProjOffset",
"textureSize",
"this",
"transpose",
"true",
"trunc",
"typedef",
"uaddCarry",
"uimage1D",
"uimage1DArray",
"uimage2D",
@ -235,8 +355,15 @@ const char* kReservedKeywordsGLSL[] = {
"uimageCube",
"uimageCubeArray",
"uint",
"uintBitsToFloat",
"umulExtended",
"uniform",
"union",
"unpackHalf2x16",
"unpackSnorm2x16",
"unpackSnorm4x8",
"unpackUnorm2x16",
"unpackUnorm4x8",
"unsigned",
"usampler1D",
"usampler1DArray",
@ -250,6 +377,7 @@ const char* kReservedKeywordsGLSL[] = {
"usamplerCube",
"usamplerCubeArray",
"using",
"usubBorrow",
"uvec2",
"uvec3",
"uvec4",

View File

@ -62,32 +62,6 @@ bool last_is_break_or_fallthrough(const ast::BlockStatement* stmts) {
return IsAnyOf<ast::BreakStatement, ast::FallthroughStatement>(stmts->Last());
}
const char* image_format_to_rwtexture_type(ast::ImageFormat image_format) {
switch (image_format) {
case ast::ImageFormat::kRgba8Unorm:
case ast::ImageFormat::kRgba8Snorm:
case ast::ImageFormat::kRgba16Float:
case ast::ImageFormat::kR32Float:
case ast::ImageFormat::kRg32Float:
case ast::ImageFormat::kRgba32Float:
return "float4";
case ast::ImageFormat::kRgba8Uint:
case ast::ImageFormat::kRgba16Uint:
case ast::ImageFormat::kR32Uint:
case ast::ImageFormat::kRg32Uint:
case ast::ImageFormat::kRgba32Uint:
return "uint4";
case ast::ImageFormat::kRgba8Sint:
case ast::ImageFormat::kRgba16Sint:
case ast::ImageFormat::kR32Sint:
case ast::ImageFormat::kRg32Sint:
case ast::ImageFormat::kRgba32Sint:
return "int4";
default:
return nullptr;
}
}
} // namespace
GeneratorImpl::GeneratorImpl(const Program* program) : TextGenerator(program) {}
@ -1086,7 +1060,7 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
return false;
}
}
out << ");";
out << ")";
return true;
}
// TODO(senorblanco): determine if this works for array textures
@ -1111,9 +1085,6 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
break;
}
if (!EmitExpression(out, texture))
return false;
// If pack_level_in_coords is true, then the mip level will be appended as the
// last value of the coordinates argument. If the WGSL intrinsic overload does
// not have a level parameter and pack_level_in_coords is true, then a zero
@ -1124,34 +1095,32 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
switch (intrinsic->Type()) {
case sem::IntrinsicType::kTextureSample:
out << ".Sample(";
break;
case sem::IntrinsicType::kTextureSampleBias:
out << ".SampleBias(";
out << "texture(";
break;
case sem::IntrinsicType::kTextureSampleLevel:
out << ".SampleLevel(";
out << "textureLod(";
break;
case sem::IntrinsicType::kTextureSampleGrad:
out << ".SampleGrad(";
out << "textureGrad(";
break;
case sem::IntrinsicType::kTextureSampleCompare:
out << ".SampleCmp(";
out << "texture(";
glsl_ret_width = 1;
break;
case sem::IntrinsicType::kTextureSampleCompareLevel:
out << ".SampleCmpLevelZero(";
out << "texture(";
glsl_ret_width = 1;
break;
case sem::IntrinsicType::kTextureLoad:
out << ".Load(";
out << "texelFetch(";
// Multisampled textures do not support mip-levels.
if (!texture_type->Is<sem::MultisampledTexture>()) {
pack_level_in_coords = true;
}
break;
case sem::IntrinsicType::kTextureStore:
out << "[";
out << "imageStore(";
break;
default:
diagnostics_.add_error(
@ -1161,11 +1130,10 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
return false;
}
if (auto* sampler = arg(Usage::kSampler)) {
if (!EmitExpression(out, sampler))
if (!EmitExpression(out, texture))
return false;
out << ", ";
}
auto* param_coords = arg(Usage::kCoords);
if (!param_coords) {
@ -1215,8 +1183,9 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
}
}
for (auto usage : {Usage::kDepthRef, Usage::kBias, Usage::kLevel, Usage::kDdx,
Usage::kDdy, Usage::kSampleIndex, Usage::kOffset}) {
for (auto usage :
{Usage::kDepthRef, Usage::kBias, Usage::kLevel, Usage::kDdx, Usage::kDdy,
Usage::kSampleIndex, Usage::kOffset, Usage::kValue}) {
if (usage == Usage::kLevel && pack_level_in_coords) {
continue; // mip level already packed in coordinates.
}
@ -1228,12 +1197,6 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
}
}
if (intrinsic->Type() == sem::IntrinsicType::kTextureStore) {
out << "] = ";
if (!EmitExpression(out, arg(Usage::kValue))) {
return false;
}
} else {
out << ")";
// If the intrinsic return type does not match the number of elements of the
@ -1256,7 +1219,6 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
<< intrinsic->Type();
return false;
}
}
return true;
}
@ -1671,6 +1633,10 @@ bool GeneratorImpl::EmitHandleVariable(const sem::Variable* var) {
auto name = builder_.Symbols().NameFor(decl->symbol);
auto* type = var->Type()->UnwrapRef();
if (type->As<sem::Sampler>()) {
// GLSL ignores Sampler variables.
return true;
}
if (!EmitTypeAndName(out, type, var->StorageClass(), var->Access(), name)) {
return false;
}
@ -2426,12 +2392,8 @@ bool GeneratorImpl::EmitType(std::ostream& out,
<< "Attempting to emit pointer type. These should have been removed "
"with the InlinePointerLets transform";
return false;
} else if (auto* sampler = type->As<sem::Sampler>()) {
out << "Sampler";
if (sampler->IsComparison()) {
out << "Comparison";
}
out << "State";
} else if (type->Is<sem::Sampler>()) {
return false;
} else if (auto* str = type->As<sem::Struct>()) {
out << StructName(str);
} else if (auto* tex = type->As<sem::Texture>()) {
@ -2440,10 +2402,29 @@ bool GeneratorImpl::EmitType(std::ostream& out,
auto* depth_ms = tex->As<sem::DepthMultisampledTexture>();
auto* sampled = tex->As<sem::SampledTexture>();
if (storage && storage->access() != ast::Access::kRead) {
out << "RW";
out << "uniform highp ";
if (sampled || ms) {
auto* subtype =
sampled ? sampled->type() : storage ? storage->type() : ms->type();
if (subtype->Is<sem::F32>()) {
} else if (subtype->Is<sem::I32>()) {
out << "i";
} else if (subtype->Is<sem::U32>()) {
out << "u";
} else {
TINT_ICE(Writer, diagnostics_) << "Unsupported texture type";
return false;
}
}
if (storage) {
if (storage->access() != ast::Access::kRead) {
out << "writeonly ";
}
out << "image";
} else {
out << "sampler";
}
out << "Texture";
switch (tex->dim()) {
case ast::TextureDimension::k1d:
@ -2469,34 +2450,6 @@ bool GeneratorImpl::EmitType(std::ostream& out,
<< "unexpected TextureDimension " << tex->dim();
return false;
}
if (storage) {
auto* component = image_format_to_rwtexture_type(storage->image_format());
if (component == nullptr) {
TINT_ICE(Writer, diagnostics_)
<< "Unsupported StorageTexture ImageFormat: "
<< static_cast<int>(storage->image_format());
return false;
}
out << "<" << component << ">";
} else if (depth_ms) {
out << "<float4>";
} else if (sampled || ms) {
auto* subtype = sampled ? sampled->type() : ms->type();
out << "<";
if (subtype->Is<sem::F32>()) {
out << "float4";
} else if (subtype->Is<sem::I32>()) {
out << "int4";
} else if (subtype->Is<sem::U32>()) {
out << "uint4";
} else {
TINT_ICE(Writer, diagnostics_)
<< "Unsupported multisampled texture type";
return false;
}
out << ">";
}
} else if (type->Is<sem::U32>()) {
out << "uint";
} else if (auto* vec = type->As<sem::Vector>()) {

View File

@ -81,151 +81,151 @@ ExpectedResult expected_texture_overload(
case ValidTextureOverload::kNumSamplesMultisampled2d:
return {"textureSamples"};
case ValidTextureOverload::kSample1dF32:
return R"(texture.Sample(sampler, 1.0f);)";
return R"(texture(tint_symbol, 1.0f);)";
case ValidTextureOverload::kSample2dF32:
return R"(texture.Sample(sampler, vec2(1.0f, 2.0f));)";
return R"(texture(tint_symbol, vec2(1.0f, 2.0f));)";
case ValidTextureOverload::kSample2dOffsetF32:
return R"(texture.Sample(sampler, vec2(1.0f, 2.0f), ivec2(3, 4));)";
return R"(texture(tint_symbol, vec2(1.0f, 2.0f), ivec2(3, 4));)";
case ValidTextureOverload::kSample2dArrayF32:
return R"(texture.Sample(sampler, vec3(1.0f, 2.0f, float(3)));)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(3)));)";
case ValidTextureOverload::kSample2dArrayOffsetF32:
return R"(texture.Sample(sampler, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5));)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5));)";
case ValidTextureOverload::kSample3dF32:
return R"(texture.Sample(sampler, vec3(1.0f, 2.0f, 3.0f));)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f));)";
case ValidTextureOverload::kSample3dOffsetF32:
return R"(texture.Sample(sampler, vec3(1.0f, 2.0f, 3.0f), ivec3(4, 5, 6));)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), ivec3(4, 5, 6));)";
case ValidTextureOverload::kSampleCubeF32:
return R"(texture.Sample(sampler, vec3(1.0f, 2.0f, 3.0f));)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f));)";
case ValidTextureOverload::kSampleCubeArrayF32:
return R"(texture.Sample(sampler, vec4(1.0f, 2.0f, 3.0f, float(4)));)";
return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)));)";
case ValidTextureOverload::kSampleDepth2dF32:
return R"(texture.Sample(sampler, vec2(1.0f, 2.0f)).x;)";
return R"(texture(tint_symbol, vec2(1.0f, 2.0f)).x;)";
case ValidTextureOverload::kSampleDepth2dOffsetF32:
return R"(texture.Sample(sampler, vec2(1.0f, 2.0f), ivec2(3, 4)).x;)";
return R"(texture(tint_symbol, vec2(1.0f, 2.0f), ivec2(3, 4)).x;)";
case ValidTextureOverload::kSampleDepth2dArrayF32:
return R"(texture.Sample(sampler, vec3(1.0f, 2.0f, float(3))).x;)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(3))).x;)";
case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
return R"(texture.Sample(sampler, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5)).x;)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5)).x;)";
case ValidTextureOverload::kSampleDepthCubeF32:
return R"(texture.Sample(sampler, vec3(1.0f, 2.0f, 3.0f)).x;)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f)).x;)";
case ValidTextureOverload::kSampleDepthCubeArrayF32:
return R"(texture.Sample(sampler, vec4(1.0f, 2.0f, 3.0f, float(4))).x;)";
return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4))).x;)";
case ValidTextureOverload::kSampleBias2dF32:
return R"(texture.SampleBias(sampler, vec2(1.0f, 2.0f), 3.0f);)";
return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f);)";
case ValidTextureOverload::kSampleBias2dOffsetF32:
return R"(texture.SampleBias(sampler, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
case ValidTextureOverload::kSampleBias2dArrayF32:
return R"(texture.SampleBias(sampler, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
case ValidTextureOverload::kSampleBias2dArrayOffsetF32:
return R"(texture.SampleBias(sampler, vec3(1.0f, 2.0f, float(3)), 4.0f, ivec2(5, 6));)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4.0f, ivec2(5, 6));)";
case ValidTextureOverload::kSampleBias3dF32:
return R"(texture.SampleBias(sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
case ValidTextureOverload::kSampleBias3dOffsetF32:
return R"(texture.SampleBias(sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f, ivec3(5, 6, 7));)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f, ivec3(5, 6, 7));)";
case ValidTextureOverload::kSampleBiasCubeF32:
return R"(texture.SampleBias(sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
case ValidTextureOverload::kSampleBiasCubeArrayF32:
return R"(texture.SampleBias(sampler, vec4(1.0f, 2.0f, 3.0f, float(3)), 4.0f);)";
return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(3)), 4.0f);)";
case ValidTextureOverload::kSampleLevel2dF32:
return R"(texture.SampleLevel(sampler, vec2(1.0f, 2.0f), 3.0f);)";
return R"(textureLod(tint_symbol, vec2(1.0f, 2.0f), 3.0f);)";
case ValidTextureOverload::kSampleLevel2dOffsetF32:
return R"(texture.SampleLevel(sampler, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
return R"(textureLod(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
case ValidTextureOverload::kSampleLevel2dArrayF32:
return R"(texture.SampleLevel(sampler, vec3(1.0f, 2.0f, float(3)), 4.0f);)";
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4.0f);)";
case ValidTextureOverload::kSampleLevel2dArrayOffsetF32:
return R"(texture.SampleLevel(sampler, vec3(1.0f, 2.0f, float(3)), 4.0f, ivec2(5, 6));)";
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4.0f, ivec2(5, 6));)";
case ValidTextureOverload::kSampleLevel3dF32:
return R"(texture.SampleLevel(sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
case ValidTextureOverload::kSampleLevel3dOffsetF32:
return R"(texture.SampleLevel(sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f, ivec3(5, 6, 7));)";
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f, ivec3(5, 6, 7));)";
case ValidTextureOverload::kSampleLevelCubeF32:
return R"(texture.SampleLevel(sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
case ValidTextureOverload::kSampleLevelCubeArrayF32:
return R"(texture.SampleLevel(sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
return R"(textureLod(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
case ValidTextureOverload::kSampleLevelDepth2dF32:
return R"(texture.SampleLevel(sampler, vec2(1.0f, 2.0f), 3).x;)";
return R"(textureLod(tint_symbol, vec2(1.0f, 2.0f), 3).x;)";
case ValidTextureOverload::kSampleLevelDepth2dOffsetF32:
return R"(texture.SampleLevel(sampler, vec2(1.0f, 2.0f), 3, ivec2(4, 5)).x;)";
return R"(textureLod(tint_symbol, vec2(1.0f, 2.0f), 3, ivec2(4, 5)).x;)";
case ValidTextureOverload::kSampleLevelDepth2dArrayF32:
return R"(texture.SampleLevel(sampler, vec3(1.0f, 2.0f, float(3)), 4).x;)";
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4).x;)";
case ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32:
return R"(texture.SampleLevel(sampler, vec3(1.0f, 2.0f, float(3)), 4, ivec2(5, 6)).x;)";
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, float(3)), 4, ivec2(5, 6)).x;)";
case ValidTextureOverload::kSampleLevelDepthCubeF32:
return R"(texture.SampleLevel(sampler, vec3(1.0f, 2.0f, 3.0f), 4).x;)";
return R"(textureLod(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4).x;)";
case ValidTextureOverload::kSampleLevelDepthCubeArrayF32:
return R"(texture.SampleLevel(sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 5).x;)";
return R"(textureLod(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5).x;)";
case ValidTextureOverload::kSampleGrad2dF32:
return R"(texture.SampleGrad(sampler, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f));)";
return R"(textureGrad(tint_symbol, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f));)";
case ValidTextureOverload::kSampleGrad2dOffsetF32:
return R"(texture.SampleGrad(sampler, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f), ivec2(7, 7));)";
return R"(textureGrad(tint_symbol, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f), ivec2(7, 7));)";
case ValidTextureOverload::kSampleGrad2dArrayF32:
return R"(texture.SampleGrad(sampler, vec3(1.0f, 2.0f, float(3)), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f));)";
return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, float(3)), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f));)";
case ValidTextureOverload::kSampleGrad2dArrayOffsetF32:
return R"(texture.SampleGrad(sampler, vec3(1.0f, 2.0f, float(3)), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f), ivec2(6, 7));)";
return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, float(3)), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f), ivec2(6, 7));)";
case ValidTextureOverload::kSampleGrad3dF32:
return R"(texture.SampleGrad(sampler, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));)";
return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));)";
case ValidTextureOverload::kSampleGrad3dOffsetF32:
return R"(texture.SampleGrad(sampler, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f), ivec3(0, 1, 2));)";
return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f), ivec3(0, 1, 2));)";
case ValidTextureOverload::kSampleGradCubeF32:
return R"(texture.SampleGrad(sampler, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));)";
return R"(textureGrad(tint_symbol, vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));)";
case ValidTextureOverload::kSampleGradCubeArrayF32:
return R"(texture.SampleGrad(sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), vec3(5.0f, 6.0f, 7.0f), vec3(8.0f, 9.0f, 10.0f));)";
return R"(textureGrad(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), vec3(5.0f, 6.0f, 7.0f), vec3(8.0f, 9.0f, 10.0f));)";
case ValidTextureOverload::kSampleCompareDepth2dF32:
return R"(texture.SampleCmp(sampler, vec2(1.0f, 2.0f), 3.0f);)";
return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f);)";
case ValidTextureOverload::kSampleCompareDepth2dOffsetF32:
return R"(texture.SampleCmp(sampler, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
case ValidTextureOverload::kSampleCompareDepth2dArrayF32:
return R"(texture.SampleCmp(sampler, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
case ValidTextureOverload::kSampleCompareDepth2dArrayOffsetF32:
return R"(texture.SampleCmp(sampler, vec3(1.0f, 2.0f, float(4)), 3.0f, ivec2(5, 6));)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f, ivec2(5, 6));)";
case ValidTextureOverload::kSampleCompareDepthCubeF32:
return R"(texture.SampleCmp(sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
case ValidTextureOverload::kSampleCompareDepthCubeArrayF32:
return R"(texture.SampleCmp(sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
case ValidTextureOverload::kSampleCompareLevelDepth2dF32:
return R"(texture.SampleCmpLevelZero(sampler, vec2(1.0f, 2.0f), 3.0f);)";
return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f);)";
case ValidTextureOverload::kSampleCompareLevelDepth2dOffsetF32:
return R"(texture.SampleCmpLevelZero(sampler, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
return R"(texture(tint_symbol, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
case ValidTextureOverload::kSampleCompareLevelDepth2dArrayF32:
return R"(texture.SampleCmpLevelZero(sampler, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
case ValidTextureOverload::kSampleCompareLevelDepth2dArrayOffsetF32:
return R"(texture.SampleCmpLevelZero(sampler, vec3(1.0f, 2.0f, float(4)), 3.0f, ivec2(5, 6));)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, float(4)), 3.0f, ivec2(5, 6));)";
case ValidTextureOverload::kSampleCompareLevelDepthCubeF32:
return R"(texture.SampleCmpLevelZero(sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
return R"(texture(tint_symbol, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
case ValidTextureOverload::kSampleCompareLevelDepthCubeArrayF32:
return R"(texture.SampleCmpLevelZero(sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
return R"(texture(tint_symbol, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
case ValidTextureOverload::kLoad1dLevelF32:
case ValidTextureOverload::kLoad1dLevelU32:
case ValidTextureOverload::kLoad1dLevelI32:
return R"(texture.Load(ivec2(1, 3));)";
return R"(texelFetch(tint_symbol, ivec2(1, 3));)";
case ValidTextureOverload::kLoad2dLevelF32:
case ValidTextureOverload::kLoad2dLevelU32:
case ValidTextureOverload::kLoad2dLevelI32:
return R"(texture.Load(ivec3(1, 2, 3));)";
return R"(texelFetch(tint_symbol, ivec3(1, 2, 3));)";
case ValidTextureOverload::kLoad2dArrayLevelF32:
case ValidTextureOverload::kLoad2dArrayLevelU32:
case ValidTextureOverload::kLoad2dArrayLevelI32:
case ValidTextureOverload::kLoad3dLevelF32:
case ValidTextureOverload::kLoad3dLevelU32:
case ValidTextureOverload::kLoad3dLevelI32:
return R"(texture.Load(ivec4(1, 2, 3, 4));)";
return R"(texelFetch(tint_symbol, ivec4(1, 2, 3, 4));)";
case ValidTextureOverload::kLoadDepthMultisampled2dF32:
case ValidTextureOverload::kLoadMultisampled2dF32:
case ValidTextureOverload::kLoadMultisampled2dU32:
case ValidTextureOverload::kLoadMultisampled2dI32:
return R"(texture.Load(ivec2(1, 2), 3);)";
return R"(texelFetch(tint_symbol, ivec2(1, 2), 3);)";
case ValidTextureOverload::kLoadDepth2dLevelF32:
return R"(texture.Load(ivec3(1, 2, 3)).x;)";
return R"(texelFetch(tint_symbol, ivec3(1, 2, 3)).x;)";
case ValidTextureOverload::kLoadDepth2dArrayLevelF32:
return R"(texture.Load(ivec4(1, 2, 3, 4)).x;)";
return R"(texelFetch(tint_symbol, ivec4(1, 2, 3, 4)).x;)";
case ValidTextureOverload::kStoreWO1dRgba32float:
return R"(texture[1] = vec4(2.0f, 3.0f, 4.0f, 5.0f);)";
return R"(imageStore(tint_symbol, 1, vec4(2.0f, 3.0f, 4.0f, 5.0f)).x;)";
case ValidTextureOverload::kStoreWO2dRgba32float:
return R"(texture[ivec2(1, 2)] = vec4(3.0f, 4.0f, 5.0f, 6.0f);)";
return R"(imageStore(tint_symbol, ivec2(1, 2), vec4(3.0f, 4.0f, 5.0f, 6.0f)).x;)";
case ValidTextureOverload::kStoreWO2dArrayRgba32float:
return R"(texture[ivec3(1, 2, 3)] = vec4(4.0f, 5.0f, 6.0f, 7.0f);)";
return R"(imageStore(tint_symbol, ivec3(1, 2, 3), vec4(4.0f, 5.0f, 6.0f, 7.0f)).x;)";
case ValidTextureOverload::kStoreWO3dRgba32float:
return R"(texture[ivec3(1, 2, 3)] = vec4(4.0f, 5.0f, 6.0f, 7.0f);)";
return R"(imageStore(tint_symbol, ivec3(1, 2, 3), vec4(4.0f, 5.0f, 6.0f, 7.0f)).x;)";
}
return "<unmatched texture overload>";
} // NOLINT - Ignore the length of this function

View File

@ -281,10 +281,9 @@ TEST_F(GlslGeneratorImplTest_Type, EmitSampler) {
GeneratorImpl& gen = Build();
std::stringstream out;
ASSERT_TRUE(gen.EmitType(out, sampler, ast::StorageClass::kNone,
ASSERT_FALSE(gen.EmitType(out, sampler, ast::StorageClass::kNone,
ast::Access::kReadWrite, ""))
<< gen.error();
EXPECT_EQ(out.str(), "SamplerState");
}
TEST_F(GlslGeneratorImplTest_Type, EmitSamplerComparison) {
@ -293,10 +292,9 @@ TEST_F(GlslGeneratorImplTest_Type, EmitSamplerComparison) {
GeneratorImpl& gen = Build();
std::stringstream out;
ASSERT_TRUE(gen.EmitType(out, sampler, ast::StorageClass::kNone,
ASSERT_FALSE(gen.EmitType(out, sampler, ast::StorageClass::kNone,
ast::Access::kReadWrite, ""))
<< gen.error();
EXPECT_EQ(out.str(), "SamplerComparisonState");
}
struct GlslDepthTextureData {
@ -331,12 +329,12 @@ INSTANTIATE_TEST_SUITE_P(
GlslGeneratorImplTest_Type,
GlslDepthTexturesTest,
testing::Values(
GlslDepthTextureData{ast::TextureDimension::k2d, "Texture2D tex;"},
GlslDepthTextureData{ast::TextureDimension::k2d, "sampler2D tex;"},
GlslDepthTextureData{ast::TextureDimension::k2dArray,
"Texture2DArray tex;"},
GlslDepthTextureData{ast::TextureDimension::kCube, "TextureCube tex;"},
"sampler2DArray tex;"},
GlslDepthTextureData{ast::TextureDimension::kCube, "samplerCube tex;"},
GlslDepthTextureData{ast::TextureDimension::kCubeArray,
"TextureCubeArray tex;"}));
"samplerCubeArray tex;"}));
using GlslDepthMultisampledTexturesTest = TestHelper;
TEST_F(GlslDepthMultisampledTexturesTest, Emit) {
@ -354,7 +352,7 @@ TEST_F(GlslDepthMultisampledTexturesTest, Emit) {
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_THAT(gen.result(), HasSubstr("Texture2DMS<float4> tex;"));
EXPECT_THAT(gen.result(), HasSubstr("sampler2DMS tex;"));
}
enum class TextureDataType { F32, U32, I32 };
@ -406,92 +404,92 @@ INSTANTIATE_TEST_SUITE_P(GlslGeneratorImplTest_Type,
GlslSampledTextureData{
ast::TextureDimension::k1d,
TextureDataType::F32,
"Texture1D<float4> tex;",
"sampler1D tex;",
},
GlslSampledTextureData{
ast::TextureDimension::k2d,
TextureDataType::F32,
"Texture2D<float4> tex;",
"sampler2D tex;",
},
GlslSampledTextureData{
ast::TextureDimension::k2dArray,
TextureDataType::F32,
"Texture2DArray<float4> tex;",
"sampler2DArray tex;",
},
GlslSampledTextureData{
ast::TextureDimension::k3d,
TextureDataType::F32,
"Texture3D<float4> tex;",
"sampler3D tex;",
},
GlslSampledTextureData{
ast::TextureDimension::kCube,
TextureDataType::F32,
"TextureCube<float4> tex;",
"samplerCube tex;",
},
GlslSampledTextureData{
ast::TextureDimension::kCubeArray,
TextureDataType::F32,
"TextureCubeArray<float4> tex;",
"samplerCubeArray tex;",
},
GlslSampledTextureData{
ast::TextureDimension::k1d,
TextureDataType::U32,
"Texture1D<uint4> tex;",
"usampler1D tex;",
},
GlslSampledTextureData{
ast::TextureDimension::k2d,
TextureDataType::U32,
"Texture2D<uint4> tex;",
"usampler2D tex;",
},
GlslSampledTextureData{
ast::TextureDimension::k2dArray,
TextureDataType::U32,
"Texture2DArray<uint4> tex;",
"usampler2DArray tex;",
},
GlslSampledTextureData{
ast::TextureDimension::k3d,
TextureDataType::U32,
"Texture3D<uint4> tex;",
"usampler3D tex;",
},
GlslSampledTextureData{
ast::TextureDimension::kCube,
TextureDataType::U32,
"TextureCube<uint4> tex;",
"usamplerCube tex;",
},
GlslSampledTextureData{
ast::TextureDimension::kCubeArray,
TextureDataType::U32,
"TextureCubeArray<uint4> tex;",
"usamplerCubeArray tex;",
},
GlslSampledTextureData{
ast::TextureDimension::k1d,
TextureDataType::I32,
"Texture1D<int4> tex;",
"isampler1D tex;",
},
GlslSampledTextureData{
ast::TextureDimension::k2d,
TextureDataType::I32,
"Texture2D<int4> tex;",
"isampler2D tex;",
},
GlslSampledTextureData{
ast::TextureDimension::k2dArray,
TextureDataType::I32,
"Texture2DArray<int4> tex;",
"isampler2DArray tex;",
},
GlslSampledTextureData{
ast::TextureDimension::k3d,
TextureDataType::I32,
"Texture3D<int4> tex;",
"isampler3D tex;",
},
GlslSampledTextureData{
ast::TextureDimension::kCube,
TextureDataType::I32,
"TextureCube<int4> tex;",
"isamplerCube tex;",
},
GlslSampledTextureData{
ast::TextureDimension::kCubeArray,
TextureDataType::I32,
"TextureCubeArray<int4> tex;",
"isamplerCubeArray tex;",
}));
TEST_F(GlslGeneratorImplTest_Type, EmitMultisampledTexture) {
@ -504,7 +502,7 @@ TEST_F(GlslGeneratorImplTest_Type, EmitMultisampledTexture) {
ASSERT_TRUE(gen.EmitType(out, s, ast::StorageClass::kNone,
ast::Access::kReadWrite, ""))
<< gen.error();
EXPECT_EQ(out.str(), "Texture2DMS<float4>");
EXPECT_EQ(out.str(), "uniform highp sampler2DMS");
}
struct GlslStorageTextureData {
@ -539,45 +537,34 @@ TEST_P(GlslStorageTexturesTest, Emit) {
INSTANTIATE_TEST_SUITE_P(
GlslGeneratorImplTest_Type,
GlslStorageTexturesTest,
testing::Values(GlslStorageTextureData{ast::TextureDimension::k1d,
ast::ImageFormat::kRgba8Unorm,
"RWTexture1D<float4> tex;"},
testing::Values(
GlslStorageTextureData{ast::TextureDimension::k1d,
ast::ImageFormat::kRgba8Unorm, "image1D tex;"},
GlslStorageTextureData{ast::TextureDimension::k2d,
ast::ImageFormat::kRgba16Float,
"RWTexture2D<float4> tex;"},
ast::ImageFormat::kRgba16Float, "image2D tex;"},
GlslStorageTextureData{ast::TextureDimension::k2dArray,
ast::ImageFormat::kR32Float,
"RWTexture2DArray<float4> tex;"},
"image2DArray tex;"},
GlslStorageTextureData{ast::TextureDimension::k3d,
ast::ImageFormat::kRg32Float,
"RWTexture3D<float4> tex;"},
ast::ImageFormat::kRg32Float, "image3D tex;"},
GlslStorageTextureData{ast::TextureDimension::k1d,
ast::ImageFormat::kRgba32Float,
"RWTexture1D<float4> tex;"},
ast::ImageFormat::kRgba32Float, "image1D tex;"},
GlslStorageTextureData{ast::TextureDimension::k2d,
ast::ImageFormat::kRgba16Uint,
"RWTexture2D<uint4> tex;"},
ast::ImageFormat::kRgba16Uint, "image2D tex;"},
GlslStorageTextureData{ast::TextureDimension::k2dArray,
ast::ImageFormat::kR32Uint,
"RWTexture2DArray<uint4> tex;"},
ast::ImageFormat::kR32Uint, "image2DArray tex;"},
GlslStorageTextureData{ast::TextureDimension::k3d,
ast::ImageFormat::kRg32Uint,
"RWTexture3D<uint4> tex;"},
ast::ImageFormat::kRg32Uint, "image3D tex;"},
GlslStorageTextureData{ast::TextureDimension::k1d,
ast::ImageFormat::kRgba32Uint,
"RWTexture1D<uint4> tex;"},
ast::ImageFormat::kRgba32Uint, "image1D tex;"},
GlslStorageTextureData{ast::TextureDimension::k2d,
ast::ImageFormat::kRgba16Sint,
"RWTexture2D<int4> tex;"},
ast::ImageFormat::kRgba16Sint, "image2D tex;"},
GlslStorageTextureData{ast::TextureDimension::k2dArray,
ast::ImageFormat::kR32Sint,
"RWTexture2DArray<int4> tex;"},
ast::ImageFormat::kR32Sint, "image2DArray tex;"},
GlslStorageTextureData{ast::TextureDimension::k3d,
ast::ImageFormat::kRg32Sint,
"RWTexture3D<int4> tex;"},
ast::ImageFormat::kRg32Sint, "image3D tex;"},
GlslStorageTextureData{ast::TextureDimension::k1d,
ast::ImageFormat::kRgba32Sint,
"RWTexture1D<int4> tex;"}));
ast::ImageFormat::kRgba32Sint, "image1D tex;"}));
} // namespace
} // namespace glsl