天天看點

Vulkan Specification(Vulkan規範):第十一章 11.6. 資源記憶體關聯

11.6. 資源記憶體關聯

資源初始都是以_虛拟配置設定_ 的方式建立的,并不占記憶體。 裝置記憶體被單獨配置設定(參看裝置記憶體),然後再和資源關聯上。 這個關聯操作對于稀疏、非稀疏資源來說是不同的。

任何以稀疏标志建立資源都被認為是稀疏資源。 以這些标志之外的标志建立的資源被認為是非稀疏資源。 關于稀疏資源的記憶體關聯在 稀疏資源中有描述。

在資源被當作參數傳遞到以下任何一個操作之前,非稀疏資源必須完全并連續的綁定到一個

VkDeviceMemory

 對象:

  • 建立圖像或者緩沖區視圖
  • 更新描述符集合
  • 在指令緩沖區中記錄指令

一旦綁定了,記憶體綁定在資源的生命周期内就是不變的。

想要知道一個緩沖區資源的記憶體限制條件,可調用:

void vkGetBufferMemoryRequirements(
    VkDevice                                    device,
    VkBuffer                                    buffer,
    VkMemoryRequirements*                       pMemoryRequirements);
           
  • device

     是持有緩沖區的邏輯裝置。
  • buffer

     被查詢的緩沖區。
  • pMemoryRequirements

     指向一個 

    VkMemoryRequirements

    執行個體,裝載了被傳回的記憶體限制條件資訊。

Valid Usage (Implicit)

  • device

     must be a valid 

    VkDevice

     handle
  • buffer

     must be a valid 

    VkBuffer

     handle
  • pMemoryRequirements

     must be a pointer to a 

    VkMemoryRequirements

     structure
  • buffer

     must have been created, allocated, or retrieved from 

    device

想要知道圖像資源記憶體限制條件,可調用:

void vkGetImageMemoryRequirements(
    VkDevice                                    device,
    VkImage                                     image,
    VkMemoryRequirements*                       pMemoryRequirements);
           
  • device

     是擁有該圖像的邏輯裝置。
  • image

     是被查詢的圖像。
  • pMemoryRequirements

     指向了一個

    VkMemoryRequirements

    是列,裝載了該圖像對象記憶體限制條件資訊。

Valid Usage (Implicit)

  • device

     must be a valid 

    VkDevice

     handle
  • image

     must be a valid 

    VkImage

     handle
  • pMemoryRequirements

     must be a pointer to a 

    VkMemoryRequirements

     structure
  • image

     must have been created, allocated, or retrieved from 

    device

VkMemoryRequirements

類型資料結構定義如下:

typedef struct VkMemoryRequirements {
    VkDeviceSize    size;
    VkDeviceSize    alignment;
    uint32_t        memoryTypeBits;
} VkMemoryRequirements;
           
  • size

     該資源所需的記憶體配置設定的大小,以位元組為機關。
  • alignment

     是資源所要求的記憶體配置設定的對齊大小,以位元組為機關。
  • memoryTypeBits

     是一個标志位,每一bit表示每一個受支援的記憶體類型。但是, 隻有當 

    i

     在實體裝置支援的記憶體類型 

    VkPhysicalDeviceMemoryProperties

    中的時候,

    i

     才會被設定。

Vulkan實作保證關于記憶體限制條件的某些屬性通過

vkGetBufferMemoryRequirements

 和

vkGetImageMemoryRequirements

傳回:

  • memoryTypeBits

     成員總是至少包含一個被設定的bit位。
  • buffer

     是一個在建立時沒有帶有 

    VK_BUFFER_CREATE_SPARSE_BINDING_BIT

     的

    VkBuffer

    ,或者若

    image

    是在建立時 

    VkImageCreateInfo

    tiling

     成員帶有 

    VK_IMAGE_TILING_LINEAR

     的

    VkImage

    ,那麼此

    memoryTypeBits

    成員總是至少包含一個被設定的bit位,對應一個帶有

    propertyFlags

    的 

    VkMemoryType

    ,該

    propertyFlags

    VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT

     bit 和 

    VK_MEMORY_PROPERTY_HOST_COHERENT_BIT

     bit 都被設定。 換言之,可映射的一緻性記憶體可以總是被附着到這些對象上。
  • memoryTypeBits

     成員總是至少包含一個被設定的bit位,對應着帶有一個

    propertyFlags

    VkMemoryType

     , 該

    propertyFlags

     的

    VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT

     bit 被設定。
  • memoryTypeBits

     成員和所有的 建立時傳遞給

    vkCreateBuffer

    的 

    VkBufferCreateInfo

    中 帶有相同 

    flags

     and 

    usage

    VkBuffer

     對象相同, Further, if 

    usage1

     and 

    usage2

     of type 

    VkBufferUsageFlags

     are such that the bits set in 

    usage2

     are a subset of the bits set in 

    usage1

    , and they have the same 

    flags

    , then the bits set in

    memoryTypeBits

     returned for 

    usage1

     必須 be a subset of the bits set in 

    memoryTypeBits

     returned for 

    usage2

    , for all values of 

    flags

    .
  • alignment

     成員值是2的幂。
  • alignment

     成員與 傳遞給name:vkCreateBuffer的

    VkBufferCreateInfo

    資料結構的成員

    usage

     和 

    flags

     的相同bit組合 而建立的所有 

    VkBuffer

     對象 相同。
  • 對于被建立時帶有一個顔色格式的圖像, 

    memoryTypeBits

     成員與 建立時傳遞給

    vkCreateImage

    VkImageCreateInfo

     資料結構中的

    tiling

    成員, 

    flags

    成員的

    VK_IMAGE_CREATE_SPARSE_BINDING_BIT

     bit和 name:usage成員的 

    VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT

     的組合相同 所有的

    VkImage

     對象完全一緻。
  • 對于被建立時帶有一個depth/stencil 格式的圖像, 

    memoryTypeBits

     成員與 建立時傳遞給 

    vkCreateImage

    函數的

    VkImageCreateInfo

    資料結構的 

    format

     成員、

    tiling

    成員,  

    flags

     成員的

    VK_IMAGE_CREATE_SPARSE_BINDING_BIT

     bit、

    usage

     成員的

    VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT

     的組合值相同的 所有 

    VkImage

     對象。
  • 若記憶體要求是為

    VkImage

    準備的,

    memoryTypeBits

     成員必須不能指代一個 

    propertyFlags

    VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT

     bit 被設定的

    VkMemoryType

    ,若傳遞給

    vkCreateImage

    的資料結構的 

    VkImageCreateInfo

    的 

    vkGetImageMemoryRequirements

    ::

    image

    的成員

    usage

    VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT

     bit 沒有被設定。
  • 若記憶體要求是為

    VkBuffer

    準備的, 

    memoryTypeBits

     成員必須不能指代一個

    propertyFlags

    VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT

     bit被設定的 

    VkMemoryType

    注意

    此要求的隐藏含義是 該惰性配置設定的記憶體不适用于所有情形的緩沖區。

把記憶體附着在一個緩沖區對象,可調用:

VkResult vkBindBufferMemory(
    VkDevice                                    device,
    VkBuffer                                    buffer,
    VkDeviceMemory                              memory,
    VkDeviceSize                                memoryOffset);
           
  • device

     是擁有該緩沖區和記憶體的邏輯裝置。
  • buffer

     是緩沖區。
  • memory

     是一個 

    VkDeviceMemory

     類型對象,描述了需附着的裝置記憶體。
  • memoryOffset

     是  

    memory

    區域的起始偏移,該記憶體被綁定到緩沖區上。 被傳回的

    memory

    的成員

    VkMemoryRequirements

    ::

    size

     帶有的位元組數,從

    memoryOffset

     開始的位元組數, 将被綁定到特定的緩沖區。

Valid Usage

  • buffer

     本身不能是記憶體對象。
  • buffer

     被建立時不能帶有稀疏記憶體綁定辨別位。
  • memoryOffset

     必須小于

    memory

    的大小。
  • 若建立

    buffer

     時帶有 

    VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT

    VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT

    memoryOffset

     必須是

    VkPhysicalDeviceLimits

    ::

    minTexelBufferOffsetAlignment

    的倍數。
  • 若建立

    buffer

     時帶有 

    VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT

    memoryOffset

     必須是

    VkPhysicalDeviceLimits

    ::

    minUniformBufferOffsetAlignment

    的倍數。
  • 若建立

    buffer

     時帶有 

    VK_BUFFER_USAGE_STORAGE_BUFFER_BIT

    memoryOffset

     必須是

    VkPhysicalDeviceLimits

    ::

    minStorageBufferOffsetAlignment

    的倍數。
  • memory

     被配置設定時必須使用 以

    buffer

    為參數調用

    vkGetBufferMemoryRequirements

    而傳回的 

    VkMemoryRequirements

     資料結構的

    memoryTypeBits

    成員中被允許的記憶體類型。
  • memoryOffset

     必須是一個 以 

    buffer

    為參數調用 

    vkGetBufferMemoryRequirements

     而傳回的 

    VkMemoryRequirements

     資料結構

    alignment

    成員 的倍數的正整數。
  • buffer

    為參數調用

    vkGetBufferMemoryRequirements

     而傳回的 

    VkMemoryRequirements

     資料結構的

    size

     成員 必須 小于或 等于 

    memory

    減去 

    memoryOffset

    之差。

Valid Usage (Implicit)

  • device

     must be a valid 

    VkDevice

     handle
  • buffer

     must be a valid 

    VkBuffer

     handle
  • memory

     must be a valid 

    VkDeviceMemory

     handle
  • buffer

     must have been created, allocated, or retrieved from 

    device

  • memory

     must have been created, allocated, or retrieved from 

    device

Host Synchronization

  • Host access to 

    buffer

     must be externally synchronized

Return Codes

Success

  • VK_SUCCESS

Failure

  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

把記憶體附着到一個圖像對象上,可調用:

VkResult vkBindImageMemory(
    VkDevice                                    device,
    VkImage                                     image,
    VkDeviceMemory                              memory,
    VkDeviceSize                                memoryOffset);
           
  • device

     是擁有該圖像和記憶體的邏輯裝置。
  • image

     是圖像。
  • memory

     是一個

    VkDeviceMemory

    對象,描述了需被附着的裝置記憶體。
  • memoryOffset

     綁定到該圖像的記憶體的區域的起始偏移。 

    memory

    VkMemoryRequirements

    ::

    size

     成員裡被傳回的位元組數量,從

    memoryOffset

     位元組開始, 将被綁定到特定的圖像。

Valid Usage

  • image

     實際記憶體不能是記憶體對象。
  • image

     被建立是不能帶有稀疏記憶體綁定flags。
  • memoryOffset

     必須小于 

    memory

    的大小。
  • memory

     必須在建立時使用 以 

    image

    為參數調用 

    vkGetImageMemoryRequirements

     而傳回的 

    VkMemoryRequirements

    資料結構的

    memoryTypeBits

    成員中被允許的記憶體類型之一。
  • memoryOffset

     必須是 以 

    image

    為參數調用 

    vkGetImageMemoryRequirements

     而傳回的 

    VkMemoryRequirements

    資料結構的 

    alignment

    成員的正整數倍。
  • image

    為參數調用

    vkGetImageMemoryRequirements

     而傳回的 

    VkMemoryRequirements

    資料結構的

    size

     成員 必須 小于或 等于  

    memory

     減去 

    memoryOffset

    之差。

Valid Usage (Implicit)

  • device

     must be a valid 

    VkDevice

     handle
  • image

     must be a valid 

    VkImage

     handle
  • memory

     must be a valid 

    VkDeviceMemory

     handle
  • image

     must have been created, allocated, or retrieved from 

    device

  • memory

     must have been created, allocated, or retrieved from 

    device

Host Synchronization

  • Host access to 

    image

     must be externally synchronized

Return Codes

Success

  • VK_SUCCESS

Failure

  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

Buffer-Image Granularity

There is an implementation-dependent limit, 

bufferImageGranularity

, which specifies a page-like granularity at which buffer, linear image and optimal image resources 必須 be placed in adjacent memory locations to avoid aliasing. Two resources which do not satisfy this granularity requirement are said to alias. Linear image resource are images created with 

VK_IMAGE_TILING_LINEAR

 and optimal image resources are those created with

VK_IMAGE_TILING_OPTIMAL

bufferImageGranularity

 is specified in bytes, and 必須 be a power of two. Implementations which do not require such an additional granularity may report a value of one.

注意

bufferImageGranularity

 is really a granularity between "linear" resources, including buffers and images with linear tiling, vs. "optimal" resources, i.e. images with optimal tiling. It would have been better named "linearOptimalGranularity".

Given resourceA at the lower memory offset and resourceB at the higher memory offset in the same 

VkDeviceMemory

 object, where one of the resources is a buffer或 a linear image and the other is an optimal image, and the following:

resourceA.end       = resourceA.memoryOffset + resourceA.size - 1
resourceA.endPage   = resourceA.end & ~(bufferImageGranularity-1)
resourceB.start     = resourceB.memoryOffset
resourceB.startPage = resourceB.start & ~(bufferImageGranularity-1)
           

The following property 必須 hold:

resourceA.endPage < resourceB.startPage
           

That is, the end of the first resource (A) and the beginning of the second resource (B) 必須 be on separate “pages” of size 

bufferImageGranularity

bufferImageGranularity

 may be different than the physical page size of the memory heap. This restriction is only needed when a buffer或 a linear image is at adjacent memory location with an optimal image and both will被用于 simultaneously. Adjacent buffers’或 adjacent images' memory ranges可以 be closer than 

bufferImageGranularity

, provided they meet the 

alignment

 requirement for the objects in question.

Sparse block size in bytes and sparse image and buffer memory alignments 必須 all be multiples of the 

bufferImageGranularity

. Therefore, memory bound to sparse resources naturally satisfies the

bufferImageGranularity

.