aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h6
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp88
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h1
-rw-r--r--src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp6
8 files changed, 63 insertions, 54 deletions
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
index 59e963263..f93447610 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
@@ -257,6 +257,8 @@ vk::ShaderStageFlagBits ShaderStage(Tegra::Engines::ShaderType stage) {
return vk::ShaderStageFlagBits::eGeometry;
case Tegra::Engines::ShaderType::Fragment:
return vk::ShaderStageFlagBits::eFragment;
+ case Tegra::Engines::ShaderType::Compute:
+ return vk::ShaderStageFlagBits::eCompute;
}
UNIMPLEMENTED_MSG("Unimplemented shader stage={}", static_cast<u32>(stage));
return {};
@@ -367,6 +369,10 @@ vk::Format VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttr
return vk::Format::eR8G8B8A8Uint;
case Maxwell::VertexAttribute::Size::Size_32:
return vk::Format::eR32Uint;
+ case Maxwell::VertexAttribute::Size::Size_32_32:
+ return vk::Format::eR32G32Uint;
+ case Maxwell::VertexAttribute::Size::Size_32_32_32:
+ return vk::Format::eR32G32B32Uint;
case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
return vk::Format::eR32G32B32A32Uint;
default:
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 056ef495c..557b9d662 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -179,10 +179,11 @@ Tegra::Engines::ConstBufferEngineInterface& CachedShader::GetEngine(
VKPipelineCache::VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer,
const VKDevice& device, VKScheduler& scheduler,
VKDescriptorPool& descriptor_pool,
- VKUpdateDescriptorQueue& update_descriptor_queue)
+ VKUpdateDescriptorQueue& update_descriptor_queue,
+ VKRenderPassCache& renderpass_cache)
: RasterizerCache{rasterizer}, system{system}, device{device}, scheduler{scheduler},
descriptor_pool{descriptor_pool}, update_descriptor_queue{update_descriptor_queue},
- renderpass_cache(device) {}
+ renderpass_cache{renderpass_cache} {}
VKPipelineCache::~VKPipelineCache() = default;
@@ -191,7 +192,6 @@ std::array<Shader, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() {
std::array<Shader, Maxwell::MaxShaderProgram> shaders;
for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
- const auto& shader_config = gpu.regs.shader_config[index];
const auto program{static_cast<Maxwell::ShaderProgram>(index)};
// Skip stages that are not enabled
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
index 21340c9a4..c4c112290 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
@@ -161,7 +161,8 @@ public:
explicit VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer,
const VKDevice& device, VKScheduler& scheduler,
VKDescriptorPool& descriptor_pool,
- VKUpdateDescriptorQueue& update_descriptor_queue);
+ VKUpdateDescriptorQueue& update_descriptor_queue,
+ VKRenderPassCache& renderpass_cache);
~VKPipelineCache();
std::array<Shader, Maxwell::MaxShaderProgram> GetShaders();
@@ -184,8 +185,7 @@ private:
VKScheduler& scheduler;
VKDescriptorPool& descriptor_pool;
VKUpdateDescriptorQueue& update_descriptor_queue;
-
- VKRenderPassCache renderpass_cache;
+ VKRenderPassCache& renderpass_cache;
std::array<Shader, Maxwell::MaxShaderProgram> last_shaders;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index c9886cc16..58c69b786 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -287,12 +287,13 @@ RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWind
screen_info{screen_info}, device{device}, resource_manager{resource_manager},
memory_manager{memory_manager}, state_tracker{state_tracker}, scheduler{scheduler},
staging_pool(device, memory_manager, scheduler), descriptor_pool(device),
- update_descriptor_queue(device, scheduler),
+ update_descriptor_queue(device, scheduler), renderpass_cache(device),
quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),
uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),
texture_cache(system, *this, device, resource_manager, memory_manager, scheduler,
staging_pool),
- pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue),
+ pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue,
+ renderpass_cache),
buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool),
sampler_cache(device), query_cache(system, *this, device, scheduler) {
scheduler.SetQueryCache(query_cache);
@@ -365,13 +366,16 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
void RasterizerVulkan::Clear() {
MICROPROFILE_SCOPE(Vulkan_Clearing);
- query_cache.UpdateCounters();
-
const auto& gpu = system.GPU().Maxwell3D();
if (!system.GPU().Maxwell3D().ShouldExecute()) {
return;
}
+ sampled_views.clear();
+ image_views.clear();
+
+ query_cache.UpdateCounters();
+
const auto& regs = gpu.regs;
const bool use_color = regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
regs.clear_buffers.A;
@@ -380,52 +384,54 @@ void RasterizerVulkan::Clear() {
if (!use_color && !use_depth && !use_stencil) {
return;
}
- // Clearing images requires to be out of a renderpass
- scheduler.RequestOutsideRenderPassOperationContext();
- // TODO(Rodrigo): Implement clears rendering a quad or using beginning a renderpass.
+ [[maybe_unused]] const auto texceptions = UpdateAttachments();
+ DEBUG_ASSERT(texceptions.none());
+ SetupImageTransitions(0, color_attachments, zeta_attachment);
- if (use_color) {
- View color_view;
- {
- MICROPROFILE_SCOPE(Vulkan_RenderTargets);
- color_view = texture_cache.GetColorBufferSurface(regs.clear_buffers.RT.Value(), false);
- }
+ const vk::RenderPass renderpass = renderpass_cache.GetRenderPass(GetRenderPassParams(0));
+ const auto [framebuffer, render_area] = ConfigureFramebuffers(renderpass);
+ scheduler.RequestRenderpass({renderpass, framebuffer, {{0, 0}, render_area}, 0, nullptr});
+
+ const auto& scissor = regs.scissor_test[0];
+ const vk::Offset2D scissor_offset(scissor.min_x, scissor.min_y);
+ vk::Extent2D scissor_extent{scissor.max_x - scissor.min_x, scissor.max_y - scissor.min_y};
+ scissor_extent.width = std::min(scissor_extent.width, render_area.width);
+ scissor_extent.height = std::min(scissor_extent.height, render_area.height);
- color_view->Transition(vk::ImageLayout::eTransferDstOptimal,
- vk::PipelineStageFlagBits::eTransfer,
- vk::AccessFlagBits::eTransferWrite);
+ const u32 layer = regs.clear_buffers.layer;
+ const vk::ClearRect clear_rect({scissor_offset, scissor_extent}, layer, 1);
+ if (use_color) {
const std::array clear_color = {regs.clear_color[0], regs.clear_color[1],
regs.clear_color[2], regs.clear_color[3]};
- const vk::ClearColorValue clear(clear_color);
- scheduler.Record([image = color_view->GetImage(),
- subresource = color_view->GetImageSubresourceRange(),
- clear](auto cmdbuf, auto& dld) {
- cmdbuf.clearColorImage(image, vk::ImageLayout::eTransferDstOptimal, clear, subresource,
- dld);
+ const vk::ClearValue clear_value{clear_color};
+ const u32 color_attachment = regs.clear_buffers.RT;
+ scheduler.Record([color_attachment, clear_value, clear_rect](auto cmdbuf, auto& dld) {
+ const vk::ClearAttachment attachment(vk::ImageAspectFlagBits::eColor, color_attachment,
+ clear_value);
+ cmdbuf.clearAttachments(1, &attachment, 1, &clear_rect, dld);
});
}
- if (use_depth || use_stencil) {
- View zeta_surface;
- {
- MICROPROFILE_SCOPE(Vulkan_RenderTargets);
- zeta_surface = texture_cache.GetDepthBufferSurface(false);
- }
- zeta_surface->Transition(vk::ImageLayout::eTransferDstOptimal,
- vk::PipelineStageFlagBits::eTransfer,
- vk::AccessFlagBits::eTransferWrite);
-
- const vk::ClearDepthStencilValue clear(regs.clear_depth,
- static_cast<u32>(regs.clear_stencil));
- scheduler.Record([image = zeta_surface->GetImage(),
- subresource = zeta_surface->GetImageSubresourceRange(),
- clear](auto cmdbuf, auto& dld) {
- cmdbuf.clearDepthStencilImage(image, vk::ImageLayout::eTransferDstOptimal, clear,
- subresource, dld);
- });
+ if (!use_depth && !use_stencil) {
+ return;
+ }
+ vk::ImageAspectFlags aspect_flags;
+ if (use_depth) {
+ aspect_flags |= vk::ImageAspectFlagBits::eDepth;
+ }
+ if (use_stencil) {
+ aspect_flags |= vk::ImageAspectFlagBits::eStencil;
}
+
+ scheduler.Record([clear_depth = regs.clear_depth, clear_stencil = regs.clear_stencil,
+ clear_rect, aspect_flags](auto cmdbuf, auto& dld) {
+ const vk::ClearDepthStencilValue clear_zeta(clear_depth, clear_stencil);
+ const vk::ClearValue clear_value{clear_zeta};
+ const vk::ClearAttachment attachment(aspect_flags, 0, clear_value);
+ cmdbuf.clearAttachments(1, &attachment, 1, &clear_rect, dld);
+ });
}
void RasterizerVulkan::DispatchCompute(GPUVAddr code_addr) {
@@ -542,8 +548,6 @@ bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config,
// Verify that the cached surface is the same size and format as the requested framebuffer
const auto& params{surface->GetSurfaceParams()};
- const auto& pixel_format{
- VideoCore::Surface::PixelFormatFromGPUPixelFormat(config.pixel_format)};
ASSERT_MSG(params.width == config.width, "Framebuffer width is different");
ASSERT_MSG(params.height == config.height, "Framebuffer height is different");
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index b2e73d98d..3185868e9 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -253,6 +253,7 @@ private:
VKStagingBufferPool staging_pool;
VKDescriptorPool descriptor_pool;
VKUpdateDescriptorQueue update_descriptor_queue;
+ VKRenderPassCache renderpass_cache;
QuadArrayPass quad_array_pass;
Uint8Pass uint8_pass;
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
index d9ea3cc21..374959f82 100644
--- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
+++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
@@ -100,7 +100,6 @@ void VKStagingBufferPool::ReleaseCache(bool host_visible) {
}
u64 VKStagingBufferPool::ReleaseLevel(StagingBuffersCache& cache, std::size_t log2) {
- static constexpr u64 epochs_to_destroy = 180;
static constexpr std::size_t deletions_per_tick = 16;
auto& staging = cache[log2];
@@ -108,6 +107,7 @@ u64 VKStagingBufferPool::ReleaseLevel(StagingBuffersCache& cache, std::size_t lo
const std::size_t old_size = entries.size();
const auto is_deleteable = [this](const auto& entry) {
+ static constexpr u64 epochs_to_destroy = 180;
return entry.last_epoch + epochs_to_destroy < epoch && !entry.watch.IsUsed();
};
const std::size_t begin_offset = staging.delete_index;
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
index d74e68b63..94a89e388 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
@@ -90,8 +90,6 @@ void StateTracker::Initialize() {
SetupDirtyBlendConstants(tables);
SetupDirtyDepthBounds(tables);
SetupDirtyStencilProperties(tables);
-
- SetupCommonOnWriteStores(dirty.on_write_stores);
}
void StateTracker::InvalidateCommandBufferState() {
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 73d92a5ae..26175921b 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -52,6 +52,9 @@ vk::ImageType SurfaceTargetToImage(SurfaceTarget target) {
return vk::ImageType::e2D;
case SurfaceTarget::Texture3D:
return vk::ImageType::e3D;
+ case SurfaceTarget::TextureBuffer:
+ UNREACHABLE();
+ return {};
}
UNREACHABLE_MSG("Unknown texture target={}", static_cast<u32>(target));
return {};
@@ -273,7 +276,6 @@ void CachedSurface::UploadImage(const std::vector<u8>& staging_buffer) {
for (u32 level = 0; level < params.num_levels; ++level) {
vk::BufferImageCopy copy = GetBufferImageCopy(level);
- const auto& dld = device.GetDispatchLoader();
if (image->GetAspectMask() ==
(vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil)) {
vk::BufferImageCopy depth = copy;
@@ -422,7 +424,6 @@ void VKTextureCache::ImageCopy(Surface& src_surface, Surface& dst_surface,
dst_base_layer, num_layers, copy_params.dest_level, 1, vk::PipelineStageFlagBits::eTransfer,
vk::AccessFlagBits::eTransferWrite, vk::ImageLayout::eTransferDstOptimal);
- const auto& dld{device.GetDispatchLoader()};
const vk::ImageSubresourceLayers src_subresource(
src_surface->GetAspectMask(), copy_params.source_level, copy_params.source_z, num_layers);
const vk::ImageSubresourceLayers dst_subresource(
@@ -458,7 +459,6 @@ void VKTextureCache::ImageBlit(View& src_view, View& dst_view,
dst_view->GetImageSubresourceLayers(), {dst_top_left, dst_bot_right});
const bool is_linear = copy_config.filter == Tegra::Engines::Fermi2D::Filter::Linear;
- const auto& dld{device.GetDispatchLoader()};
scheduler.Record([src_image = src_view->GetImage(), dst_image = dst_view->GetImage(), blit,
is_linear](auto cmdbuf, auto& dld) {
cmdbuf.blitImage(src_image, vk::ImageLayout::eTransferSrcOptimal, dst_image,