(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 <string>
#include <algorithm>
#include <compat/strl.h>
#include "../../verbosity.h"
#include "../../libretro-common/include/compat/strl.h"
using namespace std;
@ -28,28 +30,32 @@ bool slang_preprocess_parse_parameters(glslang_meta& meta,
{
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)
{
bool mismatch_dup = false;
bool dup = false;
auto itr = find_if(shader->parameters, shader->parameters + shader->num_parameters,
[&](const video_shader_parameter &parsed_param) {
bool dup = false;
auto itr = find_if(shader->parameters,
shader->parameters + shader->num_parameters,
[&](const video_shader_parameter &parsed_param)
{
return param.id == parsed_param.id;
});
if (itr != shader->parameters + shader->num_parameters)
{
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 ||
param.initial != itr->initial ||
param.minimum != itr->minimum ||
param.maximum != itr->maximum ||
param.step != itr->step)
param.initial != itr->initial ||
param.minimum != itr->minimum ||
param.maximum != itr->maximum ||
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);
mismatch_dup = true;
}
@ -70,7 +76,7 @@ bool slang_preprocess_parse_parameters(glslang_meta& meta,
p.initial = param.initial;
p.minimum = param.minimum;
p.maximum = param.maximum;
p.step = param.step;
p.step = param.step;
p.current = param.initial;
}
@ -82,12 +88,11 @@ bool slang_preprocess_parse_parameters(const char *shader_path,
{
glslang_meta meta;
vector<string> lines;
if (!glslang_read_shader_file(shader_path, &lines, true))
return false;
if (!glslang_parse_meta(lines, &meta))
return false;
return slang_preprocess_parse_parameters(meta, shader);
}

View File

@ -17,7 +17,8 @@ using namespace spirv_cross;
using namespace std;
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);
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>
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)
{
@ -42,7 +44,8 @@ static string get_semantic_name(const unordered_map<string, M>* map, S semantic,
}
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[] = {
"MVP",
@ -57,7 +60,8 @@ get_semantic_name(slang_reflection& reflection, slang_semantic semantic, unsigne
}
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[] = {
"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(
slang_reflection& reflection, slang_texture_semantic semantic, unsigned index)
slang_reflection& reflection,
slang_texture_semantic semantic, unsigned index)
{
static const char* names[] = {
"OriginalSize", "SourceSize", "OriginalHistorySize", "PassOutputSize", "PassFeedbackSize",
@ -96,6 +101,8 @@ static bool slang_process_reflection(
{
int semantic;
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_uniform_map;
@ -108,22 +115,26 @@ static bool slang_process_reflection(
if (!set_unique_map(
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;
if (!set_unique_map(
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;
if (!set_unique_map(
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;
if (!set_unique_map(
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;
}
@ -131,12 +142,15 @@ static bool slang_process_reflection(
{
if (!set_unique_map(
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;
if (!set_unique_map(
texture_semantic_uniform_map, string(shader_info->lut[i].id) + "Size",
slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_USER, i }))
texture_semantic_uniform_map,
string(shader_info->lut[i].id) + "Size",
slang_texture_semantic_map{
SLANG_TEXTURE_SEMANTIC_USER, i }))
return false;
}
@ -156,9 +170,11 @@ static bool slang_process_reflection(
sl_reflection.texture_semantic_uniform_map = &texture_semantic_uniform_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");
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].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++)
{
slang_semantic_meta& src = sl_reflection.semantics[semantic];
if (src.push_constant || src.uniform)
{
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));
if (src.push_constant)
@ -203,9 +218,11 @@ static bool slang_process_reflection(
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));
if (src.push_constant)
@ -225,9 +242,11 @@ static bool slang_process_reflection(
{
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)
{
@ -237,17 +256,18 @@ static bool slang_process_reflection(
if (semantic == SLANG_TEXTURE_SEMANTIC_USER)
{
texture.wrap = shader_info->lut[index].wrap;
texture.filter = shader_info->lut[index].filter;
texture.wrap = shader_info->lut[index].wrap;
texture.filter = shader_info->lut[index].filter;
}
else
{
texture.wrap = shader_info->pass[pass_number].wrap;
texture.filter = shader_info->pass[pass_number].filter;
texture.wrap = shader_info->pass[pass_number].wrap;
texture.filter = shader_info->pass[pass_number].filter;
}
texture.stage_mask = src.stage_mask;
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));
@ -264,12 +284,15 @@ static bool slang_process_reflection(
if (src.push_constant || src.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)
};
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));
@ -290,8 +313,10 @@ static bool slang_process_reflection(
out->texture_count = textures.size();
textures.push_back({ NULL });
out->textures = (texture_sem_t*)malloc(textures.size() * sizeof(*textures.data()));
memcpy(out->textures, textures.data(), textures.size() * sizeof(*textures.data()));
out->textures = (texture_sem_t*)
malloc(textures.size() * sizeof(*textures.data()));
memcpy(out->textures, textures.data(),
textures.size() * sizeof(*textures.data()));
for (i = 0; i < SLANG_CBUFFER_MAX; i++)
{
@ -302,7 +327,9 @@ static bool slang_process_reflection(
uniforms[i].push_back({ NULL });
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(
out->cbuffers[i].uniforms, uniforms[i].data(),
uniforms[i].size() * sizeof(*uniforms[i].data()));
@ -319,10 +346,10 @@ bool slang_process(
const semantics_map_t* semantics_map,
pass_semantics_t* out)
{
glslang_output output;
Compiler* vs_compiler = NULL;
Compiler* ps_compiler = NULL;
video_shader_pass& pass = shader_info->pass[pass_number];
glslang_output output;
if (!glslang_compile_shader(pass.source.path, &output))
return false;
@ -370,9 +397,11 @@ bool slang_process(
ps_resources = ps_compiler->get_shader_resources();
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())
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())
vs_compiler->set_decoration(
@ -390,12 +419,12 @@ bool slang_process(
vs->set_options(options);
ps->set_options(options);
#if 0
#if 0
CompilerGLSL::Options glsl_options;
glsl_options.vertex.flip_vert_y = true;
((CompilerGLSL*)vs)->set_options(glsl_options);
((CompilerGLSL*)ps)->set_options(glsl_options);
#endif
#endif
/* not exactly a vertex attribute but this remaps
* float2 FragCoord :TEXCOORD# to float4 FragCoord : SV_POSITION */
@ -404,9 +433,7 @@ bool slang_process(
VariableTypeRemapCallback ps_var_remap_cb =
[&](const SPIRType& type, const std::string& var_name, std::string& name_of_type) {
if (var_name == "FragCoord")
{
name_of_type = "float4";
}
};
for (Resource& resource : ps_resources.stage_inputs)
{
@ -440,11 +467,13 @@ bool slang_process(
pass.source.string.fragment = strdup(ps_code.c_str());
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))
goto error;
} catch (const std::exception& e)
}
catch (const std::exception& e)
{
RARCH_ERR("[slang]: SPIRV-Cross threw exception: %s.\n", e.what());
goto error;

View File

@ -83,12 +83,13 @@ static slang_texture_semantic slang_name_to_texture_semantic_array(const string
unsigned i = 0;
while (*names)
{
auto n = *names;
auto n = *names;
auto semantic = static_cast<slang_texture_semantic>(i);
if (slang_texture_semantic_is_array(semantic))
{
size_t baselen = strlen(n);
int cmp = strncmp(n, name.c_str(), baselen);
int cmp = strncmp(n, name.c_str(), baselen);
if (cmp == 0)
{
@ -190,7 +191,7 @@ static bool set_ubo_texture_offset(slang_reflection *reflection,
}
}
active = true;
active = true;
active_offset = offset;
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;
/* uint */
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 */
case SLANG_SEMANTIC_FLOAT_PARAMETER:
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);
for (auto &range : ranges)
{
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 &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]);
unsigned sem_index = 0;
unsigned sem_index = 0;
unsigned tex_sem_index = 0;
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 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,
name, &tex_sem_index);
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 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();
if (!slang_reflect(vertex_compiler, fragment_compiler,
vertex_resources, fragment_resources,
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;
}