mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-26 12:42:41 +01:00
vulkan: Mark of critical code from allowing cb split in exception handler
vk: Shader loads are sacred
This commit is contained in:
parent
3b27b3c182
commit
0ec88bb65d
@ -682,7 +682,10 @@ bool VKGSRender::on_access_violation(u32 address, bool is_writing)
|
||||
else
|
||||
{
|
||||
//NOTE: If the rsx::thread is trampling its own data, we have an operation that should be moved to the GPU
|
||||
flush_command_queue();
|
||||
//We should never interrupt our own cb recording since some operations are not interruptible
|
||||
if (!vk::is_uninterruptible())
|
||||
//TODO: Investigate driver behaviour to determine if we need a hard sync or a soft flush
|
||||
flush_command_queue();
|
||||
}
|
||||
}
|
||||
|
||||
@ -844,8 +847,10 @@ void VKGSRender::end()
|
||||
std::chrono::time_point<steady_clock> textures_end = steady_clock::now();
|
||||
m_textures_upload_time += std::chrono::duration_cast<std::chrono::microseconds>(textures_end - textures_start).count();
|
||||
|
||||
//upload_vertex_data is a memory op and can trigger an access violation
|
||||
//render passes are supposed to be uninterruptible, so we have to finish everything first before we start the render pass
|
||||
//While vertex upload is an interruptible process, if we made it this far, there's no need to sync anything that occurs past this point
|
||||
//Only textures are synchronized tightly with the GPU and they have been read back above
|
||||
vk::enter_uninterruptible();
|
||||
|
||||
auto upload_info = upload_vertex_data();
|
||||
|
||||
std::chrono::time_point<steady_clock> vertex_end = steady_clock::now();
|
||||
@ -882,6 +887,8 @@ void VKGSRender::end()
|
||||
|
||||
vkCmdEndRenderPass(*m_current_command_buffer);
|
||||
|
||||
vk::leave_uninterruptible();
|
||||
|
||||
std::chrono::time_point<steady_clock> draw_end = steady_clock::now();
|
||||
m_draw_time += std::chrono::duration_cast<std::chrono::microseconds>(draw_end - vertex_end).count();
|
||||
|
||||
@ -1058,6 +1065,8 @@ void VKGSRender::copy_render_targets_to_dma_location()
|
||||
//This is due to all the hard waits for fences
|
||||
//TODO: Use a command buffer array to allow explicit draw command tracking
|
||||
|
||||
vk::enter_uninterruptible();
|
||||
|
||||
if (g_cfg_rsx_write_color_buffers)
|
||||
{
|
||||
for (u8 index = 0; index < rsx::limits::color_buffers_count; index++)
|
||||
@ -1079,6 +1088,8 @@ void VKGSRender::copy_render_targets_to_dma_location()
|
||||
}
|
||||
}
|
||||
|
||||
vk::leave_uninterruptible();
|
||||
|
||||
m_last_flushable_cb = m_current_cb_index;
|
||||
flush_command_queue();
|
||||
|
||||
@ -1374,6 +1385,8 @@ bool VKGSRender::load_program()
|
||||
|
||||
properties.num_targets = m_draw_buffers_count;
|
||||
|
||||
vk::enter_uninterruptible();
|
||||
|
||||
//Load current program from buffer
|
||||
m_program = m_prog_buffer.getGraphicPipelineState(vertex_program, fragment_program, properties, *m_device, pipeline_layout).get();
|
||||
|
||||
@ -1415,6 +1428,8 @@ bool VKGSRender::load_program()
|
||||
m_program->bind_uniform({ m_uniform_buffer_ring_info.heap->value, vertex_constants_offset, 512 * 4 * sizeof(float) }, VERTEX_CONSTANT_BUFFERS_BIND_SLOT, descriptor_sets);
|
||||
m_program->bind_uniform({ m_uniform_buffer_ring_info.heap->value, fragment_constants_offset, fragment_buffer_sz }, FRAGMENT_CONSTANT_BUFFERS_BIND_SLOT, descriptor_sets);
|
||||
|
||||
vk::leave_uninterruptible();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,8 @@ namespace vk
|
||||
VkSampler g_null_sampler = nullptr;
|
||||
VkImageView g_null_image_view = nullptr;
|
||||
|
||||
bool g_cb_no_interrupt_flag = false;
|
||||
|
||||
VKAPI_ATTR void* VKAPI_CALL mem_realloc(void* pUserData, void* pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
@ -253,6 +255,21 @@ namespace vk
|
||||
vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
}
|
||||
|
||||
void enter_uninterruptible()
|
||||
{
|
||||
g_cb_no_interrupt_flag = true;
|
||||
}
|
||||
|
||||
void leave_uninterruptible()
|
||||
{
|
||||
g_cb_no_interrupt_flag = false;
|
||||
}
|
||||
|
||||
bool is_uninterruptible()
|
||||
{
|
||||
return g_cb_no_interrupt_flag;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
|
||||
uint64_t srcObject, size_t location, int32_t msgCode,
|
||||
const char *pLayerPrefix, const char *pMsg, void *pUserData)
|
||||
|
@ -78,6 +78,10 @@ namespace vk
|
||||
std::pair<VkFormat, VkComponentMapping> get_compatible_surface_format(rsx::surface_color_format color_format);
|
||||
size_t get_render_pass_location(VkFormat color_surface_format, VkFormat depth_stencil_format, u8 color_surface_count);
|
||||
|
||||
void enter_uninterruptible();
|
||||
void leave_uninterruptible();
|
||||
bool is_uninterruptible();
|
||||
|
||||
struct memory_type_mapping
|
||||
{
|
||||
uint32_t host_visible_coherent;
|
||||
|
@ -507,11 +507,16 @@ namespace vk
|
||||
mapping,
|
||||
subresource_range);
|
||||
|
||||
//We cannot split mipmap uploads across multiple command buffers (must explicitly open and close operations on the same cb)
|
||||
vk::enter_uninterruptible();
|
||||
|
||||
copy_mipmaped_image_using_buffer(cmd, image->value, get_subresources_layout(tex), format, !(tex.format() & CELL_GCM_TEXTURE_LN), tex.get_exact_mipmap_count(),
|
||||
upload_heap, upload_buffer);
|
||||
|
||||
change_image_layout(cmd, image->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresource_range);
|
||||
|
||||
vk::leave_uninterruptible();
|
||||
|
||||
region.reset(texaddr, range);
|
||||
region.create(tex.width(), height, depth, tex.get_exact_mipmap_count(), view, image);
|
||||
region.protect(utils::protection::ro);
|
||||
|
Loading…
Reference in New Issue
Block a user