mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 01:24:11 +01:00
[d3d11] Fixed mip-mapped texture creation
This commit is contained in:
parent
c0f5b46f81
commit
b4f85a2c2f
@ -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(
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user