diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index b6b0ca4bd..4fc1f46ed 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -237,45 +237,32 @@ bool PipelineCache::RefreshGraphicsKey() { const bool skip_cb_binding = regs.color_control.mode == AmdGpu::Liverpool::ColorControl::OperationMode::Disable; - const auto& BindColorBuffers = [&](u32 mrt_mask) { - // `RenderingInfo` is assumed to be initialized with a contiguous array of valid color - // attachments. This might be not a case as HW color buffers can be bound in an arbitrary - // order. We need to do some arrays compaction at this stage - key.color_formats.fill(vk::Format::eUndefined); - key.blend_controls.fill({}); - key.write_masks.fill({}); - key.mrt_swizzles.fill(Liverpool::ColorBuffer::SwapMode::Standard); + // `RenderingInfo` is assumed to be initialized with a contiguous array of valid color + // attachments. This might be not a case as HW color buffers can be bound in an arbitrary + // order. We need to do some arrays compaction at this stage + key.color_formats.fill(vk::Format::eUndefined); + key.blend_controls.fill({}); + key.write_masks.fill({}); + key.mrt_swizzles.fill(Liverpool::ColorBuffer::SwapMode::Standard); - int remapped_cb{}; - for (auto cb = 0u; cb < Liverpool::NumColorBuffers; ++cb) { - auto const& col_buf = regs.color_buffers[cb]; - if (skip_cb_binding || !col_buf || !regs.color_target_mask.GetMask(cb)) { - continue; - } - if ((mrt_mask & (1u << cb)) == 0) { - continue; - } - const auto base_format = - LiverpoolToVK::SurfaceFormat(col_buf.info.format, col_buf.NumFormat()); - const bool is_vo_surface = renderer->IsVideoOutSurface(col_buf); - key.color_formats[remapped_cb] = LiverpoolToVK::AdjustColorBufferFormat( - base_format, col_buf.info.comp_swap.Value(), false /*is_vo_surface*/); - if (base_format == key.color_formats[remapped_cb]) { - key.mrt_swizzles[remapped_cb] = col_buf.info.comp_swap.Value(); - } - key.blend_controls[remapped_cb] = regs.blend_control[cb]; - key.blend_controls[remapped_cb].enable.Assign(key.blend_controls[remapped_cb].enable && - !col_buf.info.blend_bypass); - key.write_masks[remapped_cb] = - vk::ColorComponentFlags{regs.color_target_mask.GetMask(cb)}; - key.cb_shader_mask.SetMask(remapped_cb, regs.color_shader_mask.GetMask(cb)); - - ++remapped_cb; + // First pass of bindings check to idenitfy formats and swizzles and pass them to rhe shader + // recompiler. + for (auto cb = 0u, remapped_cb = 0u; cb < Liverpool::NumColorBuffers; ++cb) { + auto const& col_buf = regs.color_buffers[cb]; + if (skip_cb_binding || !col_buf || !regs.color_target_mask.GetMask(cb)) { + continue; + } + const auto base_format = + LiverpoolToVK::SurfaceFormat(col_buf.info.format, col_buf.NumFormat()); + const bool is_vo_surface = renderer->IsVideoOutSurface(col_buf); + key.color_formats[remapped_cb] = LiverpoolToVK::AdjustColorBufferFormat( + base_format, col_buf.info.comp_swap.Value(), false /*is_vo_surface*/); + if (base_format == key.color_formats[remapped_cb]) { + key.mrt_swizzles[remapped_cb] = col_buf.info.comp_swap.Value(); } - }; - // We need to run CB binding twice as actual MRT exports are unknown before FS is compiled. - BindColorBuffers(0xff); + ++remapped_cb; + } u32 binding{}; for (u32 i = 0; i < MaxShaderStages; i++) { @@ -322,8 +309,25 @@ bool PipelineCache::RefreshGraphicsKey() { const auto* fs_info = infos[u32(Shader::Stage::Fragment)]; key.mrt_mask = fs_info ? fs_info->mrt_mask : 0u; - BindColorBuffers(key.mrt_mask); + // Second pass to fill remain CB pipeline key data + for (auto cb = 0u, remapped_cb = 0u; cb < Liverpool::NumColorBuffers; ++cb) { + auto const& col_buf = regs.color_buffers[cb]; + if (skip_cb_binding || !col_buf || !regs.color_target_mask.GetMask(cb) || + (key.mrt_mask & (1u << cb)) == 0) { + key.color_formats[cb] = vk::Format::eUndefined; + key.mrt_swizzles[cb] = Liverpool::ColorBuffer::SwapMode::Standard; + continue; + } + + key.blend_controls[remapped_cb] = regs.blend_control[cb]; + key.blend_controls[remapped_cb].enable.Assign(key.blend_controls[remapped_cb].enable && + !col_buf.info.blend_bypass); + key.write_masks[remapped_cb] = vk::ColorComponentFlags{regs.color_target_mask.GetMask(cb)}; + key.cb_shader_mask.SetMask(remapped_cb, regs.color_shader_mask.GetMask(cb)); + + ++remapped_cb; + } return true; } diff --git a/src/video_core/texture_cache/image.cpp b/src/video_core/texture_cache/image.cpp index 5c8bf54f4..4ce6e1eea 100644 --- a/src/video_core/texture_cache/image.cpp +++ b/src/video_core/texture_cache/image.cpp @@ -213,7 +213,9 @@ boost::container::small_vector Image::GetBarriers( for (u32 layer : layers) { // NOTE: these loops may produce a lot of small barriers. // If this becomes a problem, we can optimize it by merging adjacent barriers. - auto& state = subresource_states[mip * info.resources.layers + layer]; + const auto subres_idx = mip * info.resources.layers + layer; + ASSERT(subres_idx < subresource_states.size()); + auto& state = subresource_states[subres_idx]; if (state.layout != dst_layout || state.access_mask != dst_mask) { barriers.emplace_back(vk::ImageMemoryBarrier2{ diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp index ef402ecc4..dfa1bab64 100644 --- a/src/video_core/texture_cache/texture_cache.cpp +++ b/src/video_core/texture_cache/texture_cache.cpp @@ -87,8 +87,7 @@ ImageId TextureCache::ResolveDepthOverlap(const ImageInfo& requested_info, Image auto new_image_id = slot_images.insert(instance, scheduler, requested_info); RegisterImage(new_image_id); - // auto& new_image = slot_images[new_image_id]; - // TODO: need to run a helper for depth copy here + // TODO: perform a depth copy here FreeImage(cache_image_id); return new_image_id; @@ -98,7 +97,11 @@ ImageId TextureCache::ResolveDepthOverlap(const ImageInfo& requested_info, Image !requested_info.usage.depth_target && (requested_info.usage.texture || requested_info.usage.storage); if (cache_info.usage.depth_target && should_bind_as_texture) { - return cache_image_id; + if (cache_info.resources == requested_info.resources) { + return cache_image_id; + } else { + UNREACHABLE(); + } } return {};