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
IsGL() bool
HasHighPrecisionFloat() bool
MaxImageSize() int
}
type Image interface {

View File

@ -382,46 +382,13 @@ func (d *Driver) flush(wait bool, present bool) {
}
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 {
panic(fmt.Sprintf("metal: width (%d) must be equal or more than %d", width, 1))
}
if height < 1 {
panic(fmt.Sprintf("metal: height (%d) must be equal or more than %d", height, 1))
}
m := d.MaxImageSize()
if 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
}
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 {
driver *Driver
width int

View File

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

View File

@ -50,7 +50,12 @@ func init() {
}
if graphicsDriver.HasHighPrecisionFloat() {
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
if m := graphicsDriver.MaxImageSize(); maxSize < m {
maxSize = m
}
} else {
minSize = 512
maxSize = 512