diff --git a/MarathonRecomp/gpu/video.cpp b/MarathonRecomp/gpu/video.cpp index 08c8c74e..145358ff 100644 --- a/MarathonRecomp/gpu/video.cpp +++ b/MarathonRecomp/gpu/video.cpp @@ -362,6 +362,10 @@ static std::unique_ptr g_copyQueue; static std::unique_ptr g_copyCommandList; static std::unique_ptr g_copyCommandFence; +static Mutex g_discardMutex; +static std::unique_ptr g_discardCommandList; +static std::unique_ptr g_discardCommandFence; + static std::unique_ptr g_swapChain; static bool g_swapChainValid; @@ -1913,22 +1917,9 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry) { bool redirectToVulkan = false; - if (deviceDescription.vendor == RenderDeviceVendor::AMD) - { - // AMD Drivers before this version have a known issue where MSAA resolve targets will fail to work correctly. - // If no specific graphics API was selected, we silently destroy this one and move to the next option as it'll - // just work incorrectly otherwise and result in visual glitches and 3D rendering not working in general. - constexpr uint64_t MinimumAMDDriverVersion = 0x1F00005DC2005CULL; // 31.0.24002.92 - if ((Config::GraphicsAPI == EGraphicsAPI::Auto) && (deviceDescription.driverVersion < MinimumAMDDriverVersion)) - redirectToVulkan = true; - } - else if (deviceDescription.vendor == RenderDeviceVendor::INTEL) - { - // Intel drivers on D3D12 are extremely buggy, introducing various graphical glitches. - // We will redirect users to Vulkan until a workaround can be found. - if (Config::GraphicsAPI == EGraphicsAPI::Auto) - redirectToVulkan = true; - } + // ... + // There used to be driver redirections here, but they are all free from Vulkan purgatory for now... + // ... if (redirectToVulkan) { @@ -2036,6 +2027,12 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry) g_copyCommandList = g_copyQueue->createCommandList(); g_copyCommandFence = g_device->createCommandFence(); + if (g_backend == Backend::D3D12) + { + g_discardCommandList = g_queue->createCommandList(); + g_discardCommandFence = g_device->createCommandFence(); + } + uint32_t bufferCount = 2; switch (Config::TripleBuffering) @@ -3400,6 +3397,27 @@ static RenderFormat ConvertFormat(uint32_t format) } } +static void DiscardTexture(GuestBaseTexture* texture, RenderTextureLayout layout) +{ + if (g_backend == Backend::D3D12) + { + std::lock_guard lock(g_discardMutex); + + g_discardCommandList->begin(); + if (texture->layout != layout) + { + g_discardCommandList->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(texture->texture, layout)); + texture->layout = layout; + } + + g_discardCommandList->discardTexture(texture->texture); + g_discardCommandList->end(); + + g_queue->executeCommandLists(g_discardCommandList.get(), g_discardCommandFence.get()); + g_queue->waitForCommandFence(g_discardCommandFence.get()); + } +} + static GuestTexture* CreateTexture(uint32_t width, uint32_t height, uint32_t depth, uint32_t levels, uint32_t usage, uint32_t format, uint32_t pool, uint32_t type) { ResourceType resourceType; @@ -3474,10 +3492,17 @@ static GuestTexture* CreateTexture(uint32_t width, uint32_t height, uint32_t dep texture->descriptorIndex = g_textureDescriptorAllocator.allocate(); g_textureDescriptorSet->setTexture(texture->descriptorIndex, texture->texture, RenderTextureLayout::SHADER_READ, texture->textureView.get()); - + #ifdef _DEBUG texture->texture->setName(fmt::format("Texture {:X}", g_memory.MapVirtual(texture))); #endif + + if (desc.flags != RenderTextureFlag::NONE) + { + DiscardTexture(texture, desc.flags == RenderTextureFlag::RENDER_TARGET ? + RenderTextureLayout::COLOR_WRITE : RenderTextureLayout::DEPTH_WRITE); + } + // printf("CreateTexture: w: %d, h: %d, depth: %d, levels: %d, usage: %d, format: %d, pool: %d, type: %d - %x\n", width, height, depth, levels, usage, format, pool, type, texture); return texture; } @@ -3573,6 +3598,10 @@ static GuestSurface* CreateSurface(uint32_t width, uint32_t height, uint32_t for #ifdef _DEBUG surface->texture->setName(fmt::format("{} {:X}", desc.flags & RenderTextureFlag::RENDER_TARGET ? "Render Target" : "Depth Stencil", g_memory.MapVirtual(surface))); #endif + + DiscardTexture(surface, desc.flags == RenderTextureFlag::RENDER_TARGET ? + RenderTextureLayout::COLOR_WRITE : RenderTextureLayout::DEPTH_WRITE); + if (params) { surface->wasCached = true; g_surfaceCache.emplace_back(surface, baseValue);