mirror of
https://github.com/libretro/RetroArch
synced 2025-02-09 00:40:09 +00:00
Merge pull request #3316 from Themaister/master
Vulkan: Add shader parameters
This commit is contained in:
commit
1ec84ca44d
@ -16,6 +16,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <streams/file_stream.h>
|
#include <streams/file_stream.h>
|
||||||
#include <lists/string_list.h>
|
#include <lists/string_list.h>
|
||||||
@ -252,6 +253,9 @@ static glslang_format glslang_find_format(const char *fmt)
|
|||||||
|
|
||||||
static bool glslang_parse_meta(const vector<string> &lines, glslang_meta *meta)
|
static bool glslang_parse_meta(const vector<string> &lines, glslang_meta *meta)
|
||||||
{
|
{
|
||||||
|
char id[64] = {};
|
||||||
|
char desc[64] = {};
|
||||||
|
|
||||||
*meta = glslang_meta{};
|
*meta = glslang_meta{};
|
||||||
for (auto &line : lines)
|
for (auto &line : lines)
|
||||||
{
|
{
|
||||||
@ -268,6 +272,46 @@ static bool glslang_parse_meta(const vector<string> &lines, glslang_meta *meta)
|
|||||||
str++;
|
str++;
|
||||||
meta->name = str;
|
meta->name = str;
|
||||||
}
|
}
|
||||||
|
else if (line.find("#pragma parameter ") == 0)
|
||||||
|
{
|
||||||
|
float initial, minimum, maximum, step;
|
||||||
|
int ret = sscanf(line.c_str(), "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f",
|
||||||
|
id, desc, &initial, &minimum, &maximum, &step);
|
||||||
|
|
||||||
|
if (ret == 5)
|
||||||
|
{
|
||||||
|
step = 0.1f * (maximum - minimum);
|
||||||
|
ret = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 6)
|
||||||
|
{
|
||||||
|
auto itr = find_if(begin(meta->parameters), end(meta->parameters), [&](const glslang_parameter ¶m) {
|
||||||
|
return param.id == id;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Allow duplicate #pragma parameter, but only if they are exactly the same.
|
||||||
|
if (itr != end(meta->parameters))
|
||||||
|
{
|
||||||
|
if (itr->desc != desc ||
|
||||||
|
itr->initial != initial ||
|
||||||
|
itr->minimum != minimum ||
|
||||||
|
itr->maximum != maximum ||
|
||||||
|
itr->step != step)
|
||||||
|
{
|
||||||
|
RARCH_ERR("[slang]: Duplicate parameters found for \"%s\", but arguments do not match.\n", id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
meta->parameters.push_back({ id, desc, initial, minimum, maximum, step });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RARCH_ERR("[slang]: Invalid #pragma parameter line: \"%s\".\n", line.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (line.find("#pragma format ") == 0)
|
else if (line.find("#pragma format ") == 0)
|
||||||
{
|
{
|
||||||
if (meta->rt_format != SLANG_FORMAT_UNKNOWN)
|
if (meta->rt_format != SLANG_FORMAT_UNKNOWN)
|
||||||
|
@ -63,8 +63,19 @@ enum glslang_format
|
|||||||
SLANG_FORMAT_UNKNOWN
|
SLANG_FORMAT_UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct glslang_parameter
|
||||||
|
{
|
||||||
|
std::string id;
|
||||||
|
std::string desc;
|
||||||
|
float initial;
|
||||||
|
float minimum;
|
||||||
|
float maximum;
|
||||||
|
float step;
|
||||||
|
};
|
||||||
|
|
||||||
struct glslang_meta
|
struct glslang_meta
|
||||||
{
|
{
|
||||||
|
std::vector<glslang_parameter> parameters;
|
||||||
std::string name;
|
std::string name;
|
||||||
glslang_format rt_format = SLANG_FORMAT_UNKNOWN;
|
glslang_format rt_format = SLANG_FORMAT_UNKNOWN;
|
||||||
};
|
};
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <algorithm>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@ -323,7 +324,7 @@ struct CommonResources
|
|||||||
|
|
||||||
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;
|
||||||
unordered_map<string, slang_semantic> semantic_map;
|
unique_ptr<video_shader> shader_preset;
|
||||||
|
|
||||||
VkDevice device;
|
VkDevice device;
|
||||||
};
|
};
|
||||||
@ -432,6 +433,8 @@ class Pass
|
|||||||
pass_number = pass;
|
pass_number = pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_parameter(unsigned parameter_index, const std::string &id);
|
||||||
|
|
||||||
void end_frame();
|
void end_frame();
|
||||||
void allocate_buffers();
|
void allocate_buffers();
|
||||||
|
|
||||||
@ -488,6 +491,7 @@ class Pass
|
|||||||
void build_semantic_vec4(uint8_t *data, slang_semantic semantic,
|
void build_semantic_vec4(uint8_t *data, slang_semantic semantic,
|
||||||
unsigned width, unsigned height);
|
unsigned width, unsigned height);
|
||||||
void build_semantic_uint(uint8_t *data, slang_semantic semantic, uint32_t value);
|
void build_semantic_uint(uint8_t *data, slang_semantic semantic, uint32_t value);
|
||||||
|
void build_semantic_parameter(uint8_t *data, unsigned index, float value);
|
||||||
void build_semantic_texture_vec4(uint8_t *data,
|
void build_semantic_texture_vec4(uint8_t *data,
|
||||||
slang_texture_semantic semantic,
|
slang_texture_semantic semantic,
|
||||||
unsigned width, unsigned height);
|
unsigned width, unsigned height);
|
||||||
@ -505,6 +509,16 @@ class Pass
|
|||||||
|
|
||||||
size_t ubo_offset = 0;
|
size_t ubo_offset = 0;
|
||||||
string pass_name;
|
string pass_name;
|
||||||
|
|
||||||
|
struct Parameter
|
||||||
|
{
|
||||||
|
string id;
|
||||||
|
unsigned index;
|
||||||
|
unsigned semantic_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
vector<Parameter> parameters;
|
||||||
|
vector<Parameter> filtered_parameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
// struct here since we're implementing the opaque typedef from C.
|
// struct here since we're implementing the opaque typedef from C.
|
||||||
@ -516,12 +530,12 @@ struct vulkan_filter_chain
|
|||||||
|
|
||||||
inline void set_shader_preset(unique_ptr<video_shader> shader)
|
inline void set_shader_preset(unique_ptr<video_shader> shader)
|
||||||
{
|
{
|
||||||
shader_preset = move(shader);
|
common.shader_preset = move(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline video_shader *get_shader_preset()
|
inline video_shader *get_shader_preset()
|
||||||
{
|
{
|
||||||
return shader_preset.get();
|
return common.shader_preset.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_pass_info(unsigned pass,
|
void set_pass_info(unsigned pass,
|
||||||
@ -544,6 +558,7 @@ struct vulkan_filter_chain
|
|||||||
void set_pass_name(unsigned pass, const char *name);
|
void set_pass_name(unsigned pass, const char *name);
|
||||||
|
|
||||||
void add_static_texture(unique_ptr<StaticTexture> texture);
|
void add_static_texture(unique_ptr<StaticTexture> texture);
|
||||||
|
void add_parameter(unsigned pass, unsigned parameter_index, const std::string &id);
|
||||||
void release_staging_buffers();
|
void release_staging_buffers();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -563,8 +578,6 @@ struct vulkan_filter_chain
|
|||||||
vulkan_filter_chain_swapchain_info swapchain_info;
|
vulkan_filter_chain_swapchain_info swapchain_info;
|
||||||
unsigned current_sync_index;
|
unsigned current_sync_index;
|
||||||
|
|
||||||
unique_ptr<video_shader> shader_preset;
|
|
||||||
|
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
void set_num_passes(unsigned passes);
|
void set_num_passes(unsigned passes);
|
||||||
@ -610,6 +623,11 @@ void vulkan_filter_chain::set_swapchain_info(
|
|||||||
set_num_sync_indices(info.num_indices);
|
set_num_sync_indices(info.num_indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vulkan_filter_chain::add_parameter(unsigned pass, unsigned index, const std::string &id)
|
||||||
|
{
|
||||||
|
passes[pass]->add_parameter(index, id);
|
||||||
|
}
|
||||||
|
|
||||||
void vulkan_filter_chain::set_num_sync_indices(unsigned num_indices)
|
void vulkan_filter_chain::set_num_sync_indices(unsigned num_indices)
|
||||||
{
|
{
|
||||||
execute_deferred();
|
execute_deferred();
|
||||||
@ -852,7 +870,6 @@ bool vulkan_filter_chain::init_alias()
|
|||||||
{
|
{
|
||||||
common.texture_semantic_map.clear();
|
common.texture_semantic_map.clear();
|
||||||
common.texture_semantic_uniform_map.clear();
|
common.texture_semantic_uniform_map.clear();
|
||||||
common.semantic_map.clear();
|
|
||||||
|
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (auto &pass : passes)
|
for (auto &pass : passes)
|
||||||
@ -1213,6 +1230,11 @@ Pass::~Pass()
|
|||||||
clear_vk();
|
clear_vk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pass::add_parameter(unsigned index, const std::string &id)
|
||||||
|
{
|
||||||
|
parameters.push_back({ id, index, unsigned(parameters.size()) });
|
||||||
|
}
|
||||||
|
|
||||||
void Pass::set_shader(VkShaderStageFlags stage,
|
void Pass::set_shader(VkShaderStageFlags stage,
|
||||||
const uint32_t *spirv,
|
const uint32_t *spirv,
|
||||||
size_t spirv_words)
|
size_t spirv_words)
|
||||||
@ -1693,15 +1715,33 @@ bool Pass::build()
|
|||||||
pass_info.rt_format, pass_info.max_levels));
|
pass_info.rt_format, pass_info.max_levels));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unordered_map<string, slang_semantic_map> semantic_map;
|
||||||
|
unsigned j = 0;
|
||||||
|
for (auto ¶m : parameters)
|
||||||
|
{
|
||||||
|
if (!set_unique_map(semantic_map, param.id,
|
||||||
|
slang_semantic_map{ SLANG_SEMANTIC_FLOAT_PARAMETER, j }))
|
||||||
|
return false;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
reflection = slang_reflection{};
|
reflection = slang_reflection{};
|
||||||
reflection.pass_number = pass_number;
|
reflection.pass_number = pass_number;
|
||||||
reflection.texture_semantic_map = &common->texture_semantic_map;
|
reflection.texture_semantic_map = &common->texture_semantic_map;
|
||||||
reflection.texture_semantic_uniform_map = &common->texture_semantic_uniform_map;
|
reflection.texture_semantic_uniform_map = &common->texture_semantic_uniform_map;
|
||||||
reflection.semantic_map = &common->semantic_map;
|
reflection.semantic_map = &semantic_map;
|
||||||
|
|
||||||
if (!slang_reflect_spirv(vertex_shader, fragment_shader, &reflection))
|
if (!slang_reflect_spirv(vertex_shader, fragment_shader, &reflection))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Filter out parameters which we will never use anyways.
|
||||||
|
filtered_parameters.clear();
|
||||||
|
for (unsigned i = 0; i < reflection.semantic_float_parameters.size(); i++)
|
||||||
|
{
|
||||||
|
if (reflection.semantic_float_parameters[i].uniform)
|
||||||
|
filtered_parameters.push_back(parameters[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (!init_pipeline())
|
if (!init_pipeline())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1801,6 +1841,13 @@ void Pass::build_semantic_vec4(uint8_t *data, slang_semantic semantic,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pass::build_semantic_parameter(uint8_t *data, unsigned index, float value)
|
||||||
|
{
|
||||||
|
// We will have filtered out stale parameters.
|
||||||
|
if (data)
|
||||||
|
*reinterpret_cast<float*>(data + reflection.semantic_float_parameters[index].ubo_offset) = value;
|
||||||
|
}
|
||||||
|
|
||||||
void Pass::build_semantic_uint(uint8_t *data, slang_semantic semantic,
|
void Pass::build_semantic_uint(uint8_t *data, slang_semantic semantic,
|
||||||
uint32_t value)
|
uint32_t value)
|
||||||
{
|
{
|
||||||
@ -1853,6 +1900,13 @@ void Pass::build_semantics(VkDescriptorSet set, uint8_t *buffer,
|
|||||||
// ORIGINAL_HISTORY[0] is an alias of ORIGINAL.
|
// ORIGINAL_HISTORY[0] is an alias of ORIGINAL.
|
||||||
build_semantic_texture_array(set, buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, 0, original);
|
build_semantic_texture_array(set, buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, 0, original);
|
||||||
|
|
||||||
|
// Parameters.
|
||||||
|
for (auto ¶m : filtered_parameters)
|
||||||
|
{
|
||||||
|
float value = common->shader_preset->parameters[param.index].current;
|
||||||
|
build_semantic_parameter(buffer, param.semantic_index, value);
|
||||||
|
}
|
||||||
|
|
||||||
// Previous inputs.
|
// Previous inputs.
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (auto &texture : common->original_history)
|
for (auto &texture : common->original_history)
|
||||||
@ -2736,7 +2790,6 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
video_shader_resolve_relative(shader.get(), path);
|
video_shader_resolve_relative(shader.get(), path);
|
||||||
video_shader_resolve_parameters(conf.get(), shader.get());
|
|
||||||
|
|
||||||
bool last_pass_is_fbo = shader->pass[shader->passes - 1].fbo.valid;
|
bool last_pass_is_fbo = shader->pass[shader->passes - 1].fbo.valid;
|
||||||
auto tmpinfo = *info;
|
auto tmpinfo = *info;
|
||||||
@ -2749,6 +2802,8 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
|||||||
if (shader->luts && !vulkan_filter_chain_load_luts(info, chain.get(), shader.get()))
|
if (shader->luts && !vulkan_filter_chain_load_luts(info, chain.get(), shader.get()))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
shader->num_parameters = 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < shader->passes; i++)
|
for (unsigned i = 0; i < shader->passes; i++)
|
||||||
{
|
{
|
||||||
const video_shader_pass *pass = &shader->pass[i];
|
const video_shader_pass *pass = &shader->pass[i];
|
||||||
@ -2765,6 +2820,49 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &meta_param : output.meta.parameters)
|
||||||
|
{
|
||||||
|
if (shader->num_parameters >= GFX_MAX_PARAMETERS)
|
||||||
|
{
|
||||||
|
RARCH_ERR("[Vulkan]: Exceeded maximum number of parameters.\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto itr = find_if(shader->parameters, shader->parameters + shader->num_parameters,
|
||||||
|
[&](const video_shader_parameter ¶m) {
|
||||||
|
return meta_param.id == param.id;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (itr != shader->parameters + shader->num_parameters)
|
||||||
|
{
|
||||||
|
// Allow duplicate #pragma parameter, but only if they are exactly the same.
|
||||||
|
if (meta_param.desc != itr->desc ||
|
||||||
|
meta_param.initial != itr->initial ||
|
||||||
|
meta_param.minimum != itr->minimum ||
|
||||||
|
meta_param.maximum != itr->maximum ||
|
||||||
|
meta_param.step != itr->step)
|
||||||
|
{
|
||||||
|
RARCH_ERR("[Vulkan]: Duplicate parameters found for \"%s\", but arguments do not match.\n",
|
||||||
|
itr->id);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
chain->add_parameter(i, itr - shader->parameters, meta_param.id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto ¶m = shader->parameters[shader->num_parameters];
|
||||||
|
strlcpy(param.id, meta_param.id.c_str(), sizeof(param.id));
|
||||||
|
strlcpy(param.desc, meta_param.desc.c_str(), sizeof(param.desc));
|
||||||
|
param.current = meta_param.initial;
|
||||||
|
param.initial = meta_param.initial;
|
||||||
|
param.minimum = meta_param.minimum;
|
||||||
|
param.maximum = meta_param.maximum;
|
||||||
|
param.step = meta_param.step;
|
||||||
|
chain->add_parameter(i, shader->num_parameters, meta_param.id);
|
||||||
|
shader->num_parameters++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chain->set_shader(i,
|
chain->set_shader(i,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT,
|
VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
output.vertex.data(),
|
output.vertex.data(),
|
||||||
@ -2917,6 +3015,9 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
|||||||
sizeof(opaque_frag) / sizeof(uint32_t));
|
sizeof(opaque_frag) / sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!video_shader_resolve_current_parameters(conf.get(), shader.get()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
chain->set_shader_preset(move(shader));
|
chain->set_shader_preset(move(shader));
|
||||||
|
|
||||||
if (!chain->init())
|
if (!chain->init())
|
||||||
|
@ -134,13 +134,18 @@ static slang_texture_semantic slang_uniform_name_to_texture_semantic(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static slang_semantic slang_uniform_name_to_semantic(
|
static slang_semantic slang_uniform_name_to_semantic(
|
||||||
const unordered_map<string, slang_semantic> &semantic_map,
|
const unordered_map<string, slang_semantic_map> &semantic_map,
|
||||||
const string &name)
|
const string &name, unsigned *index)
|
||||||
{
|
{
|
||||||
auto itr = semantic_map.find(name);
|
auto itr = semantic_map.find(name);
|
||||||
if (itr != end(semantic_map))
|
if (itr != end(semantic_map))
|
||||||
return itr->second;
|
{
|
||||||
|
*index = itr->second.index;
|
||||||
|
return itr->second.semantic;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No builtin semantics are arrayed.
|
||||||
|
*index = 0;
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (auto n : semantic_uniform_names)
|
for (auto n : semantic_uniform_names)
|
||||||
{
|
{
|
||||||
@ -183,6 +188,29 @@ static bool set_ubo_texture_offset(slang_reflection *reflection,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool set_ubo_float_parameter_offset(slang_reflection *reflection,
|
||||||
|
unsigned index, size_t offset, unsigned num_components)
|
||||||
|
{
|
||||||
|
resize_minimum(reflection->semantic_float_parameters, index + 1);
|
||||||
|
auto &sem = reflection->semantic_float_parameters[index];
|
||||||
|
|
||||||
|
if (sem.uniform)
|
||||||
|
{
|
||||||
|
if (sem.ubo_offset != offset)
|
||||||
|
{
|
||||||
|
RARCH_ERR("[slang]: Vertex and fragment have different offsets for same parameter #%u (%u vs. %u).\n",
|
||||||
|
index,
|
||||||
|
unsigned(sem.ubo_offset),
|
||||||
|
unsigned(offset));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sem.uniform = true;
|
||||||
|
sem.ubo_offset = offset;
|
||||||
|
sem.num_components = num_components;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool set_ubo_offset(slang_reflection *reflection, slang_semantic semantic,
|
static bool set_ubo_offset(slang_reflection *reflection, slang_semantic semantic,
|
||||||
size_t offset, unsigned num_components)
|
size_t offset, unsigned num_components)
|
||||||
{
|
{
|
||||||
@ -230,6 +258,10 @@ static bool validate_type_for_semantic(const SPIRType &type, slang_semantic sem)
|
|||||||
// uint
|
// uint
|
||||||
return type.basetype == SPIRType::UInt && type.vecsize == 1 && type.columns == 1;
|
return type.basetype == SPIRType::UInt && type.vecsize == 1 && type.columns == 1;
|
||||||
|
|
||||||
|
case SLANG_SEMANTIC_FLOAT_PARAMETER:
|
||||||
|
// float
|
||||||
|
return type.basetype == SPIRType::Float && type.vecsize == 1 && type.columns == 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// vec4
|
// vec4
|
||||||
return type.basetype == SPIRType::Float && type.vecsize == 4 && type.columns == 1;
|
return type.basetype == SPIRType::Float && type.vecsize == 4 && type.columns == 1;
|
||||||
@ -253,8 +285,9 @@ static bool add_active_buffer_ranges(const Compiler &compiler, const Resource &r
|
|||||||
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 tex_sem_index = 0;
|
unsigned tex_sem_index = 0;
|
||||||
auto sem = slang_uniform_name_to_semantic(*reflection->semantic_map, name);
|
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);
|
||||||
|
|
||||||
@ -273,8 +306,18 @@ static bool add_active_buffer_ranges(const Compiler &compiler, const Resource &r
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!set_ubo_offset(reflection, sem, range.offset, type.vecsize))
|
switch (sem)
|
||||||
return false;
|
{
|
||||||
|
case SLANG_SEMANTIC_FLOAT_PARAMETER:
|
||||||
|
if (!set_ubo_float_parameter_offset(reflection, sem_index, range.offset, type.vecsize))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (!set_ubo_offset(reflection, sem, range.offset, type.vecsize))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (tex_sem != SLANG_INVALID_TEXTURE_SEMANTIC)
|
else if (tex_sem != SLANG_INVALID_TEXTURE_SEMANTIC)
|
||||||
{
|
{
|
||||||
@ -510,6 +553,16 @@ static bool slang_reflect(const Compiler &vertex_compiler, const Compiler &fragm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RARCH_LOG("[slang]:\n");
|
||||||
|
RARCH_LOG("[slang]: Parameters:\n");
|
||||||
|
unsigned i = 0;
|
||||||
|
for (auto ¶m : reflection->semantic_float_parameters)
|
||||||
|
{
|
||||||
|
if (param.uniform)
|
||||||
|
RARCH_LOG("[slang]: #%u (Offset: %u)\n", i, param.ubo_offset);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,10 +59,16 @@ enum slang_texture_semantic
|
|||||||
|
|
||||||
enum slang_semantic
|
enum slang_semantic
|
||||||
{
|
{
|
||||||
|
// mat4, MVP
|
||||||
SLANG_SEMANTIC_MVP = 0,
|
SLANG_SEMANTIC_MVP = 0,
|
||||||
|
// vec4, viewport size of current pass
|
||||||
SLANG_SEMANTIC_OUTPUT = 1,
|
SLANG_SEMANTIC_OUTPUT = 1,
|
||||||
|
// vec4, viewport size of final pass
|
||||||
SLANG_SEMANTIC_FINAL_VIEWPORT = 2,
|
SLANG_SEMANTIC_FINAL_VIEWPORT = 2,
|
||||||
|
// uint, frame count with modulo
|
||||||
SLANG_SEMANTIC_FRAME_COUNT = 3,
|
SLANG_SEMANTIC_FRAME_COUNT = 3,
|
||||||
|
// float, user defined parameter, arrayed
|
||||||
|
SLANG_SEMANTIC_FLOAT_PARAMETER = 4,
|
||||||
|
|
||||||
SLANG_NUM_SEMANTICS,
|
SLANG_NUM_SEMANTICS,
|
||||||
SLANG_INVALID_SEMANTIC = -1
|
SLANG_INVALID_SEMANTIC = -1
|
||||||
@ -100,6 +106,12 @@ struct slang_texture_semantic_map
|
|||||||
unsigned index;
|
unsigned index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct slang_semantic_map
|
||||||
|
{
|
||||||
|
slang_semantic semantic;
|
||||||
|
unsigned index;
|
||||||
|
};
|
||||||
|
|
||||||
struct slang_reflection
|
struct slang_reflection
|
||||||
{
|
{
|
||||||
slang_reflection();
|
slang_reflection();
|
||||||
@ -110,10 +122,11 @@ struct slang_reflection
|
|||||||
|
|
||||||
std::vector<slang_texture_semantic_meta> semantic_textures[SLANG_NUM_TEXTURE_SEMANTICS];
|
std::vector<slang_texture_semantic_meta> semantic_textures[SLANG_NUM_TEXTURE_SEMANTICS];
|
||||||
slang_semantic_meta semantics[SLANG_NUM_SEMANTICS];
|
slang_semantic_meta semantics[SLANG_NUM_SEMANTICS];
|
||||||
|
std::vector<slang_semantic_meta> semantic_float_parameters;
|
||||||
|
|
||||||
const std::unordered_map<std::string, slang_texture_semantic_map> *texture_semantic_map = nullptr;
|
const std::unordered_map<std::string, slang_texture_semantic_map> *texture_semantic_map = nullptr;
|
||||||
const std::unordered_map<std::string, slang_texture_semantic_map> *texture_semantic_uniform_map = nullptr;
|
const std::unordered_map<std::string, slang_texture_semantic_map> *texture_semantic_uniform_map = nullptr;
|
||||||
const std::unordered_map<std::string, slang_semantic> *semantic_map = nullptr;
|
const std::unordered_map<std::string, slang_semantic_map> *semantic_map = nullptr;
|
||||||
unsigned pass_number = 0;
|
unsigned pass_number = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -391,6 +391,48 @@ static struct video_shader_parameter *video_shader_parse_find_parameter(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* video_shader_set_current_parameters:
|
||||||
|
* @conf : Preset file to read from.
|
||||||
|
* @shader : Shader passes handle.
|
||||||
|
*
|
||||||
|
* Reads the current value for all parameters from config file.
|
||||||
|
*
|
||||||
|
* Returns: true (1) if successful, otherwise false (0).
|
||||||
|
**/
|
||||||
|
bool video_shader_resolve_current_parameters(config_file_t *conf,
|
||||||
|
struct video_shader *shader)
|
||||||
|
{
|
||||||
|
if (!conf)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Read in parameters which override the defaults. */
|
||||||
|
char parameters[4096] = {0};
|
||||||
|
const char *id = NULL;
|
||||||
|
char *save = NULL;
|
||||||
|
|
||||||
|
if (!config_get_array(conf, "parameters",
|
||||||
|
parameters, sizeof(parameters)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (id = strtok_r(parameters, ";", &save); id;
|
||||||
|
id = strtok_r(NULL, ";", &save))
|
||||||
|
{
|
||||||
|
struct video_shader_parameter *parameter = (struct video_shader_parameter*)
|
||||||
|
video_shader_parse_find_parameter(shader->parameters, shader->num_parameters, id);
|
||||||
|
|
||||||
|
if (!parameter)
|
||||||
|
{
|
||||||
|
RARCH_WARN("[CGP/GLSLP]: Parameter %s is set in the preset, but no shader uses this parameter, ignoring.\n", id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config_get_float(conf, id, ¶meter->current))
|
||||||
|
RARCH_WARN("[CGP/GLSLP]: Parameter %s is not set in preset.\n", id);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* video_shader_resolve_parameters:
|
* video_shader_resolve_parameters:
|
||||||
* @conf : Preset file to read from.
|
* @conf : Preset file to read from.
|
||||||
@ -447,33 +489,8 @@ bool video_shader_resolve_parameters(config_file_t *conf,
|
|||||||
filestream_close(file);
|
filestream_close(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf)
|
if (conf && !video_shader_resolve_current_parameters(conf, shader))
|
||||||
{
|
return false;
|
||||||
/* Read in parameters which override the defaults. */
|
|
||||||
char parameters[4096] = {0};
|
|
||||||
const char *id = NULL;
|
|
||||||
char *save = NULL;
|
|
||||||
|
|
||||||
if (!config_get_array(conf, "parameters",
|
|
||||||
parameters, sizeof(parameters)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (id = strtok_r(parameters, ";", &save); id;
|
|
||||||
id = strtok_r(NULL, ";", &save))
|
|
||||||
{
|
|
||||||
struct video_shader_parameter *parameter = (struct video_shader_parameter*)
|
|
||||||
video_shader_parse_find_parameter(shader->parameters, shader->num_parameters, id);
|
|
||||||
|
|
||||||
if (!parameter)
|
|
||||||
{
|
|
||||||
RARCH_WARN("[CGP/GLSLP]: Parameter %s is set in the preset, but no shader uses this parameter, ignoring.\n", id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config_get_float(conf, id, ¶meter->current))
|
|
||||||
RARCH_WARN("[CGP/GLSLP]: Parameter %s is not set in preset.\n", id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -192,6 +192,18 @@ void video_shader_write_conf_cgp(config_file_t *conf,
|
|||||||
void video_shader_resolve_relative(struct video_shader *shader,
|
void video_shader_resolve_relative(struct video_shader *shader,
|
||||||
const char *ref_path);
|
const char *ref_path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* video_shader_resolve_parameters:
|
||||||
|
* @conf : Preset file to read from.
|
||||||
|
* @shader : Shader passes handle.
|
||||||
|
*
|
||||||
|
* Reads the current value for all parameters from config file.
|
||||||
|
*
|
||||||
|
* Returns: true (1) if successful, otherwise false (0).
|
||||||
|
**/
|
||||||
|
bool video_shader_resolve_current_parameters(config_file_t *conf,
|
||||||
|
struct video_shader *shader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* video_shader_resolve_parameters:
|
* video_shader_resolve_parameters:
|
||||||
* @conf : Preset file to read from.
|
* @conf : Preset file to read from.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user