diff --git a/include/dxc/Test/DxcTestUtils.h b/include/dxc/Test/DxcTestUtils.h index 1b056bb1bf..194a64507e 100644 --- a/include/dxc/Test/DxcTestUtils.h +++ b/include/dxc/Test/DxcTestUtils.h @@ -126,6 +126,10 @@ class FileRunCommandPart { FileRunCommandResult RunTee(const FileRunCommandResult *Prior); FileRunCommandResult RunXFail(const FileRunCommandResult *Prior); FileRunCommandResult RunDxilVer(dxc::DxcDllSupport& DllSupport, const FileRunCommandResult* Prior); +#ifdef ENABLE_DXIL2SPV + FileRunCommandResult RunDxil2Spv(dxc::DxcDllSupport &DllSupport, + const FileRunCommandResult *Prior); +#endif FileRunCommandResult RunDxcHashTest(dxc::DxcDllSupport &DllSupport); FileRunCommandResult RunFromPath(const std::string &path, const FileRunCommandResult *Prior); FileRunCommandResult RunFileCompareText(const FileRunCommandResult *Prior); diff --git a/tools/clang/unittests/HLSL/HLSLTestOptions.h b/include/dxc/Test/HLSLTestOptions.h similarity index 63% rename from tools/clang/unittests/HLSL/HLSLTestOptions.h rename to include/dxc/Test/HLSLTestOptions.h index 8e05c2fa9f..6320ed515a 100644 --- a/tools/clang/unittests/HLSL/HLSLTestOptions.h +++ b/include/dxc/Test/HLSLTestOptions.h @@ -26,18 +26,19 @@ namespace hlsl { namespace testOptions { /// \brief Command line option that specifies the path to the directory that -/// contains files that have the HLSL source code (used for the CodeGen test flow). +/// contains files that have the HLSL source code (used for the CodeGen test +/// flow). #define ARG_DECLARE(argname) extern std::string argname; -#define ARG_LIST(ARGOP)\ - ARGOP(HlslDataDir)\ - ARGOP(TestName)\ - ARGOP(DXBC)\ - ARGOP(SaveImages)\ - ARGOP(ExperimentalShaders)\ - ARGOP(DebugLayer)\ - ARGOP(SuitePath)\ - ARGOP(InputPath) +#define ARG_LIST(ARGOP) \ + ARGOP(HlslDataDir) \ + ARGOP(TestName) \ + ARGOP(DXBC) \ + ARGOP(SaveImages) \ + ARGOP(ExperimentalShaders) \ + ARGOP(DebugLayer) \ + ARGOP(SuitePath) \ + ARGOP(InputPath) ARG_LIST(ARG_DECLARE) diff --git a/tools/clang/test/Dxil2Spv/passthru-cs.ll b/tools/clang/test/Dxil2Spv/passthru-cs.ll index e7aa76407b..3fc2fd279a 100644 --- a/tools/clang/test/Dxil2Spv/passthru-cs.ll +++ b/tools/clang/test/Dxil2Spv/passthru-cs.ll @@ -1,4 +1,4 @@ -; RUN: %dxil2spv +; RUN: %dxil2spv | %FileCheck %s ; ; Input signature: ; @@ -82,94 +82,93 @@ attributes #2 = { nounwind } !10 = !{i32 0, i64 16, i32 4, !11} !11 = !{i32 1, i32 1, i32 1} -; CHECK-WHOLE-SPIR-V: -; ; SPIR-V -; ; Version: 1.0 -; ; Generator: Google spiregg; 0 -; ; Bound: 59 -; ; Schema: 0 -; OpCapability Shader -; OpMemoryModel Logical GLSL450 -; OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID -; OpExecutionMode %main LocalSize 1 1 1 -; OpName %type_ByteAddressBuffer "type.ByteAddressBuffer" -; OpName %type_RWByteAddressBuffer "type.RWByteAddressBuffer" -; OpName %main "main" -; OpName %dx_types_ResRet_i32 "dx.types.ResRet.i32" -; OpDecorate %3 DescriptorSet 0 -; OpDecorate %3 Binding 0 -; OpDecorate %4 DescriptorSet 0 -; OpDecorate %4 Binding 1 -; OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId -; OpDecorate %_runtimearr_uint ArrayStride 4 -; OpMemberDecorate %type_ByteAddressBuffer 0 Offset 0 -; OpMemberDecorate %type_ByteAddressBuffer 0 NonWritable -; OpDecorate %type_ByteAddressBuffer BufferBlock -; OpMemberDecorate %type_RWByteAddressBuffer 0 Offset 0 -; OpDecorate %type_RWByteAddressBuffer BufferBlock -; %uint = OpTypeInt 32 0 -; %uint_0 = OpConstant %uint 0 -; %uint_2 = OpConstant %uint 2 -; %uint_1 = OpConstant %uint 1 -; %uint_3 = OpConstant %uint 3 -; %uint_4 = OpConstant %uint 4 -; %_runtimearr_uint = OpTypeRuntimeArray %uint -; %type_ByteAddressBuffer = OpTypeStruct %_runtimearr_uint -; %_ptr_Uniform_type_ByteAddressBuffer = OpTypePointer Uniform %type_ByteAddressBuffer -; %type_RWByteAddressBuffer = OpTypeStruct %_runtimearr_uint -; %_ptr_Uniform_type_RWByteAddressBuffer = OpTypePointer Uniform %type_RWByteAddressBuffer -; %v3uint = OpTypeVector %uint 3 -; %_ptr_Input_v3uint = OpTypePointer Input %v3uint -; %void = OpTypeVoid -; %19 = OpTypeFunction %void -; %int = OpTypeInt 32 1 -; %dx_types_ResRet_i32 = OpTypeStruct %int %int %int %int %int -; %_ptr_Function_dx_types_ResRet_i32 = OpTypePointer Function %dx_types_ResRet_i32 -; %_ptr_Input_uint = OpTypePointer Input %uint -; %_ptr_Uniform_uint = OpTypePointer Uniform %uint -; %_ptr_Function_int = OpTypePointer Function %int -; %3 = OpVariable %_ptr_Uniform_type_ByteAddressBuffer Uniform -; %4 = OpVariable %_ptr_Uniform_type_RWByteAddressBuffer Uniform -; %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input -; %main = OpFunction %void None %19 -; %20 = OpLabel -; %24 = OpVariable %_ptr_Function_dx_types_ResRet_i32 Function -; %26 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 -; %27 = OpLoad %uint %26 -; %28 = OpShiftLeftLogical %uint %27 %uint_2 -; %29 = OpIAdd %uint %28 %uint_0 -; %31 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %29 -; %32 = OpLoad %uint %31 -; %34 = OpAccessChain %_ptr_Function_int %24 %uint_0 -; %35 = OpBitcast %int %32 -; OpStore %34 %35 -; %36 = OpIAdd %uint %28 %uint_1 -; %37 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %36 -; %38 = OpLoad %uint %37 -; %39 = OpAccessChain %_ptr_Function_int %24 %uint_1 -; %40 = OpBitcast %int %38 -; OpStore %39 %40 -; %41 = OpIAdd %uint %28 %uint_2 -; %42 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %41 -; %43 = OpLoad %uint %42 -; %44 = OpAccessChain %_ptr_Function_int %24 %uint_2 -; %45 = OpBitcast %int %43 -; OpStore %44 %45 -; %46 = OpIAdd %uint %28 %uint_3 -; %47 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %46 -; %48 = OpLoad %uint %47 -; %49 = OpAccessChain %_ptr_Function_int %24 %uint_3 -; %50 = OpBitcast %int %48 -; OpStore %49 %50 -; %51 = OpIAdd %uint %28 %uint_4 -; %52 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %51 -; %53 = OpLoad %uint %52 -; %54 = OpAccessChain %_ptr_Function_int %24 %uint_4 -; %55 = OpBitcast %int %53 -; OpStore %54 %55 -; %56 = OpAccessChain %_ptr_Function_int %24 %uint_0 -; %57 = OpAccessChain %_ptr_Uniform_uint %4 %uint_0 %28 -; %58 = OpBitcast %uint %56 -; OpStore %57 %58 -; OpReturn -; OpFunctionEnd +; CHECK: ; SPIR-V +; CHECK-NEXT: ; Version: 1.0 +; CHECK-NEXT: ; Generator: Google spiregg; 0 +; CHECK-NEXT: ; Bound: 59 +; CHECK-NEXT: ; Schema: 0 +; CHECK-NEXT: OpCapability Shader +; CHECK-NEXT: OpMemoryModel Logical GLSL450 +; CHECK-NEXT: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID +; CHECK-NEXT: OpExecutionMode %main LocalSize 1 1 1 +; CHECK-NEXT: OpName %type_ByteAddressBuffer "type.ByteAddressBuffer" +; CHECK-NEXT: OpName %type_RWByteAddressBuffer "type.RWByteAddressBuffer" +; CHECK-NEXT: OpName %main "main" +; CHECK-NEXT: OpName %dx_types_ResRet_i32 "dx.types.ResRet.i32" +; CHECK-NEXT: OpDecorate %3 DescriptorSet 0 +; CHECK-NEXT: OpDecorate %3 Binding 0 +; CHECK-NEXT: OpDecorate %4 DescriptorSet 0 +; CHECK-NEXT: OpDecorate %4 Binding 1 +; CHECK-NEXT: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId +; CHECK-NEXT: OpDecorate %_runtimearr_uint ArrayStride 4 +; CHECK-NEXT: OpMemberDecorate %type_ByteAddressBuffer 0 Offset 0 +; CHECK-NEXT: OpMemberDecorate %type_ByteAddressBuffer 0 NonWritable +; CHECK-NEXT: OpDecorate %type_ByteAddressBuffer BufferBlock +; CHECK-NEXT: OpMemberDecorate %type_RWByteAddressBuffer 0 Offset 0 +; CHECK-NEXT: OpDecorate %type_RWByteAddressBuffer BufferBlock +; CHECK-NEXT: %uint = OpTypeInt 32 0 +; CHECK-NEXT: %uint_0 = OpConstant %uint 0 +; CHECK-NEXT: %uint_2 = OpConstant %uint 2 +; CHECK-NEXT: %uint_1 = OpConstant %uint 1 +; CHECK-NEXT: %uint_3 = OpConstant %uint 3 +; CHECK-NEXT: %uint_4 = OpConstant %uint 4 +; CHECK-NEXT: %_runtimearr_uint = OpTypeRuntimeArray %uint +; CHECK-NEXT: %type_ByteAddressBuffer = OpTypeStruct %_runtimearr_uint +; CHECK-NEXT: %_ptr_Uniform_type_ByteAddressBuffer = OpTypePointer Uniform %type_ByteAddressBuffer +; CHECK-NEXT: %type_RWByteAddressBuffer = OpTypeStruct %_runtimearr_uint +; CHECK-NEXT: %_ptr_Uniform_type_RWByteAddressBuffer = OpTypePointer Uniform %type_RWByteAddressBuffer +; CHECK-NEXT: %v3uint = OpTypeVector %uint 3 +; CHECK-NEXT: %_ptr_Input_v3uint = OpTypePointer Input %v3uint +; CHECK-NEXT: %void = OpTypeVoid +; CHECK-NEXT: %19 = OpTypeFunction %void +; CHECK-NEXT: %int = OpTypeInt 32 1 +; CHECK-NEXT: %dx_types_ResRet_i32 = OpTypeStruct %int %int %int %int %int +; CHECK-NEXT: %_ptr_Function_dx_types_ResRet_i32 = OpTypePointer Function %dx_types_ResRet_i32 +; CHECK-NEXT: %_ptr_Input_uint = OpTypePointer Input %uint +; CHECK-NEXT: %_ptr_Uniform_uint = OpTypePointer Uniform %uint +; CHECK-NEXT: %_ptr_Function_int = OpTypePointer Function %int +; CHECK-NEXT: %3 = OpVariable %_ptr_Uniform_type_ByteAddressBuffer Uniform +; CHECK-NEXT: %4 = OpVariable %_ptr_Uniform_type_RWByteAddressBuffer Uniform +; CHECK-NEXT: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +; CHECK-NEXT: %main = OpFunction %void None %19 +; CHECK-NEXT: %20 = OpLabel +; CHECK-NEXT: %24 = OpVariable %_ptr_Function_dx_types_ResRet_i32 Function +; CHECK-NEXT: %26 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0 +; CHECK-NEXT: %27 = OpLoad %uint %26 +; CHECK-NEXT: %28 = OpShiftLeftLogical %uint %27 %uint_2 +; CHECK-NEXT: %29 = OpIAdd %uint %28 %uint_0 +; CHECK-NEXT: %31 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %29 +; CHECK-NEXT: %32 = OpLoad %uint %31 +; CHECK-NEXT: %34 = OpAccessChain %_ptr_Function_int %24 %uint_0 +; CHECK-NEXT: %35 = OpBitcast %int %32 +; CHECK-NEXT: OpStore %34 %35 +; CHECK-NEXT: %36 = OpIAdd %uint %28 %uint_1 +; CHECK-NEXT: %37 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %36 +; CHECK-NEXT: %38 = OpLoad %uint %37 +; CHECK-NEXT: %39 = OpAccessChain %_ptr_Function_int %24 %uint_1 +; CHECK-NEXT: %40 = OpBitcast %int %38 +; CHECK-NEXT: OpStore %39 %40 +; CHECK-NEXT: %41 = OpIAdd %uint %28 %uint_2 +; CHECK-NEXT: %42 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %41 +; CHECK-NEXT: %43 = OpLoad %uint %42 +; CHECK-NEXT: %44 = OpAccessChain %_ptr_Function_int %24 %uint_2 +; CHECK-NEXT: %45 = OpBitcast %int %43 +; CHECK-NEXT: OpStore %44 %45 +; CHECK-NEXT: %46 = OpIAdd %uint %28 %uint_3 +; CHECK-NEXT: %47 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %46 +; CHECK-NEXT: %48 = OpLoad %uint %47 +; CHECK-NEXT: %49 = OpAccessChain %_ptr_Function_int %24 %uint_3 +; CHECK-NEXT: %50 = OpBitcast %int %48 +; CHECK-NEXT: OpStore %49 %50 +; CHECK-NEXT: %51 = OpIAdd %uint %28 %uint_4 +; CHECK-NEXT: %52 = OpAccessChain %_ptr_Uniform_uint %3 %uint_0 %51 +; CHECK-NEXT: %53 = OpLoad %uint %52 +; CHECK-NEXT: %54 = OpAccessChain %_ptr_Function_int %24 %uint_4 +; CHECK-NEXT: %55 = OpBitcast %int %53 +; CHECK-NEXT: OpStore %54 %55 +; CHECK-NEXT: %56 = OpAccessChain %_ptr_Function_int %24 %uint_0 +; CHECK-NEXT: %57 = OpAccessChain %_ptr_Uniform_uint %4 %uint_0 %28 +; CHECK-NEXT: %58 = OpBitcast %uint %56 +; CHECK-NEXT: OpStore %57 %58 +; CHECK-NEXT: OpReturn +; CHECK-NEXT: OpFunctionEnd diff --git a/tools/clang/test/Dxil2Spv/passthru-ps.ll b/tools/clang/test/Dxil2Spv/passthru-ps.ll index 3e4c88e1e9..6ba7114354 100644 --- a/tools/clang/test/Dxil2Spv/passthru-ps.ll +++ b/tools/clang/test/Dxil2Spv/passthru-ps.ll @@ -1,4 +1,4 @@ -; RUN: %dxil2spv +; RUN: %dxil2spv | %FileCheck %s ; ; Input signature: ; @@ -101,55 +101,54 @@ attributes #1 = { nounwind } !12 = !{!13} !13 = !{i32 0, !"SV_Target", i8 9, i8 16, !9, i8 0, i32 1, i8 4, i32 0, i8 0, !11} -; CHECK-WHOLE-SPIR-V: -; ; SPIR-V -; ; Version: 1.0 -; ; Generator: Google spiregg; 0 -; ; Bound: 31 -; ; Schema: 0 -; OpCapability Shader -; OpMemoryModel Logical GLSL450 -; OpEntryPoint Fragment %PSMain "PSMain" %gl_Position %COLOR %SV_Target -; OpExecutionMode %PSMain OriginUpperLeft -; OpName %COLOR "COLOR" -; OpName %SV_Target "SV_Target" -; OpName %PSMain "PSMain" -; OpDecorate %gl_Position BuiltIn Position -; OpDecorate %COLOR Location 1 -; OpDecorate %SV_Target Location 0 -; %uint = OpTypeInt 32 0 -; %uint_0 = OpConstant %uint 0 -; %uint_1 = OpConstant %uint 1 -; %uint_2 = OpConstant %uint 2 -; %uint_3 = OpConstant %uint 3 -; %float = OpTypeFloat 32 -; %v4float = OpTypeVector %float 4 -; %_ptr_Input_v4float = OpTypePointer Input %v4float -; %_ptr_Output_v4float = OpTypePointer Output %v4float -; %void = OpTypeVoid -; %15 = OpTypeFunction %void -; %_ptr_Input_float = OpTypePointer Input %float -; %_ptr_Output_float = OpTypePointer Output %float -; %gl_Position = OpVariable %_ptr_Input_v4float Input -; %COLOR = OpVariable %_ptr_Input_v4float Input -; %SV_Target = OpVariable %_ptr_Output_v4float Output -; %PSMain = OpFunction %void None %15 -; %16 = OpLabel -; %18 = OpAccessChain %_ptr_Input_float %COLOR %uint_0 -; %19 = OpLoad %float %18 -; %20 = OpAccessChain %_ptr_Input_float %COLOR %uint_1 -; %21 = OpLoad %float %20 -; %22 = OpAccessChain %_ptr_Input_float %COLOR %uint_2 -; %23 = OpLoad %float %22 -; %24 = OpAccessChain %_ptr_Input_float %COLOR %uint_3 -; %25 = OpLoad %float %24 -; %27 = OpAccessChain %_ptr_Output_float %SV_Target %uint_0 -; OpStore %27 %19 -; %28 = OpAccessChain %_ptr_Output_float %SV_Target %uint_1 -; OpStore %28 %21 -; %29 = OpAccessChain %_ptr_Output_float %SV_Target %uint_2 -; OpStore %29 %23 -; %30 = OpAccessChain %_ptr_Output_float %SV_Target %uint_3 -; OpStore %30 %25 -; OpReturn -; OpFunctionEnd +; CHECK: ; SPIR-V +; CHECK-NEXT: ; Version: 1.0 +; CHECK-NEXT: ; Generator: Google spiregg; 0 +; CHECK-NEXT: ; Bound: 31 +; CHECK-NEXT: ; Schema: 0 +; CHECK-NEXT: OpCapability Shader +; CHECK-NEXT: OpMemoryModel Logical GLSL450 +; CHECK-NEXT: OpEntryPoint Fragment %PSMain "PSMain" %gl_Position %COLOR %SV_Target +; CHECK-NEXT: OpExecutionMode %PSMain OriginUpperLeft +; CHECK-NEXT: OpName %COLOR "COLOR" +; CHECK-NEXT: OpName %SV_Target "SV_Target" +; CHECK-NEXT: OpName %PSMain "PSMain" +; CHECK-NEXT: OpDecorate %gl_Position BuiltIn Position +; CHECK-NEXT: OpDecorate %COLOR Location 1 +; CHECK-NEXT: OpDecorate %SV_Target Location 0 +; CHECK-NEXT: %uint = OpTypeInt 32 0 +; CHECK-NEXT: %uint_0 = OpConstant %uint 0 +; CHECK-NEXT: %uint_1 = OpConstant %uint 1 +; CHECK-NEXT: %uint_2 = OpConstant %uint 2 +; CHECK-NEXT: %uint_3 = OpConstant %uint 3 +; CHECK-NEXT: %float = OpTypeFloat 32 +; CHECK-NEXT: %v4float = OpTypeVector %float 4 +; CHECK-NEXT: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK-NEXT: %_ptr_Output_v4float = OpTypePointer Output %v4float +; CHECK-NEXT: %void = OpTypeVoid +; CHECK-NEXT: %15 = OpTypeFunction %void +; CHECK-NEXT: %_ptr_Input_float = OpTypePointer Input %float +; CHECK-NEXT: %_ptr_Output_float = OpTypePointer Output %float +; CHECK-NEXT: %gl_Position = OpVariable %_ptr_Input_v4float Input +; CHECK-NEXT: %COLOR = OpVariable %_ptr_Input_v4float Input +; CHECK-NEXT: %SV_Target = OpVariable %_ptr_Output_v4float Output +; CHECK-NEXT: %PSMain = OpFunction %void None %15 +; CHECK-NEXT: %16 = OpLabel +; CHECK-NEXT: %18 = OpAccessChain %_ptr_Input_float %COLOR %uint_0 +; CHECK-NEXT: %19 = OpLoad %float %18 +; CHECK-NEXT: %20 = OpAccessChain %_ptr_Input_float %COLOR %uint_1 +; CHECK-NEXT: %21 = OpLoad %float %20 +; CHECK-NEXT: %22 = OpAccessChain %_ptr_Input_float %COLOR %uint_2 +; CHECK-NEXT: %23 = OpLoad %float %22 +; CHECK-NEXT: %24 = OpAccessChain %_ptr_Input_float %COLOR %uint_3 +; CHECK-NEXT: %25 = OpLoad %float %24 +; CHECK-NEXT: %27 = OpAccessChain %_ptr_Output_float %SV_Target %uint_0 +; CHECK-NEXT: OpStore %27 %19 +; CHECK-NEXT: %28 = OpAccessChain %_ptr_Output_float %SV_Target %uint_1 +; CHECK-NEXT: OpStore %28 %21 +; CHECK-NEXT: %29 = OpAccessChain %_ptr_Output_float %SV_Target %uint_2 +; CHECK-NEXT: OpStore %29 %23 +; CHECK-NEXT: %30 = OpAccessChain %_ptr_Output_float %SV_Target %uint_3 +; CHECK-NEXT: OpStore %30 %25 +; CHECK-NEXT: OpReturn +; CHECK-NEXT: OpFunctionEnd diff --git a/tools/clang/test/Dxil2Spv/passthru-vs.ll b/tools/clang/test/Dxil2Spv/passthru-vs.ll index 1ebdcff231..b4081ec102 100644 --- a/tools/clang/test/Dxil2Spv/passthru-vs.ll +++ b/tools/clang/test/Dxil2Spv/passthru-vs.ll @@ -1,4 +1,4 @@ -; RUN: %dxil2spv +; RUN: %dxil2spv | %FileCheck %s ; ; Input signature: ; @@ -115,73 +115,72 @@ attributes #1 = { nounwind } !13 = !{i32 0, !"SV_Position", i8 9, i8 3, !9, i8 4, i32 1, i8 4, i32 0, i8 0, !10} !14 = !{i32 1, !"COLOR", i8 9, i8 0, !9, i8 2, i32 1, i8 4, i32 1, i8 0, !10} -; CHECK-WHOLE-SPIR-V: -; ; SPIR-V -; ; Version: 1.0 -; ; Generator: Google spiregg; 0 -; ; Bound: 44 -; ; Schema: 0 -; OpCapability Shader -; OpMemoryModel Logical GLSL450 -; OpEntryPoint Vertex %VSMain "VSMain" %POSITION %COLOR %gl_Position %COLOR_0 -; OpName %POSITION "POSITION" -; OpName %COLOR "COLOR" -; OpName %COLOR_0 "COLOR" -; OpName %VSMain "VSMain" -; OpDecorate %POSITION Location 0 -; OpDecorate %COLOR Location 1 -; OpDecorate %gl_Position BuiltIn Position -; OpDecorate %COLOR_0 Location 1 -; %uint = OpTypeInt 32 0 -; %uint_0 = OpConstant %uint 0 -; %uint_1 = OpConstant %uint 1 -; %uint_2 = OpConstant %uint 2 -; %uint_3 = OpConstant %uint 3 -; %float = OpTypeFloat 32 -; %v4float = OpTypeVector %float 4 -; %_ptr_Input_v4float = OpTypePointer Input %v4float -; %_ptr_Output_v4float = OpTypePointer Output %v4float -; %void = OpTypeVoid -; %16 = OpTypeFunction %void -; %_ptr_Input_float = OpTypePointer Input %float -; %_ptr_Output_float = OpTypePointer Output %float -; %POSITION = OpVariable %_ptr_Input_v4float Input -; %COLOR = OpVariable %_ptr_Input_v4float Input -; %gl_Position = OpVariable %_ptr_Output_v4float Output -; %COLOR_0 = OpVariable %_ptr_Output_v4float Output -; %VSMain = OpFunction %void None %16 -; %17 = OpLabel -; %19 = OpAccessChain %_ptr_Input_float %COLOR %uint_0 -; %20 = OpLoad %float %19 -; %21 = OpAccessChain %_ptr_Input_float %COLOR %uint_1 -; %22 = OpLoad %float %21 -; %23 = OpAccessChain %_ptr_Input_float %COLOR %uint_2 -; %24 = OpLoad %float %23 -; %25 = OpAccessChain %_ptr_Input_float %COLOR %uint_3 -; %26 = OpLoad %float %25 -; %27 = OpAccessChain %_ptr_Input_float %POSITION %uint_0 -; %28 = OpLoad %float %27 -; %29 = OpAccessChain %_ptr_Input_float %POSITION %uint_1 -; %30 = OpLoad %float %29 -; %31 = OpAccessChain %_ptr_Input_float %POSITION %uint_2 -; %32 = OpLoad %float %31 -; %33 = OpAccessChain %_ptr_Input_float %POSITION %uint_3 -; %34 = OpLoad %float %33 -; %36 = OpAccessChain %_ptr_Output_float %gl_Position %uint_0 -; OpStore %36 %28 -; %37 = OpAccessChain %_ptr_Output_float %gl_Position %uint_1 -; OpStore %37 %30 -; %38 = OpAccessChain %_ptr_Output_float %gl_Position %uint_2 -; OpStore %38 %32 -; %39 = OpAccessChain %_ptr_Output_float %gl_Position %uint_3 -; OpStore %39 %34 -; %40 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_0 -; OpStore %40 %20 -; %41 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_1 -; OpStore %41 %22 -; %42 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_2 -; OpStore %42 %24 -; %43 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_3 -; OpStore %43 %26 -; OpReturn -; OpFunctionEnd +; CHECK: ; SPIR-V +; CHECK-NEXT: ; Version: 1.0 +; CHECK-NEXT: ; Generator: Google spiregg; 0 +; CHECK-NEXT: ; Bound: 44 +; CHECK-NEXT: ; Schema: 0 +; CHECK-NEXT: OpCapability Shader +; CHECK-NEXT: OpMemoryModel Logical GLSL450 +; CHECK-NEXT: OpEntryPoint Vertex %VSMain "VSMain" %POSITION %COLOR %gl_Position %COLOR_0 +; CHECK-NEXT: OpName %POSITION "POSITION" +; CHECK-NEXT: OpName %COLOR "COLOR" +; CHECK-NEXT: OpName %COLOR_0 "COLOR" +; CHECK-NEXT: OpName %VSMain "VSMain" +; CHECK-NEXT: OpDecorate %POSITION Location 0 +; CHECK-NEXT: OpDecorate %COLOR Location 1 +; CHECK-NEXT: OpDecorate %gl_Position BuiltIn Position +; CHECK-NEXT: OpDecorate %COLOR_0 Location 1 +; CHECK-NEXT: %uint = OpTypeInt 32 0 +; CHECK-NEXT: %uint_0 = OpConstant %uint 0 +; CHECK-NEXT: %uint_1 = OpConstant %uint 1 +; CHECK-NEXT: %uint_2 = OpConstant %uint 2 +; CHECK-NEXT: %uint_3 = OpConstant %uint 3 +; CHECK-NEXT: %float = OpTypeFloat 32 +; CHECK-NEXT: %v4float = OpTypeVector %float 4 +; CHECK-NEXT: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK-NEXT: %_ptr_Output_v4float = OpTypePointer Output %v4float +; CHECK-NEXT: %void = OpTypeVoid +; CHECK-NEXT: %16 = OpTypeFunction %void +; CHECK-NEXT: %_ptr_Input_float = OpTypePointer Input %float +; CHECK-NEXT: %_ptr_Output_float = OpTypePointer Output %float +; CHECK-NEXT: %POSITION = OpVariable %_ptr_Input_v4float Input +; CHECK-NEXT: %COLOR = OpVariable %_ptr_Input_v4float Input +; CHECK-NEXT: %gl_Position = OpVariable %_ptr_Output_v4float Output +; CHECK-NEXT: %COLOR_0 = OpVariable %_ptr_Output_v4float Output +; CHECK-NEXT: %VSMain = OpFunction %void None %16 +; CHECK-NEXT: %17 = OpLabel +; CHECK-NEXT: %19 = OpAccessChain %_ptr_Input_float %COLOR %uint_0 +; CHECK-NEXT: %20 = OpLoad %float %19 +; CHECK-NEXT: %21 = OpAccessChain %_ptr_Input_float %COLOR %uint_1 +; CHECK-NEXT: %22 = OpLoad %float %21 +; CHECK-NEXT: %23 = OpAccessChain %_ptr_Input_float %COLOR %uint_2 +; CHECK-NEXT: %24 = OpLoad %float %23 +; CHECK-NEXT: %25 = OpAccessChain %_ptr_Input_float %COLOR %uint_3 +; CHECK-NEXT: %26 = OpLoad %float %25 +; CHECK-NEXT: %27 = OpAccessChain %_ptr_Input_float %POSITION %uint_0 +; CHECK-NEXT: %28 = OpLoad %float %27 +; CHECK-NEXT: %29 = OpAccessChain %_ptr_Input_float %POSITION %uint_1 +; CHECK-NEXT: %30 = OpLoad %float %29 +; CHECK-NEXT: %31 = OpAccessChain %_ptr_Input_float %POSITION %uint_2 +; CHECK-NEXT: %32 = OpLoad %float %31 +; CHECK-NEXT: %33 = OpAccessChain %_ptr_Input_float %POSITION %uint_3 +; CHECK-NEXT: %34 = OpLoad %float %33 +; CHECK-NEXT: %36 = OpAccessChain %_ptr_Output_float %gl_Position %uint_0 +; CHECK-NEXT: OpStore %36 %28 +; CHECK-NEXT: %37 = OpAccessChain %_ptr_Output_float %gl_Position %uint_1 +; CHECK-NEXT: OpStore %37 %30 +; CHECK-NEXT: %38 = OpAccessChain %_ptr_Output_float %gl_Position %uint_2 +; CHECK-NEXT: OpStore %38 %32 +; CHECK-NEXT: %39 = OpAccessChain %_ptr_Output_float %gl_Position %uint_3 +; CHECK-NEXT: OpStore %39 %34 +; CHECK-NEXT: %40 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_0 +; CHECK-NEXT: OpStore %40 %20 +; CHECK-NEXT: %41 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_1 +; CHECK-NEXT: OpStore %41 %22 +; CHECK-NEXT: %42 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_2 +; CHECK-NEXT: OpStore %42 %24 +; CHECK-NEXT: %43 = OpAccessChain %_ptr_Output_float %COLOR_0 %uint_3 +; CHECK-NEXT: OpStore %43 %26 +; CHECK-NEXT: OpReturn +; CHECK-NEXT: OpFunctionEnd diff --git a/tools/clang/test/Dxil2Spv/static-vertex.hlsl b/tools/clang/test/Dxil2Spv/static-vertex.hlsl new file mode 100644 index 0000000000..8c067f729e --- /dev/null +++ b/tools/clang/test/Dxil2Spv/static-vertex.hlsl @@ -0,0 +1,10 @@ +// dxc -T ps_6_0 static-vertex.hlsl -Fc static-vertex.ll +struct VSOutput { + float4 Position : SV_POSITION; + float3 Color : COLOR; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + return float4(input.Color, 1); +}; diff --git a/tools/clang/test/Dxil2Spv/static-vertex.ll b/tools/clang/test/Dxil2Spv/static-vertex.ll new file mode 100644 index 0000000000..a3a5d5f7b3 --- /dev/null +++ b/tools/clang/test/Dxil2Spv/static-vertex.ll @@ -0,0 +1,113 @@ +; RUN: %dxil2spv %s | %FileCheck %s +; +; Input signature: +; +; Name Index Mask Register SysValue Format Used +; -------------------- ----- ------ -------- -------- ------- ------ +; SV_Position 0 xyzw 0 POS float +; COLOR 0 xyz 1 NONE float xyz +; +; +; Output signature: +; +; Name Index Mask Register SysValue Format Used +; -------------------- ----- ------ -------- -------- ------- ------ +; SV_Target 0 xyzw 0 TARGET float xyzw +; +; shader hash: c23cfb9164637d35921d87c5895173ea +; +; Pipeline Runtime Information: +; +; Pixel Shader +; DepthOutput=0 +; SampleFrequency=0 +; +; +; Input signature: +; +; Name Index InterpMode DynIdx +; -------------------- ----- ---------------------- ------ +; SV_Position 0 noperspective +; COLOR 0 linear +; +; Output signature: +; +; Name Index InterpMode DynIdx +; -------------------- ----- ---------------------- ------ +; SV_Target 0 +; +; Buffer Definitions: +; +; +; Resource Bindings: +; +; Name Type Format Dim ID HLSL Bind Count +; ------------------------------ ---------- ------- ----------- ------- -------------- ------ +; +; +; ViewId state: +; +; Number of inputs: 7, outputs: 4 +; Outputs dependent on ViewId: { } +; Inputs contributing to computation of Outputs: +; output 0 depends on inputs: { 4 } +; output 1 depends on inputs: { 5 } +; output 2 depends on inputs: { 6 } +; +target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +; CHECK: %float_1 = OpConstant %float 1 + +define void @main() { +; CHECK: %gl_Position = OpVariable %_ptr_Input_v4float Input + %1 = call float @dx.op.loadInput.f32(i32 4, i32 1, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis) + +; CHECK: %COLOR = OpVariable %_ptr_Input_v3float Input + %2 = call float @dx.op.loadInput.f32(i32 4, i32 1, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis) + +; CHECK: %SV_Target = OpVariable %_ptr_Output_v4float Output + %3 = call float @dx.op.loadInput.f32(i32 4, i32 1, i32 0, i8 2, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis) + + call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %1) ; StoreOutput(outputSigId,rowIndex,colIndex,value) + call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %2) ; StoreOutput(outputSigId,rowIndex,colIndex,value) + call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %3) ; StoreOutput(outputSigId,rowIndex,colIndex,value) + +; CHECK: [[v0:%[0-9]+]] = OpAccessChain %_ptr_Output_float %SV_Target %uint_3 +; CHECK: OpStore [[v0]] %float_1 + call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float 1.000000e+00) ; StoreOutput(outputSigId,rowIndex,colIndex,value) + ret void +} + +; Function Attrs: nounwind readnone +declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0 + +; Function Attrs: nounwind +declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1 + +attributes #0 = { nounwind readnone } +attributes #1 = { nounwind } + +!llvm.ident = !{!0} +!dx.version = !{!1} +!dx.valver = !{!2} +!dx.shaderModel = !{!3} +!dx.viewIdState = !{!4} +!dx.entryPoints = !{!5} + +!0 = !{!"clang version 3.7 (tags/RELEASE_370/final)"} +!1 = !{i32 1, i32 0} +!2 = !{i32 1, i32 7} +!3 = !{!"ps", i32 6, i32 0} +!4 = !{[9 x i32] [i32 7, i32 4, i32 0, i32 0, i32 0, i32 0, i32 1, i32 2, i32 4]} +!5 = !{void ()* @main, !"main", !6, null, null} +!6 = !{!7, !12, null} +!7 = !{!8, !10} +!8 = !{i32 0, !"SV_Position", i8 9, i8 3, !9, i8 4, i32 1, i8 4, i32 0, i8 0, null} +!9 = !{i32 0} +!10 = !{i32 1, !"COLOR", i8 9, i8 0, !9, i8 2, i32 1, i8 3, i32 1, i8 0, !11} +!11 = !{i32 3, i32 7} +!12 = !{!13} +!13 = !{i32 0, !"SV_Target", i8 9, i8 16, !9, i8 0, i32 1, i8 4, i32 0, i8 0, !14} +!14 = !{i32 3, i32 15} + diff --git a/tools/clang/unittests/Dxil2Spv/CMakeLists.txt b/tools/clang/unittests/Dxil2Spv/CMakeLists.txt index e21601396e..76aed8717d 100644 --- a/tools/clang/unittests/Dxil2Spv/CMakeLists.txt +++ b/tools/clang/unittests/Dxil2Spv/CMakeLists.txt @@ -1,27 +1,25 @@ set(LLVM_LINK_COMPONENTS - Support dxcsupport dxil dxilrootsignature hlsl + Support ) add_clang_unittest(clang-dxil2spv-tests - TestMain.cpp - LitTest.cpp - WholeFileTestFixture.cpp - WholeFileTestFixture.h - FileTestUtils.cpp - FileTestUtils.h Dxil2SpvTestOptions.cpp Dxil2SpvTestOptions.h + FileTestUtils.cpp + FileTestUtils.h + LitTest.cpp + TestMain.cpp ) target_link_libraries(clang-dxil2spv-tests clangSPIRV dxcompiler dxil2spvlib - effcee + HLSLTestLib ) include_directories(${LLVM_SOURCE_DIR}/tools/clang/tools) diff --git a/tools/clang/unittests/Dxil2Spv/LitTest.cpp b/tools/clang/unittests/Dxil2Spv/LitTest.cpp index 86c38ceb44..59b534cb80 100644 --- a/tools/clang/unittests/Dxil2Spv/LitTest.cpp +++ b/tools/clang/unittests/Dxil2Spv/LitTest.cpp @@ -7,21 +7,54 @@ // //===----------------------------------------------------------------------===// -#include "WholeFileTestFixture.h" +#include "FileTestUtils.h" +#include "dxc/Test/DxcTestUtils.h" +#include "dxc/Test/WEXAdapter.h" namespace { -using clang::dxil2spv::WholeFileTest; -TEST_F(WholeFileTest, PassThruPixelShader) { - runWholeFileTest("passthru-ps.ll"); -} +#ifdef _WIN32 +class FileTest { +#else +class FileTest : public ::testing::Test { +#endif +public: + BEGIN_TEST_CLASS(FileTest) + TEST_CLASS_PROPERTY(L"Parallel", L"true") + TEST_METHOD_PROPERTY(L"Priority", L"0") + END_TEST_CLASS() -TEST_F(WholeFileTest, PassThruVertexShader) { - runWholeFileTest("passthru-vs.ll"); -} + TEST_CLASS_SETUP(InitSupport); + + dxc::DxcDllSupport m_dllSupport; + VersionSupportInfo m_version; + + void runFileTest(std::string name) { + std::string fullPath = + clang::dxil2spv::utils::getAbsPathOfInputDataFile(name); + FileRunTestResult result = + FileRunTestResult::RunFromFileCommands(CA2W(fullPath.c_str())); + if (result.RunResult != 0) { + WEX::Logging::Log::Error(L"FileTest failed"); + WEX::Logging::Log::Error(CA2W(result.ErrorMessage.c_str(), CP_UTF8)); + } + } +}; -TEST_F(WholeFileTest, PassThruComputeShader) { - runWholeFileTest("passthru-cs.ll"); +bool FileTest::InitSupport() { + if (!m_dllSupport.IsEnabled()) { + VERIFY_SUCCEEDED(m_dllSupport.Initialize()); + m_version.Initialize(m_dllSupport); + } + return true; } +TEST_F(FileTest, PassThruPixelShader) { runFileTest("passthru-ps.ll"); } + +TEST_F(FileTest, PassThruVertexShader) { runFileTest("passthru-vs.ll"); } + +TEST_F(FileTest, PassThruComputeShader) { runFileTest("passthru-cs.ll"); } + +TEST_F(FileTest, StaticVertex) { runFileTest("static-vertex.ll"); } + } // namespace diff --git a/tools/clang/unittests/Dxil2Spv/README.md b/tools/clang/unittests/Dxil2Spv/README.md new file mode 100644 index 0000000000..0839cdcb72 --- /dev/null +++ b/tools/clang/unittests/Dxil2Spv/README.md @@ -0,0 +1,72 @@ +# `dxil2spv` Tests + +## How to Add a Test + +These instructions assume the new test will be generated from HLSL source, +rather than hand-writing DXIL directly. Whenever this is the case, the HLSL +source should be preserved to aid in regenerating tests in future as needed +(i.e. if changes are made to `dxc` that warrant recompiling, or a new test needs +to be created as a modified version of an existing test). + +1. Create a new HLSL source file in `tools/clang/test/Dxil2Spv/`. + + For example, `my-new-test.hlsl`: + + ``` + struct VSOutput { + float4 Position : SV_POSITION; + float3 Color : COLOR; + }; + + float4 main(VSOutput input) : SV_TARGET + { + return float4(input.Color, 1); + }; + ``` + +2. Compile HLSL source file to DXIL. + + Use the appropriate `dxc` command to compile the HLSL source and output the + disassembled DXIL to a file with the same name and a `.ll` extension using + the option `-Fc`. + + For example: `dxc -T ps_6_0 my-new-test.hlsl -Fc my-new-test.ll` + +3. Add a comment the to the top of your HLSL source file with the compile + command used. + + `my-new-test.hlsl`: + + ``` + // dxc -T ps_6_0 my-new-test.hlsl -Fc my-new-test.ll + struct VSOutput { + [...] + ``` + +4. Add a `; RUN: %dxil2spv %s | %FileCheck %s` command to the top of your DXIL + test file. + + `my-new-test.ll`: + + ``` + ; RUN: %dxil2spv %s | %FileCheck %s + ; + ; Input signature: + [...] + ``` + +5. Add `CHECK` lines to test the generated SPIR-V. + + As needed for your test, add `CHECK` lines throughout the DXIL test file. See + the LLVM FileCheck documentation for more information about the `CHECK` types + supported and pattern matching syntax. + +6. Add the test to `tools/clang/unittests/Dxil2Spv/LitTest.cpp`. + + For example: + + ``` + TEST_F(FileTest, MyNewTest) { + runFileTest("my-new-test.ll"); + } + ``` diff --git a/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.cpp b/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.cpp deleted file mode 100644 index 7eb63c5c6c..0000000000 --- a/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.cpp +++ /dev/null @@ -1,121 +0,0 @@ -//===- WholeFileTestFixture.cpp - WholeFileTest impl-----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include - -#include "FileTestUtils.h" -#include "WholeFileTestFixture.h" - -namespace clang { -namespace dxil2spv { - -namespace { -const char dxilStartLabel[] = "; RUN:"; -const char spirvStartLabel[] = "; CHECK-WHOLE-SPIR-V:"; -const char errorStartLabel[] = "; CHECK-ERRORS:"; - -enum class ParsingStage : unsigned { - None = 0, - DXIL = 1, - SPIRV = 2, - ERRORS = 3 -}; -} // namespace - -bool WholeFileTest::parseInputFile() { - ParsingStage stage = ParsingStage::None; - bool foundRunCommand = false; - bool foundCheckCommand = false; - std::ostringstream outString; - std::ostringstream errString; - std::ifstream inputFile; - inputFile.exceptions(std::ifstream::failbit); - try { - inputFile.open(inputFilePath); - for (std::string line; std::getline(inputFile, line);) { - if (line.find(dxilStartLabel) != std::string::npos) { - stage = ParsingStage::DXIL; - foundRunCommand = true; - } else if (line.find(spirvStartLabel) != std::string::npos) { - // SPIR-V source starts on the next line. - stage = ParsingStage::SPIRV; - foundCheckCommand = true; - } else if (line.find(errorStartLabel) != std::string::npos) { - // Expected errors starts on the next line. - stage = ParsingStage::ERRORS; - foundCheckCommand = true; - } else if (stage == ParsingStage::SPIRV) { - // Strip the leading "; " from the SPIR-V assembly (skip 1 characters) - if (line.size() > 2u) { - line = line.substr(2); - } - if (line[line.size() - 1] == '\r') - line = line.substr(0, line.size() - 1); - outString << line << std::endl; - } else if (stage == ParsingStage::ERRORS) { - // Strip the leading "; " (skip 1 characters) - if (line.size() > 2u) { - line = line.substr(2); - } - if (line[line.size() - 1] == '\r') - line = line.substr(0, line.size() - 1); - errString << line << std::endl; - } - } - } catch (...) { - if (!inputFile.eof()) { - fprintf( - stderr, - "Error: Exception occurred while opening/reading the input file %s\n", - inputFilePath.c_str()); - return false; - } - } - - if (!foundRunCommand) { - fprintf(stderr, "Error: Missing \"RUN:\" command.\n"); - return false; - } - if (!foundCheckCommand) { - fprintf(stderr, "Error: Missing \"CHECK-WHOLE-SPIR-V:\" and/or " - "\"CHECK-ERRORS:\" command.\n"); - return false; - } - - // Reached the end of the file. SPIR-V source has ended. Store it for - // comparison. - expectedSpirvAsm = outString.str(); - expectedErrors = errString.str(); - - // Close the input file. - inputFile.close(); - - // Everything was successful. - return true; -} - -void WholeFileTest::runWholeFileTest(llvm::StringRef filename) { - inputFilePath = utils::getAbsPathOfInputDataFile(filename); - - // Parse the input file. - ASSERT_TRUE(parseInputFile()); - - // Feed the HLSL source into the Compiler. - ASSERT_TRUE(utils::translateFileWithDxil2Spv( - inputFilePath, &generatedSpirvAsm, &generatedErrors)); - - // Compare the expected and the generted SPIR-V code. - EXPECT_EQ(expectedSpirvAsm, generatedSpirvAsm); - - // Compare the expected and the generted errors. - EXPECT_EQ(expectedErrors, generatedErrors); -} - -} // end namespace dxil2spv -} // end namespace clang diff --git a/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.h b/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.h deleted file mode 100644 index f93d1b48a2..0000000000 --- a/tools/clang/unittests/Dxil2Spv/WholeFileTestFixture.h +++ /dev/null @@ -1,63 +0,0 @@ -//===- WholeFileTestFixture.h - Whole file test Fixture--------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_UNITTESTS_DXIL2SPV_WHOLEFILETESTFIXTURE_H -#define LLVM_CLANG_UNITTESTS_DXIL2SPV_WHOLEFILETESTFIXTURE_H - -#include "llvm/ADT/StringRef.h" -#include "gtest/gtest.h" - -namespace clang { -namespace dxil2spv { - -/// \brief The purpose of the this test class is to take in an input file with -/// the following format: -/// -/// ; Comments... -/// ; More comments... -/// ; RUN: %dxil2spv -/// ... -/// -/// ... -/// ; CHECK-WHOLE-SPIR-V: -/// ; ... -/// ; -/// ; ... -/// -/// This file is fully read in as the DXIL source (therefore any non-DXIL must -/// be commented out). It is fed to dxil2spv to translate to SPIR-V. The -/// resulting SPIR-V assembly text is compared to the second part of the input -/// file (after the directive). If these match, the test -/// is marked as a PASS, and marked as a FAILED otherwise. -class WholeFileTest : public ::testing::Test { -public: - /// \brief Runs a WHOLE-FILE-TEST! (See class description for more info) - /// Returns true if the test passes; false otherwise. - void runWholeFileTest(llvm::StringRef path); - - WholeFileTest() {} - -private: - /// \brief Reads in the given input file. - /// Stores the SPIR-V portion of the file into the - /// member variable. - /// Returns true on success, and false on failure. - bool parseInputFile(); - - std::string inputFilePath; ///< Path to the input test file - std::string expectedSpirvAsm; ///< Expected SPIR-V parsed from input - std::string generatedSpirvAsm; ///< Disassembled binary (SPIR-V code) - std::string expectedErrors; ///< Expected errors parsed from input - std::string generatedErrors; ///< Actual errors from running -}; - -} // end namespace dxil2spv -} // end namespace clang - -#endif diff --git a/tools/clang/unittests/HLSL/CMakeLists.txt b/tools/clang/unittests/HLSL/CMakeLists.txt index c7648b8ea4..ac648741ad 100644 --- a/tools/clang/unittests/HLSL/CMakeLists.txt +++ b/tools/clang/unittests/HLSL/CMakeLists.txt @@ -26,7 +26,6 @@ set( LLVM_LINK_COMPONENTS if(WIN32) set(HLSL_IGNORE_SOURCES TestMain.cpp - HLSLTestOptions.cpp ) add_clang_library(clang-hlsl-tests SHARED AllocatorTest.cpp @@ -70,7 +69,6 @@ add_clang_unittest(clang-hlsl-tests DXIsenseTest.cpp ExtensionTest.cpp FunctionTest.cpp - HLSLTestOptions.cpp Objects.cpp OptimizerTest.cpp OptionsTest.cpp diff --git a/tools/clang/unittests/HLSL/TestMain.cpp b/tools/clang/unittests/HLSL/TestMain.cpp index 8346f55390..cbb04c299c 100644 --- a/tools/clang/unittests/HLSL/TestMain.cpp +++ b/tools/clang/unittests/HLSL/TestMain.cpp @@ -12,7 +12,7 @@ #include "llvm/Support/Signals.h" -#include "HLSLTestOptions.h" +#include "dxc/Test/HLSLTestOptions.h" #include "dxc/Test/WEXAdapter.h" #if defined(_WIN32) diff --git a/tools/clang/unittests/HLSLTestLib/CMakeLists.txt b/tools/clang/unittests/HLSLTestLib/CMakeLists.txt index b1108f8d0b..64caf5c4f9 100644 --- a/tools/clang/unittests/HLSLTestLib/CMakeLists.txt +++ b/tools/clang/unittests/HLSLTestLib/CMakeLists.txt @@ -1,5 +1,8 @@ if(WIN32) +set(HLSL_IGNORE_SOURCES + HLSLTestOptions.cpp +) find_package(TAEF REQUIRED) include_directories(${TAEF_INCLUDE_DIRS}) @@ -19,10 +22,26 @@ add_clang_library(HLSLTestLib DxcTestUtils.cpp FileCheckerTest.cpp FileCheckForTest.cpp + HLSLTestOptions.cpp ) include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include) include_directories(${LLVM_MAIN_SRC_DIR}/utils/unittest/googlemock/include) +if(ENABLE_DXIL2SPV) +target_compile_definitions(HLSLTestLib PRIVATE ENABLE_DXIL2SPV) + +target_include_directories(HLSLTestLib PRIVATE + ${LLVM_SOURCE_DIR}/tools/clang/tools + ${SPIRV_TOOLS_INCLUDE_DIR} + ${SPIRV_HEADER_INCLUDE_DIR} + ) +target_link_libraries(HLSLTestLib + clangSPIRV + dxcompiler + dxil2spvlib + ) +endif(ENABLE_DXIL2SPV) + endif(WIN32) add_dependencies(HLSLTestLib TablegenHLSLOptions) diff --git a/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp b/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp index 8d9974b1f1..59818815a8 100644 --- a/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp +++ b/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp @@ -29,18 +29,21 @@ #include "dxc/Test/HlslTestUtils.h" #include "dxc/Test/DxcTestUtils.h" -#include "llvm/Support/raw_os_ostream.h" -#include "llvm/Support/MD5.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" +#include "dxc/DxilContainer/DxilContainer.h" #include "dxc/Support/Global.h" -#include "dxc/Support/dxcapi.use.h" -#include "dxc/dxctools.h" #include "dxc/Support/HLSLOptions.h" #include "dxc/Support/Unicode.h" +#include "dxc/Support/dxcapi.use.h" #include "dxc/Support/microcom.h" -#include "dxc/DxilContainer/DxilContainer.h" +#include "dxc/dxctools.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/MD5.h" +#include "llvm/Support/MSFileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/raw_os_ostream.h" +#include "llvm/Support/raw_ostream.h" #ifdef _WIN32 // Reflection unsupported #include "dxc/Test/D3DReflectionDumper.h" @@ -51,6 +54,10 @@ using namespace hlsl::dump; #endif // WIN32 - Reflection unsupported +#ifdef ENABLE_DXIL2SPV +#include "dxil2spv/lib/dxil2spv.h" +#endif // ENABLE_DXIL2SPV + using namespace std; using namespace hlsl_test; @@ -137,6 +144,11 @@ FileRunCommandResult FileRunCommandPart::Run(dxc::DxcDllSupport &DllSupport, con return result; #endif // WIN32 - Linking unsupported } +#ifdef ENABLE_DXIL2SPV + else if (0 == _stricmp(Command.c_str(), "%dxil2spv")) { + return RunDxil2Spv(DllSupport, Prior); + } +#endif // ENABLE_DXIL2SPV else if (pPluginToolsPaths != nullptr) { auto it = pPluginToolsPaths->find(Command.c_str()); if (it != pPluginToolsPaths->end()) { @@ -1091,6 +1103,56 @@ FileRunCommandResult FileRunCommandPart::RunDxilVer(dxc::DxcDllSupport& DllSuppo return CheckDxilVer(DllSupport, RequiredDxilMajor, RequiredDxilMinor); } +#ifdef ENABLE_DXIL2SPV +FileRunCommandResult +FileRunCommandPart::RunDxil2Spv(dxc::DxcDllSupport &DllSupport, + const FileRunCommandResult *Prior) { + // Support piping stdin from prior if needed. + UNREFERENCED_PARAMETER(Prior); + bool success = true; + + std::string stdoutString; + std::string stderrString; + llvm::raw_string_ostream stdoutStream(stdoutString); + llvm::raw_string_ostream stderrStream(stderrString); + + try { + // Configure filesystem. + llvm::sys::fs::MSFileSystem *msf = nullptr; + HRESULT hr; + if (SUCCEEDED(hr = CreateMSFileSystemForDisk(&msf))) { + llvm::sys::fs::AutoPerThreadSystem pts(msf); + IFTLLVM(pts.error_code()); + + // Set up diagnostics. + clang::CompilerInstance instance; + auto *diagnosticPrinter = new clang::TextDiagnosticPrinter( + stderrStream, new clang::DiagnosticOptions()); + instance.createDiagnostics(diagnosticPrinter, false); + instance.setOutStream(&stdoutStream); + + // Set compiler options. + instance.getCodeGenOpts().MainFileName = CW2A(CommandFileName, CP_UTF8); + instance.getCodeGenOpts().SpirvOptions.targetEnv = "vulkan1.0"; + + clang::dxil2spv::Translator translator(instance); + translator.Run(); + } else { + success = false; + } + } catch (...) { + success = false; + } + + FileRunCommandResult result = {}; + result.StdOut = stdoutStream.str(); + result.StdErr = stderrStream.str(); + result.ExitCode = success ? 0 : 1; + + return result; +} +#endif // ENABLE_DXIL2SPV + #ifndef _WIN32 FileRunCommandResult FileRunCommandPart::RunFromPath(const std::string &toolPath, const FileRunCommandResult *Prior) { return FileRunCommandResult::Error("RunFromPath not supported"); diff --git a/tools/clang/unittests/HLSL/HLSLTestOptions.cpp b/tools/clang/unittests/HLSLTestLib/HLSLTestOptions.cpp similarity index 97% rename from tools/clang/unittests/HLSL/HLSLTestOptions.cpp rename to tools/clang/unittests/HLSLTestLib/HLSLTestOptions.cpp index a56dc161cd..121e2a4cbd 100644 --- a/tools/clang/unittests/HLSL/HLSLTestOptions.cpp +++ b/tools/clang/unittests/HLSLTestLib/HLSLTestOptions.cpp @@ -12,9 +12,9 @@ // //===----------------------------------------------------------------------===// -#include "HLSLTestOptions.h" -#include "dxc/Test/WEXAdapter.h" +#include "dxc/Test/HLSLTestOptions.h" #include "dxc/Support/WinAdapter.h" +#include "dxc/Test/WEXAdapter.h" namespace clang { namespace hlsl {