소스 검색

Add HLSL macros with version information (#2665)

* Add HLSL macros with version information

Adds three sets of version information as defined macros available
to the shader.

The DXC version is included as __DXC_VERSION_{MAJOR|MINOR|RELEASE|COMMITS}
The values of these are set at compile time and derived from version.inc
RELEASE and COMMITS information varies according to the criteria
described in gen_version.py.

The HLSL Version is included as __HLSL_VERSION. It may be taken from
the -HV argument with which dxc was invoked, derived from other
arguments, or the default.

The shader target stage and version information is taken from the
-T argument with which dxc was invoked. For the stage, defined
constants representing each stage are defined at compile time that
correspond to the enum values used internally. The shader stage
specified by -T is determined at runtime and set to the corresponding
enum value. The major and minor versions are similarly derived from
the -T argument at runtime.

The runtime defines are set in InitializeStandardPredefinedMacros()
This allows them to be set just once and the same way for any way
that dxc is invoked including testing.

This makes some changes to how the version.inc file is generated and
found in cmake files in order to generate it regardless of the need
for a .rc resource file as it was before.

A series of hlsl tests are added that test for the defines presence
and values in order to add versus subtract with checks for the adds.
Since many of the defines are determined by arguments at runtime, a
few different tests were needed, but as much consolidation as possible
was done to reduce the number of individual test runs.
Greg Roth 5 년 전
부모
커밋
d9242790d4

+ 2 - 2
CMakeLists.txt

@@ -81,7 +81,7 @@ endif()
 
 option(HLSL_EMBED_VERSION "If set, embeds version information in the binaries." ON) # HLSL Change
 # HLSL Change - Directory with version.inc file used for the build (generated or copied from HLSL_FIXED_VERSION_LOCATION)
-set(HLSL_VERSION_LOCATION ${CMAKE_CURRENT_BINARY_DIR}\\utils\\version)
+set(HLSL_VERSION_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/utils/version)
 option(HLSL_OFFICIAL_BUILD "If set, embeds official version in the binaries (based on the latest release version)" OFF) # HLSL Change
 option(HLSL_ENABLE_FIXED_VER "Reads version information from a file." OFF) # HLSL Change
 
@@ -89,7 +89,7 @@ if (HLSL_ENABLE_FIXED_VER)
   set(HLSL_EMBED_VERSION ON)
   if (NOT DEFINED HLSL_FIXED_VERSION_LOCATION OR HLSL_FIXED_VERSION_LOCATION STREQUAL "")
     # HLSL Change - Directory with fixed version.inc file
-    set(HLSL_FIXED_VERSION_LOCATION  ${CMAKE_CURRENT_SOURCE_DIR}\\utils\\version)
+    set(HLSL_FIXED_VERSION_LOCATION  ${CMAKE_CURRENT_SOURCE_DIR}/utils/version)
   endif()
 endif()
 

+ 2 - 0
tools/clang/lib/Frontend/CMakeLists.txt

@@ -46,6 +46,7 @@ add_clang_library(clangFrontend
   DEPENDS
   ClangDriverOptions
   TablegenHLSLOptions
+  hlsl_version_autogen # HLSL Change
 
   LINK_LIBS
   clangAST
@@ -57,3 +58,4 @@ add_clang_library(clangFrontend
   clangSema
 #  clangSerialization # HLSL Change
   )
+target_include_directories(clangFrontend PUBLIC ${HLSL_VERSION_LOCATION}) # HLSL Change

+ 32 - 1
tools/clang/lib/Frontend/InitPreprocessor.cpp

@@ -27,6 +27,9 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
+#include "version.inc" // HLSL Change
+#include "dxc/DXIL/DxilConstants.h" // HLSL Change
+#include "dxc/DXIL/DxilShaderModel.h" // HLSL Change
 using namespace clang;
 
 static bool MacroBodyEndsInBackslash(StringRef MacroBody) {
@@ -355,13 +358,41 @@ static void AddObjCXXARCLibstdcxxDefines(const LangOptions &LangOpts,
   Builder.append(Result);
 }
 
+#define STRINGIFY_INNER(str) #str
+#define STRINGIFY(str) STRINGIFY_INNER(str)
+
 static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
                                                const LangOptions &LangOpts,
                                                const FrontendOptions &FEOpts,
                                                MacroBuilder &Builder) {
 #if 1 // HLSL Change Starts
-  if (LangOpts.HLSL)
+  if (LangOpts.HLSL) {
     Builder.defineMacro("__hlsl_dx_compiler");
+    // DXC Version information
+    Builder.defineMacro("__DXC_VERSION_MAJOR", STRINGIFY(RC_VERSION_FIELD_1));
+    Builder.defineMacro("__DXC_VERSION_MINOR", STRINGIFY(RC_VERSION_FIELD_2));
+    Builder.defineMacro("__DXC_VERSION_RELEASE", STRINGIFY(RC_VERSION_FIELD_3));
+    Builder.defineMacro("__DXC_VERSION_COMMITS", STRINGIFY(RC_VERSION_FIELD_4));
+    // HLSL Version
+    Builder.defineMacro("__HLSL_VERSION", Twine(LangOpts.HLSLVersion));
+    // Shader target information
+    // "enums" for shader stages
+    Builder.defineMacro("__SHADER_STAGE_VERTEX",  Twine((unsigned)hlsl::DXIL::ShaderKind::Vertex));
+    Builder.defineMacro("__SHADER_STAGE_PIXEL",   Twine((unsigned)hlsl::DXIL::ShaderKind::Pixel));
+    Builder.defineMacro("__SHADER_STAGE_GEOMETRY",Twine((unsigned)hlsl::DXIL::ShaderKind::Geometry));
+    Builder.defineMacro("__SHADER_STAGE_HULL",    Twine((unsigned)hlsl::DXIL::ShaderKind::Hull));
+    Builder.defineMacro("__SHADER_STAGE_DOMAIN",  Twine((unsigned)hlsl::DXIL::ShaderKind::Domain));
+    Builder.defineMacro("__SHADER_STAGE_COMPUTE", Twine((unsigned)hlsl::DXIL::ShaderKind::Compute));
+    Builder.defineMacro("__SHADER_STAGE_AMPLIFICATION",Twine((unsigned)hlsl::DXIL::ShaderKind::Amplification));
+    Builder.defineMacro("__SHADER_STAGE_MESH",    Twine((unsigned)hlsl::DXIL::ShaderKind::Mesh));
+    Builder.defineMacro("__SHADER_STAGE_LIBRARY", Twine((unsigned)hlsl::DXIL::ShaderKind::Library));
+    const hlsl::ShaderModel *SM = hlsl::ShaderModel::GetByName(LangOpts.HLSLProfile.c_str());
+    // The current shader stage itself
+    Builder.defineMacro("__SHADER_TARGET_STAGE", Twine((unsigned)SM->GetKind()));
+    // Add target versions
+    Builder.defineMacro("__SHADER_TARGET_MAJOR", Twine(SM->GetMajor()));
+    Builder.defineMacro("__SHADER_TARGET_MINOR", Twine(SM->GetMinor()));
+  }
   return;
 #else
   if (!LangOpts.MSVCCompat && !LangOpts.TraditionalCPP)

+ 1 - 0
tools/clang/test/HLSLFileCheck/hlsl/preprocessor/version_defines/Readme.md

@@ -0,0 +1 @@
+The shaders in this directory test the builtin definition of version macros covering DXC version, HLSL versions, and target stage and version information.

+ 36 - 0
tools/clang/test/HLSLFileCheck/hlsl/preprocessor/version_defines/target_version_amplification.hlsl

@@ -0,0 +1,36 @@
+// RUN: %dxc -O0 -T as_6_6 %s | FileCheck %s
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+
+#define NUM_THREADS 32
+
+struct Payload {
+    float2 dummy;
+    float4 pos;
+    float color[2];
+};
+
+[numthreads(NUM_THREADS, 1, 1)]
+void main()
+{
+    Payload pld;
+    float x = 0;
+#if defined(__SHADER_TARGET_STAGE) && __SHADER_TARGET_STAGE == __SHADER_STAGE_AMPLIFICATION
+    x += 1;
+#else
+    x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MAJOR) && __SHADER_TARGET_MAJOR == 6
+    x += 1;
+#else
+    x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MINOR) && __SHADER_TARGET_MINOR == 6
+    x += 1;
+#else
+    x -= 1;
+#endif
+    pld.pos = x;
+    DispatchMesh(NUM_THREADS, 1, 1, pld);
+}

+ 27 - 0
tools/clang/test/HLSLFileCheck/hlsl/preprocessor/version_defines/target_version_compute.hlsl

@@ -0,0 +1,27 @@
+// RUN: %dxc -O0 -T cs_6_4 %s | FileCheck %s
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+
+RWBuffer<float> buf;
+
+[numthreads(8, 8, 1)]
+void main(uint id : SV_DispatchThreadId) {
+    float x = 0;
+#if defined(__SHADER_TARGET_STAGE) && __SHADER_TARGET_STAGE == __SHADER_STAGE_COMPUTE
+    x += 1;
+#else
+    x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MAJOR) && __SHADER_TARGET_MAJOR == 6
+    x += 1;
+#else
+    x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MINOR) && __SHADER_TARGET_MINOR == 4
+    x += 1;
+#else
+    x -= 1;
+#endif
+    buf[id] = x;
+}

+ 53 - 0
tools/clang/test/HLSLFileCheck/hlsl/preprocessor/version_defines/target_version_domain.hlsl

@@ -0,0 +1,53 @@
+// RUN: %dxc -O0 -T ds_6_3 %s | FileCheck %s
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+
+struct VSSceneIn {
+  float3 pos : POSITION;
+};
+
+struct PSSceneIn {
+  float4 pos : SV_Position;
+
+uint   RTIndex      : SV_RenderTargetArrayIndex;
+};
+
+struct HSPerVertexData {
+  PSSceneIn v;
+};
+
+struct HSPerPatchData {
+  float edges[3] : SV_TessFactor;
+  float inside : SV_InsideTessFactor;
+};
+
+// domain shader that actually outputs the triangle vertices
+[domain("tri")] PSSceneIn main(const float3 bary
+                               : SV_DomainLocation,
+                                 const OutputPatch<HSPerVertexData, 3> patch,
+                                 const HSPerPatchData perPatchData) {
+  PSSceneIn v;
+  float x = bary.x;
+
+#if defined(__SHADER_TARGET_STAGE) && __SHADER_TARGET_STAGE == __SHADER_STAGE_DOMAIN
+    x += 1;
+#else
+    x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MAJOR) && __SHADER_TARGET_MAJOR == 6
+    x += 1;
+#else
+    x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MINOR) && __SHADER_TARGET_MINOR == 3
+    x += 1;
+#else
+    x -= 1;
+#endif
+
+    v = patch[0].v;
+    v.pos.x = x;
+
+    return v;
+}

+ 44 - 0
tools/clang/test/HLSLFileCheck/hlsl/preprocessor/version_defines/target_version_geometry.hlsl

@@ -0,0 +1,44 @@
+// RUN: %dxc -O0 -HV 2017 -T gs_6_1 %s | FileCheck %s
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+
+struct Out
+{
+  float4 pos : SV_Position;
+};
+
+[maxvertexcount(3)]
+void main(inout PointStream<Out> OutputStream0)
+{
+  Out output = (Out)0;
+  float x = 0;
+
+  // Version should be as specified by -HV
+#if defined(__HLSL_VERSION) && __HLSL_VERSION == 2017
+  x += 1;
+#else
+  x -= 1;
+#endif
+#if defined(__SHADER_TARGET_STAGE) && __SHADER_TARGET_STAGE == __SHADER_STAGE_GEOMETRY
+  x += 1;
+#else
+  x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MAJOR) && __SHADER_TARGET_MAJOR == 6
+  x += 1;
+#else
+  x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MINOR) && __SHADER_TARGET_MINOR == 1
+  x += 1;
+#else
+  x -= 1;
+#endif
+
+  output.pos.x = x;
+
+  OutputStream0.Append(output);
+  OutputStream0.RestartStrip();
+}

+ 73 - 0
tools/clang/test/HLSLFileCheck/hlsl/preprocessor/version_defines/target_version_hull.hlsl

@@ -0,0 +1,73 @@
+// RUN: %dxc -O0 -T hs_6_2 %s | FileCheck %s
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+
+struct PSSceneIn
+{
+    float4 pos  : SV_Position;
+    float2 tex  : TEXCOORD0;
+    float3 norm : NORMAL;
+
+uint   RTIndex      : SV_RenderTargetArrayIndex;
+};
+
+
+struct HSPerVertexData
+{
+    PSSceneIn v;
+};
+
+struct HSPerPatchData
+{
+	float	edges[ 3 ]	: SV_TessFactor;
+	float	inside		: SV_InsideTessFactor;
+};
+
+HSPerPatchData HSPerPatchFunc( const InputPatch< PSSceneIn, 3 > points,  OutputPatch<HSPerVertexData, 3> outp )
+{
+    HSPerPatchData d;
+
+    d.edges[ 0 ] = 1;
+    d.edges[ 1 ] = 1;
+    d.edges[ 2 ] = 1;
+    d.inside = 1;
+
+    return d;
+}
+
+[domain("tri")]
+[partitioning("fractional_odd")]
+[outputtopology("triangle_cw")]
+[patchconstantfunc("HSPerPatchFunc")]
+[outputcontrolpoints(3)]
+HSPerVertexData main( const uint id : SV_OutputControlPointID,
+                      const InputPatch< PSSceneIn, 3 > points )
+{
+    HSPerVertexData v;
+    v.v = points[ id ];
+
+    float x = 0;
+
+#if defined(__SHADER_TARGET_STAGE) && __SHADER_TARGET_STAGE == __SHADER_STAGE_HULL
+    x += 1;
+#else
+    x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MAJOR) && __SHADER_TARGET_MAJOR == 6
+    x += 1;
+#else
+    x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MINOR) && __SHADER_TARGET_MINOR == 2
+    x += 1;
+#else
+    x -= 1;
+#endif
+
+    v.v.pos.x = x;
+
+    return v;
+}
+
+

+ 26 - 0
tools/clang/test/HLSLFileCheck/hlsl/preprocessor/version_defines/target_version_library.hlsl

@@ -0,0 +1,26 @@
+// RUN: %dxc -O0 -T lib_6_x %s | FileCheck %s
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+
+float foo() {
+    float x = 0;
+
+#if defined(__SHADER_TARGET_STAGE) && __SHADER_TARGET_STAGE == __SHADER_STAGE_LIBRARY
+    x += 1;
+#else
+    x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MAJOR) && __SHADER_TARGET_MAJOR == 6
+    x += 1;
+#else
+    x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MINOR) && __SHADER_TARGET_MINOR == 15
+    x += 1;
+#else
+    x -= 1;
+#endif
+
+    return x;
+}

+ 34 - 0
tools/clang/test/HLSLFileCheck/hlsl/preprocessor/version_defines/target_version_mesh.hlsl

@@ -0,0 +1,34 @@
+// RUN: %dxc -O0 -T ms_6_5 %s | FileCheck %s
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+
+struct Vertex { float4 pos : SV_Position; };
+
+[outputtopology("point")]
+[numthreads(2,2,1)]
+void main(
+    out vertices Vertex verts[1],
+    out indices uint3 idx[1])
+{
+    verts = (Vertex[1])0;
+
+    float x = 0;
+#if defined(__SHADER_TARGET_STAGE) && __SHADER_TARGET_STAGE == __SHADER_STAGE_MESH
+    x += 1;
+#else
+    x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MAJOR) && __SHADER_TARGET_MAJOR == 6
+    x += 1;
+#else
+    x -= 1;
+#endif
+#if defined(__SHADER_TARGET_MINOR) && __SHADER_TARGET_MINOR == 5
+    x += 1;
+#else
+    x -= 1;
+#endif
+    verts[0].pos = x;
+    SetMeshOutputCounts(0, 0);
+}

+ 34 - 0
tools/clang/test/HLSLFileCheck/hlsl/preprocessor/version_defines/target_version_pixel.hlsl

@@ -0,0 +1,34 @@
+// RUN: %dxc -O0 -Gec -T ps_6_0 %s | FileCheck %s
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+
+float4 main(float4 color : A) : SV_Target
+{
+  float red = color.r;
+  float4 outColor = color;
+  // Backward compatibility mode (-Gec) should set version to 2016
+#if defined(__HLSL_VERSION) && __HLSL_VERSION == 2016
+  red += 1;
+#else
+  red -= 1;
+#endif
+#if defined(__SHADER_TARGET_STAGE) && __SHADER_TARGET_STAGE == __SHADER_STAGE_PIXEL
+  red += 1;
+#else
+  red -= 1;
+#endif
+#if defined(__SHADER_TARGET_MAJOR) && __SHADER_TARGET_MAJOR == 6
+  red += 1;
+#else
+  red -= 1;
+#endif
+#if defined(__SHADER_TARGET_MINOR) && __SHADER_TARGET_MINOR == 0
+  red += 1;
+#else
+  red -= 1;
+#endif
+  outColor.r = red;
+  return outColor;
+}

+ 70 - 0
tools/clang/test/HLSLFileCheck/hlsl/preprocessor/version_defines/target_version_vertex.hlsl

@@ -0,0 +1,70 @@
+// RUN: %dxc -O0 -T vs_6_0 %s | FileCheck %s
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+// CHECK: fadd
+
+float4 main(float4 pos : IN) : OUT
+{
+  float x = pos.x;
+  float4 outPos = pos;
+
+  // Will need to change if there's ever a major version bump
+#if defined(__DXC_VERSION_MAJOR) && __DXC_VERSION_MAJOR == 1
+  x += 1;
+#else
+  x -= 1;
+#endif
+
+  // Minor version is expected to change fairly frequently. So be conservative
+#if defined(__DXC_VERSION_MINOR) && __DXC_VERSION_MINOR >= 0 && __DXC_VERSION_MINOR < 50
+  x += 1;
+#else
+  x -= 1;
+#endif
+
+  // Release is either based on the year/month or set to zero for dev builds
+#if defined(__DXC_VERSION_RELEASE) && (__DXC_VERSION_RELEASE == 0 ||  __DXC_VERSION_RELEASE > 1900)
+  x += 1;
+#else
+  x -= 1;
+#endif
+
+  // The last number varies a lot. In a dev build, Release is 0, and this number
+  // is the total number of commits since the beginning of the project.
+  // which can be expected to be more than 1000 at least.
+#if defined(__DXC_VERSION_COMMITS) && (__DXC_VERSION_RELEASE > 0 ||  __DXC_VERSION_COMMITS > 1000)
+  x += 1;
+#else
+  x -= 1;
+#endif
+  // Default HLSL version should be the highest available version
+#if defined(__HLSL_VERSION) && __HLSL_VERSION >= 2018
+  x += 1;
+#else
+  x -= 1;
+#endif
+#if defined(__SHADER_TARGET_STAGE) && __SHADER_TARGET_STAGE == __SHADER_STAGE_VERTEX
+  x += 1;
+#else
+  x -= 1;
+#endif
+// Compiler upgrades to 6.0 if less
+#if defined(__SHADER_TARGET_MAJOR) && __SHADER_TARGET_MAJOR == 6
+  x += 1;
+#else
+  x -= 1;
+#endif
+// Compiler upgrades to 6.0 if less
+#if defined(__SHADER_TARGET_MINOR) && __SHADER_TARGET_MINOR == 0
+  x += 1;
+#else
+  x -= 1;
+#endif
+  outPos.x = x;
+  return outPos;
+}

+ 15 - 7
utils/version/CMakeLists.txt

@@ -1,13 +1,21 @@
 if(HLSL_EMBED_VERSION)
-    string(REPLACE "/" "\\" HLSL_VERSION_LOCATION_mspath ${HLSL_VERSION_LOCATION})
+    if (WIN32)
+        string(REPLACE "/" "\\" HLSL_VERSION_LOCATION_local ${HLSL_VERSION_LOCATION}\\)
+    else (WIN32)
+        set(HLSL_VERSION_LOCATION_local ${HLSL_VERSION_LOCATION}/)
+    endif (WIN32)
 
-    set(HLSL_VERSION_FILE ${HLSL_VERSION_LOCATION_mspath}\\version.inc)
+    set(HLSL_VERSION_FILE ${HLSL_VERSION_LOCATION_local}version.inc)
     if(HLSL_ENABLE_FIXED_VER)
-        string(REPLACE "/" "\\" HLSL_FIXED_VERSION_LOCATION_mspath ${HLSL_FIXED_VERSION_LOCATION})
-        message("Using fixed version file ${HLSL_FIXED_VERSION_LOCATION_mspath}\\version.inc")
+        if (WIN32)
+            string(REPLACE "/" "\\" HLSL_FIXED_VERSION_LOCATION_local ${HLSL_FIXED_VERSION_LOCATION}\\)
+        else (WIN32)
+            set(HLSL_FIXED_VERSION_LOCATION_local ${HLSL_FIXED_VERSION_LOCATION}/)
+        endif (WIN32)
+        message("Using fixed version file ${HLSL_FIXED_VERSION_LOCATION_local}version.inc")
         add_custom_target(hlsl_version_autogen
-            COMMAND echo "Using fixed version file ${HLSL_FIXED_VERSION_LOCATION_mspath}\\version.inc"
-            COMMAND copy ${HLSL_FIXED_VERSION_LOCATION_mspath}\\version.inc ${HLSL_VERSION_LOCATION_mspath}
+            COMMAND echo "Using fixed version file ${HLSL_FIXED_VERSION_LOCATION_local}version.inc"
+            COMMAND ${CMAKE_COMMAND} -E copy ${HLSL_FIXED_VERSION_LOCATION_local}version.inc ${HLSL_VERSION_LOCATION_local}
             )
     else(HLSL_ENABLE_FIXED_VER)
         if (HLSL_OFFICIAL_BUILD)
@@ -31,4 +39,4 @@ if(HLSL_EMBED_VERSION)
         FOLDER version
     )
 
-endif(HLSL_EMBED_VERSION)
+endif(HLSL_EMBED_VERSION)