Use copy commands 2

This commit is contained in:
CamilleLaVey
2026-09-30 03:00:07 -04:00
parent efba499fd3
commit 4f5fc58b6e
11 changed files with 193 additions and 106 deletions
@@ -140,8 +140,10 @@ VkImageMemoryBarrier2 MakeTransitionBarrier(VkImage image, VkPipelineStageFlags2
};
}
VkImageCopy MakeCopyRegion(VkExtent2D extent) {
return VkImageCopy{
VkImageCopy2 MakeCopyRegion(VkExtent2D extent) {
return VkImageCopy2{
.sType = VK_STRUCTURE_TYPE_IMAGE_COPY_2,
.pNext = nullptr,
.srcSubresource{
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0,
@@ -343,7 +343,9 @@ void Layer::UpdateRawImage(const Tegra::FramebufferConfig& framebuffer, size_t i
buffer.Flush(); // Ensure host writes are visible before the GPU copy.
}
const VkBufferImageCopy copy{
const VkBufferImageCopy2 copy{
.sType = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2,
.pNext = nullptr,
.bufferOffset = image_offset,
.bufferRowLength = 0,
.bufferImageHeight = 0,
@@ -89,7 +89,9 @@ void UploadImage(const Device& device, MemoryAllocator& allocator, Scheduler& sc
std::ranges::copy(initial_contents, upload_buffer.Mapped().begin());
upload_buffer.Flush();
const std::array<VkBufferImageCopy, 1> regions{{{
const VkBufferImageCopy2 region{
.sType = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2,
.pNext = nullptr,
.bufferOffset = 0,
.bufferRowLength = dimensions.width,
.bufferImageHeight = dimensions.height,
@@ -99,14 +101,14 @@ void UploadImage(const Device& device, MemoryAllocator& allocator, Scheduler& sc
.layerCount = 1},
.imageOffset{},
.imageExtent{.width = dimensions.width, .height = dimensions.height, .depth = 1},
}}};
};
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([&](vk::CommandBuffer cmdbuf) {
TransitionImageLayout(cmdbuf, *image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_UNDEFINED);
cmdbuf.CopyBufferToImage(*upload_buffer, *image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
regions);
region);
TransitionImageLayout(cmdbuf, *image, VK_IMAGE_LAYOUT_GENERAL,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
});
@@ -163,7 +165,9 @@ void DownloadColorImage(vk::CommandBuffer& cmdbuf, VkImage image, VkBuffer buffe
.dstStageMask = vk::PIPELINE_STAGE_HOST,
.dstAccessMask = VK_ACCESS_2_HOST_READ_BIT,
};
const VkBufferImageCopy copy{
const VkBufferImageCopy2 copy{
.sType = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2,
.pNext = nullptr,
.bufferOffset = 0,
.bufferRowLength = 0,
.bufferImageHeight = 0,
@@ -36,8 +36,10 @@ struct VertexBindings {
u32 count;
};
VkBufferCopy MakeBufferCopy(const VideoCommon::BufferCopy& copy) {
return VkBufferCopy{
VkBufferCopy2 MakeBufferCopy(const VideoCommon::BufferCopy& copy) {
return VkBufferCopy2{
.sType = VK_STRUCTURE_TYPE_BUFFER_COPY_2,
.pNext = nullptr,
.srcOffset = copy.src_offset,
.dstOffset = copy.dst_offset,
.size = copy.size,
@@ -234,7 +236,9 @@ public:
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([src_buffer = staging.buffer, src_offset = staging.offset,
dst_buffer = *buffer, size_bytes](vk::CommandBuffer cmdbuf) {
const VkBufferCopy copy{
const VkBufferCopy2 copy{
.sType = VK_STRUCTURE_TYPE_BUFFER_COPY_2,
.pNext = nullptr,
.srcOffset = src_offset,
.dstOffset = 0,
.size = size_bytes,
@@ -500,7 +504,7 @@ void BufferCacheRuntime::CopyBuffer(VkBuffer dst_buffer, VkBuffer src_buffer,
}
// Measuring a popular game, this number never exceeds the specified size once data is warmed up
boost::container::small_vector<VkBufferCopy, 8> vk_copies(copies.size());
boost::container::small_vector<VkBufferCopy2, 8> vk_copies(copies.size());
std::ranges::transform(copies, vk_copies.begin(), MakeBufferCopy);
if (src_buffer == staging_pool.StreamBuf() && can_reorder_upload) {
scheduler.RecordWithUploadBuffer([src_buffer, dst_buffer, vk_copies](
@@ -51,9 +51,11 @@ bool CanBlitToSwapchain(const vk::PhysicalDevice& physical_device, VkFormat form
};
}
[[nodiscard]] VkImageBlit MakeImageBlit(s32 frame_width, s32 frame_height, s32 swapchain_width,
s32 swapchain_height) {
return VkImageBlit{
[[nodiscard]] VkImageBlit2 MakeImageBlit(s32 frame_width, s32 frame_height, s32 swapchain_width,
s32 swapchain_height) {
return VkImageBlit2{
.sType = VK_STRUCTURE_TYPE_IMAGE_BLIT_2,
.pNext = nullptr,
.srcSubresource = MakeImageSubresourceLayers(),
.srcOffsets =
{
@@ -85,9 +87,11 @@ bool CanBlitToSwapchain(const vk::PhysicalDevice& physical_device, VkFormat form
};
}
[[nodiscard]] VkImageCopy MakeImageCopy(u32 frame_width, u32 frame_height, u32 swapchain_width,
u32 swapchain_height) {
return VkImageCopy{
[[nodiscard]] VkImageCopy2 MakeImageCopy(u32 frame_width, u32 frame_height, u32 swapchain_width,
u32 swapchain_height) {
return VkImageCopy2{
.sType = VK_STRUCTURE_TYPE_IMAGE_COPY_2,
.pNext = nullptr,
.srcSubresource = MakeImageSubresourceLayers(),
.srcOffset =
{
@@ -653,11 +653,13 @@ public:
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([this, dst_buffer = stagging_buffer.buffer, extra_offset, start,
size](vk::CommandBuffer cmdbuf) {
std::array<VkBufferCopy, 1> copy{VkBufferCopy{
const VkBufferCopy2 copy{
.sType = VK_STRUCTURE_TYPE_BUFFER_COPY_2,
.pNext = nullptr,
.srcOffset = start * QUERY_SIZE,
.dstOffset = extra_offset,
.size = size * QUERY_SIZE,
}};
};
cmdbuf.CopyBuffer(*buffer, dst_buffer, copy);
});
}
@@ -1040,11 +1042,13 @@ private:
src_offset = offsets[slot_index],
slot](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(READ_BARRIER);
std::array<VkBufferCopy, 1> copy{VkBufferCopy{
const VkBufferCopy2 copy{
.sType = VK_STRUCTURE_TYPE_BUFFER_COPY_2,
.pNext = nullptr,
.srcOffset = src_offset,
.dstOffset = slot * TFBQueryBank::QUERY_SIZE,
.size = TFBQueryBank::QUERY_SIZE,
}};
};
cmdbuf.CopyBuffer(src_buffer, dst_buffer, copy);
cmdbuf.PipelineBarrier(WRITE_BARRIER);
});
@@ -1339,7 +1343,7 @@ struct QueryCacheRuntimeImpl {
std::vector<std::pair<DAddr, DAddr>> little_cache;
std::vector<std::pair<VkBuffer, VkDeviceSize>> buffers_to_upload_to;
std::vector<size_t> redirect_cache;
std::vector<std::vector<VkBufferCopy>> copies_setup;
std::vector<std::vector<VkBufferCopy2>> copies_setup;
// Host conditional rendering data
std::optional<ConditionalRenderingResolvePass> conditional_resolve_pass;
@@ -1657,7 +1661,9 @@ void QueryCacheRuntime::SyncValues(std::span<SyncValuesType> values, VkBuffer ba
size_t accumulated_size = 0;
for (size_t i = 0; i < values.size(); i++) {
size_t which_copy = impl->redirect_cache[i];
impl->copies_setup[which_copy].emplace_back(VkBufferCopy{
impl->copies_setup[which_copy].emplace_back(VkBufferCopy2{
.sType = VK_STRUCTURE_TYPE_BUFFER_COPY_2,
.pNext = nullptr,
.srcOffset = current_offset + accumulated_size,
.dstOffset = impl->buffers_to_upload_to[which_copy].second + values[i].address -
impl->little_cache[which_copy].first,
@@ -1671,7 +1677,9 @@ void QueryCacheRuntime::SyncValues(std::span<SyncValuesType> values, VkBuffer ba
} else {
for (size_t i = 0; i < values.size(); i++) {
size_t which_copy = impl->redirect_cache[i];
impl->copies_setup[which_copy].emplace_back(VkBufferCopy{
impl->copies_setup[which_copy].emplace_back(VkBufferCopy2{
.sType = VK_STRUCTURE_TYPE_BUFFER_COPY_2,
.pNext = nullptr,
.srcOffset = values[i].offset,
.dstOffset = impl->buffers_to_upload_to[which_copy].second + values[i].address -
impl->little_cache[which_copy].first,
@@ -503,9 +503,11 @@ void SanitizeDepthStencilSwizzle(std::array<SwizzleSource, 4>& swizzle,
};
}
[[nodiscard]] VkImageCopy MakeImageCopy(const VideoCommon::ImageCopy& copy,
VkImageAspectFlags aspect_mask) noexcept {
return VkImageCopy{
[[nodiscard]] VkImageCopy2 MakeImageCopy(const VideoCommon::ImageCopy& copy,
VkImageAspectFlags aspect_mask) noexcept {
return VkImageCopy2{
.sType = VK_STRUCTURE_TYPE_IMAGE_COPY_2,
.pNext = nullptr,
.srcSubresource = MakeImageSubresourceLayers(copy.src_subresource, aspect_mask),
.srcOffset = MakeOffset3D(copy.src_offset),
.dstSubresource = MakeImageSubresourceLayers(copy.dst_subresource, aspect_mask),
@@ -514,9 +516,12 @@ void SanitizeDepthStencilSwizzle(std::array<SwizzleSource, 4>& swizzle,
};
}
[[nodiscard]] VkBufferImageCopy MakeBufferImageCopy(const VideoCommon::ImageCopy& copy, bool is_src,
VkImageAspectFlags aspect_mask) noexcept {
return VkBufferImageCopy{
[[nodiscard]] VkBufferImageCopy2 MakeBufferImageCopy(const VideoCommon::ImageCopy& copy,
bool is_src,
VkImageAspectFlags aspect_mask) noexcept {
return VkBufferImageCopy2{
.sType = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2,
.pNext = nullptr,
.bufferOffset = 0,
.bufferRowLength = 0,
.bufferImageHeight = 0,
@@ -527,25 +532,13 @@ void SanitizeDepthStencilSwizzle(std::array<SwizzleSource, 4>& swizzle,
};
}
[[maybe_unused]] [[nodiscard]] boost::container::small_vector<VkBufferCopy, 16>
TransformBufferCopies(std::span<const VideoCommon::BufferCopy> copies, size_t buffer_offset) {
boost::container::small_vector<VkBufferCopy, 16> result(copies.size());
std::ranges::transform(
copies, result.begin(), [buffer_offset](const VideoCommon::BufferCopy& copy) {
return VkBufferCopy{
.srcOffset = static_cast<VkDeviceSize>(copy.src_offset + buffer_offset),
.dstOffset = static_cast<VkDeviceSize>(copy.dst_offset),
.size = static_cast<VkDeviceSize>(copy.size),
};
});
return result;
}
[[nodiscard]] boost::container::small_vector<VkBufferImageCopy, 16> TransformBufferImageCopies(
[[nodiscard]] boost::container::small_vector<VkBufferImageCopy2, 16> TransformBufferImageCopies(
std::span<const BufferImageCopy> copies, size_t buffer_offset, VkImageAspectFlags aspect_mask) {
struct Maker {
VkBufferImageCopy operator()(const BufferImageCopy& copy) const {
return VkBufferImageCopy{
VkBufferImageCopy2 operator()(const BufferImageCopy& copy) const {
return VkBufferImageCopy2{
.sType = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2,
.pNext = nullptr,
.bufferOffset = copy.buffer_offset + buffer_offset,
.bufferRowLength = copy.buffer_row_length,
.bufferImageHeight = copy.buffer_image_height,
@@ -574,14 +567,14 @@ TransformBufferCopies(std::span<const VideoCommon::BufferCopy> copies, size_t bu
VkImageAspectFlags aspect_mask;
};
if (aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
boost::container::small_vector<VkBufferImageCopy, 16> result(copies.size() * 2);
boost::container::small_vector<VkBufferImageCopy2, 16> result(copies.size() * 2);
std::ranges::transform(copies, result.begin(),
Maker{buffer_offset, VK_IMAGE_ASPECT_DEPTH_BIT});
std::ranges::transform(copies, result.begin() + copies.size(),
Maker{buffer_offset, VK_IMAGE_ASPECT_STENCIL_BIT});
return result;
} else {
boost::container::small_vector<VkBufferImageCopy, 16> result(copies.size());
boost::container::small_vector<VkBufferImageCopy2, 16> result(copies.size());
std::ranges::transform(copies, result.begin(), Maker{buffer_offset, aspect_mask});
return result;
}
@@ -688,7 +681,7 @@ struct RangedBarrierRange {
};
void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage image,
VkImageAspectFlags aspect_mask, bool is_initialized,
std::span<const VkBufferImageCopy> copies) {
std::span<const VkBufferImageCopy2> copies) {
// Compute exact mip/layer range being written to
RangedBarrierRange range;
for (const auto& region : copies) {
@@ -732,10 +725,12 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
cmdbuf.PipelineBarrier(0, {}, {}, write_barrier);
}
[[nodiscard]] VkImageBlit MakeImageBlit(const Region2D& dst_region, const Region2D& src_region,
const VkImageSubresourceLayers& dst_layers,
const VkImageSubresourceLayers& src_layers) {
return VkImageBlit{
[[nodiscard]] VkImageBlit2 MakeImageBlit(const Region2D& dst_region, const Region2D& src_region,
const VkImageSubresourceLayers& dst_layers,
const VkImageSubresourceLayers& src_layers) {
return VkImageBlit2{
.sType = VK_STRUCTURE_TYPE_IMAGE_BLIT_2,
.pNext = nullptr,
.srcSubresource = src_layers,
.srcOffsets =
{
@@ -772,11 +767,13 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
dst_region.end.y - dst_region.start.y == src_region.end.y - src_region.start.y;
}
[[nodiscard]] VkImageResolve MakeImageResolve(const Region2D& dst_region,
const Region2D& src_region,
const VkImageSubresourceLayers& dst_layers,
const VkImageSubresourceLayers& src_layers) {
return VkImageResolve{
[[nodiscard]] VkImageResolve2 MakeImageResolve(const Region2D& dst_region,
const Region2D& src_region,
const VkImageSubresourceLayers& dst_layers,
const VkImageSubresourceLayers& src_layers) {
return VkImageResolve2{
.sType = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2,
.pNext = nullptr,
.srcSubresource = src_layers,
.srcOffset =
{
@@ -879,10 +876,12 @@ void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const
.x = static_cast<s32>(up_scaling ? scaled_width : extent.width),
.y = static_cast<s32>(up_scaling ? scaled_height : extent.height),
};
boost::container::small_vector<VkImageBlit, 4> regions;
boost::container::small_vector<VkImageBlit2, 4> regions;
regions.reserve(resources.levels);
for (s32 level = 0; level < resources.levels; level++) {
regions.push_back({
.sType = VK_STRUCTURE_TYPE_IMAGE_BLIT_2,
.pNext = nullptr,
.srcSubresource{
.aspectMask = aspect_mask,
.mipLevel = static_cast<u32>(level),
@@ -1237,8 +1236,8 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
if (ENABLE_MSAA_RESOLVE_CONSUME) {
InvalidateResolveShadow(dst.Handle());
}
boost::container::small_vector<VkBufferImageCopy, 16> vk_in_copies(copies.size());
boost::container::small_vector<VkBufferImageCopy, 16> vk_out_copies(copies.size());
boost::container::small_vector<VkBufferImageCopy2, 16> vk_in_copies(copies.size());
boost::container::small_vector<VkBufferImageCopy2, 16> vk_out_copies(copies.size());
const VkImageAspectFlags src_aspect_mask = src.AspectMask();
const VkImageAspectFlags dst_aspect_mask = dst.AspectMask();
@@ -1267,10 +1266,10 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
vk_in_copies, vk_out_copies](vk::CommandBuffer cmdbuf) {
RangedBarrierRange dst_range;
RangedBarrierRange src_range;
for (const VkBufferImageCopy& copy : vk_in_copies) {
for (const VkBufferImageCopy2& copy : vk_in_copies) {
src_range.AddLayers(copy.imageSubresource);
}
for (const VkBufferImageCopy& copy : vk_out_copies) {
for (const VkBufferImageCopy2& copy : vk_out_copies) {
dst_range.AddLayers(copy.imageSubresource);
}
static constexpr VkMemoryBarrier2 READ_BARRIER{
@@ -1397,7 +1396,6 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst
}
}();
// Use shader-based depth/stencil blits if hardware doesn't support the format
// Note: MSAA resolves (MSAA->single) use vkCmdResolveImage which works fine
if (!can_blit_depth_stencil) {
UNIMPLEMENTED_IF(is_src_msaa || is_dst_msaa);
blit_image_helper.BlitDepthStencil(dst_framebuffer, src, dst_region, src_region,
@@ -1647,7 +1645,7 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
};
return ReinterpretImage(dst, src, std::span{&oneCopy, 1});
}
boost::container::small_vector<VkImageCopy, 16> vk_copies(copies.size());
boost::container::small_vector<VkImageCopy2, 16> vk_copies(copies.size());
const VkImageAspectFlags aspect_mask = dst.AspectMask();
ASSERT(aspect_mask == src.AspectMask());
@@ -1660,7 +1658,7 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
scheduler.Record([dst_image, src_image, aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) {
RangedBarrierRange dst_range;
RangedBarrierRange src_range;
for (const VkImageCopy& copy : vk_copies) {
for (const VkImageCopy2& copy : vk_copies) {
dst_range.AddLayers(copy.dstSubresource);
src_range.AddLayers(copy.srcSubresource);
}
@@ -1749,7 +1747,9 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
const VkImageAspectFlags aspect_mask = shadow->aspect_mask;
const VkImage shadow_image = *shadow->image;
const VkImage dst_image = dst.Handle();
const VkImageCopy region{
const VkImageCopy2 region{
.sType = VK_STRUCTURE_TYPE_IMAGE_COPY_2,
.pNext = nullptr,
.srcSubresource{
.aspectMask = aspect_mask,
.mipLevel = 0,
@@ -2199,7 +2199,8 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
}
boost::container::small_vector<VkBuffer, 8> buffers_vector{};
boost::container::small_vector<boost::container::small_vector<VkBufferImageCopy, 16>, 8>
boost::container::small_vector<
boost::container::small_vector<VkBufferImageCopy2, 16>, 8>
vk_copies;
for (size_t index = 0; index < buffers_span.size(); index++) {
buffers_vector.emplace_back(buffers_span[index]);
@@ -2278,7 +2279,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
return;
} else {
boost::container::small_vector<VkBuffer, 8> buffers_vector{};
boost::container::small_vector<boost::container::small_vector<VkBufferImageCopy, 16>, 8>
boost::container::small_vector<boost::container::small_vector<VkBufferImageCopy2, 16>, 8>
vk_copies;
for (size_t index = 0; index < buffers_span.size(); index++) {
buffers_vector.emplace_back(buffers_span[index]);
@@ -1423,7 +1423,9 @@ void Device::RemoveUnsuitableExtensions() {
extensions.synchronization2 = features.synchronization2.synchronization2;
extensions.dynamic_rendering = features.dynamic_rendering.dynamicRendering;
if (!extensions.synchronization2 || !extensions.dynamic_rendering) {
const bool copy_commands2 =
extensions.copy_commands2 || instance_version >= VK_API_VERSION_1_3;
if (!extensions.synchronization2 || !extensions.dynamic_rendering || !copy_commands2) {
throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
}
}
@@ -97,6 +97,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
EXTENSION(EXT, SHADER_VIEWPORT_INDEX_LAYER, shader_viewport_index_layer) \
EXTENSION(EXT, TOOLING_INFO, tooling_info) \
EXTENSION(EXT, VERTEX_ATTRIBUTE_DIVISOR, vertex_attribute_divisor) \
EXTENSION(KHR, COPY_COMMANDS_2, copy_commands2) \
EXTENSION(KHR, CREATE_RENDERPASS_2, create_renderpass2) \
EXTENSION(KHR, DEPTH_STENCIL_RESOLVE, depth_stencil_resolve) \
EXTENSION(KHR, DRAW_INDIRECT_COUNT, draw_indirect_count) \
+19 -12
View File
@@ -96,13 +96,13 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
X(vkCmdBindPipeline);
X(vkCmdBindTransformFeedbackBuffersEXT);
X(vkCmdBindVertexBuffers);
X(vkCmdBlitImage);
X(vkCmdBlitImage2);
X(vkCmdClearAttachments);
X(vkCmdClearColorImage);
X(vkCmdCopyBuffer);
X(vkCmdCopyBufferToImage);
X(vkCmdCopyImage);
X(vkCmdCopyImageToBuffer);
X(vkCmdCopyBuffer2);
X(vkCmdCopyBufferToImage2);
X(vkCmdCopyImage2);
X(vkCmdCopyImageToBuffer2);
X(vkCmdCopyQueryPoolResults);
X(vkCmdDispatch);
X(vkCmdDispatchIndirect);
@@ -158,7 +158,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
X(vkCmdSetColorBlendEnableEXT);
X(vkCmdSetColorBlendEquationEXT);
X(vkCmdResetQueryPool);
X(vkCmdResolveImage);
X(vkCmdResolveImage2);
X(vkCreateBuffer);
X(vkCreateBufferView);
X(vkCreateCommandPool);
@@ -253,12 +253,19 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
Proc(dld.vkQueueSubmit2, dld, "vkQueueSubmit2KHR", device);
}
if (!dld.vkCmdBeginRendering) {
Proc(dld.vkCmdBeginRendering, dld, "vkCmdBeginRenderingKHR", device);
}
if (!dld.vkCmdEndRendering) {
Proc(dld.vkCmdEndRendering, dld, "vkCmdEndRenderingKHR", device);
}
const auto load_khr = [&](auto& function, const char* name) {
if (!function) {
Proc(function, dld, name, device);
}
};
load_khr(dld.vkCmdBeginRendering, "vkCmdBeginRenderingKHR");
load_khr(dld.vkCmdEndRendering, "vkCmdEndRenderingKHR");
load_khr(dld.vkCmdBlitImage2, "vkCmdBlitImage2KHR");
load_khr(dld.vkCmdCopyBuffer2, "vkCmdCopyBuffer2KHR");
load_khr(dld.vkCmdCopyBufferToImage2, "vkCmdCopyBufferToImage2KHR");
load_khr(dld.vkCmdCopyImage2, "vkCmdCopyImage2KHR");
load_khr(dld.vkCmdCopyImageToBuffer2, "vkCmdCopyImageToBuffer2KHR");
load_khr(dld.vkCmdResolveImage2, "vkCmdResolveImage2KHR");
#undef X
}
+75 -23
View File
@@ -246,13 +246,13 @@ struct DeviceDispatch : InstanceDispatch {
PFN_vkCmdBindTransformFeedbackBuffersEXT vkCmdBindTransformFeedbackBuffersEXT{};
PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers{};
PFN_vkCmdBindVertexBuffers2EXT vkCmdBindVertexBuffers2EXT{};
PFN_vkCmdBlitImage vkCmdBlitImage{};
PFN_vkCmdBlitImage2 vkCmdBlitImage2{};
PFN_vkCmdClearAttachments vkCmdClearAttachments{};
PFN_vkCmdClearColorImage vkCmdClearColorImage{};
PFN_vkCmdCopyBuffer vkCmdCopyBuffer{};
PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage{};
PFN_vkCmdCopyImage vkCmdCopyImage{};
PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer{};
PFN_vkCmdCopyBuffer2 vkCmdCopyBuffer2{};
PFN_vkCmdCopyBufferToImage2 vkCmdCopyBufferToImage2{};
PFN_vkCmdCopyImage2 vkCmdCopyImage2{};
PFN_vkCmdCopyImageToBuffer2 vkCmdCopyImageToBuffer2{};
PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults{};
PFN_vkCmdDispatch vkCmdDispatch{};
PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect{};
@@ -272,7 +272,7 @@ struct DeviceDispatch : InstanceDispatch {
PFN_vkCmdPushConstants vkCmdPushConstants{};
PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR{};
PFN_vkCmdResetQueryPool vkCmdResetQueryPool{};
PFN_vkCmdResolveImage vkCmdResolveImage{};
PFN_vkCmdResolveImage2 vkCmdResolveImage2{};
PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants{};
PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT{};
PFN_vkCmdSetDepthBias vkCmdSetDepthBias{};
@@ -1274,16 +1274,35 @@ public:
}
void BlitImage(VkImage src_image, VkImageLayout src_layout, VkImage dst_image,
VkImageLayout dst_layout, Span<VkImageBlit> regions,
VkImageLayout dst_layout, Span<VkImageBlit2> regions,
VkFilter filter) const noexcept {
dld->vkCmdBlitImage(handle, src_image, src_layout, dst_image, dst_layout, regions.size(),
regions.data(), filter);
const VkBlitImageInfo2 info{
.sType = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2,
.pNext = nullptr,
.srcImage = src_image,
.srcImageLayout = src_layout,
.dstImage = dst_image,
.dstImageLayout = dst_layout,
.regionCount = regions.size(),
.pRegions = regions.data(),
.filter = filter,
};
dld->vkCmdBlitImage2(handle, &info);
}
void ResolveImage(VkImage src_image, VkImageLayout src_layout, VkImage dst_image,
VkImageLayout dst_layout, Span<VkImageResolve> regions) {
dld->vkCmdResolveImage(handle, src_image, src_layout, dst_image, dst_layout, regions.size(),
regions.data());
VkImageLayout dst_layout, Span<VkImageResolve2> regions) const noexcept {
const VkResolveImageInfo2 info{
.sType = VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2,
.pNext = nullptr,
.srcImage = src_image,
.srcImageLayout = src_layout,
.dstImage = dst_image,
.dstImageLayout = dst_layout,
.regionCount = regions.size(),
.pRegions = regions.data(),
};
dld->vkCmdResolveImage2(handle, &info);
}
void Dispatch(u32 x, u32 y, u32 z) const noexcept {
@@ -1353,26 +1372,59 @@ public:
}
void CopyBufferToImage(VkBuffer src_buffer, VkImage dst_image, VkImageLayout dst_image_layout,
Span<VkBufferImageCopy> regions) const noexcept {
dld->vkCmdCopyBufferToImage(handle, src_buffer, dst_image, dst_image_layout, regions.size(),
regions.data());
Span<VkBufferImageCopy2> regions) const noexcept {
const VkCopyBufferToImageInfo2 info{
.sType = VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2,
.pNext = nullptr,
.srcBuffer = src_buffer,
.dstImage = dst_image,
.dstImageLayout = dst_image_layout,
.regionCount = regions.size(),
.pRegions = regions.data(),
};
dld->vkCmdCopyBufferToImage2(handle, &info);
}
void CopyBuffer(VkBuffer src_buffer, VkBuffer dst_buffer,
Span<VkBufferCopy> regions) const noexcept {
dld->vkCmdCopyBuffer(handle, src_buffer, dst_buffer, regions.size(), regions.data());
Span<VkBufferCopy2> regions) const noexcept {
const VkCopyBufferInfo2 info{
.sType = VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2,
.pNext = nullptr,
.srcBuffer = src_buffer,
.dstBuffer = dst_buffer,
.regionCount = regions.size(),
.pRegions = regions.data(),
};
dld->vkCmdCopyBuffer2(handle, &info);
}
void CopyImage(VkImage src_image, VkImageLayout src_layout, VkImage dst_image,
VkImageLayout dst_layout, Span<VkImageCopy> regions) const noexcept {
dld->vkCmdCopyImage(handle, src_image, src_layout, dst_image, dst_layout, regions.size(),
regions.data());
VkImageLayout dst_layout, Span<VkImageCopy2> regions) const noexcept {
const VkCopyImageInfo2 info{
.sType = VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2,
.pNext = nullptr,
.srcImage = src_image,
.srcImageLayout = src_layout,
.dstImage = dst_image,
.dstImageLayout = dst_layout,
.regionCount = regions.size(),
.pRegions = regions.data(),
};
dld->vkCmdCopyImage2(handle, &info);
}
void CopyImageToBuffer(VkImage src_image, VkImageLayout src_layout, VkBuffer dst_buffer,
Span<VkBufferImageCopy> regions) const noexcept {
dld->vkCmdCopyImageToBuffer(handle, src_image, src_layout, dst_buffer, regions.size(),
regions.data());
Span<VkBufferImageCopy2> regions) const noexcept {
const VkCopyImageToBufferInfo2 info{
.sType = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2,
.pNext = nullptr,
.srcImage = src_image,
.srcImageLayout = src_layout,
.dstBuffer = dst_buffer,
.regionCount = regions.size(),
.pRegions = regions.data(),
};
dld->vkCmdCopyImageToBuffer2(handle, &info);
}
void CopyQueryPoolResults(VkQueryPool query_pool, u32 first_query, u32 query_count,