Search Unity

DrawProcedural doesn't seem to work in URP

Discussion in 'Universal Render Pipeline' started by jwtstone, Oct 20, 2019.

  1. jwtstone

    jwtstone

    Joined:
    Oct 11, 2019
    Posts:
    1
    Hi, This is my first thread in unity forum... Because I have absolutely no clue of the problem and I really need some help now...

    Breif:
    • I wrote a custom renderer feature binded with a custom render pass in Universal Render Pipeline,
    • Firstly, I tried to use DrawProceduralIndirect(...) in Excute() function in my render pass, It crashed all the time.
    • Then I tried DrawProcedural(...), It was a little better because it won't cause a crash, and in frame profiler "Draw Procedural" calls are captured, but it basically draws nothing on the screen. Snipaste_2019-10-20_11-31-53.png
    Details:
    • Before Using DrawProcedural, I dispatched a compute shader, I don't know if this will affect DrawProcedural()?
    • In DrawProcedural, I used a material with several compute buffers stored in other monobehaviours,
      I used GetData() to check them and these buffers are setup correctly all the time. I setup buffers and call drawprocedural in line 111-135. (The compute buffers are stored in some monobehaviours in scene, I create them in start() event).
      Code (CSharp):
      1.     public override void Execute(
      2.         ScriptableRenderContext context,
      3.         ref RenderingData renderingData
      4.     )
      5.     {
      6.         m_cmd = new CommandBuffer { name = m_ProfilerTag };
      7.         m_cmd.Clear();
      8.  
      9.         //-/////////////////////////////////////////////////////////
      10.         /// Bind Per-Camera parameters with Compute Kernels
      11.         Camera camera = renderingData.cameraData.camera;
      12.         m_cmd.SetComputeVectorParam(
      13.             m_CS,
      14.             Shader.PropertyToID("CVector_CameraPosWS"),
      15.             camera.transform.position
      16.         );
      17.  
      18.         //-/////////////////////////////////////////////////////////
      19.         foreach (LineDrawingObject mesh in LineDrawingMaster.objectPool){
      20.             //-/////////////////////////////////////////////////////////
      21.             // Bind Per-Mesh Resources with Compute Kernels
      22.             /// From LineDrawingObject (Monobehaviour)
      23.             ///-/// Constants
      24.             m_cmd.SetComputeMatrixParam( // Object to World amtrx
      25.                 m_CS,
      26.                 Shader.PropertyToID("CMatrix_Object2World"),
      27.                 mesh.transformMatrixOS
      28.             );
      29.             ///-/// Compute Buffers
      30.             m_cmd.SetComputeBufferParam(
      31.                 m_CS,
      32.                 m_CSKernel_Prev.kernelIndex,
      33.                 "CBuffer_VPList",
      34.                 mesh.cbuffVPosition
      35.             );
      36.             m_cmd.SetComputeBufferParam(
      37.                 m_CS,
      38.                 m_CSKernel_Prev.kernelIndex,
      39.                 "CBuffer_VNList",
      40.                 mesh.cbuffVNormal
      41.             );
      42.             m_cmd.SetComputeBufferParam(
      43.                 m_CS,
      44.                 m_CSKernel_Main.kernelIndex,
      45.                 "CBuffer_TriangleList",
      46.                 mesh.cbuffTris
      47.             );
      48.             m_cmd.SetComputeBufferParam(
      49.                 m_CS,
      50.                 m_CSKernel_Main.kernelIndex,
      51.                 "CBuffer_VPList",
      52.                 mesh.cbuffVPosition
      53.             );
      54.             m_cmd.SetComputeBufferParam(
      55.                 m_CS,
      56.                 m_CSKernel_Main.kernelIndex,
      57.                 "CBuffer_VNList",
      58.                 mesh.cbuffVNormal
      59.             );
      60.             //-/////////////////////////////////////////////////////////
      61.             /// Set Actual Data for Compute Buffers
      62.             // Custom global buffer data
      63.             int triBufferSize = mesh.meshData.triList.Count;
      64.             int triCount = triBufferSize / 3;
      65.             int vertCount = mesh.meshData.vertPositionList.Count;
      66.             if (m_CSData_TrisExtracted.mainBufferAllocated == false ||
      67.                 m_CSData_TrisExtracted.mainBufferCount < triBufferSize
      68.             ){
      69.                 m_CSData_TrisExtracted.AllocBuffers(
      70.                     triBufferSize,
      71.                     GeoContourSO.bytesPerElem.triList,
      72.                     "TriangleExtracted",
      73.                     !m_CSData_TrisExtracted.utilityBuffersInitialized,
      74.                     !m_CSData_TrisExtracted.utilityBuffersInitialized,
      75.                     ComputeBufferType.Structured
      76.                 );
      77.             }
      78.             // Counter & Arg Buffers data
      79.             m_CSData_TrisExtracted.resetCounter(0);
      80.             int[] args = new int[4]{
      81.                 3,   // Vertex per instance (Topology.TRIANGLE)
      82.                 triCount,  // Instance (Triangle) count
      83.                 0, 0,  // Vertex, Instance index offsets
      84.             };
      85.             m_CSData_TrisExtracted.setIndirectArgs(
      86.                 args
      87.             );
      88.             /// Bind Custom CBuffers (Instantiated Scriptable Objects)
      89.             m_CSKernel_Main.SetCBufferGlobal(m_cmd, m_CS, m_CSData_TrisExtracted);
      90.  
      91.             ///-/////////////////////////////////////////////////
      92.             // Setup Compute Kernel(s)
      93.             /// Kernel size
      94.             m_CSKernel_Prev.groupsPerDispatch.x =
      95.                 m_CSKernel_Prev.GetGroupNum(vertCount);
      96.             m_CSKernel_Prev.groupsPerDispatch.y = 1;
      97.             m_CSKernel_Prev.groupsPerDispatch.z = 1;
      98.  
      99.             m_CSKernel_Main.groupsPerDispatch.x =
      100.                 m_CSKernel_Main.GetGroupNum(triBufferSize);
      101.             m_CSKernel_Main.groupsPerDispatch.y = 1;
      102.             m_CSKernel_Main.groupsPerDispatch.z = 1;
      103.  
      104.             ///-//////////////////////////////////////-------------
      105.             // Dispatch Compute Kernel(s)
      106.             // m_CSKernel_Prev.Dispatch(ref cmd, ref m_CS);
      107.  
      108.  
      109.             ///-//////////////////////////////////////-------------
      110.             // Debugging
      111.             m_Mat_Contour.SetBuffer(
      112.                 Shader.PropertyToID("CBuffer_TriangleList"),    
      113.                 mesh.cbuffTris    
      114.             );
      115.             m_Mat_Contour.SetBuffer(
      116.                 Shader.PropertyToID("CBuffer_VPList"),          
      117.                 mesh.cbuffVPosition
      118.             );
      119.             m_Mat_Contour.SetBuffer(
      120.                 Shader.PropertyToID("CBuffer_VNList"),          
      121.                 mesh.cbuffVNormal  
      122.             );
      123.             Matrix4x4 trans = new Matrix4x4(
      124.                 new Vector4(1.0f, 0.0f, 0.0f, 0.0f),
      125.                 new Vector4(0.0f, 1.0f, 0.0f, 0.5f),
      126.                 new Vector4(0.0f, 0.0f, 1.0f, 0.5f),
      127.                 new Vector4(0.0f, 0.0f, 0.0f, 1.0f)
      128.             );
      129.            
      130.             trilist_cpucop = new int[triCount * 3];
      131.             mesh.cbuffTris.GetData(trilist_cpucop);
      132.  
      133.             m_cmd.DrawProcedural(
      134.                 trans, m_Mat_Contour, 0,
      135.                 MeshTopology.Triangles, triCount * 3
      136.             );
      137.             // m_cmd.DrawProceduralIndirect(
      138.             //     trans,
      139.             //     m_Mat_Contour,
      140.             //     0,
      141.             //     MeshTopology.Triangles,
      142.             //     m_CSData_TrisExtracted.argsBuffer
      143.             // );
      144.         }
    • In my shader, I just used 3 Structured Buffers, nothing complex nor fancy... I wonder if it's because #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" in line 15 messed everything up...
      Code (CSharp):
      1. Pass    // ----- Procedural Shader Test ----- //
      2.         {
      3.            HLSLPROGRAM
      4.             #pragma target 4.5
      5.            
      6.             #pragma vertex      ProceduralVertexShader
      7.             #pragma fragment    ProceduralFragmentShader
      8.            
      9.             //== Resources ================================================
      10.             StructuredBuffer<int>       CBuffer_TriangleList;
      11.             StructuredBuffer<float4>    CBuffer_VPList;
      12.             StructuredBuffer<float4>    CBuffer_VNList;
      13.            
      14.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
      15.  
      16.             ////////////////////////////////////////////////////////////////
      17.             /// Indirect Draw Shader
      18.  
      19.             //== Structures ===============================================
      20.             struct ProceduralVertexOutput{
      21.                 float4 posCS            : SV_POSITION;
      22.             };
      23.             struct Vertex{
      24.                 float3 pos;
      25.                 float3 normal;
      26.                 float NdotV;
      27.             };
      28.             Vertex newVertex(int vbo_Id){
      29.                 float4 data_VP = CBuffer_VPList[vbo_Id];
      30.                 float4 data_VN = CBuffer_VNList[vbo_Id];
      31.                
      32.                 Vertex vout;
      33.                 vout.pos    = data_VP.xyz;
      34.                 vout.NdotV  = data_VP.w;
      35.                 vout.normal = data_VN.xyz;
      36.                
      37.                 return vout;
      38.             }
      39.  
      40.             //== Shader Programs ==========================================
      41.             ProceduralVertexOutput ProceduralVertexShader(
      42.                 uint vert_Id : SV_VertexID
      43.             ){
      44.                 ProceduralVertexOutput output;
      45.                 Vertex v;
      46.                 uint inst_Id = vert_Id / 3;
      47.                 uint linear_Id = 3 * inst_Id + vert_Id % 3;
      48.                 int vbo_Id = CBuffer_TriangleList[linear_Id];
      49.                 v = newVertex(vbo_Id);
      50.  
      51.                 output.posCS = TransformObjectToHClip(v.pos);
      52.                
      53.                 return output;
      54.             }
      55.  
      56.             float4 ProceduralFragmentShader(
      57.                 ProceduralVertexOutput input
      58.             ) : SV_TARGET
      59.             {
      60.                 float4 col = float4(1.0, 0.5, .1, 1.0);
      61.                 return col;
      62.             }
      63.            
      64.            ENDHLSL
      65.         }
    • I tried to use Graphics Debugger in Visual Studio, and I can see corresponding Draw events, but can't find my structured buffers... Snipaste_2019-10-20_11-22-32.png
     
  2. deus0

    deus0

    Joined:
    May 12, 2015
    Posts:
    256
    I'm getting crashes too. It was working with 'DrawMeshInstancedProcedural'. I switched to indirect as i have unique meshes and it seems faster.
     
  3. thimler9

    thimler9

    Joined:
    Sep 25, 2019
    Posts:
    10
    I don't know if this related, but I'm also getting crashes using Graphics.DrawProceduralIndirect in URP. It seems to give me an "invalid buffer" error in builds.
     
    deus0 likes this.