diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.cpp b/rpcs3/Emu/RSX/VK/VKOverlays.cpp index b3deb880df..9519ecebc9 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.cpp +++ b/rpcs3/Emu/RSX/VK/VKOverlays.cpp @@ -492,7 +492,7 @@ namespace vk glsl::input_type_push_constant, 0, 0, - glsl::push_constant_ref { .size = 68 } + glsl::push_constant_ref { .size = vertex_push_constants_size } ) ); return result; @@ -508,7 +508,7 @@ namespace vk glsl::input_type_push_constant, 0, 0, - glsl::push_constant_ref {.offset = 68, .size = 60 } + glsl::push_constant_ref {.offset = vertex_push_constants_size, .size = fragment_push_constants_size } ) ); return result; @@ -530,28 +530,34 @@ namespace vk // 104: vec2 reserved; // 112: vec4 sdf_border_color; - f32 push_buf[32]; + usz pos = 0; + std::array push_buf{}; + // 1. Vertex config (00 - 63) - std::memcpy(push_buf, m_scale_offset.rgba, 16); - std::memcpy(push_buf + 4, m_color.rgba, 16); + write_to_ptr(push_buf, pos, m_scale_offset.rgba); + pos += sizeof(m_scale_offset.rgba) / sizeof(f32); + write_to_ptr(push_buf, pos, m_color.rgba); + pos += sizeof(m_color.rgba) / sizeof(f32); - push_buf[8] = m_viewport.width; - push_buf[9] = m_viewport.height; - push_buf[10] = m_viewport.x; - push_buf[11] = m_viewport.y; + push_buf[pos++] = m_viewport.width; + push_buf[pos++] = m_viewport.height; + push_buf[pos++] = m_viewport.x; + push_buf[pos++] = m_viewport.y; - push_buf[12] = m_clip_region.x1; - push_buf[13] = m_clip_region.y1; - push_buf[14] = m_clip_region.x2; - push_buf[15] = m_clip_region.y2; + push_buf[pos++] = m_clip_region.x1; + push_buf[pos++] = m_clip_region.y1; + push_buf[pos++] = m_clip_region.x2; + push_buf[pos++] = m_clip_region.y2; rsx::overlays::vertex_options vert_opts {}; const auto vert_config = vert_opts .disable_vertex_snap(m_disable_vertex_snap) .get(); - push_buf[16] = std::bit_cast(vert_config); + push_buf[pos++] = std::bit_cast(vert_config); - vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_VERTEX_BIT, 0, 68, push_buf); + ensure(pos <= push_buf.size()); + ensure(pos == (vertex_push_constants_size / sizeof(f32))); + vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_VERTEX_BIT, 0, vertex_push_constants_size, push_buf.data()); // 2. Fragment stuff rsx::overlays::fragment_options frag_opts {}; @@ -562,21 +568,25 @@ namespace vk .set_sdf(m_sdf_config.func) .get(); - push_buf[0] = std::bit_cast(frag_config); - push_buf[1] = m_time; - push_buf[2] = m_blur_strength; - push_buf[3] = m_sdf_config.hx; - push_buf[4] = m_sdf_config.hy; - push_buf[5] = m_sdf_config.br; - push_buf[6] = m_sdf_config.bw; - push_buf[7] = m_sdf_config.cx; - push_buf[8] = m_sdf_config.cy; - push_buf[9] = 0.f; - push_buf[10] = 0.f; + pos = 0; + push_buf[pos++] = std::bit_cast(frag_config); + push_buf[pos++] = m_time; + push_buf[pos++] = m_blur_strength; + push_buf[pos++] = m_sdf_config.hx; + push_buf[pos++] = m_sdf_config.hy; + push_buf[pos++] = m_sdf_config.br; + push_buf[pos++] = m_sdf_config.bw; + push_buf[pos++] = m_sdf_config.cx; + push_buf[pos++] = m_sdf_config.cy; + push_buf[pos++] = 0.f; + push_buf[pos++] = 0.f; - std::memcpy(push_buf + 11, m_sdf_config.border_color.rgba, 16); + write_to_ptr(push_buf, pos, m_sdf_config.border_color.rgba); + pos += sizeof(m_sdf_config.border_color.rgba) / sizeof(f32); - vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_FRAGMENT_BIT, 68, 60, push_buf); + ensure(pos <= push_buf.size()); + ensure(pos == (fragment_push_constants_size / sizeof(f32))); + vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_FRAGMENT_BIT, vertex_push_constants_size, fragment_push_constants_size, push_buf.data()); } void ui_overlay_renderer::set_primitive_type(rsx::overlays::primitive_type type) @@ -747,7 +757,7 @@ namespace vk vk::glsl::input_type_push_constant, 0, 0, - glsl::push_constant_ref{ .size = 32 }) + glsl::push_constant_ref{ .size = vertex_push_constants_size }) }; } @@ -763,7 +773,8 @@ namespace vk data[6] = colormask.b; data[7] = colormask.a; - vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_VERTEX_BIT, 0, 32, data); + static_assert(sizeof(data) == vertex_push_constants_size); + vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_VERTEX_BIT, 0, vertex_push_constants_size, data); } void attachment_clear_pass::set_up_viewport(vk::command_buffer& cmd, u32 x, u32 y, u32 w, u32 h) @@ -901,7 +912,7 @@ namespace vk vk::glsl::input_type_push_constant, 0, 0, - glsl::push_constant_ref{ .size = 16 } + glsl::push_constant_ref{ .size = fragment_push_constants_size } ) ); return result; @@ -909,7 +920,8 @@ namespace vk void video_out_calibration_pass::update_uniforms(vk::command_buffer& cmd, vk::glsl::program* program) { - vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(config.data), config.data); + static_assert(sizeof(config.data) == fragment_push_constants_size); + vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, fragment_push_constants_size, config.data); } void video_out_calibration_pass::run(vk::command_buffer& cmd, const areau& viewport, vk::framebuffer* target, diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.h b/rpcs3/Emu/RSX/VK/VKOverlays.h index cfae31f9df..e354d237f3 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.h +++ b/rpcs3/Emu/RSX/VK/VKOverlays.h @@ -141,6 +141,9 @@ namespace vk std::unordered_map> temp_view_cache; rsx::overlays::primitive_type m_current_primitive_type = rsx::overlays::primitive_type::quad_list; + static constexpr u32 vertex_push_constants_size = 68; + static constexpr u32 fragment_push_constants_size = 60; + ui_overlay_renderer(); void upload_simple_texture(vk::image* tex, vk::command_buffer& cmd, @@ -177,6 +180,9 @@ namespace vk color4f colormask = { 1.f, 1.f, 1.f, 1.f }; VkRect2D region = {}; + static constexpr u32 vertex_push_constants_size = 32; + static_assert(vertex_push_constants_size == (sizeof(clear_color) + sizeof(colormask))); + attachment_clear_pass(); std::vector get_vertex_inputs() override; @@ -224,6 +230,8 @@ namespace vk } config = {}; + static constexpr u32 fragment_push_constants_size = 112; + video_out_calibration_pass(); std::vector get_fragment_inputs() override; @@ -241,7 +249,7 @@ namespace vk template T* get_overlay_pass() { - u32 index = stx::typeindex(); + const u32 index = stx::typeindex(); auto& e = g_overlay_passes[index]; if (!e) diff --git a/rpcs3/Emu/RSX/VK/VKResolveHelper.h b/rpcs3/Emu/RSX/VK/VKResolveHelper.h index 550c52da2a..ada374a837 100644 --- a/rpcs3/Emu/RSX/VK/VKResolveHelper.h +++ b/rpcs3/Emu/RSX/VK/VKResolveHelper.h @@ -99,6 +99,8 @@ namespace vk s32 static_parameters[4]; s32 static_parameters_width = 2; + static constexpr usz fragment_push_constants_size = sizeof(static_parameters); + depth_resolve_base() { renderpass_config.set_depth_mask(true); @@ -122,14 +124,16 @@ namespace vk glsl::input_type_push_constant, 0, umax, - glsl::push_constant_ref{ .size = 16 } + glsl::push_constant_ref{ .size = fragment_push_constants_size } )); return result; } void update_uniforms(vk::command_buffer& cmd, vk::glsl::program* program) override { - vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, static_parameters_width * 4, static_parameters); + const u32 size_to_push = static_parameters_width * sizeof(decltype(static_parameters[0])); + ensure(size_to_push <= fragment_push_constants_size); + vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, size_to_push, static_parameters); } void update_sample_configuration(vk::image* msaa_image) diff --git a/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp b/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp index fbd4e868f9..dd10f2a22a 100644 --- a/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp +++ b/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp @@ -59,7 +59,7 @@ namespace vk m_src = fmt::replace_all(m_src, replacement_table); // Fill with 0 to avoid sending incomplete/unused variables to the GPU - memset(m_constants_buf, 0, sizeof(m_constants_buf)); + std::fill(m_constants_buf.begin(), m_constants_buf.end(), 0u); // No ssbo usage ssbo_count = 0; @@ -160,7 +160,8 @@ namespace vk static_cast(src_image->width()), static_cast(src_image->height()), // Size of the raw image to upscale (in case viewport does not cover it all) static_cast(m_output_size.width), static_cast(m_output_size.height)); // Size of output viewport (target size) - vkCmdPushConstants(cmd, m_program->layout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, push_constants_size, m_constants_buf); + ensure(push_constants_size <= (m_constants_buf.size() * sizeof(decltype(m_constants_buf)::value_type))); + vkCmdPushConstants(cmd, m_program->layout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, push_constants_size, m_constants_buf.data()); } rcas_pass::rcas_pass() @@ -179,7 +180,8 @@ namespace vk auto cas_attenuation = 2.f - (g_cfg.video.rcas_sharpening_intensity / 50.f); FsrRcasCon(&m_constants_buf[0], cas_attenuation); - vkCmdPushConstants(cmd, m_program->layout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, push_constants_size, m_constants_buf); + ensure(push_constants_size <= (m_constants_buf.size() * sizeof(decltype(m_constants_buf)::value_type))); + vkCmdPushConstants(cmd, m_program->layout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, push_constants_size, m_constants_buf.data()); } } // Namespace FidelityFX diff --git a/rpcs3/Emu/RSX/VK/upscalers/fsr_pass.h b/rpcs3/Emu/RSX/VK/upscalers/fsr_pass.h index 7bff58b049..924e3d4c03 100644 --- a/rpcs3/Emu/RSX/VK/upscalers/fsr_pass.h +++ b/rpcs3/Emu/RSX/VK/upscalers/fsr_pass.h @@ -17,7 +17,7 @@ namespace vk const vk::image_view* m_output_image = nullptr; size2u m_input_size; size2u m_output_size; - u32 m_constants_buf[20]; + std::array m_constants_buf {}; std::vector get_inputs() override; void bind_resources(const vk::command_buffer&) override;