Wie kann ich feed compute shader Ergebnisse in vertex-shader-w/o mit einem vertex-buffer?

Bevor ich in die details gehen möchte ich umreißen das problem:

Benutze ich RWStructuredBuffers zu speichern, die Ausgabe von meinem compute Shader (CS). Da vertex-und pixel-Shader können nicht Lesen RWStructuredBuffers, ich Karte einer StructuredBuffer auf den gleichen Steckplatz (u0/t0) und (u4/t4):

cbuffer cbWorld : register (b1) 
{
    float4x4 worldViewProj;
    int dummy;
}   

struct VS_IN
{
    float4 pos : POSITION;
    float4 col : COLOR;
};

struct PS_IN
{

    float4 pos : SV_POSITION;
    float4 col : COLOR;
};

RWStructuredBuffer<float4> colorOutputTable : register (u0);    //2D color data
StructuredBuffer<float4> output2 :            register (t0);    //same as u0
RWStructuredBuffer<int> counterTable :        register (u1);    //depth data for z values
RWStructuredBuffer<VS_IN>vertexTable :        register (u4);    //triangle list
StructuredBuffer<VS_IN>vertexTable2 :         register (t4);    //same as u4

Verwende ich eine ShaderRecourceView zu gewähren, pixel-und/oder vertex-shader-Zugriff auf die Puffer. Dieses Konzept funktioniert gut für meine pixel-shader, vertex-shader hingegen scheint nur Lesen nur Lesen 0-Werte (ich benutze SV_VertexID als index für den Puffer):

PS_IN VS_3DA ( uint vid : SV_VertexID ) 
{           
    PS_IN output = (PS_IN)0; 
    PS_IN input = vertexTable2[vid];
    output.pos = mul(input.pos, worldViewProj); 
    output.col = input.col; 
    return output;
}

Keine Fehlermeldungen oder Warnungen aus der hlsl-compiler, der renderloop läuft mit 60 fps (mit vsync), aber der Bildschirm bleibt schwarz. Da ich einen leeren Bildschirm mit Farbe.Weiß vor dem Draw(..) aufgerufen wird, wird der render-pipeline scheint aktiv zu sein.

Wenn ich lese das Dreieck Daten Inhalt über eine UAView von der GPU in "vertArray" und führen es zurück in ein vertex-buffer, alles funktioniert aber:

Programm:

    let vertices = Buffer.Create(device, BindFlags.VertexBuffer, vertArray)
    context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Utilities.SizeOf<Vector4>() * 2, 0))

HLSL:

PS_IN VS_3D (VS_IN input )
{
    PS_IN output = (PS_IN)0;    
    output.pos = mul(input.pos, worldViewProj);
    output.col = input.col; 
    return output;
}

Hier die definition des 2D - Vertex /Pixelshaders. Bitte beachten Sie, dass PS_2D greift auf die Puffer "output2" in Schlitz t0 - und das ist genau der "trick" was ich will, zu replizieren, für die dann die 3D-vertex-shader "VS_3DA":

float4 PS_2D ( float4 input : SV_Position) : SV_Target
{        
    uint2 pixel =  uint2(input.x, input.y);         
    return output2[ pixel.y * width + pixel.x]; 
}

float4 VS_2D ( uint vid : SV_VertexID ) : SV_POSITION
{
if (vid == 0)
    return float4(-1, -1, 0, 1);
if (vid == 1)
    return float4( 1, -1, 0, 1);
if (vid == 2)
    return float4(-1,  1, 0, 1);    

return float4( 1,  1, 0, 1);    
}

Drei Tage lang habe ich danach gesucht und experimentiert, ohne Erfolg. Alle Informationen die ich gesammelt, scheinen zu bestätigen, dass mein Ansatz dann SV_VertexID funktionieren sollte.

Kann jemand Tipps geben? Vielen Dank für das Lesen meiner post!

=====================================================================

DETAILS:

Ich mag das Konzept der DirectX-11-compute-Shader sehr viel, und ich will Sie anwenden algebraischer computing. Als test-Fall, den ich render, Fraktale (apfelmännchen) in 3D. Alles funktioniert wie erwartet – außer einem letzten Stein in der Wand fehlt.

Die Berechnung die folgenden Schritte erfolgt:

  1. Verwendung eines CS zur Berechnung einer 2D-textur (Ausgang ist "counterTable" und "colorOutbutTable" (funktioniert)

  2. Optional machen diese textur zu Bildschirm (funktioniert)

  3. Mit einem anderen CS zu erzeugen, ein mesh (triangle list). Das CS nimmt die x -, y-und color-Werte aus Schritt 1 berechnet die z-Koordinate, und schafft endlich ein quad für jedes pixel. Das Ergebnis wird gespeichert in "vertexTable". (Werke)

  4. Fütterung der Dreiecke Liste der vertex-shader (problem!!!!!)

  5. Render to screen (Werke - mit einem vertex-buffer).

Zur Programmierung verwende ich F# 3.0 und SharpDX als .NET-wrapper.
Die ShaderRessourceView für beide Shader (pixel - & Eckpunkt) mit gleichen Parametern (außer der Größe-Parameter):

let mutable descr = new BufferDescription()     
descr.BindFlags <- BindFlags.UnorderedAccess ||| BindFlags.ShaderResource 
descr.Usage <- ResourceUsage.Default  
descr.CpuAccessFlags <- CpuAccessFlags.None
descr.StructureByteStride <- xxx    //depends on shader
descr.SizeInBytes <-  yyy       //depends on shader
descr.OptionFlags <- ResourceOptionFlags.BufferStructured

Hier nichts besonderes.
Erstellung von 2D-Puffer (bindet an Puffer "output2" in Schlitz t0):

outputBuffer2D <- new Buffer(device, descr) 
outputView2D <- new UnorderedAccessView (device, outputBuffer2D)  
shaderResourceView2D <- new ShaderResourceView (device, outputBuffer2D)

Erstellung von 3D-Puffer (bindet an "vertexTable2" in slot t4):

vertexBuffer3D <- new Buffer(device, descr) 
shaderResourceView3D <- new ShaderResourceView (device, vertexBuffer3D)
// UAView not required here

Festlegen von Ressourcen für 2D:

context.InputAssembler.PrimitiveTopology <- PrimitiveTopology.TriangleStrip
context.OutputMerger.SetRenderTargets(renderTargetView2D)
context.OutputMerger.SetDepthStencilState(depthStencilState2D)
context.VertexShader.Set (vertexShader2D)
context.PixelShader.Set (pixelShader2D) 

Rendern 2D:

context.PixelShader.SetShaderResource(COLOR_OUT_SLOT, shaderResourceView2D)
context.PixelShader.SetConstantBuffer(CONSTANT_SLOT_GLOBAL, constantBuffer2D )
context.ClearRenderTargetView (renderTargetView2D, Color.White.ToColor4())         
context.Draw(4,0)                                                
swapChain.Present(1, PresentFlags.None)            

Festlegen von Ressourcen für 3D:

context.InputAssembler.PrimitiveTopology <- PrimitiveTopology.TriangleList
context.OutputMerger.SetTargets(depthView3D, renderTargetView2D)
context.VertexShader.SetShaderResource(TRIANGLE_SLOT, shaderResourceView3D )
context.VertexShader.SetConstantBuffer(CONSTANT_SLOT_3D, constantBuffer3D)
context.VertexShader.Set(vertexShader3D)
context.PixelShader.Set(pixelShader3D)

Rendern 3D (funktioniert nicht – schwarzer Bildschirm als Ausgabe-Ergebnis)

context.ClearDepthStencilView(depthView3D, DepthStencilClearFlags.Depth, 1.0f, 0uy)
context.Draw(dataXsize * dataYsize * 6, 0)
swapChain.Present(1, PresentFlags.None)

Schließlich die slot-Nummern:

static let CONSTANT_SLOT_GLOBAL = 0
static let CONSTANT_SLOT_3D = 1
static let COLOR_OUT_SLOT = 0
static let COUNTER_SLOT = 1
static let COLOR_SLOT = 2    
static let TRIANGLE_SLOT = 4
Haben Sie jemals behoben? Ich bin auf der Suche zu tun, fast die gleiche Sache, aber es ist nicht für mich arbeiten. Wie hast du dieses Problem beheben?

InformationsquelleAutor Siegfried Stephan | 2013-11-11

Schreibe einen Kommentar