Vulkan: Add frame count suport.

This commit is contained in:
Hans-Kristian Arntzen 2016-03-25 22:06:31 +01:00
parent b7b03c531a
commit 3838b3c045
5 changed files with 68 additions and 0 deletions

View File

@ -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. */

View File

@ -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<uint32_t*>(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)

View File

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

View File

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

View File

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