Can't bind a UAV texture and a UAV buffer at the same time in a compute shader

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


User avatar
TaaTT4
OGRE Contributor
OGRE Contributor
Posts: 267
Joined: Wed Apr 23, 2014 3:49 pm
Location: Bologna, Italy
x 75

Can't bind a UAV texture and a UAV buffer at the same time in a compute shader

Post by TaaTT4 »

As the title says, doing so raises the following error (which appears to be non-sense in this context):

Code: Select all

OGRE EXCEPTION(-2147467259:RenderingAPIException): Cannot compile D3D11 high-level shader 0ComputeTest Errors:
D:\Development\SDK\OGRE\OGRE\build\bin\Debug\0ComputeTest.hlsl(3,47-48): error X3530: buffer requires a 't' register
 in D3D11HLSLProgram::compileMicrocode at D:\Development\SDK\OGRE\OGRE\RenderSystems\Direct3D11\src\OgreD3D11HLSLProgram.cpp (line 549)
I'm not sure to have done things in a proper way (there's nothing in OGRE that shows how to do it). I made a bit of mix and match looking at Sample_TutorialCompute* samples. Here below you can find a patch that allows to easily reproduce the issue in Sample_TutorialCompute01_UavTexture:

Code: Select all

From c4051b7d2ffba6acdbd20925ca59f6be60f3cca7 Mon Sep 17 00:00:00 2001
From: TaaTT4 <raffaele.bratta@gmail.com>
Date: Mon, 6 Jul 2020 12:42:02 +0200
Subject: [PATCH] COMPUTE

---
 .../materials/TutorialCompute01_UavTexture/Compute.compositor  | 2 ++
 .../TutorialCompute01_UavTexture/ComputeJobs.material.json     | 2 +-
 .../TutorialCompute01_UavTexture/HLSL/ComputeTest.hlsl         | 3 ++-
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Samples/Media/2.0/scripts/materials/TutorialCompute01_UavTexture/Compute.compositor b/Samples/Media/2.0/scripts/materials/TutorialCompute01_UavTexture/Compute.compositor
index 47aa1977d..66f8f3d8d 100644
--- a/Samples/Media/2.0/scripts/materials/TutorialCompute01_UavTexture/Compute.compositor
+++ b/Samples/Media/2.0/scripts/materials/TutorialCompute01_UavTexture/Compute.compositor
@@ -3,6 +3,7 @@ compositor_node TutorialComputeTest01_UavTextureRenderingNode
 	in 0 rt_renderwindow
 
 	texture testTexture target_width target_height PFG_RGBA8_UNORM depth_pool 0 uav
+	buffer testBuffer 1 4 target_width target_height
 
 	target
 	{
@@ -12,6 +13,7 @@ compositor_node TutorialComputeTest01_UavTextureRenderingNode
 			
 			//uav # textureName read write allow_write_after_write
 			uav 0 testTexture	write
+			uav_buffer 1 testBuffer read
 			//input 0 mrtTexture 1
 		}
 	}
diff --git a/Samples/Media/2.0/scripts/materials/TutorialCompute01_UavTexture/ComputeJobs.material.json b/Samples/Media/2.0/scripts/materials/TutorialCompute01_UavTexture/ComputeJobs.material.json
index 01b94e9da..5d90a33e2 100644
--- a/Samples/Media/2.0/scripts/materials/TutorialCompute01_UavTexture/ComputeJobs.material.json
+++ b/Samples/Media/2.0/scripts/materials/TutorialCompute01_UavTexture/ComputeJobs.material.json
@@ -9,7 +9,7 @@
 
             "source" : "ComputeTest",
 
-            "uav_units" : 1,
+            "uav_units" : 2,
 
             "params" :
             [
diff --git a/Samples/Media/2.0/scripts/materials/TutorialCompute01_UavTexture/HLSL/ComputeTest.hlsl b/Samples/Media/2.0/scripts/materials/TutorialCompute01_UavTexture/HLSL/ComputeTest.hlsl
index af25e5ebf..630ad7aeb 100644
--- a/Samples/Media/2.0/scripts/materials/TutorialCompute01_UavTexture/HLSL/ComputeTest.hlsl
+++ b/Samples/Media/2.0/scripts/materials/TutorialCompute01_UavTexture/HLSL/ComputeTest.hlsl
@@ -1,5 +1,6 @@
 
 RWTexture2D<float4> testTexture			: register(u0);
+StructuredBuffer<uint> pixelBuffer : register(u1);
 
 [numthreads(@value( threads_per_group_x ), @value( threads_per_group_y ), @value( threads_per_group_z ))]
 void main
@@ -8,5 +9,5 @@ void main
     uint3 gl_GlobalInvocationID : SV_DispatchThreadId
 )
 {
-    testTexture[gl_GlobalInvocationID.xy].xyzw = float4( float2(gl_LocalInvocationID.xy) / 16.0f, 0.0f, 1.0f );
+    testTexture[gl_GlobalInvocationID.xy].xyzw = float4( float2(gl_LocalInvocationID.xy) / 16.0f, pixelBuffer[0], 1.0f );
 }
-- 
2.24.0.windows.2

Senior programmer at 505 Games; former senior engine programmer at Sandbox Games
Worked on: Racecraft EsportRacecraft Coin-Op, Victory: The Age of Racing

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5446
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1348

Re: Can't bind a UAV texture and a UAV buffer at the same time in a compute shader

Post by dark_sylinc »

You need to declare the hlsl as RWStructuredBuffer
User avatar
TaaTT4
OGRE Contributor
OGRE Contributor
Posts: 267
Joined: Wed Apr 23, 2014 3:49 pm
Location: Bologna, Italy
x 75

Re: Can't bind a UAV texture and a UAV buffer at the same time in a compute shader

Post by TaaTT4 »

dark_sylinc wrote: Mon Jul 06, 2020 3:59 pm You need to declare the hlsl as RWStructuredBuffer
It works doing so (I'm feeling so stupid...) :roll:
But isn't StructuredBuffer the read-only version of RWStructuredBuffer (or at least MSDN doc says so: https://docs.microsoft.com/en-us/window ... -resources? I thought that, since in material I binded the buffer as read, I had to use a StructuredBuffer.

Senior programmer at 505 Games; former senior engine programmer at Sandbox Games
Worked on: Racecraft EsportRacecraft Coin-Op, Victory: The Age of Racing

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5446
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1348

Re: Can't bind a UAV texture and a UAV buffer at the same time in a compute shader

Post by dark_sylinc »

Yeah I know, it's confusing as hell.

StructuredBuffer originally allowed to use u registers, but later MS decided that was a compiler bug (Str. Buffer = Texture buffer) so you have to use the RW version even if you plan to use it as read only.

OpenGL & Vulkan decided to use SSBOs (UAVs) as read only because it's faster to fetch (no need to do automatic format conversion), but MS decided to put that in both StructuredBuffer and RWStructuredBuffer. Thus it's a mess.