mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-21 22:54:16 +01:00
[dxvk] Refactor meta blits
This commit is contained in:
parent
58dab7e8c6
commit
67d1285b08
@ -1330,20 +1330,37 @@ namespace dxvk {
|
|||||||
srcImage = resolveSrc;
|
srcImage = resolveSrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DxvkImageViewKey dstViewInfo;
|
||||||
|
dstViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||||
|
dstViewInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||||
|
dstViewInfo.format = dstImage->info().format;
|
||||||
|
dstViewInfo.aspects = blitInfo.dstSubresource.aspectMask;
|
||||||
|
dstViewInfo.mipIndex = blitInfo.dstSubresource.mipLevel;
|
||||||
|
dstViewInfo.mipCount = 1;
|
||||||
|
dstViewInfo.layerIndex = blitInfo.dstSubresource.baseArrayLayer;
|
||||||
|
dstViewInfo.layerCount = blitInfo.dstSubresource.layerCount;
|
||||||
|
dstViewInfo.packedSwizzle = DxvkImageViewKey::packSwizzle(dstTextureInfo->GetMapping().Swizzle);
|
||||||
|
|
||||||
|
DxvkImageViewKey srcViewInfo;
|
||||||
|
srcViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||||
|
srcViewInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
srcViewInfo.format = srcImage->info().format;
|
||||||
|
srcViewInfo.aspects = blitInfo.srcSubresource.aspectMask;
|
||||||
|
srcViewInfo.mipIndex = blitInfo.srcSubresource.mipLevel;
|
||||||
|
srcViewInfo.mipCount = 1;
|
||||||
|
srcViewInfo.layerIndex = blitInfo.srcSubresource.baseArrayLayer;
|
||||||
|
srcViewInfo.layerCount = blitInfo.srcSubresource.layerCount;
|
||||||
|
srcViewInfo.packedSwizzle = DxvkImageViewKey::packSwizzle(srcTextureInfo->GetMapping().Swizzle);
|
||||||
|
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cDstImage = dstImage,
|
cDstView = dstImage->createView(dstViewInfo),
|
||||||
cDstMap = dstTextureInfo->GetMapping().Swizzle,
|
cSrcView = srcImage->createView(srcViewInfo),
|
||||||
cSrcImage = srcImage,
|
|
||||||
cSrcMap = srcTextureInfo->GetMapping().Swizzle,
|
|
||||||
cBlitInfo = blitInfo,
|
cBlitInfo = blitInfo,
|
||||||
cFilter = stretch ? DecodeFilter(Filter) : VK_FILTER_NEAREST
|
cFilter = stretch ? DecodeFilter(Filter) : VK_FILTER_NEAREST
|
||||||
] (DxvkContext* ctx) {
|
] (DxvkContext* ctx) {
|
||||||
ctx->blitImage(
|
ctx->blitImageView(
|
||||||
cDstImage,
|
cDstView, cBlitInfo.dstOffsets,
|
||||||
cDstMap,
|
cSrcView, cBlitInfo.srcOffsets,
|
||||||
cSrcImage,
|
|
||||||
cSrcMap,
|
|
||||||
cBlitInfo,
|
|
||||||
cFilter);
|
cFilter);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -414,17 +414,37 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
DxvkImageViewKey dstViewInfo;
|
||||||
|
dstViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||||
|
dstViewInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||||
|
dstViewInfo.format = blittedSrc->info().format;
|
||||||
|
dstViewInfo.aspects = blitInfo.dstSubresource.aspectMask;
|
||||||
|
dstViewInfo.mipIndex = blitInfo.dstSubresource.mipLevel;
|
||||||
|
dstViewInfo.mipCount = 1;
|
||||||
|
dstViewInfo.layerIndex = blitInfo.dstSubresource.baseArrayLayer;
|
||||||
|
dstViewInfo.layerCount = blitInfo.dstSubresource.layerCount;
|
||||||
|
dstViewInfo.packedSwizzle = DxvkImageViewKey::packSwizzle(dstTexInfo->GetMapping().Swizzle);
|
||||||
|
|
||||||
|
DxvkImageViewKey srcViewInfo;
|
||||||
|
srcViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||||
|
srcViewInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
srcViewInfo.format = srcImage->info().format;
|
||||||
|
srcViewInfo.aspects = blitInfo.srcSubresource.aspectMask;
|
||||||
|
srcViewInfo.mipIndex = blitInfo.srcSubresource.mipLevel;
|
||||||
|
srcViewInfo.mipCount = 1;
|
||||||
|
srcViewInfo.layerIndex = blitInfo.srcSubresource.baseArrayLayer;
|
||||||
|
srcViewInfo.layerCount = blitInfo.srcSubresource.layerCount;
|
||||||
|
srcViewInfo.packedSwizzle = DxvkImageViewKey::packSwizzle(srcTexInfo->GetMapping().Swizzle);
|
||||||
|
|
||||||
m_parent->EmitCs([
|
m_parent->EmitCs([
|
||||||
cDstImage = blittedSrc,
|
cDstView = blittedSrc->createView(dstViewInfo),
|
||||||
cDstMap = dstTexInfo->GetMapping().Swizzle,
|
cSrcView = srcImage->createView(srcViewInfo),
|
||||||
cSrcImage = srcImage,
|
|
||||||
cSrcMap = srcTexInfo->GetMapping().Swizzle,
|
|
||||||
cBlitInfo = blitInfo
|
cBlitInfo = blitInfo
|
||||||
] (DxvkContext* ctx) {
|
] (DxvkContext* ctx) {
|
||||||
ctx->blitImage(
|
ctx->blitImageView(
|
||||||
cDstImage, cDstMap,
|
cDstView, cBlitInfo.dstOffsets,
|
||||||
cSrcImage, cSrcMap,
|
cSrcView, cBlitInfo.srcOffsets,
|
||||||
cBlitInfo, VK_FILTER_NEAREST);
|
VK_FILTER_NEAREST);
|
||||||
});
|
});
|
||||||
|
|
||||||
srcImage = std::move(blittedSrc);
|
srcImage = std::move(blittedSrc);
|
||||||
|
@ -124,37 +124,47 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::blitImage(
|
void DxvkContext::blitImageView(
|
||||||
const Rc<DxvkImage>& dstImage,
|
const Rc<DxvkImageView>& dstView,
|
||||||
const VkComponentMapping& dstMapping,
|
const VkOffset3D* dstOffsets,
|
||||||
const Rc<DxvkImage>& srcImage,
|
const Rc<DxvkImageView>& srcView,
|
||||||
const VkComponentMapping& srcMapping,
|
const VkOffset3D* srcOffsets,
|
||||||
const VkImageBlit& region,
|
|
||||||
VkFilter filter) {
|
VkFilter filter) {
|
||||||
this->spillRenderPass(true);
|
this->spillRenderPass(true);
|
||||||
this->prepareImage(dstImage, vk::makeSubresourceRange(region.dstSubresource));
|
this->prepareImage(dstView->image(), dstView->imageSubresources());
|
||||||
this->prepareImage(srcImage, vk::makeSubresourceRange(region.srcSubresource));
|
this->prepareImage(srcView->image(), srcView->imageSubresources());
|
||||||
|
|
||||||
auto mapping = util::resolveSrcComponentMapping(dstMapping, srcMapping);
|
auto mapping = util::resolveSrcComponentMapping(
|
||||||
|
dstView->info().unpackSwizzle(),
|
||||||
|
srcView->info().unpackSwizzle());
|
||||||
|
|
||||||
bool canUseFb = (srcImage->info().usage & VK_IMAGE_USAGE_SAMPLED_BIT)
|
bool useFb = dstView->image()->info().sampleCount != VK_SAMPLE_COUNT_1_BIT
|
||||||
&& (dstImage->info().usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
|| dstView->image()->info().format != dstView->info().format
|
||||||
&& ((dstImage->info().flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT)
|
|| srcView->image()->info().format != srcView->info().format
|
||||||
|| (dstImage->info().type != VK_IMAGE_TYPE_3D));
|
|
||||||
|
|
||||||
bool useFb = dstImage->info().sampleCount != VK_SAMPLE_COUNT_1_BIT
|
|
||||||
|| !util::isIdentityMapping(mapping);
|
|| !util::isIdentityMapping(mapping);
|
||||||
|
|
||||||
|
// Use render pass path if we already have the correct usage flags anyway
|
||||||
|
useFb |= (dstView->info().usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT))
|
||||||
|
&& (srcView->info().usage & (VK_IMAGE_USAGE_SAMPLED_BIT));
|
||||||
|
|
||||||
if (!useFb) {
|
if (!useFb) {
|
||||||
this->blitImageHw(
|
// Otherwise, verify that the vkCmdBlit path is supported for the given formats
|
||||||
dstImage, srcImage,
|
auto dstFeatures = m_device->adapter()->getFormatFeatures(dstView->info().format);
|
||||||
region, filter);
|
auto srcFeatures = m_device->adapter()->getFormatFeatures(srcView->info().format);
|
||||||
} else if (canUseFb) {
|
|
||||||
this->blitImageFb(
|
auto dstBits = dstView->image()->info().tiling == VK_IMAGE_TILING_OPTIMAL ? dstFeatures.optimal : dstFeatures.linear;
|
||||||
dstImage, srcImage,
|
auto srcBits = srcView->image()->info().tiling == VK_IMAGE_TILING_OPTIMAL ? srcFeatures.optimal : srcFeatures.linear;
|
||||||
region, mapping, filter);
|
|
||||||
|
useFb |= !(dstBits & VK_FORMAT_FEATURE_2_BLIT_DST_BIT)
|
||||||
|
|| !(srcBits & VK_FORMAT_FEATURE_2_BLIT_SRC_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useFb) {
|
||||||
|
this->blitImageFb(dstView, dstOffsets,
|
||||||
|
srcView, srcOffsets, filter);
|
||||||
} else {
|
} else {
|
||||||
Logger::err("DxvkContext: Unsupported blit operation");
|
this->blitImageHw(dstView, dstOffsets,
|
||||||
|
srcView, srcOffsets, filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3045,45 +3055,55 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void DxvkContext::blitImageFb(
|
void DxvkContext::blitImageFb(
|
||||||
const Rc<DxvkImage>& dstImage,
|
Rc<DxvkImageView> dstView,
|
||||||
const Rc<DxvkImage>& srcImage,
|
const VkOffset3D* dstOffsets,
|
||||||
const VkImageBlit& region,
|
Rc<DxvkImageView> srcView,
|
||||||
const VkComponentMapping& mapping,
|
const VkOffset3D* srcOffsets,
|
||||||
VkFilter filter) {
|
VkFilter filter) {
|
||||||
this->invalidateState();
|
this->invalidateState();
|
||||||
|
|
||||||
auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource);
|
bool srcIsDepthStencil = srcView->info().aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||||
auto srcSubresourceRange = vk::makeSubresourceRange(region.srcSubresource);
|
bool dstIsDepthStencil = dstView->info().aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||||
|
|
||||||
if (m_execBarriers.isImageDirty(dstImage, dstSubresourceRange, DxvkAccess::Write)
|
dstView = ensureImageViewCompatibility(dstView, dstIsDepthStencil
|
||||||
|| m_execBarriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write))
|
? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
|
||||||
|
: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||||
|
srcView = ensureImageViewCompatibility(srcView, VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||||
|
|
||||||
|
if (!dstView || !srcView) {
|
||||||
|
Logger::err(str::format("DxvkContext: blitImageFb: Resources not supported"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_execBarriers.isImageDirty(dstView->image(), dstView->imageSubresources(), DxvkAccess::Write)
|
||||||
|
|| m_execBarriers.isImageDirty(srcView->image(), srcView->imageSubresources(), DxvkAccess::Write))
|
||||||
m_execBarriers.recordCommands(m_cmd);
|
m_execBarriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
bool srcIsDepthStencil = region.srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
VkImageLayout srcLayout = srcView->image()->pickLayout(srcIsDepthStencil
|
||||||
|
|
||||||
VkImageLayout srcLayout = srcImage->pickLayout(srcIsDepthStencil
|
|
||||||
? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
|
? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
|
||||||
: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
|
||||||
VkImageLayout dstLayout = dstImage->pickLayout(
|
VkImageLayout dstLayout = dstView->image()->pickLayout(
|
||||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
|
|
||||||
if (dstImage->info().layout != dstLayout) {
|
if (dstView->image()->info().layout != dstLayout) {
|
||||||
m_execAcquires.accessImage(
|
m_execAcquires.accessImage(
|
||||||
dstImage, dstSubresourceRange,
|
dstView->image(),
|
||||||
dstImage->info().layout,
|
dstView->imageSubresources(),
|
||||||
dstImage->info().stages, 0,
|
dstView->image()->info().layout,
|
||||||
|
dstView->image()->info().stages, 0,
|
||||||
dstLayout,
|
dstLayout,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcImage->info().layout != srcLayout) {
|
if (srcView->image()->info().layout != srcLayout) {
|
||||||
m_execAcquires.accessImage(
|
m_execAcquires.accessImage(
|
||||||
srcImage, srcSubresourceRange,
|
srcView->image(),
|
||||||
srcImage->info().layout,
|
srcView->imageSubresources(),
|
||||||
srcImage->info().stages, 0,
|
srcView->image()->info().layout,
|
||||||
|
srcView->image()->info().stages, 0,
|
||||||
srcLayout,
|
srcLayout,
|
||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
VK_ACCESS_SHADER_READ_BIT);
|
VK_ACCESS_SHADER_READ_BIT);
|
||||||
@ -3093,37 +3113,34 @@ namespace dxvk {
|
|||||||
|
|
||||||
// Sort out image offsets so that dstOffset[0] points
|
// Sort out image offsets so that dstOffset[0] points
|
||||||
// to the top-left corner of the target area
|
// to the top-left corner of the target area
|
||||||
VkOffset3D srcOffsets[2] = { region.srcOffsets[0], region.srcOffsets[1] };
|
std::array<VkOffset3D, 2> srcOffsetsAdjusted = { srcOffsets[0], srcOffsets[1] };
|
||||||
VkOffset3D dstOffsets[2] = { region.dstOffsets[0], region.dstOffsets[1] };
|
std::array<VkOffset3D, 2> dstOffsetsAdjusted = { dstOffsets[0], dstOffsets[1] };
|
||||||
|
|
||||||
if (dstOffsets[0].x > dstOffsets[1].x) {
|
if (dstOffsetsAdjusted[0].x > dstOffsetsAdjusted[1].x) {
|
||||||
std::swap(dstOffsets[0].x, dstOffsets[1].x);
|
std::swap(dstOffsetsAdjusted[0].x, dstOffsetsAdjusted[1].x);
|
||||||
std::swap(srcOffsets[0].x, srcOffsets[1].x);
|
std::swap(srcOffsetsAdjusted[0].x, srcOffsetsAdjusted[1].x);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dstOffsets[0].y > dstOffsets[1].y) {
|
if (dstOffsetsAdjusted[0].y > dstOffsetsAdjusted[1].y) {
|
||||||
std::swap(dstOffsets[0].y, dstOffsets[1].y);
|
std::swap(dstOffsetsAdjusted[0].y, dstOffsetsAdjusted[1].y);
|
||||||
std::swap(srcOffsets[0].y, srcOffsets[1].y);
|
std::swap(srcOffsetsAdjusted[0].y, srcOffsetsAdjusted[1].y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dstOffsets[0].z > dstOffsets[1].z) {
|
if (dstOffsetsAdjusted[0].z > dstOffsetsAdjusted[1].z) {
|
||||||
std::swap(dstOffsets[0].z, dstOffsets[1].z);
|
std::swap(dstOffsetsAdjusted[0].z, dstOffsetsAdjusted[1].z);
|
||||||
std::swap(srcOffsets[0].z, srcOffsets[1].z);
|
std::swap(srcOffsetsAdjusted[0].z, srcOffsetsAdjusted[1].z);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkExtent3D dstExtent = {
|
VkExtent3D dstExtent = {
|
||||||
uint32_t(dstOffsets[1].x - dstOffsets[0].x),
|
uint32_t(dstOffsetsAdjusted[1].x - dstOffsetsAdjusted[0].x),
|
||||||
uint32_t(dstOffsets[1].y - dstOffsets[0].y),
|
uint32_t(dstOffsetsAdjusted[1].y - dstOffsetsAdjusted[0].y),
|
||||||
uint32_t(dstOffsets[1].z - dstOffsets[0].z) };
|
uint32_t(dstOffsetsAdjusted[1].z - dstOffsetsAdjusted[0].z) };
|
||||||
|
|
||||||
// Begin render pass
|
// Begin render pass
|
||||||
Rc<DxvkMetaBlitRenderPass> pass = new DxvkMetaBlitRenderPass(
|
VkExtent3D imageExtent = dstView->mipLevelExtent(0);
|
||||||
m_device, dstImage, srcImage, region, mapping);
|
|
||||||
|
|
||||||
VkExtent3D imageExtent = dstImage->mipLevelExtent(region.dstSubresource.mipLevel);
|
|
||||||
|
|
||||||
VkRenderingAttachmentInfo attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO };
|
VkRenderingAttachmentInfo attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO };
|
||||||
attachmentInfo.imageView = pass->getDstView();
|
attachmentInfo.imageView = dstView->handle();
|
||||||
attachmentInfo.imageLayout = dstLayout;
|
attachmentInfo.imageLayout = dstLayout;
|
||||||
attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
@ -3132,7 +3149,7 @@ namespace dxvk {
|
|||||||
renderingInfo.renderArea = VkRect2D {
|
renderingInfo.renderArea = VkRect2D {
|
||||||
VkOffset2D { 0, 0 },
|
VkOffset2D { 0, 0 },
|
||||||
VkExtent2D { imageExtent.width, imageExtent.height } };
|
VkExtent2D { imageExtent.width, imageExtent.height } };
|
||||||
renderingInfo.layerCount = pass->framebufferLayerCount();
|
renderingInfo.layerCount = dstView->info().layerCount;
|
||||||
renderingInfo.colorAttachmentCount = 1;
|
renderingInfo.colorAttachmentCount = 1;
|
||||||
renderingInfo.pColorAttachments = &attachmentInfo;
|
renderingInfo.pColorAttachments = &attachmentInfo;
|
||||||
|
|
||||||
@ -3140,22 +3157,23 @@ namespace dxvk {
|
|||||||
|
|
||||||
// Bind pipeline
|
// Bind pipeline
|
||||||
DxvkMetaBlitPipeline pipeInfo = m_common->metaBlit().getPipeline(
|
DxvkMetaBlitPipeline pipeInfo = m_common->metaBlit().getPipeline(
|
||||||
pass->viewType(), dstImage->info().format, dstImage->info().sampleCount);
|
dstView->info().viewType, dstView->info().format,
|
||||||
|
dstView->image()->info().sampleCount);
|
||||||
|
|
||||||
m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeHandle);
|
m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeHandle);
|
||||||
|
|
||||||
// Set up viewport
|
// Set up viewport
|
||||||
VkViewport viewport;
|
VkViewport viewport;
|
||||||
viewport.x = float(dstOffsets[0].x);
|
viewport.x = float(dstOffsetsAdjusted[0].x);
|
||||||
viewport.y = float(dstOffsets[0].y);
|
viewport.y = float(dstOffsetsAdjusted[0].y);
|
||||||
viewport.width = float(dstExtent.width);
|
viewport.width = float(dstExtent.width);
|
||||||
viewport.height = float(dstExtent.height);
|
viewport.height = float(dstExtent.height);
|
||||||
viewport.minDepth = 0.0f;
|
viewport.minDepth = 0.0f;
|
||||||
viewport.maxDepth = 1.0f;
|
viewport.maxDepth = 1.0f;
|
||||||
|
|
||||||
VkRect2D scissor;
|
VkRect2D scissor;
|
||||||
scissor.offset = { dstOffsets[0].x, dstOffsets[0].y };
|
scissor.offset = { dstOffsetsAdjusted[0].x, dstOffsetsAdjusted[0].y };
|
||||||
scissor.extent = { dstExtent.width, dstExtent.height };
|
scissor.extent = { dstExtent.width, dstExtent.height };
|
||||||
|
|
||||||
m_cmd->cmdSetViewport(1, &viewport);
|
m_cmd->cmdSetViewport(1, &viewport);
|
||||||
m_cmd->cmdSetScissor(1, &scissor);
|
m_cmd->cmdSetScissor(1, &scissor);
|
||||||
@ -3163,7 +3181,7 @@ namespace dxvk {
|
|||||||
// Bind source image view
|
// Bind source image view
|
||||||
VkDescriptorImageInfo descriptorImage;
|
VkDescriptorImageInfo descriptorImage;
|
||||||
descriptorImage.sampler = m_common->metaBlit().getSampler(filter);
|
descriptorImage.sampler = m_common->metaBlit().getSampler(filter);
|
||||||
descriptorImage.imageView = pass->getSrcView();
|
descriptorImage.imageView = srcView->handle();
|
||||||
descriptorImage.imageLayout = srcLayout;
|
descriptorImage.imageLayout = srcLayout;
|
||||||
|
|
||||||
VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
|
VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
|
||||||
@ -3179,18 +3197,18 @@ namespace dxvk {
|
|||||||
pipeInfo.pipeLayout, descriptorWrite.dstSet, 0, nullptr);
|
pipeInfo.pipeLayout, descriptorWrite.dstSet, 0, nullptr);
|
||||||
|
|
||||||
// Compute shader parameters for the operation
|
// Compute shader parameters for the operation
|
||||||
VkExtent3D srcExtent = srcImage->mipLevelExtent(region.srcSubresource.mipLevel);
|
VkExtent3D srcExtent = srcView->mipLevelExtent(0);
|
||||||
|
|
||||||
DxvkMetaBlitPushConstants pushConstants = { };
|
DxvkMetaBlitPushConstants pushConstants = { };
|
||||||
pushConstants.srcCoord0 = {
|
pushConstants.srcCoord0 = {
|
||||||
float(srcOffsets[0].x) / float(srcExtent.width),
|
float(srcOffsetsAdjusted[0].x) / float(srcExtent.width),
|
||||||
float(srcOffsets[0].y) / float(srcExtent.height),
|
float(srcOffsetsAdjusted[0].y) / float(srcExtent.height),
|
||||||
float(srcOffsets[0].z) / float(srcExtent.depth) };
|
float(srcOffsetsAdjusted[0].z) / float(srcExtent.depth) };
|
||||||
pushConstants.srcCoord1 = {
|
pushConstants.srcCoord1 = {
|
||||||
float(srcOffsets[1].x) / float(srcExtent.width),
|
float(srcOffsetsAdjusted[1].x) / float(srcExtent.width),
|
||||||
float(srcOffsets[1].y) / float(srcExtent.height),
|
float(srcOffsetsAdjusted[1].y) / float(srcExtent.height),
|
||||||
float(srcOffsets[1].z) / float(srcExtent.depth) };
|
float(srcOffsetsAdjusted[1].z) / float(srcExtent.depth) };
|
||||||
pushConstants.layerCount = pass->framebufferLayerCount();
|
pushConstants.layerCount = dstView->info().layerCount;
|
||||||
|
|
||||||
m_cmd->cmdPushConstants(
|
m_cmd->cmdPushConstants(
|
||||||
pipeInfo.pipeLayout,
|
pipeInfo.pipeLayout,
|
||||||
@ -3202,60 +3220,59 @@ namespace dxvk {
|
|||||||
m_cmd->cmdEndRendering();
|
m_cmd->cmdEndRendering();
|
||||||
|
|
||||||
// Add barriers and track image objects
|
// Add barriers and track image objects
|
||||||
m_execBarriers.accessImage(dstImage,
|
m_execBarriers.accessImage(
|
||||||
vk::makeSubresourceRange(region.dstSubresource),
|
dstView->image(),
|
||||||
dstLayout,
|
dstView->imageSubresources(), dstLayout,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
dstImage->info().layout,
|
dstView->image()->info().layout,
|
||||||
dstImage->info().stages,
|
dstView->image()->info().stages,
|
||||||
dstImage->info().access);
|
dstView->image()->info().access);
|
||||||
|
|
||||||
m_execBarriers.accessImage(srcImage,
|
m_execBarriers.accessImage(
|
||||||
vk::makeSubresourceRange(region.srcSubresource),
|
srcView->image(),
|
||||||
srcLayout,
|
srcView->imageSubresources(), srcLayout,
|
||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
VK_ACCESS_SHADER_READ_BIT,
|
VK_ACCESS_SHADER_READ_BIT,
|
||||||
srcImage->info().layout,
|
srcView->image()->info().layout,
|
||||||
srcImage->info().stages,
|
srcView->image()->info().stages,
|
||||||
srcImage->info().access);
|
srcView->image()->info().access);
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(dstImage);
|
m_cmd->trackResource<DxvkAccess::Write>(dstView->image());
|
||||||
m_cmd->trackResource<DxvkAccess::Read>(srcImage);
|
m_cmd->trackResource<DxvkAccess::Read>(srcView->image());
|
||||||
m_cmd->trackResource<DxvkAccess::None>(pass);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::blitImageHw(
|
void DxvkContext::blitImageHw(
|
||||||
const Rc<DxvkImage>& dstImage,
|
const Rc<DxvkImageView>& dstView,
|
||||||
const Rc<DxvkImage>& srcImage,
|
const VkOffset3D* dstOffsets,
|
||||||
const VkImageBlit& region,
|
const Rc<DxvkImageView>& srcView,
|
||||||
|
const VkOffset3D* srcOffsets,
|
||||||
VkFilter filter) {
|
VkFilter filter) {
|
||||||
auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource);
|
if (m_execBarriers.isImageDirty(dstView->image(), dstView->imageSubresources(), DxvkAccess::Write)
|
||||||
auto srcSubresourceRange = vk::makeSubresourceRange(region.srcSubresource);
|
|| m_execBarriers.isImageDirty(srcView->image(), srcView->imageSubresources(), DxvkAccess::Write))
|
||||||
|
|
||||||
if (m_execBarriers.isImageDirty(dstImage, dstSubresourceRange, DxvkAccess::Write)
|
|
||||||
|| m_execBarriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write))
|
|
||||||
m_execBarriers.recordCommands(m_cmd);
|
m_execBarriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
// Prepare the two images for transfer ops if necessary
|
// Prepare the two images for transfer ops if necessary
|
||||||
auto dstLayout = dstImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
auto dstLayout = dstView->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
auto srcLayout = srcImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
auto srcLayout = srcView->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||||
|
|
||||||
if (dstImage->info().layout != dstLayout) {
|
if (dstView->image()->info().layout != dstLayout) {
|
||||||
m_execAcquires.accessImage(
|
m_execAcquires.accessImage(
|
||||||
dstImage, dstSubresourceRange,
|
dstView->image(),
|
||||||
dstImage->info().layout,
|
dstView->imageSubresources(),
|
||||||
|
dstView->image()->info().layout,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||||
dstLayout,
|
dstLayout,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
VK_ACCESS_TRANSFER_WRITE_BIT);
|
VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcImage->info().layout != srcLayout) {
|
if (srcView->image()->info().layout != srcLayout) {
|
||||||
m_execAcquires.accessImage(
|
m_execAcquires.accessImage(
|
||||||
srcImage, srcSubresourceRange,
|
srcView->image(),
|
||||||
srcImage->info().layout,
|
srcView->imageSubresources(),
|
||||||
|
srcView->image()->info().layout,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||||
srcLayout,
|
srcLayout,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
@ -3266,18 +3283,18 @@ namespace dxvk {
|
|||||||
|
|
||||||
// Perform the blit operation
|
// Perform the blit operation
|
||||||
VkImageBlit2 blitRegion = { VK_STRUCTURE_TYPE_IMAGE_BLIT_2 };
|
VkImageBlit2 blitRegion = { VK_STRUCTURE_TYPE_IMAGE_BLIT_2 };
|
||||||
blitRegion.srcSubresource = region.srcSubresource;
|
blitRegion.srcSubresource = vk::pickSubresourceLayers(srcView->imageSubresources(), 0);
|
||||||
blitRegion.dstSubresource = region.dstSubresource;
|
blitRegion.dstSubresource = vk::pickSubresourceLayers(dstView->imageSubresources(), 0);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 2; i++) {
|
for (uint32_t i = 0; i < 2; i++) {
|
||||||
blitRegion.srcOffsets[i] = region.srcOffsets[i];
|
blitRegion.srcOffsets[i] = srcOffsets[i];
|
||||||
blitRegion.dstOffsets[i] = region.dstOffsets[i];
|
blitRegion.dstOffsets[i] = dstOffsets[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
VkBlitImageInfo2 blitInfo = { VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 };
|
VkBlitImageInfo2 blitInfo = { VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 };
|
||||||
blitInfo.srcImage = srcImage->handle();
|
blitInfo.srcImage = srcView->image()->handle();
|
||||||
blitInfo.srcImageLayout = srcLayout;
|
blitInfo.srcImageLayout = srcLayout;
|
||||||
blitInfo.dstImage = dstImage->handle();
|
blitInfo.dstImage = dstView->image()->handle();
|
||||||
blitInfo.dstImageLayout = dstLayout;
|
blitInfo.dstImageLayout = dstLayout;
|
||||||
blitInfo.regionCount = 1;
|
blitInfo.regionCount = 1;
|
||||||
blitInfo.pRegions = &blitRegion;
|
blitInfo.pRegions = &blitRegion;
|
||||||
@ -3286,23 +3303,25 @@ namespace dxvk {
|
|||||||
m_cmd->cmdBlitImage(&blitInfo);
|
m_cmd->cmdBlitImage(&blitInfo);
|
||||||
|
|
||||||
m_execBarriers.accessImage(
|
m_execBarriers.accessImage(
|
||||||
dstImage, dstSubresourceRange, dstLayout,
|
dstView->image(),
|
||||||
|
dstView->imageSubresources(), dstLayout,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
dstImage->info().layout,
|
dstView->image()->info().layout,
|
||||||
dstImage->info().stages,
|
dstView->image()->info().stages,
|
||||||
dstImage->info().access);
|
dstView->image()->info().access);
|
||||||
|
|
||||||
m_execBarriers.accessImage(
|
m_execBarriers.accessImage(
|
||||||
srcImage, srcSubresourceRange, srcLayout,
|
srcView->image(),
|
||||||
|
srcView->imageSubresources(), srcLayout,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
VK_ACCESS_TRANSFER_READ_BIT,
|
VK_ACCESS_TRANSFER_READ_BIT,
|
||||||
srcImage->info().layout,
|
srcView->image()->info().layout,
|
||||||
srcImage->info().stages,
|
srcView->image()->info().stages,
|
||||||
srcImage->info().access);
|
srcView->image()->info().access);
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(dstImage);
|
m_cmd->trackResource<DxvkAccess::Write>(dstView->image());
|
||||||
m_cmd->trackResource<DxvkAccess::Read>(srcImage);
|
m_cmd->trackResource<DxvkAccess::Read>(srcView->image());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -383,19 +383,17 @@ namespace dxvk {
|
|||||||
/**
|
/**
|
||||||
* \brief Blits an image
|
* \brief Blits an image
|
||||||
*
|
*
|
||||||
* \param [in] dstImage Destination image
|
* \param [in] dstView Destination image view
|
||||||
* \param [in] dstMapping Destination swizzle
|
* \param [in] srcView Source image view
|
||||||
* \param [in] srcImage Source image
|
* \param [in] dstOffsets Two pixel coordinates in the destination image
|
||||||
* \param [in] srcMapping Source swizzle
|
* \param [in] srcOffsets Two pixel coordinates in the source image
|
||||||
* \param [in] region Blit region
|
|
||||||
* \param [in] filter Texture filter
|
* \param [in] filter Texture filter
|
||||||
*/
|
*/
|
||||||
void blitImage(
|
void blitImageView(
|
||||||
const Rc<DxvkImage>& dstImage,
|
const Rc<DxvkImageView>& dstView,
|
||||||
const VkComponentMapping& dstMapping,
|
const VkOffset3D* dstOffsets,
|
||||||
const Rc<DxvkImage>& srcImage,
|
const Rc<DxvkImageView>& srcView,
|
||||||
const VkComponentMapping& srcMapping,
|
const VkOffset3D* srcOffsets,
|
||||||
const VkImageBlit& region,
|
|
||||||
VkFilter filter);
|
VkFilter filter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1462,16 +1460,17 @@ namespace dxvk {
|
|||||||
std::array<DxvkComputePipeline*, 256> m_cpLookupCache = { };
|
std::array<DxvkComputePipeline*, 256> m_cpLookupCache = { };
|
||||||
|
|
||||||
void blitImageFb(
|
void blitImageFb(
|
||||||
const Rc<DxvkImage>& dstImage,
|
Rc<DxvkImageView> dstView,
|
||||||
const Rc<DxvkImage>& srcImage,
|
const VkOffset3D* dstOffsets,
|
||||||
const VkImageBlit& region,
|
Rc<DxvkImageView> srcView,
|
||||||
const VkComponentMapping& mapping,
|
const VkOffset3D* srcOffsets,
|
||||||
VkFilter filter);
|
VkFilter filter);
|
||||||
|
|
||||||
void blitImageHw(
|
void blitImageHw(
|
||||||
const Rc<DxvkImage>& dstImage,
|
const Rc<DxvkImageView>& dstView,
|
||||||
const Rc<DxvkImage>& srcImage,
|
const VkOffset3D* dstOffsets,
|
||||||
const VkImageBlit& region,
|
const Rc<DxvkImageView>& srcView,
|
||||||
|
const VkOffset3D* srcOffsets,
|
||||||
VkFilter filter);
|
VkFilter filter);
|
||||||
|
|
||||||
template<bool ToImage>
|
template<bool ToImage>
|
||||||
|
@ -11,111 +11,6 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxvkMetaBlitRenderPass::DxvkMetaBlitRenderPass(
|
|
||||||
const Rc<DxvkDevice>& device,
|
|
||||||
const Rc<DxvkImage>& dstImage,
|
|
||||||
const Rc<DxvkImage>& srcImage,
|
|
||||||
const VkImageBlit& region,
|
|
||||||
const VkComponentMapping& mapping)
|
|
||||||
: m_vkd (device->vkd()),
|
|
||||||
m_dstImage (dstImage),
|
|
||||||
m_srcImage (srcImage),
|
|
||||||
m_region (region),
|
|
||||||
m_dstView (createDstView()),
|
|
||||||
m_srcView (createSrcView(mapping)) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkMetaBlitRenderPass::~DxvkMetaBlitRenderPass() {
|
|
||||||
m_vkd->vkDestroyImageView(m_vkd->device(), m_dstView, nullptr);
|
|
||||||
m_vkd->vkDestroyImageView(m_vkd->device(), m_srcView, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkImageViewType DxvkMetaBlitRenderPass::viewType() const {
|
|
||||||
static const std::array<VkImageViewType, 3> viewTypes = {{
|
|
||||||
VK_IMAGE_VIEW_TYPE_1D_ARRAY,
|
|
||||||
VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
|
||||||
VK_IMAGE_VIEW_TYPE_3D,
|
|
||||||
}};
|
|
||||||
|
|
||||||
return viewTypes.at(uint32_t(m_srcImage->info().type));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t DxvkMetaBlitRenderPass::framebufferLayerIndex() const {
|
|
||||||
uint32_t result = m_region.dstSubresource.baseArrayLayer;
|
|
||||||
|
|
||||||
if (m_dstImage->info().type == VK_IMAGE_TYPE_3D)
|
|
||||||
result = std::min(m_region.dstOffsets[0].z, m_region.dstOffsets[1].z);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t DxvkMetaBlitRenderPass::framebufferLayerCount() const {
|
|
||||||
uint32_t result = m_region.dstSubresource.layerCount;
|
|
||||||
|
|
||||||
if (m_dstImage->info().type == VK_IMAGE_TYPE_3D) {
|
|
||||||
uint32_t minZ = std::min(m_region.dstOffsets[0].z, m_region.dstOffsets[1].z);
|
|
||||||
uint32_t maxZ = std::max(m_region.dstOffsets[0].z, m_region.dstOffsets[1].z);
|
|
||||||
result = maxZ - minZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkImageView DxvkMetaBlitRenderPass::createDstView() {
|
|
||||||
std::array<VkImageViewType, 3> viewTypes = {{
|
|
||||||
VK_IMAGE_VIEW_TYPE_1D_ARRAY,
|
|
||||||
VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
|
||||||
VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
|
||||||
}};
|
|
||||||
|
|
||||||
VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO };
|
|
||||||
usageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
||||||
|
|
||||||
VkImageViewCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo };
|
|
||||||
info.image = m_dstImage->handle();
|
|
||||||
info.viewType = viewTypes.at(uint32_t(m_dstImage->info().type));
|
|
||||||
info.format = m_dstImage->info().format;
|
|
||||||
info.components = VkComponentMapping();
|
|
||||||
info.subresourceRange = vk::makeSubresourceRange(m_region.dstSubresource);
|
|
||||||
|
|
||||||
if (m_dstImage->info().type) {
|
|
||||||
info.subresourceRange.baseArrayLayer = framebufferLayerIndex();
|
|
||||||
info.subresourceRange.layerCount = framebufferLayerCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
VkImageView result;
|
|
||||||
if (m_vkd->vkCreateImageView(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS)
|
|
||||||
throw DxvkError("DxvkMetaBlitRenderPass: Failed to create image view");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkImageView DxvkMetaBlitRenderPass::createSrcView(const VkComponentMapping& mapping) {
|
|
||||||
VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO };
|
|
||||||
usageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
||||||
|
|
||||||
VkImageViewCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo };
|
|
||||||
info.image = m_srcImage->handle();
|
|
||||||
info.viewType = this->viewType();
|
|
||||||
info.format = m_srcImage->info().format;
|
|
||||||
info.components = mapping;
|
|
||||||
info.subresourceRange = vk::makeSubresourceRange(m_region.srcSubresource);
|
|
||||||
|
|
||||||
VkImageView result;
|
|
||||||
if (m_vkd->vkCreateImageView(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS)
|
|
||||||
throw DxvkError("DxvkMetaBlitRenderPass: Failed to create image view");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DxvkMetaBlitObjects::DxvkMetaBlitObjects(const DxvkDevice* device)
|
DxvkMetaBlitObjects::DxvkMetaBlitObjects(const DxvkDevice* device)
|
||||||
: m_vkd (device->vkd()),
|
: m_vkd (device->vkd()),
|
||||||
m_samplerCopy (createSampler(VK_FILTER_NEAREST)),
|
m_samplerCopy (createSampler(VK_FILTER_NEAREST)),
|
||||||
|
@ -86,51 +86,7 @@ namespace dxvk {
|
|||||||
VkPipeline pipeHandle;
|
VkPipeline pipeHandle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Blit render pass
|
|
||||||
*
|
|
||||||
* Stores image view, render pass and framebuffer
|
|
||||||
* objects for a blit operation, as well as some
|
|
||||||
* metadata.
|
|
||||||
*/
|
|
||||||
class DxvkMetaBlitRenderPass : public DxvkResource {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DxvkMetaBlitRenderPass(
|
|
||||||
const Rc<DxvkDevice>& device,
|
|
||||||
const Rc<DxvkImage>& dstImage,
|
|
||||||
const Rc<DxvkImage>& srcImage,
|
|
||||||
const VkImageBlit& region,
|
|
||||||
const VkComponentMapping& mapping);
|
|
||||||
|
|
||||||
~DxvkMetaBlitRenderPass();
|
|
||||||
|
|
||||||
VkImageViewType viewType() const;
|
|
||||||
|
|
||||||
uint32_t framebufferLayerIndex() const;
|
|
||||||
uint32_t framebufferLayerCount() const;
|
|
||||||
|
|
||||||
VkImageView getDstView() const { return m_dstView; }
|
|
||||||
VkImageView getSrcView() const { return m_srcView; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
|
||||||
Rc<DxvkImage> m_dstImage;
|
|
||||||
Rc<DxvkImage> m_srcImage;
|
|
||||||
|
|
||||||
VkImageBlit m_region;
|
|
||||||
VkImageView m_dstView;
|
|
||||||
VkImageView m_srcView;
|
|
||||||
|
|
||||||
VkImageView createDstView();
|
|
||||||
VkImageView createSrcView(const VkComponentMapping& mapping);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Blitter objects
|
* \brief Blitter objects
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user