像素着色器可以访问结构化缓冲区,而顶点着色器可以';这是DirectX规范吗?

像素着色器可以访问结构化缓冲区,而顶点着色器可以';这是DirectX规范吗?,directx,hlsl,vertex-shader,compute-shader,Directx,Hlsl,Vertex Shader,Compute Shader,============================编辑:解决方案===================== 我终于发现了这个问题,因为答案对于学习DirectX的初学者来说可能很重要,所以我把它贴在这里。(我使用F#和SharpDX作为DirectX的.NET包装器) 在我的程序中,资源(缓冲区、视图等)只有在交换链调整大小时才会改变。因此,我将所有资源分配(IA、OM、VS、PS)放入一个函数switchTo2DLayoutswitchTo2DLayout立即返回(不做任何操作)。这是由

============================编辑:解决方案=====================

我终于发现了这个问题,因为答案对于学习DirectX的初学者来说可能很重要,所以我把它贴在这里。(我使用F#和SharpDX作为DirectX的.NET包装器)

在我的程序中,资源(缓冲区、视图等)只有在交换链调整大小时才会改变。因此,我将所有资源分配(IA、OM、VS、PS)放入一个函数
switchTo2DLayout
<如果交换链未调整大小,则code>switchTo2DLayout立即返回(不做任何操作)。这是由一个标志控制的

后来,我检测到这个标志从未重置,因此资源分配是在每次draw调用之前完成的。我纠正了这个错误,但现在仅在第一次调用
renderPixels
时才渲染图像。事实证明,每次在draw调用之前,我都必须设置
ShaderresourceView

let renderPixels () =
    switchTo2DLayout()

    // this line was missing:
    context.PixelShader.SetShaderResource(COUNT_COLOR_SLOT, countColorSRV_2D)

    context.ClearRenderTargetView (renderTargetView2D, Color.White.ToColor4())
    context.Draw(4,0)                                                
    swapChain.Present(1, PresentFlags.None)  
这对我来说完全出乎意料。我使用的有关DirectX的书籍从未明确说明哪些资源可以分配一次(只要设置没有更改),哪些资源必须在每次绘图调用时分配

对于网格渲染,我使用了类似的设置(这里没有我提到的bug),同样缺少了等效线:

let draw3D() = 
    switchTo3DLayout()

     // this line was missing:
     context.VertexShader.SetShaderResource(TRIANGLE_SLOT, triangleSRV  ) 

     context.ClearDepthStencilView(depthView3D, DepthStencilClearFlags.Depth, 1.0f, 0uy
     context.ClearRenderTargetView(renderTargetView2D, Color4.Black )                                                            
     context.Draw(triangleCount, 0)
     swapChain.Present(1, PresentFlags.None)    
这解释了为什么2D渲染工作是因为存在缺陷(像素着色器从缓冲区读取),而3D渲染工作不是因为缺陷(顶点着色器从缓冲区读取)

=================================我原来的帖子:=================

几天前,我发布了一个问题[link:],可能太复杂了,无法回答。同时,我将设置简化为更简单的情况:

struct PS_IN
{
float4 pos : SV_POSITION;
float4 col : COLOR;
};

RWStructuredBuffer<float4> colorOutputTable :  register (u5);
StructuredBuffer<float4> output2 :             register (t5);  
案例B:顶点着色器设置颜色(不工作)

显然,像素着色器可以访问“output2”缓冲区,而顶点着色器不能(读取始终为零)

在互联网上搜索,我找不到这种行为的任何解释。在我的“真实”应用程序中,计算着色器计算三角形列表并将其存储在RWStructuredBuffer中,因此我需要从顶点着色器(通过映射槽)访问此表


我猜许多使用计算着色器的人可能会在这个问题上遇到困难。你知道怎么解决这个问题吗?(我目前无法使用11.1级或11.2级,我必须找到一个基于11.0的解决方案)

刚刚在这里尝试过,您的着色器似乎工作正常(StructuredBuffer从未出现任何问题,在任何阶段都无法访问,功能级别11)

示例来自SharpDX minicube(刚刚替换了内部的着色器代码,并添加了一个缓冲区)

我要做的唯一一件事就是为你的三角网格反转缠绕(我可以修改光栅化器)

因为我知道您对调试管道有问题,所以另一种查看是否有问题的有用方法是使用查询(在您的例子中,主要是PipelineStatistics和Occlusion)

一些错误的状态可能很容易产生问题,所以您可以通过查看写入/渲染的基本体的像素数立即查看是否有问题

着色器代码如下:

struct PS_IN
{
    float4 pos : SV_POSITION;
    float4 col : COLOR;
};

RWStructuredBuffer<float4> colorOutputTable :  register (u5);
StructuredBuffer<float4> output2 :             register (t5);

PS_IN VS_B(uint vid : SV_VertexID)
{
    PS_IN output = (PS_IN)0;
    if (vid == 1) output.pos = float4(-1, -1, 0, 1);
    if (vid == 0) output.pos = float4(1, -1, 0, 1);
    if (vid == 3) output.pos = float4(-1, 1, 0, 1);
    if (vid == 2) output.pos = float4(1, 1, 0, 1);
    output.col = output2[vid];  // VS accesses buffer (does not work)
    return output;
}

// pixel shader B

float4 PS_B(PS_IN input) : SV_Target
{
    return input.col;
}
struct PS\u IN
{
浮动4位置:SV_位置;
第4列:颜色;
};
RWStructuredBuffer可输出颜色:寄存器(u5);
StructuredBuffer输出2:寄存器(t5);
PS_IN VS_B(单元视频:SV_VertexID)
{
输出中的PS_=(PS_IN)0;
如果(vid==1)output.pos=float4(-1,-1,0,1);
如果(vid==0)output.pos=float4(1,-1,0,1);
如果(vid==3)output.pos=float4(-1,1,0,1);
如果(vid==2)output.pos=float4(1,1,0,1);
output.col=output2[vid];//VS访问缓冲区(不工作)
返回输出;
}
//像素着色器B
浮动4 PS_B(PS_输入):SV_目标
{
返回input.col;
}

代码是(它非常笨重,所以我把它放在了pastebin上)

你能解释一下为什么在这种情况下反转绕组会产生不同吗?我的原始数据是一个三角形列表,而这里的四个顶点形成一个三角形网格-我也必须反转我的三角形吗?因为我们没有指定光栅化器状态,所以默认情况下启用背面消隐(请参见:)。你的卷绕是反向的,这样你的三角形面将被剔除,而不会出现在像素着色器中。我的卷绕在被替换为
output.col=output2[vid]时确实显示了一个蓝色矩形带有
output.col=float4(0.5,0.6,0.8,1)旁边-我总是使用顺时针缠绕,只要我使用顶点缓冲区(从CPU复制到GPU),它就可以处理我的三角形列表…这取决于你如何设置光栅化器,你是否尝试过从pastebin编写代码?我当然会,但在开始之前我有一个问题:你没有复制
rStructuredBuffer colorOutputTable:register(u5);StructuredBuffer输出2:寄存器(t5)同时,我尝试了你和我的缠绕,当我在VS中设置颜色常量时,两者都生成了蓝色矩形,当我尝试从缓冲区获取颜色时,两者都重新生成黑色。也许插槽5中两个缓冲区的“映射”都不起作用,但什么是有效的方法呢?计算着色器无法写入结构化缓冲区,VS无法从RW缓冲区读取数据(如果我尝试,我的HLSL编译器会哭泣)。
// vertex shader B

PS_IN VS_B ( uint vid : SV_VertexID )   
{
    PS_IN output = (PS_IN)0;   
    if (vid == 0) output.pos = float4(-1, -1, 0, 1);
    if (vid == 1) output.pos = float4( 1, -1, 0, 1);
    if (vid == 2) output.pos = float4(-1,  1, 0, 1);    
    if (vid == 3) output.pos = float4( 1,  1, 0, 1);    
    output.col = output2[vid];  // VS accesses buffer (does not work)
    return output;  
}

// pixel shader B

float4 PS_B  (PS_IN input ) : SV_Target
{
    return input.col;
}
struct PS_IN
{
    float4 pos : SV_POSITION;
    float4 col : COLOR;
};

RWStructuredBuffer<float4> colorOutputTable :  register (u5);
StructuredBuffer<float4> output2 :             register (t5);

PS_IN VS_B(uint vid : SV_VertexID)
{
    PS_IN output = (PS_IN)0;
    if (vid == 1) output.pos = float4(-1, -1, 0, 1);
    if (vid == 0) output.pos = float4(1, -1, 0, 1);
    if (vid == 3) output.pos = float4(-1, 1, 0, 1);
    if (vid == 2) output.pos = float4(1, 1, 0, 1);
    output.col = output2[vid];  // VS accesses buffer (does not work)
    return output;
}

// pixel shader B

float4 PS_B(PS_IN input) : SV_Target
{
    return input.col;
}