vulkan: Mark of critical code from allowing cb split in exception handler

vk: Shader loads are sacred
This commit is contained in:
kd-11 2017-04-23 17:17:05 +03:00
parent 3b27b3c182
commit 0ec88bb65d
4 changed files with 44 additions and 3 deletions

View File

@ -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;
}

View File

@ -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)

View File

@ -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;

View File

@ -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);