mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-11 04:29:15 +01:00
[d3d11] Handle MAP_MODE_STAGING in initializer
Otherwise, we'll crash if no real image is present.
This commit is contained in:
parent
596f65f75f
commit
731e88b196
@ -122,89 +122,94 @@ namespace dxvk {
|
||||
|
||||
Rc<DxvkImage> image = pTexture->GetImage();
|
||||
|
||||
VkFormat packedFormat = m_parent->LookupPackedFormat(
|
||||
pTexture->Desc()->Format, pTexture->GetFormatMode()).Format;
|
||||
|
||||
auto formatInfo = imageFormatInfo(image->info().format);
|
||||
auto mapMode = pTexture->GetMapMode();
|
||||
auto desc = pTexture->Desc();
|
||||
|
||||
VkFormat packedFormat = m_parent->LookupPackedFormat(desc->Format, pTexture->GetFormatMode()).Format;
|
||||
auto formatInfo = imageFormatInfo(packedFormat);
|
||||
|
||||
if (pInitialData != nullptr && pInitialData->pSysMem != nullptr) {
|
||||
// pInitialData is an array that stores an entry for
|
||||
// every single subresource. Since we will define all
|
||||
// subresources, this counts as initialization.
|
||||
for (uint32_t layer = 0; layer < image->info().numLayers; layer++) {
|
||||
for (uint32_t level = 0; level < image->info().mipLevels; level++) {
|
||||
VkImageSubresourceLayers subresourceLayers;
|
||||
subresourceLayers.aspectMask = formatInfo->aspectMask;
|
||||
subresourceLayers.mipLevel = level;
|
||||
subresourceLayers.baseArrayLayer = layer;
|
||||
subresourceLayers.layerCount = 1;
|
||||
|
||||
for (uint32_t layer = 0; layer < desc->ArraySize; layer++) {
|
||||
for (uint32_t level = 0; level < desc->MipLevels; level++) {
|
||||
const uint32_t id = D3D11CalcSubresource(
|
||||
level, layer, image->info().mipLevels);
|
||||
level, layer, desc->MipLevels);
|
||||
|
||||
VkOffset3D mipLevelOffset = { 0, 0, 0 };
|
||||
VkExtent3D mipLevelExtent = image->mipLevelExtent(level);
|
||||
VkExtent3D mipLevelExtent = pTexture->MipLevelExtent(level);
|
||||
|
||||
m_transferCommands += 1;
|
||||
m_transferMemory += pTexture->GetSubresourceLayout(formatInfo->aspectMask, id).Size;
|
||||
|
||||
if (formatInfo->aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||
m_context->uploadImage(
|
||||
image, subresourceLayers,
|
||||
pInitialData[id].pSysMem,
|
||||
pInitialData[id].SysMemPitch,
|
||||
pInitialData[id].SysMemSlicePitch);
|
||||
} else {
|
||||
m_context->updateDepthStencilImage(
|
||||
image, subresourceLayers,
|
||||
VkOffset2D { mipLevelOffset.x, mipLevelOffset.y },
|
||||
VkExtent2D { mipLevelExtent.width, mipLevelExtent.height },
|
||||
pInitialData[id].pSysMem,
|
||||
pInitialData[id].SysMemPitch,
|
||||
pInitialData[id].SysMemSlicePitch,
|
||||
packedFormat);
|
||||
if (mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING) {
|
||||
m_transferCommands += 1;
|
||||
m_transferMemory += pTexture->GetSubresourceLayout(formatInfo->aspectMask, id).Size;
|
||||
|
||||
VkImageSubresourceLayers subresourceLayers;
|
||||
subresourceLayers.aspectMask = formatInfo->aspectMask;
|
||||
subresourceLayers.mipLevel = level;
|
||||
subresourceLayers.baseArrayLayer = layer;
|
||||
subresourceLayers.layerCount = 1;
|
||||
|
||||
if (formatInfo->aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||
m_context->uploadImage(
|
||||
image, subresourceLayers,
|
||||
pInitialData[id].pSysMem,
|
||||
pInitialData[id].SysMemPitch,
|
||||
pInitialData[id].SysMemSlicePitch);
|
||||
} else {
|
||||
m_context->updateDepthStencilImage(
|
||||
image, subresourceLayers,
|
||||
VkOffset2D { mipLevelOffset.x, mipLevelOffset.y },
|
||||
VkExtent2D { mipLevelExtent.width, mipLevelExtent.height },
|
||||
pInitialData[id].pSysMem,
|
||||
pInitialData[id].SysMemPitch,
|
||||
pInitialData[id].SysMemSlicePitch,
|
||||
packedFormat);
|
||||
}
|
||||
}
|
||||
|
||||
if (pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) {
|
||||
if (mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_NONE) {
|
||||
util::packImageData(pTexture->GetMappedBuffer(id)->mapPtr(0),
|
||||
pInitialData[id].pSysMem, pInitialData[id].SysMemPitch, pInitialData[id].SysMemSlicePitch,
|
||||
image->info().type, mipLevelExtent, 1, formatInfo, formatInfo->aspectMask);
|
||||
pTexture->GetVkImageType(), mipLevelExtent, 1, formatInfo, formatInfo->aspectMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_transferCommands += 1;
|
||||
|
||||
// While the Microsoft docs state that resource contents are
|
||||
// undefined if no initial data is provided, some applications
|
||||
// expect a resource to be pre-cleared. We can only do that
|
||||
// for non-compressed images, but that should be fine.
|
||||
VkImageSubresourceRange subresources;
|
||||
subresources.aspectMask = formatInfo->aspectMask;
|
||||
subresources.baseMipLevel = 0;
|
||||
subresources.levelCount = image->info().mipLevels;
|
||||
subresources.baseArrayLayer = 0;
|
||||
subresources.layerCount = image->info().numLayers;
|
||||
if (mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING) {
|
||||
m_transferCommands += 1;
|
||||
|
||||
// While the Microsoft docs state that resource contents are
|
||||
// undefined if no initial data is provided, some applications
|
||||
// expect a resource to be pre-cleared. We can only do that
|
||||
// for non-compressed images, but that should be fine.
|
||||
VkImageSubresourceRange subresources;
|
||||
subresources.aspectMask = formatInfo->aspectMask;
|
||||
subresources.baseMipLevel = 0;
|
||||
subresources.levelCount = desc->MipLevels;
|
||||
subresources.baseArrayLayer = 0;
|
||||
subresources.layerCount = desc->ArraySize;
|
||||
|
||||
if (formatInfo->flags.any(DxvkFormatFlag::BlockCompressed, DxvkFormatFlag::MultiPlane)) {
|
||||
m_context->clearCompressedColorImage(image, subresources);
|
||||
} else {
|
||||
if (subresources.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
|
||||
VkClearColorValue value = { };
|
||||
|
||||
m_context->clearColorImage(
|
||||
image, value, subresources);
|
||||
if (formatInfo->flags.any(DxvkFormatFlag::BlockCompressed, DxvkFormatFlag::MultiPlane)) {
|
||||
m_context->clearCompressedColorImage(image, subresources);
|
||||
} else {
|
||||
VkClearDepthStencilValue value;
|
||||
value.depth = 0.0f;
|
||||
value.stencil = 0;
|
||||
|
||||
m_context->clearDepthStencilImage(
|
||||
image, value, subresources);
|
||||
if (subresources.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
|
||||
VkClearColorValue value = { };
|
||||
|
||||
m_context->clearColorImage(
|
||||
image, value, subresources);
|
||||
} else {
|
||||
VkClearDepthStencilValue value;
|
||||
value.depth = 0.0f;
|
||||
value.stencil = 0;
|
||||
|
||||
m_context->clearDepthStencilImage(
|
||||
image, value, subresources);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pTexture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_NONE) {
|
||||
if (mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_NONE) {
|
||||
for (uint32_t i = 0; i < pTexture->CountSubresources(); i++) {
|
||||
auto buffer = pTexture->GetMappedBuffer(i);
|
||||
std::memset(buffer->mapPtr(0), 0, buffer->info().size);
|
||||
|
@ -18,7 +18,7 @@ namespace dxvk {
|
||||
m_packedFormat = formatPacked.Format;
|
||||
|
||||
DxvkImageCreateInfo imageInfo;
|
||||
imageInfo.type = GetImageTypeFromResourceDim(Dimension);
|
||||
imageInfo.type = GetVkImageType();
|
||||
imageInfo.format = formatInfo.Format;
|
||||
imageInfo.flags = 0;
|
||||
imageInfo.sampleCount = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
@ -91,6 +91,17 @@ namespace dxvk {
|
||||
return &m_desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves Vulkan image type
|
||||
*
|
||||
* Returns the image type based on the D3D11 resource
|
||||
* dimension. Also works if there is no actual image.
|
||||
* \returns Vulkan image type
|
||||
*/
|
||||
VkImageType GetVkImageType() const {
|
||||
return GetImageTypeFromResourceDim(m_dimension);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Computes extent of a given mip level
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user