CUDA学习(二十三)

2023-11-16

Direct3D互操作性:
Direct3D 9Ex,Direct3D 10和Direct3D 11支持Direct3D互操作性。
CUDA上下文只能与满足以下条件的Direct3D设备互操作:必须使用设置为D3DDEVTYPE_HAL的DeviceType和具有D3DCREATE_HARDWARE_VERTEXPROCESSING标志的BehaviorFlags创建Direct3D 9Ex设备; 必须使用设置为D3D_DRIVER_TYPE_HARDWARE的DriverType创建Direct3D 10和Direct3D 11设备。
可以映射到CUDA地址空间的Direct3D资源是Direct3D缓冲区,纹理和曲面。 这些资源是使用cudaGraphicsD3D9RegisterResource(),cudaGraphicsD3D10RegisterResource()和cudaGraphicsD3D11RegisterResource()注册的。
以下代码示例使用内核动态修改存储在顶点缓冲区对象中的顶点的2D宽度x高度网格:
Direct3D 9 版本:

IDirect3D9* D3D;
IDirect3DDevice9* device;
struct CUSTOMVERTEX {
    FLOAT x, y, z;
    DWORD color;
};
IDirect3DVertexBuffer9* positionsVB;
struct cudaGraphicsResource* positionsVB_CUDA;
int main()
{
    int dev;
    // Initialize Direct3D
    D3D = Direct3DCreate9Ex(D3D_SDK_VERSION);
    // Get a CUDA-enabled adapter
    unsigned int adapter = 0;
    for (; adapter < g_pD3D->GetAdapterCount(); adapter++) {
        D3DADAPTER_IDENTIFIER9 adapterId;
        g_pD3D->GetAdapterIdentifier(adapter, 0, &adapterId);
        if (cudaD3D9GetDevice(&dev, adapterId.DeviceName)
            == cudaSuccess)
            break;
    }
    // Create device
    ...
        D3D->CreateDeviceEx(adapter, D3DDEVTYPE_HAL, hWnd,
            D3DCREATE_HARDWARE_VERTEXPROCESSING,
            &params, NULL, &device);
    // Use the same device
    cudaSetDevice(dev);
    // Create vertex buffer and register it with CUDA
    unsigned int size = width * height * sizeof(CUSTOMVERTEX);
    device->CreateVertexBuffer(size, 0, D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT, &positionsVB, 0);
    cudaGraphicsD3D9RegisterResource(&positionsVB_CUDA,
        positionsVB,
        cudaGraphicsRegisterFlagsNone);
    cudaGraphicsResourceSetMapFlags(positionsVB_CUDA,
        cudaGraphicsMapFlagsWriteDiscard);
    // Launch rendering loop
    while (...) {
        ...
            Render();
        ...
    }
    ...
}
void Render()
{
    // Map vertex buffer for writing from CUDA
    float4* positions;
    cudaGraphicsMapResources(1, &positionsVB_CUDA, 0);
    size_t num_bytes;
    cudaGraphicsResourceGetMappedPointer((void**)&positions,
        &num_bytes,
        positionsVB_CUDA));
        // Execute kernel
        dim3 dimBlock(16, 16, 1);
        dim3 dimGrid(width / dimBlock.x, height / dimBlock.y, 1);
        createVertices << <dimGrid, dimBlock >> >(positions, time,
            width, height);
        // Unmap vertex buffer
        cudaGraphicsUnmapResources(1, &positionsVB_CUDA, 0);
        // Draw and present
        ...
}
void releaseVB()
{
    cudaGraphicsUnregisterResource(positionsVB_CUDA);
    positionsVB->Release();
}
__global__ void createVertices(float4* positions, float time,
    unsigned int width, unsigned int height)
{
    unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
    unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
    // Calculate uv coordinates
    float u = x / (float)width;
    float v = y / (float)height;
    u = u * 2.0f - 1.0f;
    v = v * 2.0f - 1.0f;
    // Calculate simple sine wave pattern
    float freq = 4.0f;
    float w = sinf(u * freq + time)
        * cosf(v * freq + time) * 0.5f;
    // Write positions
    positions[y * width + x] =
        make_float4(u, w, v, __int_as_float(0xff00ff00));
}

Direct3D 10 版本:

ID3D10Device* device;
struct CUSTOMVERTEX {
    FLOAT x, y, z;
    DWORD color;
};
ID3D10Buffer* positionsVB;
struct cudaGraphicsResource* positionsVB_CUDA;
int main()
{
    int dev;
    // Get a CUDA-enabled adapter
    IDXGIFactory* factory;
    CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
    IDXGIAdapter* adapter = 0;
    for (unsigned int i = 0; !adapter; ++i) {
        if (FAILED(factory->EnumAdapters(i, &adapter))
            break;
        if (cudaD3D10GetDevice(&dev, adapter) == cudaSuccess)
            break;
        adapter->Release();
    }
    factory->Release();
    // Create swap chain and device
    ...
        D3D10CreateDeviceAndSwapChain(adapter,
            D3D10_DRIVER_TYPE_HARDWARE, 0,
            D3D10_CREATE_DEVICE_DEBUG,
            D3D10_SDK_VERSION,
            &swapChainDesc, &swapChain,
            &device);
    adapter->Release();
    // Use the same device
    cudaSetDevice(dev);
    // Create vertex buffer and register it with CUDA
    unsigned int size = width * height * sizeof(CUSTOMVERTEX);
    D3D10_BUFFER_DESC bufferDesc;
    bufferDesc.Usage = D3D10_USAGE_DEFAULT;
    bufferDesc.ByteWidth = size;
    bufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags = 0;
    bufferDesc.MiscFlags = 0;
    device->CreateBuffer(&bufferDesc, 0, &positionsVB);
    cudaGraphicsD3D10RegisterResource(&positionsVB_CUDA,
        positionsVB,
        cudaGraphicsRegisterFlagsNone);
    cudaGraphicsResourceSetMapFlags(positionsVB_CUDA,
        cudaGraphicsMapFlagsWriteDiscard);
    // Launch rendering loop
    while (...) {
        ...
            Render();
        ...
    }
    ...
}
void Render()
{
    // Map vertex buffer for writing from CUDA
    float4* positions;
    cudaGraphicsMapResources(1, &positionsVB_CUDA, 0);
    size_t num_bytes;
    cudaGraphicsResourceGetMappedPointer((void**)&positions,
        &num_bytes,
        positionsVB_CUDA));
        // Execute kernel
        dim3 dimBlock(16, 16, 1);
        dim3 dimGrid(width / dimBlock.x, height / dimBlock.y, 1);
        createVertices << <dimGrid, dimBlock >> >(positions, time,
            width, height);
        // Unmap vertex buffer
        cudaGraphicsUnmapResources(1, &positionsVB_CUDA, 0);
        // Draw and present
        ...
}
void releaseVB()
{
    cudaGraphicsUnregisterResource(positionsVB_CUDA);
    positionsVB->Release();
}
__global__ void createVertices(float4* positions, float time,
    unsigned int width, unsigned int height)
{
    unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
    unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
    // Calculate uv coordinates
    float u = x / (float)width;
    float v = y / (float)height;
    u = u * 2.0f - 1.0f;
    v = v * 2.0f - 1.0f;
    // Calculate simple sine wave pattern
    float freq = 4.0f;
    float w = sinf(u * freq + time)
        * cosf(v * freq + time) * 0.5f;
    // Write positions
    positions[y * width + x] =
        make_float4(u, w, v, __int_as_float(0xff00ff00));
}

Direct3D 11版本

ID3D11Device* device;
struct CUSTOMVERTEX {
    FLOAT x, y, z;
    DWORD color;
};
ID3D11Buffer* positionsVB;
struct cudaGraphicsResource* positionsVB_CUDA;
int main()
{
    int dev;
    // Get a CUDA-enabled adapter
    IDXGIFactory* factory;
    CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
    IDXGIAdapter* adapter = 0;
    for (unsigned int i = 0; !adapter; ++i) {
        if (FAILED(factory->EnumAdapters(i, &adapter))
            break;
        if (cudaD3D11GetDevice(&dev, adapter) == cudaSuccess)
            break;
        adapter->Release();
    }
    factory->Release();
    // Create swap chain and device
    ...
        sFnPtr_D3D11CreateDeviceAndSwapChain(adapter,
            D3D11_DRIVER_TYPE_HARDWARE,
            0,
            D3D11_CREATE_DEVICE_DEBUG,
            featureLevels, 3,
            D3D11_SDK_VERSION,
            &swapChainDesc, &swapChain,
            &device,
            &featureLevel,
            &deviceContext);
    adapter->Release();
    // Use the same device
    cudaSetDevice(dev);
    // Create vertex buffer and register it with CUDA
    unsigned int size = width * height * sizeof(CUSTOMVERTEX);
    D3D11_BUFFER_DESC bufferDesc;
    bufferDesc.Usage = D3D11_USAGE_DEFAULT;
    bufferDesc.ByteWidth = size;
    bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags = 0;
    bufferDesc.MiscFlags = 0;
    device->CreateBuffer(&bufferDesc, 0, &positionsVB);
    cudaGraphicsD3D11RegisterResource(&positionsVB_CUDA,
        positionsVB,
        cudaGraphicsRegisterFlagsNone);
    cudaGraphicsResourceSetMapFlags(positionsVB_CUDA,
        cudaGraphicsMapFlagsWriteDiscard);
    // Launch rendering loop
    while (...) {
        ...
            Render();
        ...
    }
    ...
}
void Render()
{
    // Map vertex buffer for writing from CUDA
    float4* positions;
    cudaGraphicsMapResources(1, &positionsVB_CUDA, 0);
    size_t num_bytes;
    cudaGraphicsResourceGetMappedPointer((void**)&positions,
        &num_bytes,
        positionsVB_CUDA));
        // Execute kernel
        dim3 dimBlock(16, 16, 1);
        dim3 dimGrid(width / dimBlock.x, height / dimBlock.y, 1);
        createVertices << <dimGrid, dimBlock >> >(positions, time,
            width, height);
        // Unmap vertex buffer
        cudaGraphicsUnmapResources(1, &positionsVB_CUDA, 0);
        // Draw and present
        ...
}
void releaseVB()
{
    cudaGraphicsUnregisterResource(positionsVB_CUDA);
    positionsVB->Release();
}
__global__ void createVertices(float4* positions, float time,
    unsigned int width, unsigned int height)
{
    unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
    unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
    // Calculate uv coordinates
    float u = x / (float)width;
    float v = y / (float)height;
    u = u * 2.0f - 1.0f;
    v = v * 2.0f - 1.0f;
    // Calculate simple sine wave pattern
    float freq = 4.0f;
    float w = sinf(u * freq + time)
        * cosf(v * freq + time) * 0.5f;
    // Write positions
    positions[y * width + x] =
        make_float4(u, w, v, __int_as_float(0xff00ff00));
}

SLI互操作性;
在具有多个GPU的系统中,所有支持CUDA的GPU都可以通过CUDA驱动程序和运行时作为单独的设备访问。 当系统处于SLI模式时,有以下特殊的考虑:
首先,在一个GPU上的一个CUDA设备中的分配会消耗作为Direct3D或OpenGL设备的SLI配置的一部分的其他GPU上的存储器。 因此,分配可能会比预期的更早失败;
其次,应用程序应该为SLI配置中的每个GPU创建多个CUDA上下文。 虽然这不是一个严格的要求,但它避免了设备之间不必要的数据传输。 应用程序可以使用Direct3D的cudaD3D [GetDevices()]和OpenGL的cudaGLGetDevices()函数来标识正在当前执行渲染的设备的CUDA设备句柄 和下一帧。 给定此信息,当deviceList参数设置为cudaD3D [9 | 10] GetDevices()或cudaGLGetDevices()时,应用程序通常会选择合适的设备并将Direct3D或OpenGL资源映射到cudaD3D [9 | 10] 11返回的CUDA设备 DeviceListCurrentFrame或cudaGLDeviceListCurrentFrame。
请注意,从cudaGraphicsD9D [9 | 10 | 11] RegisterResource和cudaGraphicsGLRegister [Buffer | Image]只能在设备上使用。 因此,在SLI配置中,在不同的CUDA设备上计算不同帧的数据时,需要分别注册资源.
有关CUDA运行时如何分别与Direct3D和OpenGL互操作的详细信息,请参见Direct3D互操作性和OpenGL互操作性。;
timg

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CUDA学习(二十三) 的相关文章

随机推荐

  • 再见!微软官宣放弃Mac 版 Visual Studio IDE

    程序员的成长之路 互联网 程序员 技术 资料共享 关注 阅读本文大概需要 5 分钟 来自 撰稿丨千山 对于Visual Studio 只要是开发者 或多或少都接触过 发布于1997年的Visual Studio标志着微软第一次将这么多开发工
  • 关系代数之专门的关系运算(选择、投影)

    选择 选择运算是从指定的关系中选出满足给定条件 用逻辑表达式表达 的元组而组成一个新的关系 进行选择运算的对象是 一个关系当中某一个属性的值 选择运算是将一张表当中的某一属性进行筛选 比如 将性别 sex 这列当中性别为女的元组筛选出来组成
  • constraint的一些用法总结

    主要就是增加约束的 以下几种约束 并 一一列举 1 主键约束 要对一个列加主键约束的话 这列就必须要满足的条件就是分空 因为主键约束 就是对一个列进行了约束 约束为 非空 不重复 以下是代码 要对一个列加主键 列名为id 表名为emp 格式
  • 刷脸支付:双12刷脸支付5折省翻天,政策持续补贴预热双十二

    刷脸支付成潮流 三家巨头争江山 刷脸支付的使用场景正在深入拓展 进入每一个与人民生活息息相关的行业 在政府综合政务 社会公交运输 商超营销运营 酒店景区服务等各方面都出现了刷脸支付的身影 我们能够看到 科技是在进步的 社会是在进步的 二维码
  • Caffe2——cifar10数据集创建lmdb或leveldb类型的数据

    cifar10数据集和mnist数据集存储方式不同 cifar10数据集把标签和图像数据以bin文件的方式存放在同一个文件内 这种存放方式使得每个子cifar数据bin文件的结构相同 所以cifar转换数据代码比mnist的代码更加的模块化
  • Vue项目提示 doesn‘t work properly without JavaScript enabled. Please enable it to continue

    由于本地是用docker部署了一套微服务 为了避免跨越问题 前端使用的nginx配置转发后端路径 访问返回状态时200 但是在response返回We re sorry but doesn t work properly without J
  • 「雕爷学编程」Arduino动手做(37)——MQ-3乙醇易燃气酒精传感器模块

    37款传感器与模块的提法 在网络上广泛流传 其实Arduino能够兼容的传感器模块肯定是不止37种的 鉴于本人手头积累了一些传感器和模块 依照实践出真知 一定要动手做 的理念 以学习和交流为目的 这里准备逐一动手试试做实验 不管成功与否 都
  • Android studio心得——fragment动态加载

    前言 在Android应用程序中 Fragment是一种可以嵌入Activity中的组件 通过 Fragment 我们可以将UI 目录 前言 一 什么是Android Studio 二 简介Fragment 三 学期知识汇总 四 什么是碎片
  • C++类与对象--static修饰符

    C 类与对象 static修饰符 1 类静态数据成员的定义及初始化 1 1 声明 1 2 初始化 1 3 调用 1 4 案例 1 5 小结 2 类静态成员函数的定义 2 1 声明 2 2 调用 2 3 案例 2 4 小结 3 static
  • 数据库字段类型

    太长时间没有操作数据库 收集了部分有用的资料 一 创建数据表 CREATE TABLE mytable id VARCHAR 4 NOT NULL name VARCHAR 10 sex CHAR 1 createtime DATE age
  • ROS系统

    参考 https blog csdn net qq 28087491 article details 119053810 https www bilibili com video BV1zt411G7Vn spm id from 333 3
  • 静态网页怎样实现动态交互?-JavaScript

    在Html基础上 javascript能够开发交互式web网页 javascript的出现使得网页和用户之间实现了一种实时性的 动态的 交互性的关系 javascript短小精悍 又是在客户机上执行的 大大提高了网页的浏览速度和交互能力 同
  • Python高级培训第三次作业

    任务 作业 import threading 导入threading库 import time 导入time库 class Get time object 创建类Get time 用于获取当前时间 def init self each ti
  • “msg“:“Request method ‘GET‘ not supported“,“code“:500原因及解决

    GetMapping add parentId 这里的路径纠错 漏 了 controller 缺少add的保存方法 GetMapping add parentId 及其以下 Html出现错误 如下图
  • B树及其基本操作、B+树的基本概念

    B树及其基本操作 B 树的基本概念 1 B树 B 树的基本概念 1 B树的基本概念及性质 2 B 树的基本概念及性质 2 B树与B 树的区别 3 B树的基本操作 1 B树的查找 2 B树的插入 3 B树的删除 1 B树 B 树的基本概念 1
  • SpringBoot集成海康设备网络SDK

    文章目录 SDK介绍 概述 功能 下载 对接指南 集成 初始化项目 初始化SDK 初始化SDK概述 新建AppRunner 新建SdkInitService 新建InitSdkTask 新建 HCNetSDK 调用业务接口 部署 拷贝so库
  • 解决鼠标右击菜单的新建中没有“文本文档”的问题

    解决鼠标右击菜单的新建中没有 文本文档 的问题 原创 丶无殇 2022 2 12 注意 博主测试平台为WIN10系统 其他系统不保证一定可以 一 问题现象 在桌面右击打开新建菜单时没有文本文档这个选项 二 问题原因 有以下可能 安装某个软件
  • 单链表的数据结构和基本操作

    单链表的基本操作 头结点单链表的基本操作 头结点单链表的数据结构 头结点的初始化 插入新结点 头插法插入新结点 尾插法插入新结点 按位置插入新结点 删除节点 头删 尾删 按位置删 头指针单链表的基本操作 实现代码 链表是一种线性结构 在存储
  • UE4 技能系统(GAS插件的使用) 01--Build Basic Classes 创建基础类

    翻译自Udemy的视频课程introduction to unreal engine 4 ability system Build Basic Classes 创建基础类 1 创建工程和人物设置 01 创建Git仓库 使用UE4 22 VS
  • CUDA学习(二十三)

    Direct3D互操作性 Direct3D 9Ex Direct3D 10和Direct3D 11支持Direct3D互操作性 CUDA上下文只能与满足以下条件的Direct3D设备互操作 必须使用设置为D3DDEVTYPE HAL的Dev