[d3d11] Fixed mip-mapped texture creation

This commit is contained in:
Philip Rebohle 2017-12-10 19:10:17 +01:00
parent c0f5b46f81
commit b4f85a2c2f
5 changed files with 65 additions and 18 deletions

View File

@ -229,6 +229,9 @@ namespace dxvk {
if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE)
info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
if (pDesc->MipLevels == 0)
info.mipLevels = util::computeMipLevelCount(info.extent);
if (ppTexture2D != nullptr) {
Com<IDXGIImageResourcePrivate> image;
@ -1178,29 +1181,44 @@ namespace dxvk {
m_dxvkDevice->createCommandList());
const Rc<DxvkImage> image = pImage->GetDXVKImage();
VkImageSubresourceRange subresources;
subresources.aspectMask = imageFormatInfo(image->info().format)->aspectMask;
subresources.baseMipLevel = 0;
subresources.levelCount = image->info().mipLevels;
subresources.baseArrayLayer = 0;
subresources.layerCount = image->info().numLayers;
m_resourceInitContext->initImage(image, subresources);
const DxvkFormatInfo* formatInfo = imageFormatInfo(image->info().format);
if (pInitialData != nullptr) {
// pInitialData is an array that stores an entry for
// every single subresource. Since we will define all
// subresources, this counts as initialization.
VkImageSubresourceLayers subresourceLayers;
subresourceLayers.aspectMask = subresources.aspectMask;
subresourceLayers.aspectMask = formatInfo->aspectMask;
subresourceLayers.mipLevel = 0;
subresourceLayers.baseArrayLayer = 0;
subresourceLayers.layerCount = subresources.layerCount;
subresourceLayers.layerCount = 1;
m_resourceInitContext->updateImage(
image, subresourceLayers,
VkOffset3D { 0, 0, 0 },
image->info().extent,
pInitialData->pSysMem,
pInitialData->SysMemPitch,
pInitialData->SysMemSlicePitch);
for (uint32_t layer = 0; layer < image->info().numLayers; layer++) {
for (uint32_t level = 0; level < image->info().mipLevels; level++) {
subresourceLayers.baseArrayLayer = layer;
subresourceLayers.mipLevel = level;
const uint32_t id = D3D11CalcSubresource(
level, layer, image->info().mipLevels);
m_resourceInitContext->updateImage(
image, subresourceLayers,
VkOffset3D { 0, 0, 0 },
image->mipLevelExtent(level),
pInitialData[id].pSysMem,
pInitialData[id].SysMemPitch,
pInitialData[id].SysMemSlicePitch);
}
}
} else {
// Leave the image contents undefined
VkImageSubresourceRange subresources;
subresources.aspectMask = formatInfo->aspectMask;
subresources.baseMipLevel = 0;
subresources.levelCount = image->info().mipLevels;
subresources.baseArrayLayer = 0;
subresources.layerCount = image->info().numLayers;
m_resourceInitContext->initImage(image, subresources);
}
m_dxvkDevice->submitCommandList(

View File

@ -480,7 +480,7 @@ namespace dxvk {
m_barriers.accessImage(
image, subresourceRange,
image->info().extent == imageExtent
image->mipLevelExtent(subresources.mipLevel) == imageExtent
? VK_IMAGE_LAYOUT_UNDEFINED
: image->info().layout,
image->info().stages,

View File

@ -132,6 +132,14 @@ namespace dxvk {
return m_info;
}
VkExtent3D mipLevelExtent(uint32_t level) const {
VkExtent3D size = m_info.extent;
size.width = std::max(1u, size.width >> level);
size.height = std::max(1u, size.height >> level);
size.depth = std::max(1u, size.depth >> level);
return size;
}
private:
Rc<vk::DeviceFn> m_vkd;

View File

@ -20,6 +20,20 @@ namespace dxvk::util {
return result;
}
uint32_t computeMipLevelCount(VkExtent3D imageSize) {
uint32_t maxDim = std::max(imageSize.width, imageSize.height);
maxDim = std::max(imageSize.depth, maxDim);
uint32_t mipCnt = 0;
while (maxDim > 0) {
mipCnt += 1;
maxDim /= 2;
}
return mipCnt;
}
}
bool operator == (VkExtent3D a, VkExtent3D b) {

View File

@ -13,6 +13,13 @@ namespace dxvk::util {
VkPipelineStageFlags pipelineStages(
VkShaderStageFlags shaderStages);
/**
* \brief Computes number of mip levels for an image
*
* \param [in] imageSize Size of the image
* \returns Number of mipmap layers
*/
uint32_t computeMipLevelCount(VkExtent3D imageSize);
}