¿Cómo puedo incluir los resultados de compute shader en vértice sin utilizar un búfer de vértice?

Antes de entrar en detalles, quiero delinear el problema:

Utilizo RWStructuredBuffers para almacenar la salida de mis sombreadores de cálculo (CS). Como los sombreadores de vértices y píxeles no pueden leer de RWStructuredBuffers, asigno un StructuredBuffer en la misma ranura (u0 / t0) y (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

Uso un ShaderRecourceView para otorgar acceso de sombreado de píxeles y / o vértices a los buffers. Este concepto funciona bien para mi píxel sombreado, sin embargo, el vértice sombreador parece leer solo 0 valores (yo uso SV_VertexID como índice para los búferes):

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;
}

Sin mensajes de error ni advertencias del compilador hlsl, el renderloop se ejecuta con 60 fps (usando vsync), pero la pantalla permanece en negro. Como en blanco la pantalla está con Color.White antes de llamar a Draw (..), el canal de renderizado parece estar activo.

Cuando leo el contenido de los datos del triángulo a través de un UAView de la GPU en "vertArray" y lo devuelvo a un búfer de vértice, todo funciona sin embargo:

Programa:

    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;
}

Aquí la definición de los 2D - Vertex / Pixelshaders. Tenga en cuenta que PS_2D accede al búfer "output2" en la ranura t0, y ese es exactamente el "truco" para el que quiero replicar el sombreador de vértices en 3D "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);    
}

Durante tres días he buscado y experimentado en vano. Todas las informaciones que reuní parecen confirmar que mi enfoque con SV_VertexID debería funcionar.

¿Alguien puede dar consejos? ¡Gracias por leer mi publicación!

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

DETALLES:

Me gusta mucho el concepto de los sombreadores de cálculo de DirectX 11 y quiero emplearlo para la computación algebraica. Como caso de prueba, renderizo fractales (conjuntos de Mandelbrot) en 3D. Todo funciona como se esperaba, excepto que falta un último ladrillo en la pared.

El cálculo toma los siguientes pasos:

Uso de una CS para calcular una textura 2D (la salida es “counterTable” y “colorOutbutTable” (funciona)

Opcionalmente renderizar esta textura a la pantalla (funciona).

Usando otro CS para generar una malla (lista de triángulos). Este CS toma los valores de x, y y color del paso 1, calcula la coordenada z y finalmente crea un cuadrante para cada píxel. El resultado se almacena en "tabla de vertex". (trabajos)

Alimentando la lista de triángulos al sombreador de vértice (problema !!!)

Renderizar a pantalla (funciona - usando un buffer de vértice).

Para la programación, uso F # 3.0 y SharpDX como envoltorio .NET. El ShaderRessourceView para ambos sombreadores (píxel y vértice) se configura con los mismos parámetros (excepto los parámetros de tamaño):

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

Nada especial aquí. Creación de búfer 2D (se une al búfer "output2" en la ranura t0):

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

Creación de búfer 3D (se une a "vertexTable2" en la ranura t4):

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

Configuración de recursos para 2D:

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

render 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)            

Configuración de recursos para 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)

render 3D (no funciona - pantalla negra como resultado de salida)

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

Finalmente los números de la ranura:

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

Respuestas a la pregunta(2)

Su respuesta a la pregunta