From 3838b3c045bc67e3c8ce8d7f56f4fc0cc8a59f55 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Fri, 25 Mar 2016 22:06:31 +0100 Subject: [PATCH] Vulkan: Add frame count suport. --- gfx/drivers/vulkan.c | 1 + gfx/drivers_shader/shader_vulkan.cpp | 54 +++++++++++++++++++++++++ gfx/drivers_shader/shader_vulkan.h | 7 ++++ gfx/drivers_shader/slang_reflection.cpp | 5 +++ gfx/drivers_shader/slang_reflection.hpp | 1 + 5 files changed, 68 insertions(+) diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index 3bf140e625..4f7afd9544 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -1481,6 +1481,7 @@ static bool vulkan_frame(void *data, const void *frame, /* Notify filter chain about the new sync index. */ vulkan_filter_chain_notify_sync_index(vk->filter_chain, frame_index); + vulkan_filter_chain_set_frame_count(vk->filter_chain, frame_count); retro_perf_start(&build_cmd); /* Render offscreen filter chain passes. */ diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp index 3ce7a21523..a1fd7d4a73 100644 --- a/gfx/drivers_shader/shader_vulkan.cpp +++ b/gfx/drivers_shader/shader_vulkan.cpp @@ -276,6 +276,16 @@ class Pass sync_index = index; } + void set_frame_count(uint64_t count) + { + frame_count = count; + } + + void set_frame_count_period(unsigned period) + { + frame_count_period = period; + } + vulkan_filter_chain_filter get_source_filter() const { return pass_info.source_filter; @@ -347,6 +357,7 @@ class Pass const float *mvp, const Texture &original, const Texture &source); void build_semantic_vec4(uint8_t *data, slang_semantic semantic, unsigned width, unsigned height); + void build_semantic_uint(uint8_t *data, slang_semantic semantic, uint32_t value); void build_semantic_texture_vec4(uint8_t *data, slang_texture_semantic semantic, unsigned width, unsigned height); @@ -357,6 +368,9 @@ class Pass slang_texture_semantic semantic, const Texture &texture); void build_semantic_texture_array(VkDescriptorSet set, uint8_t *buffer, slang_texture_semantic semantic, unsigned index, const Texture &texture); + + uint64_t frame_count = 0; + unsigned frame_count_period = 0; }; // struct here since we're implementing the opaque typedef from C. @@ -391,6 +405,9 @@ struct vulkan_filter_chain void build_viewport_pass(VkCommandBuffer cmd, const VkViewport &vp, const float *mvp); + void set_frame_count(uint64_t count); + void set_frame_count_period(unsigned pass, unsigned period); + private: VkDevice device; const VkPhysicalDeviceMemoryProperties &memory_properties; @@ -511,6 +528,17 @@ void vulkan_filter_chain::set_input_texture( input_texture = texture; } +void vulkan_filter_chain::set_frame_count(uint64_t count) +{ + for (auto &pass : passes) + pass->set_frame_count(count); +} + +void vulkan_filter_chain::set_frame_count_period(unsigned pass, unsigned period) +{ + passes[pass]->set_frame_count_period(period); +} + void vulkan_filter_chain::execute_deferred() { for (auto &calls : deferred_calls) @@ -1378,6 +1406,13 @@ void Pass::build_semantic_vec4(uint8_t *data, slang_semantic semantic, } } +void Pass::build_semantic_uint(uint8_t *data, slang_semantic semantic, + uint32_t value) +{ + if (data && reflection.semantics[semantic].uniform) + *reinterpret_cast(data + reflection.semantics[semantic].ubo_offset) = value; +} + void Pass::build_semantic_texture(VkDescriptorSet set, uint8_t *buffer, slang_texture_semantic semantic, const Texture &texture) { @@ -1412,6 +1447,8 @@ void Pass::build_semantics(VkDescriptorSet set, uint8_t *buffer, current_framebuffer_size.width, current_framebuffer_size.height); build_semantic_vec4(buffer, SLANG_SEMANTIC_FINAL_VIEWPORT, unsigned(current_viewport.width), unsigned(current_viewport.height)); + build_semantic_uint(buffer, SLANG_SEMANTIC_FRAME_COUNT, + frame_count_period ? uint32_t(frame_count % frame_count_period) : uint32_t(frame_count)); // Standard inputs build_semantic_texture(set, buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL, original); @@ -1908,6 +1945,8 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset( output.fragment.data(), output.fragment.size()); + chain->set_frame_count_period(i, pass->frame_count_mod); + if (pass->filter == RARCH_FILTER_UNSPEC) pass_info.source_filter = filter; else @@ -2067,6 +2106,21 @@ void vulkan_filter_chain_set_input_texture( chain->set_input_texture(*texture); } +void vulkan_filter_chain_set_frame_count( + vulkan_filter_chain_t *chain, + uint64_t count) +{ + chain->set_frame_count(count); +} + +void vulkan_filter_chain_set_frame_count_period( + vulkan_filter_chain_t *chain, + unsigned pass, + unsigned period) +{ + chain->set_frame_count_period(pass, period); +} + void vulkan_filter_chain_build_offscreen_passes( vulkan_filter_chain_t *chain, VkCommandBuffer cmd, const VkViewport *vp) diff --git a/gfx/drivers_shader/shader_vulkan.h b/gfx/drivers_shader/shader_vulkan.h index bf05c305f8..86eab01d42 100644 --- a/gfx/drivers_shader/shader_vulkan.h +++ b/gfx/drivers_shader/shader_vulkan.h @@ -116,6 +116,13 @@ bool vulkan_filter_chain_init(vulkan_filter_chain_t *chain); void vulkan_filter_chain_set_input_texture(vulkan_filter_chain_t *chain, const struct vulkan_filter_chain_texture *texture); +void vulkan_filter_chain_set_frame_count(vulkan_filter_chain_t *chain, + uint64_t count); + +void vulkan_filter_chain_set_frame_count_period(vulkan_filter_chain_t *chain, + unsigned pass, + unsigned period); + void vulkan_filter_chain_build_offscreen_passes(vulkan_filter_chain_t *chain, VkCommandBuffer cmd, const VkViewport *vp); void vulkan_filter_chain_build_viewport_pass(vulkan_filter_chain_t *chain, diff --git a/gfx/drivers_shader/slang_reflection.cpp b/gfx/drivers_shader/slang_reflection.cpp index ff27c81540..a6a0c1250a 100644 --- a/gfx/drivers_shader/slang_reflection.cpp +++ b/gfx/drivers_shader/slang_reflection.cpp @@ -68,6 +68,7 @@ static const char *semantic_uniform_names[] = { "MVP", "OutputSize", "FinalViewportSize", + "FrameCount", }; static slang_texture_semantic slang_name_to_texture_semantic_array(const string &name, const char **names, @@ -198,6 +199,10 @@ static bool validate_type_for_semantic(const SPIRType &type, slang_semantic sem) // mat4 return type.basetype == SPIRType::Float && type.vecsize == 4 && type.columns == 4; + case SLANG_SEMANTIC_FRAME_COUNT: + // uint + return type.basetype == SPIRType::UInt && type.vecsize == 1 && type.columns == 1; + default: // vec4 return type.basetype == SPIRType::Float && type.vecsize == 4 && type.columns == 1; diff --git a/gfx/drivers_shader/slang_reflection.hpp b/gfx/drivers_shader/slang_reflection.hpp index 94228b2757..f416b52385 100644 --- a/gfx/drivers_shader/slang_reflection.hpp +++ b/gfx/drivers_shader/slang_reflection.hpp @@ -56,6 +56,7 @@ enum slang_semantic SLANG_SEMANTIC_MVP = 0, SLANG_SEMANTIC_OUTPUT = 1, SLANG_SEMANTIC_FINAL_VIEWPORT = 2, + SLANG_SEMANTIC_FRAME_COUNT = 3, SLANG_NUM_SEMANTICS, SLANG_INVALID_SEMANTIC = -1