Vulkan: Add pass name handling.

Add #pragma name.
This commit is contained in:
Hans-Kristian Arntzen 2016-03-26 17:59:50 +01:00
parent 21c7ff99d1
commit 7d5eb2bc27
4 changed files with 129 additions and 3 deletions

View File

@ -101,8 +101,11 @@ static string build_stage_source(const vector<string> &lines, const char *stage)
{
if (itr->find("#pragma stage ") != string::npos)
{
auto expected = string("#pragma stage ") + stage;
active = itr->find(expected) != string::npos;
if (stage)
{
auto expected = string("#pragma stage ") + stage;
active = itr->find(expected) != string::npos;
}
// Improve debuggability.
if (active)
@ -120,14 +123,39 @@ static string build_stage_source(const vector<string> &lines, const char *stage)
return str.str();
}
static bool glslang_parse_meta(const vector<string> &lines, glslang_meta *meta)
{
*meta = glslang_meta{};
for (auto &line : lines)
{
if (line.find("#pragma name ") != string::npos)
{
if (!meta->name.empty())
{
RARCH_ERR("[slang]: Trying to declare multiple names for file.\n");
return false;
}
const char *str = line.c_str() + strlen("#pragma name ");
while (*str == ' ')
str++;
meta->name = str;
}
}
return true;
}
bool glslang_compile_shader(const char *shader_path, glslang_output *output)
{
vector<string> lines;
RARCH_LOG("Compiling shader \"%s\".\n", shader_path);
RARCH_LOG("[slang]: Compiling shader \"%s\".\n", shader_path);
if (!read_shader_file(shader_path, &lines))
return false;
if (!glslang_parse_meta(lines, &output->meta))
return false;
auto &header = lines.front();
if (header.find_first_of("#version ") == string::npos)
{

View File

@ -18,11 +18,18 @@
#include <stdint.h>
#include <vector>
#include <string>
struct glslang_meta
{
std::string name;
};
struct glslang_output
{
std::vector<uint32_t> vertex;
std::vector<uint32_t> fragment;
glslang_meta meta;
};
bool glslang_compile_shader(const char *shader_path, glslang_output *output);

View File

@ -290,6 +290,16 @@ class Pass
frame_count_period = period;
}
void set_name(const char *name)
{
pass_name = name;
}
const string &get_name() const
{
return pass_name;
}
vulkan_filter_chain_filter get_source_filter() const
{
return pass_info.source_filter;
@ -375,6 +385,8 @@ class Pass
uint64_t frame_count = 0;
unsigned frame_count_period = 0;
string pass_name;
};
// struct here since we're implementing the opaque typedef from C.
@ -411,6 +423,7 @@ struct vulkan_filter_chain
void set_frame_count(uint64_t count);
void set_frame_count_period(unsigned pass, unsigned period);
void set_pass_name(unsigned pass, const char *name);
private:
VkDevice device;
@ -439,6 +452,7 @@ struct vulkan_filter_chain
bool init_history();
bool init_feedback();
bool init_alias();
void update_history(DeferredDisposer &disposer, VkCommandBuffer cmd);
vector<unique_ptr<Framebuffer>> original_history;
bool require_clear = false;
@ -543,6 +557,11 @@ void vulkan_filter_chain::set_frame_count_period(unsigned pass, unsigned period)
passes[pass]->set_frame_count_period(period);
}
void vulkan_filter_chain::set_pass_name(unsigned pass, const char *name)
{
passes[pass]->set_name(name);
}
void vulkan_filter_chain::execute_deferred()
{
for (auto &calls : deferred_calls)
@ -674,13 +693,66 @@ bool vulkan_filter_chain::init_feedback()
return true;
}
template <typename M, typename P>
static bool set_unique_map(M &m, const string &name, const P &p)
{
auto itr = m.find(name);
if (itr != end(m))
{
RARCH_ERR("[slang]: Alias \"%s\" already exists.\n",
name.c_str());
return false;
}
m[name] = p;
return true;
}
bool vulkan_filter_chain::init_alias()
{
common.texture_semantic_map.clear();
common.texture_semantic_uniform_map.clear();
common.semantic_map.clear();
unsigned i = 0;
for (auto &pass : passes)
{
auto &name = pass->get_name();
if (name.empty())
continue;
if (!set_unique_map(common.texture_semantic_map, name,
slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i }))
return false;
if (!set_unique_map(common.texture_semantic_uniform_map, name + "Size",
slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i }))
return false;
if (!set_unique_map(common.texture_semantic_map, name + "Feedback",
slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i }))
return false;
if (!set_unique_map(common.texture_semantic_uniform_map, name + "FeedbackSize",
slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i }))
return false;
i++;
}
return true;
}
bool vulkan_filter_chain::init()
{
Size2D source = max_input_size;
if (!init_alias())
return false;
for (unsigned i = 0; i < passes.size(); i++)
{
auto &pass = passes[i];
RARCH_LOG("[slang]: Building pass #%u (%s)\n", i, pass->get_name().empty() ? "N/A" : pass->get_name().c_str());
source = pass->set_pass_info(max_input_size,
source, swapchain_info, pass_info[i]);
if (!pass->build())
@ -1955,6 +2027,13 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
chain->set_frame_count_period(i, pass->frame_count_mod);
if (!output.meta.name.empty())
chain->set_pass_name(i, output.meta.name.c_str());
// Preset overrides.
if (*pass->alias)
chain->set_pass_name(i, pass->alias);
if (pass->filter == RARCH_FILTER_UNSPEC)
pass_info.source_filter = filter;
else
@ -2129,6 +2208,14 @@ void vulkan_filter_chain_set_frame_count_period(
chain->set_frame_count_period(pass, period);
}
void vulkan_filter_chain_set_pass_name(
vulkan_filter_chain_t *chain,
unsigned pass,
const char *name)
{
chain->set_pass_name(pass, name);
}
void vulkan_filter_chain_build_offscreen_passes(
vulkan_filter_chain_t *chain,
VkCommandBuffer cmd, const VkViewport *vp)

View File

@ -123,6 +123,10 @@ void vulkan_filter_chain_set_frame_count_period(vulkan_filter_chain_t *chain,
unsigned pass,
unsigned period);
void vulkan_filter_chain_set_pass_name(vulkan_filter_chain_t *chain,
unsigned pass,
const char *name);
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,