============ РЕДАКТИРОВАНИЕ: решение =====================Pixel Shader может получить доступ к Structured Buffer, а Vertex Shader не может - это спецификация DirectX?
Я, наконец, нашел проблему, и поскольку ответ может быть важен для новичков, которые изучают DirectX, я размещаю его здесь. (Я использую F # и SharpDX в качестве оболочки .NET для DirectX)
В моей программе ресурсы (буферы, представления и т. Д.) Изменяются только тогда, когда изменяется цепочка подкачки. Поэтому я включил все распределения ресурсов (IA, OM, VS, PS) в функцию switchTo2DLayout
. switchTo2DLayout
немедленно возвращается (без каких-либо действий), если цепочка подкачки была не изменено. Это контролируется флагом.
Позже я обнаружил, что этот флаг не был сброшен, поэтому распределения ресурсов выполнялись перед каждым обратным вызовом. Я исправил эту ошибку, но теперь изображение было отображено только при первом вызове renderPixels
. Оказалось, что я должен установить 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, которые я использую, явным образом не указываю, какие ресурсы могут быть выделены один раз (до тех пор, пока настройка не будет изменена) и которые должны быть выделены на на каждый вызов ничьей.
Для рендеринга сетки я использую подобную установку (здесь без ошибки я уже упоминал), и снова эквивалентная линия отсутствует:
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:] How can I feed compute shader results into vertex shader w/o using a vertex buffer?, которая была, вероятно, слишком сложной для ответа. В то же время я урезанная установку в гораздо более простом случае:
struct PS_IN
{
float4 pos : SV_POSITION;
float4 col : COLOR;
};
RWStructuredBuffer<float4> colorOutputTable : register (u5);
StructuredBuffer<float4> output2 : register (t5);
Случай A: пиксельные шейдеры устанавливает цвет (работ)
// vertex shader A
PS_IN VS_A (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);
return output;
}
// pixel shader A
float4 PS_A (float4 input : SV_Position) : SV_Target
{
uint2 pixel = uint2(input.x, input.y);
return output2[ pixel.y * width + pixel.x]; // PS accesses buffer (works)
}
Случай B: вершинные шейдеры устанавливает цвет (не работает)
// 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;
}
Очевидно пиксельного шейдера может доступ к «output2» буфер, а вершинные шейдеры не может (чтение всегда нулей).
Поиск в Интернете Я не мог найти объяснения этого поведения. В моем «реальном» приложении вычислительный шейдер вычисляет список треугольников и сохраняет его в RWStructuredBuffer, поэтому мне нужен доступ к этой таблице из вершинного шейдера (через слот с отображением).
Я думаю, что многие люди, которые работают с вычислительными шейдерами, могут наткнуться на эту проблему. Любая идея, как это решить? (В настоящее время я не могу использовать Level 11.1 или 11.2, мне нужно найти решение на основе 11.0)
Можете ли вы объяснить, почему реверсирования обмотка делает разницу в этом случае? Мои исходные данные - это TriangleList, в то время как четыре верта здесь образуют TriangleStrip - нужно ли мне также менять треугольники? –
Поскольку мы не указываем состояние растеризатора, эквалайзер на лицевой панели включен по умолчанию (см. Http://msdn.microsoft.com/en-us/library/windows/desktop/ff476198(v=vs.85). aspx). Ваша обмотка будет отменена, так что ваши лица треугольника будут отбракованы и не попадут в пиксельный шейдер. – catflier
Моя обмотка DID показывает синий прямоугольник, когда он заменил 'output.col = output2 [vid];' с 'output.col = float4 (0.5, 0.6, 0.8, 1);' Рядом - я всегда использовал по часовой стрелке обмотку, и это работал с моим списком треугольников, пока я использовал Vertex Buffer (копирование с процессора на графический процессор) ... –