mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[d3d11] Implemented mipmap generation
This commit is contained in:
parent
a644eebfd7
commit
f88adc4e82
@ -651,7 +651,16 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void STDMETHODCALLTYPE D3D11DeviceContext::GenerateMips(ID3D11ShaderResourceView* pShaderResourceView) {
|
void STDMETHODCALLTYPE D3D11DeviceContext::GenerateMips(ID3D11ShaderResourceView* pShaderResourceView) {
|
||||||
Logger::err("D3D11DeviceContext::GenerateMips: Not implemented");
|
auto view = static_cast<D3D11ShaderResourceView*>(pShaderResourceView);
|
||||||
|
|
||||||
|
if (view->GetResourceType() != D3D11_RESOURCE_DIMENSION_BUFFER) {
|
||||||
|
m_context->generateMipmaps(
|
||||||
|
view->GetImageView()->image(),
|
||||||
|
view->GetImageView()->subresources());
|
||||||
|
} else {
|
||||||
|
Logger::err("D3D11DeviceContext: GenerateMips called on a buffer");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,6 +141,21 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cmdBlitImage(
|
||||||
|
VkImage srcImage,
|
||||||
|
VkImageLayout srcImageLayout,
|
||||||
|
VkImage dstImage,
|
||||||
|
VkImageLayout dstImageLayout,
|
||||||
|
uint32_t regionCount,
|
||||||
|
const VkImageBlit* pRegions,
|
||||||
|
VkFilter filter) {
|
||||||
|
m_vkd->vkCmdBlitImage(m_buffer,
|
||||||
|
srcImage, srcImageLayout,
|
||||||
|
dstImage, dstImageLayout,
|
||||||
|
regionCount, pRegions, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void cmdClearAttachments(
|
void cmdClearAttachments(
|
||||||
uint32_t attachmentCount,
|
uint32_t attachmentCount,
|
||||||
const VkClearAttachment* pAttachments,
|
const VkClearAttachment* pAttachments,
|
||||||
|
@ -610,6 +610,125 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkContext::generateMipmaps(
|
||||||
|
const Rc<DxvkImage>& image,
|
||||||
|
const VkImageSubresourceRange& subresources) {
|
||||||
|
if (subresources.levelCount <= 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// The top-most level will only be read. We can
|
||||||
|
// discard the contents of all the lower levels
|
||||||
|
// since we're going to override them anyway.
|
||||||
|
m_barriers.accessImage(image,
|
||||||
|
VkImageSubresourceRange {
|
||||||
|
subresources.aspectMask,
|
||||||
|
subresources.baseMipLevel, 1,
|
||||||
|
subresources.baseArrayLayer,
|
||||||
|
subresources.layerCount },
|
||||||
|
image->info().layout,
|
||||||
|
image->info().stages,
|
||||||
|
image->info().access,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
VK_ACCESS_TRANSFER_READ_BIT);
|
||||||
|
|
||||||
|
m_barriers.accessImage(image,
|
||||||
|
VkImageSubresourceRange {
|
||||||
|
subresources.aspectMask,
|
||||||
|
subresources.baseMipLevel + 1,
|
||||||
|
subresources.levelCount - 1,
|
||||||
|
subresources.baseArrayLayer,
|
||||||
|
subresources.layerCount },
|
||||||
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
image->info().stages,
|
||||||
|
image->info().access,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||||
|
|
||||||
|
m_barriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
|
// Generate each individual mip level with a blit
|
||||||
|
for (uint32_t i = 1; i < subresources.levelCount; i++) {
|
||||||
|
const uint32_t mip = subresources.baseMipLevel + i;
|
||||||
|
|
||||||
|
const VkExtent3D srcExtent = image->mipLevelExtent(mip - 1);
|
||||||
|
const VkExtent3D dstExtent = image->mipLevelExtent(mip);
|
||||||
|
|
||||||
|
VkImageBlit region;
|
||||||
|
region.srcSubresource = VkImageSubresourceLayers {
|
||||||
|
subresources.aspectMask, mip - 1,
|
||||||
|
subresources.baseArrayLayer,
|
||||||
|
subresources.layerCount };
|
||||||
|
region.srcOffsets[0] = VkOffset3D { 0, 0, 0 };
|
||||||
|
region.srcOffsets[1].x = srcExtent.width;
|
||||||
|
region.srcOffsets[1].y = srcExtent.height;
|
||||||
|
region.srcOffsets[1].z = srcExtent.depth;
|
||||||
|
|
||||||
|
region.dstSubresource = VkImageSubresourceLayers {
|
||||||
|
subresources.aspectMask, mip,
|
||||||
|
subresources.baseArrayLayer,
|
||||||
|
subresources.layerCount };
|
||||||
|
region.dstOffsets[0] = VkOffset3D { 0, 0, 0 };
|
||||||
|
region.dstOffsets[1].x = dstExtent.width;
|
||||||
|
region.dstOffsets[1].y = dstExtent.height;
|
||||||
|
region.dstOffsets[1].z = dstExtent.depth;
|
||||||
|
|
||||||
|
m_cmd->cmdBlitImage(
|
||||||
|
image->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||||
|
image->handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
1, ®ion, VK_FILTER_LINEAR);
|
||||||
|
|
||||||
|
if (i + 1 < subresources.levelCount) {
|
||||||
|
m_barriers.accessImage(image,
|
||||||
|
VkImageSubresourceRange {
|
||||||
|
subresources.aspectMask, mip, 1,
|
||||||
|
subresources.baseArrayLayer,
|
||||||
|
subresources.layerCount },
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
VK_ACCESS_TRANSFER_READ_BIT);
|
||||||
|
m_barriers.recordCommands(m_cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform mip levels back into their original layout.
|
||||||
|
// The last mip level is still in TRANSFER_DST_OPTIMAL.
|
||||||
|
m_barriers.accessImage(image,
|
||||||
|
VkImageSubresourceRange {
|
||||||
|
subresources.aspectMask,
|
||||||
|
subresources.baseMipLevel,
|
||||||
|
subresources.levelCount - 1,
|
||||||
|
subresources.baseArrayLayer,
|
||||||
|
subresources.layerCount },
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
VK_ACCESS_TRANSFER_READ_BIT,
|
||||||
|
image->info().layout,
|
||||||
|
image->info().stages,
|
||||||
|
image->info().access);
|
||||||
|
|
||||||
|
m_barriers.accessImage(image,
|
||||||
|
VkImageSubresourceRange {
|
||||||
|
subresources.aspectMask,
|
||||||
|
subresources.baseMipLevel
|
||||||
|
+ subresources.levelCount - 1, 1,
|
||||||
|
subresources.baseArrayLayer,
|
||||||
|
subresources.layerCount },
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
|
image->info().layout,
|
||||||
|
image->info().stages,
|
||||||
|
image->info().access);
|
||||||
|
|
||||||
|
m_barriers.recordCommands(m_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::invalidateBuffer(const Rc<DxvkBuffer>& buffer) {
|
void DxvkContext::invalidateBuffer(const Rc<DxvkBuffer>& buffer) {
|
||||||
// Allocate new backing resource
|
// Allocate new backing resource
|
||||||
buffer->rename(buffer->allocPhysicalSlice());
|
buffer->rename(buffer->allocPhysicalSlice());
|
||||||
|
@ -325,6 +325,18 @@ namespace dxvk {
|
|||||||
uint32_t count,
|
uint32_t count,
|
||||||
uint32_t stride);
|
uint32_t stride);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Generates mip maps
|
||||||
|
*
|
||||||
|
* Uses blitting to generate lower mip levels from
|
||||||
|
* the top-most mip level passed to this method.
|
||||||
|
* \param [in] image The image to generate mips for
|
||||||
|
* \param [in] subresource The subresource range
|
||||||
|
*/
|
||||||
|
void generateMipmaps(
|
||||||
|
const Rc<DxvkImage>& image,
|
||||||
|
const VkImageSubresourceRange& subresources);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initializes or invalidates an image
|
* \brief Initializes or invalidates an image
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user