internal/shaderir/hlsl: refactoring: more flexible generation

Updates #2640
This commit is contained in:
Hajime Hoshi 2024-08-25 15:56:44 +09:00
parent ed45843c13
commit fef487e09d
3 changed files with 141 additions and 64 deletions

View File

@ -27,34 +27,56 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/hlsl" "github.com/hajimehoshi/ebiten/v2/internal/shaderir/hlsl"
) )
var inputElementDescsForDX11 = []_D3D11_INPUT_ELEMENT_DESC{ var inputElementDescsForDX11 []_D3D11_INPUT_ELEMENT_DESC
{
SemanticName: &([]byte("POSITION\000"))[0], func init() {
SemanticIndex: 0, inputElementDescsForDX11 = []_D3D11_INPUT_ELEMENT_DESC{
Format: _DXGI_FORMAT_R32G32_FLOAT, {
InputSlot: 0, SemanticName: &([]byte("POSITION\000"))[0],
AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT, SemanticIndex: 0,
InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA, Format: _DXGI_FORMAT_R32G32_FLOAT,
InstanceDataStepRate: 0, InputSlot: 0,
}, AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT,
{ InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA,
SemanticName: &([]byte("TEXCOORD\000"))[0], InstanceDataStepRate: 0,
SemanticIndex: 0, },
Format: _DXGI_FORMAT_R32G32_FLOAT, {
InputSlot: 0, SemanticName: &([]byte("TEXCOORD\000"))[0],
AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT, SemanticIndex: 0,
InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA, Format: _DXGI_FORMAT_R32G32_FLOAT,
InstanceDataStepRate: 0, InputSlot: 0,
}, AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT,
{ InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA,
SemanticName: &([]byte("COLOR\000"))[0], InstanceDataStepRate: 0,
SemanticIndex: 0, },
Format: _DXGI_FORMAT_R32G32B32A32_FLOAT, {
InputSlot: 0, SemanticName: &([]byte("COLOR\000"))[0],
AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT, SemanticIndex: 0,
InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA, Format: _DXGI_FORMAT_R32G32B32A32_FLOAT,
InstanceDataStepRate: 0, InputSlot: 0,
}, AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
}
diff := graphics.VertexFloatCount - 8
if diff == 0 {
return
}
if diff%4 != 0 {
panic("directx: unexpected attribute layout")
}
for i := 0; i < diff/4; i++ {
inputElementDescsForDX11 = append(inputElementDescsForDX11, _D3D11_INPUT_ELEMENT_DESC{
SemanticName: &([]byte("COLOR\000"))[0],
SemanticIndex: uint32(i) + 1,
Format: _DXGI_FORMAT_R32G32B32A32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D11_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D11_INPUT_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
})
}
} }
func blendFactorToBlend11(f graphicsdriver.BlendFactor, alpha bool) _D3D11_BLEND { func blendFactorToBlend11(f graphicsdriver.BlendFactor, alpha bool) _D3D11_BLEND {

View File

@ -23,34 +23,56 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
) )
var inputElementDescsForDX12 = []_D3D12_INPUT_ELEMENT_DESC{ var inputElementDescsForDX12 []_D3D12_INPUT_ELEMENT_DESC
{
SemanticName: &([]byte("POSITION\000"))[0], func init() {
SemanticIndex: 0, inputElementDescsForDX12 = []_D3D12_INPUT_ELEMENT_DESC{
Format: _DXGI_FORMAT_R32G32_FLOAT, {
InputSlot: 0, SemanticName: &([]byte("POSITION\000"))[0],
AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT, SemanticIndex: 0,
InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, Format: _DXGI_FORMAT_R32G32_FLOAT,
InstanceDataStepRate: 0, InputSlot: 0,
}, AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT,
{ InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
SemanticName: &([]byte("TEXCOORD\000"))[0], InstanceDataStepRate: 0,
SemanticIndex: 0, },
Format: _DXGI_FORMAT_R32G32_FLOAT, {
InputSlot: 0, SemanticName: &([]byte("TEXCOORD\000"))[0],
AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT, SemanticIndex: 0,
InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, Format: _DXGI_FORMAT_R32G32_FLOAT,
InstanceDataStepRate: 0, InputSlot: 0,
}, AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT,
{ InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
SemanticName: &([]byte("COLOR\000"))[0], InstanceDataStepRate: 0,
SemanticIndex: 0, },
Format: _DXGI_FORMAT_R32G32B32A32_FLOAT, {
InputSlot: 0, SemanticName: &([]byte("COLOR\000"))[0],
AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT, SemanticIndex: 0,
InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, Format: _DXGI_FORMAT_R32G32B32A32_FLOAT,
InstanceDataStepRate: 0, InputSlot: 0,
}, AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
}
diff := graphics.VertexFloatCount - 8
if diff == 0 {
return
}
if diff%4 != 0 {
panic("directx: unexpected attribute layout")
}
for i := 0; i < diff/4; i++ {
inputElementDescsForDX12 = append(inputElementDescsForDX12, _D3D12_INPUT_ELEMENT_DESC{
SemanticName: &([]byte("COLOR\000"))[0],
SemanticIndex: uint32(i) + 1,
Format: _DXGI_FORMAT_R32G32B32A32_FLOAT,
InputSlot: 0,
AlignedByteOffset: _D3D12_APPEND_ALIGNED_ELEMENT,
InputSlotClass: _D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
})
}
} }
const numDescriptorsPerFrame = 32 const numDescriptorsPerFrame = 32

View File

@ -52,13 +52,7 @@ func (c *compileContext) structName(p *shaderir.Program, t *shaderir.Type) strin
return n return n
} }
const Prelude = `struct Varyings { const Prelude = `float mod(float x, float y) {
float4 Position : SV_POSITION;
float2 M0 : TEXCOORD0;
float4 M1 : COLOR;
};
float mod(float x, float y) {
return x - y * floor(x/y); return x - y * floor(x/y);
} }
@ -95,6 +89,27 @@ func Compile(p *shaderir.Program) (vertexShader, pixelShader string) {
var lines []string var lines []string
lines = append(lines, strings.Split(Prelude, "\n")...) lines = append(lines, strings.Split(Prelude, "\n")...)
lines = append(lines, "", "struct Varyings {")
lines = append(lines, "\tfloat4 Position : SV_POSITION;")
if len(p.Varyings) > 0 {
for i, v := range p.Varyings {
switch i {
case 0:
lines = append(lines, fmt.Sprintf("\tfloat2 M%d : TEXCOORD0;", i))
case 1:
lines = append(lines, fmt.Sprintf("\tfloat4 M%d : COLOR0;", i))
default:
// Use COLOR[n] as a general purpose varying.
if v.Main != shaderir.Vec4 {
lines = append(lines, fmt.Sprintf("\t?(unexpected type: %s) M%d : COLOR%d;", v, i, i-1))
} else {
lines = append(lines, fmt.Sprintf("\tfloat4 M%d : COLOR%d;", i, i-1))
}
}
}
}
lines = append(lines, "};")
lines = append(lines, "", "{{.Structs}}") lines = append(lines, "", "{{.Structs}}")
if len(p.Uniforms) > 0 { if len(p.Uniforms) > 0 {
@ -156,7 +171,25 @@ func Compile(p *shaderir.Program) (vertexShader, pixelShader string) {
} }
if p.VertexFunc.Block != nil && len(p.VertexFunc.Block.Stmts) > 0 { if p.VertexFunc.Block != nil && len(p.VertexFunc.Block.Stmts) > 0 {
vslines = append(vslines, "") vslines = append(vslines, "")
vslines = append(vslines, "Varyings VSMain(float2 A0 : POSITION, float2 A1 : TEXCOORD, float4 A2 : COLOR) {") var args []string
for i, a := range p.Attributes {
switch i {
case 0:
args = append(args, fmt.Sprintf("float2 A%d : POSITION", i))
case 1:
args = append(args, fmt.Sprintf("float2 A%d : TEXCOORD0", i))
case 2:
args = append(args, fmt.Sprintf("float4 A%d : COLOR0", i))
default:
// Use COLOR[n] as a general purpose varying.
if a.Main != shaderir.Vec4 {
args = append(args, fmt.Sprintf("?(unexpected type: %s) A%d : COLOR%d", a, i, i-2))
} else {
args = append(args, fmt.Sprintf("float4 A%d : COLOR%d", i, i-2))
}
}
}
vslines = append(vslines, "Varyings VSMain("+strings.Join(args, ", ")+") {")
vslines = append(vslines, fmt.Sprintf("\tVaryings %s;", vsOut)) vslines = append(vslines, fmt.Sprintf("\tVaryings %s;", vsOut))
vslines = append(vslines, c.block(p, p.VertexFunc.Block, p.VertexFunc.Block, 0)...) vslines = append(vslines, c.block(p, p.VertexFunc.Block, p.VertexFunc.Block, 0)...)
if last := fmt.Sprintf("\treturn %s;", vsOut); vslines[len(vslines)-1] != last { if last := fmt.Sprintf("\treturn %s;", vsOut); vslines[len(vslines)-1] != last {