以OpenGL/ES视角介绍gfx-hal(Vulkan) Texture接口使用

栏目: 后端 · 发布时间: 7年前

内容简介:文档列表见:就OpenGL、OpenGL ES、gfx-hal(1:1仿Vulkan接口定义)等KHR定义的图形库接口而言,Texture都有创建、上传数据、下载绘制结果数据、作为Framebuffer的挂载点等操作,下面分别介绍。OpenGL(ES)的Texture对应到Vulkan分别是Image、ImageView、Memory、Sampler,上传/下载Image的数据还需要配合Buffer,涉及到非常多细节。如果是刚开始学习图形开发,不建议使用Vulkan。

文档列表见: Rust 移动端跨平台复杂图形渲染项目开发系列总结(目录)

就OpenGL、OpenGL ES、gfx-hal(1:1仿Vulkan接口定义)等KHR定义的图形库接口而言,Texture都有创建、上传数据、下载绘制结果数据、作为Framebuffer的挂载点等操作,下面分别介绍。

OpenGL(ES)的Texture对应到Vulkan分别是Image、ImageView、Memory、Sampler,上传/下载Image的数据还需要配合Buffer,涉及到非常多细节。如果是刚开始学习图形开发,不建议使用Vulkan。

创建纹理的整体流程:

  1. 创建Image
  2. 创建Image关联的Memory
  3. 关联Image到Memory

上传数据到纹理的整体流程:

  1. 创建Staging Buffer
  2. 创建Fence
  3. 创建用于数据拷贝的Submmit
    • 创建Command Buffer
    • 创建Barrier
    • 向Command Buffer提交Barrier
    • 向Command Buffer提交Copy Buffer to Image命令
    • 结束Command Buffer编码
  4. 提交Submmit到GPU命令队列

在Shader使用纹理的整体流程:

  1. 创建ImageView
  2. 创建Sampler
  3. 创建、配置DescriptorSet、DescriptorSetLayout

下载绘制结果数据的整体流程:

待续

作为Framebuffer挂载点的整体流程:

待续

创建纹理的整体流程

创建Image

let kind = image::Kind::D2(dims.width as image::Size, dims.height as image::Size, 1 /* Layer */, 1 /* NumSamples */);
let unbound = device.create_image(
        kind,
        1 /* mip_levels */,
        ColorFormat::SELF,
        image::Tiling::Optimal,
        image::Usage::TRANSFER_DST | image::Usage::SAMPLED,
        image::StorageFlags::empty(),
    )
    .unwrap();
复制代码

创建Image关联的Memory

let req = device.get_image_requirements(&unbound);

let device_type = adapter
    .memory_types
    .iter()
    .enumerate()
    .position(|(id, memory_type)| {
        req.type_mask & (1 << id) != 0 && memory_type.properties.contains(memory::Properties::DEVICE_LOCAL)
    })
    .unwrap()
    .into();

let memory = device.allocate_memory(device_type, req.size).unwrap();
复制代码

关联Image到Memory

let image = device.bind_image_memory(&memory, 0, unbound).unwrap();
复制代码

上传数据到纹理的整体流程

创建传输Fence

let mut transfered_image_fence = device.create_fence(false);
复制代码

上传CPU数据到纹理

// copy buffer to texture
{
    let submit = {
        let mut cmd_buffer = staging_pool.acquire_command_buffer(false);

        let image_barrier = memory::Barrier::Image {
            states: (image::Access::empty(), image::Layout::Undefined)
                ..(image::Access::TRANSFER_WRITE, image::Layout::TransferDstOptimal),
            target: &image,
            range: COLOR_RANGE.clone(),
        };

        cmd_buffer.pipeline_barrier(
            PipelineStage::TOP_OF_PIPE..PipelineStage::TRANSFER,
            memory::Dependencies::empty(),
            &[image_barrier],
        );

        cmd_buffer.copy_buffer_to_image(
            buffer.as_ref().unwrap().get_buffer(),
            &image,
            image::Layout::TransferDstOptimal,
            &[command::BufferImageCopy {
                buffer_offset: 0,
                buffer_width: row_pitch / (stride as u32),
                buffer_height: dims.height as u32,
                image_layers: image::SubresourceLayers {
                    aspects: f::Aspects::COLOR,
                    level: 0,
                    layers: 0..1,
                },
                image_offset: image::Offset { x: 0, y: 0, z: 0 },
                image_extent: image::Extent {
                    width: dims.width,
                    height: dims.height,
                    depth: 1,
                },
            }],
        );

        let image_barrier = memory::Barrier::Image {
            states: (image::Access::TRANSFER_WRITE, image::Layout::TransferDstOptimal)
                ..(image::Access::SHADER_READ, image::Layout::ShaderReadOnlyOptimal),
            target: &image,
            range: COLOR_RANGE.clone(),
        };
        cmd_buffer.pipeline_barrier(
            PipelineStage::TRANSFER..PipelineStage::FRAGMENT_SHADER,
            memory::Dependencies::empty(),
            &[image_barrier],
        );

        cmd_buffer.finish()
    };

    let submission = Submission::new().submit(Some(submit));
    device_state.queues.queues[0].submit(submission, Some(&mut transfered_image_fence));
}
复制代码

在Shader使用纹理的整体流程

创建ImageView

let image_view = device.create_image_view(
        &image,
        image::ViewKind::D2,
        ColorFormat::SELF,
        Swizzle::NO,
        COLOR_RANGE.clone(),
    )
    .unwrap();
复制代码

创建Sampler

let sampler = device.create_sampler(image::SamplerInfo::new(image::Filter::Linear, image::WrapMode::Clamp));
复制代码

配置DescriptorSet

device.write_descriptor_sets(vec![
    pso::DescriptorSetWrite {
        set: &desc_set,
        binding: 0,
        array_offset: 0,
        descriptors: Some(pso::Descriptor::Image(&image_srv, image::Layout::Undefined)),
    },
    pso::DescriptorSetWrite {
        set: &desc_set,
        binding: 1,
        array_offset: 0,
        descriptors: Some(pso::Descriptor::Sampler(&sampler)),
    },
]);
复制代码

以上所述就是小编给大家介绍的《以OpenGL/ES视角介绍gfx-hal(Vulkan) Texture接口使用》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python Algorithms

Python Algorithms

Magnus Lie Hetland / Apress / 2010-11-24 / USD 49.99

Python Algorithms explains the Python approach to algorithm analysis and design. Written by Magnus Lie Hetland, author of Beginning Python, this book is sharply focused on classical algorithms, but it......一起来看看 《Python Algorithms》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具