opengl.go 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381
  1. // SPDX-License-Identifier: Unlicense OR MIT
  2. package opengl
  3. import (
  4. "errors"
  5. "fmt"
  6. "image"
  7. "math/bits"
  8. "runtime"
  9. "strings"
  10. "time"
  11. "unsafe"
  12. "gioui.org/gpu/internal/driver"
  13. "gioui.org/internal/gl"
  14. "gioui.org/shader"
  15. )
  16. // Backend implements driver.Device.
  17. type Backend struct {
  18. funcs *gl.Functions
  19. clear bool
  20. glstate glState
  21. state state
  22. savedState glState
  23. sharedCtx bool
  24. glver [2]int
  25. gles bool
  26. feats driver.Caps
  27. // floatTriple holds the settings for floating point
  28. // textures.
  29. floatTriple textureTriple
  30. // Single channel alpha textures.
  31. alphaTriple textureTriple
  32. srgbaTriple textureTriple
  33. storage [storageBindings]*buffer
  34. outputFBO gl.Framebuffer
  35. sRGBFBO *SRGBFBO
  36. // vertArray is bound during a frame. We don't need it, but
  37. // core desktop OpenGL profile 3.3 requires some array bound.
  38. vertArray gl.VertexArray
  39. }
  40. // State tracking.
  41. type glState struct {
  42. drawFBO gl.Framebuffer
  43. readFBO gl.Framebuffer
  44. vertAttribs [5]struct {
  45. obj gl.Buffer
  46. enabled bool
  47. size int
  48. typ gl.Enum
  49. normalized bool
  50. stride int
  51. offset uintptr
  52. }
  53. prog gl.Program
  54. texUnits struct {
  55. active gl.Enum
  56. binds [2]gl.Texture
  57. }
  58. arrayBuf gl.Buffer
  59. elemBuf gl.Buffer
  60. uniBuf gl.Buffer
  61. uniBufs [2]gl.Buffer
  62. storeBuf gl.Buffer
  63. storeBufs [4]gl.Buffer
  64. vertArray gl.VertexArray
  65. srgb bool
  66. blend struct {
  67. enable bool
  68. srcRGB, dstRGB gl.Enum
  69. srcA, dstA gl.Enum
  70. }
  71. clearColor [4]float32
  72. viewport [4]int
  73. unpack_row_length int
  74. pack_row_length int
  75. }
  76. type state struct {
  77. pipeline *pipeline
  78. buffer bufferBinding
  79. }
  80. type bufferBinding struct {
  81. obj gl.Buffer
  82. offset int
  83. }
  84. type timer struct {
  85. funcs *gl.Functions
  86. obj gl.Query
  87. }
  88. type texture struct {
  89. backend *Backend
  90. obj gl.Texture
  91. fbo gl.Framebuffer
  92. hasFBO bool
  93. triple textureTriple
  94. width int
  95. height int
  96. mipmap bool
  97. bindings driver.BufferBinding
  98. foreign bool
  99. }
  100. type pipeline struct {
  101. prog *program
  102. inputs []shader.InputLocation
  103. layout driver.VertexLayout
  104. blend driver.BlendDesc
  105. topology driver.Topology
  106. }
  107. type buffer struct {
  108. backend *Backend
  109. hasBuffer bool
  110. obj gl.Buffer
  111. typ driver.BufferBinding
  112. size int
  113. immutable bool
  114. // For emulation of uniform buffers.
  115. data []byte
  116. }
  117. type glshader struct {
  118. backend *Backend
  119. obj gl.Shader
  120. src shader.Sources
  121. }
  122. type program struct {
  123. backend *Backend
  124. obj gl.Program
  125. vertUniforms uniforms
  126. fragUniforms uniforms
  127. }
  128. type uniforms struct {
  129. locs []uniformLocation
  130. size int
  131. }
  132. type uniformLocation struct {
  133. uniform gl.Uniform
  134. offset int
  135. typ shader.DataType
  136. size int
  137. }
  138. // textureTriple holds the type settings for
  139. // a TexImage2D call.
  140. type textureTriple struct {
  141. internalFormat gl.Enum
  142. format gl.Enum
  143. typ gl.Enum
  144. }
  145. const (
  146. storageBindings = 32
  147. )
  148. func init() {
  149. driver.NewOpenGLDevice = newOpenGLDevice
  150. }
  151. // Supporting compute programs is theoretically possible with OpenGL ES 3.1. In
  152. // practice, there are too many driver issues, especially on Android (e.g.
  153. // Google Pixel, Samsung J2 are both broken i different ways). Disable support
  154. // and rely on Vulkan for devices that support it, and the CPU fallback for
  155. // devices that don't.
  156. const brokenGLES31 = true
  157. func newOpenGLDevice(api driver.OpenGL) (driver.Device, error) {
  158. f, err := gl.NewFunctions(api.Context, api.ES)
  159. if err != nil {
  160. return nil, err
  161. }
  162. exts := strings.Split(f.GetString(gl.EXTENSIONS), " ")
  163. glVer := f.GetString(gl.VERSION)
  164. ver, gles, err := gl.ParseGLVersion(glVer)
  165. if err != nil {
  166. return nil, err
  167. }
  168. floatTriple, ffboErr := floatTripleFor(f, ver, exts)
  169. srgbaTriple, srgbErr := srgbaTripleFor(ver, exts)
  170. gles31 := gles && (ver[0] > 3 || (ver[0] == 3 && ver[1] >= 1))
  171. b := &Backend{
  172. glver: ver,
  173. gles: gles,
  174. funcs: f,
  175. floatTriple: floatTriple,
  176. alphaTriple: alphaTripleFor(ver),
  177. srgbaTriple: srgbaTriple,
  178. sharedCtx: api.Shared,
  179. }
  180. b.feats.BottomLeftOrigin = true
  181. if srgbErr == nil {
  182. b.feats.Features |= driver.FeatureSRGB
  183. }
  184. if ffboErr == nil {
  185. b.feats.Features |= driver.FeatureFloatRenderTargets
  186. }
  187. if gles31 && !brokenGLES31 {
  188. b.feats.Features |= driver.FeatureCompute
  189. }
  190. if hasExtension(exts, "GL_EXT_disjoint_timer_query_webgl2") || hasExtension(exts, "GL_EXT_disjoint_timer_query") {
  191. b.feats.Features |= driver.FeatureTimers
  192. }
  193. b.feats.MaxTextureSize = f.GetInteger(gl.MAX_TEXTURE_SIZE)
  194. if !b.sharedCtx {
  195. // We have exclusive access to the context, so query the GL state once
  196. // instead of at each frame.
  197. b.glstate = b.queryState()
  198. }
  199. return b, nil
  200. }
  201. func (b *Backend) BeginFrame(target driver.RenderTarget, clear bool, viewport image.Point) driver.Texture {
  202. b.clear = clear
  203. if b.sharedCtx {
  204. b.glstate = b.queryState()
  205. b.savedState = b.glstate
  206. }
  207. b.state = state{}
  208. var renderFBO gl.Framebuffer
  209. if target != nil {
  210. switch t := target.(type) {
  211. case driver.OpenGLRenderTarget:
  212. renderFBO = gl.Framebuffer(t)
  213. case *texture:
  214. renderFBO = t.ensureFBO()
  215. default:
  216. panic(fmt.Errorf("opengl: invalid render target type: %T", target))
  217. }
  218. }
  219. b.outputFBO = renderFBO
  220. b.glstate.bindFramebuffer(b.funcs, gl.FRAMEBUFFER, renderFBO)
  221. if b.gles {
  222. // If the output framebuffer is not in the sRGB colorspace already, emulate it.
  223. fbSRGB := false
  224. if !b.gles || b.glver[0] > 2 {
  225. var fbEncoding int
  226. if !renderFBO.Valid() {
  227. fbEncoding = b.funcs.GetFramebufferAttachmentParameteri(gl.FRAMEBUFFER, gl.BACK, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING)
  228. } else {
  229. fbEncoding = b.funcs.GetFramebufferAttachmentParameteri(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING)
  230. }
  231. fbSRGB = fbEncoding != gl.LINEAR
  232. }
  233. if !fbSRGB && viewport != (image.Point{}) {
  234. if b.sRGBFBO == nil {
  235. sfbo, err := NewSRGBFBO(b.funcs, &b.glstate)
  236. if err != nil {
  237. panic(err)
  238. }
  239. b.sRGBFBO = sfbo
  240. }
  241. if err := b.sRGBFBO.Refresh(viewport); err != nil {
  242. panic(err)
  243. }
  244. renderFBO = b.sRGBFBO.Framebuffer()
  245. } else if b.sRGBFBO != nil {
  246. b.sRGBFBO.Release()
  247. b.sRGBFBO = nil
  248. }
  249. } else {
  250. b.glstate.set(b.funcs, gl.FRAMEBUFFER_SRGB, true)
  251. if !b.vertArray.Valid() {
  252. b.vertArray = b.funcs.CreateVertexArray()
  253. }
  254. b.glstate.bindVertexArray(b.funcs, b.vertArray)
  255. }
  256. b.glstate.bindFramebuffer(b.funcs, gl.FRAMEBUFFER, renderFBO)
  257. if b.sRGBFBO != nil && !clear {
  258. b.clearOutput(0, 0, 0, 0)
  259. }
  260. return &texture{backend: b, fbo: renderFBO, hasFBO: true, foreign: true}
  261. }
  262. func (b *Backend) EndFrame() {
  263. if b.sRGBFBO != nil {
  264. b.glstate.bindFramebuffer(b.funcs, gl.FRAMEBUFFER, b.outputFBO)
  265. if b.clear {
  266. b.SetBlend(false)
  267. } else {
  268. b.BlendFunc(driver.BlendFactorOne, driver.BlendFactorOneMinusSrcAlpha)
  269. b.SetBlend(true)
  270. }
  271. b.sRGBFBO.Blit()
  272. }
  273. if b.sharedCtx {
  274. b.restoreState(b.savedState)
  275. } else if runtime.GOOS == "android" {
  276. // The Android emulator needs the output framebuffer to be current when
  277. // eglSwapBuffers is called.
  278. b.glstate.bindFramebuffer(b.funcs, gl.FRAMEBUFFER, b.outputFBO)
  279. }
  280. }
  281. func (b *Backend) queryState() glState {
  282. s := glState{
  283. prog: gl.Program(b.funcs.GetBinding(gl.CURRENT_PROGRAM)),
  284. arrayBuf: gl.Buffer(b.funcs.GetBinding(gl.ARRAY_BUFFER_BINDING)),
  285. elemBuf: gl.Buffer(b.funcs.GetBinding(gl.ELEMENT_ARRAY_BUFFER_BINDING)),
  286. drawFBO: gl.Framebuffer(b.funcs.GetBinding(gl.FRAMEBUFFER_BINDING)),
  287. clearColor: b.funcs.GetFloat4(gl.COLOR_CLEAR_VALUE),
  288. viewport: b.funcs.GetInteger4(gl.VIEWPORT),
  289. }
  290. if !b.gles || b.glver[0] > 2 {
  291. s.unpack_row_length = b.funcs.GetInteger(gl.UNPACK_ROW_LENGTH)
  292. s.pack_row_length = b.funcs.GetInteger(gl.PACK_ROW_LENGTH)
  293. }
  294. s.blend.enable = b.funcs.IsEnabled(gl.BLEND)
  295. s.blend.srcRGB = gl.Enum(b.funcs.GetInteger(gl.BLEND_SRC_RGB))
  296. s.blend.dstRGB = gl.Enum(b.funcs.GetInteger(gl.BLEND_DST_RGB))
  297. s.blend.srcA = gl.Enum(b.funcs.GetInteger(gl.BLEND_SRC_ALPHA))
  298. s.blend.dstA = gl.Enum(b.funcs.GetInteger(gl.BLEND_DST_ALPHA))
  299. s.texUnits.active = gl.Enum(b.funcs.GetInteger(gl.ACTIVE_TEXTURE))
  300. if !b.gles {
  301. s.srgb = b.funcs.IsEnabled(gl.FRAMEBUFFER_SRGB)
  302. }
  303. if !b.gles || b.glver[0] >= 3 {
  304. s.vertArray = gl.VertexArray(b.funcs.GetBinding(gl.VERTEX_ARRAY_BINDING))
  305. s.readFBO = gl.Framebuffer(b.funcs.GetBinding(gl.READ_FRAMEBUFFER_BINDING))
  306. s.uniBuf = gl.Buffer(b.funcs.GetBinding(gl.UNIFORM_BUFFER_BINDING))
  307. for i := range s.uniBufs {
  308. s.uniBufs[i] = gl.Buffer(b.funcs.GetBindingi(gl.UNIFORM_BUFFER_BINDING, i))
  309. }
  310. }
  311. if b.gles && (b.glver[0] > 3 || (b.glver[0] == 3 && b.glver[1] >= 1)) {
  312. s.storeBuf = gl.Buffer(b.funcs.GetBinding(gl.SHADER_STORAGE_BUFFER_BINDING))
  313. for i := range s.storeBufs {
  314. s.storeBufs[i] = gl.Buffer(b.funcs.GetBindingi(gl.SHADER_STORAGE_BUFFER_BINDING, i))
  315. }
  316. }
  317. active := s.texUnits.active
  318. for i := range s.texUnits.binds {
  319. s.activeTexture(b.funcs, gl.TEXTURE0+gl.Enum(i))
  320. s.texUnits.binds[i] = gl.Texture(b.funcs.GetBinding(gl.TEXTURE_BINDING_2D))
  321. }
  322. s.activeTexture(b.funcs, active)
  323. for i := range s.vertAttribs {
  324. a := &s.vertAttribs[i]
  325. a.enabled = b.funcs.GetVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_ENABLED) != gl.FALSE
  326. a.obj = gl.Buffer(b.funcs.GetVertexAttribBinding(i, gl.VERTEX_ATTRIB_ARRAY_ENABLED))
  327. a.size = b.funcs.GetVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_SIZE)
  328. a.typ = gl.Enum(b.funcs.GetVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_TYPE))
  329. a.normalized = b.funcs.GetVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED) != gl.FALSE
  330. a.stride = b.funcs.GetVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_STRIDE)
  331. a.offset = b.funcs.GetVertexAttribPointer(i, gl.VERTEX_ATTRIB_ARRAY_POINTER)
  332. }
  333. return s
  334. }
  335. func (b *Backend) restoreState(dst glState) {
  336. src := &b.glstate
  337. f := b.funcs
  338. for i, unit := range dst.texUnits.binds {
  339. src.bindTexture(f, i, unit)
  340. }
  341. src.activeTexture(f, dst.texUnits.active)
  342. src.bindFramebuffer(f, gl.FRAMEBUFFER, dst.drawFBO)
  343. src.bindFramebuffer(f, gl.READ_FRAMEBUFFER, dst.readFBO)
  344. src.set(f, gl.BLEND, dst.blend.enable)
  345. bf := dst.blend
  346. src.setBlendFuncSeparate(f, bf.srcRGB, bf.dstRGB, bf.srcA, bf.dstA)
  347. src.set(f, gl.FRAMEBUFFER_SRGB, dst.srgb)
  348. src.bindVertexArray(f, dst.vertArray)
  349. src.useProgram(f, dst.prog)
  350. src.bindBuffer(f, gl.ELEMENT_ARRAY_BUFFER, dst.elemBuf)
  351. for i, b := range dst.uniBufs {
  352. src.bindBufferBase(f, gl.UNIFORM_BUFFER, i, b)
  353. }
  354. src.bindBuffer(f, gl.UNIFORM_BUFFER, dst.uniBuf)
  355. for i, b := range dst.storeBufs {
  356. src.bindBufferBase(f, gl.SHADER_STORAGE_BUFFER, i, b)
  357. }
  358. src.bindBuffer(f, gl.SHADER_STORAGE_BUFFER, dst.storeBuf)
  359. col := dst.clearColor
  360. src.setClearColor(f, col[0], col[1], col[2], col[3])
  361. for i, attr := range dst.vertAttribs {
  362. src.setVertexAttribArray(f, i, attr.enabled)
  363. src.vertexAttribPointer(f, attr.obj, i, attr.size, attr.typ, attr.normalized, attr.stride, int(attr.offset))
  364. }
  365. src.bindBuffer(f, gl.ARRAY_BUFFER, dst.arrayBuf)
  366. v := dst.viewport
  367. src.setViewport(f, v[0], v[1], v[2], v[3])
  368. src.pixelStorei(f, gl.UNPACK_ROW_LENGTH, dst.unpack_row_length)
  369. src.pixelStorei(f, gl.PACK_ROW_LENGTH, dst.pack_row_length)
  370. }
  371. func (s *glState) setVertexAttribArray(f *gl.Functions, idx int, enabled bool) {
  372. a := &s.vertAttribs[idx]
  373. if enabled != a.enabled {
  374. if enabled {
  375. f.EnableVertexAttribArray(gl.Attrib(idx))
  376. } else {
  377. f.DisableVertexAttribArray(gl.Attrib(idx))
  378. }
  379. a.enabled = enabled
  380. }
  381. }
  382. func (s *glState) vertexAttribPointer(f *gl.Functions, buf gl.Buffer, idx, size int, typ gl.Enum, normalized bool, stride, offset int) {
  383. s.bindBuffer(f, gl.ARRAY_BUFFER, buf)
  384. a := &s.vertAttribs[idx]
  385. a.obj = buf
  386. a.size = size
  387. a.typ = typ
  388. a.normalized = normalized
  389. a.stride = stride
  390. a.offset = uintptr(offset)
  391. f.VertexAttribPointer(gl.Attrib(idx), a.size, a.typ, a.normalized, a.stride, int(a.offset))
  392. }
  393. func (s *glState) activeTexture(f *gl.Functions, unit gl.Enum) {
  394. if unit != s.texUnits.active {
  395. f.ActiveTexture(unit)
  396. s.texUnits.active = unit
  397. }
  398. }
  399. func (s *glState) bindTexture(f *gl.Functions, unit int, t gl.Texture) {
  400. s.activeTexture(f, gl.TEXTURE0+gl.Enum(unit))
  401. if !t.Equal(s.texUnits.binds[unit]) {
  402. f.BindTexture(gl.TEXTURE_2D, t)
  403. s.texUnits.binds[unit] = t
  404. }
  405. }
  406. func (s *glState) bindVertexArray(f *gl.Functions, a gl.VertexArray) {
  407. if !a.Equal(s.vertArray) {
  408. f.BindVertexArray(a)
  409. s.vertArray = a
  410. }
  411. }
  412. func (s *glState) deleteFramebuffer(f *gl.Functions, fbo gl.Framebuffer) {
  413. f.DeleteFramebuffer(fbo)
  414. if fbo.Equal(s.drawFBO) {
  415. s.drawFBO = gl.Framebuffer{}
  416. }
  417. if fbo.Equal(s.readFBO) {
  418. s.readFBO = gl.Framebuffer{}
  419. }
  420. }
  421. func (s *glState) deleteBuffer(f *gl.Functions, b gl.Buffer) {
  422. f.DeleteBuffer(b)
  423. if b.Equal(s.arrayBuf) {
  424. s.arrayBuf = gl.Buffer{}
  425. }
  426. if b.Equal(s.elemBuf) {
  427. s.elemBuf = gl.Buffer{}
  428. }
  429. if b.Equal(s.uniBuf) {
  430. s.uniBuf = gl.Buffer{}
  431. }
  432. if b.Equal(s.storeBuf) {
  433. s.uniBuf = gl.Buffer{}
  434. }
  435. for i, b2 := range s.storeBufs {
  436. if b.Equal(b2) {
  437. s.storeBufs[i] = gl.Buffer{}
  438. }
  439. }
  440. for i, b2 := range s.uniBufs {
  441. if b.Equal(b2) {
  442. s.uniBufs[i] = gl.Buffer{}
  443. }
  444. }
  445. }
  446. func (s *glState) deleteProgram(f *gl.Functions, p gl.Program) {
  447. f.DeleteProgram(p)
  448. if p.Equal(s.prog) {
  449. s.prog = gl.Program{}
  450. }
  451. }
  452. func (s *glState) deleteVertexArray(f *gl.Functions, a gl.VertexArray) {
  453. f.DeleteVertexArray(a)
  454. if a.Equal(s.vertArray) {
  455. s.vertArray = gl.VertexArray{}
  456. }
  457. }
  458. func (s *glState) deleteTexture(f *gl.Functions, t gl.Texture) {
  459. f.DeleteTexture(t)
  460. binds := &s.texUnits.binds
  461. for i, obj := range binds {
  462. if t.Equal(obj) {
  463. binds[i] = gl.Texture{}
  464. }
  465. }
  466. }
  467. func (s *glState) useProgram(f *gl.Functions, p gl.Program) {
  468. if !p.Equal(s.prog) {
  469. f.UseProgram(p)
  470. s.prog = p
  471. }
  472. }
  473. func (s *glState) bindFramebuffer(f *gl.Functions, target gl.Enum, fbo gl.Framebuffer) {
  474. switch target {
  475. case gl.FRAMEBUFFER:
  476. if fbo.Equal(s.drawFBO) && fbo.Equal(s.readFBO) {
  477. return
  478. }
  479. s.drawFBO = fbo
  480. s.readFBO = fbo
  481. case gl.READ_FRAMEBUFFER:
  482. if fbo.Equal(s.readFBO) {
  483. return
  484. }
  485. s.readFBO = fbo
  486. case gl.DRAW_FRAMEBUFFER:
  487. if fbo.Equal(s.drawFBO) {
  488. return
  489. }
  490. s.drawFBO = fbo
  491. default:
  492. panic("unknown target")
  493. }
  494. f.BindFramebuffer(target, fbo)
  495. }
  496. func (s *glState) bindBufferBase(f *gl.Functions, target gl.Enum, idx int, buf gl.Buffer) {
  497. switch target {
  498. case gl.UNIFORM_BUFFER:
  499. if buf.Equal(s.uniBuf) && buf.Equal(s.uniBufs[idx]) {
  500. return
  501. }
  502. s.uniBuf = buf
  503. s.uniBufs[idx] = buf
  504. case gl.SHADER_STORAGE_BUFFER:
  505. if buf.Equal(s.storeBuf) && buf.Equal(s.storeBufs[idx]) {
  506. return
  507. }
  508. s.storeBuf = buf
  509. s.storeBufs[idx] = buf
  510. default:
  511. panic("unknown buffer target")
  512. }
  513. f.BindBufferBase(target, idx, buf)
  514. }
  515. func (s *glState) bindBuffer(f *gl.Functions, target gl.Enum, buf gl.Buffer) {
  516. switch target {
  517. case gl.ARRAY_BUFFER:
  518. if buf.Equal(s.arrayBuf) {
  519. return
  520. }
  521. s.arrayBuf = buf
  522. case gl.ELEMENT_ARRAY_BUFFER:
  523. if buf.Equal(s.elemBuf) {
  524. return
  525. }
  526. s.elemBuf = buf
  527. case gl.UNIFORM_BUFFER:
  528. if buf.Equal(s.uniBuf) {
  529. return
  530. }
  531. s.uniBuf = buf
  532. case gl.SHADER_STORAGE_BUFFER:
  533. if buf.Equal(s.storeBuf) {
  534. return
  535. }
  536. s.storeBuf = buf
  537. default:
  538. panic("unknown buffer target")
  539. }
  540. f.BindBuffer(target, buf)
  541. }
  542. func (s *glState) pixelStorei(f *gl.Functions, pname gl.Enum, val int) {
  543. switch pname {
  544. case gl.UNPACK_ROW_LENGTH:
  545. if val == s.unpack_row_length {
  546. return
  547. }
  548. s.unpack_row_length = val
  549. case gl.PACK_ROW_LENGTH:
  550. if val == s.pack_row_length {
  551. return
  552. }
  553. s.pack_row_length = val
  554. default:
  555. panic("unsupported PixelStorei pname")
  556. }
  557. f.PixelStorei(pname, val)
  558. }
  559. func (s *glState) setClearColor(f *gl.Functions, r, g, b, a float32) {
  560. col := [4]float32{r, g, b, a}
  561. if col != s.clearColor {
  562. f.ClearColor(r, g, b, a)
  563. s.clearColor = col
  564. }
  565. }
  566. func (s *glState) setViewport(f *gl.Functions, x, y, width, height int) {
  567. view := [4]int{x, y, width, height}
  568. if view != s.viewport {
  569. f.Viewport(x, y, width, height)
  570. s.viewport = view
  571. }
  572. }
  573. func (s *glState) setBlendFuncSeparate(f *gl.Functions, srcRGB, dstRGB, srcA, dstA gl.Enum) {
  574. if srcRGB != s.blend.srcRGB || dstRGB != s.blend.dstRGB || srcA != s.blend.srcA || dstA != s.blend.dstA {
  575. s.blend.srcRGB = srcRGB
  576. s.blend.dstRGB = dstRGB
  577. s.blend.srcA = srcA
  578. s.blend.dstA = dstA
  579. f.BlendFuncSeparate(srcA, dstA, srcA, dstA)
  580. }
  581. }
  582. func (s *glState) set(f *gl.Functions, target gl.Enum, enable bool) {
  583. switch target {
  584. case gl.FRAMEBUFFER_SRGB:
  585. if s.srgb == enable {
  586. return
  587. }
  588. s.srgb = enable
  589. case gl.BLEND:
  590. if enable == s.blend.enable {
  591. return
  592. }
  593. s.blend.enable = enable
  594. default:
  595. panic("unknown enable")
  596. }
  597. if enable {
  598. f.Enable(target)
  599. } else {
  600. f.Disable(target)
  601. }
  602. }
  603. func (b *Backend) Caps() driver.Caps {
  604. return b.feats
  605. }
  606. func (b *Backend) NewTimer() driver.Timer {
  607. return &timer{
  608. funcs: b.funcs,
  609. obj: b.funcs.CreateQuery(),
  610. }
  611. }
  612. func (b *Backend) IsTimeContinuous() bool {
  613. return b.funcs.GetInteger(gl.GPU_DISJOINT_EXT) == gl.FALSE
  614. }
  615. func (t *texture) ensureFBO() gl.Framebuffer {
  616. if t.hasFBO {
  617. return t.fbo
  618. }
  619. b := t.backend
  620. oldFBO := b.glstate.drawFBO
  621. defer func() {
  622. b.glstate.bindFramebuffer(b.funcs, gl.FRAMEBUFFER, oldFBO)
  623. }()
  624. glErr(b.funcs)
  625. fb := b.funcs.CreateFramebuffer()
  626. b.glstate.bindFramebuffer(b.funcs, gl.FRAMEBUFFER, fb)
  627. if err := glErr(b.funcs); err != nil {
  628. b.funcs.DeleteFramebuffer(fb)
  629. panic(err)
  630. }
  631. b.funcs.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, t.obj, 0)
  632. if st := b.funcs.CheckFramebufferStatus(gl.FRAMEBUFFER); st != gl.FRAMEBUFFER_COMPLETE {
  633. b.funcs.DeleteFramebuffer(fb)
  634. panic(fmt.Errorf("incomplete framebuffer, status = 0x%x, err = %d", st, b.funcs.GetError()))
  635. }
  636. t.fbo = fb
  637. t.hasFBO = true
  638. return fb
  639. }
  640. func (b *Backend) NewTexture(format driver.TextureFormat, width, height int, minFilter, magFilter driver.TextureFilter, binding driver.BufferBinding) (driver.Texture, error) {
  641. glErr(b.funcs)
  642. tex := &texture{backend: b, obj: b.funcs.CreateTexture(), width: width, height: height, bindings: binding}
  643. switch format {
  644. case driver.TextureFormatFloat:
  645. tex.triple = b.floatTriple
  646. case driver.TextureFormatSRGBA:
  647. tex.triple = b.srgbaTriple
  648. case driver.TextureFormatRGBA8:
  649. tex.triple = textureTriple{gl.RGBA8, gl.RGBA, gl.UNSIGNED_BYTE}
  650. default:
  651. return nil, errors.New("unsupported texture format")
  652. }
  653. b.BindTexture(0, tex)
  654. min, mipmap := toTexFilter(minFilter)
  655. mag, _ := toTexFilter(magFilter)
  656. if b.gles && b.glver[0] < 3 {
  657. // OpenGL ES 2 only supports mipmaps for power-of-two textures.
  658. mipmap = false
  659. }
  660. tex.mipmap = mipmap
  661. b.funcs.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, mag)
  662. b.funcs.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, min)
  663. b.funcs.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
  664. b.funcs.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
  665. if mipmap {
  666. nmipmaps := 1
  667. if mipmap {
  668. dim := width
  669. if height > dim {
  670. dim = height
  671. }
  672. log2 := 32 - bits.LeadingZeros32(uint32(dim)) - 1
  673. nmipmaps = log2 + 1
  674. }
  675. // Immutable textures are required for BindImageTexture, and can't hurt otherwise.
  676. b.funcs.TexStorage2D(gl.TEXTURE_2D, nmipmaps, tex.triple.internalFormat, width, height)
  677. } else {
  678. b.funcs.TexImage2D(gl.TEXTURE_2D, 0, tex.triple.internalFormat, width, height, tex.triple.format, tex.triple.typ)
  679. }
  680. if err := glErr(b.funcs); err != nil {
  681. tex.Release()
  682. return nil, err
  683. }
  684. return tex, nil
  685. }
  686. func (b *Backend) NewBuffer(typ driver.BufferBinding, size int) (driver.Buffer, error) {
  687. glErr(b.funcs)
  688. buf := &buffer{backend: b, typ: typ, size: size}
  689. if typ&driver.BufferBindingUniforms != 0 {
  690. if typ != driver.BufferBindingUniforms {
  691. return nil, errors.New("uniforms buffers cannot be bound as anything else")
  692. }
  693. buf.data = make([]byte, size)
  694. }
  695. if typ&^driver.BufferBindingUniforms != 0 {
  696. buf.hasBuffer = true
  697. buf.obj = b.funcs.CreateBuffer()
  698. if err := glErr(b.funcs); err != nil {
  699. buf.Release()
  700. return nil, err
  701. }
  702. firstBinding := firstBufferType(typ)
  703. b.glstate.bindBuffer(b.funcs, firstBinding, buf.obj)
  704. b.funcs.BufferData(firstBinding, size, gl.DYNAMIC_DRAW, nil)
  705. }
  706. return buf, nil
  707. }
  708. func (b *Backend) NewImmutableBuffer(typ driver.BufferBinding, data []byte) (driver.Buffer, error) {
  709. glErr(b.funcs)
  710. obj := b.funcs.CreateBuffer()
  711. buf := &buffer{backend: b, obj: obj, typ: typ, size: len(data), hasBuffer: true}
  712. firstBinding := firstBufferType(typ)
  713. b.glstate.bindBuffer(b.funcs, firstBinding, buf.obj)
  714. b.funcs.BufferData(firstBinding, len(data), gl.STATIC_DRAW, data)
  715. buf.immutable = true
  716. if err := glErr(b.funcs); err != nil {
  717. buf.Release()
  718. return nil, err
  719. }
  720. return buf, nil
  721. }
  722. func glErr(f *gl.Functions) error {
  723. if st := f.GetError(); st != gl.NO_ERROR {
  724. return fmt.Errorf("glGetError: %#x", st)
  725. }
  726. return nil
  727. }
  728. func (b *Backend) Release() {
  729. if b.sRGBFBO != nil {
  730. b.sRGBFBO.Release()
  731. }
  732. if b.vertArray.Valid() {
  733. b.glstate.deleteVertexArray(b.funcs, b.vertArray)
  734. }
  735. *b = Backend{}
  736. }
  737. func (b *Backend) DispatchCompute(x, y, z int) {
  738. for binding, buf := range b.storage {
  739. if buf != nil {
  740. b.glstate.bindBufferBase(b.funcs, gl.SHADER_STORAGE_BUFFER, binding, buf.obj)
  741. }
  742. }
  743. b.funcs.DispatchCompute(x, y, z)
  744. b.funcs.MemoryBarrier(gl.ALL_BARRIER_BITS)
  745. }
  746. func (b *Backend) BindImageTexture(unit int, tex driver.Texture) {
  747. t := tex.(*texture)
  748. var acc gl.Enum
  749. switch t.bindings & (driver.BufferBindingShaderStorageRead | driver.BufferBindingShaderStorageWrite) {
  750. case driver.BufferBindingShaderStorageRead:
  751. acc = gl.READ_ONLY
  752. case driver.BufferBindingShaderStorageWrite:
  753. acc = gl.WRITE_ONLY
  754. case driver.BufferBindingShaderStorageRead | driver.BufferBindingShaderStorageWrite:
  755. acc = gl.READ_WRITE
  756. default:
  757. panic("unsupported access bits")
  758. }
  759. b.funcs.BindImageTexture(unit, t.obj, 0, false, 0, acc, t.triple.internalFormat)
  760. }
  761. func (b *Backend) BlendFunc(sfactor, dfactor driver.BlendFactor) {
  762. src, dst := toGLBlendFactor(sfactor), toGLBlendFactor(dfactor)
  763. b.glstate.setBlendFuncSeparate(b.funcs, src, dst, src, dst)
  764. }
  765. func toGLBlendFactor(f driver.BlendFactor) gl.Enum {
  766. switch f {
  767. case driver.BlendFactorOne:
  768. return gl.ONE
  769. case driver.BlendFactorOneMinusSrcAlpha:
  770. return gl.ONE_MINUS_SRC_ALPHA
  771. case driver.BlendFactorZero:
  772. return gl.ZERO
  773. case driver.BlendFactorDstColor:
  774. return gl.DST_COLOR
  775. default:
  776. panic("unsupported blend factor")
  777. }
  778. }
  779. func (b *Backend) SetBlend(enable bool) {
  780. b.glstate.set(b.funcs, gl.BLEND, enable)
  781. }
  782. func (b *Backend) DrawElements(off, count int) {
  783. b.prepareDraw()
  784. // off is in 16-bit indices, but DrawElements take a byte offset.
  785. byteOff := off * 2
  786. b.funcs.DrawElements(toGLDrawMode(b.state.pipeline.topology), count, gl.UNSIGNED_SHORT, byteOff)
  787. }
  788. func (b *Backend) DrawArrays(off, count int) {
  789. b.prepareDraw()
  790. b.funcs.DrawArrays(toGLDrawMode(b.state.pipeline.topology), off, count)
  791. }
  792. func (b *Backend) prepareDraw() {
  793. p := b.state.pipeline
  794. if p == nil {
  795. return
  796. }
  797. b.setupVertexArrays()
  798. }
  799. func toGLDrawMode(mode driver.Topology) gl.Enum {
  800. switch mode {
  801. case driver.TopologyTriangleStrip:
  802. return gl.TRIANGLE_STRIP
  803. case driver.TopologyTriangles:
  804. return gl.TRIANGLES
  805. default:
  806. panic("unsupported draw mode")
  807. }
  808. }
  809. func (b *Backend) Viewport(x, y, width, height int) {
  810. b.glstate.setViewport(b.funcs, x, y, width, height)
  811. }
  812. func (b *Backend) clearOutput(colR, colG, colB, colA float32) {
  813. b.glstate.setClearColor(b.funcs, colR, colG, colB, colA)
  814. b.funcs.Clear(gl.COLOR_BUFFER_BIT)
  815. }
  816. func (b *Backend) NewComputeProgram(src shader.Sources) (driver.Program, error) {
  817. // We don't support ES 3.1 compute, see brokenGLES31 above.
  818. const GLES31Source = ""
  819. p, err := gl.CreateComputeProgram(b.funcs, GLES31Source)
  820. if err != nil {
  821. return nil, fmt.Errorf("%s: %v", src.Name, err)
  822. }
  823. return &program{
  824. backend: b,
  825. obj: p,
  826. }, nil
  827. }
  828. func (b *Backend) NewVertexShader(src shader.Sources) (driver.VertexShader, error) {
  829. glslSrc := b.glslFor(src)
  830. sh, err := gl.CreateShader(b.funcs, gl.VERTEX_SHADER, glslSrc)
  831. return &glshader{backend: b, obj: sh, src: src}, err
  832. }
  833. func (b *Backend) NewFragmentShader(src shader.Sources) (driver.FragmentShader, error) {
  834. glslSrc := b.glslFor(src)
  835. sh, err := gl.CreateShader(b.funcs, gl.FRAGMENT_SHADER, glslSrc)
  836. return &glshader{backend: b, obj: sh, src: src}, err
  837. }
  838. func (b *Backend) glslFor(src shader.Sources) string {
  839. if b.gles {
  840. return src.GLSL100ES
  841. } else {
  842. return src.GLSL150
  843. }
  844. }
  845. func (b *Backend) NewPipeline(desc driver.PipelineDesc) (driver.Pipeline, error) {
  846. p, err := b.newProgram(desc)
  847. if err != nil {
  848. return nil, err
  849. }
  850. layout := desc.VertexLayout
  851. vsrc := desc.VertexShader.(*glshader).src
  852. if len(vsrc.Inputs) != len(layout.Inputs) {
  853. return nil, fmt.Errorf("opengl: got %d inputs, expected %d", len(layout.Inputs), len(vsrc.Inputs))
  854. }
  855. for i, inp := range vsrc.Inputs {
  856. if exp, got := inp.Size, layout.Inputs[i].Size; exp != got {
  857. return nil, fmt.Errorf("opengl: data size mismatch for %q: got %d expected %d", inp.Name, got, exp)
  858. }
  859. }
  860. return &pipeline{
  861. prog: p,
  862. inputs: vsrc.Inputs,
  863. layout: layout,
  864. blend: desc.BlendDesc,
  865. topology: desc.Topology,
  866. }, nil
  867. }
  868. func (b *Backend) newProgram(desc driver.PipelineDesc) (*program, error) {
  869. p := b.funcs.CreateProgram()
  870. if !p.Valid() {
  871. return nil, errors.New("opengl: glCreateProgram failed")
  872. }
  873. vsh, fsh := desc.VertexShader.(*glshader), desc.FragmentShader.(*glshader)
  874. b.funcs.AttachShader(p, vsh.obj)
  875. b.funcs.AttachShader(p, fsh.obj)
  876. for _, inp := range vsh.src.Inputs {
  877. b.funcs.BindAttribLocation(p, gl.Attrib(inp.Location), inp.Name)
  878. }
  879. b.funcs.LinkProgram(p)
  880. if b.funcs.GetProgrami(p, gl.LINK_STATUS) == 0 {
  881. log := b.funcs.GetProgramInfoLog(p)
  882. b.funcs.DeleteProgram(p)
  883. return nil, fmt.Errorf("opengl: program link failed: %s", strings.TrimSpace(log))
  884. }
  885. prog := &program{
  886. backend: b,
  887. obj: p,
  888. }
  889. b.glstate.useProgram(b.funcs, p)
  890. // Bind texture uniforms.
  891. for _, tex := range vsh.src.Textures {
  892. u := b.funcs.GetUniformLocation(p, tex.Name)
  893. if u.Valid() {
  894. b.funcs.Uniform1i(u, tex.Binding)
  895. }
  896. }
  897. for _, tex := range fsh.src.Textures {
  898. u := b.funcs.GetUniformLocation(p, tex.Name)
  899. if u.Valid() {
  900. b.funcs.Uniform1i(u, tex.Binding)
  901. }
  902. }
  903. prog.vertUniforms.setup(b.funcs, p, vsh.src.Uniforms.Size, vsh.src.Uniforms.Locations)
  904. prog.fragUniforms.setup(b.funcs, p, fsh.src.Uniforms.Size, fsh.src.Uniforms.Locations)
  905. return prog, nil
  906. }
  907. func (b *Backend) BindStorageBuffer(binding int, buf driver.Buffer) {
  908. bf := buf.(*buffer)
  909. if bf.typ&(driver.BufferBindingShaderStorageRead|driver.BufferBindingShaderStorageWrite) == 0 {
  910. panic("not a shader storage buffer")
  911. }
  912. b.storage[binding] = bf
  913. }
  914. func (b *Backend) BindUniforms(buf driver.Buffer) {
  915. bf := buf.(*buffer)
  916. if bf.typ&driver.BufferBindingUniforms == 0 {
  917. panic("not a uniform buffer")
  918. }
  919. b.state.pipeline.prog.vertUniforms.update(b.funcs, bf)
  920. b.state.pipeline.prog.fragUniforms.update(b.funcs, bf)
  921. }
  922. func (b *Backend) BindProgram(prog driver.Program) {
  923. p := prog.(*program)
  924. b.glstate.useProgram(b.funcs, p.obj)
  925. }
  926. func (s *glshader) Release() {
  927. s.backend.funcs.DeleteShader(s.obj)
  928. }
  929. func (p *program) Release() {
  930. p.backend.glstate.deleteProgram(p.backend.funcs, p.obj)
  931. }
  932. func (u *uniforms) setup(funcs *gl.Functions, p gl.Program, uniformSize int, uniforms []shader.UniformLocation) {
  933. u.locs = make([]uniformLocation, len(uniforms))
  934. for i, uniform := range uniforms {
  935. loc := funcs.GetUniformLocation(p, uniform.Name)
  936. u.locs[i] = uniformLocation{uniform: loc, offset: uniform.Offset, typ: uniform.Type, size: uniform.Size}
  937. }
  938. u.size = uniformSize
  939. }
  940. func (p *uniforms) update(funcs *gl.Functions, buf *buffer) {
  941. if buf.size < p.size {
  942. panic(fmt.Errorf("uniform buffer too small, got %d need %d", buf.size, p.size))
  943. }
  944. data := buf.data
  945. for _, u := range p.locs {
  946. if !u.uniform.Valid() {
  947. continue
  948. }
  949. data := data[u.offset:]
  950. switch {
  951. case u.typ == shader.DataTypeFloat && u.size == 1:
  952. data := data[:4]
  953. v := *(*[1]float32)(unsafe.Pointer(&data[0]))
  954. funcs.Uniform1f(u.uniform, v[0])
  955. case u.typ == shader.DataTypeFloat && u.size == 2:
  956. data := data[:8]
  957. v := *(*[2]float32)(unsafe.Pointer(&data[0]))
  958. funcs.Uniform2f(u.uniform, v[0], v[1])
  959. case u.typ == shader.DataTypeFloat && u.size == 3:
  960. data := data[:12]
  961. v := *(*[3]float32)(unsafe.Pointer(&data[0]))
  962. funcs.Uniform3f(u.uniform, v[0], v[1], v[2])
  963. case u.typ == shader.DataTypeFloat && u.size == 4:
  964. data := data[:16]
  965. v := *(*[4]float32)(unsafe.Pointer(&data[0]))
  966. funcs.Uniform4f(u.uniform, v[0], v[1], v[2], v[3])
  967. default:
  968. panic("unsupported uniform data type or size")
  969. }
  970. }
  971. }
  972. func (b *buffer) Upload(data []byte) {
  973. if b.immutable {
  974. panic("immutable buffer")
  975. }
  976. if len(data) > b.size {
  977. panic("buffer size overflow")
  978. }
  979. copy(b.data, data)
  980. if b.hasBuffer {
  981. firstBinding := firstBufferType(b.typ)
  982. b.backend.glstate.bindBuffer(b.backend.funcs, firstBinding, b.obj)
  983. if len(data) == b.size {
  984. // the iOS GL implementation doesn't recognize when BufferSubData
  985. // clears the entire buffer. Tell it and avoid GPU stalls.
  986. // See also https://github.com/godotengine/godot/issues/23956.
  987. b.backend.funcs.BufferData(firstBinding, b.size, gl.DYNAMIC_DRAW, data)
  988. } else {
  989. b.backend.funcs.BufferSubData(firstBinding, 0, data)
  990. }
  991. }
  992. }
  993. func (b *buffer) Download(data []byte) error {
  994. if len(data) > b.size {
  995. panic("buffer size overflow")
  996. }
  997. if !b.hasBuffer {
  998. copy(data, b.data)
  999. return nil
  1000. }
  1001. firstBinding := firstBufferType(b.typ)
  1002. b.backend.glstate.bindBuffer(b.backend.funcs, firstBinding, b.obj)
  1003. bufferMap := b.backend.funcs.MapBufferRange(firstBinding, 0, len(data), gl.MAP_READ_BIT)
  1004. if bufferMap == nil {
  1005. return fmt.Errorf("MapBufferRange: error %#x", b.backend.funcs.GetError())
  1006. }
  1007. copy(data, bufferMap)
  1008. if !b.backend.funcs.UnmapBuffer(firstBinding) {
  1009. return driver.ErrContentLost
  1010. }
  1011. return nil
  1012. }
  1013. func (b *buffer) Release() {
  1014. if b.hasBuffer {
  1015. b.backend.glstate.deleteBuffer(b.backend.funcs, b.obj)
  1016. b.hasBuffer = false
  1017. }
  1018. }
  1019. func (b *Backend) BindVertexBuffer(buf driver.Buffer, offset int) {
  1020. gbuf := buf.(*buffer)
  1021. if gbuf.typ&driver.BufferBindingVertices == 0 {
  1022. panic("not a vertex buffer")
  1023. }
  1024. b.state.buffer = bufferBinding{obj: gbuf.obj, offset: offset}
  1025. }
  1026. func (b *Backend) setupVertexArrays() {
  1027. p := b.state.pipeline
  1028. inputs := p.inputs
  1029. if len(inputs) == 0 {
  1030. return
  1031. }
  1032. layout := p.layout
  1033. const max = len(b.glstate.vertAttribs)
  1034. var enabled [max]bool
  1035. buf := b.state.buffer
  1036. for i, inp := range inputs {
  1037. l := layout.Inputs[i]
  1038. var gltyp gl.Enum
  1039. switch l.Type {
  1040. case shader.DataTypeFloat:
  1041. gltyp = gl.FLOAT
  1042. case shader.DataTypeShort:
  1043. gltyp = gl.SHORT
  1044. default:
  1045. panic("unsupported data type")
  1046. }
  1047. enabled[inp.Location] = true
  1048. b.glstate.vertexAttribPointer(b.funcs, buf.obj, inp.Location, l.Size, gltyp, false, p.layout.Stride, buf.offset+l.Offset)
  1049. }
  1050. for i := 0; i < max; i++ {
  1051. b.glstate.setVertexAttribArray(b.funcs, i, enabled[i])
  1052. }
  1053. }
  1054. func (b *Backend) BindIndexBuffer(buf driver.Buffer) {
  1055. gbuf := buf.(*buffer)
  1056. if gbuf.typ&driver.BufferBindingIndices == 0 {
  1057. panic("not an index buffer")
  1058. }
  1059. b.glstate.bindBuffer(b.funcs, gl.ELEMENT_ARRAY_BUFFER, gbuf.obj)
  1060. }
  1061. func (b *Backend) CopyTexture(dst driver.Texture, dstOrigin image.Point, src driver.Texture, srcRect image.Rectangle) {
  1062. const unit = 0
  1063. oldTex := b.glstate.texUnits.binds[unit]
  1064. defer func() {
  1065. b.glstate.bindTexture(b.funcs, unit, oldTex)
  1066. }()
  1067. b.glstate.bindTexture(b.funcs, unit, dst.(*texture).obj)
  1068. b.glstate.bindFramebuffer(b.funcs, gl.FRAMEBUFFER, src.(*texture).ensureFBO())
  1069. sz := srcRect.Size()
  1070. b.funcs.CopyTexSubImage2D(gl.TEXTURE_2D, 0, dstOrigin.X, dstOrigin.Y, srcRect.Min.X, srcRect.Min.Y, sz.X, sz.Y)
  1071. }
  1072. func (t *texture) ReadPixels(src image.Rectangle, pixels []byte, stride int) error {
  1073. glErr(t.backend.funcs)
  1074. t.backend.glstate.bindFramebuffer(t.backend.funcs, gl.FRAMEBUFFER, t.ensureFBO())
  1075. w, h := src.Dx(), src.Dy()
  1076. if len(pixels) < w*h*4 {
  1077. return errors.New("unexpected RGBA size")
  1078. }
  1079. // OpenGL ES 2 doesn't support PACK_ROW_LENGTH != 0. Avoid it if possible.
  1080. rowLen := 0
  1081. if n := stride / 4; n != w {
  1082. rowLen = n
  1083. }
  1084. if rowLen == 0 || t.backend.glver[0] > 2 {
  1085. t.backend.glstate.pixelStorei(t.backend.funcs, gl.PACK_ROW_LENGTH, rowLen)
  1086. t.backend.funcs.ReadPixels(src.Min.X, src.Min.Y, w, h, gl.RGBA, gl.UNSIGNED_BYTE, pixels)
  1087. } else {
  1088. tmp := make([]byte, w*h*4)
  1089. t.backend.funcs.ReadPixels(src.Min.X, src.Min.Y, w, h, gl.RGBA, gl.UNSIGNED_BYTE, tmp)
  1090. for y := 0; y < h; y++ {
  1091. copy(pixels[y*stride:], tmp[y*w*4:])
  1092. }
  1093. }
  1094. return glErr(t.backend.funcs)
  1095. }
  1096. func (b *Backend) BindPipeline(pl driver.Pipeline) {
  1097. p := pl.(*pipeline)
  1098. b.state.pipeline = p
  1099. b.glstate.useProgram(b.funcs, p.prog.obj)
  1100. b.SetBlend(p.blend.Enable)
  1101. b.BlendFunc(p.blend.SrcFactor, p.blend.DstFactor)
  1102. }
  1103. func (b *Backend) BeginCompute() {
  1104. b.funcs.MemoryBarrier(gl.ALL_BARRIER_BITS)
  1105. }
  1106. func (b *Backend) EndCompute() {
  1107. }
  1108. func (b *Backend) BeginRenderPass(tex driver.Texture, desc driver.LoadDesc) {
  1109. fbo := tex.(*texture).ensureFBO()
  1110. b.glstate.bindFramebuffer(b.funcs, gl.FRAMEBUFFER, fbo)
  1111. switch desc.Action {
  1112. case driver.LoadActionClear:
  1113. c := desc.ClearColor
  1114. b.clearOutput(c.R, c.G, c.B, c.A)
  1115. case driver.LoadActionInvalidate:
  1116. b.funcs.InvalidateFramebuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0)
  1117. }
  1118. }
  1119. func (b *Backend) EndRenderPass() {
  1120. }
  1121. func (f *texture) ImplementsRenderTarget() {}
  1122. func (p *pipeline) Release() {
  1123. p.prog.Release()
  1124. *p = pipeline{}
  1125. }
  1126. func toTexFilter(f driver.TextureFilter) (int, bool) {
  1127. switch f {
  1128. case driver.FilterNearest:
  1129. return gl.NEAREST, false
  1130. case driver.FilterLinear:
  1131. return gl.LINEAR, false
  1132. case driver.FilterLinearMipmapLinear:
  1133. return gl.LINEAR_MIPMAP_LINEAR, true
  1134. default:
  1135. panic("unsupported texture filter")
  1136. }
  1137. }
  1138. func (b *Backend) PrepareTexture(tex driver.Texture) {}
  1139. func (b *Backend) BindTexture(unit int, t driver.Texture) {
  1140. b.glstate.bindTexture(b.funcs, unit, t.(*texture).obj)
  1141. }
  1142. func (t *texture) Release() {
  1143. if t.foreign {
  1144. panic("texture not created by NewTexture")
  1145. }
  1146. if t.hasFBO {
  1147. t.backend.glstate.deleteFramebuffer(t.backend.funcs, t.fbo)
  1148. }
  1149. t.backend.glstate.deleteTexture(t.backend.funcs, t.obj)
  1150. }
  1151. func (t *texture) Upload(offset, size image.Point, pixels []byte, stride int) {
  1152. if min := size.X * size.Y * 4; min > len(pixels) {
  1153. panic(fmt.Errorf("size %d larger than data %d", min, len(pixels)))
  1154. }
  1155. t.backend.BindTexture(0, t)
  1156. // WebGL 1 doesn't support UNPACK_ROW_LENGTH != 0. Avoid it if possible.
  1157. rowLen := 0
  1158. if n := stride / 4; n != size.X {
  1159. rowLen = n
  1160. }
  1161. t.backend.glstate.pixelStorei(t.backend.funcs, gl.UNPACK_ROW_LENGTH, rowLen)
  1162. t.backend.funcs.TexSubImage2D(gl.TEXTURE_2D, 0, offset.X, offset.Y, size.X, size.Y, t.triple.format, t.triple.typ, pixels)
  1163. if t.mipmap {
  1164. t.backend.funcs.GenerateMipmap(gl.TEXTURE_2D)
  1165. }
  1166. }
  1167. func (t *timer) Begin() {
  1168. t.funcs.BeginQuery(gl.TIME_ELAPSED_EXT, t.obj)
  1169. }
  1170. func (t *timer) End() {
  1171. t.funcs.EndQuery(gl.TIME_ELAPSED_EXT)
  1172. }
  1173. func (t *timer) ready() bool {
  1174. return t.funcs.GetQueryObjectuiv(t.obj, gl.QUERY_RESULT_AVAILABLE) == gl.TRUE
  1175. }
  1176. func (t *timer) Release() {
  1177. t.funcs.DeleteQuery(t.obj)
  1178. }
  1179. func (t *timer) Duration() (time.Duration, bool) {
  1180. if !t.ready() {
  1181. return 0, false
  1182. }
  1183. nanos := t.funcs.GetQueryObjectuiv(t.obj, gl.QUERY_RESULT)
  1184. return time.Duration(nanos), true
  1185. }
  1186. // floatTripleFor determines the best texture triple for floating point FBOs.
  1187. func floatTripleFor(f *gl.Functions, ver [2]int, exts []string) (textureTriple, error) {
  1188. var triples []textureTriple
  1189. if ver[0] >= 3 {
  1190. triples = append(triples, textureTriple{gl.R16F, gl.Enum(gl.RED), gl.Enum(gl.HALF_FLOAT)})
  1191. }
  1192. // According to the OES_texture_half_float specification, EXT_color_buffer_half_float is needed to
  1193. // render to FBOs. However, the Safari WebGL1 implementation does support half-float FBOs but does not
  1194. // report EXT_color_buffer_half_float support. The triples are verified below, so it doesn't matter if we're
  1195. // wrong.
  1196. if hasExtension(exts, "GL_OES_texture_half_float") || hasExtension(exts, "GL_EXT_color_buffer_half_float") {
  1197. // Try single channel.
  1198. triples = append(triples, textureTriple{gl.LUMINANCE, gl.Enum(gl.LUMINANCE), gl.Enum(gl.HALF_FLOAT_OES)})
  1199. // Fallback to 4 channels.
  1200. triples = append(triples, textureTriple{gl.RGBA, gl.Enum(gl.RGBA), gl.Enum(gl.HALF_FLOAT_OES)})
  1201. }
  1202. if hasExtension(exts, "GL_OES_texture_float") || hasExtension(exts, "GL_EXT_color_buffer_float") {
  1203. triples = append(triples, textureTriple{gl.RGBA, gl.Enum(gl.RGBA), gl.Enum(gl.FLOAT)})
  1204. }
  1205. tex := f.CreateTexture()
  1206. defer f.DeleteTexture(tex)
  1207. defTex := gl.Texture(f.GetBinding(gl.TEXTURE_BINDING_2D))
  1208. defer f.BindTexture(gl.TEXTURE_2D, defTex)
  1209. f.BindTexture(gl.TEXTURE_2D, tex)
  1210. f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
  1211. f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
  1212. f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
  1213. f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
  1214. fbo := f.CreateFramebuffer()
  1215. defer f.DeleteFramebuffer(fbo)
  1216. defFBO := gl.Framebuffer(f.GetBinding(gl.FRAMEBUFFER_BINDING))
  1217. f.BindFramebuffer(gl.FRAMEBUFFER, fbo)
  1218. defer f.BindFramebuffer(gl.FRAMEBUFFER, defFBO)
  1219. var attempts []string
  1220. for _, tt := range triples {
  1221. const size = 256
  1222. f.TexImage2D(gl.TEXTURE_2D, 0, tt.internalFormat, size, size, tt.format, tt.typ)
  1223. f.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)
  1224. st := f.CheckFramebufferStatus(gl.FRAMEBUFFER)
  1225. if st == gl.FRAMEBUFFER_COMPLETE {
  1226. return tt, nil
  1227. }
  1228. attempts = append(attempts, fmt.Sprintf("(0x%x, 0x%x, 0x%x): 0x%x", tt.internalFormat, tt.format, tt.typ, st))
  1229. }
  1230. return textureTriple{}, fmt.Errorf("floating point fbos not supported (attempted %s)", attempts)
  1231. }
  1232. func srgbaTripleFor(ver [2]int, exts []string) (textureTriple, error) {
  1233. switch {
  1234. case ver[0] >= 3:
  1235. return textureTriple{gl.SRGB8_ALPHA8, gl.Enum(gl.RGBA), gl.Enum(gl.UNSIGNED_BYTE)}, nil
  1236. case hasExtension(exts, "GL_EXT_sRGB"):
  1237. return textureTriple{gl.SRGB_ALPHA_EXT, gl.Enum(gl.SRGB_ALPHA_EXT), gl.Enum(gl.UNSIGNED_BYTE)}, nil
  1238. default:
  1239. return textureTriple{}, errors.New("no sRGB texture formats found")
  1240. }
  1241. }
  1242. func alphaTripleFor(ver [2]int) textureTriple {
  1243. intf, f := gl.Enum(gl.R8), gl.Enum(gl.RED)
  1244. if ver[0] < 3 {
  1245. // R8, RED not supported on OpenGL ES 2.0.
  1246. intf, f = gl.LUMINANCE, gl.Enum(gl.LUMINANCE)
  1247. }
  1248. return textureTriple{intf, f, gl.UNSIGNED_BYTE}
  1249. }
  1250. func hasExtension(exts []string, ext string) bool {
  1251. for _, e := range exts {
  1252. if ext == e {
  1253. return true
  1254. }
  1255. }
  1256. return false
  1257. }
  1258. func firstBufferType(typ driver.BufferBinding) gl.Enum {
  1259. switch {
  1260. case typ&driver.BufferBindingIndices != 0:
  1261. return gl.ELEMENT_ARRAY_BUFFER
  1262. case typ&driver.BufferBindingVertices != 0:
  1263. return gl.ARRAY_BUFFER
  1264. case typ&driver.BufferBindingUniforms != 0:
  1265. return gl.UNIFORM_BUFFER
  1266. case typ&(driver.BufferBindingShaderStorageRead|driver.BufferBindingShaderStorageWrite) != 0:
  1267. return gl.SHADER_STORAGE_BUFFER
  1268. default:
  1269. panic("unsupported buffer type")
  1270. }
  1271. }