driver: Add Graphics.MaxImageSize and use it

There are some devices that cannot accept 4096x4096 pixels
textures. Get the maximum size and use it.

Fixes #892
This commit is contained in:
Hajime Hoshi 2019-07-04 01:10:08 +09:00
parent 51951d6087
commit 6b7f21f0c8
4 changed files with 48 additions and 34 deletions

View File

@ -35,6 +35,7 @@ type Graphics interface {
NeedsRestoring() bool NeedsRestoring() bool
IsGL() bool IsGL() bool
HasHighPrecisionFloat() bool HasHighPrecisionFloat() bool
MaxImageSize() int
} }
type Image interface { type Image interface {

View File

@ -382,46 +382,13 @@ func (d *Driver) flush(wait bool, present bool) {
} }
func (d *Driver) checkSize(width, height int) { func (d *Driver) checkSize(width, height int) {
m := 0
d.t.Call(func() error {
if d.maxImageSize == 0 {
d.maxImageSize = 4096
// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
switch {
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily5_v1):
d.maxImageSize = 16384
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily4_v1):
d.maxImageSize = 16384
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily3_v1):
d.maxImageSize = 16384
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily2_v2):
d.maxImageSize = 8192
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily2_v1):
d.maxImageSize = 4096
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily1_v2):
d.maxImageSize = 8192
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily1_v1):
d.maxImageSize = 4096
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_tvOS_GPUFamily2_v1):
d.maxImageSize = 16384
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_tvOS_GPUFamily1_v1):
d.maxImageSize = 8192
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_macOS_GPUFamily1_v1):
d.maxImageSize = 16384
default:
panic("metal: there is no supported feature set")
}
}
m = d.maxImageSize
return nil
})
if width < 1 { if width < 1 {
panic(fmt.Sprintf("metal: width (%d) must be equal or more than %d", width, 1)) panic(fmt.Sprintf("metal: width (%d) must be equal or more than %d", width, 1))
} }
if height < 1 { if height < 1 {
panic(fmt.Sprintf("metal: height (%d) must be equal or more than %d", height, 1)) panic(fmt.Sprintf("metal: height (%d) must be equal or more than %d", height, 1))
} }
m := d.MaxImageSize()
if width > m { if width > m {
panic(fmt.Sprintf("metal: width (%d) must be less than or equal to %d", width, m)) panic(fmt.Sprintf("metal: width (%d) must be less than or equal to %d", width, m))
} }
@ -707,6 +674,43 @@ func (d *Driver) HasHighPrecisionFloat() bool {
return true return true
} }
func (d *Driver) MaxImageSize() int {
m := 0
d.t.Call(func() error {
if d.maxImageSize == 0 {
d.maxImageSize = 4096
// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
switch {
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily5_v1):
d.maxImageSize = 16384
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily4_v1):
d.maxImageSize = 16384
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily3_v1):
d.maxImageSize = 16384
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily2_v2):
d.maxImageSize = 8192
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily2_v1):
d.maxImageSize = 4096
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily1_v2):
d.maxImageSize = 8192
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_iOS_GPUFamily1_v1):
d.maxImageSize = 4096
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_tvOS_GPUFamily2_v1):
d.maxImageSize = 16384
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_tvOS_GPUFamily1_v1):
d.maxImageSize = 8192
case d.view.getMTLDevice().SupportsFeatureSet(mtl.FeatureSet_macOS_GPUFamily1_v1):
d.maxImageSize = 16384
default:
panic("metal: there is no supported feature set")
}
}
m = d.maxImageSize
return nil
})
return m
}
type Image struct { type Image struct {
driver *Driver driver *Driver
width int width int

View File

@ -142,3 +142,7 @@ func (d *Driver) IsGL() bool {
func (d *Driver) HasHighPrecisionFloat() bool { func (d *Driver) HasHighPrecisionFloat() bool {
return d.context.hasHighPrecisionFloat() return d.context.hasHighPrecisionFloat()
} }
func (d *Driver) MaxImageSize() int {
return d.context.getMaxTextureSize()
}

View File

@ -50,7 +50,12 @@ func init() {
} }
if graphicsDriver.HasHighPrecisionFloat() { if graphicsDriver.HasHighPrecisionFloat() {
minSize = 1024 minSize = 1024
// Use 4096 as a maximum size whatever size the graphics driver accepts. There are
// not enough evidences that bigger textures works correctly.
maxSize = 4096 maxSize = 4096
if m := graphicsDriver.MaxImageSize(); maxSize < m {
maxSize = m
}
} else { } else {
minSize = 512 minSize = 512
maxSize = 512 maxSize = 512