The code pattern that clang will generate for HLSL has changed from the original plan. This allows the SPIR-V backend to generate code for the current code generation. It looks for patterns of the form: ``` %1 = @llvm.spv.resource.handlefrombinding %2 = @llvm.spv.resource.getpointer(%1, index) load/store %2 ``` These three llvm-ir instruction are treated as a single unit that will 1. Generate or find the global variable identified by the call to `resource.handlefrombinding`. 2. Generate an OpLoad of the variable to get the handle to the image. 3. Generate an OpImageRead or OpImageWrite using that handle with the given index. This will generate the OpLoad in the same BB as the read/write. Note: Now that `resource.handlefrombinding` is not processed on its own, many existing tests had to be removed. We do not have intrinsics that are able to use handles to sampled images, input attachments, etc., so we cannot generate the load of the handle. These tests are removed for now, and will be added when those resource types are fully implemented.
44 lines
2.4 KiB
LLVM
44 lines
2.4 KiB
LLVM
; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
|
|
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
|
|
|
|
; CHECK: OpCapability Shader
|
|
; CHECK-NEXT: OpCapability StorageImageArrayDynamicIndexing
|
|
; CHECK-NEXT: OpCapability Image1D
|
|
; CHECK-NOT: OpCapability
|
|
|
|
; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
|
|
; CHECK-DAG: OpDecorate [[Var]] Binding 4
|
|
|
|
; CHECK-DAG: [[int:%[0-9]+]] = OpTypeInt 32 0
|
|
; CHECK-DAG: [[BufferType:%[0-9]+]] = OpTypeImage [[int]] 1D 2 0 0 2 R32i {{$}}
|
|
; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
|
|
; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
|
|
; CHECK-DAG: [[One:%[0-9]+]] = OpConstant [[int]] 1
|
|
; CHECK-DAG: [[Zero:%[0-9]+]] = OpConstant [[int]] 0
|
|
; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
|
|
; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
|
|
; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
|
|
|
|
; CHECK: {{%[0-9]+}} = OpFunction {{%[0-9]+}} DontInline {{%[0-9]+}}
|
|
; CHECK-NEXT: OpLabel
|
|
define void @main() #0 {
|
|
; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[Zero]]
|
|
; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
|
|
%buffer0 = call target("spirv.Image", i32, 0, 2, 0, 0, 2, 24)
|
|
@llvm.spv.resource.handlefrombinding.tspirv.Image_f32_0_2_0_0_2_24(
|
|
i32 3, i32 4, i32 3, i32 0, i1 false)
|
|
%ptr0 = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.spv.resource.getpointer.p0.tspirv.Image_f32_5_2_0_0_2_0t(target("spirv.Image", i32, 0, 2, 0, 0, 2, 24) %buffer0, i32 0)
|
|
store i32 0, ptr %ptr0, align 4
|
|
|
|
; CHECK: [[ac:%[0-9]+]] = OpAccessChain [[BufferPtrType]] [[Var]] [[One]]
|
|
; CHECK: [[buffer:%[0-9]+]] = OpLoad [[BufferType]] [[ac]]
|
|
%buffer1 = call target("spirv.Image", i32, 0, 2, 0, 0, 2, 24)
|
|
@llvm.spv.resource.handlefrombinding.tspirv.Image_f32_0_2_0_0_2_24(
|
|
i32 3, i32 4, i32 3, i32 1, i1 false)
|
|
%ptr1 = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.spv.resource.getpointer.p0.tspirv.Image_f32_5_2_0_0_2_0t(target("spirv.Image", i32, 0, 2, 0, 0, 2, 24) %buffer1, i32 0)
|
|
store i32 0, ptr %ptr1, align 4
|
|
ret void
|
|
}
|
|
|
|
attributes #0 = { convergent noinline norecurse "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
|