Compare commits

...

3 Commits

Author SHA1 Message Date
Hajime Hoshi
81bb5044ea internal/shaderir: revert the refactoring to generalize the memory layout logic
Unfortunately, the memory layout was not so universal. For example,
the memory layout for mat2 is different between Metal and DirectX.
2024-11-24 23:57:30 +09:00
Hajime Hoshi
b24bd93ae5 internal/shaderir: typo 2024-11-24 23:16:04 +09:00
Hajime Hoshi
4aad9d37e9 internal/shaderir: cache offset calculations for HLSL 2024-11-24 21:59:45 +09:00
4 changed files with 15 additions and 14 deletions

View File

@ -513,7 +513,7 @@ func (g *graphics11) NewShader(program *shaderir.Program) (graphicsdriver.Shader
graphics: g, graphics: g,
id: g.genNextShaderID(), id: g.genNextShaderID(),
uniformTypes: program.Uniforms, uniformTypes: program.Uniforms,
uniformOffsets: hlsl.CalcUniformMemoryOffsetsInDWords(program), uniformOffsets: hlsl.UniformVariableOffsetsInDWords(program),
vertexShaderBlob: vsh, vertexShaderBlob: vsh,
pixelShaderBlob: psh, pixelShaderBlob: psh,
} }

View File

@ -1073,7 +1073,7 @@ func (g *graphics12) NewShader(program *shaderir.Program) (graphicsdriver.Shader
graphics: g, graphics: g,
id: g.genNextShaderID(), id: g.genNextShaderID(),
uniformTypes: program.Uniforms, uniformTypes: program.Uniforms,
uniformOffsets: hlsl.CalcUniformMemoryOffsetsInDWords(program), uniformOffsets: hlsl.UniformVariableOffsetsInDWords(program),
vertexShader: vsh, vertexShader: vsh,
pixelShader: psh, pixelShader: psh,
} }

View File

@ -81,7 +81,7 @@ float4x4 float4x4FromScalar(float x) {
}` }`
func Compile(p *shaderir.Program) (vertexShader, pixelShader, prelude string) { func Compile(p *shaderir.Program) (vertexShader, pixelShader, prelude string) {
offsets := CalcUniformMemoryOffsetsInDWords(p) offsets := UniformVariableOffsetsInDWords(p)
c := &compileContext{ c := &compileContext{
unit: p.Unit, unit: p.Unit,
@ -119,8 +119,8 @@ func Compile(p *shaderir.Program) (vertexShader, pixelShader, prelude string) {
lines = append(lines, "cbuffer Uniforms : register(b0) {") lines = append(lines, "cbuffer Uniforms : register(b0) {")
for i, t := range p.Uniforms { for i, t := range p.Uniforms {
// packingoffset is not mandatory, but this is useful to ensure the correct offset is used. // packingoffset is not mandatory, but this is useful to ensure the correct offset is used.
offset := fmt.Sprintf("c%d", offsets[i]/boundaryInDWords) offset := fmt.Sprintf("c%d", offsets[i]/UniformVariableBoundaryInDWords)
switch offsets[i] % boundaryInDWords { switch offsets[i] % UniformVariableBoundaryInDWords {
case 1: case 1:
offset += ".y" offset += ".y"
case 2: case 2:

View File

@ -20,22 +20,23 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/shaderir" "github.com/hajimehoshi/ebiten/v2/internal/shaderir"
) )
const boundaryInDWords = 4 const UniformVariableBoundaryInDWords = 4
func CalcUniformMemoryOffsetsInDWords(program *shaderir.Program) []int { // UniformVariableOffsetsInDWords returns the offsets of the uniform variables in DWROD units in the HLSL layout.
func UniformVariableOffsetsInDWords(program *shaderir.Program) []int {
// https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-packing-rules // https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-packing-rules
// https://github.com/microsoft/DirectXShaderCompiler/wiki/Buffer-Packing // https://github.com/microsoft/DirectXShaderCompiler/wiki/Buffer-Packing
var offsetsInDWords []int
var headInDWords int
align := func(x int) int { align := func(x int) int {
if x == 0 { if x == 0 {
return 0 return 0
} }
return ((x-1)/boundaryInDWords + 1) * boundaryInDWords return ((x-1)/UniformVariableBoundaryInDWords + 1) * UniformVariableBoundaryInDWords
} }
var offsetsInDWords []int
var headInDWords int
// TODO: Reorder the variables with packoffset. // TODO: Reorder the variables with packoffset.
// See https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-variable-packoffset // See https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-variable-packoffset
for _, u := range program.Uniforms { for _, u := range program.Uniforms {
@ -47,19 +48,19 @@ func CalcUniformMemoryOffsetsInDWords(program *shaderir.Program) []int {
offsetsInDWords = append(offsetsInDWords, headInDWords) offsetsInDWords = append(offsetsInDWords, headInDWords)
headInDWords += 1 headInDWords += 1
case shaderir.Vec2, shaderir.IVec2: case shaderir.Vec2, shaderir.IVec2:
if headInDWords%boundaryInDWords >= 3 { if headInDWords%UniformVariableBoundaryInDWords >= 3 {
headInDWords = align(headInDWords) headInDWords = align(headInDWords)
} }
offsetsInDWords = append(offsetsInDWords, headInDWords) offsetsInDWords = append(offsetsInDWords, headInDWords)
headInDWords += 2 headInDWords += 2
case shaderir.Vec3, shaderir.IVec3: case shaderir.Vec3, shaderir.IVec3:
if headInDWords%boundaryInDWords >= 2 { if headInDWords%UniformVariableBoundaryInDWords >= 2 {
headInDWords = align(headInDWords) headInDWords = align(headInDWords)
} }
offsetsInDWords = append(offsetsInDWords, headInDWords) offsetsInDWords = append(offsetsInDWords, headInDWords)
headInDWords += 3 headInDWords += 3
case shaderir.Vec4, shaderir.IVec4: case shaderir.Vec4, shaderir.IVec4:
if headInDWords%boundaryInDWords >= 1 { if headInDWords%UniformVariableBoundaryInDWords >= 1 {
headInDWords = align(headInDWords) headInDWords = align(headInDWords)
} }
offsetsInDWords = append(offsetsInDWords, headInDWords) offsetsInDWords = append(offsetsInDWords, headInDWords)