mirror of
https://github.com/libretro/RetroArch
synced 2025-03-22 16:20:58 +00:00
Vulkan: Begin sketching out support for complete filter chain.
This commit is contained in:
parent
d3f0ca76bc
commit
4f3ade1b95
@ -708,11 +708,12 @@ bool Pass::init_pipeline_layout()
|
||||
}
|
||||
|
||||
// Semantic textures.
|
||||
for (unsigned i = 0; i < SLANG_NUM_TEXTURE_SEMANTICS; i++)
|
||||
for (auto &semantic : reflection.semantic_textures)
|
||||
{
|
||||
if (reflection.semantic_texture_mask & (1u << i))
|
||||
for (auto &texture : semantic)
|
||||
{
|
||||
auto &texture = reflection.semantic_textures[i];
|
||||
if (!texture.texture)
|
||||
continue;
|
||||
|
||||
VkShaderStageFlags stages = 0;
|
||||
if (texture.stage_mask & SLANG_STAGE_VERTEX_MASK)
|
||||
@ -1069,17 +1070,17 @@ void Pass::set_texture(VkDescriptorSet set, unsigned binding,
|
||||
void Pass::set_semantic_texture(VkDescriptorSet set,
|
||||
slang_texture_semantic semantic, const Texture &texture)
|
||||
{
|
||||
if (reflection.semantic_texture_mask & (1u << semantic))
|
||||
set_texture(set, reflection.semantic_textures[semantic].binding, texture);
|
||||
if (reflection.semantic_textures[semantic][0].texture)
|
||||
set_texture(set, reflection.semantic_textures[semantic][0].binding, texture);
|
||||
}
|
||||
|
||||
void Pass::build_semantic_texture_vec4(uint8_t *data, slang_texture_semantic semantic,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
if (data && (reflection.semantic_texture_ubo_mask & (1 << semantic)))
|
||||
if (data && reflection.semantic_textures[semantic][0].uniform)
|
||||
{
|
||||
build_vec4(
|
||||
reinterpret_cast<float *>(data + reflection.semantic_textures[semantic].ubo_offset),
|
||||
reinterpret_cast<float *>(data + reflection.semantic_textures[semantic][0].ubo_offset),
|
||||
width,
|
||||
height);
|
||||
}
|
||||
@ -1088,7 +1089,7 @@ void Pass::build_semantic_texture_vec4(uint8_t *data, slang_texture_semantic sem
|
||||
void Pass::build_semantic_vec4(uint8_t *data, slang_semantic semantic,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
if (data && (reflection.semantic_ubo_mask & (1 << semantic)))
|
||||
if (data && reflection.semantics[semantic].uniform)
|
||||
{
|
||||
build_vec4(
|
||||
reinterpret_cast<float *>(data + reflection.semantics[semantic].ubo_offset),
|
||||
@ -1108,7 +1109,7 @@ void Pass::build_semantic_texture(VkDescriptorSet set, uint8_t *buffer,
|
||||
void Pass::build_semantics(VkDescriptorSet set, uint8_t *buffer,
|
||||
const float *mvp, const Texture &original, const Texture &source)
|
||||
{
|
||||
if (buffer && (reflection.semantic_ubo_mask & (1u << SLANG_SEMANTIC_MVP)))
|
||||
if (buffer && reflection.semantics[SLANG_SEMANTIC_MVP].uniform)
|
||||
{
|
||||
size_t offset = reflection.semantics[SLANG_SEMANTIC_MVP].ubo_offset;
|
||||
if (mvp)
|
||||
|
@ -22,14 +22,46 @@
|
||||
using namespace std;
|
||||
using namespace spir2cross;
|
||||
|
||||
static bool slang_texture_semantic_is_array(slang_texture_semantic sem)
|
||||
{
|
||||
switch (sem)
|
||||
{
|
||||
case SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY:
|
||||
case SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT:
|
||||
case SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
slang_reflection::slang_reflection()
|
||||
{
|
||||
for (unsigned i = 0; i < SLANG_NUM_TEXTURE_SEMANTICS; i++)
|
||||
{
|
||||
semantic_textures[i].resize(
|
||||
slang_texture_semantic_is_array(static_cast<slang_texture_semantic>(i))
|
||||
? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *texture_semantic_names[] = {
|
||||
"Original",
|
||||
"Source",
|
||||
"OriginalHistory",
|
||||
"PassOutput",
|
||||
"PassFeedback",
|
||||
nullptr
|
||||
};
|
||||
|
||||
static const char *texture_semantic_uniform_names[] = {
|
||||
"OriginalSize",
|
||||
"SourceSize",
|
||||
"OriginalHistorySize",
|
||||
"PassOutputSize",
|
||||
"PassFeedbackSize",
|
||||
nullptr
|
||||
};
|
||||
|
||||
static const char *semantic_uniform_names[] = {
|
||||
@ -38,28 +70,45 @@ static const char *semantic_uniform_names[] = {
|
||||
"FinalViewportSize",
|
||||
};
|
||||
|
||||
static slang_texture_semantic slang_name_to_texture_semantic(const string &name)
|
||||
static slang_texture_semantic slang_name_to_texture_semantic_array(const string &name, const char **names,
|
||||
unsigned *index)
|
||||
{
|
||||
unsigned i = 0;
|
||||
for (auto n : texture_semantic_names)
|
||||
while (*names)
|
||||
{
|
||||
if (name == n)
|
||||
return static_cast<slang_texture_semantic>(i);
|
||||
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);
|
||||
|
||||
if (cmp == 0)
|
||||
{
|
||||
*index = strtoul(name.c_str() + baselen, nullptr, 0);
|
||||
return semantic;
|
||||
}
|
||||
}
|
||||
else if (name == n)
|
||||
{
|
||||
*index = 0;
|
||||
return semantic;
|
||||
}
|
||||
|
||||
i++;
|
||||
names++;
|
||||
}
|
||||
return SLANG_INVALID_TEXTURE_SEMANTIC;
|
||||
}
|
||||
|
||||
static slang_texture_semantic slang_uniform_name_to_texture_semantic(const string &name)
|
||||
static slang_texture_semantic slang_name_to_texture_semantic(const string &name, unsigned *index)
|
||||
{
|
||||
unsigned i = 0;
|
||||
for (auto n : texture_semantic_uniform_names)
|
||||
{
|
||||
if (name == n)
|
||||
return static_cast<slang_texture_semantic>(i);
|
||||
i++;
|
||||
}
|
||||
return SLANG_INVALID_TEXTURE_SEMANTIC;
|
||||
return slang_name_to_texture_semantic_array(name, texture_semantic_names, index);
|
||||
}
|
||||
|
||||
static slang_texture_semantic slang_uniform_name_to_texture_semantic(const string &name, unsigned *index)
|
||||
{
|
||||
return slang_name_to_texture_semantic_array(name, texture_semantic_uniform_names, index);
|
||||
}
|
||||
|
||||
static slang_semantic slang_uniform_name_to_semantic(const string &name)
|
||||
@ -75,50 +124,64 @@ static slang_semantic slang_uniform_name_to_semantic(const string &name)
|
||||
return SLANG_INVALID_SEMANTIC;
|
||||
}
|
||||
|
||||
static bool set_ubo_texture_offset(slang_reflection *reflection, slang_texture_semantic semantic,
|
||||
template <typename T>
|
||||
static void resize_minimum(T &vec, unsigned minimum)
|
||||
{
|
||||
if (vec.size() < minimum)
|
||||
vec.resize(minimum);
|
||||
}
|
||||
|
||||
static bool set_ubo_texture_offset(slang_reflection *reflection,
|
||||
slang_texture_semantic semantic, unsigned index,
|
||||
size_t offset)
|
||||
{
|
||||
if (reflection->semantic_texture_ubo_mask & (1u << semantic))
|
||||
resize_minimum(reflection->semantic_textures[semantic], index + 1);
|
||||
auto &sem = reflection->semantic_textures[semantic][index];
|
||||
|
||||
if (sem.uniform)
|
||||
{
|
||||
if (reflection->semantic_textures[semantic].ubo_offset != offset)
|
||||
if (sem.ubo_offset != offset)
|
||||
{
|
||||
RARCH_ERR("[slang]: Vertex and fragment have different offsets for same semantic %s (%u vs. %u).\n",
|
||||
RARCH_ERR("[slang]: Vertex and fragment have different offsets for same semantic %s #%u (%u vs. %u).\n",
|
||||
texture_semantic_uniform_names[semantic],
|
||||
unsigned(reflection->semantic_textures[semantic].ubo_offset),
|
||||
index,
|
||||
unsigned(sem.ubo_offset),
|
||||
unsigned(offset));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
reflection->semantic_texture_ubo_mask |= 1u << semantic;
|
||||
reflection->semantic_textures[semantic].ubo_offset = offset;
|
||||
sem.uniform = true;
|
||||
sem.ubo_offset = offset;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool set_ubo_offset(slang_reflection *reflection, slang_semantic semantic,
|
||||
size_t offset, unsigned num_components)
|
||||
{
|
||||
if (reflection->semantic_ubo_mask & (1u << semantic))
|
||||
auto &sem = reflection->semantics[semantic];
|
||||
|
||||
if (sem.uniform)
|
||||
{
|
||||
if (reflection->semantics[semantic].ubo_offset != offset)
|
||||
if (sem.ubo_offset != offset)
|
||||
{
|
||||
RARCH_ERR("[slang]: Vertex and fragment have different offsets for same semantic %s (%u vs. %u).\n",
|
||||
semantic_uniform_names[semantic],
|
||||
unsigned(reflection->semantics[semantic].ubo_offset),
|
||||
unsigned(sem.ubo_offset),
|
||||
unsigned(offset));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reflection->semantics[semantic].num_components != num_components)
|
||||
if (sem.num_components != num_components)
|
||||
{
|
||||
RARCH_ERR("[slang]: Vertex and fragment have different components for same semantic %s (%u vs. %u).\n",
|
||||
semantic_uniform_names[semantic],
|
||||
unsigned(reflection->semantics[semantic].num_components),
|
||||
unsigned(sem.num_components),
|
||||
unsigned(num_components));
|
||||
}
|
||||
}
|
||||
reflection->semantic_ubo_mask |= 1u << semantic;
|
||||
reflection->semantics[semantic].ubo_offset = offset;
|
||||
reflection->semantics[semantic].num_components = num_components;
|
||||
sem.uniform = true;
|
||||
sem.ubo_offset = offset;
|
||||
sem.num_components = num_components;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -157,8 +220,10 @@ static bool add_active_buffer_ranges(const Compiler &compiler, const Resource &r
|
||||
{
|
||||
auto &name = compiler.get_member_name(resource.type_id, range.index);
|
||||
auto &type = compiler.get_type(compiler.get_type(resource.type_id).member_types[range.index]);
|
||||
slang_semantic sem = slang_uniform_name_to_semantic(name);
|
||||
slang_texture_semantic tex_sem = slang_uniform_name_to_texture_semantic(name);
|
||||
|
||||
unsigned tex_sem_index = 0;
|
||||
auto sem = slang_uniform_name_to_semantic(name);
|
||||
auto tex_sem = slang_uniform_name_to_texture_semantic(name, &tex_sem_index);
|
||||
|
||||
if (sem != SLANG_INVALID_SEMANTIC)
|
||||
{
|
||||
@ -179,7 +244,7 @@ static bool add_active_buffer_ranges(const Compiler &compiler, const Resource &r
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!set_ubo_texture_offset(reflection, tex_sem, range.offset))
|
||||
if (!set_ubo_texture_offset(reflection, tex_sem, tex_sem_index, range.offset))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@ -346,7 +411,8 @@ static bool slang_reflect(const Compiler &vertex_compiler, const Compiler &fragm
|
||||
}
|
||||
binding_mask |= 1 << binding;
|
||||
|
||||
slang_texture_semantic index = slang_name_to_texture_semantic(texture.name);
|
||||
unsigned array_index = 0;
|
||||
slang_texture_semantic index = slang_name_to_texture_semantic(texture.name, &array_index);
|
||||
|
||||
if (index == SLANG_INVALID_TEXTURE_SEMANTIC)
|
||||
{
|
||||
@ -354,17 +420,25 @@ static bool slang_reflect(const Compiler &vertex_compiler, const Compiler &fragm
|
||||
return false;
|
||||
}
|
||||
|
||||
auto &semantic = reflection->semantic_textures[index];
|
||||
resize_minimum(reflection->semantic_textures[index], array_index + 1);
|
||||
auto &semantic = reflection->semantic_textures[index][array_index];
|
||||
semantic.binding = binding;
|
||||
semantic.stage_mask = SLANG_STAGE_FRAGMENT_MASK;
|
||||
reflection->semantic_texture_mask |= 1 << index;
|
||||
semantic.texture = true;
|
||||
}
|
||||
|
||||
RARCH_LOG("[slang]: Reflection\n");
|
||||
RARCH_LOG("[slang]: Textures:\n");
|
||||
for (unsigned i = 0; i < SLANG_NUM_TEXTURE_SEMANTICS; i++)
|
||||
if (reflection->semantic_texture_mask & (1u << i))
|
||||
RARCH_LOG("[slang]: %s\n", texture_semantic_names[i]);
|
||||
{
|
||||
unsigned index = 0;
|
||||
for (auto &sem : reflection->semantic_textures[i])
|
||||
{
|
||||
if (sem.texture)
|
||||
RARCH_LOG("[slang]: %s (#%u)\n", texture_semantic_names[i], index);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
RARCH_LOG("[slang]:\n");
|
||||
RARCH_LOG("[slang]: Uniforms (Vertex: %s, Fragment: %s):\n",
|
||||
@ -372,7 +446,7 @@ static bool slang_reflect(const Compiler &vertex_compiler, const Compiler &fragm
|
||||
reflection->ubo_stage_mask & SLANG_STAGE_FRAGMENT_MASK ? "yes": "no");
|
||||
for (unsigned i = 0; i < SLANG_NUM_SEMANTICS; i++)
|
||||
{
|
||||
if (reflection->semantic_ubo_mask & (1u << i))
|
||||
if (reflection->semantics[i].uniform)
|
||||
{
|
||||
RARCH_LOG("[slang]: %s (Offset: %u)\n", semantic_uniform_names[i],
|
||||
unsigned(reflection->semantics[i].ubo_offset));
|
||||
@ -381,10 +455,16 @@ static bool slang_reflect(const Compiler &vertex_compiler, const Compiler &fragm
|
||||
|
||||
for (unsigned i = 0; i < SLANG_NUM_TEXTURE_SEMANTICS; i++)
|
||||
{
|
||||
if (reflection->semantic_texture_ubo_mask & (1u << i))
|
||||
unsigned index = 0;
|
||||
for (auto &sem : reflection->semantic_textures[i])
|
||||
{
|
||||
RARCH_LOG("[slang]: %s (Offset: %u)\n", texture_semantic_uniform_names[i],
|
||||
unsigned(reflection->semantic_textures[i].ubo_offset));
|
||||
if (sem.uniform)
|
||||
{
|
||||
RARCH_LOG("[slang]: %s (#%u) (Offset: %u)\n", texture_semantic_uniform_names[i],
|
||||
index,
|
||||
unsigned(sem.ubo_offset));
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,31 @@
|
||||
// Textures with built-in meaning.
|
||||
enum slang_texture_semantic
|
||||
{
|
||||
// The input texture to the filter chain.
|
||||
// Canonical name: "Original".
|
||||
SLANG_TEXTURE_SEMANTIC_ORIGINAL = 0,
|
||||
|
||||
// The output from pass N - 1 if executing pass N, or ORIGINAL
|
||||
// if pass #0 is executed.
|
||||
// Canonical name: "Source".
|
||||
SLANG_TEXTURE_SEMANTIC_SOURCE = 1,
|
||||
|
||||
// The original inputs with a history back in time.
|
||||
// Canonical name: "OriginalHistory#", e.g. "OriginalHistory2" <- Two frames back.
|
||||
// "OriginalHistory0" is an alias for SEMANTIC_ORIGINAL.
|
||||
// Size name: "OriginalHistorySize#".
|
||||
SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY = 2,
|
||||
|
||||
// The output from pass #N, where pass #0 is the first pass.
|
||||
// Canonical name: "PassOutput#", e.g. "PassOutput3".
|
||||
// Size name: "PassOutputSize#".
|
||||
SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT = 3,
|
||||
|
||||
// The output from pass #N, one frame ago where pass #0 is the first pass.
|
||||
// It is not valid to use the pass feedback from a pass which is not offscreen.
|
||||
// Canonical name: "PassFeedback#", e.g. "PassFeedback2".
|
||||
SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK = 4,
|
||||
|
||||
SLANG_NUM_TEXTURE_SEMANTICS,
|
||||
SLANG_INVALID_TEXTURE_SEMANTIC = -1
|
||||
};
|
||||
@ -44,6 +66,8 @@ enum slang_stage
|
||||
SLANG_STAGE_VERTEX_MASK = 1 << 0,
|
||||
SLANG_STAGE_FRAGMENT_MASK = 1 << 1
|
||||
};
|
||||
|
||||
// Vulkan minimum limit.
|
||||
#define SLANG_NUM_BINDINGS 16
|
||||
|
||||
struct slang_texture_semantic_meta
|
||||
@ -51,27 +75,28 @@ struct slang_texture_semantic_meta
|
||||
size_t ubo_offset = 0;
|
||||
unsigned binding = 0;
|
||||
uint32_t stage_mask = 0;
|
||||
|
||||
bool texture = false;
|
||||
bool uniform = false;
|
||||
};
|
||||
|
||||
struct slang_semantic_meta
|
||||
{
|
||||
size_t ubo_offset = 0;
|
||||
unsigned num_components = 0;
|
||||
bool uniform = false;
|
||||
};
|
||||
|
||||
struct slang_reflection
|
||||
{
|
||||
slang_reflection() = default;
|
||||
slang_reflection();
|
||||
|
||||
size_t ubo_size = 0;
|
||||
unsigned ubo_binding = 0;
|
||||
uint32_t ubo_stage_mask = 0;
|
||||
|
||||
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];
|
||||
uint32_t semantic_texture_mask = 0;
|
||||
uint32_t semantic_texture_ubo_mask = 0;
|
||||
uint32_t semantic_ubo_mask = 0;
|
||||
};
|
||||
|
||||
bool slang_reflect_spirv(const std::vector<uint32_t> &vertex,
|
||||
|
Loading…
x
Reference in New Issue
Block a user