diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-10-18 11:08:47 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-10-18 11:08:47 -0700 |
| commit | a12480fe49d5ba7c0a9c2ac63363dc76b599ddbd (patch) | |
| tree | 6344dec2a432f2f5cb1cdd981d0aafe21ea6a443 /source/slang/emit.cpp | |
| parent | f12c2552b3f494cbc8245edb90b32b93ca8a1539 (diff) | |
Work on IR-based cross-compilation (#222)
There are two big changes here:
- Add logic during the initial IR cloning pass for an entry point + target that tries to pick the best possible version of any target-overloaded function. This allows us to pick the intrinsic version of `saturate()` when compiling for HLSL output, but then pick the non-intrinsic version (that is implemented in terms of `clamp()`) when targetting GLSL.
- Add an initial specialization pass that tries to deal with generics. This required some fixing work to IR generation, so that we correctly generate explicit operations to specialize a generic for specific types (this is currently implemented as a `specialize` instruction that takes the generic to specialize plus a declaration-reference that represents the specialized form). With that work in place, we can scan for `specialize` instructions inside of non-generic functions, and use them to trigger generation of specialized code. We rely on the name-mangling scheme to help us find pre-existing specializations when possible.
There are also a bunch of cleanups encountered along the way:
- Don't use the explicit `layout(offset=...)` for uniforms, because it isn't supported by all current drivers. For now we will just assume that our layout rules compute the same values that the driver would for un-marked-up code. We can come back later and try to implement a workaround in the cases where this doesn't apply (e.g., by re-running the layout logic as part of emission, and dropping layout modifiers from variables that don't need explicit layout).
- Fix some issues in IR dump printing so that we print function declarations more nicely.
- Testing: print out failing pixel when image-diff fails
Diffstat (limited to 'source/slang/emit.cpp')
| -rw-r--r-- | source/slang/emit.cpp | 72 |
1 files changed, 61 insertions, 11 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index f9c0b5f09..d8d9e13ed 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -3574,17 +3574,34 @@ struct EmitVisitor switch(info.kind) { case LayoutResourceKind::Uniform: - // Explicit offsets require a GLSL extension. - // - // TODO: We really need to fix this so that we - // only output an explicit offset for things - // that are layed out differently than they - // would normally be... - requireGLSLExtension("GL_ARB_enhanced_layouts"); + { + // Explicit offsets require a GLSL extension (which + // is not universally supported, it seems) or a new + // enough GLSL version (which we don't want to + // universall require), so for right now we + // won't actually output explicit offsets for uniform + // shader parameters. + // + // TODO: We should fix this so that we skip any + // extra work for parameters that are laid out as + // expected by the default rules, but do *something* + // for parameters that need non-default layout. + // + // Using the `GL_ARB_enhanced_layouts` feature is one + // option, but we should also be able to do some + // things by introducing padding into the declaration + // (padding insertion would probably be best done at + // the IR level). + bool useExplicitOffsets = false; + if (useExplicitOffsets) + { + requireGLSLExtension("GL_ARB_enhanced_layouts"); - Emit("layout(offset = "); - Emit(info.index); - Emit(")\n"); + Emit("layout(offset = "); + Emit(info.index); + Emit(")\n"); + } + } break; case LayoutResourceKind::VertexInput: @@ -4073,7 +4090,11 @@ emitDeclImpl(decl, nullptr); { case kIROp_global_var: case kIROp_Func: - return ((IRGlobalValue*)inst)->mangledName; + { + auto& mangledName = ((IRGlobalValue*)inst)->mangledName; + if(mangledName.Length() != 0) + return mangledName; + } break; default: @@ -4396,6 +4417,7 @@ emitDeclImpl(decl, nullptr); case kIROp_boolConst: case kIROp_FieldAddress: case kIROp_getElementPtr: + case kIROp_specialize: return true; } @@ -4937,6 +4959,12 @@ emitDeclImpl(decl, nullptr); } break; + case kIROp_specialize: + { + emitIROperand(context, inst->getArg(0)); + } + break; + default: emit("/* unhandled */"); break; @@ -5579,6 +5607,11 @@ emitDeclImpl(decl, nullptr); if(!value) return nullptr; + if(value->op == kIROp_specialize) + { + value = ((IRSpecialize*) value)->genericVal.usedValue; + } + if(value->op != kIROp_Func) return nullptr; @@ -5608,6 +5641,14 @@ emitDeclImpl(decl, nullptr); } else #endif + if(func->genericDecl) + { + Emit("/* "); + emitIRFuncDecl(context, func); + Emit(" */"); + return; + } + if(!isDefinition(func)) { // This is just a function declaration, @@ -6339,6 +6380,13 @@ String emitEntryPoint( // TODO: we should apply some guaranteed transformations here, // to eliminate constructs that aren't legal downstream (e.g. generics). + + specializeGenerics(lowered); + +// fprintf(stderr, "###\n"); +// dumpIR(lowered); +// fprintf(stderr, "###\n"); + // // TODO: Need to decide whether to do these before or after // target-specific legalization steps. Currently I've folded @@ -6348,6 +6396,8 @@ String emitEntryPoint( // IR back into AST for emission? visitor.emitIRModule(&context, lowered); + + // TODO: need to clean up the IR module here } else if(!(translationUnit->compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING ) || translationUnit->compileRequest->loadedModulesList.Count() != 0) |
