Compare commits

..

No commits in common. "7d3007a43e74974755f2f9b452a9146223aae94b" and "ee8b289106178d5917ca7236b6f99e48afef9a73" have entirely different histories.

17 changed files with 86 additions and 104 deletions

View File

@ -29,20 +29,13 @@ const (
ProjectionMatrixUniformVariableIndex = 6 ProjectionMatrixUniformVariableIndex = 6
PreservedUniformDwordCount = 2 + // the destination texture size PreservedUniformUint32Count = 2 + // the destination texture size
2*ShaderSrcImageCount + // the source texture sizes array 2*ShaderSrcImageCount + // the source texture sizes array
2 + // the destination image region origin 2 + // the destination image region origin
2 + // the destination image region size 2 + // the destination image region size
2*ShaderSrcImageCount + // the source image region origins array 2*ShaderSrcImageCount + // the source image region origins array
2*ShaderSrcImageCount + // the source image region sizes array 2*ShaderSrcImageCount + // the source image region sizes array
16 // the projection matrix 16 // the projection matrix
ProjectionMatrixUniformDwordIndex = 2 +
2*ShaderSrcImageCount +
2 +
2 +
2*ShaderSrcImageCount +
2*ShaderSrcImageCount
) )
const ( const (

View File

@ -23,7 +23,7 @@ import (
) )
func BenchmarkPrependPreservedUniforms(b *testing.B) { func BenchmarkPrependPreservedUniforms(b *testing.B) {
var uniforms [graphics.PreservedUniformDwordCount]uint32 var uniforms [graphics.PreservedUniformUint32Count]uint32
dst := graphicscommand.NewImage(16, 16, false, "") dst := graphicscommand.NewImage(16, 16, false, "")
src := graphicscommand.NewImage(16, 16, false, "") src := graphicscommand.NewImage(16, 16, false, "")
dr := image.Rect(0, 0, 16, 16) dr := image.Rect(0, 0, 16, 16)

View File

@ -347,15 +347,15 @@ func imageRectangleToRectangleF32(r image.Rectangle) rectangleF32 {
func (q *commandQueue) prependPreservedUniforms(uniforms []uint32, shader *Shader, dst *Image, srcs [graphics.ShaderSrcImageCount]*Image, dstRegion image.Rectangle, srcRegions [graphics.ShaderSrcImageCount]image.Rectangle) []uint32 { func (q *commandQueue) prependPreservedUniforms(uniforms []uint32, shader *Shader, dst *Image, srcs [graphics.ShaderSrcImageCount]*Image, dstRegion image.Rectangle, srcRegions [graphics.ShaderSrcImageCount]image.Rectangle) []uint32 {
origUniforms := uniforms origUniforms := uniforms
uniforms = q.uint32sBuffer.alloc(len(origUniforms) + graphics.PreservedUniformDwordCount) uniforms = q.uint32sBuffer.alloc(len(origUniforms) + graphics.PreservedUniformUint32Count)
copy(uniforms[graphics.PreservedUniformDwordCount:], origUniforms) copy(uniforms[graphics.PreservedUniformUint32Count:], origUniforms)
return prependPreservedUniforms(uniforms, shader, dst, srcs, dstRegion, srcRegions) return prependPreservedUniforms(uniforms, shader, dst, srcs, dstRegion, srcRegions)
} }
func prependPreservedUniforms(uniforms []uint32, shader *Shader, dst *Image, srcs [graphics.ShaderSrcImageCount]*Image, dstRegion image.Rectangle, srcRegions [graphics.ShaderSrcImageCount]image.Rectangle) []uint32 { func prependPreservedUniforms(uniforms []uint32, shader *Shader, dst *Image, srcs [graphics.ShaderSrcImageCount]*Image, dstRegion image.Rectangle, srcRegions [graphics.ShaderSrcImageCount]image.Rectangle) []uint32 {
// Set the destination texture size. // Set the destination texture size.
// Hard-code indices for BCE optimization. // Hard-code indices for BCE optimization.
_ = uniforms[graphics.PreservedUniformDwordCount-1] _ = uniforms[graphics.PreservedUniformUint32Count-1]
dw, dh := dst.InternalSize() dw, dh := dst.InternalSize()
uniforms[0] = math.Float32bits(float32(dw)) uniforms[0] = math.Float32bits(float32(dw))
@ -468,8 +468,8 @@ func prependPreservedUniforms(uniforms []uint32, shader *Shader, dst *Image, src
return uniforms return uniforms
} }
// Confirm the concrete value of graphics.PreservedUniformDwordCount. // Confirm the concrete value of graphics.PreservedUniformUint32Count.
var _ [0]struct{} = [graphics.PreservedUniformDwordCount - 46]struct{}{} var _ [0]struct{} = [graphics.PreservedUniformUint32Count - 46]struct{}{}
type commandQueuePool struct { type commandQueuePool struct {
cache []*commandQueue cache []*commandQueue

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.UniformVariableOffsetsInDwords(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.UniformVariableOffsetsInDwords(program), uniformOffsets: hlsl.UniformVariableOffsetsInDWords(program),
vertexShader: vsh, vertexShader: vsh,
pixelShader: psh, pixelShader: psh,
} }

View File

@ -209,7 +209,7 @@ func adjustUniforms(uniformTypes []shaderir.Type, uniformOffsets []int, uniforms
fs = append(fs, make([]uint32, uniformOffsets[i]-len(fs))...) fs = append(fs, make([]uint32, uniformOffsets[i]-len(fs))...)
} }
n := typ.DwordCount() n := typ.Uint32Count()
switch typ.Main { switch typ.Main {
case shaderir.Float: case shaderir.Float:
fs = append(fs, uniforms[idx:idx+1]...) fs = append(fs, uniforms[idx:idx+1]...)

View File

@ -882,7 +882,7 @@ func adjustUniformVariablesLayout(uniformTypes []shaderir.Type, uniforms []uint3
var idx int var idx int
for i, typ := range uniformTypes { for i, typ := range uniformTypes {
n := typ.DwordCount() n := typ.Uint32Count()
switch typ.Main { switch typ.Main {
case shaderir.Float, shaderir.Int: case shaderir.Float, shaderir.Int:
values = append(values, uniforms[idx:idx+n]...) values = append(values, uniforms[idx:idx+n]...)

View File

@ -224,7 +224,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
var idx int var idx int
for i, typ := range shader.ir.Uniforms { for i, typ := range shader.ir.Uniforms {
n := typ.DwordCount() n := typ.Uint32Count()
g.uniformVars[i].name = g.uniformVariableName(i) g.uniformVars[i].name = g.uniformVariableName(i)
g.uniformVars[i].value = uniforms[idx : idx+n] g.uniformVars[i].value = uniforms[idx : idx+n]
g.uniformVars[i].typ = typ g.uniformVars[i].typ = typ

View File

@ -292,7 +292,7 @@ func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textu
if u.value == nil { if u.value == nil {
continue continue
} }
if got, expected := len(u.value), u.typ.DwordCount(); got != expected { if got, expected := len(u.value), u.typ.Uint32Count(); got != expected {
// Copy a shaderir.Type value once. Do not pass u.typ directly to fmt.Errorf arguments, or // Copy a shaderir.Type value once. Do not pass u.typ directly to fmt.Errorf arguments, or
// the value u would be allocated on heap. // the value u would be allocated on heap.
typ := u.typ typ := u.typ

View File

@ -30,11 +30,6 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/shaderir" "github.com/hajimehoshi/ebiten/v2/internal/shaderir"
) )
//export ebitengine_ProjectionMatrixUniformDwordIndex
func ebitengine_ProjectionMatrixUniformDwordIndex() C.int {
return C.int(graphics.ProjectionMatrixUniformDwordIndex)
}
type playstation5Error struct { type playstation5Error struct {
name string name string
code int code int

View File

@ -25,8 +25,6 @@
extern "C" { extern "C" {
#endif #endif
int ebitengine_ProjectionMatrixUniformDwordIndex();
typedef struct ebitengine_Error { typedef struct ebitengine_Error {
const char *message; const char *message;
int code; int code;
@ -54,27 +52,23 @@ typedef struct ebitengine_DstRegion {
// kBlendFactor* and kBlendOperation* must be synced with // kBlendFactor* and kBlendOperation* must be synced with
// internal/graphicsdriver/blend.go. // internal/graphicsdriver/blend.go.
enum { const uint8_t kBlendFactorZero = 0;
kBlendFactorZero = 0, const uint8_t kBlendFactorOne = 1;
kBlendFactorOne = 1, const uint8_t kBlendFactorSourceColor = 2;
kBlendFactorSourceColor = 2, const uint8_t kBlendFactorOneMinusSourceColor = 3;
kBlendFactorOneMinusSourceColor = 3, const uint8_t kBlendFactorSourceAlpha = 4;
kBlendFactorSourceAlpha = 4, const uint8_t kBlendFactorOneMinusSourceAlpha = 5;
kBlendFactorOneMinusSourceAlpha = 5, const uint8_t kBlendFactorDestinationColor = 6;
kBlendFactorDestinationColor = 6, const uint8_t kBlendFactorOneMinusDestinationColor = 7;
kBlendFactorOneMinusDestinationColor = 7, const uint8_t kBlendFactorDestinationAlpha = 8;
kBlendFactorDestinationAlpha = 8, const uint8_t kBlendFactorOneMinusDestinationAlpha = 9;
kBlendFactorOneMinusDestinationAlpha = 9, const uint8_t kBlendFactorSourceAlphaSaturated = 10;
kBlendFactorSourceAlphaSaturated = 10,
};
enum { const uint8_t kBlendOperationAdd = 0;
kBlendOperationAdd = 0, const uint8_t kBlendOperationSubtract = 1;
kBlendOperationSubtract = 1, const uint8_t kBlendOperationReverseSubtract = 2;
kBlendOperationReverseSubtract = 2, const uint8_t kBlendOperationMin = 3;
kBlendOperationMin = 3, const uint8_t kBlendOperationMax = 4;
kBlendOperationMax = 4,
};
typedef struct ebitengine_Blend { typedef struct ebitengine_Blend {
uint8_t factor_src_rgb; uint8_t factor_src_rgb;

View File

@ -27,7 +27,7 @@ func BenchmarkFilter(b *testing.B) {
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
uniforms := make([]uint32, graphics.PreservedUniformDwordCount) uniforms := make([]uint32, graphics.PreservedUniformUint32Count)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
s.FilterUniformVariables(uniforms) s.FilterUniformVariables(uniforms)
} }

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 := UniformVariableOffsetsInDwords(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]/UniformVariableBoundaryInDwords) offset := fmt.Sprintf("c%d", offsets[i]/UniformVariableBoundaryInDWords)
switch offsets[i] % UniformVariableBoundaryInDwords { switch offsets[i] % UniformVariableBoundaryInDWords {
case 1: case 1:
offset += ".y" offset += ".y"
case 2: case 2:

View File

@ -20,10 +20,10 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/shaderir" "github.com/hajimehoshi/ebiten/v2/internal/shaderir"
) )
const UniformVariableBoundaryInDwords = 4 const UniformVariableBoundaryInDWords = 4
// UniformVariableOffsetsInDwords returns the offsets of the uniform variables in DWROD units in the HLSL layout. // UniformVariableOffsetsInDWords returns the offsets of the uniform variables in DWROD units in the HLSL layout.
func UniformVariableOffsetsInDwords(program *shaderir.Program) []int { 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
@ -31,59 +31,59 @@ func UniformVariableOffsetsInDwords(program *shaderir.Program) []int {
if x == 0 { if x == 0 {
return 0 return 0
} }
return ((x-1)/UniformVariableBoundaryInDwords + 1) * UniformVariableBoundaryInDwords return ((x-1)/UniformVariableBoundaryInDWords + 1) * UniformVariableBoundaryInDWords
} }
var offsetsInDwords []int var offsetsInDWords []int
var headInDwords 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 {
switch u.Main { switch u.Main {
case shaderir.Float: case shaderir.Float:
offsetsInDwords = append(offsetsInDwords, headInDwords) offsetsInDWords = append(offsetsInDWords, headInDWords)
headInDwords += 1 headInDWords += 1
case shaderir.Int: case shaderir.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%UniformVariableBoundaryInDwords >= 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%UniformVariableBoundaryInDwords >= 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%UniformVariableBoundaryInDwords >= 1 { if headInDWords%UniformVariableBoundaryInDWords >= 1 {
headInDwords = align(headInDwords) headInDWords = align(headInDWords)
} }
offsetsInDwords = append(offsetsInDwords, headInDwords) offsetsInDWords = append(offsetsInDWords, headInDWords)
headInDwords += 4 headInDWords += 4
case shaderir.Mat2: case shaderir.Mat2:
// For matrices, each column is aligned to the boundary. // For matrices, each column is aligned to the boundary.
headInDwords = align(headInDwords) headInDWords = align(headInDWords)
offsetsInDwords = append(offsetsInDwords, headInDwords) offsetsInDWords = append(offsetsInDWords, headInDWords)
headInDwords += 6 headInDWords += 6
case shaderir.Mat3: case shaderir.Mat3:
headInDwords = align(headInDwords) headInDWords = align(headInDWords)
offsetsInDwords = append(offsetsInDwords, headInDwords) offsetsInDWords = append(offsetsInDWords, headInDWords)
headInDwords += 11 headInDWords += 11
case shaderir.Mat4: case shaderir.Mat4:
headInDwords = align(headInDwords) headInDWords = align(headInDWords)
offsetsInDwords = append(offsetsInDwords, headInDwords) offsetsInDWords = append(offsetsInDWords, headInDWords)
headInDwords += 16 headInDWords += 16
case shaderir.Array: case shaderir.Array:
// Each array is 16-byte aligned. // Each array is 16-byte aligned.
// TODO: What if the array has 2 or more dimensions? // TODO: What if the array has 2 or more dimensions?
headInDwords = align(headInDwords) headInDWords = align(headInDWords)
offsetsInDwords = append(offsetsInDwords, headInDwords) offsetsInDWords = append(offsetsInDWords, headInDWords)
n := u.Sub[0].DwordCount() n := u.Sub[0].Uint32Count()
switch u.Sub[0].Main { switch u.Sub[0].Main {
case shaderir.Mat2: case shaderir.Mat2:
n = 6 n = 6
@ -92,9 +92,9 @@ func UniformVariableOffsetsInDwords(program *shaderir.Program) []int {
case shaderir.Mat4: case shaderir.Mat4:
n = 16 n = 16
} }
headInDwords += (u.Length - 1) * align(n) headInDWords += (u.Length - 1) * align(n)
// The last element is not with a padding. // The last element is not with a padding.
headInDwords += n headInDWords += n
case shaderir.Struct: case shaderir.Struct:
// TODO: Implement this // TODO: Implement this
panic("hlsl: offset for a struct is not implemented yet") panic("hlsl: offset for a struct is not implemented yet")
@ -103,5 +103,5 @@ func UniformVariableOffsetsInDwords(program *shaderir.Program) []int {
} }
} }
return offsetsInDwords return offsetsInDWords
} }

View File

@ -493,7 +493,7 @@ func (p *Program) FilterUniformVariables(uniforms []uint32) {
p.uniformFactors = make([]uint32, len(uniforms)) p.uniformFactors = make([]uint32, len(uniforms))
var idx int var idx int
for i, typ := range p.Uniforms { for i, typ := range p.Uniforms {
c := typ.DwordCount() c := typ.Uint32Count()
if reachableUniforms[i] { if reachableUniforms[i] {
for i := idx; i < idx+c; i++ { for i := idx; i < idx+c; i++ {
p.uniformFactors[i] = 1 p.uniformFactors[i] = 1

View File

@ -87,7 +87,7 @@ func (t Type) String() string {
} }
} }
func (t Type) DwordCount() int { func (t Type) Uint32Count() int {
switch t.Main { switch t.Main {
case Int: case Int:
return 1 return 1
@ -112,7 +112,7 @@ func (t Type) DwordCount() int {
case Mat4: case Mat4:
return 16 return 16
case Array: case Array:
return t.Length * t.Sub[0].DwordCount() return t.Length * t.Sub[0].Uint32Count()
default: // TODO: Parse a struct correctly default: // TODO: Parse a struct correctly
return -1 return -1
} }

View File

@ -27,9 +27,9 @@ import (
type Shader struct { type Shader struct {
shader *atlas.Shader shader *atlas.Shader
uniformNames []string uniformNames []string
uniformTypes []shaderir.Type uniformTypes []shaderir.Type
uniformDwordCount int uniformUint32Count int
} }
func NewShader(ir *shaderir.Program, name string) *Shader { func NewShader(ir *shaderir.Program, name string) *Shader {
@ -45,20 +45,20 @@ func (s *Shader) Deallocate() {
} }
func (s *Shader) AppendUniforms(dst []uint32, uniforms map[string]any) []uint32 { func (s *Shader) AppendUniforms(dst []uint32, uniforms map[string]any) []uint32 {
if s.uniformDwordCount == 0 { if s.uniformUint32Count == 0 {
for _, typ := range s.uniformTypes { for _, typ := range s.uniformTypes {
s.uniformDwordCount += typ.DwordCount() s.uniformUint32Count += typ.Uint32Count()
} }
} }
origLen := len(dst) origLen := len(dst)
if cap(dst)-len(dst) >= s.uniformDwordCount { if cap(dst)-len(dst) >= s.uniformUint32Count {
dst = dst[:len(dst)+s.uniformDwordCount] dst = dst[:len(dst)+s.uniformUint32Count]
for i := origLen; i < len(dst); i++ { for i := origLen; i < len(dst); i++ {
dst[i] = 0 dst[i] = 0
} }
} else { } else {
dst = append(dst, make([]uint32, s.uniformDwordCount)...) dst = append(dst, make([]uint32, s.uniformUint32Count)...)
} }
idx := origLen idx := origLen
@ -71,23 +71,23 @@ func (s *Shader) AppendUniforms(dst []uint32, uniforms map[string]any) []uint32
t := v.Type() t := v.Type()
switch t.Kind() { switch t.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if typ.DwordCount() != 1 { if typ.Uint32Count() != 1 {
panic(fmt.Sprintf("ui: unexpected uniform value for %s (%s)", name, typ.String())) panic(fmt.Sprintf("ui: unexpected uniform value for %s (%s)", name, typ.String()))
} }
dst[idx] = uint32(v.Int()) dst[idx] = uint32(v.Int())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
if typ.DwordCount() != 1 { if typ.Uint32Count() != 1 {
panic(fmt.Sprintf("ui: unexpected uniform value for %s (%s)", name, typ.String())) panic(fmt.Sprintf("ui: unexpected uniform value for %s (%s)", name, typ.String()))
} }
dst[idx] = uint32(v.Uint()) dst[idx] = uint32(v.Uint())
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
if typ.DwordCount() != 1 { if typ.Uint32Count() != 1 {
panic(fmt.Sprintf("ui: unexpected uniform value for %s (%s)", name, typ.String())) panic(fmt.Sprintf("ui: unexpected uniform value for %s (%s)", name, typ.String()))
} }
dst[idx] = math.Float32bits(float32(v.Float())) dst[idx] = math.Float32bits(float32(v.Float()))
case reflect.Slice, reflect.Array: case reflect.Slice, reflect.Array:
l := v.Len() l := v.Len()
if typ.DwordCount() != l { if typ.Uint32Count() != l {
panic(fmt.Sprintf("ui: unexpected uniform value for %s (%s)", name, typ.String())) panic(fmt.Sprintf("ui: unexpected uniform value for %s (%s)", name, typ.String()))
} }
switch t.Elem().Kind() { switch t.Elem().Kind() {
@ -111,7 +111,7 @@ func (s *Shader) AppendUniforms(dst []uint32, uniforms map[string]any) []uint32
} }
} }
idx += typ.DwordCount() idx += typ.Uint32Count()
} }
return dst return dst