[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
public ComputeShaderWrapper ComputeShader { get; }SlimDX.Direct3D11.ComputeShaderWrapperクラスは
public void SetUnorderedAccessView(UnorderedAccessView unorderedAccessView, int slot);unorderedAccessViewは演算シェーダーにセットするUnorderedAccessViewです。
public class UnorderedAccessView : ResourceView
public UnorderedAccessView(Device device, Resource resource);deviceはこのViewを持つデバイスです。
~Viewクラス | 説明 |
DepthStencilView | 深度ステンシルテストでテクスチャリソースとして使います。 |
RenderTargetView | レンダーターゲットなテクスチャーリソースとして使います。画面に映る描画先のことですね。 |
ShaderResourceView | シェーダーリソースとして使います。たとえば定数バッファ、テクスチャバッファ、テクスチャ、サンプラーなどです。演算シェーダーでも計算に必要なデータを格納したバッファをこれに指定することがあります。 |
UnorderedAccessView | ピクセルシェーダーか演算シェーダーで、複数のスレッドからのランダムアクセスっぽい読み書きを受け付ける、ということを意味します。 |
BindFlags = BindFlags.UnorderedAccess
BindFlagsの値 | 数値 | 説明 |
None | 0 | 特に何も指定しません。 |
VertexBuffer | 1 | 生成されるリソースが、Input Assemblerステージで、頂点バッファとして使えることを意味します。 |
IndexBuffer | 2 | 生成されるリソースが、Input Assemblerステージで、インデックスバッファとして使えることを意味します。 |
ConstantBuffer | 4 | 生成されるリソースが、シェーダーステージで、定数バッファとして使えることを意味します。 |
ShaderResource | 8 | 生成されるリソースが、シェーダーステージで、バッファやテクスチャとして使えるとうことを意味します。 |
StreamOutput | 16 | 生成されるリソースが、Stream Outputステージで、出力バッファとして使用できるということを意味します。Stream Outputステージとは頂点シェーダーとピクセルシェーダーステージの間に位置するステージの一つです。どうやらジオメトリーシェーダーとセットになっているらしく、新たな頂点データをメモリに書き出すことができます。 |
RenderTarget | 32 | 生成されるリソースが、Output Mergerステージで、レンダーターゲットとして使えることを意味します。つまり普通のDirectXアプリケーションで画面に表示される画像のことですね。 |
DepthStencil | 64 | 生成されるリソースが、Output Mergerステージで、深度ステンシルとして使えることを意味します。 |
UnorderedAccess | 128 | 生成されるリソースが、ランダムアクセス風に、複数のスレッドから同時に読み書きできることを意味します。 |
public static ShaderBytecode CompileFromFile( string fileName, string entryPoint, string profile, ShaderFlags shaderFlags, EffectFlags effectFlags );これはDirectX SDK付属のHLSLコンパイルツール、fxc.exeに似ています。
public class ComputeShader : DeviceChild
public ComputeShader(Device device, ShaderBytecode shaderBytecode);
public void Set(ComputeShader shader);shaderはデバイスにセットする演算シェーダーです。
public void Dispatch( int threadGroupCountX, int threadGroupCountY, int threadGroupCountZ );
numthreads(X, Y, Z)
演算シェーダーバージョン | Zの最大値 | スレッドの最大個数(X * Y * Z) |
cs_4_x | 1 | 768 |
cs_5_0 | 64 | 1024 |
T Operator[]( in uint indexPosition );
using System.Collections.Generic; using System.Linq; using SlimDX; using SlimDX.Direct3D11; using SlimDX.D3DCompiler; class Program { static void Main(string[] args) { Device device = new Device(DriverType.Hardware); Buffer onlyGpuBuffer = createStructuredBuffer(device, Enumerable.Range(0, 10).ToArray()); initComputeShader(device, onlyGpuBuffer); device.ImmediateContext.Dispatch(10, 1, 1); writeBuffer(device, onlyGpuBuffer); } static void initComputeShader(Device device, Buffer onlyGpuBuffer) { device.ImmediateContext.ComputeShader.SetUnorderedAccessView(new UnorderedAccessView(device, onlyGpuBuffer), 0); ShaderBytecode shaderBytecode = ShaderBytecode.CompileFromFile( "MyShader.fx", "MyComputeShader", "cs_4_0", ShaderFlags.None, EffectFlags.None ); device.ImmediateContext.ComputeShader.Set( new ComputeShader(device, shaderBytecode) ); } static void writeBuffer(Device device, Buffer buffer) { Buffer cpuAccessibleBuffer = createCpuAccessibleBuffer(device, Enumerable.Range(0, 10).ToArray()); device.ImmediateContext.CopyResource(buffer, cpuAccessibleBuffer); int[] readBack = readBackFromGpu(cpuAccessibleBuffer); foreach (var number in readBack) { System.Console.WriteLine(number); } } static Buffer createStructuredBuffer(Device device, int[] initialData) { DataStream initialDataStream = new DataStream(initialData, true, true); return new Buffer( device, initialDataStream, new BufferDescription { SizeInBytes = (int)initialDataStream.Length, BindFlags = BindFlags.UnorderedAccess, OptionFlags = ResourceOptionFlags.StructuredBuffer, StructureByteStride = sizeof(int) } ); } static Buffer createCpuAccessibleBuffer(Device device, int[] initialData) { DataStream initialDataStream = new DataStream(initialData, true, true); return new Buffer( device, initialDataStream, new BufferDescription { SizeInBytes = (int)initialDataStream.Length, CpuAccessFlags = CpuAccessFlags.Read, Usage = ResourceUsage.Staging } ); } static int[] readBackFromGpu(Buffer from) { DataBox data = from.Device.ImmediateContext.MapSubresource( from, MapMode.Read, MapFlags.None ); return getArrayInt32(data.Data); } static int[] getArrayInt32(DataStream stream) { int[] buffer = new int[stream.Length / sizeof(int)]; stream.ReadRange(buffer, 0, buffer.Length); return buffer; } }
RWStructuredBuffer<int> MyBuffer;
[numthreads(1, 1, 1)]void MyComputeShader( uint3 threadID : SV_DispatchThreadID ){MyBuffer[threadID.x] *= 2;}
0 2 4 6 8 10 12 14 16 182倍になりました!