Chapter 11. Drawing Textures

In the previous chapter, we learned how to update the resource contents and read them at the shader stage using descriptors. We also covered push constant, which is an optimized way of updating the constant data at the shader stage using command buffers. In addition, by making use of descriptors, we added 3D transformations to our rendering primitives and also demonstrated an example to learn push constants.

In this chapter, we will learn and implement textures; we will wrap them around the geometry surfaces to bring realism to the scene. Textures are created using the Vulkan image resource; its data can be stored in either a linear or optimal layout. We will implement these two layouts—the latter layout uses staging. In staging, two different memory regions are used for the physical allocation process. The ideal memory placement for a resource may not be visible to the host. In this case, the application must first populate the resource in a host-visible staging buffer and then transfer it to the ideal location.

In this chapter, we will cover the following topics:

  • Image resource - a quick recap
  • Prerequisites for texture drawing
  • Implementing the image resource with linear tiling
  • Implementing the image resource with optimal tiling
  • Copying data content between images and buffers
  • Updating the descriptor set

Image resource - a quick recap

Images are continuous array of bytes stored in 1D, 2D, or 3D form. Unlike the buffer resource, an image is a formatted piece of information stored in the memory.

The image resource in Vulkan is represented by the VkImage object and created using the vkCreateImage API. The creation of this object does not back with the actual image contents, yet. This has to be done separately, where device memory is allocated and the image contents are stored into it. This memory is then bound to the created object.

In order to utilize the created images' objects at the shader stage, they must be converted into the image view—VkImageView. Before you convert an image into an image view, it has to be made compatible with the underlying implementation using image layouts.

The image is converted into the implementation-dependent layouts using VkImageLayout. For a given image resource, multiple image layouts can be created and used across. Different layouts might expose different performance characteristics, as they are very dedicated to the usage type. Indicating a correct usage lets the driver choose a specific memory location or portion suitable to offer optimal performance.

If you like to get a detailed introduction of image resources, refer to the very first section, namely Getting started with image resources in Chapter 6, Allocating Image Resources and Building a Swapchain with WSI. In the same chapter, you can refer to the Understanding image resource section for detailed information on images, image views, and image layouts.

Creating an image resource is simple. It consists of the following steps:

  1. Image object creation: First, the VkImage object is created. This object does not contain the image data, but it holds various important object states of the image resource, such as the format, dimension, image type, image's usage type, tiling fashion, and more. A given image can have multiple sub image resources, such as mipmaps. Following are the steps to create an image object:
    1. Tiling: There are two ways in which image tiling can be specified: linear and optimal. In the linear layout, the image data is mapped to contiguous memory on the device, arranged in a linear fashion. However, in an optimal layout, the image is stored in the form of tiles, and the texels inside each tile may be arranged in either a linear or some proprietary format to offer optimal performance. For a detailed view of linear and optimal layouts, refer to the Introduction to tiling section in Chapter 6, Allocating Image Resources and Building a Swapchain with WSI.
    2. Allocating and assigning image data: Read the image contents and allocate the required memory to the image resource. Fill the allocated device memory with the image channel contents.
    3. Setting the correct layout: Create an implementation-compatible image layout. A single image and its sub resource can be specified with multiple layouts.

  2. Image sampler: Create samplers (VkSampler) to control texture filtering.
  3. Image view creation: An image resource can only be accessed in the shader in the form of an image view (VkImageView).
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.136.17.12