Bindings.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import DataMap from './DataMap.js';
  2. import { AttributeType } from './Constants.js';
  3. class Bindings extends DataMap {
  4. constructor( backend, nodes, textures, attributes, pipelines, info ) {
  5. super();
  6. this.backend = backend;
  7. this.textures = textures;
  8. this.pipelines = pipelines;
  9. this.attributes = attributes;
  10. this.nodes = nodes;
  11. this.info = info;
  12. this.pipelines.bindings = this; // assign bindings to pipelines
  13. }
  14. getForRender( renderObject ) {
  15. const bindings = renderObject.getBindings();
  16. const data = this.get( renderObject );
  17. if ( data.bindings !== bindings ) {
  18. // each object defines an array of bindings (ubos, textures, samplers etc.)
  19. data.bindings = bindings;
  20. this._init( bindings );
  21. this.backend.createBindings( bindings );
  22. }
  23. return data.bindings;
  24. }
  25. getForCompute( computeNode ) {
  26. const data = this.get( computeNode );
  27. if ( data.bindings === undefined ) {
  28. const nodeBuilderState = this.nodes.getForCompute( computeNode );
  29. const bindings = nodeBuilderState.bindings.compute;
  30. data.bindings = bindings;
  31. this._init( bindings );
  32. this.backend.createBindings( bindings );
  33. }
  34. return data.bindings;
  35. }
  36. updateForCompute( computeNode ) {
  37. this._update( computeNode, this.getForCompute( computeNode ) );
  38. }
  39. updateForRender( renderObject ) {
  40. this._update( renderObject, this.getForRender( renderObject ) );
  41. }
  42. _init( bindings ) {
  43. for ( const binding of bindings ) {
  44. if ( binding.isSampledTexture ) {
  45. this.textures.updateTexture( binding.texture );
  46. } else if ( binding.isStorageBuffer ) {
  47. const attribute = binding.attribute;
  48. this.attributes.update( attribute, AttributeType.STORAGE );
  49. }
  50. }
  51. }
  52. _update( object, bindings ) {
  53. const { backend } = this;
  54. let needsBindingsUpdate = false;
  55. // iterate over all bindings and check if buffer updates or a new binding group is required
  56. for ( const binding of bindings ) {
  57. if ( binding.isNodeUniformsGroup ) {
  58. const updated = this.nodes.updateGroup( binding );
  59. if ( ! updated ) continue;
  60. }
  61. if ( binding.isUniformBuffer ) {
  62. const updated = binding.update();
  63. if ( updated ) {
  64. backend.updateBinding( binding );
  65. }
  66. } else if ( binding.isSampledTexture ) {
  67. const texture = binding.texture;
  68. if ( binding.needsBindingsUpdate ) needsBindingsUpdate = true;
  69. const updated = binding.update();
  70. if ( updated ) {
  71. this.textures.updateTexture( binding.texture );
  72. }
  73. if ( texture.isStorageTexture === true ) {
  74. const textureData = this.get( texture );
  75. if ( binding.store === true ) {
  76. textureData.needsMipmap = true;
  77. } else if ( texture.generateMipmaps === true && this.textures.needsMipmaps( texture ) && textureData.needsMipmap === true ) {
  78. this.backend.generateMipmaps( texture );
  79. textureData.needsMipmap = false;
  80. }
  81. }
  82. }
  83. }
  84. if ( needsBindingsUpdate === true ) {
  85. const pipeline = this.pipelines.getForRender( object );
  86. this.backend.updateBindings( bindings, pipeline );
  87. }
  88. }
  89. }
  90. export default Bindings;