mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-28 12:04:19 +01:00
Vulkan: Avoid calling vkCmdClearColorImage() on compressed textures
This is not allowed according to the spec and can crash drivers. Fixes #1100
This commit is contained in:
parent
b8d81283e8
commit
9f9bc9865f
@ -1412,8 +1412,7 @@ bool VulkanRenderer::IsSwapchainInfoValid(bool mainWindow) const
|
|||||||
|
|
||||||
void VulkanRenderer::CreateNullTexture(NullTexture& nullTex, VkImageType imageType)
|
void VulkanRenderer::CreateNullTexture(NullTexture& nullTex, VkImageType imageType)
|
||||||
{
|
{
|
||||||
// these are used when the game requests NULL ptr textures or buffers
|
// these are used when the game requests NULL ptr textures
|
||||||
// texture
|
|
||||||
VkImageCreateInfo imageInfo{};
|
VkImageCreateInfo imageInfo{};
|
||||||
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
if (imageType == VK_IMAGE_TYPE_1D)
|
if (imageType == VK_IMAGE_TYPE_1D)
|
||||||
@ -2818,6 +2817,35 @@ void VulkanRenderer::ClearColorImageRaw(VkImage image, uint32 sliceIndex, uint32
|
|||||||
|
|
||||||
void VulkanRenderer::ClearColorImage(LatteTextureVk* vkTexture, uint32 sliceIndex, uint32 mipIndex, const VkClearColorValue& color, VkImageLayout outputLayout)
|
void VulkanRenderer::ClearColorImage(LatteTextureVk* vkTexture, uint32 sliceIndex, uint32 mipIndex, const VkClearColorValue& color, VkImageLayout outputLayout)
|
||||||
{
|
{
|
||||||
|
if(vkTexture->isDepth)
|
||||||
|
{
|
||||||
|
cemu_assert_suspicious();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (vkTexture->IsCompressedFormat())
|
||||||
|
{
|
||||||
|
// vkCmdClearColorImage cannot be called on compressed formats
|
||||||
|
// for now we ignore affected clears but still transition the image to the correct layout
|
||||||
|
auto imageObj = vkTexture->GetImageObj();
|
||||||
|
imageObj->flagForCurrentCommandBuffer();
|
||||||
|
VkImageSubresourceLayers subresourceRange{};
|
||||||
|
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
subresourceRange.mipLevel = mipIndex;
|
||||||
|
subresourceRange.baseArrayLayer = sliceIndex;
|
||||||
|
subresourceRange.layerCount = 1;
|
||||||
|
barrier_image<ANY_TRANSFER | IMAGE_READ, ANY_TRANSFER | IMAGE_READ | IMAGE_WRITE>(vkTexture, subresourceRange, outputLayout);
|
||||||
|
if(color.float32[0] == 0.0f && color.float32[1] == 0.0f && color.float32[2] == 0.0f && color.float32[3] == 0.0f)
|
||||||
|
{
|
||||||
|
static bool dbgMsgPrinted = false;
|
||||||
|
if(!dbgMsgPrinted)
|
||||||
|
{
|
||||||
|
cemuLog_logDebug(LogType::Force, "Unsupported compressed texture clear to zero");
|
||||||
|
dbgMsgPrinted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
VkImageSubresourceRange subresourceRange;
|
VkImageSubresourceRange subresourceRange;
|
||||||
|
|
||||||
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
@ -3154,32 +3182,18 @@ void VulkanRenderer::texture_clearSlice(LatteTexture* hostTexture, sint32 sliceI
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
cemu_assert_debug(vkTexture->dim != Latte::E_DIM::DIM_3D);
|
cemu_assert_debug(vkTexture->dim != Latte::E_DIM::DIM_3D);
|
||||||
if (hostTexture->IsCompressedFormat())
|
ClearColorImage(vkTexture, sliceIndex, mipIndex, { 0,0,0,0 }, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
{
|
|
||||||
auto imageObj = vkTexture->GetImageObj();
|
|
||||||
imageObj->flagForCurrentCommandBuffer();
|
|
||||||
|
|
||||||
cemuLog_logDebug(LogType::Force, "Compressed texture ({}/{} fmt {:04x}) unsupported clear", vkTexture->width, vkTexture->height, (uint32)vkTexture->format);
|
|
||||||
|
|
||||||
VkImageSubresourceLayers subresourceRange{};
|
|
||||||
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
subresourceRange.mipLevel = mipIndex;
|
|
||||||
subresourceRange.baseArrayLayer = sliceIndex;
|
|
||||||
subresourceRange.layerCount = 1;
|
|
||||||
barrier_image<ANY_TRANSFER | IMAGE_READ, ANY_TRANSFER | IMAGE_READ | IMAGE_WRITE>(vkTexture, subresourceRange, VK_IMAGE_LAYOUT_GENERAL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ClearColorImage(vkTexture, sliceIndex, mipIndex, { 0,0,0,0 }, VK_IMAGE_LAYOUT_GENERAL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderer::texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a)
|
void VulkanRenderer::texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a)
|
||||||
{
|
{
|
||||||
auto vkTexture = (LatteTextureVk*)hostTexture;
|
auto vkTexture = (LatteTextureVk*)hostTexture;
|
||||||
cemu_assert_debug(vkTexture->dim != Latte::E_DIM::DIM_3D);
|
if(vkTexture->dim == Latte::E_DIM::DIM_3D)
|
||||||
ClearColorImage(vkTexture, sliceIndex, mipIndex, { r,g,b,a }, VK_IMAGE_LAYOUT_GENERAL);
|
{
|
||||||
|
cemu_assert_unimplemented();
|
||||||
|
}
|
||||||
|
ClearColorImage(vkTexture, sliceIndex, mipIndex, {r, g, b, a}, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sliceIndex, sint32 mipIndex, bool clearDepth, bool clearStencil, float depthValue, uint32 stencilValue)
|
void VulkanRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sliceIndex, sint32 mipIndex, bool clearDepth, bool clearStencil, float depthValue, uint32 stencilValue)
|
||||||
|
@ -130,7 +130,6 @@ class VulkanRenderer : public Renderer
|
|||||||
using QueueFamilyIndices = SwapchainInfoVk::QueueFamilyIndices;
|
using QueueFamilyIndices = SwapchainInfoVk::QueueFamilyIndices;
|
||||||
|
|
||||||
static const inline int UNIFORMVAR_RINGBUFFER_SIZE = 1024 * 1024 * 16; // 16MB
|
static const inline int UNIFORMVAR_RINGBUFFER_SIZE = 1024 * 1024 * 16; // 16MB
|
||||||
static const inline int INDEX_STREAM_BUFFER_SIZE = 16 * 1024 * 1024; // 16 MB
|
|
||||||
|
|
||||||
static const inline int TEXTURE_READBACK_SIZE = 32 * 1024 * 1024; // 32 MB
|
static const inline int TEXTURE_READBACK_SIZE = 32 * 1024 * 1024; // 32 MB
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user