protonscr

DXIL shaders fail to compile

vkd3dclosed
HansKristian-Work/vkd3d-proton#229 · opened 2020-07-28 by alexfs · updated 2020-07-30 · 2 comments · github
Aalexfs 2020-07-28 github

DXIL support seems a bit rough right now. Attached a vertex and pixel shader binaries. The first one errors with:
[ERROR]: Unimplemented DXIL opcode 127
[ERROR]: Failed to emit instruction.
[ERROR]: Failed to convert function.
While the second one just silently fails to compile.

sample.zip

HHansKristian-Work maintainer 2020-07-29 github

DXIL bugs should be reported at https://github.com/HansKristian-Work/dxil-spirv.

The vertex shader was missing some opcodes which only seem to be generated by DXBC-DXIL conversion (are you using this library by any chance?). That shader converts fine on dxil-spirv master now.

The pixel shader seems just to be a broken shader.

Extracting the raw BC and disassembling gives:

; ModuleID = '/tmp/pixel.bc'
source_filename = "/tmp/pixel.bc"

define void @main() {
entry:
  %0 = call half @dx.op.loadInput.f16(i32 4, i32 0, i32 0, i8 0, i32 undef)
  %1 = fpext half %0 to float
  %2 = call half @dx.op.loadInput.f16(i32 4, i32 0, i32 0, i8 1, i32 undef)
  %3 = fpext half %2 to float
  %4 = call half @dx.op.loadInput.f16(i32 4, i32 0, i32 0, i8 2, i32 undef)
  %5 = fpext half %4 to float
  %6 = call half @dx.op.loadInput.f16(i32 4, i32 0, i32 0, i8 3, i32 undef)
  %7 = fpext half %6 to float
  %8 = fptrunc float %1 to half
  call void @dx.op.storeOutput.f16(i32 5, i32 0, i32 0, i8 0, half %8)
  %9 = fptrunc float %3 to half
  call void @dx.op.storeOutput.f16(i32 5, i32 0, i32 0, i8 1, half %9)
  %10 = fptrunc float %5 to half
  call void @dx.op.storeOutput.f16(i32 5, i32 0, i32 0, i8 2, half %10)
  %11 = fptrunc float %7 to half
  call void @dx.op.storeOutput.f16(i32 5, i32 0, i32 0, i8 3, half %11)
  ret void
}

; Function Attrs: nounwind readnone
declare half @dx.op.loadInput.f16(i32, i32, i32, i8, i32) #0

; Function Attrs: nounwind
declare void @dx.op.storeOutput.f16(i32, i32, i32, i8, half) #1

attributes #0 = { nounwind readnone }
attributes #1 = { nounwind }

!dx.version = !{!0}
!dx.valver = !{!0}
!dx.shaderModel = !{!1}
!dx.entryPoints = !{!2}
!llvm.ident = !{!8}

!0 = !{i32 1, i32 0}
!1 = !{!"ps", i32 6, i32 0}
!2 = !{void ()* @main, !"main", !3, null, !7}
!3 = !{!4, null, null}
!4 = !{!5}
!5 = !{i32 0, !"R1", i8 8, i8 0, !6, i8 2, i32 1, i8 4, i32 1, i8 0, null}
!6 = !{i32 0}
!7 = !{i32 0, i64 32}
!8 = !{!"dxbc2dxil 1.2"}

The storeOutput is bogus since there is no metadata record for it. Also, the BC module is not valid, llvm-bcanalyzer complains:

llvm-bcanalyzer: Invalid record at top-level
Aalexfs 2020-07-30 github

The shader was generated by Microsoft DXBC converter API (dxbc->dxil). You're probably familiar with it.
Strange that it generates a broken code since it's used in their official D3D11On12 implementation.
[](https://github.com/microsoft/D3D11On12/blob/0595a34398b2e52d53cd21df0707d742f61a5d51/src/shader.cpp

Nothing extracted yet.