diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-07-17 13:43:58 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-07-17 13:43:58 -0700 |
| commit | 0059ccb3997c2af87bc3f76524d8cd4787c20b7e (patch) | |
| tree | 3c07ad5576737423cd407772a7d23748eb67f090 /source | |
| parent | b4977c1626f9791bc0c84c75e7012ddd7cb40913 (diff) | |
| parent | 453a9ca07417bbc17294267c5e44843d16e93c50 (diff) | |
Merge pull request #111 from tfoleyNV/falcor-shadows-fixes
Falcor shadows fixes
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/emit.cpp | 26 | ||||
| -rw-r--r-- | source/slang/lower.cpp | 240 | ||||
| -rw-r--r-- | source/slang/slang-stdlib.cpp | 107 | ||||
| -rw-r--r-- | source/slang/syntax.h | 4 |
4 files changed, 330 insertions, 47 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 0eb371b88..c6efa88dc 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -1041,7 +1041,7 @@ struct EmitVisitor default: switch (samplerStateType->flavor) { - case SamplerStateType::Flavor::SamplerState: Emit("SamplerState"); break; + case SamplerStateType::Flavor::SamplerState: Emit("SamplerState"); break; case SamplerStateType::Flavor::SamplerComparisonState: Emit("SamplerComparisonState"); break; default: assert(!"unreachable"); @@ -1050,7 +1050,15 @@ struct EmitVisitor break; case CodeGenTarget::GLSL: - Emit("sampler"); + switch (samplerStateType->flavor) + { + case SamplerStateType::Flavor::SamplerState: Emit("sampler"); break; + case SamplerStateType::Flavor::SamplerComparisonState: Emit("samplerShadow"); break; + default: + assert(!"unreachable"); + break; + } + break; break; } @@ -1847,6 +1855,15 @@ struct EmitVisitor if (auto baseTextureType = base->Type->As<TextureType>()) { emitGLSLTextureOrTextureSamplerType(baseTextureType, "sampler"); + + if (auto samplerType = callExpr->Arguments[0]->Type.type->As<SamplerStateType>()) + { + if (samplerType->flavor == SamplerStateType::Flavor::SamplerComparisonState) + { + Emit("Shadow"); + } + } + Emit("("); EmitExpr(memberExpr->BaseExpression); Emit(","); @@ -2683,6 +2700,9 @@ struct EmitVisitor #define CASE2(TYPE, HLSL_NAME, GLSL_NAME) \ else if(auto mod_##TYPE = mod.As<TYPE>()) Emit((context->shared->target == CodeGenTarget::GLSL) ? (#GLSL_NAME " ") : (#HLSL_NAME " ")) + #define CASE2_RAW(TYPE, HLSL_NAME, GLSL_NAME) \ + else if(auto mod_##TYPE = mod.As<TYPE>()) Emit((context->shared->target == CodeGenTarget::GLSL) ? (GLSL_NAME) : (HLSL_NAME)) + CASE(RowMajorLayoutModifier, row_major); CASE(ColumnMajorLayoutModifier, column_major); @@ -2703,7 +2723,7 @@ struct EmitVisitor CASE(HLSLLineAdjModifier, lineadj); CASE(HLSLTriangleAdjModifier, triangleadj); - CASE(HLSLLinearModifier, linear); + CASE2_RAW(HLSLLinearModifier, "linear ", ""); CASE(HLSLSampleModifier, sample); CASE(HLSLCentroidModifier, centroid); diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index 98f6d8273..b6a19ab34 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -616,7 +616,7 @@ struct LoweringVisitor result->tupleElements.Add(elem); } - return result; +return result; } RefPtr<ExpressionSyntaxNode> visitVarExpressionSyntaxNode( @@ -708,6 +708,84 @@ struct LoweringVisitor return loweredExpr; } + RefPtr<ExpressionType> getSubscripResultType( + RefPtr<ExpressionType> type) + { + if (auto arrayType = type->As<ArrayExpressionType>()) + { + return arrayType->BaseType; + } + return nullptr; + } + + RefPtr<ExpressionSyntaxNode> createSubscriptExpr( + RefPtr<ExpressionSyntaxNode> baseExpr, + RefPtr<ExpressionSyntaxNode> indexExpr) + { + // TODO: This logic ends up duplicating the `indexExpr` + // that was given, without worrying about any side + // effects it might contain. That needs to be fixed. + + if (auto baseTuple = baseExpr.As<TupleExpr>()) + { + auto loweredExpr = new TupleExpr(); + loweredExpr->Type.type = getSubscripResultType(baseExpr->Type.type); + + if (auto basePrimary = baseTuple->primaryExpr) + { + loweredExpr->primaryExpr = createSubscriptExpr( + basePrimary, + indexExpr); + } + for (auto elem : baseTuple->tupleElements) + { + TupleExpr::Element loweredElem; + loweredElem.tupleFieldDeclRef = elem.tupleFieldDeclRef; + loweredElem.expr = createSubscriptExpr( + elem.expr, + indexExpr); + + loweredExpr->tupleElements.Add(loweredElem); + } + + return loweredExpr; + } + else + { + // Default case: just reconstrut a subscript expr + auto loweredExpr = new IndexExpressionSyntaxNode(); + + loweredExpr->Type.type = getSubscripResultType(baseExpr->Type.type); + + loweredExpr->BaseExpression = baseExpr; + loweredExpr->IndexExpression = indexExpr; + return loweredExpr; + } + } + + RefPtr<ExpressionSyntaxNode> visitIndexExpressionSyntaxNode( + IndexExpressionSyntaxNode* subscriptExpr) + { + auto baseExpr = lowerExpr(subscriptExpr->BaseExpression); + auto indexExpr = lowerExpr(subscriptExpr->IndexExpression); + + // An attempt to subscript a tuple must be turned into a + // tuple of subscript expressions. + if (auto baseTuple = baseExpr.As<TupleExpr>()) + { + return createSubscriptExpr(baseExpr, indexExpr); + } + else + { + // Default case: just reconstrut a subscript expr + RefPtr<IndexExpressionSyntaxNode> loweredExpr = new IndexExpressionSyntaxNode(); + lowerExprCommon(loweredExpr, subscriptExpr); + loweredExpr->BaseExpression = baseExpr; + loweredExpr->IndexExpression = indexExpr; + return loweredExpr; + } + } + void addArgs( InvokeExpressionSyntaxNode* callExpr, RefPtr<ExpressionSyntaxNode> argExpr) @@ -1615,6 +1693,21 @@ struct LoweringVisitor return nullptr; } + ExpressionType* unwrapArray(ExpressionType* inType) + { + auto type = inType; + while (auto arrayType = type->As<ArrayExpressionType>()) + { + type = arrayType->BaseType; + } + return type; + } + + TupleTypeModifier* isTupleTypeOrArrayOfTupleType(ExpressionType* type) + { + return isTupleType(unwrapArray(type)); + } + bool isResourceType(ExpressionType* type) { while (auto arrayType = type->As<ArrayExpressionType>()) @@ -1692,7 +1785,7 @@ struct LoweringVisitor bool isTupleField = false; bool fieldHasAnyNonTupleFields = false; bool fieldHasTupleType = false; - if (auto fieldTupleTypeMod = isTupleType(loweredFieldType)) + if (auto fieldTupleTypeMod = isTupleTypeOrArrayOfTupleType(loweredFieldType)) { isTupleField = true; fieldHasTupleType = true; @@ -1780,19 +1873,60 @@ struct LoweringVisitor return lowerSimpleVarDeclCommon(loweredDecl, decl, loweredType); } + struct TupleTypeSecondaryVarArraySpec + { + TupleTypeSecondaryVarArraySpec* next; + RefPtr<IntVal> elementCount; + }; + + struct TupleSecondaryVarInfo + { + // Parent tuple decl to add the secondary decl into + RefPtr<TupleVarDecl> tupleDecl; + + // Syntax class for declarations to create + SyntaxClass<VarDeclBase> varDeclClass; + + // Name "stem" to use for any actual variables we create + String name; + + // The parent tuple type (or array thereof) we are scalarizing + RefPtr<ExpressionType> tupleType; + + // The actual declaration of the tuple type (which will give us the fields) + DeclRef<AggTypeDecl> tupleTypeDecl; + + // An initializer expression to use for the tuple members + RefPtr<ExpressionSyntaxNode> initExpr; + + // The original layout given to the top-level variable + RefPtr<VarLayout> primaryVarLayout; + + // The computed layout of the tuple type itself + RefPtr<StructTypeLayout> tupleTypeLayout; + + TupleTypeSecondaryVarArraySpec* arraySpecs = nullptr; + }; + void createTupleTypeSecondaryVarDecls( - RefPtr<TupleVarDecl> tupleDecl, - SyntaxClass<VarDeclBase> varDeclClass, - String const& name, - RefPtr<ExpressionType> tupleType, - DeclRef<AggTypeDecl> tupleTypeDecl, - RefPtr<ExpressionSyntaxNode> initExpr, - RefPtr<VarLayout> primaryVarLayout, - RefPtr<StructTypeLayout> tupleTypeLayout) + TupleSecondaryVarInfo const& info) { + if (auto arrayType = info.tupleType->As<ArrayExpressionType>()) + { + TupleTypeSecondaryVarArraySpec arraySpec; + arraySpec.next = info.arraySpecs; + arraySpec.elementCount = arrayType->ArrayLength; + + TupleSecondaryVarInfo subInfo = info; + subInfo.tupleType = arrayType->BaseType; + subInfo.arraySpecs = &arraySpec; + createTupleTypeSecondaryVarDecls(subInfo); + return; + } + // Next, we need to go through the declarations in the aggregate // type, and deal with all of those that should be tuple-ified. - for (auto dd : getMembersOfType<VarDeclBase>(tupleTypeDecl)) + for (auto dd : getMembersOfType<VarDeclBase>(info.tupleTypeDecl)) { if (dd.getDecl()->HasModifier<HLSLStaticModifier>()) continue; @@ -1802,10 +1936,10 @@ struct LoweringVisitor continue; // TODO: need to extract the initializer for this field - assert(!initExpr); + assert(!info.initExpr); RefPtr<ExpressionSyntaxNode> fieldInitExpr; - String fieldName = name + "_" + dd.GetName(); + String fieldName = info.name + "_" + dd.GetName(); auto fieldType = GetType(dd); @@ -1814,11 +1948,11 @@ struct LoweringVisitor assert(originalFieldDecl); RefPtr<VarLayout> fieldLayout; - if(tupleTypeLayout) + if(info.tupleTypeLayout) { - tupleTypeLayout->mapVarToLayout.TryGetValue(originalFieldDecl, fieldLayout); + info.tupleTypeLayout->mapVarToLayout.TryGetValue(originalFieldDecl, fieldLayout); } - if (fieldLayout && primaryVarLayout) + if (fieldLayout && info.primaryVarLayout) { // The layout for a field may need to be adjusted // based on a base offset stored in the primary @@ -1835,7 +1969,7 @@ struct LoweringVisitor bool needsOffset = false; for (auto rr : fieldLayout->resourceInfos) { - if (auto parentInfo = primaryVarLayout->FindResourceInfo(rr.kind)) + if (auto parentInfo = info.primaryVarLayout->FindResourceInfo(rr.kind)) { if (parentInfo->index != 0 || parentInfo->space != 0) { @@ -1858,7 +1992,7 @@ struct LoweringVisitor auto newResInfo = newFieldLayout->findOrAddResourceInfo(resInfo.kind); newResInfo->index = resInfo.index; newResInfo->space = resInfo.space; - if (auto parentInfo = primaryVarLayout->FindResourceInfo(resInfo.kind)) + if (auto parentInfo = info.primaryVarLayout->FindResourceInfo(resInfo.kind)) { newResInfo->index += parentInfo->index; newResInfo->space += parentInfo->space; @@ -1871,29 +2005,44 @@ struct LoweringVisitor } RefPtr<VarDeclBase> fieldVarOrTupleDecl; - if (auto fieldTupleTypeMod = isTupleType(fieldType)) + if (auto fieldTupleTypeMod = isTupleTypeOrArrayOfTupleType(fieldType)) { // If the field is itself a tuple, then recurse RefPtr<TupleVarDecl> fieldTupleDecl = new TupleVarDecl(); + + TupleSecondaryVarInfo fieldInfo; + fieldInfo.tupleDecl = fieldTupleDecl; + fieldInfo.varDeclClass = info.varDeclClass; + fieldInfo.name = fieldName; + fieldInfo.tupleType = fieldType; + fieldInfo.tupleTypeDecl = makeDeclRef(fieldTupleTypeMod->decl); + fieldInfo.initExpr = fieldInitExpr; + fieldInfo.primaryVarLayout = fieldLayout; + fieldInfo.tupleTypeLayout = getBodyStructTypeLayout(fieldLayout ? fieldLayout->typeLayout : nullptr); + fieldInfo.arraySpecs = info.arraySpecs; + fieldTupleDecl->tupleType = fieldTupleTypeMod; - createTupleTypeSecondaryVarDecls( - fieldTupleDecl, - varDeclClass, - fieldName, - fieldType, - makeDeclRef(fieldTupleTypeMod->decl), - fieldInitExpr, - fieldLayout, - getBodyStructTypeLayout(fieldLayout ? fieldLayout->typeLayout : nullptr)); + createTupleTypeSecondaryVarDecls(fieldInfo); fieldVarOrTupleDecl = fieldTupleDecl; } else { // Otherwise the field has a simple type, and we just need to declare the variable here - RefPtr<VarDeclBase> fieldVarDecl = varDeclClass.createInstance(); + + RefPtr<ExpressionType> fieldVarType = fieldType; + for (auto aa = info.arraySpecs; aa; aa = aa->next) + { + RefPtr<ArrayExpressionType> arrayType = new ArrayExpressionType(); + arrayType->BaseType = fieldVarType; + arrayType->ArrayLength = aa->elementCount; + + fieldVarType = arrayType; + } + + RefPtr<VarDeclBase> fieldVarDecl = info.varDeclClass.createInstance(); fieldVarDecl->Name.Content = fieldName; - fieldVarDecl->Type.type = fieldType; + fieldVarDecl->Type.type = fieldVarType; addDecl(fieldVarDecl); @@ -1911,7 +2060,7 @@ struct LoweringVisitor fieldTupleVarMod->tupleField = tupleFieldMod; addModifier(fieldVarOrTupleDecl, fieldTupleVarMod); - tupleDecl->tupleDecls.Add(fieldVarOrTupleDecl); + info.tupleDecl->tupleDecls.Add(fieldVarOrTupleDecl); } } @@ -1955,15 +2104,17 @@ struct LoweringVisitor addDecl(primaryVarDecl); } - createTupleTypeSecondaryVarDecls( - tupleDecl, - varDeclClass, - name, - tupleType, - tupleTypeDecl, - initExpr, - primaryVarLayout, - tupleTypeLayout); + TupleSecondaryVarInfo info; + info.tupleDecl = tupleDecl; + info.varDeclClass = varDeclClass; + info.name = name; + info.tupleType = tupleType; + info.tupleTypeDecl = tupleTypeDecl; + info.initExpr = initExpr; + info.primaryVarLayout = primaryVarLayout; + info.tupleTypeLayout = tupleTypeLayout; + + createTupleTypeSecondaryVarDecls(info); return tupleDecl; } @@ -1978,6 +2129,11 @@ struct LoweringVisitor typeLayout = parameterBlockTypeLayout->elementTypeLayout; } + while (auto arrayTypeLayout = typeLayout.As<ArrayTypeLayout>()) + { + typeLayout = arrayTypeLayout->elementTypeLayout; + } + if (auto structTypeLayout = typeLayout.As<StructTypeLayout>()) { return structTypeLayout; @@ -2020,7 +2176,7 @@ struct LoweringVisitor { auto loweredType = lowerType(decl->Type); - if (auto tupleTypeMod = isTupleType(loweredType)) + if (auto tupleTypeMod = isTupleTypeOrArrayOfTupleType(loweredType)) { auto varLayout = tryToFindLayout(decl).As<VarLayout>(); @@ -2051,7 +2207,7 @@ struct LoweringVisitor auto varLayout = tryToFindLayout(decl).As<VarLayout>(); auto elementType = bufferType->elementType; - if (auto elementTupleTypeMod = isTupleType(elementType)) + if (auto elementTupleTypeMod = isTupleTypeOrArrayOfTupleType(elementType)) { auto tupleDecl = createTupleTypeVarDecls( loweredDeclClass, diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp index 1c1bcceaf..3de33f554 100644 --- a/source/slang/slang-stdlib.cpp +++ b/source/slang/slang-stdlib.cpp @@ -1440,6 +1440,66 @@ namespace Slang for(int isFloat = 0; isFloat < 2; ++isFloat) for(int includeMipInfo = 0; includeMipInfo < 2; ++includeMipInfo) { + { + sb << "__intrinsic(glsl, \"("; + + int aa = 0; + String lodStr = "0"; + if (includeMipInfo) + { + int mipLevelArg = aa++; + lodStr.append("$"); + lodStr.append(mipLevelArg); + } + + int cc = 0; + switch(baseShape) + { + case TextureType::Shape1D: + sb << "($" << aa++ << " = textureSize($P, " << lodStr << "))"; + cc = 1; + break; + + case TextureType::Shape2D: + case TextureType::ShapeCube: + sb << "($" << aa++ << " = textureSize($P, " << lodStr << ").x)"; + sb << ", ($" << aa++ << " = textureSize($P, " << lodStr << ").y)"; + cc = 2; + break; + + case TextureType::Shape3D: + sb << "($" << aa++ << " = textureSize($P, " << lodStr << ").x)"; + sb << ", ($" << aa++ << " = textureSize($P, " << lodStr << ").y)"; + sb << ", ($" << aa++ << " = textureSize($P, " << lodStr << ").z)"; + cc = 3; + break; + + default: + assert(!"unexpected"); + break; + } + + if(isArray) + { + sb << ", ($" << aa++ << " = textureSize($P, " << lodStr << ")." << kComponentNames[cc] << ")"; + } + + if(isMultisample) + { + sb << ", ($" << aa++ << " = textureSamples($P))"; + } + + if (includeMipInfo) + { + sb << ", ($" << aa++ << " = textureQueryLevels($P))"; + } + + + sb << ")\")\n"; + sb << "__intrinsic\n"; + + } + char const* t = isFloat ? "out float " : "out uint "; sb << "void GetDimensions("; @@ -1612,6 +1672,48 @@ namespace Slang sb << "float compareValue"; sb << ");\n"; + int baseCoordCount = kBaseTextureTypes[tt].coordCount; + int arrCoordCount = baseCoordCount + isArray; + if (arrCoordCount < 3) + { + int extCoordCount = arrCoordCount + 1; + + if (extCoordCount < 3) + extCoordCount = 3; + + sb << "__intrinsic(glsl, \"textureLod($p, "; + + sb << "vec" << extCoordCount << "($1,"; + for (int ii = arrCoordCount; ii < extCoordCount - 1; ++ii) + { + sb << " 0.0,"; + } + sb << "$2)"; + + sb << ", 0.0)\")\n"; + } + else if(arrCoordCount <= 3) + { + int extCoordCount = arrCoordCount + 1; + + if (extCoordCount < 3) + extCoordCount = 3; + + sb << "__intrinsic(glsl, \"textureGrad($p, "; + + sb << "vec" << extCoordCount << "($1,"; + for (int ii = arrCoordCount; ii < extCoordCount - 1; ++ii) + { + sb << " 0.0,"; + } + sb << "$2)"; + + // Construct gradients + sb << ", vec" << baseCoordCount << "(0.0)"; + sb << ", vec" << baseCoordCount << "(0.0)"; + sb << ")\")\n"; + } + sb << "__intrinsic\n"; sb << "T SampleCmpLevelZero(SamplerComparisonState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float compareValue"; @@ -1637,6 +1739,9 @@ namespace Slang sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; } + + sb << "__intrinsic(glsl, \"textureGrad($p, $1, $2, $3)\")\n"; + sb << "__intrinsic\n"; sb << "T SampleGrad(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " gradX, "; @@ -1645,6 +1750,8 @@ namespace Slang if( baseShape != TextureType::ShapeCube ) { + sb << "__intrinsic(glsl, \"textureGradOffset($p, $1, $2, $3, $4)\")\n"; + sb << "__intrinsic\n"; sb << "T SampleGrad(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " gradX, "; diff --git a/source/slang/syntax.h b/source/slang/syntax.h index 83b2f5801..3f1c47fb9 100644 --- a/source/slang/syntax.h +++ b/source/slang/syntax.h @@ -244,7 +244,7 @@ namespace Slang : createFunc(createFunc) {} - void* createInstanceImpl() + void* createInstanceImpl() const { return createFunc ? createFunc() : nullptr; } @@ -271,7 +271,7 @@ namespace Slang { } - T* createInstance() + T* createInstance() const { return (T*)createInstanceImpl(); } |
