| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975 |
- #include "analyzer.h"
- #include "array.h"
- #include "errors.h"
- #include <string.h>
- static render_pipelines all_render_pipelines;
- // a pipeline group is a collection of pipelines that share shaders
- static render_pipeline_groups all_render_pipeline_groups;
- static compute_shaders all_compute_shaders;
- static raytracing_pipelines all_raytracing_pipelines;
- // a pipeline group is a collection of pipelines that share shaders
- static raytracing_pipeline_groups all_raytracing_pipeline_groups;
- static void find_referenced_global_for_var(variable v, global_array *globals, bool read, bool write) {
- for (global_id j = 0; get_global(j) != NULL && get_global(j)->type != NO_TYPE; ++j) {
- global *g = get_global(j);
- if (v.index == g->var_index) {
- bool found = false;
- for (size_t k = 0; k < globals->size; ++k) {
- if (globals->globals[k] == j) {
- found = true;
- if (read) {
- globals->readable[k] = true;
- }
- if (write) {
- globals->writable[k] = true;
- }
- break;
- }
- }
- if (!found) {
- globals->globals[globals->size] = j;
- globals->readable[globals->size] = read;
- globals->writable[globals->size] = write;
- globals->size += 1;
- }
- return;
- }
- }
- }
- void find_referenced_globals(function *f, global_array *globals) {
- if (f->block == NULL) {
- // built-in
- return;
- }
- function *functions[256];
- size_t functions_size = 0;
- functions[functions_size] = f;
- functions_size += 1;
- find_referenced_functions(f, functions, &functions_size);
- for (size_t l = 0; l < functions_size; ++l) {
- uint8_t *data = functions[l]->code.o;
- size_t size = functions[l]->code.size;
- size_t index = 0;
- while (index < size) {
- opcode *o = (opcode *)&data[index];
- switch (o->type) {
- case OPCODE_MULTIPLY:
- case OPCODE_DIVIDE:
- case OPCODE_ADD:
- case OPCODE_SUB:
- case OPCODE_EQUALS:
- case OPCODE_NOT_EQUALS:
- case OPCODE_GREATER:
- case OPCODE_GREATER_EQUAL:
- case OPCODE_LESS:
- case OPCODE_LESS_EQUAL: {
- find_referenced_global_for_var(o->op_binary.left, globals, false, false);
- find_referenced_global_for_var(o->op_binary.right, globals, false, false);
- break;
- }
- case OPCODE_LOAD_ACCESS_LIST: {
- find_referenced_global_for_var(o->op_load_access_list.from, globals, true, false);
- break;
- }
- case OPCODE_STORE_ACCESS_LIST:
- case OPCODE_SUB_AND_STORE_ACCESS_LIST:
- case OPCODE_ADD_AND_STORE_ACCESS_LIST:
- case OPCODE_DIVIDE_AND_STORE_ACCESS_LIST:
- case OPCODE_MULTIPLY_AND_STORE_ACCESS_LIST: {
- find_referenced_global_for_var(o->op_store_access_list.to, globals, false, true);
- break;
- }
- case OPCODE_CALL: {
- for (uint8_t i = 0; i < o->op_call.parameters_size; ++i) {
- find_referenced_global_for_var(o->op_call.parameters[i], globals, false, false);
- }
- break;
- }
- default:
- break;
- }
- index += o->size;
- }
- }
- }
- void find_referenced_functions(function *f, function **functions, size_t *functions_size) {
- if (f->block == NULL) {
- // built-in
- return;
- }
- uint8_t *data = f->code.o;
- size_t size = f->code.size;
- size_t index = 0;
- while (index < size) {
- opcode *o = (opcode *)&data[index];
- switch (o->type) {
- case OPCODE_CALL: {
- for (function_id i = 0; get_function(i) != NULL; ++i) {
- function *f = get_function(i);
- if (f->name == o->op_call.func) {
- if (f->block == NULL) {
- // built-in
- break;
- }
- bool found = false;
- for (size_t j = 0; j < *functions_size; ++j) {
- if (functions[j]->name == o->op_call.func) {
- found = true;
- break;
- }
- }
- if (!found) {
- functions[*functions_size] = f;
- *functions_size += 1;
- find_referenced_functions(f, functions, functions_size);
- }
- break;
- }
- }
- break;
- }
- default:
- break;
- }
- index += o->size;
- }
- }
- void find_used_builtins(function *f) {
- if (f->block == NULL) {
- // built-in
- return;
- }
- if (f->used_builtins.builtins_analyzed) {
- return;
- }
- f->used_builtins.builtins_analyzed = true;
- uint8_t *data = f->code.o;
- size_t size = f->code.size;
- size_t index = 0;
- while (index < size) {
- opcode *o = (opcode *)&data[index];
- switch (o->type) {
- case OPCODE_CALL: {
- name_id func = o->op_call.func;
- if (func == add_name("dispatch_thread_id")) {
- f->used_builtins.dispatch_thread_id = true;
- }
- if (func == add_name("group_thread_id")) {
- f->used_builtins.group_thread_id = true;
- }
- if (func == add_name("group_id")) {
- f->used_builtins.group_id = true;
- }
- if (func == add_name("vertex_id")) {
- f->used_builtins.vertex_id = true;
- }
- for (function_id i = 0; get_function(i) != NULL; ++i) {
- function *called = get_function(i);
- if (called->name == o->op_call.func) {
- find_used_builtins(f);
- f->used_builtins.dispatch_thread_id |= called->used_builtins.dispatch_thread_id;
- f->used_builtins.group_thread_id |= called->used_builtins.group_thread_id;
- f->used_builtins.group_id |= called->used_builtins.group_id;
- f->used_builtins.vertex_id |= called->used_builtins.vertex_id;
- break;
- }
- }
- break;
- }
- default:
- break;
- }
- index += o->size;
- }
- }
- static global *find_global_by_var(variable var) {
- for (global_id global_index = 0; get_global(global_index) != NULL && get_global(global_index)->type != NO_TYPE; ++global_index) {
- if (var.index == get_global(global_index)->var_index) {
- return get_global(global_index);
- }
- }
- return NULL;
- }
- void find_used_capabilities(function *f) {
- if (f->block == NULL) {
- // built-in
- return;
- }
- if (f->used_capabilities.capabilities_analyzed) {
- return;
- }
- f->used_capabilities.capabilities_analyzed = true;
- uint8_t *data = f->code.o;
- size_t size = f->code.size;
- size_t index = 0;
- variable last_base_texture_from = {0};
- variable last_base_texture_to = {0};
- while (index < size) {
- opcode *o = (opcode *)&data[index];
- switch (o->type) {
- case OPCODE_STORE_ACCESS_LIST: {
- variable to = o->op_store_access_list.to;
- type_id to_type = to.type.type;
- if (is_texture(to_type)) {
- assert(get_type(to_type)->array_size == 0);
- f->used_capabilities.image_write = true;
- global *g = find_global_by_var(to);
- assert(g != NULL);
- g->usage |= GLOBAL_USAGE_TEXTURE_WRITE;
- }
- break;
- }
- case OPCODE_LOAD_ACCESS_LIST: {
- variable from = o->op_load_access_list.from;
- type_id from_type = from.type.type;
- if (is_texture(from_type)) {
- f->used_capabilities.image_read = true;
- if (get_type(from_type)->array_size > 0) {
- last_base_texture_from = from;
- last_base_texture_to = o->op_load_access_list.to;
- }
- else {
- global *g = find_global_by_var(from);
- assert(g != NULL);
- g->usage |= GLOBAL_USAGE_TEXTURE_READ;
- }
- }
- break;
- }
- case OPCODE_CALL: {
- name_id func_name = o->op_call.func;
- if (func_name == add_name("sample") || func_name == add_name("sample_lod")) {
- variable tex_parameter = o->op_call.parameters[0];
- global *g = NULL;
- if (tex_parameter.kind == VARIABLE_INTERNAL) {
- assert(last_base_texture_to.index == tex_parameter.index);
- g = find_global_by_var(last_base_texture_from);
- }
- else {
- g = find_global_by_var(tex_parameter);
- }
- assert(g != NULL);
- g->usage |= GLOBAL_USAGE_TEXTURE_SAMPLE;
- }
- for (function_id i = 0; get_function(i) != NULL; ++i) {
- function *called = get_function(i);
- if (called->name == func_name) {
- find_used_capabilities(f);
- f->used_capabilities.image_read |= called->used_capabilities.image_read;
- f->used_capabilities.image_write |= called->used_capabilities.image_write;
- break;
- }
- }
- break;
- }
- default:
- break;
- }
- index += o->size;
- }
- }
- static void add_found_type(type_id t, type_id *types, size_t *types_size) {
- for (size_t i = 0; i < *types_size; ++i) {
- if (types[i] == t) {
- return;
- }
- }
- types[*types_size] = t;
- *types_size += 1;
- }
- void find_referenced_types(function *f, type_id *types, size_t *types_size) {
- if (f->block == NULL) {
- // built-in
- return;
- }
- function *functions[256];
- size_t functions_size = 0;
- functions[functions_size] = f;
- functions_size += 1;
- find_referenced_functions(f, functions, &functions_size);
- for (size_t function_index = 0; function_index < functions_size; ++function_index) {
- function *func = functions[function_index];
- debug_context context = {0};
- for (uint8_t parameter_index = 0; parameter_index < func->parameters_size; ++parameter_index) {
- check(func->parameter_types[parameter_index].type != NO_TYPE, context, "Function parameter type not found");
- add_found_type(func->parameter_types[parameter_index].type, types, types_size);
- }
- check(func->return_type.type != NO_TYPE, context, "Function return type missing");
- add_found_type(func->return_type.type, types, types_size);
- uint8_t *data = functions[function_index]->code.o;
- size_t size = functions[function_index]->code.size;
- size_t index = 0;
- while (index < size) {
- opcode *o = (opcode *)&data[index];
- switch (o->type) {
- case OPCODE_VAR:
- add_found_type(o->op_var.var.type.type, types, types_size);
- break;
- default:
- break;
- }
- index += o->size;
- }
- }
- }
- static bool has_set(descriptor_sets *sets, descriptor_set *set) {
- for (size_t set_index = 0; set_index < sets->size; ++set_index) {
- if (sets->values[set_index] == set) {
- return true;
- }
- }
- return false;
- }
- static void add_set(descriptor_sets *sets, descriptor_set *set) {
- if (has_set(sets, set)) {
- return;
- }
- static_array_push_p(sets, set);
- }
- static void find_referenced_sets(global_array *globals, descriptor_sets *sets) {
- for (size_t global_index = 0; global_index < globals->size; ++global_index) {
- global *g = get_global(globals->globals[global_index]);
- if (g->sets_count == 0) {
- continue;
- }
- if (g->sets_count == 1) {
- add_set(sets, g->sets[0]);
- continue;
- }
- }
- for (size_t global_index = 0; global_index < globals->size; ++global_index) {
- global *g = get_global(globals->globals[global_index]);
- if (g->sets_count < 2) {
- continue;
- }
- bool found = false;
- for (size_t set_index = 0; set_index < g->sets_count; ++set_index) {
- descriptor_set *set = g->sets[set_index];
- if (has_set(sets, set)) {
- found = true;
- break;
- }
- }
- if (!found) {
- debug_context context = {0};
- error(context, "Global %s could be used from multiple descriptor sets.", get_name(g->name));
- }
- }
- }
- static render_pipeline extract_render_pipeline_from_type(type *t) {
- name_id vertex_shader_name = NO_NAME;
- name_id amplification_shader_name = NO_NAME;
- name_id mesh_shader_name = NO_NAME;
- name_id fragment_shader_name = NO_NAME;
- for (size_t j = 0; j < t->members.size; ++j) {
- if (t->members.m[j].name == add_name("vertex")) {
- vertex_shader_name = t->members.m[j].value.identifier;
- }
- else if (t->members.m[j].name == add_name("amplification")) {
- amplification_shader_name = t->members.m[j].value.identifier;
- }
- else if (t->members.m[j].name == add_name("mesh")) {
- mesh_shader_name = t->members.m[j].value.identifier;
- }
- else if (t->members.m[j].name == add_name("fragment")) {
- fragment_shader_name = t->members.m[j].value.identifier;
- }
- }
- debug_context context = {0};
- check(vertex_shader_name != NO_NAME || mesh_shader_name != NO_NAME, context, "vertex or mesh shader missing");
- check(fragment_shader_name != NO_NAME, context, "fragment shader missing");
- render_pipeline pipeline = {0};
- for (function_id i = 0; get_function(i) != NULL; ++i) {
- function *f = get_function(i);
- if (vertex_shader_name != NO_NAME && f->name == vertex_shader_name) {
- pipeline.vertex_shader = f;
- }
- if (amplification_shader_name != NO_NAME && f->name == amplification_shader_name) {
- pipeline.amplification_shader = f;
- }
- if (mesh_shader_name != NO_NAME && f->name == mesh_shader_name) {
- pipeline.mesh_shader = f;
- }
- if (f->name == fragment_shader_name) {
- pipeline.fragment_shader = f;
- }
- }
- return pipeline;
- }
- static void find_all_render_pipelines(void) {
- static_array_init(all_render_pipelines);
- for (type_id i = 0; get_type(i) != NULL; ++i) {
- type *t = get_type(i);
- if (!t->built_in && has_attribute(&t->attributes, add_name("pipe"))) {
- static_array_push(all_render_pipelines, extract_render_pipeline_from_type(t));
- }
- }
- }
- static bool same_shader(function *a, function *b) {
- if (a == NULL && b == NULL) {
- return false;
- }
- return a == b;
- }
- static void find_render_pipeline_groups(void) {
- static_array_init(all_render_pipeline_groups);
- render_pipeline_indices remaining_pipelines;
- static_array_init(remaining_pipelines);
- for (uint32_t index = 0; index < all_render_pipelines.size; ++index) {
- static_array_push(remaining_pipelines, index);
- }
- while (remaining_pipelines.size > 0) {
- render_pipeline_indices next_remaining_pipelines;
- static_array_init(next_remaining_pipelines);
- render_pipeline_group group;
- static_array_init(group);
- static_array_push(group, remaining_pipelines.values[0]);
- for (size_t index = 1; index < remaining_pipelines.size; ++index) {
- uint32_t pipeline_index = remaining_pipelines.values[index];
- render_pipeline *pipeline = &all_render_pipelines.values[pipeline_index];
- bool found = false;
- for (size_t index_in_bucket = 0; index_in_bucket < group.size; ++index_in_bucket) {
- render_pipeline *pipeline_in_group = &all_render_pipelines.values[group.values[index_in_bucket]];
- if (same_shader(pipeline->vertex_shader, pipeline_in_group->vertex_shader) ||
- same_shader(pipeline->amplification_shader, pipeline_in_group->amplification_shader) ||
- same_shader(pipeline->mesh_shader, pipeline_in_group->mesh_shader) ||
- same_shader(pipeline->fragment_shader, pipeline_in_group->fragment_shader)) {
- found = true;
- break;
- }
- }
- if (found) {
- static_array_push(group, pipeline_index);
- }
- else {
- static_array_push(next_remaining_pipelines, pipeline_index);
- }
- }
- remaining_pipelines = next_remaining_pipelines;
- static_array_push(all_render_pipeline_groups, group);
- }
- }
- static void find_all_compute_shaders(void) {
- static_array_init(all_compute_shaders);
- for (function_id i = 0; get_function(i) != NULL; ++i) {
- function *f = get_function(i);
- if (has_attribute(&f->attributes, add_name("compute"))) {
- static_array_push(all_compute_shaders, f);
- }
- }
- }
- static raytracing_pipeline extract_raytracing_pipeline_from_type(type *t) {
- name_id gen_shader_name = NO_NAME;
- name_id miss_shader_name = NO_NAME;
- name_id closest_shader_name = NO_NAME;
- name_id intersection_shader_name = NO_NAME;
- name_id any_shader_name = NO_NAME;
- for (size_t j = 0; j < t->members.size; ++j) {
- if (t->members.m[j].name == add_name("gen")) {
- gen_shader_name = t->members.m[j].value.identifier;
- }
- else if (t->members.m[j].name == add_name("miss")) {
- miss_shader_name = t->members.m[j].value.identifier;
- }
- else if (t->members.m[j].name == add_name("closest")) {
- closest_shader_name = t->members.m[j].value.identifier;
- }
- else if (t->members.m[j].name == add_name("intersection")) {
- intersection_shader_name = t->members.m[j].value.identifier;
- }
- else if (t->members.m[j].name == add_name("any")) {
- any_shader_name = t->members.m[j].value.identifier;
- }
- }
- raytracing_pipeline pipeline = {0};
- for (function_id i = 0; get_function(i) != NULL; ++i) {
- function *f = get_function(i);
- if (gen_shader_name != NO_NAME && f->name == gen_shader_name) {
- pipeline.gen_shader = f;
- }
- if (miss_shader_name != NO_NAME && f->name == miss_shader_name) {
- pipeline.miss_shader = f;
- }
- if (closest_shader_name != NO_NAME && f->name == closest_shader_name) {
- pipeline.closest_shader = f;
- }
- if (intersection_shader_name != NO_NAME && f->name == intersection_shader_name) {
- pipeline.intersection_shader = f;
- }
- if (any_shader_name != NO_NAME && f->name == any_shader_name) {
- pipeline.any_shader = f;
- }
- }
- return pipeline;
- }
- static void find_all_raytracing_pipelines(void) {
- static_array_init(all_raytracing_pipelines);
- for (type_id i = 0; get_type(i) != NULL; ++i) {
- type *t = get_type(i);
- if (!t->built_in && has_attribute(&t->attributes, add_name("raypipe"))) {
- static_array_push(all_raytracing_pipelines, extract_raytracing_pipeline_from_type(t));
- }
- }
- }
- static void find_raytracing_pipeline_groups(void) {
- static_array_init(all_raytracing_pipeline_groups);
- raytracing_pipeline_indices remaining_pipelines;
- static_array_init(remaining_pipelines);
- for (uint32_t index = 0; index < all_raytracing_pipelines.size; ++index) {
- static_array_push(remaining_pipelines, index);
- }
- while (remaining_pipelines.size > 0) {
- raytracing_pipeline_indices next_remaining_pipelines;
- static_array_init(next_remaining_pipelines);
- raytracing_pipeline_group group;
- static_array_init(group);
- static_array_push(group, remaining_pipelines.values[0]);
- for (size_t index = 1; index < remaining_pipelines.size; ++index) {
- uint32_t pipeline_index = remaining_pipelines.values[index];
- raytracing_pipeline *pipeline = &all_raytracing_pipelines.values[pipeline_index];
- bool found = false;
- for (size_t index_in_bucket = 0; index_in_bucket < group.size; ++index_in_bucket) {
- raytracing_pipeline *pipeline_in_group = &all_raytracing_pipelines.values[group.values[index_in_bucket]];
- if (pipeline->gen_shader == pipeline_in_group->gen_shader || pipeline->miss_shader == pipeline_in_group->miss_shader ||
- pipeline->closest_shader == pipeline_in_group->closest_shader || pipeline->intersection_shader == pipeline_in_group->intersection_shader ||
- pipeline->any_shader == pipeline_in_group->any_shader) {
- found = true;
- break;
- }
- }
- if (found) {
- static_array_push(group, pipeline_index);
- }
- else {
- static_array_push(next_remaining_pipelines, pipeline_index);
- }
- }
- remaining_pipelines = next_remaining_pipelines;
- static_array_push(all_raytracing_pipeline_groups, group);
- }
- }
- static void check_globals_in_descriptor_set_group(descriptor_set_group *group) {
- static_array(global_id, globals, 256);
- globals set_globals;
- static_array_init(set_globals);
- for (size_t set_index = 0; set_index < group->size; ++set_index) {
- descriptor_set *set = group->values[set_index];
- for (size_t global_index = 0; global_index < set->globals.size; ++global_index) {
- global_id g = set->globals.globals[global_index];
- for (size_t global_index2 = 0; global_index2 < set_globals.size; ++global_index2) {
- if (set_globals.values[global_index2] == g) {
- debug_context context = {0};
- error(context, "Global used from more than one descriptor set in one descriptor set group");
- }
- }
- static_array_push(set_globals, g);
- }
- }
- }
- static void update_globals_in_descriptor_set_group(descriptor_set_group *group, global_array *globals) {
- for (size_t set_index = 0; set_index < group->size; ++set_index) {
- descriptor_set *set = group->values[set_index];
- for (size_t global_index = 0; global_index < set->globals.size; ++global_index) {
- global_id g = set->globals.globals[global_index];
- for (size_t global_index2 = 0; global_index2 < globals->size; ++global_index2) {
- if (globals->globals[global_index2] == g) {
- if (globals->readable[global_index2]) {
- set->globals.readable[global_index] = true;
- }
- if (globals->writable[global_index2]) {
- set->globals.writable[global_index] = true;
- }
- }
- }
- }
- }
- }
- static descriptor_set_groups all_descriptor_set_groups;
- descriptor_set_group *get_descriptor_set_group(uint32_t descriptor_set_group_index) {
- assert(descriptor_set_group_index < all_descriptor_set_groups.size);
- return &all_descriptor_set_groups.values[descriptor_set_group_index];
- }
- static void assign_descriptor_set_group_index(function *f, uint32_t descriptor_set_group_index) {
- assert(f->descriptor_set_group_index == UINT32_MAX || f->descriptor_set_group_index == descriptor_set_group_index);
- f->descriptor_set_group_index = descriptor_set_group_index;
- }
- static void find_descriptor_set_groups(void) {
- static_array_init(all_descriptor_set_groups);
- for (size_t pipeline_group_index = 0; pipeline_group_index < all_render_pipeline_groups.size; ++pipeline_group_index) {
- descriptor_set_group group;
- static_array_init(group);
- global_array function_globals = {0};
- render_pipeline_group *pipeline_group = &all_render_pipeline_groups.values[pipeline_group_index];
- for (size_t pipeline_index = 0; pipeline_index < pipeline_group->size; ++pipeline_index) {
- render_pipeline *pipeline = &all_render_pipelines.values[pipeline_group->values[pipeline_index]];
- if (pipeline->vertex_shader != NULL) {
- find_referenced_globals(pipeline->vertex_shader, &function_globals);
- }
- if (pipeline->amplification_shader != NULL) {
- find_referenced_globals(pipeline->amplification_shader, &function_globals);
- }
- if (pipeline->mesh_shader != NULL) {
- find_referenced_globals(pipeline->mesh_shader, &function_globals);
- }
- if (pipeline->fragment_shader != NULL) {
- find_referenced_globals(pipeline->fragment_shader, &function_globals);
- }
- }
- find_referenced_sets(&function_globals, &group);
- check_globals_in_descriptor_set_group(&group);
- update_globals_in_descriptor_set_group(&group, &function_globals);
- uint32_t descriptor_set_group_index = (uint32_t)all_descriptor_set_groups.size;
- static_array_push(all_descriptor_set_groups, group);
- for (size_t pipeline_index = 0; pipeline_index < pipeline_group->size; ++pipeline_index) {
- render_pipeline *pipeline = &all_render_pipelines.values[pipeline_group->values[pipeline_index]];
- if (pipeline->vertex_shader != NULL) {
- assign_descriptor_set_group_index(pipeline->vertex_shader, descriptor_set_group_index);
- }
- if (pipeline->amplification_shader != NULL) {
- assign_descriptor_set_group_index(pipeline->amplification_shader, descriptor_set_group_index);
- }
- if (pipeline->mesh_shader != NULL) {
- assign_descriptor_set_group_index(pipeline->mesh_shader, descriptor_set_group_index);
- }
- if (pipeline->fragment_shader != NULL) {
- assign_descriptor_set_group_index(pipeline->fragment_shader, descriptor_set_group_index);
- }
- }
- }
- for (size_t compute_shader_index = 0; compute_shader_index < all_compute_shaders.size; ++compute_shader_index) {
- descriptor_set_group group;
- static_array_init(group);
- global_array function_globals = {0};
- find_referenced_globals(all_compute_shaders.values[compute_shader_index], &function_globals);
- find_referenced_sets(&function_globals, &group);
- check_globals_in_descriptor_set_group(&group);
- update_globals_in_descriptor_set_group(&group, &function_globals);
- uint32_t descriptor_set_group_index = (uint32_t)all_descriptor_set_groups.size;
- static_array_push(all_descriptor_set_groups, group);
- for (size_t compute_shader_index = 0; compute_shader_index < all_compute_shaders.size; ++compute_shader_index) {
- assign_descriptor_set_group_index(all_compute_shaders.values[compute_shader_index], descriptor_set_group_index);
- }
- }
- for (size_t pipeline_group_index = 0; pipeline_group_index < all_raytracing_pipeline_groups.size; ++pipeline_group_index) {
- descriptor_set_group group;
- static_array_init(group);
- global_array function_globals = {0};
- raytracing_pipeline_group *pipeline_group = &all_raytracing_pipeline_groups.values[pipeline_group_index];
- for (size_t pipeline_index = 0; pipeline_index < pipeline_group->size; ++pipeline_index) {
- raytracing_pipeline *pipeline = &all_raytracing_pipelines.values[pipeline_group->values[pipeline_index]];
- if (pipeline->gen_shader != NULL) {
- find_referenced_globals(pipeline->gen_shader, &function_globals);
- }
- if (pipeline->miss_shader != NULL) {
- find_referenced_globals(pipeline->miss_shader, &function_globals);
- }
- if (pipeline->closest_shader != NULL) {
- find_referenced_globals(pipeline->closest_shader, &function_globals);
- }
- if (pipeline->intersection_shader != NULL) {
- find_referenced_globals(pipeline->intersection_shader, &function_globals);
- }
- if (pipeline->any_shader != NULL) {
- find_referenced_globals(pipeline->any_shader, &function_globals);
- }
- }
- find_referenced_sets(&function_globals, &group);
- check_globals_in_descriptor_set_group(&group);
- update_globals_in_descriptor_set_group(&group, &function_globals);
- uint32_t descriptor_set_group_index = (uint32_t)all_descriptor_set_groups.size;
- static_array_push(all_descriptor_set_groups, group);
- for (size_t pipeline_index = 0; pipeline_index < pipeline_group->size; ++pipeline_index) {
- raytracing_pipeline *pipeline = &all_raytracing_pipelines.values[pipeline_group->values[pipeline_index]];
- if (pipeline->gen_shader != NULL) {
- assign_descriptor_set_group_index(pipeline->gen_shader, descriptor_set_group_index);
- }
- if (pipeline->miss_shader != NULL) {
- assign_descriptor_set_group_index(pipeline->miss_shader, descriptor_set_group_index);
- }
- if (pipeline->closest_shader != NULL) {
- assign_descriptor_set_group_index(pipeline->closest_shader, descriptor_set_group_index);
- }
- if (pipeline->intersection_shader != NULL) {
- assign_descriptor_set_group_index(pipeline->intersection_shader, descriptor_set_group_index);
- }
- if (pipeline->any_shader != NULL) {
- assign_descriptor_set_group_index(pipeline->any_shader, descriptor_set_group_index);
- }
- }
- }
- }
- descriptor_set_group *find_descriptor_set_group_for_pipe_type(type *t) {
- if (!t->built_in && has_attribute(&t->attributes, add_name("pipe"))) {
- render_pipeline pipeline = extract_render_pipeline_from_type(t);
- if (pipeline.vertex_shader->descriptor_set_group_index != UINT32_MAX) {
- return &all_descriptor_set_groups.values[pipeline.vertex_shader->descriptor_set_group_index];
- }
- if (pipeline.amplification_shader->descriptor_set_group_index != UINT32_MAX) {
- return &all_descriptor_set_groups.values[pipeline.amplification_shader->descriptor_set_group_index];
- }
- if (pipeline.mesh_shader->descriptor_set_group_index != UINT32_MAX) {
- return &all_descriptor_set_groups.values[pipeline.mesh_shader->descriptor_set_group_index];
- }
- if (pipeline.fragment_shader->descriptor_set_group_index != UINT32_MAX) {
- return &all_descriptor_set_groups.values[pipeline.fragment_shader->descriptor_set_group_index];
- }
- return NULL;
- }
- if (!t->built_in && has_attribute(&t->attributes, add_name("raypipe"))) {
- raytracing_pipeline pipeline = extract_raytracing_pipeline_from_type(t);
- if (pipeline.gen_shader->descriptor_set_group_index != UINT32_MAX) {
- return &all_descriptor_set_groups.values[pipeline.gen_shader->descriptor_set_group_index];
- }
- if (pipeline.miss_shader->descriptor_set_group_index != UINT32_MAX) {
- return &all_descriptor_set_groups.values[pipeline.miss_shader->descriptor_set_group_index];
- }
- if (pipeline.closest_shader->descriptor_set_group_index != UINT32_MAX) {
- return &all_descriptor_set_groups.values[pipeline.closest_shader->descriptor_set_group_index];
- }
- if (pipeline.intersection_shader->descriptor_set_group_index != UINT32_MAX) {
- return &all_descriptor_set_groups.values[pipeline.intersection_shader->descriptor_set_group_index];
- }
- if (pipeline.any_shader->descriptor_set_group_index != UINT32_MAX) {
- return &all_descriptor_set_groups.values[pipeline.any_shader->descriptor_set_group_index];
- }
- return NULL;
- }
- return NULL;
- }
- descriptor_set_group *find_descriptor_set_group_for_function(function *f) {
- if (f->descriptor_set_group_index != UINT32_MAX) {
- return &all_descriptor_set_groups.values[f->descriptor_set_group_index];
- }
- else {
- return NULL;
- }
- }
- void find_sampler_use() {
- for (function_id i = 0; get_function(i) != NULL; ++i) {
- function *f = get_function(i);
- if (f->block == NULL) {
- continue;
- }
- uint8_t *data = f->code.o;
- size_t size = f->code.size;
- size_t index = 0;
- while (index < size) {
- opcode *o = (opcode *)&data[index];
- switch (o->type) {
- case OPCODE_CALL:
- if (o->op_call.func == add_name("sample") || o->op_call.func == add_name("sample_lod")) {
- if (is_depth(get_type(o->op_call.parameters[0].type.type)->tex_format)) {
- type *sampler_type = get_type(o->op_call.parameters[1].type.type);
- global *g = find_global_by_var(o->op_call.parameters[1]);
- assert(g != NULL);
- g->usage |= GLOBAL_USAGE_SAMPLE_DEPTH;
- }
- }
- break;
- default:
- break;
- }
- index += o->size;
- }
- }
- }
- void analyze(void) {
- find_all_render_pipelines();
- find_render_pipeline_groups();
- find_all_compute_shaders();
- find_all_raytracing_pipelines();
- find_raytracing_pipeline_groups();
- find_descriptor_set_groups();
- find_sampler_use();
- }
|