mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
internal/shaderir/hlsl: refactoring
This commit is contained in:
parent
ee5b6a3680
commit
c5d664ccf7
@ -513,7 +513,7 @@ func (g *graphics11) NewShader(program *shaderir.Program) (graphicsdriver.Shader
|
||||
graphics: g,
|
||||
id: g.genNextShaderID(),
|
||||
uniformTypes: program.Uniforms,
|
||||
uniformOffsets: hlsl.CalcUniformMemoryOffsets(program),
|
||||
uniformOffsets: hlsl.CalcUniformMemoryOffsetsInDWords(program),
|
||||
vertexShaderBlob: vsh,
|
||||
pixelShaderBlob: psh,
|
||||
}
|
||||
|
@ -1073,7 +1073,7 @@ func (g *graphics12) NewShader(program *shaderir.Program) (graphicsdriver.Shader
|
||||
graphics: g,
|
||||
id: g.genNextShaderID(),
|
||||
uniformTypes: program.Uniforms,
|
||||
uniformOffsets: hlsl.CalcUniformMemoryOffsets(program),
|
||||
uniformOffsets: hlsl.CalcUniformMemoryOffsetsInDWords(program),
|
||||
vertexShader: vsh,
|
||||
pixelShader: psh,
|
||||
}
|
||||
|
@ -148,8 +148,8 @@ func compileShader(program *shaderir.Program) (vsh, psh *_ID3DBlob, ferr error)
|
||||
func constantBufferSize(uniformTypes []shaderir.Type, uniformOffsets []int) int {
|
||||
var size int
|
||||
for i, typ := range uniformTypes {
|
||||
if size < uniformOffsets[i]/4 {
|
||||
size = uniformOffsets[i] / 4
|
||||
if size < uniformOffsets[i] {
|
||||
size = uniformOffsets[i]
|
||||
}
|
||||
|
||||
switch typ.Main {
|
||||
@ -202,8 +202,8 @@ func adjustUniforms(uniformTypes []shaderir.Type, uniformOffsets []int, uniforms
|
||||
var fs []uint32
|
||||
var idx int
|
||||
for i, typ := range uniformTypes {
|
||||
if len(fs) < uniformOffsets[i]/4 {
|
||||
fs = append(fs, make([]uint32, uniformOffsets[i]/4-len(fs))...)
|
||||
if len(fs) < uniformOffsets[i] {
|
||||
fs = append(fs, make([]uint32, uniformOffsets[i]-len(fs))...)
|
||||
}
|
||||
|
||||
n := typ.Uint32Count()
|
||||
|
@ -81,7 +81,7 @@ float4x4 float4x4FromScalar(float x) {
|
||||
}`
|
||||
|
||||
func Compile(p *shaderir.Program) (vertexShader, pixelShader, prelude string) {
|
||||
offsets := CalcUniformMemoryOffsets(p)
|
||||
offsets := CalcUniformMemoryOffsetsInDWords(p)
|
||||
|
||||
c := &compileContext{
|
||||
unit: p.Unit,
|
||||
@ -119,13 +119,13 @@ func Compile(p *shaderir.Program) (vertexShader, pixelShader, prelude string) {
|
||||
lines = append(lines, "cbuffer Uniforms : register(b0) {")
|
||||
for i, t := range p.Uniforms {
|
||||
// packingoffset is not mandatory, but this is useful to ensure the correct offset is used.
|
||||
offset := fmt.Sprintf("c%d", offsets[i]/boundaryInBytes)
|
||||
switch offsets[i] % boundaryInBytes {
|
||||
case 4:
|
||||
offset := fmt.Sprintf("c%d", offsets[i]/boundaryInDWords)
|
||||
switch offsets[i] % boundaryInDWords {
|
||||
case 1:
|
||||
offset += ".y"
|
||||
case 8:
|
||||
case 2:
|
||||
offset += ".z"
|
||||
case 12:
|
||||
case 3:
|
||||
offset += ".w"
|
||||
}
|
||||
lines = append(lines, fmt.Sprintf("\t%s : packoffset(%s);", c.varDecl(p, &t, fmt.Sprintf("U%d", i)), offset))
|
||||
|
@ -20,20 +20,20 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
||||
)
|
||||
|
||||
const boundaryInBytes = 16
|
||||
const boundaryInDWords = 4
|
||||
|
||||
func CalcUniformMemoryOffsets(program *shaderir.Program) []int {
|
||||
func CalcUniformMemoryOffsetsInDWords(program *shaderir.Program) []int {
|
||||
// https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-packing-rules
|
||||
// https://github.com/microsoft/DirectXShaderCompiler/wiki/Buffer-Packing
|
||||
|
||||
var offsets []int
|
||||
var head int
|
||||
var offsetsInDWords []int
|
||||
var headInDWords int
|
||||
|
||||
align := func(x int) int {
|
||||
if x == 0 {
|
||||
return 0
|
||||
}
|
||||
return ((x-1)/boundaryInBytes + 1) * boundaryInBytes
|
||||
return ((x-1)/boundaryInDWords + 1) * boundaryInDWords
|
||||
}
|
||||
|
||||
// TODO: Reorder the variables with packoffset.
|
||||
@ -41,47 +41,47 @@ func CalcUniformMemoryOffsets(program *shaderir.Program) []int {
|
||||
for _, u := range program.Uniforms {
|
||||
switch u.Main {
|
||||
case shaderir.Float:
|
||||
offsets = append(offsets, head)
|
||||
head += 4
|
||||
offsetsInDWords = append(offsetsInDWords, headInDWords)
|
||||
headInDWords += 1
|
||||
case shaderir.Int:
|
||||
offsets = append(offsets, head)
|
||||
head += 4
|
||||
offsetsInDWords = append(offsetsInDWords, headInDWords)
|
||||
headInDWords += 1
|
||||
case shaderir.Vec2, shaderir.IVec2:
|
||||
if head%boundaryInBytes >= 4*3 {
|
||||
head = align(head)
|
||||
if headInDWords%boundaryInDWords >= 3 {
|
||||
headInDWords = align(headInDWords)
|
||||
}
|
||||
offsets = append(offsets, head)
|
||||
head += 4 * 2
|
||||
offsetsInDWords = append(offsetsInDWords, headInDWords)
|
||||
headInDWords += 2
|
||||
case shaderir.Vec3, shaderir.IVec3:
|
||||
if head%boundaryInBytes >= 4*2 {
|
||||
head = align(head)
|
||||
if headInDWords%boundaryInDWords >= 2 {
|
||||
headInDWords = align(headInDWords)
|
||||
}
|
||||
offsets = append(offsets, head)
|
||||
head += 4 * 3
|
||||
offsetsInDWords = append(offsetsInDWords, headInDWords)
|
||||
headInDWords += 3
|
||||
case shaderir.Vec4, shaderir.IVec4:
|
||||
if head%boundaryInBytes >= 4*1 {
|
||||
head = align(head)
|
||||
if headInDWords%boundaryInDWords >= 1 {
|
||||
headInDWords = align(headInDWords)
|
||||
}
|
||||
offsets = append(offsets, head)
|
||||
head += 4 * 4
|
||||
offsetsInDWords = append(offsetsInDWords, headInDWords)
|
||||
headInDWords += 4
|
||||
case shaderir.Mat2:
|
||||
// For matrices, each column is aligned to the boundary.
|
||||
head = align(head)
|
||||
offsets = append(offsets, head)
|
||||
head += 4 * 6
|
||||
headInDWords = align(headInDWords)
|
||||
offsetsInDWords = append(offsetsInDWords, headInDWords)
|
||||
headInDWords += 6
|
||||
case shaderir.Mat3:
|
||||
head = align(head)
|
||||
offsets = append(offsets, head)
|
||||
head += 4 * 11
|
||||
headInDWords = align(headInDWords)
|
||||
offsetsInDWords = append(offsetsInDWords, headInDWords)
|
||||
headInDWords += 11
|
||||
case shaderir.Mat4:
|
||||
head = align(head)
|
||||
offsets = append(offsets, head)
|
||||
head += 4 * 16
|
||||
headInDWords = align(headInDWords)
|
||||
offsetsInDWords = append(offsetsInDWords, headInDWords)
|
||||
headInDWords += 16
|
||||
case shaderir.Array:
|
||||
// Each array is 16-byte aligned.
|
||||
// TODO: What if the array has 2 or more dimensions?
|
||||
head = align(head)
|
||||
offsets = append(offsets, head)
|
||||
headInDWords = align(headInDWords)
|
||||
offsetsInDWords = append(offsetsInDWords, headInDWords)
|
||||
n := u.Sub[0].Uint32Count()
|
||||
switch u.Sub[0].Main {
|
||||
case shaderir.Mat2:
|
||||
@ -91,9 +91,9 @@ func CalcUniformMemoryOffsets(program *shaderir.Program) []int {
|
||||
case shaderir.Mat4:
|
||||
n = 16
|
||||
}
|
||||
head += (u.Length - 1) * align(4*n)
|
||||
headInDWords += (u.Length - 1) * align(n)
|
||||
// The last element is not with a padding.
|
||||
head += 4 * n
|
||||
headInDWords += n
|
||||
case shaderir.Struct:
|
||||
// TODO: Implement this
|
||||
panic("hlsl: offset for a struct is not implemented yet")
|
||||
@ -102,5 +102,5 @@ func CalcUniformMemoryOffsets(program *shaderir.Program) []int {
|
||||
}
|
||||
}
|
||||
|
||||
return offsets
|
||||
return offsetsInDWords
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user