Directx11 HelloWorld之DirectCompute

本文提供了一篇关于DirectX11的Direct Compute实践教程,旨在简化理解,介绍了如何创建并运行一个简单的计算着色器。通过GPU进行数据计算,包括创建缓冲区、Shader Resource View和Unordered Access View,实现CPU到GPU的数据交换,并验证计算结果。代码中包含了关键步骤的详细解释,如设备和上下文的创建、Shader的编译、结构化缓冲区的创建等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  前些天想根据DX11的SDk自己写一个最简单的Direct Compute,中间又病倒了,耽搁了这些天昨晚才调好,鉴于网上太少dx11的学习资料了,总结下。

  首先要说的是我的改写版本主要是为了代码上的简明,去掉了很多硬件检测,以便迅速明白dx11的Direct Compute的架构,所以在很多人的机器上怕一时还运行不了,这个可以先明白基本架构后再进行向下兼容。

  首先说下Directx11的存储读写模型。在Dx11的硬件中主要用buffer存储数据,device来进行计算,shader resource view和unordered access view来作为前两者沟通的桥梁 也就是device通过shader resource view来读buffer通过unordereed access view来读写buffer

  我们要实现的功能是将CPU中的数据读写入GPU,然后在GPU中执行简单的计算:将两个buffer的数据相加到另一个buffer,再读回到CPU中以验证。在GPU中主要执行的计算是

struct BufType
{
    int i;
    float f;
};

BufferOut[DTid.x].i = Buffer0[DTid.x].i+Buffer1[DTid.x].i;

BufferOut[DTid.x].f = Buffer0[DTid.x].f+Buffer1[DTid.x].f;

 

  下面集中讲解下DX11的代码,虽然有点繁琐,但是记住我们的工作关键点大部分是一一依次初始化上面说的三个存储模型ID3D11Device,ID3D11Buffer,ID3D11ShaderResourceView,ID3D11UnorderedAccessView就可以抓住关键不会乱了。

 

#include<stdio.h>
#include<crtdbg.h>
#include <d3dcommon.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <d3dx11.h>
#include<iostream>
#include <algorithm>
using namespace std;

 

#define SAFE_RELEASE(p) {if(p){(p)->Release();(p)=NULL;}}

const UINT NUM_ELEMENTS=512;

 

//为了程序易读性,全局声明所有的函数
//1-创建D3d11的设备
HRESULT CreateComputeDevice(ID3D11Device** ppDeviceOut,ID3D11DeviceContext** ppContextDeviceOut);

 

//2-编译HLSL程序以生成computeShader接口:主要调用D3DX11CompileFromFile(),ID3D11Device::CreateComputeShader()
HRESULT CreateComputeShader(LPCWSTR pSrcFile,LPCSTR pFunctionName,ID3D11Device* pDevice,ID3D11ComputeShader** ppShaderOut);

 

//3-根据CPU中的数据void* pInitData创建GPU中的structure buffer:主要调用ID3D11Device::CreateBuffer()
HRESULT CreateStructureBuffer(ID3D11Device* gDevice,UINT elementSize,UINT uCount,void* gInitData,ID3D11Buffer** ppBufferOut);

 

//4-创建ShaderResourceView,让GPU能够读取相应的buffer:主要调用ID3D11Device::CreateShaderResourceView()
HRESULT CreateBufferSRV(ID3D11Device* pDevice,ID3D11Buffer* pBuffer,ID3D11ShaderResourceView** ppSRVOut);

 

//5-创建UnorderAccessView,让GPU能够读取和写入相应的buffer:主要调用ID3D11Device::CreateUnorderedAccessView()
HRESULT CreateBufferUAV(ID3D11Device* pDevice,ID3D11Buffer* pBuffer,ID3D11UnorderedAccessView** ppUAVOut);

 

//6-运行Compute Shader的程序
void RunComputeShader(ID3D11DeviceContext* pImmediateContext,ID3D11ComputeShader* pComputeShader,UINT nNumViews,ID3D11ShaderResourceView** pShaderResourceViews,ID3D11UnorderedAccessView* pUnorderedView,
UINT X,UINT Y,UINT Z);

 

//7-将GPU输出的Buffer拷贝回CPU中,以检验运算结果:主要调用ID3D11DeviceContext::CopyResource();
ID3D11Buffer* CreateAndCopyToDebugBuf(ID3D11Device* pDevice,ID3D11DeviceContext* pd3dImmediateContext,ID3D11Buffer* pBuffer);

 

//声明和定义全局变量

//与设备相关的指针借口
ID3D11Device* g_pDevice=NULL;
ID3D11DeviceContext* g_pContext=NULL;
ID3D11ComputeShader* g_pCS=NULL;

 

//各个Buffer指针变量

ID3D11Buffer* g_pBuffer0=NULL;
ID3D11Buffer* g_pBuffer1=NULL;
ID3D11Buffer* g_pBufferResult=NULL;

 

//读写上面buffer的ID3D11ShaderResourceView和UnorderedAccessView接口

ID3D11ShaderResourceView* g_pBuf0SRV=NULL;
ID3D11ShaderResourceView* g_pBuf1SRV=NULL;
ID3D11UnorderedAccessView* g_pBufResultUAV=NULL;

 

struct BufType
{
 int i;
 float f;
};

 

BufType g_vBuf0[NUM_ELEMENTS];
BufType g_vBuf1[NUM_ELEMENTS];

int  main()
{
 //在debug模式下,开启run-time时的内存检查
#if defined(DEBUG)||defined(_DEBUG)
 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
#endif

 

 cout<<"创建设备"<<endl;
 if(FAILED(CreateCompute

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值