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) if (itr->find("#pragma stage ") != string::npos)
{ {
auto expected = string("#pragma stage ") + stage; if (stage)
active = itr->find(expected) != string::npos; {
auto expected = string("#pragma stage ") + stage;
active = itr->find(expected) != string::npos;
}
// Improve debuggability. // Improve debuggability.
if (active) if (active)
@ -120,14 +123,39 @@ static string build_stage_source(const vector<string> &lines, const char *stage)
return str.str(); 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) bool glslang_compile_shader(const char *shader_path, glslang_output *output)
{ {
vector<string> lines; 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)) if (!read_shader_file(shader_path, &lines))
return false; return false;
if (!glslang_parse_meta(lines, &output->meta))
return false;
auto &header = lines.front(); auto &header = lines.front();
if (header.find_first_of("#version ") == string::npos) if (header.find_first_of("#version ") == string::npos)
{ {

View File

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

View File

@ -290,6 +290,16 @@ class Pass
frame_count_period = period; 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 vulkan_filter_chain_filter get_source_filter() const
{ {
return pass_info.source_filter; return pass_info.source_filter;
@ -375,6 +385,8 @@ class Pass
uint64_t frame_count = 0; uint64_t frame_count = 0;
unsigned frame_count_period = 0; unsigned frame_count_period = 0;
string pass_name;
}; };
// struct here since we're implementing the opaque typedef from C. // 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(uint64_t count);
void set_frame_count_period(unsigned pass, unsigned period); void set_frame_count_period(unsigned pass, unsigned period);
void set_pass_name(unsigned pass, const char *name);
private: private:
VkDevice device; VkDevice device;
@ -439,6 +452,7 @@ struct vulkan_filter_chain
bool init_history(); bool init_history();
bool init_feedback(); bool init_feedback();
bool init_alias();
void update_history(DeferredDisposer &disposer, VkCommandBuffer cmd); void update_history(DeferredDisposer &disposer, VkCommandBuffer cmd);
vector<unique_ptr<Framebuffer>> original_history; vector<unique_ptr<Framebuffer>> original_history;
bool require_clear = false; 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); 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() void vulkan_filter_chain::execute_deferred()
{ {
for (auto &calls : deferred_calls) for (auto &calls : deferred_calls)
@ -674,13 +693,66 @@ bool vulkan_filter_chain::init_feedback()
return true; 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() bool vulkan_filter_chain::init()
{ {
Size2D source = max_input_size; Size2D source = max_input_size;
if (!init_alias())
return false;
for (unsigned i = 0; i < passes.size(); i++) for (unsigned i = 0; i < passes.size(); i++)
{ {
auto &pass = passes[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 = pass->set_pass_info(max_input_size,
source, swapchain_info, pass_info[i]); source, swapchain_info, pass_info[i]);
if (!pass->build()) 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); 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) if (pass->filter == RARCH_FILTER_UNSPEC)
pass_info.source_filter = filter; pass_info.source_filter = filter;
else else
@ -2129,6 +2208,14 @@ void vulkan_filter_chain_set_frame_count_period(
chain->set_frame_count_period(pass, 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( void vulkan_filter_chain_build_offscreen_passes(
vulkan_filter_chain_t *chain, vulkan_filter_chain_t *chain,
VkCommandBuffer cmd, const VkViewport *vp) 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 pass,
unsigned period); 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, void vulkan_filter_chain_build_offscreen_passes(vulkan_filter_chain_t *chain,
VkCommandBuffer cmd, const VkViewport *vp); VkCommandBuffer cmd, const VkViewport *vp);
void vulkan_filter_chain_build_viewport_pass(vulkan_filter_chain_t *chain, void vulkan_filter_chain_build_viewport_pass(vulkan_filter_chain_t *chain,