Jump to content
  • Advertisement
Sign in to follow this  
shinkamui

DX11 How to use a compute shader in sharpdx?

This topic is 2150 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hello, I'm new to directx11. I modified sharpdx official dx11 example MiniCubeTexture, added an RWByteAddressBuffer, and a compute shader to write data to the buffer via uav. The original pixel shader have also been modified in order to read this buffer as texture(via shader resource view) instead of the original texture2d. 
 
For debug purpose, I initialize the RWByteAddressBuffer with colorful content, and the compute shader should wrote uniform data to the buffer. At the beginning of the loop, I dispatched the compute shader, but the result I got shows that the buffer stay untounched. I must used the compute shader in wrong way. Please help. All codes are in attached file.
 
[source]// Copyright (c) 2010-2012 SharpDX - Alexandre Mutel
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Diagnostics;

using SharpDX;
using SharpDX.D3DCompiler;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Windows;
using Buffer = SharpDX.Direct3D11.Buffer;
using Device = SharpDX.Direct3D11.Device;
using MapFlags = SharpDX.Direct3D11.MapFlags;

namespace MiniCubeTexure
{
///
/// SharpDX MiniCubeTexture Direct3D 11 Sample
///
internal static class Program
{
[STAThread]
private static void Main()
{
var form = new RenderForm("SharpDX - MiniCubeTexture Direct3D11 Sample");

// SwapChain description
var desc = new SwapChainDescription()
{
BufferCount = 1,
ModeDescription =
new ModeDescription(form.ClientSize.Width, form.ClientSize.Height,
new Rational(60, 1), Format.R8G8B8A8_UNorm),
IsWindowed = true,
OutputHandle = form.Handle,
SampleDescription = new SampleDescription(1, 0),
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput
};

// Create Device and SwapChain
Device device;
SwapChain swapChain;
Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, new FeatureLevel[] { FeatureLevel.Level_11_0 }, desc, out device, out swapChain);
var context = device.ImmediateContext;

// Ignore all windows events
var factory = swapChain.GetParent();
factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll);

// New RenderTargetView from the backbuffer
var backBuffer = Texture2D.FromSwapChain(swapChain, 0);
var renderView = new RenderTargetView(device, backBuffer);

// Compile Vertex and Pixel shaders
var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniCubeTexture.fx", "VS", "vs_5_0");
var vertexShader = new VertexShader(device, vertexShaderByteCode);

var pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniCubeTexture.fx", "PS", "ps_5_0");
var pixelShader = new PixelShader(device, pixelShaderByteCode);

// add a new compute shader
var csByteCode = ShaderBytecode.CompileFromFile("MiniCubeTexture.fx", "CS", "cs_5_0");
var computeShader = new ComputeShader(device, csByteCode);

// Layout from VertexShader input signature
var layout = new InputLayout(device, ShaderSignature.GetInputSignature(vertexShaderByteCode), new[]
{
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0)
});

// Instantiate Vertex buiffer from vertex data
var vertices = Buffer.Create(device, BindFlags.VertexBuffer, new[]
{
// 3D coordinates UV Texture coordinates
-1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, // Front
-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f,
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,

-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, // BACK
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,

-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, // Top
-1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,

-1.0f,-1.0f, -1.0f, 1.0f, 1.0f, 0.0f, // Bottom
1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
-1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, -1.0f, 1.0f, 1.0f, 0.0f,
1.0f,-1.0f, -1.0f, 1.0f, 0.0f, 0.0f,
1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f,

-1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, // Left
-1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,

1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, // Right
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
});

// Create Constant Buffer
var contantBuffer = new Buffer(device, Utilities.SizeOf(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);


// Create Depth Buffer & View
var depthBuffer = new Texture2D(device, new Texture2DDescription()
{
Format = Format.D32_Float_S8X24_UInt,
ArraySize = 1,
MipLevels = 1,
Width = form.ClientSize.Width,
Height = form.ClientSize.Height,
SampleDescription = new SampleDescription(1, 0),
Usage = ResourceUsage.Default,
BindFlags = BindFlags.DepthStencil,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None
});

var depthView = new DepthStencilView(device, depthBuffer);

// Load texture and create sampler
var texture = Texture2D.FromFile(device, "GeneticaMortarlessBlocks.jpg");
var textureView = new ShaderResourceView(device, texture);

// initialize the buffer with colorful data
var db = new DataBuffer(256 * 256 * 4 * 3);
uint a, b, c = 255;
int index = 0;
for (uint j = 0; j < 256; j++)
{
b = j % 32 * 8;
for (uint i = 0; i < 256; i++)
{
a = i % 32 * 8;
db.Set(index, a);
index += 4;
db.Set(index, b);
index += 4;
db.Set(index, c);
index += 4;
}
}

// create uav and srv for this buffer
var rwrb_Texture = new Buffer(device,new DataStream(db.DataPointer,256*256*12,true,true) , 12 * 256 * 256, ResourceUsage.Default, BindFlags.UnorderedAccess | BindFlags.ShaderResource, CpuAccessFlags.None, ResourceOptionFlags.BufferAllowRawViews, 4);
var uavd = new UnorderedAccessViewDescription();
uavd.Dimension = UnorderedAccessViewDimension.Buffer;
uavd.Format = Format.R32_Typeless;
uavd.Buffer.ElementCount = 3 * 256 * 256;
uavd.Buffer.Flags = UnorderedAccessViewBufferFlags.Raw;
var uav_Texture = new UnorderedAccessView(device, rwrb_Texture, uavd);
var srvd = new ShaderResourceViewDescription();
srvd.Dimension = ShaderResourceViewDimension.Buffer;
srvd.Format = Format.R32_UInt;
srvd.Buffer.ElementCount = 3 * 256 * 256;
var srv_Texture = new ShaderResourceView(device, rwrb_Texture, srvd);


var sampler = new SamplerState(device, new SamplerStateDescription()
{
Filter = Filter.MinMagMipLinear,
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Never,
MaximumAnisotropy = 16,
MipLodBias = 0,
MinimumLod = 0,
MaximumLod = 16,
});


// Prepare All the stages
context.InputAssembler.InputLayout = layout;
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Utilities.SizeOf() + Utilities.SizeOf(), 0));
context.VertexShader.SetConstantBuffer(0, contantBuffer);
context.VertexShader.Set(vertexShader);
context.Rasterizer.SetViewports(new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height, 0.0f, 1.0f));
context.PixelShader.Set(pixelShader);
context.PixelShader.SetSampler(0, sampler);
context.PixelShader.SetShaderResource(0, textureView);
context.OutputMerger.SetTargets(depthView, renderView);
context.ComputeShader.Set(computeShader);

// Prepare matrices
var view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
var proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, form.ClientSize.Width / (float)form.ClientSize.Height, 0.1f, 100.0f);
var viewProj = Matrix.Multiply(view, proj);

// Use clock
var clock = new Stopwatch();
clock.Start();

// Main loop
RenderLoop.Run(form, () =>
{
var time = clock.ElapsedMilliseconds / 1000.0f;

// slow down the spin speed
time *= 0.1f;

// set compute shader and dispatch
context.ComputeShader.Set(computeShader);
context.OutputMerger.SetUnorderedAccessView(0, uav_Texture);
//context.ClearUnorderedAccessView(uav_Texture, Int4.One*128);
context.Dispatch(8, 8, 1);

// set original render target, use RWByteAddressBuffer as shader resource
context.OutputMerger.SetTargets(depthView, renderView);
context.PixelShader.SetShaderResource(0, textureView);
context.PixelShader.SetShaderResource(1, srv_Texture);


// Clear views
context.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
context.ClearRenderTargetView(renderView, Color.Black);

// Update WorldViewProj Matrix
var worldViewProj = Matrix.RotationX(time) * Matrix.RotationY(time * 2) * Matrix.RotationZ(time * .7f) * viewProj;
worldViewProj.Transpose();
context.UpdateSubresource(ref worldViewProj, contantBuffer);

// Draw the cube
context.Draw(36, 0);

// Present!
swapChain.Present(0, PresentFlags.None);
});

// Release all resources
vertexShaderByteCode.Dispose();
vertexShader.Dispose();
pixelShaderByteCode.Dispose();
pixelShader.Dispose();
vertices.Dispose();
layout.Dispose();
renderView.Dispose();
backBuffer.Dispose();
context.ClearState();
context.Flush();
device.Dispose();
context.Dispose();
swapChain.Dispose();
factory.Dispose();
}
}
}[/source]

Share this post


Link to post
Share on other sites
Advertisement
The debug layer of D3D (which you have enabled) reports some issues. Depending on what Visual Studio you're using you receive them directly in the debug output (see here). Alternatively use DebugView to grab them. Get familiar with it then report back wink.png

Share this post


Link to post
Share on other sites

er... Maybe I got your meanning wrong, did you say my code have errors when compile it? I got no error or warning message in vs2010. I don't clearly know how to make a compute shader working. There are few sharpdx example especially on compute/graphic domainhuh.png

 

(Sorry for my english, I'm not a native english userph34r.png )

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!