(slang) Cleanups

This commit is contained in:
twinaphex 2018-04-23 14:56:02 +02:00
parent e54cb1b121
commit 871f04e19a
3 changed files with 104 additions and 68 deletions

View File

@ -18,8 +18,10 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <algorithm> #include <algorithm>
#include <compat/strl.h>
#include "../../verbosity.h" #include "../../verbosity.h"
#include "../../libretro-common/include/compat/strl.h"
using namespace std; using namespace std;
@ -28,28 +30,32 @@ bool slang_preprocess_parse_parameters(glslang_meta& meta,
{ {
unsigned old_num_parameters = shader->num_parameters; unsigned old_num_parameters = shader->num_parameters;
// Assumes num_parameters is initialized to something sane. /* Assumes num_parameters is
* initialized to something sane. */
for (auto &param : meta.parameters) for (auto &param : meta.parameters)
{ {
bool mismatch_dup = false; bool mismatch_dup = false;
bool dup = false; bool dup = false;
auto itr = find_if(shader->parameters,
auto itr = find_if(shader->parameters, shader->parameters + shader->num_parameters, shader->parameters + shader->num_parameters,
[&](const video_shader_parameter &parsed_param) { [&](const video_shader_parameter &parsed_param)
{
return param.id == parsed_param.id; return param.id == parsed_param.id;
}); });
if (itr != shader->parameters + shader->num_parameters) if (itr != shader->parameters + shader->num_parameters)
{ {
dup = true; dup = true;
// Allow duplicate #pragma parameter, but only if they are exactly the same. /* Allow duplicate #pragma parameter, but only
* if they are exactly the same. */
if (param.desc != itr->desc || if (param.desc != itr->desc ||
param.initial != itr->initial || param.initial != itr->initial ||
param.minimum != itr->minimum || param.minimum != itr->minimum ||
param.maximum != itr->maximum || param.maximum != itr->maximum ||
param.step != itr->step) param.step != itr->step)
{ {
RARCH_ERR("[Vulkan]: Duplicate parameters found for \"%s\", but arguments do not match.\n", RARCH_ERR("[Vulkan]: Duplicate parameters"
" found for \"%s\", but arguments do not match.\n",
itr->id); itr->id);
mismatch_dup = true; mismatch_dup = true;
} }
@ -70,7 +76,7 @@ bool slang_preprocess_parse_parameters(glslang_meta& meta,
p.initial = param.initial; p.initial = param.initial;
p.minimum = param.minimum; p.minimum = param.minimum;
p.maximum = param.maximum; p.maximum = param.maximum;
p.step = param.step; p.step = param.step;
p.current = param.initial; p.current = param.initial;
} }
@ -82,12 +88,11 @@ bool slang_preprocess_parse_parameters(const char *shader_path,
{ {
glslang_meta meta; glslang_meta meta;
vector<string> lines; vector<string> lines;
if (!glslang_read_shader_file(shader_path, &lines, true)) if (!glslang_read_shader_file(shader_path, &lines, true))
return false; return false;
if (!glslang_parse_meta(lines, &meta)) if (!glslang_parse_meta(lines, &meta))
return false; return false;
return slang_preprocess_parse_parameters(meta, shader); return slang_preprocess_parse_parameters(meta, shader);
} }

View File

@ -17,7 +17,8 @@ using namespace spirv_cross;
using namespace std; using namespace std;
template <typename P> template <typename P>
static bool set_unique_map(unordered_map<string, P>& m, const string& name, const P& p) static bool set_unique_map(unordered_map<string, P>& m,
const string& name, const P& p)
{ {
auto itr = m.find(name); auto itr = m.find(name);
if (itr != end(m)) if (itr != end(m))
@ -31,7 +32,8 @@ static bool set_unique_map(unordered_map<string, P>& m, const string& name, cons
} }
template <typename M, typename S> template <typename M, typename S>
static string get_semantic_name(const unordered_map<string, M>* map, S semantic, unsigned index) static string get_semantic_name(const unordered_map<string, M>* map,
S semantic, unsigned index)
{ {
for (const pair<string, M>& m : *map) for (const pair<string, M>& m : *map)
{ {
@ -42,7 +44,8 @@ static string get_semantic_name(const unordered_map<string, M>* map, S semantic,
} }
static string static string
get_semantic_name(slang_reflection& reflection, slang_semantic semantic, unsigned index) get_semantic_name(slang_reflection& reflection,
slang_semantic semantic, unsigned index)
{ {
static const char* names[] = { static const char* names[] = {
"MVP", "MVP",
@ -57,7 +60,8 @@ get_semantic_name(slang_reflection& reflection, slang_semantic semantic, unsigne
} }
static string static string
get_semantic_name(slang_reflection& reflection, slang_texture_semantic semantic, unsigned index) get_semantic_name(slang_reflection& reflection,
slang_texture_semantic semantic, unsigned index)
{ {
static const char* names[] = { static const char* names[] = {
"Original", "Source", "OriginalHistory", "PassOutput", "PassFeedback", "Original", "Source", "OriginalHistory", "PassOutput", "PassFeedback",
@ -71,7 +75,8 @@ get_semantic_name(slang_reflection& reflection, slang_texture_semantic semantic,
} }
static string get_size_semantic_name( static string get_size_semantic_name(
slang_reflection& reflection, slang_texture_semantic semantic, unsigned index) slang_reflection& reflection,
slang_texture_semantic semantic, unsigned index)
{ {
static const char* names[] = { static const char* names[] = {
"OriginalSize", "SourceSize", "OriginalHistorySize", "PassOutputSize", "PassFeedbackSize", "OriginalSize", "SourceSize", "OriginalHistorySize", "PassOutputSize", "PassFeedbackSize",
@ -96,6 +101,8 @@ static bool slang_process_reflection(
{ {
int semantic; int semantic;
unsigned i; unsigned i;
vector<texture_sem_t> textures;
vector<uniform_sem_t> uniforms[SLANG_CBUFFER_MAX];
unordered_map<string, slang_texture_semantic_map> texture_semantic_map; unordered_map<string, slang_texture_semantic_map> texture_semantic_map;
unordered_map<string, slang_texture_semantic_map> texture_semantic_uniform_map; unordered_map<string, slang_texture_semantic_map> texture_semantic_uniform_map;
@ -108,22 +115,26 @@ static bool slang_process_reflection(
if (!set_unique_map( if (!set_unique_map(
texture_semantic_map, name, texture_semantic_map, name,
slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i })) slang_texture_semantic_map{
SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i }))
return false; return false;
if (!set_unique_map( if (!set_unique_map(
texture_semantic_uniform_map, name + "Size", texture_semantic_uniform_map, name + "Size",
slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i })) slang_texture_semantic_map{
SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i }))
return false; return false;
if (!set_unique_map( if (!set_unique_map(
texture_semantic_map, name + "Feedback", texture_semantic_map, name + "Feedback",
slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i })) slang_texture_semantic_map{
SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i }))
return false; return false;
if (!set_unique_map( if (!set_unique_map(
texture_semantic_uniform_map, name + "FeedbackSize", texture_semantic_uniform_map, name + "FeedbackSize",
slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i })) slang_texture_semantic_map{
SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i }))
return false; return false;
} }
@ -131,12 +142,15 @@ static bool slang_process_reflection(
{ {
if (!set_unique_map( if (!set_unique_map(
texture_semantic_map, shader_info->lut[i].id, texture_semantic_map, shader_info->lut[i].id,
slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_USER, i })) slang_texture_semantic_map{
SLANG_TEXTURE_SEMANTIC_USER, i }))
return false; return false;
if (!set_unique_map( if (!set_unique_map(
texture_semantic_uniform_map, string(shader_info->lut[i].id) + "Size", texture_semantic_uniform_map,
slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_USER, i })) string(shader_info->lut[i].id) + "Size",
slang_texture_semantic_map{
SLANG_TEXTURE_SEMANTIC_USER, i }))
return false; return false;
} }
@ -156,9 +170,11 @@ static bool slang_process_reflection(
sl_reflection.texture_semantic_uniform_map = &texture_semantic_uniform_map; sl_reflection.texture_semantic_uniform_map = &texture_semantic_uniform_map;
sl_reflection.semantic_map = &uniform_semantic_map; sl_reflection.semantic_map = &uniform_semantic_map;
if (!slang_reflect(*vs_compiler, *ps_compiler, vs_resources, ps_resources, &sl_reflection)) if (!slang_reflect(*vs_compiler, *ps_compiler,
vs_resources, ps_resources, &sl_reflection))
{ {
RARCH_ERR("[slang]: Failed to reflect SPIR-V. Resource usage is inconsistent with " RARCH_ERR("[slang]: Failed to reflect SPIR-V."
" Resource usage is inconsistent with "
"expectations.\n"); "expectations.\n");
return false; return false;
} }
@ -170,18 +186,17 @@ static bool slang_process_reflection(
out->cbuffers[SLANG_CBUFFER_PC].binding = sl_reflection.ubo_binding ? 0 : 1; out->cbuffers[SLANG_CBUFFER_PC].binding = sl_reflection.ubo_binding ? 0 : 1;
out->cbuffers[SLANG_CBUFFER_PC].size = (sl_reflection.push_constant_size + 0xF) & ~0xF; out->cbuffers[SLANG_CBUFFER_PC].size = (sl_reflection.push_constant_size + 0xF) & ~0xF;
vector<uniform_sem_t> uniforms[SLANG_CBUFFER_MAX];
vector<texture_sem_t> textures;
for (semantic = 0; semantic < SLANG_NUM_BASE_SEMANTICS; semantic++) for (semantic = 0; semantic < SLANG_NUM_BASE_SEMANTICS; semantic++)
{ {
slang_semantic_meta& src = sl_reflection.semantics[semantic]; slang_semantic_meta& src = sl_reflection.semantics[semantic];
if (src.push_constant || src.uniform) if (src.push_constant || src.uniform)
{ {
uniform_sem_t uniform = { map->uniforms[semantic], uniform_sem_t uniform = { map->uniforms[semantic],
src.num_components * (unsigned)sizeof(float) }; src.num_components
* (unsigned)sizeof(float) };
string uniform_id = get_semantic_name(
sl_reflection, (slang_semantic)semantic, 0);
string uniform_id = get_semantic_name(sl_reflection, (slang_semantic)semantic, 0);
strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id));
if (src.push_constant) if (src.push_constant)
@ -203,9 +218,11 @@ static bool slang_process_reflection(
if (src.push_constant || src.uniform) if (src.push_constant || src.uniform)
{ {
uniform_sem_t uniform = { &shader_info->parameters[i].current, sizeof(float) }; uniform_sem_t uniform = {
&shader_info->parameters[i].current, sizeof(float) };
string uniform_id = get_semantic_name(sl_reflection, SLANG_SEMANTIC_FLOAT_PARAMETER, i); string uniform_id = get_semantic_name(
sl_reflection, SLANG_SEMANTIC_FLOAT_PARAMETER, i);
strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id));
if (src.push_constant) if (src.push_constant)
@ -225,9 +242,11 @@ static bool slang_process_reflection(
{ {
unsigned index; unsigned index;
for (index = 0; index < sl_reflection.semantic_textures[semantic].size(); index++) for (index = 0; index <
sl_reflection.semantic_textures[semantic].size(); index++)
{ {
slang_texture_semantic_meta& src = sl_reflection.semantic_textures[semantic][index]; slang_texture_semantic_meta& src =
sl_reflection.semantic_textures[semantic][index];
if (src.stage_mask) if (src.stage_mask)
{ {
@ -237,17 +256,18 @@ static bool slang_process_reflection(
if (semantic == SLANG_TEXTURE_SEMANTIC_USER) if (semantic == SLANG_TEXTURE_SEMANTIC_USER)
{ {
texture.wrap = shader_info->lut[index].wrap; texture.wrap = shader_info->lut[index].wrap;
texture.filter = shader_info->lut[index].filter; texture.filter = shader_info->lut[index].filter;
} }
else else
{ {
texture.wrap = shader_info->pass[pass_number].wrap; texture.wrap = shader_info->pass[pass_number].wrap;
texture.filter = shader_info->pass[pass_number].filter; texture.filter = shader_info->pass[pass_number].filter;
} }
texture.stage_mask = src.stage_mask; texture.stage_mask = src.stage_mask;
texture.binding = src.binding; texture.binding = src.binding;
string id = get_semantic_name(sl_reflection, (slang_texture_semantic)semantic, index); string id = get_semantic_name(
sl_reflection, (slang_texture_semantic)semantic, index);
strncpy(texture.id, id.c_str(), sizeof(texture.id)); strncpy(texture.id, id.c_str(), sizeof(texture.id));
@ -264,12 +284,15 @@ static bool slang_process_reflection(
if (src.push_constant || src.uniform) if (src.push_constant || src.uniform)
{ {
uniform_sem_t uniform = { uniform_sem_t uniform = {
(void*)((uintptr_t)map->textures[semantic].size + index * map->textures[semantic].size_stride), (void*)((uintptr_t)map->textures[semantic].size
+ index * map->textures[semantic].size_stride),
4 * sizeof(float) 4 * sizeof(float)
}; };
string uniform_id = string uniform_id =
get_size_semantic_name(sl_reflection, (slang_texture_semantic)semantic, index); get_size_semantic_name(
sl_reflection,
(slang_texture_semantic)semantic, index);
strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id));
@ -290,8 +313,10 @@ static bool slang_process_reflection(
out->texture_count = textures.size(); out->texture_count = textures.size();
textures.push_back({ NULL }); textures.push_back({ NULL });
out->textures = (texture_sem_t*)malloc(textures.size() * sizeof(*textures.data())); out->textures = (texture_sem_t*)
memcpy(out->textures, textures.data(), textures.size() * sizeof(*textures.data())); malloc(textures.size() * sizeof(*textures.data()));
memcpy(out->textures, textures.data(),
textures.size() * sizeof(*textures.data()));
for (i = 0; i < SLANG_CBUFFER_MAX; i++) for (i = 0; i < SLANG_CBUFFER_MAX; i++)
{ {
@ -302,7 +327,9 @@ static bool slang_process_reflection(
uniforms[i].push_back({ NULL }); uniforms[i].push_back({ NULL });
out->cbuffers[i].uniforms = out->cbuffers[i].uniforms =
(uniform_sem_t*)malloc(uniforms[i].size() * sizeof(*uniforms[i].data())); (uniform_sem_t*)
malloc(uniforms[i].size() * sizeof(*uniforms[i].data()));
memcpy( memcpy(
out->cbuffers[i].uniforms, uniforms[i].data(), out->cbuffers[i].uniforms, uniforms[i].data(),
uniforms[i].size() * sizeof(*uniforms[i].data())); uniforms[i].size() * sizeof(*uniforms[i].data()));
@ -319,10 +346,10 @@ bool slang_process(
const semantics_map_t* semantics_map, const semantics_map_t* semantics_map,
pass_semantics_t* out) pass_semantics_t* out)
{ {
glslang_output output;
Compiler* vs_compiler = NULL; Compiler* vs_compiler = NULL;
Compiler* ps_compiler = NULL; Compiler* ps_compiler = NULL;
video_shader_pass& pass = shader_info->pass[pass_number]; video_shader_pass& pass = shader_info->pass[pass_number];
glslang_output output;
if (!glslang_compile_shader(pass.source.path, &output)) if (!glslang_compile_shader(pass.source.path, &output))
return false; return false;
@ -370,9 +397,11 @@ bool slang_process(
ps_resources = ps_compiler->get_shader_resources(); ps_resources = ps_compiler->get_shader_resources();
if (!vs_resources.uniform_buffers.empty()) if (!vs_resources.uniform_buffers.empty())
vs_compiler->set_decoration(vs_resources.uniform_buffers[0].id, spv::DecorationBinding, 0); vs_compiler->set_decoration(
vs_resources.uniform_buffers[0].id, spv::DecorationBinding, 0);
if (!ps_resources.uniform_buffers.empty()) if (!ps_resources.uniform_buffers.empty())
ps_compiler->set_decoration(ps_resources.uniform_buffers[0].id, spv::DecorationBinding, 0); ps_compiler->set_decoration(
ps_resources.uniform_buffers[0].id, spv::DecorationBinding, 0);
if (!vs_resources.push_constant_buffers.empty()) if (!vs_resources.push_constant_buffers.empty())
vs_compiler->set_decoration( vs_compiler->set_decoration(
@ -390,12 +419,12 @@ bool slang_process(
vs->set_options(options); vs->set_options(options);
ps->set_options(options); ps->set_options(options);
#if 0 #if 0
CompilerGLSL::Options glsl_options; CompilerGLSL::Options glsl_options;
glsl_options.vertex.flip_vert_y = true; glsl_options.vertex.flip_vert_y = true;
((CompilerGLSL*)vs)->set_options(glsl_options); ((CompilerGLSL*)vs)->set_options(glsl_options);
((CompilerGLSL*)ps)->set_options(glsl_options); ((CompilerGLSL*)ps)->set_options(glsl_options);
#endif #endif
/* not exactly a vertex attribute but this remaps /* not exactly a vertex attribute but this remaps
* float2 FragCoord :TEXCOORD# to float4 FragCoord : SV_POSITION */ * float2 FragCoord :TEXCOORD# to float4 FragCoord : SV_POSITION */
@ -404,9 +433,7 @@ bool slang_process(
VariableTypeRemapCallback ps_var_remap_cb = VariableTypeRemapCallback ps_var_remap_cb =
[&](const SPIRType& type, const std::string& var_name, std::string& name_of_type) { [&](const SPIRType& type, const std::string& var_name, std::string& name_of_type) {
if (var_name == "FragCoord") if (var_name == "FragCoord")
{
name_of_type = "float4"; name_of_type = "float4";
}
}; };
for (Resource& resource : ps_resources.stage_inputs) for (Resource& resource : ps_resources.stage_inputs)
{ {
@ -440,11 +467,13 @@ bool slang_process(
pass.source.string.fragment = strdup(ps_code.c_str()); pass.source.string.fragment = strdup(ps_code.c_str());
if (!slang_process_reflection( if (!slang_process_reflection(
vs_compiler, ps_compiler, vs_resources, ps_resources, shader_info, pass_number, vs_compiler, ps_compiler,
vs_resources, ps_resources, shader_info, pass_number,
semantics_map, out)) semantics_map, out))
goto error; goto error;
} catch (const std::exception& e) }
catch (const std::exception& e)
{ {
RARCH_ERR("[slang]: SPIRV-Cross threw exception: %s.\n", e.what()); RARCH_ERR("[slang]: SPIRV-Cross threw exception: %s.\n", e.what());
goto error; goto error;

View File

@ -83,12 +83,13 @@ static slang_texture_semantic slang_name_to_texture_semantic_array(const string
unsigned i = 0; unsigned i = 0;
while (*names) while (*names)
{ {
auto n = *names; auto n = *names;
auto semantic = static_cast<slang_texture_semantic>(i); auto semantic = static_cast<slang_texture_semantic>(i);
if (slang_texture_semantic_is_array(semantic)) if (slang_texture_semantic_is_array(semantic))
{ {
size_t baselen = strlen(n); size_t baselen = strlen(n);
int cmp = strncmp(n, name.c_str(), baselen); int cmp = strncmp(n, name.c_str(), baselen);
if (cmp == 0) if (cmp == 0)
{ {
@ -190,7 +191,7 @@ static bool set_ubo_texture_offset(slang_reflection *reflection,
} }
} }
active = true; active = true;
active_offset = offset; active_offset = offset;
return true; return true;
} }
@ -279,7 +280,7 @@ static bool validate_type_for_semantic(const SPIRType &type, slang_semantic sem)
return type.basetype == SPIRType::Float && type.vecsize == 4 && type.columns == 4; return type.basetype == SPIRType::Float && type.vecsize == 4 && type.columns == 4;
/* uint */ /* uint */
case SLANG_SEMANTIC_FRAME_COUNT: case SLANG_SEMANTIC_FRAME_COUNT:
return type.basetype == SPIRType::UInt && type.vecsize == 1 && type.columns == 1; return type.basetype == SPIRType::UInt && type.vecsize == 1 && type.columns == 1;
/* float */ /* float */
case SLANG_SEMANTIC_FLOAT_PARAMETER: case SLANG_SEMANTIC_FLOAT_PARAMETER:
return type.basetype == SPIRType::Float && type.vecsize == 1 && type.columns == 1; return type.basetype == SPIRType::Float && type.vecsize == 1 && type.columns == 1;
@ -303,13 +304,13 @@ static bool add_active_buffer_ranges(const Compiler &compiler, const Resource &r
auto ranges = compiler.get_active_buffer_ranges(resource.id); auto ranges = compiler.get_active_buffer_ranges(resource.id);
for (auto &range : ranges) for (auto &range : ranges)
{ {
auto &name = compiler.get_member_name(resource.base_type_id, range.index); auto &name = compiler.get_member_name(resource.base_type_id, range.index);
auto &type = compiler.get_type(compiler.get_type(resource.base_type_id).member_types[range.index]); auto &type = compiler.get_type(compiler.get_type(resource.base_type_id).member_types[range.index]);
unsigned sem_index = 0; unsigned sem_index = 0;
unsigned tex_sem_index = 0; unsigned tex_sem_index = 0;
auto sem = slang_uniform_name_to_semantic(*reflection->semantic_map, name, &sem_index); auto sem = slang_uniform_name_to_semantic(*reflection->semantic_map, name, &sem_index);
auto tex_sem = slang_uniform_name_to_texture_semantic(*reflection->texture_semantic_uniform_map, auto tex_sem = slang_uniform_name_to_texture_semantic(*reflection->texture_semantic_uniform_map,
name, &tex_sem_index); name, &tex_sem_index);
if (tex_sem == SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT && tex_sem_index >= reflection->pass_number) if (tex_sem == SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT && tex_sem_index >= reflection->pass_number)
@ -658,14 +659,15 @@ bool slang_reflect_spirv(const std::vector<uint32_t> &vertex,
{ {
Compiler vertex_compiler(vertex); Compiler vertex_compiler(vertex);
Compiler fragment_compiler(fragment); Compiler fragment_compiler(fragment);
auto vertex_resources = vertex_compiler.get_shader_resources(); auto vertex_resources = vertex_compiler.get_shader_resources();
auto fragment_resources = fragment_compiler.get_shader_resources(); auto fragment_resources = fragment_compiler.get_shader_resources();
if (!slang_reflect(vertex_compiler, fragment_compiler, if (!slang_reflect(vertex_compiler, fragment_compiler,
vertex_resources, fragment_resources, vertex_resources, fragment_resources,
reflection)) reflection))
{ {
RARCH_ERR("[slang]: Failed to reflect SPIR-V. Resource usage is inconsistent with expectations.\n"); RARCH_ERR("[slang]: Failed to reflect SPIR-V."
" Resource usage is inconsistent with expectations.\n");
return false; return false;
} }