CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/GPU/Vulkan/VulkanBarrier.cpp
Views: 1401
1
#include "VulkanLoader.h"
2
#include "VulkanContext.h"
3
#include "VulkanBarrier.h"
4
#include "VulkanFramebuffer.h"
5
6
#include "Common/Log.h"
7
8
VulkanBarrierBatch::~VulkanBarrierBatch() {
9
// _dbg_assert_(imageBarriers_.empty());
10
if (!imageBarriers_.empty()) {
11
ERROR_LOG(Log::G3D, "~VulkanBarrierBatch: %d barriers remaining", (int)imageBarriers_.size());
12
}
13
}
14
15
void VulkanBarrierBatch::Flush(VkCommandBuffer cmd) {
16
if (!imageBarriers_.empty()) {
17
vkCmdPipelineBarrier(cmd, srcStageMask_, dstStageMask_, dependencyFlags_, 0, nullptr, 0, nullptr, (uint32_t)imageBarriers_.size(), imageBarriers_.data());
18
}
19
imageBarriers_.clear();
20
srcStageMask_ = 0;
21
dstStageMask_ = 0;
22
dependencyFlags_ = 0;
23
}
24
25
void VulkanBarrierBatch::TransitionImage(
26
VkImage image, int baseMip, int numMipLevels, int numLayers, VkImageAspectFlags aspectMask,
27
VkImageLayout oldImageLayout, VkImageLayout newImageLayout,
28
VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,
29
VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask
30
) {
31
_dbg_assert_(image != VK_NULL_HANDLE);
32
33
srcStageMask_ |= srcStageMask;
34
dstStageMask_ |= dstStageMask;
35
dependencyFlags_ |= VK_DEPENDENCY_BY_REGION_BIT;
36
37
VkImageMemoryBarrier &imageBarrier = imageBarriers_.push_uninitialized();
38
imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
39
imageBarrier.pNext = nullptr;
40
imageBarrier.srcAccessMask = srcAccessMask;
41
imageBarrier.dstAccessMask = dstAccessMask;
42
imageBarrier.oldLayout = oldImageLayout;
43
imageBarrier.newLayout = newImageLayout;
44
imageBarrier.image = image;
45
imageBarrier.subresourceRange.aspectMask = aspectMask;
46
imageBarrier.subresourceRange.baseMipLevel = baseMip;
47
imageBarrier.subresourceRange.levelCount = numMipLevels;
48
imageBarrier.subresourceRange.layerCount = numLayers; // NOTE: We could usually use VK_REMAINING_ARRAY_LAYERS/VK_REMAINING_MIP_LEVELS, but really old Mali drivers have problems with those.
49
imageBarrier.subresourceRange.baseArrayLayer = 0;
50
imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
51
imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
52
}
53
54
void VulkanBarrierBatch::TransitionColorImageAuto(
55
VkImage image, VkImageLayout *imageLayout, VkImageLayout newImageLayout, int baseMip, int numMipLevels, int numLayers) {
56
_dbg_assert_(image != VK_NULL_HANDLE);
57
VkAccessFlags srcAccessMask = 0;
58
VkAccessFlags dstAccessMask = 0;
59
switch (*imageLayout) {
60
case VK_IMAGE_LAYOUT_UNDEFINED:
61
srcAccessMask = 0;
62
srcStageMask_ |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
63
break;
64
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
65
srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
66
srcStageMask_ |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
67
break;
68
case VK_IMAGE_LAYOUT_GENERAL:
69
// We came from the Mali workaround, and are transitioning back to COLOR_ATTACHMENT_OPTIMAL.
70
srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
71
srcStageMask_ |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
72
break;
73
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
74
// We only texture from images in the fragment shader, so can do this simply.
75
srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
76
srcStageMask_ |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
77
break;
78
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
79
srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
80
srcStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;
81
break;
82
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
83
srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
84
srcStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;
85
break;
86
default:
87
_assert_msg_(false, "Unexpected oldLayout: %s", VulkanImageLayoutToString(*imageLayout));
88
break;
89
}
90
91
switch (newImageLayout) {
92
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
93
dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
94
dstStageMask_ |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
95
break;
96
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
97
dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
98
dstStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;
99
break;
100
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
101
dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
102
dstStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;
103
break;
104
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
105
dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
106
dstStageMask_ |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
107
break;
108
default:
109
_assert_msg_(false, "Unexpected newLayout: %s", VulkanImageLayoutToString(newImageLayout));
110
break;
111
}
112
113
VkImageMemoryBarrier &imageBarrier = imageBarriers_.push_uninitialized();
114
imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
115
imageBarrier.pNext = nullptr;
116
imageBarrier.srcAccessMask = srcAccessMask;
117
imageBarrier.dstAccessMask = dstAccessMask;
118
imageBarrier.oldLayout = *imageLayout;
119
imageBarrier.newLayout = newImageLayout;
120
imageBarrier.image = image;
121
imageBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
122
imageBarrier.subresourceRange.baseMipLevel = baseMip;
123
imageBarrier.subresourceRange.levelCount = numMipLevels;
124
imageBarrier.subresourceRange.layerCount = numLayers; // NOTE: We could usually use VK_REMAINING_ARRAY_LAYERS/VK_REMAINING_MIP_LEVELS, but really old Mali drivers have problems with those.
125
imageBarrier.subresourceRange.baseArrayLayer = 0;
126
imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
127
imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
128
129
*imageLayout = newImageLayout;
130
}
131
132
void VulkanBarrierBatch::TransitionDepthStencilImageAuto(
133
VkImage image, VkImageLayout *imageLayout, VkImageLayout newImageLayout, int baseMip, int numMipLevels, int numLayers) {
134
_dbg_assert_(image != VK_NULL_HANDLE);
135
136
VkAccessFlags srcAccessMask = 0;
137
VkAccessFlags dstAccessMask = 0;
138
switch (*imageLayout) {
139
case VK_IMAGE_LAYOUT_UNDEFINED:
140
srcAccessMask = 0;
141
srcStageMask_ |= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
142
break;
143
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
144
srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
145
srcStageMask_ |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
146
break;
147
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
148
// We only texture from images in the fragment shader, so can do this simply.
149
srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
150
srcStageMask_ |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
151
break;
152
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
153
srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
154
srcStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;
155
break;
156
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
157
srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
158
srcStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;
159
break;
160
default:
161
_assert_msg_(false, "Unexpected oldLayout: %s", VulkanImageLayoutToString(*imageLayout));
162
break;
163
}
164
165
switch (newImageLayout) {
166
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
167
dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
168
dstStageMask_ |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
169
break;
170
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
171
dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
172
dstStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;
173
break;
174
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
175
dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
176
dstStageMask_ |= VK_PIPELINE_STAGE_TRANSFER_BIT;
177
break;
178
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
179
dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
180
dstStageMask_ |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
181
break;
182
default:
183
_assert_msg_(false, "Unexpected newLayout: %s", VulkanImageLayoutToString(newImageLayout));
184
break;
185
}
186
187
VkImageMemoryBarrier &imageBarrier = imageBarriers_.push_uninitialized();
188
imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
189
imageBarrier.pNext = nullptr;
190
imageBarrier.srcAccessMask = srcAccessMask;
191
imageBarrier.dstAccessMask = dstAccessMask;
192
imageBarrier.oldLayout = *imageLayout;
193
imageBarrier.newLayout = newImageLayout;
194
imageBarrier.image = image;
195
imageBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
196
imageBarrier.subresourceRange.baseMipLevel = baseMip;
197
imageBarrier.subresourceRange.levelCount = numMipLevels;
198
imageBarrier.subresourceRange.layerCount = numLayers; // NOTE: We could usually use VK_REMAINING_ARRAY_LAYERS/VK_REMAINING_MIP_LEVELS, but really old Mali drivers have problems with those.
199
imageBarrier.subresourceRange.baseArrayLayer = 0;
200
imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
201
imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
202
203
*imageLayout = newImageLayout;
204
}
205
206
void VulkanBarrierBatch::TransitionColorImageAuto(VKRImage *image, VkImageLayout newImageLayout) {
207
TransitionColorImageAuto(image->image, &image->layout, newImageLayout, 0, 1, image->numLayers);
208
}
209
210
void VulkanBarrierBatch::TransitionDepthStencilImageAuto(VKRImage *image, VkImageLayout newImageLayout) {
211
TransitionDepthStencilImageAuto(image->image, &image->layout, newImageLayout, 0, 1, image->numLayers);
212
}
213
214