diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index 09c006dc72..c9117c6273 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -1049,8 +1049,9 @@ void GPU_HW::DestroyPipelines() void GPU_HW::UpdateVRAMReadTexture() { - const auto scaled_rect = m_vram_dirty_rect * m_resolution_scale; + GL_SCOPE("UpdateVRAMReadTexture()"); + const auto scaled_rect = m_vram_dirty_rect * m_resolution_scale; if (m_vram_texture->IsMultisampled()) { if (g_gpu_device->GetFeatures().partial_msaa_resolve) diff --git a/src/util/opengl_device.cpp b/src/util/opengl_device.cpp index 2bb6e785ef..4ded4c1801 100644 --- a/src/util/opengl_device.cpp +++ b/src/util/opengl_device.cpp @@ -348,9 +348,9 @@ bool OpenGLDevice::CheckFeatures(bool* buggy_pbo) { const bool is_gles = m_gl_context->IsGLES(); - // bool vendor_id_amd = false; - // bool vendor_id_nvidia = false; - // bool vendor_id_intel = false; + bool vendor_id_amd = false; + //bool vendor_id_nvidia = false; + bool vendor_id_intel = false; bool vendor_id_arm = false; bool vendor_id_qualcomm = false; bool vendor_id_powervr = false; @@ -361,7 +361,7 @@ bool OpenGLDevice::CheckFeatures(bool* buggy_pbo) std::strstr(vendor, "ATI")) { Log_InfoPrint("AMD GPU detected."); - // vendor_id_amd = true; + vendor_id_amd = true; } else if (std::strstr(vendor, "NVIDIA Corporation")) { @@ -371,7 +371,7 @@ bool OpenGLDevice::CheckFeatures(bool* buggy_pbo) else if (std::strstr(vendor, "Intel")) { Log_InfoPrint("Intel GPU detected."); - // vendor_id_intel = true; + vendor_id_intel = true; } else if (std::strstr(vendor, "ARM")) { @@ -452,7 +452,10 @@ bool OpenGLDevice::CheckFeatures(bool* buggy_pbo) } } - m_features.per_sample_shading = GLAD_GL_VERSION_4_0 || GLAD_GL_ES_VERSION_3_2 || GLAD_GL_ARB_sample_shading; + // Sample rate shading is broken on AMD and Intel. + // If AMD and Intel can't get it right, I very much doubt broken mobile drivers can. + m_features.per_sample_shading = (GLAD_GL_VERSION_4_0 || GLAD_GL_ES_VERSION_3_2 || GLAD_GL_ARB_sample_shading) && + (!vendor_id_amd && !vendor_id_intel && !is_shitty_mobile_driver); // noperspective is not supported in GLSL ES. m_features.noperspective_interpolation = !is_gles; diff --git a/src/util/vulkan_device.cpp b/src/util/vulkan_device.cpp index a26d452729..eace049ff8 100644 --- a/src/util/vulkan_device.cpp +++ b/src/util/vulkan_device.cpp @@ -365,6 +365,7 @@ bool VulkanDevice::SelectDeviceFeatures() m_device_features.largePoints = available_features.largePoints; m_device_features.wideLines = available_features.wideLines; m_device_features.samplerAnisotropy = available_features.samplerAnisotropy; + m_device_features.sampleRateShading = available_features.sampleRateShading; return true; } @@ -2208,7 +2209,7 @@ bool VulkanDevice::CheckFeatures() Log_WarningPrintf("Vulkan driver is missing dual-source blending. This will have an impact on performance."); m_features.noperspective_interpolation = true; - m_features.per_sample_shading = true; + m_features.per_sample_shading = m_device_features.sampleRateShading; m_features.supports_texture_buffers = true; #ifdef __APPLE__ @@ -2326,12 +2327,19 @@ void VulkanDevice::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u VulkanTexture* S = static_cast(src); const VkCommandBuffer cmdbuf = GetCurrentCommandBuffer(); - S->CommitClear(cmdbuf); - D->CommitClear(cmdbuf); + if (S->GetState() == GPUTexture::State::Cleared) + S->CommitClear(cmdbuf); + if (D->IsRenderTargetOrDepthStencil() && D->GetState() == GPUTexture::State::Cleared) + { + if (width < dst->GetWidth() || height < dst->GetHeight()) + D->CommitClear(cmdbuf); + else + D->SetState(GPUTexture::State::Dirty); + } S->TransitionSubresourcesToLayout(cmdbuf, 0, 1, 0, 1, S->GetLayout(), VulkanTexture::Layout::TransferSrc); D->TransitionSubresourcesToLayout(cmdbuf, dst_layer, 1, dst_level, 1, D->GetLayout(), - VulkanTexture::Layout::TransferSrc); + VulkanTexture::Layout::TransferDst); const VkImageResolve resolve = {{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u}, {static_cast(src_x), static_cast(src_y), 0}, @@ -2342,7 +2350,7 @@ void VulkanDevice::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve); S->TransitionSubresourcesToLayout(cmdbuf, 0, 1, 0, 1, VulkanTexture::Layout::TransferSrc, S->GetLayout()); - D->TransitionSubresourcesToLayout(cmdbuf, dst_layer, 1, dst_level, 1, VulkanTexture::Layout::TransferSrc, + D->TransitionSubresourcesToLayout(cmdbuf, dst_layer, 1, dst_level, 1, VulkanTexture::Layout::TransferDst, D->GetLayout()); } diff --git a/src/util/vulkan_texture.cpp b/src/util/vulkan_texture.cpp index e557cafa3a..85bba82522 100644 --- a/src/util/vulkan_texture.cpp +++ b/src/util/vulkan_texture.cpp @@ -71,9 +71,9 @@ std::unique_ptr VulkanTexture::Create(u32 width, u32 height, u32 0, VK_IMAGE_TYPE_2D, vk_format, - {static_cast(width), static_cast(height), 1}, - static_cast(levels), - 1, + {width, height, 1u}, + levels, + layers, static_cast(samples), VK_IMAGE_TILING_OPTIMAL}; @@ -336,7 +336,7 @@ bool VulkanTexture::Update(u32 x, u32 y, u32 width, u32 height, const void* data // if we're an rt and have been cleared, and the full rect isn't being uploaded, do the clear if (m_type == Type::RenderTarget) { - if (x != 0 || y != 0 || width != m_width || height != m_height) + if (m_state == State::Cleared && (x != 0 || y != 0 || width != m_width || height != m_height)) CommitClear(cmdbuf); else m_state = State::Dirty; @@ -979,7 +979,8 @@ std::unique_ptr VulkanDevice::CreateFramebuffer(GPUTexture* rt_o const VkRenderPass render_pass = GetRenderPass(RT ? RT->GetVkFormat() : VK_FORMAT_UNDEFINED, DS ? DS->GetVkFormat() : VK_FORMAT_UNDEFINED, - VK_SAMPLE_COUNT_1_BIT, RT ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE, + static_cast(RT ? RT->GetSamples() : DS->GetSamples()), + RT ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE, RT ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE, DS ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_DONT_CARE, DS ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE);