我正在尝试编写我的第一个在 C++ 中使用 DirectX 的程序。我正在尝试使用它来运行计算以更新将绘制到屏幕上的缓冲区。这是我当前的代码:
// Create Direct3D 11 device and context
ID3D11Device* device = nullptr;
ID3D11DeviceContext* context = nullptr;
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &device, nullptr, &context);
// Define compute shader
const char cs_source[] =
"RWStructuredBuffer<Particle> particles : register(u0);\n"
"[numthreads(64,1,1)]\n"
"void main(uint3 dispatchThreadID : SV_DispatchThreadID) {\n"
" Particle p = particles[dispatchThreadID.x];\n"
" p.position.x += p.velocity.x;\n"
" p.position.y += p.velocity.y;\n"
" p.position.z += p.velocity.z;\n"
" particles[dispatchThreadID.x] = p;\n"
"}\0";
ID3DBlob* cs_blob = nullptr;
HRESULT hr = D3DCompile(cs_source, strlen(cs_source), nullptr, nullptr, nullptr, "main", "cs_5_0", 0, 0, &cs_blob, nullptr);
if (FAILED(hr)) {
// Handle the error here
std::cout << "Failed to compile shader: " << hr << "\n";
return;
}
ID3D11ComputeShader* cs = nullptr;
device->CreateComputeShader(cs_blob->GetBufferPointer(), cs_blob->GetBufferSize(), nullptr, &cs);
cs_blob->Release();
// Create input buffer
Particle particles[1024];
for (int i = 0; i < 1024; i++) {
particles[i].position = XMFLOAT3(0.0f, 0.0f, 0.0f);
particles[i].velocity = XMFLOAT3(0.1f, 0.1f, 0.1f);
}
D3D11_BUFFER_DESC input_desc = {};
input_desc.ByteWidth = sizeof(Particle) * 1024;
input_desc.Usage = D3D11_USAGE_DEFAULT;
input_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
input_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
input_desc.StructureByteStride = sizeof(Particle);
D3D11_SUBRESOURCE_DATA input_data = {};
input_data.pSysMem = particles;
ID3D11Buffer* input_buffer = nullptr;
device->CreateBuffer(&input_desc, &input_data, &input_buffer);
// Create output buffer
D3D11_BUFFER_DESC output_desc = {};
output_desc.ByteWidth = sizeof(Particle) * 1024;
output_desc.Usage = D3D11_USAGE_DEFAULT;
output_desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
output_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
output_desc.StructureByteStride = sizeof(Particle);
ID3D11Buffer* output_buffer = nullptr;
device->CreateBuffer(&output_desc, nullptr, &output_buffer);
// Set up shader inputs and outputs
ID3D11ShaderResourceView* input_srv = nullptr;
ID3D11UnorderedAccessView* output_uav = nullptr;
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = {};
srv_desc.Format = DXGI_FORMAT_UNKNOWN;
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srv_desc.Buffer.FirstElement = 0;
srv_desc.Buffer.NumElements = 1024;
device->CreateShaderResourceView(input_buffer, &srv_desc, &input_srv);
D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc = {};
uav_desc.Format = DXGI_FORMAT_UNKNOWN;
uav_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uav_desc.Buffer.FirstElement = 0;
uav_desc.Buffer.NumElements = 1024;
uav_desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_COUNTER;
device->CreateUnorderedAccessView(output_buffer, &uav_desc, &output_uav);
// Set shader inputs and outputs
context->CSSetShader(cs, nullptr, 0);
context->CSSetShaderResources(0, 1, &input_srv);
context->CSSetUnorderedAccessViews(0, 1, &output_uav, nullptr);
// Dispatch compute shader
context->Dispatch(1024 / 64, 1, 1);
// Read output buffer
Particle output_particles[1024];
D3D11_MAPPED_SUBRESOURCE mapped_resource = {};
context->Map(output_buffer, 0, D3D11_MAP_READ, 0, &mapped_resource);
memcpy(output_particles, mapped_resource.pData, sizeof(Particle) * 1024);
context->Unmap(output_buffer, 0);
// Cleanup
input_buffer->Release();
output_buffer->Release();
input_srv->Release();
output_uav->Release();
cs->Release();
context->Release();
device->Release();
我从调用
hr
返回的 D3DCompile
变量中得到错误代码 0x80070005。我也在 visual studio 2021 上运行它
我原来忘了在着色器代码(HLSL)中包含,所以我添加了它,但没有改变。我快速进行了谷歌搜索,发现错误代码的意思是“拒绝访问”。这是否意味着我必须更改计算机上的某些内容,或者是代码问题?如果有帮助,我在我的计算机(Windows 10)上拥有完全管理员访问权限。
您的着色器使用
Particle
,它既没有包含在 HLSL 代码中也没有定义。