Vulkan: Begin sketching out support for complete filter chain.

This commit is contained in:
Hans-Kristian Arntzen 2016-03-25 13:26:36 +01:00
parent d3f0ca76bc
commit 4f3ade1b95
3 changed files with 160 additions and 54 deletions

View File

@ -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)

View File

@ -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++;
}
}

View File

@ -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,