HLSL буферный ход и многопоточность — что здесь происходит?

Я действительно новичок в технологиях DirectCompute и пытаюсь извлечь уроки из документации на веб-сайте msdn, которая … плотная, если не сказать больше.

Я хотел бы создать базовый файл hlsl, который принимает матрицу 4×4 и матрицу 4xN и возвращает умноженный результат. Но потратив некоторое время на игры с кодом, я обнаружил некоторые странные вещи, которые я не понимаю — в основном, то, как потоки, которые я передаю, обрабатывают буферы и выводят данные.

Во всех этих примерах я передаю два буфера по 16 поплавков, получаю буфер с 16 поплавками, а затем отправляю их с группировкой 4x1x1 — я могу показать вам код, но, честно говоря, пока не знаю, что поможет вам помочь мне. Дайте мне знать, если вы хотите увидеть раздел моего кода на C ++.

со следующим кодом:

StructuredBuffer<float4x4> base_matrix     : register(t0); // byteWidth = 64
StructuredBuffer<float4>   extended_matrix : register(t1); // byteWidth = 64
RWStructuredBuffer<float4> BufferOut       : register(u0); // byteWidth = 64, zeroed out before reading from the GPU

[numthreads(1, 1, 1)]
void CSMain( uint3 DTid : SV_DispatchThreadID )
{
BufferOut[DTid.x].x = 1;
}

Я получаю следующие значения:

1.000 0.000 0.000 0.000
1.000 0.000 0.000 0.000
1.000 0.000 0.000 0.000
1.000 0.000 0.000 0.000

Это имеет смысл для меня — буфер анализируется как 4 потока, каждый из которых выполняет 1 группировку float4.

со следующим кодом:

StructuredBuffer<float4x4> base_matrix     : register(t0); // byteWidth = 64
StructuredBuffer<float4>   extended_matrix : register(t1); // byteWidth = 64
RWStructuredBuffer<float4> BufferOut       : register(u0); // byteWidth = 64, zeroed out before reading from the GPU

[numthreads(1, 1, 1)]
void CSMain( uint3 DTid : SV_DispatchThreadID )
{
BufferOut[DTid.x].x = 1;
BufferOut[DTid.x].y = 2;
BufferOut[DTid.x].z = 3;
BufferOut[DTid.x].w = 4;
}

Я получаю следующие значения:

1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000

и с реальным кодом, который я хочу запустить:

StructuredBuffer<float4x4> base_matrix     : register(t0);
StructuredBuffer<float4>   extended_matrix : register(t1);
RWStructuredBuffer<float4> BufferOut       : register(u0);

[numthreads(1, 1, 1)]
void CSMain( uint3 DTid : SV_DispatchThreadID )
{
BufferOut[DTid.x] = mul(base_matrix[0],extended_matrix[DTid.x])
}

Я получаю следующие значения:

0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000

Я могу сказать, что мне здесь не хватает критически важной вещи, но на всю жизнь я не могу найти соответствующую документацию, рассказывающую мне, как это работает. Может ли кто-нибудь помочь мне понять, что происходит в этом коде?

Спасибо за ваше время,

Zach

Как еще одно примечание, этот код был скомпонован с использованием Microsoft DirectX SDK (июнь 2010 г.) \ Samples \ C ++ \ Direct3D11 \ BasicCompute11 Sample. Если я делаю что-то ужасно неправильно, дайте мне знать. Я действительно новый в HLSL.

Изменить: мой код создания буфера.

CreateStructuredBuffer( g_pDevice, sizeof(float)*16,     1,            g_matrix,          &g_pBuf0 );
CreateStructuredBuffer( g_pDevice, sizeof(float)*4,      NUM_ELEMENTS, g_extended_matrix, &g_pBuf1 );
CreateStructuredBuffer( g_pDevice, sizeof(float)*4,      NUM_ELEMENTS, NULL,              &g_pBufResult );

//--------------------------------------------------------------------------------------
// Create Structured Buffer
//--------------------------------------------------------------------------------------
HRESULT CreateStructuredBuffer( ID3D11Device* pDevice, UINT uElementSize, UINT uCount, VOID* pInitData, ID3D11Buffer** ppBufOut )
{
*ppBufOut = NULL;

D3D11_BUFFER_DESC desc;
ZeroMemory( &desc, sizeof(desc) );
desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
desc.ByteWidth = uElementSize * uCount;
desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
desc.StructureByteStride = uElementSize;

if ( pInitData )
{
D3D11_SUBRESOURCE_DATA InitData;
InitData.pSysMem = pInitData;
return pDevice->CreateBuffer( &desc, &InitData, ppBufOut );
} else
return pDevice->CreateBuffer( &desc, NULL, ppBufOut );
}

Попытка .1, .2, .3, .4 …

StructuredBuffer<float4x4> base_matrix     : register(t0);
StructuredBuffer<float4>   extended_matrix : register(t1);
StructuredBuffer<uint>     loop_multiplier : register(t2);
RWStructuredBuffer<float4> BufferOut       : register(u0);

[numthreads(1, 1, 1)]
void CSMain( uint3 DTid : SV_DispatchThreadID )
{
BufferOut[DTid.x].x = .1;
BufferOut[DTid.x].y = .2;
BufferOut[DTid.x].z = .3;
BufferOut[DTid.x].w = .4;
}

получил это:

0.100 0.100 0.100 0.100
0.100 0.100 0.100 0.100
0.100 0.100 0.100 0.100
0.100 0.100 0.100 0.100

7

Решение

Я попробовал ваш путь, но получил правильный результат.
Я не могу добавить комментарий из-за моей маленькой репутации.
Вот мой код

HLSL:

RWStructuredBuffer Output: регистр (u0);

[numthreads (1, 1, 1)]

void main (uint3 DTid: SV_DispatchThreadID)

{
если (DTid.x> 4)

    return;

Output[DTid.x].x= 1.f;

Output[DTid.x].y = 2.f;

Output[DTid.x].z = 3.f;

Output[DTid.x].w = 4.f;

}

C ++:

определить PathName

L «C: \ Users \ е \ Desktop \ D3D_Reseach \ RenderPro \ x64 \ Debug \ ComputeShader.cso»

структура буфера

{

XMFLOAT4 Test;

};

int APIENTRY wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR

lpCmdLine, int nCmdShow)

{

Hardware HardWare;

WinSystem Win;

Win.CreateWindows(HardWare, 400, 300);

ShowWindow(Win.hwnd, SW_HIDE);

//UAV

SharedComPtr<ID3D11UnorderedAccessView> Resource;

SharedComPtr<ID3D11Buffer>                           _Buffer;

ShaderResourceView::STRUCT_BUUFER_DESC Desc;

Desc.ACCESS = 0;

Desc.BIND = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;

Desc.FORMAT = DXGI_FORMAT_UNKNOWN;

Desc.HasScr = false;

Desc.MISC = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;

Desc.USAGE = D3D11_USAGE_DEFAULT;

Desc.ByteWidth= 4 * sizeof(Buffer);

Desc.StructureByteStride= sizeof(Buffer);

Desc.UAV_OR_SRV = ShaderResourceView::UAV;

ShaderResourceView :: CreateStructBuffer (HardWare.GetD3DDevice (), Описание изделия,
nullptr, Resource.GetTwoLevel (), _Buffer.GetTwoLevel (), true);

//CompilerShader

SharedComPtr<ID3D11ComputeShader>        ComputerSahder;

SharedComPtr<ID3DBlob>                               Blob;

WCHAR *Name = PathName;

CompilerShader::CompileShaderFromBinary(ComputerSahder.GetTwoLevel(), Name, HardWare.GetD3DDevice(),
Blob.GetTwoLevel(), CompilerShader::ShaderFlag::ComputeShader);

//Set ComputerHlsl

HardWare.GetDeviceContext()->CSSetUnorderedAccessViews(0, 1,

Resource.GetTwoLevel (), 0);

HardWare.GetDeviceContext()->CSSetShader(ComputerSahder.Get(), 0, 0);

HardWare.GetDeviceContext()->Dispatch(4, 1, 1);

//SRV

Buffer Hy[4];

VOID *P = Hy;

ID3D11Buffer* pBuffer;

BufferSystem::CreateConstanceBuffer(HardWare.GetD3DDevice(), P, pBuffer,

Desc.ByteWidth, D3D11_USAGE_STAGING);

HardWare.GetDeviceContext()->CopyResource(pBuffer, _Buffer.Get());

D3D11_MAPPED_SUBRESOURCE Data;

HardWare.GetDeviceContext()->Map(pBuffer, 0, D3D11_MAP_READ, 0, &Data);

Buffer *PP = reinterpret_cast<Buffer*>(Data.pData);

for (UINT i = 0; i < 4; ++i) {

float a = PP[i].Test.x;

a = PP[i].Test.y;

a = PP[i].Test.z;

a = PP[i].Test.w;

a = PP[i].Test.w;

}

}

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]