Wonder-Technology/Wonder.js

View on GitHub
lib/js/src/run/rtx_path_tracer/domain_layer/domain/pipeline/pipeline/entity/jobs/update/UpdateTextureArrayCPJobEntity.bs.js

Summary

Maintainability
A
2 hrs
Test Coverage
'use strict';

var Most = require("most");
var Curry = require("bs-platform/lib/js/curry.js");
var Js_math = require("bs-platform/lib/js/js_math.js");
var Log$Wonderjs = require("../../../../../../../../../construct/domain_layer/library/log/Log.bs.js");
var ListSt$Wonderjs = require("../../../../../../../../../construct/domain_layer/library/structure/ListSt.bs.js");
var Number$Wonderjs = require("../../../../../../../../../construct/domain_layer/library/structure/Number.bs.js");
var Result$Wonderjs = require("../../../../../../../../../construct/domain_layer/library/structure/Result.bs.js");
var Tuple2$Wonderjs = require("../../../../../../../../../construct/domain_layer/library/structure/tuple/Tuple2.bs.js");
var Contract$Wonderjs = require("../../../../../../../../../construct/domain_layer/library/contract/Contract.bs.js");
var ImageIdVO$Wonderjs = require("../../../../../../../../../construct/domain_layer/domain/asset/image/value_object/ImageIdVO.bs.js");
var JobEntity$Wonderjs = require("../../../../../../../../../construct/domain_layer/domain/pipeline/pipeline/entity/JobEntity.bs.js");
var AssetRunAPI$Wonderjs = require("../../../../../../../../../construct/external_layer/api/domain/AssetRunAPI.bs.js");
var SceneRunAPI$Wonderjs = require("../../../../../../../../../construct/external_layer/api/domain/SceneRunAPI.bs.js");
var WebGPUCPAPI$Wonderjs = require("../../../../../../../external_layer/api/WebGPUCPAPI.bs.js");
var WebGPUCPRepo$Wonderjs = require("../../../../../../repo/webgpu/WebGPUCPRepo.bs.js");
var ConfigDpRunAPI$Wonderjs = require("../../../../../../../../../construct/external_layer/api/dependency/ConfigDpRunAPI.bs.js");
var GameObjectRunAPI$Wonderjs = require("../../../../../../../../../construct/external_layer/api/domain/GameObjectRunAPI.bs.js");
var BSDFMaterialRunAPI$Wonderjs = require("../../../../../../../../../construct/external_layer/api/domain/BSDFMaterialRunAPI.bs.js");
var WebGPUCoreDpRunAPI$Wonderjs = require("../../../../../../../../../construct/external_layer/api/dependency/WebGPUCoreDpRunAPI.bs.js");
var TypeArrayCPRepoUtils$Wonderjs = require("../../../../../../../infrastructure_layer/dependency/repo/utils/TypeArrayCPRepoUtils.bs.js");
var TextureArrayWebGPUCPRepo$Wonderjs = require("../../../../../../repo/webgpu/TextureArrayWebGPUCPRepo.bs.js");

function create(param) {
  return JobEntity$Wonderjs.create("update_textureArray");
}

function _addImageIdAndData(result, imageId) {
  var imageData = AssetRunAPI$Wonderjs.getImageData(imageId);
  if (imageData !== undefined) {
    return {
            hd: [
              imageId,
              imageData
            ],
            tl: result
          };
  } else {
    return result;
  }
}

function _getAllUsedImageIdAndData(sceneGameObject) {
  return ListSt$Wonderjs.removeDuplicateItemsU(ListSt$Wonderjs.reduce(GameObjectRunAPI$Wonderjs.getAllRenderBSDFMaterials(sceneGameObject), /* [] */0, (function (result, material) {
                    var imageId = BSDFMaterialRunAPI$Wonderjs.getSpecularMapImageId(material);
                    var result$1 = imageId !== undefined ? _addImageIdAndData(result, imageId) : result;
                    var imageId$1 = BSDFMaterialRunAPI$Wonderjs.getDiffuseMapImageId(material);
                    var result$2 = imageId$1 !== undefined ? _addImageIdAndData(result$1, imageId$1) : result$1;
                    var imageId$2 = BSDFMaterialRunAPI$Wonderjs.getChannelRoughnessMetallicMapImageId(material);
                    var result$3 = imageId$2 !== undefined ? _addImageIdAndData(result$2, imageId$2) : result$2;
                    var imageId$3 = BSDFMaterialRunAPI$Wonderjs.getEmissionMapImageId(material);
                    var result$4 = imageId$3 !== undefined ? _addImageIdAndData(result$3, imageId$3) : result$3;
                    var imageId$4 = BSDFMaterialRunAPI$Wonderjs.getNormalMapImageId(material);
                    var result$5 = imageId$4 !== undefined ? _addImageIdAndData(result$4, imageId$4) : result$4;
                    var imageId$5 = BSDFMaterialRunAPI$Wonderjs.getTransmissionMapImageId(material);
                    if (imageId$5 !== undefined) {
                      return _addImageIdAndData(result$5, imageId$5);
                    } else {
                      return result$5;
                    }
                  })), (function (param) {
                return ImageIdVO$Wonderjs.value(param[0]);
              }));
}

function _getLayerCount(allUsedImageIdAndData) {
  var count = ListSt$Wonderjs.length(allUsedImageIdAndData);
  return Contract$Wonderjs.ensureCheck(count === 0 ? 1 : count, (function (r) {
                var maxLayerCount = Curry._1(WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).capacity.getTextureArrayMaxLayerCount, undefined);
                return Contract$Wonderjs.test(Log$Wonderjs.buildAssertMessage("layer count:" + r + " < " + maxLayerCount, "not"), (function (param) {
                              return Contract$Wonderjs.Operators.$less(r, maxLayerCount);
                            }));
              }), Curry._1(ConfigDpRunAPI$Wonderjs.unsafeGet(undefined).getIsDebug, undefined));
}

function _setMapBetweenImageIdToLayerIndex(allUsedImageIdAndData) {
  ListSt$Wonderjs.reduce(allUsedImageIdAndData, 0, (function (layerIndex, param) {
          TextureArrayWebGPUCPRepo$Wonderjs.setLayerIndex(ImageIdVO$Wonderjs.value(param[0]), layerIndex);
          return layerIndex + 1 | 0;
        }));
  
}

function _buildWebGPUObjects(device, param) {
  var layerCount = param[2];
  var format = "rgba8unorm";
  var textureArray = Curry._2(WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).device.createTexture, {
        size: {
          width: param[0],
          height: param[1],
          depth: 1
        },
        arrayLayerCount: layerCount,
        mipLevelCount: 1,
        sampleCount: 1,
        dimension: "2d",
        format: format,
        usage: WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).textureUsage.copy_dst | WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).textureUsage.sampled
      }, device);
  var textureArrayView = Curry._2(WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).texture.createView, {
        format: format,
        dimension: "2d-array",
        baseArrayLayer: 0,
        arrayLayerCount: layerCount
      }, textureArray);
  var textureSampler = Curry._2(WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).device.createSampler, {
        magFilter: "linear",
        minFilter: "linear",
        addressModeU: "repeat",
        addressModeV: "repeat",
        addressModeW: "repeat"
      }, device);
  return [
          textureArray,
          textureArrayView,
          textureSampler
        ];
}

function _fillImageDataToBufferDataWithFixedSize(param, param$1, bytesPerRow) {
  var data = param$1.data;
  var height = param$1.height;
  var width = param$1.width;
  var textureArrayLayerHeight = param[1];
  if (width === param[0] && height === textureArrayLayerHeight) {
    return data;
  }
  var yy = 0;
  var xx = 0;
  var bufferData = new Uint8Array(Math.imul(bytesPerRow, textureArrayLayerHeight));
  while(yy < height) {
    xx = 0;
    while(xx < width) {
      var bufferDataIndex = (xx << 2) + Math.imul(yy, bytesPerRow) | 0;
      var dataIndex = (xx << 2) + (Math.imul(yy, width) << 2) | 0;
      TypeArrayCPRepoUtils$Wonderjs.setUint8_1WithoutCheck(bufferDataIndex + 0 | 0, TypeArrayCPRepoUtils$Wonderjs.getUint8_1(dataIndex + 0 | 0, data), bufferData);
      TypeArrayCPRepoUtils$Wonderjs.setUint8_1WithoutCheck(bufferDataIndex + 1 | 0, TypeArrayCPRepoUtils$Wonderjs.getUint8_1(dataIndex + 1 | 0, data), bufferData);
      TypeArrayCPRepoUtils$Wonderjs.setUint8_1WithoutCheck(bufferDataIndex + 2 | 0, TypeArrayCPRepoUtils$Wonderjs.getUint8_1(dataIndex + 2 | 0, data), bufferData);
      TypeArrayCPRepoUtils$Wonderjs.setUint8_1WithoutCheck(bufferDataIndex + 3 | 0, TypeArrayCPRepoUtils$Wonderjs.getUint8_1(dataIndex + 3 | 0, data), bufferData);
      xx = xx + 1 | 0;
    };
    yy = yy + 1 | 0;
  };
  return bufferData;
}

function _fillTextureArray(param, textureArray, param$1, allUsedImageIdAndData) {
  var textureArrayLayerHeight = param$1[1];
  var textureArrayLayerWidth = param$1[0];
  var queue = param[1];
  var device = param[0];
  var bytesPerRow = (Js_math.ceil_int(Number$Wonderjs.dividInt((textureArrayLayerWidth << 2), 256)) << 8);
  var textureBuffer = Curry._2(WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).device.createBuffer, {
        size: Math.imul(Math.imul(bytesPerRow, textureArrayLayerHeight), Uint8Array.BYTES_PER_ELEMENT),
        usage: WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).bufferUsage.copy_src | WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).bufferUsage.copy_dst
      }, device);
  return ListSt$Wonderjs.forEachi(allUsedImageIdAndData, (function (layerIndex, param) {
                var commandEncoder = Curry._2(WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).device.createCommandEncoder, {}, device);
                var bufferData = _fillImageDataToBufferDataWithFixedSize([
                      textureArrayLayerWidth,
                      textureArrayLayerHeight
                    ], param[1], bytesPerRow);
                Curry._3(WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).buffer.setSubUint8Data, 0, bufferData, textureBuffer);
                Curry._4(WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).commandEncoder.copyBufferToTexture, {
                      buffer: textureBuffer,
                      bytesPerRow: bytesPerRow,
                      arrayLayer: 0,
                      mipLevel: 0,
                      textureArrayLayerHeight: 0
                    }, {
                      texture: textureArray,
                      mipLevel: 0,
                      arrayLayer: layerIndex,
                      origin: {
                        x: 0,
                        y: 0,
                        z: 0
                      }
                    }, {
                      width: textureArrayLayerWidth,
                      height: textureArrayLayerHeight,
                      depth: 1
                    }, commandEncoder);
                return Curry._2(WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).queue.submit, [Curry._1(WebGPUCoreDpRunAPI$Wonderjs.unsafeGet(undefined).commandEncoder.finish, commandEncoder)], queue);
              }));
}

function _setWebGPUObjects(textureArrayView, textureSampler) {
  TextureArrayWebGPUCPRepo$Wonderjs.setTextureArrayView(textureArrayView);
  return TextureArrayWebGPUCPRepo$Wonderjs.setTextureSampler(textureSampler);
}

function exec(param) {
  return Most.just(Result$Wonderjs.bind(Tuple2$Wonderjs.collectOption(WebGPUCPRepo$Wonderjs.getDevice(undefined), WebGPUCPRepo$Wonderjs.getQueue(undefined)), (function (param) {
                    var queue = param[1];
                    var device = param[0];
                    var allUsedImageIdAndData = _getAllUsedImageIdAndData(SceneRunAPI$Wonderjs.getSceneGameObject(undefined));
                    _setMapBetweenImageIdToLayerIndex(allUsedImageIdAndData);
                    var match = WebGPUCPAPI$Wonderjs.getTextureArrayLayerSize(undefined);
                    var textureArrayLayerHeight = match[1];
                    var textureArrayLayerWidth = match[0];
                    return Result$Wonderjs.mapSuccess(_getLayerCount(allUsedImageIdAndData), (function (layerCount) {
                                  var match = _buildWebGPUObjects(device, [
                                        textureArrayLayerWidth,
                                        textureArrayLayerHeight,
                                        layerCount
                                      ]);
                                  _fillTextureArray([
                                        device,
                                        queue
                                      ], match[0], [
                                        textureArrayLayerWidth,
                                        textureArrayLayerHeight
                                      ], allUsedImageIdAndData);
                                  TextureArrayWebGPUCPRepo$Wonderjs.setTextureArrayView(match[1]);
                                  return TextureArrayWebGPUCPRepo$Wonderjs.setTextureSampler(match[2]);
                                }));
                  })));
}

exports.create = create;
exports._addImageIdAndData = _addImageIdAndData;
exports._getAllUsedImageIdAndData = _getAllUsedImageIdAndData;
exports._getLayerCount = _getLayerCount;
exports._setMapBetweenImageIdToLayerIndex = _setMapBetweenImageIdToLayerIndex;
exports._buildWebGPUObjects = _buildWebGPUObjects;
exports._fillImageDataToBufferDataWithFixedSize = _fillImageDataToBufferDataWithFixedSize;
exports._fillTextureArray = _fillTextureArray;
exports._setWebGPUObjects = _setWebGPUObjects;
exports.exec = exec;
/* most Not a pure module */