summaryrefslogtreecommitdiffstats
path: root/source/slang/syntax.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2019-04-08 11:09:03 -0700
committerRobert Stepinski <rob.stepinski@gmail.com>2019-04-08 14:09:03 -0400
commitdc54f1dd1b694b087816857a791e9d37dc25de6d (patch)
treeb611249a5fb5d01dbd765d67ac646fa12b495800 /source/slang/syntax.cpp
parentc9d06fe1f46a21c66c378ab9771495d6344db49c (diff)
Add better control over image formats for GLSL/SPIR-V targets (#939)
* Add better control over image formats for GLSL/SPIR-V targets Currently Slang emits GLSL code assuming all R/W images need to have explicit formats, and thus we try to infer a format from the element type of the image. E.g., given a `RWTexture2D<half4>` we might infer that a qualifier of `layout(rgba16f)` should be used. This strategy has two notable shortcomings: * Sometimes the user will want a format that doesn't match an existing HLSL type. E.g., if they want the equivalent of `layout(r11f_g11f_b10f)`, then what should they put in their `RWTexture2D<...>` to make the inference do what they need? * Sometimes the user knows that they don't need to specify a format *at all*, because using the `GL_EXT_shader_image_load_formatted` extension, they can still perform non-atomic load/store on images with no format specified in the SPIR-V. This change adds two features directed at these challenges. First, we add an explicit `[format(...)]` attribute that can be used to specify an explicit image format, including ones that don't match any HLSL type. An example of using this new attribute is: ```hlsl [format("r11f_g11f_b10f")] RWTexture2D<float3> myImage; ``` For simplicity in initial bring-up, the new formats all use the same naming as formats in GLSL (this should make it easy for a programmer who knows what they expect to get in the GLSL output). We can change the naming convention for formats at a later time, so long as we keep these existing names in as a compatibility feature. Note that this is *not* given a `vk::` prefix since the attribute should signal the programmer's intent to provide an image with that format on *all* targets (although only some targets might act on that information). Also note that the attribute takes a string (`[format("rgba8")`) instead of a bare identifier (`[format(rgba8)]`) because this is consistent with the existing convention for attributes in HLSL. When `[format(...)]` is left off, the default compiler behavior will still be to infer a format, but this behavior can be overidden for a single image using an explicit format of `"unknown"`: ```hlsl [format("unknown")] RWTexture2D<float4> mysteryMachine; ``` The second new feature is that if a user knows they are coding for a GPU that supports the `"unknown"` format in all non-atomic cases, then they can opt into making that the default for images without an explicit `[format(...)]`, using the new `-default-image-format-unknown` command-line option for `slangc`. The new test case included with this change confirms that we correctly see the explicit formats in the output GLSL and *no* formats for images without explicit `[format(...)]` when using the new command-line option. The test stresses images declared at global scope, in parameter blocks, and in entry-point parameter lists, to try and make sure that all the relevant IR passes in the compiler preserve the format information. * fixup: missing file
Diffstat (limited to 'source/slang/syntax.cpp')
-rw-r--r--source/slang/syntax.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp
index b1b9f6d80..c48eb7755 100644
--- a/source/slang/syntax.cpp
+++ b/source/slang/syntax.cpp
@@ -2723,5 +2723,41 @@ Module* getModule(Decl* decl)
return nullptr;
}
+bool findImageFormatByName(char const* name, ImageFormat* outFormat)
+{
+ static const struct
+ {
+ char const* name;
+ ImageFormat format;
+ } kFormats[] =
+ {
+#define FORMAT(NAME) { #NAME, ImageFormat::NAME },
+#include "image-format-defs.h"
+ };
+
+ for( auto item : kFormats )
+ {
+ if( strcmp(item.name, name) == 0 )
+ {
+ *outFormat = item.format;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+char const* getGLSLNameForImageFormat(ImageFormat format)
+{
+ switch( format )
+ {
+ default: return "unhandled";
+#define FORMAT(NAME) case ImageFormat::NAME: return #NAME;
+#include "image-format-defs.h"
+ }
+}
+
+
+
} // namespace Slang