当前位置: 首页 > article >正文

理解WebGPU 中的 GPUDevice :与 GPU 交互的核心接口

        在 WebGPU 开发中,  GPUDevice   是一个至关重要的对象,它是与 GPU 进行交互的核心接口。通过   GPUDevice  ,开发者可以创建和管理 GPU 资源(如缓冲区、纹理、管线等),并提交命令缓冲区以执行渲染和计算任务。本文将详细介绍   GPUDevice   的核心属性和方法,并通过实际代码示例展示如何使用它来实现高性能的图形和计算任务。

什么是   GPUDevice  ?

        GPUDevice   是 WebGPU API 中的一个接口,表示逻辑 GPU 设备。它是从   GPUAdapter   请求而来的,用于创建和管理 GPU 资源,以及提交命令缓冲区以执行 GPU 操作。  GPUDevice   是开发者与 GPU 交互的主要接口,几乎所有与 GPU 相关的操作都需要通过它来完成。

GPUDevice   的核心属性

1.   features  

  • 类型:  GPUSupportedFeatures  
  • 描述:返回一个集合,表示该设备支持的特性(如纹理格式、管线特性等)。
  • 示例:
    const device = await adapter.requestDevice();
    console.log("Supported Features:", device.features);
    

2.   limits  

  • 类型:  GPUSupportedLimits  
  • 描述:返回一个对象,表示该设备支持的资源限制(如最大纹理大小、最大缓冲区大小等)。
  • 示例:
    const device = await adapter.requestDevice();
    console.log("Supported Limits:", device.limits);
    

3.   queue

  • 类型:  GPUQueue  
  • 描述:返回一个   GPUQueue   对象,用于提交命令缓冲区以执行 GPU 操作。
  • 示例:
    const device = await adapter.requestDevice();
    const queue = device.queue;
    

 GPUDevice   的核心方法

1.   createBuffer()

  • 返回值:  GPUBuffer  
  • 描述:创建一个 GPU 缓冲区,用于存储顶点数据、索引数据或通用计算数据。
  • 参数:descriptor  :一个对象,描述缓冲区的大小、用途等。
  • 示例:
    const buffer = device.createBuffer({
        size: 1024, // 缓冲区大小(字节)
        usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST, // 缓冲区用途
    });
    

2.   createTexture()  

  • 返回值:  GPUTexture  
  • 描述:创建一个 GPU 纹理,用于存储图像数据或作为渲染目标。
  • 参数:descriptor  :一个对象,描述纹理的格式、大小和用途。
  • 示例:
    const texture = device.createTexture({
        size: { width: 512, height: 512, depthOrArrayLayers: 1 },
        format: 'rgba8unorm',
        usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT,
    });
    

3.   createShaderModule()  

  • 返回值:  GPUShaderModule  
  • 描述:创建一个着色器模块,用于定义顶点着色器和片元着色器的代码。
  • 参数:descriptor  :一个对象,包含着色器代码(WGSL)。
  • 示例:
    const shaderModule = device.createShaderModule({
        code: `
            @vertex fn vs_main() -> @builtin(position) vec4<f32> {
                return vec4<f32>(0.0, 0.0, 0.0, 1.0);
            }
            @fragment fn fs_main() -> @location(0) vec4<f32> {
                return vec4<f32>(1.0, 0.0, 0.0, 1.0);
            }
        `
    });
    

4.   createCommandEncoder()  

  • 返回值:  GPUCommandEncoder  
  • 描述:创建一个命令编码器,用于记录 GPU 操作命令。
  • 示例:
    const commandEncoder = device.createCommandEncoder();
    

5.   createRenderPipeline()  

  • 返回值:  GPURenderPipeline  
  • 描述:创建一个渲染管线,用于定义渲染流程。
  • 参数:descriptor  :一个对象,描述管线的顶点着色器、片元着色器、目标格式等。
  • 示例:
    const pipeline = device.createRenderPipeline({
        vertex: {
            module: shaderModule,
            entryPoint: 'vs_main',
        },
        fragment: {
            module: shaderModule,
            entryPoint: 'fs_main',
            targets: [{ format: 'bgra8unorm' }],
        },
    });
    

6.   createComputePipeline()  

  • 返回值:  GPUComputePipeline
  • 描述:创建一个计算管线,用于定义通用计算任务。
  • 参数:descriptor  :一个对象,描述管线的计算着色器。
  • 示例:
    const computePipeline = device.createComputePipeline({
        compute: {
            module: shaderModule,
            entryPoint: 'cs_main',
        },
    });
    

示例代码:初始化 WebGPU 并创建资源

async function initWebGPU() {
    // 检查浏览器是否支持 WebGPU
    if (!navigator.gpu) {
        throw new Error("WebGPU is not supported on this browser.");
    }

    // 请求 GPU 适配器
    const adapter = await navigator.gpu.requestAdapter();
    if (!adapter) {
        throw new Error("Couldn't request WebGPU adapter.");
    }

    // 请求 GPU 设备
    const device = await adapter.requestDevice();

    // 获取画布上下文
    const canvas = document.querySelector("canvas");
    const context = canvas.getContext("webgpu");

    // 获取首选画布格式
    const format = navigator.gpu.getPreferredCanvasFormat();

    // 配置画布上下文
    context.configure({
        device,
        format,
    });

    // 创建着色器模块
    const shaderModule = device.createShaderModule({
        code: `
            @vertex fn vs_main() -> @builtin(position) vec4<f32> {
                return vec4<f32>(0.0, 0.0, 0.0, 1.0);
            }
            @fragment fn fs_main() -> @location(0) vec4<f32> {
                return vec4<f32>(1.0, 0.0, 0.0, 1.0);
            }
        `,
    });

    // 创建渲染管线
    const pipeline = device.createRenderPipeline({
        vertex: {
            module: shaderModule,
            entryPoint: 'vs_main',
        },
        fragment: {
            module: shaderModule,
            entryPoint: 'fs_main',
            targets: [{ format }],
        },
    });

    // 创建命令编码器
    const commandEncoder = device.createCommandEncoder();

    // 获取当前纹理视图
    const textureView = context.getCurrentTexture().createView();

    // 创建渲染通道描述符
    const renderPassDescriptor = {
        colorAttachments: [{
            view: textureView,
            loadOp: 'clear',
            clearValue: { r: 0, g: 0, b: 0, a: 1 },
            storeOp: 'store',
        }],
    };

    // 开始渲染通道
    const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
    passEncoder.setPipeline(pipeline);
    passEncoder.draw(3, 1, 0, 0);
    passEncoder.end();

    // 提交命令缓冲区
    device.queue.submit([commandEncoder.finish()]);
}

initWebGPU().catch((error) => {
    console.error("Failed to initialize WebGPU:", error);
});


http://www.kler.cn/a/545831.html

相关文章:

  • 图神经网络简介
  • 理解 WebGPU 中的 GPUQueue:GPU 的命令队列
  • 机器学习:朴素贝叶斯
  • 指标+大模型,构建更全、更准、更快的数据分析体验
  • Java中关于JSON的基本使用
  • Linux 系统中,进程间通信机制
  • DedeBIZ系统审计小结
  • 关于多语言商城系统的开发流程
  • 基于Flask的全国婚姻关系数据可视化分析系统的设计与实现
  • Linux CAN编程——SocketCAN读写CAN数据
  • 华为昇腾部署 DeepSeek-R1 (671B) 大模型实战指南
  • ES的典型架构图及其核心组件
  • 网络安全之攻防笔记--web安全攻防
  • 基于Python、使用`pandas`库和`Brightway2`库实现根据Excel表格某一列内容与数据库进行匹配
  • 【Uniapp】关于实现下拉刷新的三种方式
  • 中国通信企业协会 通信网络安全服务能力评定 证书使用说明
  • 从零开始学Python爬虫:(一)爬虫前言
  • 微信小程序请求大模型监听数据块onChunkReceived方法把数据解析成json
  • 网络安全架构师怎么考 网络安全 架构
  • 如何解决ChatGPT API响应慢的问题