浏览代码

fix compute buffer bug on Unity 2019 and above on low-level machines

/main
xingwei.zhu 5 年前
当前提交
b4307cb3
共有 4 个文件被更改,包括 165 次插入66 次删除
  1. 4
      Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_impl.cs
  2. 80
      Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader.cs
  3. 136
      Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_initializer.cs
  4. 11
      Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_initializer.cs.meta

4
Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_impl.cs


}
public void flush(uiPicture picture) {
if (!CanvasShader.isReady()) {
return;
}
this._reset();
this._resetRenderTextureId();
this._resetComputeBuffer();

80
Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader.cs


}
}
static class CanvasShader {
static readonly MaterialByBlendModeStencilComp _convexFillMat;
static readonly MaterialByStencilComp _fill0Mat;
static readonly MaterialByBlendMode _fill1Mat;
static readonly MaterialByBlendModeStencilComp _stroke0Mat;
static readonly Material _stroke1Mat;
static readonly MaterialByBlendModeStencilComp _texMat;
static readonly Material _stencilMat;
static readonly Material _filterMat;
static readonly MaterialByBlendModeStencilComp _strokeAlphaMat;
static readonly Material _shadowBox;
static readonly Material _shadowRBox;
static partial class CanvasShader {
static MaterialByBlendModeStencilComp _convexFillMat;
static MaterialByStencilComp _fill0Mat;
static MaterialByBlendMode _fill1Mat;
static MaterialByBlendModeStencilComp _stroke0Mat;
static Material _stroke1Mat;
static MaterialByBlendModeStencilComp _texMat;
static Material _stencilMat;
static Material _filterMat;
static MaterialByBlendModeStencilComp _strokeAlphaMat;
static Material _shadowBox;
static Material _shadowRBox;
static Shader GetShader(string shaderName) {
var shader = Shader.Find(shaderName);

public static bool enableComputeBuffer = true;
public static readonly bool supportComputeBuffer;
public static bool supportComputeBuffer;
var convexFillShaderCompute = GetShader("UIWidgets/canvas_convexFill_cb");
supportComputeBuffer = enableComputeBuffer && SystemInfo.supportsComputeShaders && convexFillShaderCompute.isSupported;
//if compute buffer is not supported, load normal shader
if (!supportComputeBuffer) {
var convexFillShader = GetShader("UIWidgets/canvas_convexFill");
var fill0Shader = GetShader("UIWidgets/canvas_fill0");
var fill1Shader = GetShader("UIWidgets/canvas_fill1");
var stroke0Shader = GetShader("UIWidgets/canvas_stroke0");
var stroke1Shader = GetShader("UIWidgets/canvas_stroke1");
var texShader = GetShader("UIWidgets/canvas_tex");
var stencilShader = GetShader("UIWidgets/canvas_stencil");
var filterShader = GetShader("UIWidgets/canvas_filter");
var shadowBoxShader = GetShader("UIWidgets/ShadowBox");
var shadowRBoxShader = GetShader("UIWidgets/ShadowRBox");
var strokeAlphaShader = GetShader("UIWidgets/canvas_strokeAlpha");
_convexFillMat = new MaterialByBlendModeStencilComp(convexFillShader);
_fill0Mat = new MaterialByStencilComp(fill0Shader);
_fill1Mat = new MaterialByBlendMode(fill1Shader);
_stroke0Mat = new MaterialByBlendModeStencilComp(stroke0Shader);
_stroke1Mat = new Material(stroke1Shader) {hideFlags = HideFlags.HideAndDontSave};
_strokeAlphaMat = new MaterialByBlendModeStencilComp(strokeAlphaShader);
_texMat = new MaterialByBlendModeStencilComp(texShader);
_stencilMat = new Material(stencilShader) {hideFlags = HideFlags.HideAndDontSave};
_filterMat = new Material(filterShader) {hideFlags = HideFlags.HideAndDontSave};
_shadowBox = new Material(shadowBoxShader) {hideFlags = HideFlags.HideAndDontSave};
_shadowRBox = new Material(shadowRBoxShader) {hideFlags = HideFlags.HideAndDontSave};
}
else {
var fill0ShaderCompute = GetShader("UIWidgets/canvas_fill0_cb");
var fill1ShaderCompute = GetShader("UIWidgets/canvas_fill1_cb");
var stroke0ShaderCompute = GetShader("UIWidgets/canvas_stroke0_cb");
var stroke1ShaderCompute = GetShader("UIWidgets/canvas_stroke1_cb");
var texShaderCompute = GetShader("UIWidgets/canvas_tex_cb");
var stencilShaderCompute = GetShader("UIWidgets/canvas_stencil_cb");
var filterShaderCompute = GetShader("UIWidgets/canvas_filter_cb");
var shadowBoxShaderCompute = GetShader("UIWidgets/ShadowBox_cb");
var shadowRBoxShaderCompute = GetShader("UIWidgets/ShadowRBox_cb");
var strokeAlphaShaderCompute = GetShader("UIWidgets/canvas_strokeAlpha_cb");
_convexFillMat = new MaterialByBlendModeStencilComp(convexFillShaderCompute);
_fill0Mat = new MaterialByStencilComp(fill0ShaderCompute);
_fill1Mat = new MaterialByBlendMode(fill1ShaderCompute);
_stroke0Mat = new MaterialByBlendModeStencilComp(stroke0ShaderCompute);
_stroke1Mat = new Material(stroke1ShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
_strokeAlphaMat = new MaterialByBlendModeStencilComp(strokeAlphaShaderCompute);
_texMat = new MaterialByBlendModeStencilComp(texShaderCompute);
_stencilMat = new Material(stencilShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
_filterMat= new Material(filterShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
_shadowBox = new Material(shadowBoxShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
_shadowRBox = new Material(shadowRBoxShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
}
}
static readonly int _viewportId = Shader.PropertyToID("_viewport");

public static PictureFlusher.CmdDraw convexFill(PictureFlusher.RenderLayer layer, uiPaint paint,
uiMeshMesh mesh) {
var mat = _convexFillMat.getMaterial(paint.blendMode, layer.ignoreClip);
_getShaderPassAndProps(layer, paint, mesh.matrix, 1.0f, 0.0f, out var pass, out var props);
return PictureFlusher.CmdDraw.create(

136
Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_initializer.cs


using System;
using Unity.UIWidgets.foundation;
using UnityEngine;
using UnityEngine.Rendering;
namespace Unity.UIWidgets.ui {
enum InitStage {
NotPrepared,
Prepared,
Ready
}
static partial class CanvasShader {
static InitStage initStage = InitStage.NotPrepared;
static int initialFrameCount;
static Shader testShader;
const string testShaderName = "UIWidgets/canvas_convexFill_cb";
static bool OnNotPrepared() {
initStage = InitStage.Prepared;
initialFrameCount = Time.frameCount;
testShader = GetShader(testShaderName);
var material = new Material(testShader);
//for Unity 2018 or below, shader is compiled after Shader.Find() call immediately,
//therefore we can just skip the manually preload if the compilation fails
if (!material.shader.isSupported) {
ObjectUtils.SafeDestroy(material);
return OnPrepared(true);
}
using (var cmdBuf = new CommandBuffer()) {
var renderTarget = new RenderTexture(1, 1, 1);
cmdBuf.SetRenderTarget(renderTarget);
var mesh = new Mesh {
vertices = new[] {new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0)},
uv = new[] {new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1)},
triangles = new[] {0, 1, 2}
};
cmdBuf.DrawMesh(mesh, Matrix4x4.identity, material);
cmdBuf.DisableScissorRect();
Graphics.ExecuteCommandBuffer(cmdBuf);
ObjectUtils.SafeDestroy(renderTarget);
ObjectUtils.SafeDestroy(mesh);
}
ObjectUtils.SafeDestroy(material);
return false;
}
static bool OnPrepared(bool forceReady = false) {
D.assert(initStage == InitStage.Prepared);
if (!forceReady && initialFrameCount >= Time.frameCount) {
return false;
}
initStage = InitStage.Ready;
DoPrepare();
return true;
}
static void DoPrepare() {
D.assert(testShader != null);
var isShaderSupported = testShader.isSupported;
testShader = null;
supportComputeBuffer = enableComputeBuffer && SystemInfo.supportsComputeShaders && isShaderSupported;
if (!supportComputeBuffer) {
var convexFillShader = GetShader("UIWidgets/canvas_convexFill");
var fill0Shader = GetShader("UIWidgets/canvas_fill0");
var fill1Shader = GetShader("UIWidgets/canvas_fill1");
var stroke0Shader = GetShader("UIWidgets/canvas_stroke0");
var stroke1Shader = GetShader("UIWidgets/canvas_stroke1");
var texShader = GetShader("UIWidgets/canvas_tex");
var stencilShader = GetShader("UIWidgets/canvas_stencil");
var filterShader = GetShader("UIWidgets/canvas_filter");
var shadowBoxShader = GetShader("UIWidgets/ShadowBox");
var shadowRBoxShader = GetShader("UIWidgets/ShadowRBox");
var strokeAlphaShader = GetShader("UIWidgets/canvas_strokeAlpha");
_convexFillMat = new MaterialByBlendModeStencilComp(convexFillShader);
_fill0Mat = new MaterialByStencilComp(fill0Shader);
_fill1Mat = new MaterialByBlendMode(fill1Shader);
_stroke0Mat = new MaterialByBlendModeStencilComp(stroke0Shader);
_stroke1Mat = new Material(stroke1Shader) {hideFlags = HideFlags.HideAndDontSave};
_strokeAlphaMat = new MaterialByBlendModeStencilComp(strokeAlphaShader);
_texMat = new MaterialByBlendModeStencilComp(texShader);
_stencilMat = new Material(stencilShader) {hideFlags = HideFlags.HideAndDontSave};
_filterMat = new Material(filterShader) {hideFlags = HideFlags.HideAndDontSave};
_shadowBox = new Material(shadowBoxShader) {hideFlags = HideFlags.HideAndDontSave};
_shadowRBox = new Material(shadowRBoxShader) {hideFlags = HideFlags.HideAndDontSave};
}
else {
var convexFillShaderCompute = GetShader("UIWidgets/canvas_convexFill_cb");
var fill0ShaderCompute = GetShader("UIWidgets/canvas_fill0_cb");
var fill1ShaderCompute = GetShader("UIWidgets/canvas_fill1_cb");
var stroke0ShaderCompute = GetShader("UIWidgets/canvas_stroke0_cb");
var stroke1ShaderCompute = GetShader("UIWidgets/canvas_stroke1_cb");
var texShaderCompute = GetShader("UIWidgets/canvas_tex_cb");
var stencilShaderCompute = GetShader("UIWidgets/canvas_stencil_cb");
var filterShaderCompute = GetShader("UIWidgets/canvas_filter_cb");
var shadowBoxShaderCompute = GetShader("UIWidgets/ShadowBox_cb");
var shadowRBoxShaderCompute = GetShader("UIWidgets/ShadowRBox_cb");
var strokeAlphaShaderCompute = GetShader("UIWidgets/canvas_strokeAlpha_cb");
_convexFillMat = new MaterialByBlendModeStencilComp(convexFillShaderCompute);
_fill0Mat = new MaterialByStencilComp(fill0ShaderCompute);
_fill1Mat = new MaterialByBlendMode(fill1ShaderCompute);
_stroke0Mat = new MaterialByBlendModeStencilComp(stroke0ShaderCompute);
_stroke1Mat = new Material(stroke1ShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
_strokeAlphaMat = new MaterialByBlendModeStencilComp(strokeAlphaShaderCompute);
_texMat = new MaterialByBlendModeStencilComp(texShaderCompute);
_stencilMat = new Material(stencilShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
_filterMat = new Material(filterShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
_shadowBox = new Material(shadowBoxShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
_shadowRBox = new Material(shadowRBoxShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
}
}
public static bool isReady() {
switch (initStage) {
case InitStage.NotPrepared:
return OnNotPrepared();
case InitStage.Prepared:
return OnPrepared();
case InitStage.Ready:
return true;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}

11
Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_initializer.cs.meta


fileFormatVersion: 2
guid: 2ac77d972b29f49709bc66afaa7ca199
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存