diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index ebe7764478..fccb074bef 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -394,6 +394,20 @@ void GLGSRender::end() draw_fbo.bind(); m_program->use(); + //Check if depth buffer is bound and valid + //If ds is not initialized clear it; it seems new depth textures should have depth cleared + gl::render_target *ds = std::get<1>(m_rtts.m_bound_depth_stencil); + if (ds && !ds->cleared()) + { + glDepthMask(GL_TRUE); + glClearDepth(1.f); + + glClear(GL_DEPTH_BUFFER_BIT); + glDepthMask(rsx::method_registers.depth_write_enabled()); + + ds->set_cleared(); + } + //setup textures { for (int i = 0; i < rsx::limits::fragment_textures_count; ++i) @@ -696,6 +710,20 @@ bool GLGSRender::do_method(u32 cmd, u32 arg) } found->second(arg, this); + + switch (cmd) + { + case NV4097_CLEAR_SURFACE: + { + if (arg & 0x1) + { + gl::render_target *ds = std::get<1>(m_rtts.m_bound_depth_stencil); + if (ds && !ds->cleared()) + ds->set_cleared(); + } + } + } + return true; } diff --git a/rpcs3/Emu/RSX/GL/gl_render_targets.h b/rpcs3/Emu/RSX/GL/gl_render_targets.h index 4fb05d7c13..193b169ce7 100644 --- a/rpcs3/Emu/RSX/GL/gl_render_targets.h +++ b/rpcs3/Emu/RSX/GL/gl_render_targets.h @@ -4,6 +4,31 @@ #include "stdafx.h" #include "../RSXThread.h" +namespace gl +{ + class render_target : public texture + { + bool is_cleared; + + public: + + render_target() + { + is_cleared = false; + } + + void set_cleared() + { + is_cleared = true; + } + + bool cleared() + { + return is_cleared; + } + }; +} + struct color_swizzle { gl::texture::channel a = gl::texture::channel::a; @@ -47,20 +72,20 @@ namespace rsx struct gl_render_target_traits { - using surface_storage_type = std::unique_ptr; - using surface_type = gl::texture*; + using surface_storage_type = std::unique_ptr; + using surface_type = gl::render_target*; using command_list_type = void*; using download_buffer_object = std::vector; static - std::unique_ptr create_new_surface( + std::unique_ptr create_new_surface( u32 address, rsx::surface_color_format surface_color_format, size_t width, size_t height ) { - std::unique_ptr result(new gl::texture()); + std::unique_ptr result(new gl::render_target()); auto format = rsx::internals::surface_color_format_to_gl(surface_color_format); result->recreate(gl::texture::target::texture2D); @@ -80,14 +105,14 @@ struct gl_render_target_traits } static - std::unique_ptr create_new_surface( + std::unique_ptr create_new_surface( u32 address, rsx::surface_depth_format surface_depth_format, size_t width, size_t height ) { - std::unique_ptr result(new gl::texture()); + std::unique_ptr result(new gl::render_target()); auto format = rsx::internals::surface_depth_format_to_gl(surface_depth_format); result->recreate(gl::texture::target::texture2D); @@ -106,27 +131,27 @@ struct gl_render_target_traits return result; } - static void prepare_rtt_for_drawing(void *, gl::texture*) {} - static void prepare_rtt_for_sampling(void *, gl::texture*) {} - static void prepare_ds_for_drawing(void *, gl::texture*) {} - static void prepare_ds_for_sampling(void *, gl::texture*) {} + static void prepare_rtt_for_drawing(void *, gl::render_target*) {} + static void prepare_rtt_for_sampling(void *, gl::render_target*) {} + static void prepare_ds_for_drawing(void *, gl::render_target*) {} + static void prepare_ds_for_sampling(void *, gl::render_target*) {} static - bool rtt_has_format_width_height(const std::unique_ptr &rtt, rsx::surface_color_format surface_color_format, size_t width, size_t height) + bool rtt_has_format_width_height(const std::unique_ptr &rtt, rsx::surface_color_format surface_color_format, size_t width, size_t height) { // TODO: check format return rtt->width() == width && rtt->height() == height; } static - bool ds_has_format_width_height(const std::unique_ptr &rtt, rsx::surface_depth_format surface_depth_stencil_format, size_t width, size_t height) + bool ds_has_format_width_height(const std::unique_ptr &rtt, rsx::surface_depth_format surface_depth_stencil_format, size_t width, size_t height) { // TODO: check format return rtt->width() == width && rtt->height() == height; } // Note : pbo breaks fbo here so use classic texture copy - static std::vector issue_download_command(gl::texture* color_buffer, rsx::surface_color_format color_format, size_t width, size_t height) + static std::vector issue_download_command(gl::render_target* color_buffer, rsx::surface_color_format color_format, size_t width, size_t height) { auto pixel_format = rsx::internals::surface_color_format_to_gl(color_format); std::vector result(width * height * pixel_format.channel_count * pixel_format.channel_size); @@ -135,7 +160,7 @@ struct gl_render_target_traits return result; } - static std::vector issue_depth_download_command(gl::texture* depth_stencil_buffer, rsx::surface_depth_format depth_format, size_t width, size_t height) + static std::vector issue_depth_download_command(gl::render_target* depth_stencil_buffer, rsx::surface_depth_format depth_format, size_t width, size_t height) { std::vector result(width * height * 4); @@ -145,7 +170,7 @@ struct gl_render_target_traits return result; } - static std::vector issue_stencil_download_command(gl::texture* depth_stencil_buffer, size_t width, size_t height) + static std::vector issue_stencil_download_command(gl::render_target* depth_stencil_buffer, size_t width, size_t height) { std::vector result(width * height * 4); return result; @@ -162,7 +187,7 @@ struct gl_render_target_traits { } - static gl::texture* get(const std::unique_ptr &in) + static gl::render_target* get(const std::unique_ptr &in) { return in.get(); } diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.cpp b/rpcs3/Emu/RSX/VK/VKHelpers.cpp index e00b211505..7faebe85f8 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -44,8 +44,8 @@ namespace vk result.host_visible_coherent = VK_MAX_MEMORY_TYPES; bool host_visible_cached = false; - u32 host_visible_vram_size = 0; - u32 device_local_vram_size = 0; + VkDeviceSize host_visible_vram_size = 0; + VkDeviceSize device_local_vram_size = 0; for (u32 i = 0; i < memory_properties.memoryTypeCount; i++) { diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index b5373900f9..25d76eac43 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -124,7 +124,7 @@ namespace vk vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, queue_props.data()); } - if (queue >= queue_props.size()) throw EXCEPTION("Undefined trap"); + if (queue >= queue_props.size()) throw EXCEPTION("Bad queue index passed to get_queue_properties (%u)", queue); return queue_props[queue]; } @@ -154,8 +154,6 @@ namespace vk render_device(vk::physical_device &pdev, uint32_t graphics_queue_idx) { - VkResult err; - float queue_priorities[1] = { 0.f }; pgpu = &pdev; @@ -188,8 +186,7 @@ namespace vk device.ppEnabledExtensionNames = requested_extensions; device.pEnabledFeatures = nullptr; - err = vkCreateDevice(*pgpu, &device, nullptr, &dev); - if (err != VK_SUCCESS) throw EXCEPTION("Undefined trap"); + CHECK_RESULT(vkCreateDevice(*pgpu, &device, nullptr, &dev)); } ~render_device() @@ -844,7 +841,7 @@ namespace vk nb_swap_images = 0; getSwapchainImagesKHR(dev, m_vk_swapchain, &nb_swap_images, nullptr); - if (!nb_swap_images) throw EXCEPTION("Undefined trap"); + if (!nb_swap_images) throw EXCEPTION("Driver returned 0 images for swapchain"); std::vector swap_images; swap_images.resize(nb_swap_images); @@ -1052,9 +1049,7 @@ namespace vk instance_info.ppEnabledExtensionNames = requested_extensions; VkInstance instance; - VkResult error = vkCreateInstance(&instance_info, nullptr, &instance); - - if (error != VK_SUCCESS) throw EXCEPTION("Undefined trap"); + CHECK_RESULT(vkCreateInstance(&instance_info, nullptr, &instance)); m_vk_instances.push_back(instance); return (u32)m_vk_instances.size(); @@ -1063,7 +1058,7 @@ namespace vk void makeCurrentInstance(uint32_t instance_id) { if (!instance_id || instance_id > m_vk_instances.size()) - throw EXCEPTION("Undefined trap"); + throw EXCEPTION("Invalid instance passed to makeCurrentInstance (%u)", instance_id); if (m_debugger) { @@ -1083,7 +1078,7 @@ namespace vk VkInstance getInstanceById(uint32_t instance_id) { if (!instance_id || instance_id > m_vk_instances.size()) - throw EXCEPTION("Undefined trap"); + throw EXCEPTION("Invalid instance passed to getInstanceById (%u)", instance_id); instance_id--; return m_vk_instances[instance_id]; @@ -1117,7 +1112,7 @@ namespace vk createInfo.hwnd = hWnd; VkSurfaceKHR surface; - VkResult err = vkCreateWin32SurfaceKHR(m_instance, &createInfo, NULL, &surface); + CHECK_RESULT(vkCreateWin32SurfaceKHR(m_instance, &createInfo, NULL, &surface)); uint32_t device_queues = dev.get_queue_count(); std::vector supportsPresent(device_queues); @@ -1165,19 +1160,17 @@ namespace vk // Generate error if could not find both a graphics and a present queue if (graphicsQueueNodeIndex == UINT32_MAX || presentQueueNodeIndex == UINT32_MAX) - throw EXCEPTION("Undefined trap"); + throw EXCEPTION("Failed to find a suitable graphics/compute queue"); if (graphicsQueueNodeIndex != presentQueueNodeIndex) - throw EXCEPTION("Undefined trap"); + throw EXCEPTION("Separate graphics and present queues not supported"); // Get the list of VkFormat's that are supported: uint32_t formatCount; - err = vkGetPhysicalDeviceSurfaceFormatsKHR(dev, surface, &formatCount, nullptr); - if (err != VK_SUCCESS) throw EXCEPTION("Undefined trap"); + CHECK_RESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(dev, surface, &formatCount, nullptr)); std::vector surfFormats(formatCount); - err = vkGetPhysicalDeviceSurfaceFormatsKHR(dev, surface, &formatCount, surfFormats.data()); - if (err != VK_SUCCESS) throw EXCEPTION("Undefined trap"); + CHECK_RESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(dev, surface, &formatCount, surfFormats.data())); VkFormat format; VkColorSpaceKHR color_space; @@ -1188,7 +1181,7 @@ namespace vk } else { - if (!formatCount) throw EXCEPTION("Undefined trap"); + if (!formatCount) throw EXCEPTION("Format count is zero!"); format = surfFormats[0].format; }