天天看點

Vulkan程式設計指南翻譯 第四章 隊列和指令 第3節 清空和填充圖像

4.3 清空和填充圖像

和緩沖區一樣,也可以把資料直接複制到圖像,或使用一個值填充。圖像是更大、複雜、不透明的資料結構,是以原生的偏移量和資料通常對應用程式來說是不可見的。[2]

2. Of course, it’s possible to map the memory that is used for backing an image. In particular, when linear tiling is used for an image, this is standard practice. However, in general, this is not recommended.

通過vkCmdClearColorImage()函數調用,可清楚圖像資料并填充,原型如下:

void vkCmdClearColorImage (

VkCommandBuffer commandBuffer,

VkImage image,

VkImageLayout imageLayout,

const VkClearColorValue* pColor,

uint32_t rangeCount,

const VkImageSubresourceRange* pRanges);

清除指令被送出到的指令緩沖區通過commandBuffer參數指定。需要被清除資料的圖像通過image參數指定,執行清除操作時圖像可選的布局通過imageLayout參數指定。

imageLayout可接受的布局為e VK_IMAGE_LAYOUT_GENERAL 和VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL。清除不同布局的圖像,在執行清除指令之前,有必要使用管線屏障把它們轉移到這兩個布局中某一個。

清除圖像資料并填充的資料是VkClearColorValue類型的執行個體,定義如下:

typedef union VkClearColorValue {

float float32[4];

int32_t int32[4];

uint32_t uint32[4];

} VkClearColorValue;VkClearColorValue是一個簡單的union類型,有三個可選值,每個都是含有四個元素的數組。一個是浮點類型,一個是帶符号整型,一個是無符号。Vulkan将會按照圖像格式所明确的類型去讀資料。應用程式可以可以按照既定資料類型寫入資料。vkCmdClearColorImage()不會執行任何的資料轉換,需要應用程式負責正确的填充VkClearColorValue類型的資料。

單次調用vkCmdClearColorImage()可以清除目标圖像的任意大小的區域,雖然所有被清除的記憶體都會被填充相同的内容。如果你需要清除多個區域并填充不同的顔色值,你需要多次調用該函數。然而,如果你想要清除所有區域并填充同樣顔色,通過rangeCount指定區域的數量,傳入一個指針pRanges,指向大小為rangeCount、類型為VkImageSubresourceRange的數組。VkImageSubresourceRange定義如下:

typedef struct VkImageSubresourceRange {

VkImageAspectFlags aspectMask;

uint32_t baseMipLevel;

uint32_t levelCount;

uint32_t baseArrayLayer;

uint32_t layerCount;

} VkImageSubresourceRange;這個資料結構在第二章“記憶體和資源”有所介紹,讨論圖像視圖的建立的小節。這裡,它被用來定義圖像裡你想清空并填充資料的區域。因為我們正在清空顔色圖像,aspectMask須置為VK_IMAGE_ASPECT_COLOR_BIT。baseMipLevel 和 levelCount域用來指定mipmap起始層和需要被清空資料的層數,如果圖像是array image,baseArrayLayer 和 layerCount域用來指定起始層和需要被清空的層數。如果圖像不是array image,這些域應各置為0和1。

清空depth-stencil圖像與清空顔色圖像相似,除了一個VkClearDepthStencilValue類型的資料用來指定填充的資料。vkCmdClearDepthStencilImage()的原型和vkCmdClearColorImage()原型類似,其原型如下:

void vkCmdClearDepthStencilImage (

VkCommandBuffer commandBuffer,

VkImage image,

VkImageLayout imageLayout,

const VkClearDepthStencilValue* pDepthStencil,

uint32_t rangeCount,

const VkImageSubresourceRange * pRanges);

同樣,将執行清除操作的指令緩沖區通過commandBuffer參數指定,需要被清空的圖像由image參數指定,清空操作執行時期待的圖像布局通過imageLayout參數指定。和vkCmdClearColorImage()一樣,imageLayout值為VK_IMAGE_LAYOUT_GENERAL 或

VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL二者其一。對于清空操作沒有其他的有效可選。

清空後填充的資料通過一個VkClearDepthStencilValue類型的資料傳遞,它包含深度和stencil數值。它的定義如下:

typedef struct VkClearDepthStencilValue {

float depth;

uint32_t stencil;

} VkClearDepthStencilValue;

和vkCmdClearColorImage()一樣,一次vkCmdClearDepthStencilImage()調用可以清空多個圖像。可以清空的數量通過rangeCount指定,pRanges參數指向了一個大小為rangeCount、類型為VkImageSubresourceRange的數組,數組定義可以清空的範圍。

因為depth-stencil圖像包含深度和stencil aspect,pRanges的每一個成員的aspectMask都可包含VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_ASPECT_STENCIL_BIT中一個或者兩個。如果aspectMask包含VK_IMAGE_ASPECT_DEPTH_BIT,那麼存儲在VkClearDepthStencilValue結構的深度域将會被用來填充深度aspect的那塊區域。同樣,如果aspectMask包含VK_IMAGE_ASPECT_STENCIL_BIT,那麼深度aspect的那塊區域将會被清空并填充VkClearDepthStencilValue類型資料stencil域的資料。

注意,通常給單個區域指定VK_IMAGE_ASPECT_DEPTH_BIT 和 VK_IMAGE_ASPECT_STENCIL_BIT屬性,回避單獨指定一個屬性要高效率的多。