Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7a69723

Browse files
author
Alexis Ronez
committed
Rephrased Vertex buffer -> Staging buffer
1 parent 366c6fe commit 7a69723

1 file changed

Lines changed: 21 additions & 17 deletions

File tree

fr/04_Vertex_buffers/02_Buffer_intermédiaire.md

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
Nous avons maintenant un vertex buffer fonctionnel. Par contre il n'est pas dans la mémoire la plus optimale posible
44
pour la carte graphique. Il serait préférable d'utiliser une mémoire `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`,
55
mais de telles mémoires ne sont pas accessibles depuis le CPU. Dans ce chapitre nous allons créer deux vertex buffers.
6-
Le premier, un *buffer intermédiaire*, sera stocké dans de la mémoire accessible depuis le CPU, et nous y mettrons nos
7-
données. Le second sera directement dans la carte graphique, et nous y copierons les données des vertices depuis le
8-
buffer intermédiaire.
6+
Le premier, un buffer intermédiaire (*staging buffer*), sera stocké dans de la mémoire accessible depuis le CPU, et
7+
nous y mettrons nos données. Le second sera directement dans la carte graphique, et nous y copierons les données des
8+
vertices depuis le buffer intermédiaire.
99

1010
## Queue de transfert
1111

@@ -43,7 +43,7 @@ void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyF
4343
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
4444

4545
if (vkCreateBuffer(device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) {
46-
throw std::runtime_error("echec lors de la creation d'un buffer!");
46+
throw std::runtime_error("echec de la creation d'un buffer!");
4747
}
4848

4949
VkMemoryRequirements memRequirements;
@@ -55,7 +55,7 @@ void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyF
5555
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
5656

5757
if (vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) {
58-
throw std::runtime_error("echec lors de l'allocation de memoire!");
58+
throw std::runtime_error("echec de l'allocation de memoire!");
5959
}
6060

6161
vkBindBufferMemory(device, buffer, bufferMemory, 0);
@@ -112,9 +112,10 @@ graphique. Dans ce chapitre nous allons utiliser deux nouvelles valeurs pour les
112112
* `VK_BUFFER_USAGE_TRANSFER_DST_BIT` : le buffer peut être utilisé comme destination pour un transfert de mémoire
113113

114114
Le `vertexBuffer` est maintenant alloué à partir d'un type de mémoire local au device, ce qui implique en général que
115-
nous ne pouvons pas utiliser `vkMapMemory`. Nous pouvons cependant bien sûr copier les données depuis le buffer
116-
intermédiaire. Nous indiquons que nous voulons transmettre des données entre des buffers à l'aide des valeurs que nous
117-
avons vues juste au-dessus. Nous pouvons combiner ces informations avec par exemple `VK_BUFFER_USAGE_VERTEX_BUFFER_BIT`.
115+
nous ne pouvons pas utiliser `vkMapMemory`. Nous pouvons cependant bien sûr y copier les données depuis le buffer
116+
intermédiaire. Nous pouvons indiquer que nous voulons transmettre des données entre ces buffers à l'aide des valeurs
117+
que nous avons vues juste au-dessus. Nous pouvons combiner ces informations avec par exemple
118+
`VK_BUFFER_USAGE_VERTEX_BUFFER_BIT`.
118119

119120
Nous allons maintenant écrire la fonction `copyBuffer`, qui servira à recopier le contenu du buffer intermédiaire dans
120121
le véritable buffer.
@@ -125,10 +126,11 @@ void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) {
125126
}
126127
```
127128
128-
Les opérations de transfert de mémoire sont réalisée à travers un command buffer, comme pour l'affichage. Nous devons
129+
Les opérations de transfert de mémoire sont réalisées à travers un command buffer, comme pour l'affichage. Nous devons
129130
commencer par allouer des command buffers temporaires. Vous devriez d'ailleurs utiliser une autre command pool pour
130131
tous ces command buffer temporaires, afin de fournir à l'implémentation une occasion d'optimiser la gestion de la
131-
mémoire. Utilisez alors `VK_COMMAND_POOL_CREATE_TRANSIENT_BIT` pendant la création de la command pool.
132+
mémoire séparément des graphismes. Si vous le faites, utilisez `VK_COMMAND_POOL_CREATE_TRANSIENT_BIT` pendant la
133+
création de la command pool, car les commands buffers ne seront utilisés qu'une seule fois.
132134
133135
```c++
134136
void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) {
@@ -160,16 +162,16 @@ terminée avant de sortir de la fonction. Il est alors préférable d'informer l
160162
161163
```c++
162164
VkBufferCopy copyRegion = {};
163-
copyRegion.srcOffset = 0; // Optionnel
164-
copyRegion.dstOffset = 0; // Optionnel
165+
copyRegion.srcOffset = 0; // Optionel
166+
copyRegion.dstOffset = 0; // Optionel
165167
copyRegion.size = size;
166168
vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &copyRegion);
167169
```
168170

169171
La copie est réalisée à l'aide de la commande `vkCmdCopyBuffer`. Elle prend les buffers de source et d'arrivée comme
170172
arguments, et un tableau des régions à copier. Ces régions sont décrites dans des structures de type `VkBufferCopy`, qui
171173
consistent en un décalage dans le buffer source, le nombre d'octets à copier et le décalage dans le buffer d'arrivée. Il
172-
n'est pas ici possible d'indiquer `VK_WHOLE_SIZE`.
174+
n'est ici pas possible d'indiquer `VK_WHOLE_SIZE`.
173175

174176
```c++
175177
vkEndCommandBuffer(commandBuffer);
@@ -202,7 +204,7 @@ vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
202204
203205
N'oubliez pas de libérer le command buffer utilisé pour l'opération de transfert.
204206
205-
Nous pouvons maintenant appeler `copyBuffer` depuis la fonction `createVertexBuffer` pour que les vertices soient enfin
207+
Nous pouvons maintenant appeler `copyBuffer` depuis la fonction `createVertexBuffer` pour que les sommets soient enfin
206208
stockées dans la mémoire locale.
207209
208210
```c++
@@ -226,14 +228,16 @@ donc le détruire.
226228
227229
Lancez votre programme pour vérifier que vous voyez toujours le même triangle. L'amélioration n'est peut-être pas
228230
flagrante, mais il est clair que la mémoire permet d'améliorer les performances, préparant ainsi le terrain
229-
pour de la géométrie plus complexe.
231+
pour le chargement de géométrie plus complexe.
230232
231233
## Conclusion
232234
233235
Notez que dans une application réelle, vous ne devez pas allouer de la mémoire avec `vkAllocateMemory` pour chaque
234236
buffer. De toute façon le nombre d'appel à cette fonction est limité, par exemple à 4096, et ce même sur des cartes
235-
graphiques comme les GTX 1080. La bonne pratique consiste à allouer une grande zone de mémoire et d'utiliser un objet
236-
pour créer des décalages pour chacun des buffers.
237+
graphiques comme les GTX 1080. La bonne pratique consiste à allouer une grande zone de mémoire et d'utiliser un
238+
gestionnaire pour créer des décalages pour chacun des buffers. Il est même préférable d'utiliser un buffer pour
239+
plusieurs types de données (sommets et uniformes par exemple) et de séparer ces types grâce à des indices dans le
240+
buffer (voyez encore [ce même article](https://developer.nvidia.com/vulkan-memory-management)).
237241
238242
Vous pouvez implémenter votre propre solution, ou bien utiliser la librairie
239243
[VulkanMemoryAllocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator) crée par GPUOpen. Pour ce

0 commit comments

Comments
 (0)