mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 01:24:11 +01:00
[dxvk] Rework image view creation
This commit is contained in:
parent
713b76bea5
commit
25076d9220
@ -512,12 +512,12 @@ namespace dxvk {
|
|||||||
// we'll have to use a fallback using a texel buffer view and buffer copies.
|
// we'll have to use a fallback using a texel buffer view and buffer copies.
|
||||||
bool isViewCompatible = uavFormat == rawFormat;
|
bool isViewCompatible = uavFormat == rawFormat;
|
||||||
|
|
||||||
if (!isViewCompatible && (imageView->imageInfo().flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) {
|
if (!isViewCompatible && (imageView->image()->info().flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) {
|
||||||
uint32_t formatCount = imageView->imageInfo().viewFormatCount;
|
uint32_t formatCount = imageView->image()->info().viewFormatCount;
|
||||||
isViewCompatible = formatCount == 0;
|
isViewCompatible = formatCount == 0;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < formatCount && !isViewCompatible; i++)
|
for (uint32_t i = 0; i < formatCount && !isViewCompatible; i++)
|
||||||
isViewCompatible = imageView->imageInfo().viewFormats[i] == rawFormat;
|
isViewCompatible = imageView->image()->info().viewFormats[i] == rawFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isViewCompatible || isZeroClearValue) {
|
if (isViewCompatible || isZeroClearValue) {
|
||||||
@ -5428,8 +5428,8 @@ namespace dxvk {
|
|||||||
|| curView->info().numLayers != refView->info().numLayers)
|
|| curView->info().numLayers != refView->info().numLayers)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (curView->imageInfo().sampleCount
|
if (curView->image()->info().sampleCount
|
||||||
!= refView->imageInfo().sampleCount)
|
!= refView->image()->info().sampleCount)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Color targets must all be the same size
|
// Color targets must all be the same size
|
||||||
|
@ -558,9 +558,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
Rc<DxvkImage> image = m_device->importImage(imageInfo,
|
Rc<DxvkImage> image = m_device->importImage(imageInfo,
|
||||||
imageHandle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
imageHandle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
m_imageViews[i] = image->createView(viewInfo);
|
||||||
m_imageViews[i] = new DxvkImageView(
|
|
||||||
m_device->vkd(), image, viewInfo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkImageLayout GetRenderLayout() const {
|
VkImageLayout GetRenderLayout() const {
|
||||||
if (m_view->imageInfo().tiling == VK_IMAGE_TILING_OPTIMAL) {
|
if (m_view->image()->info().tiling == VK_IMAGE_TILING_OPTIMAL) {
|
||||||
switch (m_desc.Flags & (D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL)) {
|
switch (m_desc.Flags & (D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL)) {
|
||||||
default: // case 0
|
default: // case 0
|
||||||
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
@ -67,7 +67,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UINT GetSampleCount() const {
|
UINT GetSampleCount() const {
|
||||||
return UINT(m_view->imageInfo().sampleCount);
|
return UINT(m_view->image()->info().sampleCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageAspectFlags GetWritableAspectMask() const {
|
VkImageAspectFlags GetWritableAspectMask() const {
|
||||||
|
@ -52,13 +52,13 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkImageLayout GetRenderLayout() const {
|
VkImageLayout GetRenderLayout() const {
|
||||||
return m_view->imageInfo().tiling == VK_IMAGE_TILING_OPTIMAL
|
return m_view->image()->info().tiling == VK_IMAGE_TILING_OPTIMAL
|
||||||
? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||||
: VK_IMAGE_LAYOUT_GENERAL;
|
: VK_IMAGE_LAYOUT_GENERAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT GetSampleCount() const {
|
UINT GetSampleCount() const {
|
||||||
return UINT(m_view->imageInfo().sampleCount);
|
return UINT(m_view->image()->info().sampleCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D10RenderTargetView* GetD3D10Iface() {
|
D3D10RenderTargetView* GetD3D10Iface() {
|
||||||
|
@ -985,9 +985,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
Rc<DxvkImage> image = m_device->importImage(imageInfo,
|
Rc<DxvkImage> image = m_device->importImage(imageInfo,
|
||||||
imageHandle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
imageHandle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
m_wctx->imageViews[i] = image->createView(viewInfo);
|
||||||
m_wctx->imageViews[i] = new DxvkImageView(
|
|
||||||
m_device->vkd(), image, viewInfo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,7 +730,7 @@ namespace dxvk {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Create one depth view and one stencil view
|
// Create one depth view and one stencil view
|
||||||
DxvkImageViewCreateInfo dViewInfo;
|
DxvkImageViewCreateInfo dViewInfo = { };
|
||||||
dViewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
dViewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||||
dViewInfo.format = srcImage->info().format;
|
dViewInfo.format = srcImage->info().format;
|
||||||
dViewInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
dViewInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
@ -743,8 +743,8 @@ namespace dxvk {
|
|||||||
DxvkImageViewCreateInfo sViewInfo = dViewInfo;
|
DxvkImageViewCreateInfo sViewInfo = dViewInfo;
|
||||||
sViewInfo.aspect = VK_IMAGE_ASPECT_STENCIL_BIT;
|
sViewInfo.aspect = VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||||
|
|
||||||
Rc<DxvkImageView> dView = m_device->createImageView(srcImage, dViewInfo);
|
Rc<DxvkImageView> dView = srcImage->createView(dViewInfo);
|
||||||
Rc<DxvkImageView> sView = m_device->createImageView(srcImage, sViewInfo);
|
Rc<DxvkImageView> sView = srcImage->createView(sViewInfo);
|
||||||
|
|
||||||
// Create a descriptor set for the pack operation
|
// Create a descriptor set for the pack operation
|
||||||
VkImageLayout layout = srcImage->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
|
VkImageLayout layout = srcImage->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
|
||||||
@ -817,9 +817,6 @@ namespace dxvk {
|
|||||||
dstBuffer->info().stages,
|
dstBuffer->info().stages,
|
||||||
dstBuffer->info().access);
|
dstBuffer->info().access);
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::None>(dView);
|
|
||||||
m_cmd->trackResource<DxvkAccess::None>(sView);
|
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(dstBuffer);
|
m_cmd->trackResource<DxvkAccess::Write>(dstBuffer);
|
||||||
m_cmd->trackResource<DxvkAccess::Read>(srcImage);
|
m_cmd->trackResource<DxvkAccess::Read>(srcImage);
|
||||||
}
|
}
|
||||||
@ -1662,22 +1659,22 @@ namespace dxvk {
|
|||||||
VkImageLayout srcLayout = imageView->pickLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
VkImageLayout srcLayout = imageView->pickLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
|
||||||
// If necessary, transition first mip level to the read-only layout
|
// If necessary, transition first mip level to the read-only layout
|
||||||
if (imageView->imageInfo().layout != srcLayout) {
|
if (imageView->image()->info().layout != srcLayout) {
|
||||||
m_execAcquires.accessImage(imageView->image(),
|
m_execAcquires.accessImage(imageView->image(),
|
||||||
mipGenerator->getTopSubresource(),
|
mipGenerator->getTopSubresource(),
|
||||||
imageView->imageInfo().layout,
|
imageView->image()->info().layout,
|
||||||
imageView->imageInfo().stages, 0,
|
imageView->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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If necessary, initialize all levels that are written to
|
// If necessary, initialize all levels that are written to
|
||||||
if (imageView->imageInfo().layout != dstLayout) {
|
if (imageView->image()->info().layout != dstLayout) {
|
||||||
m_execAcquires.accessImage(imageView->image(),
|
m_execAcquires.accessImage(imageView->image(),
|
||||||
mipGenerator->getAllTargetSubresources(),
|
mipGenerator->getAllTargetSubresources(),
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
imageView->imageInfo().stages, 0,
|
imageView->image()->info().stages, 0,
|
||||||
dstLayout,
|
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);
|
||||||
@ -1785,9 +1782,9 @@ namespace dxvk {
|
|||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||||
VK_ACCESS_SHADER_READ_BIT,
|
VK_ACCESS_SHADER_READ_BIT,
|
||||||
imageView->imageInfo().layout,
|
imageView->image()->info().layout,
|
||||||
imageView->imageInfo().stages,
|
imageView->image()->info().stages,
|
||||||
imageView->imageInfo().access);
|
imageView->image()->info().access);
|
||||||
} else {
|
} else {
|
||||||
m_execBarriers.accessImage(imageView->image(),
|
m_execBarriers.accessImage(imageView->image(),
|
||||||
mipGenerator->getAllSourceSubresources(),
|
mipGenerator->getAllSourceSubresources(),
|
||||||
@ -1796,18 +1793,18 @@ namespace dxvk {
|
|||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||||
VK_ACCESS_SHADER_READ_BIT,
|
VK_ACCESS_SHADER_READ_BIT,
|
||||||
imageView->imageInfo().layout,
|
imageView->image()->info().layout,
|
||||||
imageView->imageInfo().stages,
|
imageView->image()->info().stages,
|
||||||
imageView->imageInfo().access);
|
imageView->image()->info().access);
|
||||||
|
|
||||||
m_execBarriers.accessImage(imageView->image(),
|
m_execBarriers.accessImage(imageView->image(),
|
||||||
mipGenerator->getBottomSubresource(),
|
mipGenerator->getBottomSubresource(),
|
||||||
dstLayout,
|
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,
|
||||||
imageView->imageInfo().layout,
|
imageView->image()->info().layout,
|
||||||
imageView->imageInfo().stages,
|
imageView->image()->info().stages,
|
||||||
imageView->imageInfo().access);
|
imageView->image()->info().access);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::None>(mipGenerator);
|
m_cmd->trackResource<DxvkAccess::None>(mipGenerator);
|
||||||
@ -1971,14 +1968,14 @@ namespace dxvk {
|
|||||||
VkClearValue clearValue) {
|
VkClearValue clearValue) {
|
||||||
DxvkColorAttachmentOps colorOp;
|
DxvkColorAttachmentOps colorOp;
|
||||||
colorOp.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
colorOp.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
colorOp.loadLayout = imageView->imageInfo().layout;
|
colorOp.loadLayout = imageView->image()->info().layout;
|
||||||
colorOp.storeLayout = imageView->imageInfo().layout;
|
colorOp.storeLayout = imageView->image()->info().layout;
|
||||||
|
|
||||||
DxvkDepthAttachmentOps depthOp;
|
DxvkDepthAttachmentOps depthOp;
|
||||||
depthOp.loadOpD = VK_ATTACHMENT_LOAD_OP_LOAD;
|
depthOp.loadOpD = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
depthOp.loadOpS = VK_ATTACHMENT_LOAD_OP_LOAD;
|
depthOp.loadOpS = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
depthOp.loadLayout = imageView->imageInfo().layout;
|
depthOp.loadLayout = imageView->image()->info().layout;
|
||||||
depthOp.storeLayout = imageView->imageInfo().layout;
|
depthOp.storeLayout = imageView->image()->info().layout;
|
||||||
|
|
||||||
if (clearAspects & VK_IMAGE_ASPECT_COLOR_BIT)
|
if (clearAspects & VK_IMAGE_ASPECT_COLOR_BIT)
|
||||||
colorOp.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
colorOp.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
@ -2015,7 +2012,7 @@ namespace dxvk {
|
|||||||
attachmentIndex = -1;
|
attachmentIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is3D = imageView->imageInfo().type == VK_IMAGE_TYPE_3D;
|
bool is3D = imageView->image()->info().type == VK_IMAGE_TYPE_3D;
|
||||||
|
|
||||||
if ((clearAspects | discardAspects) == imageView->info().aspect && !is3D) {
|
if ((clearAspects | discardAspects) == imageView->info().aspect && !is3D) {
|
||||||
colorOp.loadLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
colorOp.loadLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
@ -2023,7 +2020,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (attachmentIndex < 0) {
|
if (attachmentIndex < 0) {
|
||||||
bool hasViewFormatMismatch = imageView->info().format != imageView->imageInfo().format;
|
bool hasViewFormatMismatch = imageView->info().format != imageView->image()->info().format;
|
||||||
|
|
||||||
if (m_execBarriers.isImageDirty(imageView->image(), imageView->imageSubresources(), DxvkAccess::Write))
|
if (m_execBarriers.isImageDirty(imageView->image(), imageView->imageSubresources(), DxvkAccess::Write))
|
||||||
m_execBarriers.recordCommands(m_cmd);
|
m_execBarriers.recordCommands(m_cmd);
|
||||||
@ -2120,10 +2117,9 @@ namespace dxvk {
|
|||||||
imageView->imageSubresources(),
|
imageView->imageSubresources(),
|
||||||
imageLayout, clearStages, clearAccess,
|
imageLayout, clearStages, clearAccess,
|
||||||
storeLayout,
|
storeLayout,
|
||||||
imageView->imageInfo().stages,
|
imageView->image()->info().stages,
|
||||||
imageView->imageInfo().access);
|
imageView->image()->info().access);
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::None>(imageView);
|
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(imageView->image());
|
m_cmd->trackResource<DxvkAccess::Write>(imageView->image());
|
||||||
} else {
|
} else {
|
||||||
// Perform the operation when starting the next render pass
|
// Perform the operation when starting the next render pass
|
||||||
@ -2221,7 +2217,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
void DxvkContext::flushSharedImages() {
|
void DxvkContext::flushSharedImages() {
|
||||||
for (auto i = m_deferredClears.begin(); i != m_deferredClears.end(); ) {
|
for (auto i = m_deferredClears.begin(); i != m_deferredClears.end(); ) {
|
||||||
if (i->imageView->imageInfo().shared) {
|
if (i->imageView->image()->info().shared) {
|
||||||
this->performClear(i->imageView, -1, i->discardAspects, i->clearAspects, i->clearValue);
|
this->performClear(i->imageView, -1, i->discardAspects, i->clearAspects, i->clearValue);
|
||||||
i = m_deferredClears.erase(i);
|
i = m_deferredClears.erase(i);
|
||||||
} else {
|
} else {
|
||||||
@ -3320,11 +3316,11 @@ namespace dxvk {
|
|||||||
renderingInfo.pStencilAttachment = &attachmentInfo;
|
renderingInfo.pStencilAttachment = &attachmentInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clearLayout != imageView->imageInfo().layout) {
|
if (clearLayout != imageView->image()->info().layout) {
|
||||||
m_execAcquires.accessImage(
|
m_execAcquires.accessImage(
|
||||||
imageView->image(),
|
imageView->image(),
|
||||||
imageView->imageSubresources(),
|
imageView->imageSubresources(),
|
||||||
imageView->imageInfo().layout, clearStages, 0,
|
imageView->image()->info().layout, clearStages, 0,
|
||||||
clearLayout, clearStages, clearAccess);
|
clearLayout, clearStages, clearAccess);
|
||||||
m_execAcquires.recordCommands(m_cmd);
|
m_execAcquires.recordCommands(m_cmd);
|
||||||
}
|
}
|
||||||
@ -3365,11 +3361,10 @@ namespace dxvk {
|
|||||||
imageView->image(),
|
imageView->image(),
|
||||||
imageView->imageSubresources(),
|
imageView->imageSubresources(),
|
||||||
clearLayout, clearStages, clearAccess,
|
clearLayout, clearStages, clearAccess,
|
||||||
imageView->imageInfo().layout,
|
imageView->image()->info().layout,
|
||||||
imageView->imageInfo().stages,
|
imageView->image()->info().stages,
|
||||||
imageView->imageInfo().access);
|
imageView->image()->info().access);
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::None>(imageView);
|
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(imageView->image());
|
m_cmd->trackResource<DxvkAccess::Write>(imageView->image());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3399,7 +3394,7 @@ namespace dxvk {
|
|||||||
VkDescriptorImageInfo viewInfo;
|
VkDescriptorImageInfo viewInfo;
|
||||||
viewInfo.sampler = VK_NULL_HANDLE;
|
viewInfo.sampler = VK_NULL_HANDLE;
|
||||||
viewInfo.imageView = imageView->handle();
|
viewInfo.imageView = imageView->handle();
|
||||||
viewInfo.imageLayout = imageView->imageInfo().layout;
|
viewInfo.imageLayout = imageView->image()->info().layout;
|
||||||
|
|
||||||
VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
|
VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
|
||||||
descriptorWrite.dstSet = descriptorSet;
|
descriptorWrite.dstSet = descriptorSet;
|
||||||
@ -3443,14 +3438,13 @@ namespace dxvk {
|
|||||||
m_execBarriers.accessImage(
|
m_execBarriers.accessImage(
|
||||||
imageView->image(),
|
imageView->image(),
|
||||||
imageView->imageSubresources(),
|
imageView->imageSubresources(),
|
||||||
imageView->imageInfo().layout,
|
imageView->image()->info().layout,
|
||||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
VK_ACCESS_SHADER_WRITE_BIT,
|
VK_ACCESS_SHADER_WRITE_BIT,
|
||||||
imageView->imageInfo().layout,
|
imageView->image()->info().layout,
|
||||||
imageView->imageInfo().stages,
|
imageView->image()->info().stages,
|
||||||
imageView->imageInfo().access);
|
imageView->image()->info().access);
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::None>(imageView);
|
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(imageView->image());
|
m_cmd->trackResource<DxvkAccess::Write>(imageView->image());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4687,8 +4681,8 @@ namespace dxvk {
|
|||||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
ops.depthOps.storeLayout,
|
ops.depthOps.storeLayout,
|
||||||
depthAttachment.view->imageInfo().stages,
|
depthAttachment.view->image()->info().stages,
|
||||||
depthAttachment.view->imageInfo().access);
|
depthAttachment.view->image()->info().access);
|
||||||
} else {
|
} else {
|
||||||
VkAccessFlags srcAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
|
VkAccessFlags srcAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
|
||||||
|
|
||||||
@ -4699,8 +4693,8 @@ namespace dxvk {
|
|||||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
srcAccess,
|
srcAccess,
|
||||||
depthAttachment.view->imageInfo().stages,
|
depthAttachment.view->image()->info().stages,
|
||||||
depthAttachment.view->imageInfo().access);
|
depthAttachment.view->image()->info().access);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4717,15 +4711,15 @@ namespace dxvk {
|
|||||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
ops.colorOps[i].storeLayout,
|
ops.colorOps[i].storeLayout,
|
||||||
colorAttachment.view->imageInfo().stages,
|
colorAttachment.view->image()->info().stages,
|
||||||
colorAttachment.view->imageInfo().access);
|
colorAttachment.view->image()->info().access);
|
||||||
} else {
|
} else {
|
||||||
m_execBarriers.accessMemory(
|
m_execBarriers.accessMemory(
|
||||||
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,
|
||||||
colorAttachment.view->imageInfo().stages,
|
colorAttachment.view->image()->info().stages,
|
||||||
colorAttachment.view->imageInfo().access);
|
colorAttachment.view->image()->info().access);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4764,7 +4758,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
// We can't use LOAD_OP_CLEAR if the view format does not match the
|
// We can't use LOAD_OP_CLEAR if the view format does not match the
|
||||||
// underlying image format, so just discard here and use clear later.
|
// underlying image format, so just discard here and use clear later.
|
||||||
if (colorTarget.view->info().format != colorTarget.view->imageInfo().format) {
|
if (colorTarget.view->info().format != colorTarget.view->image()->info().format) {
|
||||||
colorInfos[i].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
colorInfos[i].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
|
||||||
auto& clear = lateClears[lateClearCount++];
|
auto& clear = lateClears[lateClearCount++];
|
||||||
@ -4830,10 +4824,8 @@ namespace dxvk {
|
|||||||
m_cmd->cmdClearAttachments(lateClearCount, lateClears.data(), 1, &clearRect);
|
m_cmd->cmdClearAttachments(lateClearCount, lateClears.data(), 1, &clearRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < framebufferInfo.numAttachments(); i++) {
|
for (uint32_t i = 0; i < framebufferInfo.numAttachments(); i++)
|
||||||
m_cmd->trackResource<DxvkAccess::None> (framebufferInfo.getAttachment(i).view);
|
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(framebufferInfo.getAttachment(i).view->image());
|
m_cmd->trackResource<DxvkAccess::Write>(framebufferInfo.getAttachment(i).view->image());
|
||||||
}
|
|
||||||
|
|
||||||
m_cmd->addStatCtr(DxvkStatCounter::CmdRenderPassCount, 1);
|
m_cmd->addStatCtr(DxvkStatCounter::CmdRenderPassCount, 1);
|
||||||
}
|
}
|
||||||
@ -5258,12 +5250,10 @@ namespace dxvk {
|
|||||||
if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) {
|
if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) {
|
||||||
descriptorInfo.image.sampler = VK_NULL_HANDLE;
|
descriptorInfo.image.sampler = VK_NULL_HANDLE;
|
||||||
descriptorInfo.image.imageView = res.imageView->handle(binding.viewType);
|
descriptorInfo.image.imageView = res.imageView->handle(binding.viewType);
|
||||||
descriptorInfo.image.imageLayout = res.imageView->imageInfo().layout;
|
descriptorInfo.image.imageLayout = res.imageView->image()->info().layout;
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
if (m_rcTracked.set(binding.resourceBinding))
|
||||||
m_cmd->trackResource<DxvkAccess::None>(res.imageView);
|
|
||||||
m_cmd->trackResource<DxvkAccess::Read>(res.imageView->image());
|
m_cmd->trackResource<DxvkAccess::Read>(res.imageView->image());
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
descriptorInfo.image.sampler = VK_NULL_HANDLE;
|
descriptorInfo.image.sampler = VK_NULL_HANDLE;
|
||||||
descriptorInfo.image.imageView = VK_NULL_HANDLE;
|
descriptorInfo.image.imageView = VK_NULL_HANDLE;
|
||||||
@ -5277,12 +5267,10 @@ namespace dxvk {
|
|||||||
if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) {
|
if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) {
|
||||||
descriptorInfo.image.sampler = VK_NULL_HANDLE;
|
descriptorInfo.image.sampler = VK_NULL_HANDLE;
|
||||||
descriptorInfo.image.imageView = res.imageView->handle(binding.viewType);
|
descriptorInfo.image.imageView = res.imageView->handle(binding.viewType);
|
||||||
descriptorInfo.image.imageLayout = res.imageView->imageInfo().layout;
|
descriptorInfo.image.imageLayout = res.imageView->image()->info().layout;
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
if (m_rcTracked.set(binding.resourceBinding))
|
||||||
m_cmd->trackResource<DxvkAccess::None>(res.imageView);
|
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(res.imageView->image());
|
m_cmd->trackResource<DxvkAccess::Write>(res.imageView->image());
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
descriptorInfo.image.sampler = VK_NULL_HANDLE;
|
descriptorInfo.image.sampler = VK_NULL_HANDLE;
|
||||||
descriptorInfo.image.imageView = VK_NULL_HANDLE;
|
descriptorInfo.image.imageView = VK_NULL_HANDLE;
|
||||||
@ -5297,11 +5285,10 @@ namespace dxvk {
|
|||||||
&& res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) {
|
&& res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) {
|
||||||
descriptorInfo.image.sampler = res.sampler->handle();
|
descriptorInfo.image.sampler = res.sampler->handle();
|
||||||
descriptorInfo.image.imageView = res.imageView->handle(binding.viewType);
|
descriptorInfo.image.imageView = res.imageView->handle(binding.viewType);
|
||||||
descriptorInfo.image.imageLayout = res.imageView->imageInfo().layout;
|
descriptorInfo.image.imageLayout = res.imageView->image()->info().layout;
|
||||||
|
|
||||||
if (m_rcTracked.set(binding.resourceBinding)) {
|
if (m_rcTracked.set(binding.resourceBinding)) {
|
||||||
m_cmd->trackResource<DxvkAccess::None>(res.sampler);
|
m_cmd->trackResource<DxvkAccess::None>(res.sampler);
|
||||||
m_cmd->trackResource<DxvkAccess::None>(res.imageView);
|
|
||||||
m_cmd->trackResource<DxvkAccess::Read>(res.imageView->image());
|
m_cmd->trackResource<DxvkAccess::Read>(res.imageView->image());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -5472,17 +5459,17 @@ namespace dxvk {
|
|||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||||
const DxvkAttachment& color = m_state.om.framebufferInfo.getColorTarget(i);
|
const DxvkAttachment& color = m_state.om.framebufferInfo.getColorTarget(i);
|
||||||
|
|
||||||
if (color.view != nullptr && (!sharedOnly || color.view->imageInfo().shared)) {
|
if (color.view != nullptr && (!sharedOnly || color.view->image()->info().shared)) {
|
||||||
this->transitionColorAttachment(color, m_rtLayouts.color[i]);
|
this->transitionColorAttachment(color, m_rtLayouts.color[i]);
|
||||||
m_rtLayouts.color[i] = color.view->imageInfo().layout;
|
m_rtLayouts.color[i] = color.view->image()->info().layout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DxvkAttachment& depth = m_state.om.framebufferInfo.getDepthTarget();
|
const DxvkAttachment& depth = m_state.om.framebufferInfo.getDepthTarget();
|
||||||
|
|
||||||
if (depth.view != nullptr && (!sharedOnly || depth.view->imageInfo().shared)) {
|
if (depth.view != nullptr && (!sharedOnly || depth.view->image()->info().shared)) {
|
||||||
this->transitionDepthAttachment(depth, m_rtLayouts.depth);
|
this->transitionDepthAttachment(depth, m_rtLayouts.depth);
|
||||||
m_rtLayouts.depth = depth.view->imageInfo().layout;
|
m_rtLayouts.depth = depth.view->image()->info().layout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5490,15 +5477,15 @@ namespace dxvk {
|
|||||||
void DxvkContext::transitionColorAttachment(
|
void DxvkContext::transitionColorAttachment(
|
||||||
const DxvkAttachment& attachment,
|
const DxvkAttachment& attachment,
|
||||||
VkImageLayout oldLayout) {
|
VkImageLayout oldLayout) {
|
||||||
if (oldLayout != attachment.view->imageInfo().layout) {
|
if (oldLayout != attachment.view->image()->info().layout) {
|
||||||
m_execBarriers.accessImage(
|
m_execBarriers.accessImage(
|
||||||
attachment.view->image(),
|
attachment.view->image(),
|
||||||
attachment.view->imageSubresources(), oldLayout,
|
attachment.view->imageSubresources(), oldLayout,
|
||||||
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,
|
||||||
attachment.view->imageInfo().layout,
|
attachment.view->image()->info().layout,
|
||||||
attachment.view->imageInfo().stages,
|
attachment.view->image()->info().stages,
|
||||||
attachment.view->imageInfo().access);
|
attachment.view->image()->info().access);
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(attachment.view->image());
|
m_cmd->trackResource<DxvkAccess::Write>(attachment.view->image());
|
||||||
}
|
}
|
||||||
@ -5508,7 +5495,7 @@ namespace dxvk {
|
|||||||
void DxvkContext::transitionDepthAttachment(
|
void DxvkContext::transitionDepthAttachment(
|
||||||
const DxvkAttachment& attachment,
|
const DxvkAttachment& attachment,
|
||||||
VkImageLayout oldLayout) {
|
VkImageLayout oldLayout) {
|
||||||
if (oldLayout != attachment.view->imageInfo().layout) {
|
if (oldLayout != attachment.view->image()->info().layout) {
|
||||||
m_execBarriers.accessImage(
|
m_execBarriers.accessImage(
|
||||||
attachment.view->image(),
|
attachment.view->image(),
|
||||||
attachment.view->imageSubresources(), oldLayout,
|
attachment.view->imageSubresources(), oldLayout,
|
||||||
@ -5516,9 +5503,9 @@ namespace dxvk {
|
|||||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
oldLayout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
|
oldLayout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
|
||||||
? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : 0,
|
? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : 0,
|
||||||
attachment.view->imageInfo().layout,
|
attachment.view->image()->info().layout,
|
||||||
attachment.view->imageInfo().stages,
|
attachment.view->image()->info().stages,
|
||||||
attachment.view->imageInfo().access);
|
attachment.view->image()->info().access);
|
||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(attachment.view->image());
|
m_cmd->trackResource<DxvkAccess::Write>(attachment.view->image());
|
||||||
}
|
}
|
||||||
@ -5532,11 +5519,11 @@ namespace dxvk {
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||||
if (newFb.getColorTarget(i).view != nullptr)
|
if (newFb.getColorTarget(i).view != nullptr)
|
||||||
layouts.color[i] = newFb.getColorTarget(i).view->imageInfo().layout;
|
layouts.color[i] = newFb.getColorTarget(i).view->image()->info().layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newFb.getDepthTarget().view != nullptr)
|
if (newFb.getDepthTarget().view != nullptr)
|
||||||
layouts.depth = newFb.getDepthTarget().view->imageInfo().layout;
|
layouts.depth = newFb.getDepthTarget().view->image()->info().layout;
|
||||||
|
|
||||||
// Check whether any of the previous attachments have been moved
|
// Check whether any of the previous attachments have been moved
|
||||||
// around or been rebound with a different view. This may help
|
// around or been rebound with a different view. This may help
|
||||||
@ -6184,7 +6171,7 @@ namespace dxvk {
|
|||||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||||
if ((slot.imageView != nullptr)
|
if ((slot.imageView != nullptr)
|
||||||
&& (slot.imageView->imageInfo().access & storageImageAccess)) {
|
&& (slot.imageView->image()->info().access & storageImageAccess)) {
|
||||||
requiresBarrier = this->checkImageViewBarrier<DoEmit>(slot.imageView,
|
requiresBarrier = this->checkImageViewBarrier<DoEmit>(slot.imageView,
|
||||||
util::pipelineStages(binding.stage), binding.access);
|
util::pipelineStages(binding.stage), binding.access);
|
||||||
}
|
}
|
||||||
@ -6267,11 +6254,11 @@ namespace dxvk {
|
|||||||
m_execBarriers.accessImage(
|
m_execBarriers.accessImage(
|
||||||
imageView->image(),
|
imageView->image(),
|
||||||
imageView->imageSubresources(),
|
imageView->imageSubresources(),
|
||||||
imageView->imageInfo().layout,
|
imageView->image()->info().layout,
|
||||||
stages, access,
|
stages, access,
|
||||||
imageView->imageInfo().layout,
|
imageView->image()->info().layout,
|
||||||
imageView->imageInfo().stages,
|
imageView->image()->info().stages,
|
||||||
imageView->imageInfo().access);
|
imageView->image()->info().access);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(access);
|
DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(access);
|
||||||
|
@ -174,7 +174,7 @@ namespace dxvk {
|
|||||||
Rc<DxvkImageView> DxvkDevice::createImageView(
|
Rc<DxvkImageView> DxvkDevice::createImageView(
|
||||||
const Rc<DxvkImage>& image,
|
const Rc<DxvkImage>& image,
|
||||||
const DxvkImageViewCreateInfo& createInfo) {
|
const DxvkImageViewCreateInfo& createInfo) {
|
||||||
return new DxvkImageView(m_vkd, image, createInfo);
|
return image->createView(createInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,13 +16,13 @@ namespace dxvk {
|
|||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||||
if (m_renderTargets.color[i].view != nullptr) {
|
if (m_renderTargets.color[i].view != nullptr) {
|
||||||
m_attachments[m_attachmentCount++] = i;
|
m_attachments[m_attachmentCount++] = i;
|
||||||
m_sampleCount = m_renderTargets.color[i].view->imageInfo().sampleCount;
|
m_sampleCount = m_renderTargets.color[i].view->image()->info().sampleCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_renderTargets.depth.view != nullptr) {
|
if (m_renderTargets.depth.view != nullptr) {
|
||||||
m_attachments[m_attachmentCount++] = -1;
|
m_attachments[m_attachmentCount++] = -1;
|
||||||
m_sampleCount = m_renderTargets.depth.view->imageInfo().sampleCount;
|
m_sampleCount = m_renderTargets.depth.view->image()->info().sampleCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,35 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rc<DxvkImageView> DxvkImage::createView(
|
||||||
|
const DxvkImageViewCreateInfo& info) {
|
||||||
|
DxvkImageViewKey key = { };
|
||||||
|
key.viewType = info.type;
|
||||||
|
key.format = info.format;
|
||||||
|
key.usage = info.usage;
|
||||||
|
key.aspects = info.aspect;
|
||||||
|
key.mipIndex = info.minLevel;
|
||||||
|
key.mipCount = info.numLevels;
|
||||||
|
key.layerIndex = info.minLayer;
|
||||||
|
key.layerCount = info.numLayers;
|
||||||
|
|
||||||
|
if (info.usage == VK_IMAGE_USAGE_SAMPLED_BIT) {
|
||||||
|
key.packedSwizzle =
|
||||||
|
(uint16_t(info.swizzle.r) << 0) |
|
||||||
|
(uint16_t(info.swizzle.g) << 4) |
|
||||||
|
(uint16_t(info.swizzle.b) << 8) |
|
||||||
|
(uint16_t(info.swizzle.a) << 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_lock lock(m_viewMutex);
|
||||||
|
|
||||||
|
auto entry = m_views.emplace(std::piecewise_construct,
|
||||||
|
std::make_tuple(key), std::make_tuple(this, key));
|
||||||
|
|
||||||
|
return &entry.first->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkResourceAllocation> DxvkImage::createResource() {
|
Rc<DxvkResourceAllocation> DxvkImage::createResource() {
|
||||||
const DxvkFormatInfo* formatInfo = lookupFormatInfo(m_info.format);
|
const DxvkFormatInfo* formatInfo = lookupFormatInfo(m_info.format);
|
||||||
|
|
||||||
@ -195,108 +224,84 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
DxvkImageView::DxvkImageView(
|
DxvkImageView::DxvkImageView(
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
DxvkImage* image,
|
||||||
const Rc<DxvkImage>& image,
|
const DxvkImageViewKey& key)
|
||||||
const DxvkImageViewCreateInfo& info)
|
: m_image(image), m_key(key) {
|
||||||
: m_vkd(vkd), m_image(image), m_info(info) {
|
|
||||||
for (uint32_t i = 0; i < ViewCount; i++)
|
|
||||||
m_views[i] = VK_NULL_HANDLE;
|
|
||||||
|
|
||||||
switch (m_info.type) {
|
|
||||||
case VK_IMAGE_VIEW_TYPE_1D:
|
|
||||||
case VK_IMAGE_VIEW_TYPE_1D_ARRAY: {
|
|
||||||
this->createView(VK_IMAGE_VIEW_TYPE_1D, 1);
|
|
||||||
this->createView(VK_IMAGE_VIEW_TYPE_1D_ARRAY, m_info.numLayers);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case VK_IMAGE_VIEW_TYPE_2D:
|
|
||||||
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
|
|
||||||
this->createView(VK_IMAGE_VIEW_TYPE_2D, 1);
|
|
||||||
[[fallthrough]];
|
|
||||||
|
|
||||||
case VK_IMAGE_VIEW_TYPE_CUBE:
|
|
||||||
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: {
|
|
||||||
this->createView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, m_info.numLayers);
|
|
||||||
|
|
||||||
if (m_image->info().flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) {
|
|
||||||
uint32_t cubeCount = m_info.numLayers / 6;
|
|
||||||
|
|
||||||
if (cubeCount > 0) {
|
|
||||||
this->createView(VK_IMAGE_VIEW_TYPE_CUBE, 6);
|
|
||||||
this->createView(VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, 6 * cubeCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case VK_IMAGE_VIEW_TYPE_3D: {
|
|
||||||
this->createView(VK_IMAGE_VIEW_TYPE_3D, 1);
|
|
||||||
|
|
||||||
if (m_image->info().flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT && m_info.numLevels == 1) {
|
|
||||||
this->createView(VK_IMAGE_VIEW_TYPE_2D, 1);
|
|
||||||
this->createView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, m_image->mipLevelExtent(m_info.minLevel).depth);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw DxvkError(str::format("DxvkImageView: Invalid view type: ", m_info.type));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkImageView::~DxvkImageView() {
|
DxvkImageView::~DxvkImageView() {
|
||||||
for (uint32_t i = 0; i < ViewCount; i++)
|
|
||||||
m_vkd->vkDestroyImageView(m_vkd->device(), m_views[i], nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkImageView::createView(VkImageViewType type, uint32_t numLayers) {
|
|
||||||
VkImageSubresourceRange subresourceRange;
|
|
||||||
subresourceRange.aspectMask = m_info.aspect;
|
|
||||||
subresourceRange.baseMipLevel = m_info.minLevel;
|
|
||||||
subresourceRange.levelCount = m_info.numLevels;
|
|
||||||
subresourceRange.baseArrayLayer = m_info.minLayer;
|
|
||||||
subresourceRange.layerCount = numLayers;
|
|
||||||
|
|
||||||
VkImageViewUsageCreateInfo viewUsage = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO };
|
VkImageView DxvkImageView::createView(VkImageViewType type) const {
|
||||||
viewUsage.usage = m_info.usage;
|
DxvkImageViewKey key = m_key;
|
||||||
|
key.viewType = type;
|
||||||
VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &viewUsage };
|
|
||||||
viewInfo.image = m_image->handle();
|
|
||||||
viewInfo.viewType = type;
|
|
||||||
viewInfo.format = m_info.format;
|
|
||||||
viewInfo.components = m_info.swizzle;
|
|
||||||
viewInfo.subresourceRange = subresourceRange;
|
|
||||||
|
|
||||||
if (m_info.usage == VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
|
// Only use one layer for non-arrayed view types
|
||||||
viewInfo.components = {
|
if (type == VK_IMAGE_VIEW_TYPE_1D || type == VK_IMAGE_VIEW_TYPE_2D)
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
key.layerCount = 1u;
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY };
|
|
||||||
|
switch (m_image->info().type) {
|
||||||
|
case VK_IMAGE_TYPE_1D: {
|
||||||
|
// Trivial, just validate that view types are compatible
|
||||||
|
if (type != VK_IMAGE_VIEW_TYPE_1D && type != VK_IMAGE_VIEW_TYPE_1D_ARRAY)
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case VK_IMAGE_TYPE_2D: {
|
||||||
|
if (type == VK_IMAGE_VIEW_TYPE_CUBE || type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
|
||||||
|
// Ensure that the image is compatible with cube maps
|
||||||
|
if (key.layerCount < 6 || !(m_image->info().flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT))
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
// Adjust layer count to make sure it's a multiple of 6
|
||||||
|
key.layerCount = type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
|
||||||
|
? key.layerCount - key.layerCount % 6u : 6u;
|
||||||
|
} else if (type != VK_IMAGE_VIEW_TYPE_2D && type != VK_IMAGE_VIEW_TYPE_2D_ARRAY) {
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case VK_IMAGE_TYPE_3D: {
|
||||||
|
if (type == VK_IMAGE_VIEW_TYPE_2D || type == VK_IMAGE_VIEW_TYPE_2D_ARRAY) {
|
||||||
|
// Ensure that the image is actually compatible with 2D views
|
||||||
|
if (!(m_image->info().flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT))
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
// In case the view's native type is 3D, we can only create 2D compat
|
||||||
|
// views if there is only one mip and with the full set of array layers.
|
||||||
|
if (m_key.viewType == VK_IMAGE_VIEW_TYPE_3D) {
|
||||||
|
if (m_key.mipCount != 1u)
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
key.layerIndex = 0u;
|
||||||
|
key.layerCount = type == VK_IMAGE_VIEW_TYPE_2D_ARRAY
|
||||||
|
? m_image->mipLevelExtent(key.mipIndex).depth : 1u;
|
||||||
|
}
|
||||||
|
} else if (type != VK_IMAGE_VIEW_TYPE_3D) {
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_vkd->vkCreateImageView(m_vkd->device(),
|
return m_image->m_storage->createImageView(key);
|
||||||
&viewInfo, nullptr, &m_views[type]) != VK_SUCCESS) {
|
}
|
||||||
throw DxvkError(str::format(
|
|
||||||
"DxvkImageView: Failed to create image view:"
|
|
||||||
"\n View type: ", viewInfo.viewType,
|
void DxvkImageView::updateViews() {
|
||||||
"\n View format: ", viewInfo.format,
|
// Update all views that are not currently null
|
||||||
"\n Subresources: ",
|
for (uint32_t i = 0; i < m_views.size(); i++) {
|
||||||
"\n Aspect mask: ", std::hex, viewInfo.subresourceRange.aspectMask,
|
if (m_views[i])
|
||||||
"\n Mip levels: ", viewInfo.subresourceRange.baseMipLevel, " - ",
|
m_views[i] = createView(VkImageViewType(i));
|
||||||
viewInfo.subresourceRange.levelCount,
|
|
||||||
"\n Array layers: ", viewInfo.subresourceRange.baseArrayLayer, " - ",
|
|
||||||
viewInfo.subresourceRange.layerCount,
|
|
||||||
"\n Image properties:",
|
|
||||||
"\n Type: ", m_image->info().type,
|
|
||||||
"\n Format: ", m_image->info().format,
|
|
||||||
"\n Extent: ", "(", m_image->info().extent.width,
|
|
||||||
",", m_image->info().extent.height,
|
|
||||||
",", m_image->info().extent.depth, ")",
|
|
||||||
"\n Mip levels: ", m_image->info().mipLevels,
|
|
||||||
"\n Array layers: ", m_image->info().numLayers,
|
|
||||||
"\n Samples: ", m_image->info().sampleCount,
|
|
||||||
"\n Usage: ", std::hex, m_image->info().usage,
|
|
||||||
"\n Tiling: ", m_image->info().tiling));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_version = m_image->m_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,6 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
class DxvkImageView;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Image create info
|
* \brief Image create info
|
||||||
*
|
*
|
||||||
@ -106,6 +104,203 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Virtual image view
|
||||||
|
*
|
||||||
|
* Stores views for a number of different view types
|
||||||
|
* that the defined view is compatible with.
|
||||||
|
*/
|
||||||
|
class DxvkImageView {
|
||||||
|
constexpr static uint32_t ViewCount = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY + 1;
|
||||||
|
public:
|
||||||
|
|
||||||
|
DxvkImageView(
|
||||||
|
DxvkImage* image,
|
||||||
|
const DxvkImageViewKey& key);
|
||||||
|
|
||||||
|
~DxvkImageView();
|
||||||
|
|
||||||
|
void incRef();
|
||||||
|
void decRef();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Image view handle for the default type
|
||||||
|
*
|
||||||
|
* The default view type is guaranteed to be
|
||||||
|
* supported by the image view, and should be
|
||||||
|
* preferred over picking a different type.
|
||||||
|
* \returns Image view handle
|
||||||
|
*/
|
||||||
|
VkImageView handle() {
|
||||||
|
return handle(m_key.viewType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Image view handle for a given view type
|
||||||
|
*
|
||||||
|
* If the view does not support the requested image
|
||||||
|
* view type, \c VK_NULL_HANDLE will be returned.
|
||||||
|
* \param [in] viewType The requested view type
|
||||||
|
* \returns The image view handle
|
||||||
|
*/
|
||||||
|
VkImageView handle(VkImageViewType viewType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Image view type
|
||||||
|
*
|
||||||
|
* Convenience method to query the view type
|
||||||
|
* in order to check for resource compatibility.
|
||||||
|
* \returns Image view type
|
||||||
|
*/
|
||||||
|
VkImageViewType type() const {
|
||||||
|
return m_key.viewType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Image view properties
|
||||||
|
* \returns Image view properties
|
||||||
|
*/
|
||||||
|
DxvkImageViewCreateInfo info() const {
|
||||||
|
DxvkImageViewCreateInfo info = { };
|
||||||
|
info.type = m_key.viewType;
|
||||||
|
info.format = m_key.format;
|
||||||
|
info.usage = m_key.usage;
|
||||||
|
info.aspect = m_key.aspects;
|
||||||
|
info.minLevel = m_key.mipIndex;
|
||||||
|
info.numLevels = m_key.mipCount;
|
||||||
|
info.minLayer = m_key.layerIndex;
|
||||||
|
info.numLayers = m_key.layerCount;
|
||||||
|
info.swizzle.r = VkComponentSwizzle((m_key.packedSwizzle >> 0) & 0xf);
|
||||||
|
info.swizzle.g = VkComponentSwizzle((m_key.packedSwizzle >> 4) & 0xf);
|
||||||
|
info.swizzle.b = VkComponentSwizzle((m_key.packedSwizzle >> 8) & 0xf);
|
||||||
|
info.swizzle.a = VkComponentSwizzle((m_key.packedSwizzle >> 12) & 0xf);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Image object
|
||||||
|
* \returns Image object
|
||||||
|
*/
|
||||||
|
DxvkImage* image() const {
|
||||||
|
return m_image;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief View format info
|
||||||
|
* \returns View format info
|
||||||
|
*/
|
||||||
|
const DxvkFormatInfo* formatInfo() const {
|
||||||
|
return lookupFormatInfo(m_key.format);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Mip level size
|
||||||
|
*
|
||||||
|
* Computes the mip level size relative to
|
||||||
|
* the first mip level that the view includes.
|
||||||
|
* \param [in] level Mip level
|
||||||
|
* \returns Size of that level
|
||||||
|
*/
|
||||||
|
VkExtent3D mipLevelExtent(uint32_t level) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief View subresource range
|
||||||
|
*
|
||||||
|
* Returns the subresource range from the image
|
||||||
|
* description. For 2D views of 3D images, this
|
||||||
|
* will return the viewed 3D slices.
|
||||||
|
* \returns View subresource range
|
||||||
|
*/
|
||||||
|
VkImageSubresourceRange subresources() const {
|
||||||
|
VkImageSubresourceRange result;
|
||||||
|
result.aspectMask = m_key.aspects;
|
||||||
|
result.baseMipLevel = m_key.mipIndex;
|
||||||
|
result.levelCount = m_key.mipCount;
|
||||||
|
result.baseArrayLayer = m_key.layerIndex;
|
||||||
|
result.layerCount = m_key.layerCount;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Actual image subresource range
|
||||||
|
*
|
||||||
|
* Handles 3D images correctly in that it only
|
||||||
|
* returns one single array layer. Use this for
|
||||||
|
* barriers.
|
||||||
|
* \returns Image subresource range
|
||||||
|
*/
|
||||||
|
VkImageSubresourceRange imageSubresources() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Picks an image layout
|
||||||
|
* \see DxvkImage::pickLayout
|
||||||
|
*/
|
||||||
|
VkImageLayout pickLayout(VkImageLayout layout) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves descriptor info
|
||||||
|
*
|
||||||
|
* \param [in] type Exact view type
|
||||||
|
* \param [in] layout Image layout
|
||||||
|
* \returns Image descriptor
|
||||||
|
*/
|
||||||
|
DxvkDescriptorInfo getDescriptor(VkImageViewType type, VkImageLayout layout) {
|
||||||
|
DxvkDescriptorInfo result;
|
||||||
|
result.image.sampler = VK_NULL_HANDLE;
|
||||||
|
result.image.imageView = handle(type);
|
||||||
|
result.image.imageLayout = layout;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checks whether this view matches another
|
||||||
|
*
|
||||||
|
* \param [in] view The other view to check
|
||||||
|
* \returns \c true if the two views have the same subresources
|
||||||
|
*/
|
||||||
|
bool matchesView(const Rc<DxvkImageView>& view) const {
|
||||||
|
if (this == view.ptr())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return this->image() == view->image()
|
||||||
|
&& this->subresources() == view->subresources()
|
||||||
|
&& this->info().type == view->info().type
|
||||||
|
&& this->info().format == view->info().format;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checks whether this view overlaps with another one
|
||||||
|
*
|
||||||
|
* Two views overlap if they were created for the same
|
||||||
|
* image and have at least one subresource in common.
|
||||||
|
* \param [in] view The other view to check
|
||||||
|
* \returns \c true if the two views overlap
|
||||||
|
*/
|
||||||
|
bool checkSubresourceOverlap(const Rc<DxvkImageView>& view) const {
|
||||||
|
if (likely(m_image != view->m_image))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return vk::checkSubresourceRangeOverlap(
|
||||||
|
this->imageSubresources(),
|
||||||
|
view->imageSubresources());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
DxvkImage* m_image = nullptr;
|
||||||
|
DxvkImageViewKey m_key = { };
|
||||||
|
|
||||||
|
uint32_t m_version = 0u;
|
||||||
|
|
||||||
|
std::array<VkImageView, ViewCount> m_views = { };
|
||||||
|
|
||||||
|
VkImageView createView(VkImageViewType type) const;
|
||||||
|
|
||||||
|
void updateViews();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Virtual image resource
|
* \brief Virtual image resource
|
||||||
*
|
*
|
||||||
@ -114,8 +309,8 @@ namespace dxvk {
|
|||||||
* memory type and if created with the linear tiling option.
|
* memory type and if created with the linear tiling option.
|
||||||
*/
|
*/
|
||||||
class DxvkImage : public DxvkPagedResource {
|
class DxvkImage : public DxvkPagedResource {
|
||||||
|
friend DxvkImageView;
|
||||||
friend class DxvkContext;
|
friend class DxvkContext;
|
||||||
friend class DxvkImageView;
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkImage(
|
DxvkImage(
|
||||||
@ -348,6 +543,15 @@ namespace dxvk {
|
|||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Creates or retrieves an image view
|
||||||
|
*
|
||||||
|
* \param [in] info Image view create info
|
||||||
|
* \returns Newly created image view
|
||||||
|
*/
|
||||||
|
Rc<DxvkImageView> createView(
|
||||||
|
const DxvkImageViewCreateInfo& info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
Rc<vk::DeviceFn> m_vkd;
|
||||||
@ -365,6 +569,10 @@ namespace dxvk {
|
|||||||
|
|
||||||
small_vector<VkFormat, 4> m_viewFormats;
|
small_vector<VkFormat, 4> m_viewFormats;
|
||||||
|
|
||||||
|
dxvk::mutex m_viewMutex;
|
||||||
|
std::unordered_map<DxvkImageViewKey,
|
||||||
|
DxvkImageView, DxvkHash, DxvkEq> m_views;
|
||||||
|
|
||||||
VkImageCreateInfo getImageCreateInfo() const;
|
VkImageCreateInfo getImageCreateInfo() const;
|
||||||
|
|
||||||
void copyFormatList(
|
void copyFormatList(
|
||||||
@ -377,219 +585,58 @@ namespace dxvk {
|
|||||||
const DxvkSharedHandleInfo& sharingInfo) const;
|
const DxvkSharedHandleInfo& sharingInfo) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief DXVK image view
|
|
||||||
*/
|
inline void DxvkImageView::incRef() {
|
||||||
class DxvkImageView : public DxvkResource {
|
m_image->incRef();
|
||||||
friend class DxvkImage;
|
}
|
||||||
constexpr static uint32_t ViewCount = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY + 1;
|
|
||||||
public:
|
|
||||||
|
inline void DxvkImageView::decRef() {
|
||||||
DxvkImageView(
|
m_image->decRef();
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
}
|
||||||
const Rc<DxvkImage>& image,
|
|
||||||
const DxvkImageViewCreateInfo& info);
|
|
||||||
|
inline VkImageSubresourceRange DxvkImageView::imageSubresources() const {
|
||||||
~DxvkImageView();
|
VkImageSubresourceRange result = { };
|
||||||
|
result.aspectMask = m_key.aspects;
|
||||||
/**
|
result.baseMipLevel = m_key.mipIndex;
|
||||||
* \brief Image view handle for the default type
|
result.levelCount = m_key.mipCount;
|
||||||
*
|
|
||||||
* The default view type is guaranteed to be
|
if (likely(m_image->info().type != VK_IMAGE_TYPE_3D)) {
|
||||||
* supported by the image view, and should be
|
result.baseArrayLayer = m_key.layerIndex;
|
||||||
* preferred over picking a different type.
|
result.layerCount = m_key.layerCount;
|
||||||
* \returns Image view handle
|
} else {
|
||||||
*/
|
result.baseArrayLayer = 0;
|
||||||
VkImageView handle() const {
|
result.layerCount = 1;
|
||||||
return handle(m_info.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Image view handle for a given view type
|
|
||||||
*
|
|
||||||
* If the view does not support the requested image
|
|
||||||
* view type, \c VK_NULL_HANDLE will be returned.
|
|
||||||
* \param [in] viewType The requested view type
|
|
||||||
* \returns The image view handle
|
|
||||||
*/
|
|
||||||
VkImageView handle(VkImageViewType viewType) const {
|
|
||||||
if (unlikely(viewType == VK_IMAGE_VIEW_TYPE_MAX_ENUM))
|
|
||||||
viewType = m_info.type;
|
|
||||||
return m_views[viewType];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Image view type
|
|
||||||
*
|
|
||||||
* Convenience method to query the view type
|
|
||||||
* in order to check for resource compatibility.
|
|
||||||
* \returns Image view type
|
|
||||||
*/
|
|
||||||
VkImageViewType type() const {
|
|
||||||
return m_info.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Image view properties
|
|
||||||
* \returns Image view properties
|
|
||||||
*/
|
|
||||||
const DxvkImageViewCreateInfo& info() const {
|
|
||||||
return m_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Image handle
|
|
||||||
* \returns Image handle
|
|
||||||
*/
|
|
||||||
VkImage imageHandle() const {
|
|
||||||
return m_image->handle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Image properties
|
|
||||||
* \returns Image properties
|
|
||||||
*/
|
|
||||||
const DxvkImageCreateInfo& imageInfo() const {
|
|
||||||
return m_image->info();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Image object
|
|
||||||
* \returns Image object
|
|
||||||
*/
|
|
||||||
const Rc<DxvkImage>& image() const {
|
|
||||||
return m_image;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief View format info
|
|
||||||
* \returns View format info
|
|
||||||
*/
|
|
||||||
const DxvkFormatInfo* formatInfo() const {
|
|
||||||
return lookupFormatInfo(m_info.format);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Mip level size
|
|
||||||
*
|
|
||||||
* Computes the mip level size relative to
|
|
||||||
* the first mip level that the view includes.
|
|
||||||
* \param [in] level Mip level
|
|
||||||
* \returns Size of that level
|
|
||||||
*/
|
|
||||||
VkExtent3D mipLevelExtent(uint32_t level) const {
|
|
||||||
return m_image->mipLevelExtent(level + m_info.minLevel, m_info.aspect);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief View subresource range
|
|
||||||
*
|
|
||||||
* Returns the subresource range from the image
|
|
||||||
* description. For 2D views of 3D images, this
|
|
||||||
* will return the viewed 3D slices.
|
|
||||||
* \returns View subresource range
|
|
||||||
*/
|
|
||||||
VkImageSubresourceRange subresources() const {
|
|
||||||
VkImageSubresourceRange result;
|
|
||||||
result.aspectMask = m_info.aspect;
|
|
||||||
result.baseMipLevel = m_info.minLevel;
|
|
||||||
result.levelCount = m_info.numLevels;
|
|
||||||
result.baseArrayLayer = m_info.minLayer;
|
|
||||||
result.layerCount = m_info.numLayers;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
return result;
|
||||||
* \brief Actual image subresource range
|
}
|
||||||
*
|
|
||||||
* Handles 3D images correctly in that it only
|
|
||||||
* returns one single array layer. Use this for
|
|
||||||
* barriers.
|
|
||||||
* \returns Image subresource range
|
|
||||||
*/
|
|
||||||
VkImageSubresourceRange imageSubresources() const {
|
|
||||||
VkImageSubresourceRange result;
|
|
||||||
result.aspectMask = m_info.aspect;
|
|
||||||
result.baseMipLevel = m_info.minLevel;
|
|
||||||
result.levelCount = m_info.numLevels;
|
|
||||||
if (likely(m_image->info().type != VK_IMAGE_TYPE_3D)) {
|
|
||||||
result.baseArrayLayer = m_info.minLayer;
|
|
||||||
result.layerCount = m_info.numLayers;
|
|
||||||
} else {
|
|
||||||
result.baseArrayLayer = 0;
|
|
||||||
result.layerCount = 1;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Picks an image layout
|
|
||||||
* \see DxvkImage::pickLayout
|
|
||||||
*/
|
|
||||||
VkImageLayout pickLayout(VkImageLayout layout) const {
|
|
||||||
return m_image->pickLayout(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Retrieves descriptor info
|
|
||||||
*
|
|
||||||
* \param [in] type Exact view type
|
|
||||||
* \param [in] layout Image layout
|
|
||||||
* \returns Image descriptor
|
|
||||||
*/
|
|
||||||
DxvkDescriptorInfo getDescriptor(VkImageViewType type, VkImageLayout layout) const {
|
|
||||||
DxvkDescriptorInfo result;
|
|
||||||
result.image.sampler = VK_NULL_HANDLE;
|
|
||||||
result.image.imageView = handle(type);
|
|
||||||
result.image.imageLayout = layout;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
inline VkExtent3D DxvkImageView::mipLevelExtent(uint32_t level) const {
|
||||||
* \brief Checks whether this view matches another
|
return m_image->mipLevelExtent(level + m_key.mipIndex, m_key.aspects);
|
||||||
*
|
}
|
||||||
* \param [in] view The other view to check
|
|
||||||
* \returns \c true if the two views have the same subresources
|
|
||||||
*/
|
|
||||||
bool matchesView(const Rc<DxvkImageView>& view) const {
|
|
||||||
if (this == view.ptr())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return this->image() == view->image()
|
|
||||||
&& this->subresources() == view->subresources()
|
|
||||||
&& this->info().type == view->info().type
|
|
||||||
&& this->info().format == view->info().format;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
inline VkImageLayout DxvkImageView::pickLayout(VkImageLayout layout) const {
|
||||||
* \brief Checks whether this view overlaps with another one
|
return m_image->pickLayout(layout);
|
||||||
*
|
}
|
||||||
* Two views overlap if they were created for the same
|
|
||||||
* image and have at least one subresource in common.
|
|
||||||
* \param [in] view The other view to check
|
|
||||||
* \returns \c true if the two views overlap
|
|
||||||
*/
|
|
||||||
bool checkSubresourceOverlap(const Rc<DxvkImageView>& view) const {
|
|
||||||
if (likely(m_image != view->m_image))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return vk::checkSubresourceRangeOverlap(
|
|
||||||
this->imageSubresources(),
|
|
||||||
view->imageSubresources());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
inline VkImageView DxvkImageView::handle(VkImageViewType viewType) {
|
||||||
|
viewType = viewType != VK_IMAGE_VIEW_TYPE_MAX_ENUM ? viewType : m_key.viewType;
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
|
||||||
Rc<DxvkImage> m_image;
|
if (unlikely(m_version < m_image->m_version))
|
||||||
|
updateViews();
|
||||||
DxvkImageViewCreateInfo m_info;
|
|
||||||
VkImageView m_views[ViewCount];
|
if (unlikely(!m_views[viewType]))
|
||||||
|
m_views[viewType] = createView(viewType);
|
||||||
|
|
||||||
|
return m_views[viewType];
|
||||||
|
}
|
||||||
|
|
||||||
void createView(VkImageViewType type, uint32_t numLayers);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ namespace dxvk {
|
|||||||
{ VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_2D_ARRAY },
|
{ VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_2D_ARRAY },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
m_srcViewType = viewTypes.at(uint32_t(view->imageInfo().type)).first;
|
m_srcViewType = viewTypes.at(uint32_t(view->image()->info().type)).first;
|
||||||
m_dstViewType = viewTypes.at(uint32_t(view->imageInfo().type)).second;
|
m_dstViewType = viewTypes.at(uint32_t(view->image()->info().type)).second;
|
||||||
|
|
||||||
// Create image views and framebuffers
|
// Create image views and framebuffers
|
||||||
m_passes.resize(view->info().numLevels - 1);
|
m_passes.resize(view->info().numLevels - 1);
|
||||||
@ -35,7 +35,7 @@ namespace dxvk {
|
|||||||
VkExtent3D DxvkMetaMipGenRenderPass::computePassExtent(uint32_t passId) const {
|
VkExtent3D DxvkMetaMipGenRenderPass::computePassExtent(uint32_t passId) const {
|
||||||
VkExtent3D extent = m_view->mipLevelExtent(passId + 1);
|
VkExtent3D extent = m_view->mipLevelExtent(passId + 1);
|
||||||
|
|
||||||
if (m_view->imageInfo().type != VK_IMAGE_TYPE_3D)
|
if (m_view->image()->info().type != VK_IMAGE_TYPE_3D)
|
||||||
extent.depth = m_view->info().numLayers;
|
extent.depth = m_view->info().numLayers;
|
||||||
|
|
||||||
return extent;
|
return extent;
|
||||||
@ -48,7 +48,7 @@ namespace dxvk {
|
|||||||
VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO };
|
VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO };
|
||||||
|
|
||||||
VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo };
|
VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo };
|
||||||
viewInfo.image = m_view->imageHandle();
|
viewInfo.image = m_view->image()->handle();
|
||||||
viewInfo.format = m_view->info().format;
|
viewInfo.format = m_view->info().format;
|
||||||
|
|
||||||
// Create source image view, which points to
|
// Create source image view, which points to
|
||||||
@ -76,7 +76,7 @@ namespace dxvk {
|
|||||||
dstSubresources.baseMipLevel = m_view->info().minLevel + pass + 1;
|
dstSubresources.baseMipLevel = m_view->info().minLevel + pass + 1;
|
||||||
dstSubresources.levelCount = 1;
|
dstSubresources.levelCount = 1;
|
||||||
|
|
||||||
if (m_view->imageInfo().type != VK_IMAGE_TYPE_3D) {
|
if (m_view->image()->info().type != VK_IMAGE_TYPE_3D) {
|
||||||
dstSubresources.baseArrayLayer = m_view->info().minLayer;
|
dstSubresources.baseArrayLayer = m_view->info().minLayer;
|
||||||
dstSubresources.layerCount = m_view->info().numLayers;
|
dstSubresources.layerCount = m_view->info().numLayers;
|
||||||
} else {
|
} else {
|
||||||
|
@ -33,21 +33,21 @@ namespace dxvk {
|
|||||||
if (!dstRect.extent.width || !dstRect.extent.height) {
|
if (!dstRect.extent.width || !dstRect.extent.height) {
|
||||||
dstRect.offset = { 0, 0 };
|
dstRect.offset = { 0, 0 };
|
||||||
dstRect.extent = {
|
dstRect.extent = {
|
||||||
dstView->imageInfo().extent.width,
|
dstView->image()->info().extent.width,
|
||||||
dstView->imageInfo().extent.height };
|
dstView->image()->info().extent.height };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!srcRect.extent.width || !srcRect.extent.height) {
|
if (!srcRect.extent.width || !srcRect.extent.height) {
|
||||||
srcRect.offset = { 0, 0 };
|
srcRect.offset = { 0, 0 };
|
||||||
srcRect.extent = {
|
srcRect.extent = {
|
||||||
srcView->imageInfo().extent.width,
|
srcView->image()->info().extent.width,
|
||||||
srcView->imageInfo().extent.height };
|
srcView->image()->info().extent.height };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sameSize = dstRect.extent == srcRect.extent;
|
bool sameSize = dstRect.extent == srcRect.extent;
|
||||||
bool usedResolveImage = false;
|
bool usedResolveImage = false;
|
||||||
|
|
||||||
if (srcView->imageInfo().sampleCount == VK_SAMPLE_COUNT_1_BIT) {
|
if (srcView->image()->info().sampleCount == VK_SAMPLE_COUNT_1_BIT) {
|
||||||
this->draw(ctx, sameSize ? m_fsCopy : m_fsBlit,
|
this->draw(ctx, sameSize ? m_fsCopy : m_fsBlit,
|
||||||
dstView, dstRect, srcView, srcRect);
|
dstView, dstRect, srcView, srcRect);
|
||||||
} else if (sameSize) {
|
} else if (sameSize) {
|
||||||
@ -55,9 +55,9 @@ namespace dxvk {
|
|||||||
dstView, dstRect, srcView, srcRect);
|
dstView, dstRect, srcView, srcRect);
|
||||||
} else {
|
} else {
|
||||||
if (m_resolveImage == nullptr
|
if (m_resolveImage == nullptr
|
||||||
|| m_resolveImage->info().extent != srcView->imageInfo().extent
|
|| m_resolveImage->info().extent != srcView->image()->info().extent
|
||||||
|| m_resolveImage->info().format != srcView->imageInfo().format)
|
|| m_resolveImage->info().format != srcView->image()->info().format)
|
||||||
this->createResolveImage(srcView->imageInfo());
|
this->createResolveImage(srcView->image()->info());
|
||||||
|
|
||||||
this->resolve(ctx, m_resolveView, srcView);
|
this->resolve(ctx, m_resolveView, srcView);
|
||||||
this->draw(ctx, m_fsBlit, dstView, dstRect, m_resolveView, srcRect);
|
this->draw(ctx, m_fsBlit, dstView, dstRect, m_resolveView, srcRect);
|
||||||
@ -185,8 +185,8 @@ namespace dxvk {
|
|||||||
ctx->bindRenderTargets(std::move(renderTargets), 0u);
|
ctx->bindRenderTargets(std::move(renderTargets), 0u);
|
||||||
|
|
||||||
VkExtent2D dstExtent = {
|
VkExtent2D dstExtent = {
|
||||||
dstView->imageInfo().extent.width,
|
dstView->image()->info().extent.width,
|
||||||
dstView->imageInfo().extent.height };
|
dstView->image()->info().extent.height };
|
||||||
|
|
||||||
if (dstRect.extent == dstExtent)
|
if (dstRect.extent == dstExtent)
|
||||||
ctx->discardImageView(dstView, VK_IMAGE_ASPECT_COLOR_BIT);
|
ctx->discardImageView(dstView, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
@ -212,7 +212,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
ctx->pushConstants(0, sizeof(args), &args);
|
ctx->pushConstants(0, sizeof(args), &args);
|
||||||
|
|
||||||
ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, srcView->imageInfo().sampleCount);
|
ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, srcView->image()->info().sampleCount);
|
||||||
ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 1, m_gammaView != nullptr);
|
ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 1, m_gammaView != nullptr);
|
||||||
ctx->draw(3, 1, 0, 0);
|
ctx->draw(3, 1, 0, 0);
|
||||||
}
|
}
|
||||||
@ -226,7 +226,7 @@ namespace dxvk {
|
|||||||
resolve.srcOffset = { 0, 0, 0 };
|
resolve.srcOffset = { 0, 0, 0 };
|
||||||
resolve.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
|
resolve.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
|
||||||
resolve.dstOffset = { 0, 0, 0 };
|
resolve.dstOffset = { 0, 0, 0 };
|
||||||
resolve.extent = dstView->imageInfo().extent;
|
resolve.extent = dstView->image()->info().extent;
|
||||||
ctx->resolveImage(dstView->image(), srcView->image(), resolve, VK_FORMAT_UNDEFINED);
|
ctx->resolveImage(dstView->image(), srcView->image(), resolve, VK_FORMAT_UNDEFINED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user