Skip to content

Commit 51cdcad

Browse files
author
Tim Foley
authored
stdlib fixes for Vulkan (shader-slang#414)
* stdlib fixes for Vulkan - Make sure to emit `image*` instead of `texture*` for `RWTexture*` types - Change `GetDimensions` to call `imageSize` instead of `textureSize` when we use images - Always output a `layout(rgba32f)` for variables that translate to `image` types - TODO: we should emit an appropriate format based on the type, or let the user specify one - Fix GLSL translation for `any()` function (required boolean inputs) - Add GLSL translation for `GroupMemoryBarrierWithGroupSync()` - Map HLSL `groupshared` to GLSL `shared` These together are enough to get the Falor `ComputeShader` example to work. * fixup for warning
1 parent 8c87259 commit 51cdcad

File tree

5 files changed

+219
-61
lines changed

5 files changed

+219
-61
lines changed

source/slang/core.meta.slang

+48-17
Original file line numberDiff line numberDiff line change
@@ -462,34 +462,47 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
462462
sb << "__target_intrinsic(glsl, \"(";
463463

464464
int aa = 1;
465-
String lodStr = "0";
465+
String lodStr = ", 0";
466466
if (includeMipInfo)
467467
{
468468
int mipLevelArg = aa++;
469-
lodStr = "int($";
469+
lodStr = ", int($";
470470
lodStr.append(mipLevelArg);
471471
lodStr.append(")");
472472
}
473473

474+
String opStr = " = textureSize($$P" + lodStr;
475+
switch( access )
476+
{
477+
case SLANG_RESOURCE_ACCESS_READ_WRITE:
478+
case SLANG_RESOURCE_ACCESS_RASTER_ORDERED:
479+
opStr = " = imageSize($0";
480+
break;
481+
482+
default:
483+
break;
484+
}
485+
486+
474487
int cc = 0;
475488
switch(baseShape)
476489
{
477490
case TextureType::Shape1D:
478-
sb << "($" << aa++ << " = textureSize($$P, " << lodStr << "))";
491+
sb << "($" << aa++ << opStr << "))";
479492
cc = 1;
480493
break;
481494

482495
case TextureType::Shape2D:
483496
case TextureType::ShapeCube:
484-
sb << "($" << aa++ << " = textureSize($$P, " << lodStr << ").x)";
485-
sb << ", ($" << aa++ << " = textureSize($$P, " << lodStr << ").y)";
497+
sb << "($" << aa++ << opStr << ").x)";
498+
sb << ", ($" << aa++ << opStr << ").y)";
486499
cc = 2;
487500
break;
488501

489502
case TextureType::Shape3D:
490-
sb << "($" << aa++ << " = textureSize($$P, " << lodStr << ").x)";
491-
sb << ", ($" << aa++ << " = textureSize($$P, " << lodStr << ").y)";
492-
sb << ", ($" << aa++ << " = textureSize($$P, " << lodStr << ").z)";
503+
sb << "($" << aa++ << opStr << ").x)";
504+
sb << ", ($" << aa++ << opStr << ").y)";
505+
sb << ", ($" << aa++ << opStr << ").z)";
493506
cc = 3;
494507
break;
495508

@@ -500,7 +513,7 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
500513

501514
if(isArray)
502515
{
503-
sb << ", ($" << aa++ << " = textureSize($$P, " << lodStr << ")." << kComponentNames[cc] << ")";
516+
sb << ", ($" << aa++ << opStr << ")." << kComponentNames[cc] << ")";
504517
}
505518

506519
if(isMultisample)
@@ -627,13 +640,30 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
627640

628641
if(baseShape != TextureType::ShapeCube)
629642
{
643+
int N = kBaseTextureTypes[tt].coordCount + isArray;
644+
645+
char const* uintNs[] = { "", "uint", "uint2", "uint3", "uint4" };
646+
char const* ivecNs[] = { "", "int", "ivec2", "ivec3", "ivec4" };
647+
648+
auto uintN = uintNs[N];
649+
auto ivecN = ivecNs[N];
650+
630651
// subscript operator
631-
sb << "__subscript(uint";
632-
if(kBaseTextureTypes[tt].coordCount + isArray > 1)
633-
{
634-
sb << kBaseTextureTypes[tt].coordCount + isArray;
635-
}
636-
sb << " location) -> T";
652+
sb << "__subscript(" << uintN << " location) -> T {\n";
653+
654+
sb << "__target_intrinsic(glsl, \"texelFetch($$P, " << ivecN << "($1)";
655+
656+
if( !isMultisample )
657+
{
658+
sb << ", 0";
659+
}
660+
else
661+
{
662+
// TODO: how to handle this...
663+
sb << ", 0";
664+
}
665+
666+
sb << ")$$z\") get;\n";
637667

638668
// Depending on the access level of the texture type,
639669
// we either have just a getter (the default), or both
@@ -642,13 +672,14 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
642672
{
643673
case SLANG_RESOURCE_ACCESS_NONE:
644674
case SLANG_RESOURCE_ACCESS_READ:
645-
sb << ";\n";
646675
break;
647676

648677
default:
649-
sb << " { get; set; }\n";
678+
sb << "__target_intrinsic(glsl, \"imageStore($0, " << ivecN << "($1), $2)\") set;\n";
650679
break;
651680
}
681+
682+
sb << "}\n";
652683
}
653684

654685
if( !isMultisample )

source/slang/core.meta.slang.h

+48-17
Original file line numberDiff line numberDiff line change
@@ -465,34 +465,47 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
465465
sb << "__target_intrinsic(glsl, \"(";
466466

467467
int aa = 1;
468-
String lodStr = "0";
468+
String lodStr = ", 0";
469469
if (includeMipInfo)
470470
{
471471
int mipLevelArg = aa++;
472-
lodStr = "int($";
472+
lodStr = ", int($";
473473
lodStr.append(mipLevelArg);
474474
lodStr.append(")");
475475
}
476476

477+
String opStr = " = textureSize($P" + lodStr;
478+
switch( access )
479+
{
480+
case SLANG_RESOURCE_ACCESS_READ_WRITE:
481+
case SLANG_RESOURCE_ACCESS_RASTER_ORDERED:
482+
opStr = " = imageSize($0";
483+
break;
484+
485+
default:
486+
break;
487+
}
488+
489+
477490
int cc = 0;
478491
switch(baseShape)
479492
{
480493
case TextureType::Shape1D:
481-
sb << "($" << aa++ << " = textureSize($P, " << lodStr << "))";
494+
sb << "($" << aa++ << opStr << "))";
482495
cc = 1;
483496
break;
484497

485498
case TextureType::Shape2D:
486499
case TextureType::ShapeCube:
487-
sb << "($" << aa++ << " = textureSize($P, " << lodStr << ").x)";
488-
sb << ", ($" << aa++ << " = textureSize($P, " << lodStr << ").y)";
500+
sb << "($" << aa++ << opStr << ").x)";
501+
sb << ", ($" << aa++ << opStr << ").y)";
489502
cc = 2;
490503
break;
491504

492505
case TextureType::Shape3D:
493-
sb << "($" << aa++ << " = textureSize($P, " << lodStr << ").x)";
494-
sb << ", ($" << aa++ << " = textureSize($P, " << lodStr << ").y)";
495-
sb << ", ($" << aa++ << " = textureSize($P, " << lodStr << ").z)";
506+
sb << "($" << aa++ << opStr << ").x)";
507+
sb << ", ($" << aa++ << opStr << ").y)";
508+
sb << ", ($" << aa++ << opStr << ").z)";
496509
cc = 3;
497510
break;
498511

@@ -503,7 +516,7 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
503516

504517
if(isArray)
505518
{
506-
sb << ", ($" << aa++ << " = textureSize($P, " << lodStr << ")." << kComponentNames[cc] << ")";
519+
sb << ", ($" << aa++ << opStr << ")." << kComponentNames[cc] << ")";
507520
}
508521

509522
if(isMultisample)
@@ -630,13 +643,30 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
630643

631644
if(baseShape != TextureType::ShapeCube)
632645
{
646+
int N = kBaseTextureTypes[tt].coordCount + isArray;
647+
648+
char const* uintNs[] = { "", "uint", "uint2", "uint3", "uint4" };
649+
char const* ivecNs[] = { "", "int", "ivec2", "ivec3", "ivec4" };
650+
651+
auto uintN = uintNs[N];
652+
auto ivecN = ivecNs[N];
653+
633654
// subscript operator
634-
sb << "__subscript(uint";
635-
if(kBaseTextureTypes[tt].coordCount + isArray > 1)
636-
{
637-
sb << kBaseTextureTypes[tt].coordCount + isArray;
638-
}
639-
sb << " location) -> T";
655+
sb << "__subscript(" << uintN << " location) -> T {\n";
656+
657+
sb << "__target_intrinsic(glsl, \"texelFetch($P, " << ivecN << "($1)";
658+
659+
if( !isMultisample )
660+
{
661+
sb << ", 0";
662+
}
663+
else
664+
{
665+
// TODO: how to handle this...
666+
sb << ", 0";
667+
}
668+
669+
sb << ")$z\") get;\n";
640670

641671
// Depending on the access level of the texture type,
642672
// we either have just a getter (the default), or both
@@ -645,13 +675,14 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
645675
{
646676
case SLANG_RESOURCE_ACCESS_NONE:
647677
case SLANG_RESOURCE_ACCESS_READ:
648-
sb << ";\n";
649678
break;
650679

651680
default:
652-
sb << " { get; set; }\n";
681+
sb << "__target_intrinsic(glsl, \"imageStore($0, " << ivecN << "($1), $2)\") set;\n";
653682
break;
654683
}
684+
685+
sb << "}\n";
655686
}
656687

657688
if( !isMultisample )

source/slang/emit.cpp

+80-7
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,17 @@ struct EmitVisitor
10151015
void emitGLSLTextureType(
10161016
RefPtr<TextureType> texType)
10171017
{
1018-
emitGLSLTextureOrTextureSamplerType(texType, "texture");
1018+
switch(texType->getAccess())
1019+
{
1020+
case SLANG_RESOURCE_ACCESS_READ_WRITE:
1021+
case SLANG_RESOURCE_ACCESS_RASTER_ORDERED:
1022+
emitGLSLTextureOrTextureSamplerType(texType, "image");
1023+
break;
1024+
1025+
default:
1026+
emitGLSLTextureOrTextureSamplerType(texType, "texture");
1027+
break;
1028+
}
10191029
}
10201030

10211031
void emitGLSLTextureSamplerType(
@@ -1289,7 +1299,19 @@ struct EmitVisitor
12891299

12901300
void visitGroupSharedType(GroupSharedType* type, TypeEmitArg const& arg)
12911301
{
1292-
Emit("groupshared ");
1302+
switch(getTarget(context))
1303+
{
1304+
case CodeGenTarget::HLSL:
1305+
Emit("groupshared ");
1306+
break;
1307+
1308+
case CodeGenTarget::GLSL:
1309+
Emit("shared ");
1310+
break;
1311+
1312+
default:
1313+
break;
1314+
}
12931315
emitTypeImpl(type->valueType, arg.declarator);
12941316
}
12951317

@@ -2275,7 +2297,6 @@ struct EmitVisitor
22752297
}
22762298
break;
22772299

2278-
22792300
default:
22802301
SLANG_UNEXPECTED("bad format in intrinsic definition");
22812302
break;
@@ -5454,6 +5475,28 @@ emitDeclImpl(decl, nullptr);
54545475
}
54555476
break;
54565477

5478+
case 'N':
5479+
{
5480+
// Extract the element count from a vector argument so that
5481+
// we can use it in the constructed expression.
5482+
5483+
SLANG_RELEASE_ASSERT(*cursor >= '0' && *cursor <= '9');
5484+
UInt argIndex = (*cursor++) - '0';
5485+
SLANG_RELEASE_ASSERT(argCount > argIndex);
5486+
5487+
auto vectorArg = args[argIndex].get();
5488+
if (auto vectorType = vectorArg->type->As<VectorExpressionType>())
5489+
{
5490+
auto elementCount = GetIntVal(vectorType->elementCount);
5491+
Emit(elementCount);
5492+
}
5493+
else
5494+
{
5495+
SLANG_UNEXPECTED("bad format in intrinsic definition");
5496+
}
5497+
}
5498+
break;
5499+
54575500

54585501
default:
54595502
SLANG_UNEXPECTED("bad format in intrinsic definition");
@@ -7090,13 +7133,43 @@ emitDeclImpl(decl, nullptr);
70907133

70917134
void emitIRVarModifiers(
70927135
EmitContext* ctx,
7093-
VarLayout* layout)
7136+
VarLayout* layout,
7137+
Type* valueType)
70947138
{
70957139
if (!layout)
70967140
return;
70977141

70987142
emitIRMatrixLayoutModifiers(ctx, layout);
70997143

7144+
// As a special case, if we are emitting a GLSL declaration
7145+
// for an HLSL `RWTexture*` then we need to emit a `format` layout qualifier.
7146+
if(getTarget(context) == CodeGenTarget::GLSL)
7147+
{
7148+
if(auto resourceType = unwrapArray(valueType).As<TextureType>())
7149+
{
7150+
switch(resourceType->getAccess())
7151+
{
7152+
case SLANG_RESOURCE_ACCESS_READ_WRITE:
7153+
case SLANG_RESOURCE_ACCESS_RASTER_ORDERED:
7154+
{
7155+
// TODO: at this point we need to look at the element
7156+
// type and figure out what format we want.
7157+
//
7158+
// For now just hack it and assume a fixed format.
7159+
Emit("layout(rgba32f)");
7160+
7161+
// TODO: we also need a way for users to specify what
7162+
// the format should be explicitly, to avoid having
7163+
// to have us infer things...
7164+
}
7165+
break;
7166+
7167+
default:
7168+
break;
7169+
}
7170+
}
7171+
}
7172+
71007173
if (ctx->shared->target == CodeGenTarget::GLSL)
71017174
{
71027175
// Layout-related modifiers need to come before the declaration,
@@ -7238,7 +7311,7 @@ emitDeclImpl(decl, nullptr);
72387311
if(fieldType->Equals(getSession()->getVoidType()))
72397312
continue;
72407313

7241-
emitIRVarModifiers(ctx, fieldLayout);
7314+
emitIRVarModifiers(ctx, fieldLayout, fieldType);
72427315

72437316
emitIRType(ctx, fieldType, getIRName(ff));
72447317

@@ -7444,7 +7517,7 @@ emitDeclImpl(decl, nullptr);
74447517

74457518
auto layout = getVarLayout(ctx, varDecl);
74467519

7447-
emitIRVarModifiers(ctx, layout);
7520+
emitIRVarModifiers(ctx, layout, varType);
74487521

74497522
#if 0
74507523
switch (addressSpace)
@@ -7597,7 +7670,7 @@ emitDeclImpl(decl, nullptr);
75977670
}
75987671
}
75997672

7600-
emitIRVarModifiers(ctx, layout);
7673+
emitIRVarModifiers(ctx, layout, varType);
76017674

76027675
emitIRType(ctx, varType, getIRName(varDecl));
76037676

0 commit comments

Comments
 (0)