diff --git a/gfx/common/d3d11_common.h b/gfx/common/d3d11_common.h index 49a39613d8..81df81cef1 100644 --- a/gfx/common/d3d11_common.h +++ b/gfx/common/d3d11_common.h @@ -2559,6 +2559,7 @@ typedef struct pass_semantics_t semantics; D3D11ShaderResourceViewRef textures[SLANG_NUM_BINDINGS]; D3D11SamplerStateRef samplers[SLANG_NUM_BINDINGS]; + int num_bindings; float frame_count; } pass[GFX_MAX_SHADERS]; diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 624fc163ab..5ea8382d44 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -151,12 +151,15 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const { /* no history support yet */ texture_map_t texture_map[3 + GFX_MAX_SHADERS + GFX_MAX_TEXTURES + 1] = { - { SLANG_TEXTURE_SEMANTIC_ORIGINAL, 0, &d3d11->frame.texture, &d3d11->pass[i].sampler, - &d3d11->frame.texture.size_data }, - { SLANG_TEXTURE_SEMANTIC_SOURCE, 0, source, &d3d11->pass[i].sampler, - &source->size_data }, - { SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, 0, &d3d11->frame.texture, - &d3d11->pass[i].sampler, &d3d11->frame.texture.size_data }, + SL_TEXTURE_MAP( + SLANG_TEXTURE_SEMANTIC_ORIGINAL, d3d11->frame.texture, d3d11->pass[i].sampler, + d3d11->frame.texture.size_data), + SL_TEXTURE_MAP( + SLANG_TEXTURE_SEMANTIC_SOURCE, *source, d3d11->pass[i].sampler, + source->size_data), + SL_TEXTURE_MAP( + SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, d3d11->frame.texture, + d3d11->pass[i].sampler, d3d11->frame.texture.size_data), }; { @@ -166,29 +169,26 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const for (int j = 0; j < i; j++) { - ptr->semantic = SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT; - ptr->id = j; - ptr->texture_data = &d3d11->pass[j].rt; - ptr->sampler_data = &d3d11->pass[i].sampler; + *ptr = (texture_map_t)SL_TEXTURE_MAP_ARRAY( + SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, j, d3d11->pass[j].rt, + d3d11->pass[i].sampler, d3d11->pass[j].rt.size_data); ptr++; } for (int j = 0; j < d3d11->shader_preset->luts; j++) { - ptr->semantic = SLANG_TEXTURE_SEMANTIC_USER; - ptr->id = j; - ptr->texture_data = &d3d11->luts[j]; - ptr->size_data = &d3d11->luts[j].size_data; - ptr->sampler_data = &d3d11->luts[j].sampler; + *ptr = (texture_map_t)SL_TEXTURE_MAP_ARRAY( + SLANG_TEXTURE_SEMANTIC_USER, j, d3d11->luts[j], d3d11->luts[j].sampler, + d3d11->luts[j].size_data); ptr++; } } uniform_map_t uniform_map[] = { - { SLANG_SEMANTIC_MVP, &d3d11->mvp }, - { SLANG_SEMANTIC_OUTPUT, &d3d11->pass[i].rt.size_data }, - { SLANG_SEMANTIC_FRAME_COUNT, &d3d11->pass[i].frame_count }, - { SLANG_SEMANTIC_FINAL_VIEWPORT, &d3d11->frame.output_size }, + SL_UNIFORM_MAP(SLANG_SEMANTIC_MVP, d3d11->mvp), + SL_UNIFORM_MAP(SLANG_SEMANTIC_OUTPUT, d3d11->pass[i].rt.size_data), + SL_UNIFORM_MAP(SLANG_SEMANTIC_FRAME_COUNT, d3d11->pass[i].frame_count), + SL_UNIFORM_MAP(SLANG_SEMANTIC_FINAL_VIEWPORT, d3d11->frame.output_size), { 0 } }; @@ -743,12 +743,15 @@ static bool d3d11_init_frame_textures(d3d11_video_t* d3d11, unsigned width, unsi for (int j = 0; j < d3d11->pass[i].semantics.texture_count; j++) { texture_sem_t* texture_sem = &d3d11->pass[i].semantics.textures[j]; - D3D11ShaderResourceView view = ((d3d11_texture_t*)texture_sem->data)->view; - D3D11SamplerStateRef sampler = *(D3D11SamplerStateRef*)texture_sem->sampler_data; + D3D11ShaderResourceView view = ((d3d11_texture_t*)texture_sem->texture_data)->view; + D3D11SamplerStateRef sampler = *(D3D11SamplerStateRef*)texture_sem->sampler_data; + int slot = texture_sem->binding - d3d11->pass[i].semantics.min_binding; - d3d11->pass[i].textures[texture_sem->binding] = view; - d3d11->pass[i].samplers[texture_sem->binding] = sampler; + d3d11->pass[i].textures[slot] = view; + d3d11->pass[i].samplers[slot] = sampler; } + d3d11->pass[i].num_bindings = + d3d11->pass[i].semantics.max_binding - d3d11->pass[i].semantics.min_binding + 1; } } @@ -845,9 +848,10 @@ static bool d3d11_gfx_frame( uniform_sem_t* uniform = buffer_sem->uniforms; D3D11MapBuffer(d3d11->ctx, buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &res); - while (uniform->data) + while (uniform->size) { - memcpy((uint8_t*)res.pData + uniform->offset, uniform->data, uniform->size); + if(uniform->data) + memcpy((uint8_t*)res.pData + uniform->offset, uniform->data, uniform->size); uniform++; } D3D11UnmapBuffer(d3d11->ctx, buffer, 0); @@ -865,10 +869,10 @@ static bool d3d11_gfx_frame( D3D11RenderTargetView null_rt = NULL; D3D11SetRenderTargets(d3d11->ctx, 1, &null_rt, NULL); D3D11SetPShaderResources( - d3d11->ctx, 0, d3d11->pass[i].semantics.texture_binding_max + 1, + d3d11->ctx, d3d11->pass[i].semantics.min_binding, d3d11->pass[i].num_bindings, d3d11->pass[i].textures); D3D11SetPShaderSamplers( - d3d11->ctx, 0, d3d11->pass[i].semantics.texture_binding_max + 1, + d3d11->ctx, d3d11->pass[i].semantics.min_binding, d3d11->pass[i].num_bindings, d3d11->pass[i].samplers); if (d3d11->pass[i].rt.handle) diff --git a/gfx/drivers_shader/slang_process.cpp b/gfx/drivers_shader/slang_process.cpp index faaa4dc57f..a4a5007825 100644 --- a/gfx/drivers_shader/slang_process.cpp +++ b/gfx/drivers_shader/slang_process.cpp @@ -27,6 +27,60 @@ static bool set_unique_map(unordered_map& m, const string& name, cons return true; } +template +static string get_semantic_name(const unordered_map* map, S semantic, unsigned index) +{ + for (const pair& m : *map) + { + if (m.second.semantic == semantic && m.second.index == index) + return m.first; + } + return string(); +} + +static string +get_semantic_name(slang_reflection& reflection, slang_semantic semantic, unsigned index) +{ + static const char* names[] = { + "MVP", + "OutputSize", + "FinalViewportSize", + "FrameCount", + }; + if ((int)semantic < sizeof(names) / sizeof(*names)) + return std::string(names[semantic]); + + return get_semantic_name(reflection.semantic_map, semantic, index); +} + +static string +get_semantic_name(slang_reflection& reflection, slang_texture_semantic semantic, unsigned index) +{ + static const char* names[] = { + "Original", "Source", "OriginalHistory", "PassOutput", "PassFeedback", + }; + if ((int)semantic < (int)SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY) + return std::string(names[semantic]); + else if ((int)semantic < sizeof(names) / sizeof(*names)) + return std::string(names[semantic]) + to_string(index); + + return get_semantic_name(reflection.texture_semantic_map, semantic, index); +} + +static string get_size_semantic_name( + slang_reflection& reflection, slang_texture_semantic semantic, unsigned index) +{ + static const char* names[] = { + "OriginalSize", "SourceSize", "OriginalHistorySize", "PassOutputSize", "PassFeedbackSize", + }; + if ((int)semantic < (int)SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY) + return std::string(names[semantic]); + if ((int)semantic < sizeof(names) / sizeof(*names)) + return std::string(names[semantic]) + to_string(index); + + return get_semantic_name(reflection.texture_semantic_uniform_map, semantic, index); +} + static bool slang_process_reflection( const Compiler* vs_compiler, const Compiler* ps_compiler, @@ -75,11 +129,12 @@ static bool slang_process_reflection( return false; } - unordered_map semantic_map; + unordered_map uniform_semantic_map; for (unsigned i = 0; i < shader_info->num_parameters; i++) { if (!set_unique_map( - semantic_map, shader_info->parameters[i].id, { SLANG_SEMANTIC_FLOAT_PARAMETER, i })) + uniform_semantic_map, shader_info->parameters[i].id, + { SLANG_SEMANTIC_FLOAT_PARAMETER, i })) return false; } @@ -87,7 +142,7 @@ static bool slang_process_reflection( sl_reflection.pass_number = pass_number; sl_reflection.texture_semantic_map = &texture_semantic_map; sl_reflection.texture_semantic_uniform_map = &texture_semantic_uniform_map; - sl_reflection.semantic_map = &semantic_map; + sl_reflection.semantic_map = &uniform_semantic_map; if (!slang_reflect(*vs_compiler, *ps_compiler, vs_resources, ps_resources, &sl_reflection)) { @@ -111,8 +166,12 @@ static bool slang_process_reflection( uniform_map_t* uniform_map = semantics_map->uniform_map; while (uniform_map->data) { - slang_semantic_meta& src = sl_reflection.semantics[uniform_map->semantic]; - uniform_sem_t uniform = { uniform_map->data, src.num_components * (unsigned)sizeof(float) }; + slang_semantic_meta& src = sl_reflection.semantics[uniform_map->semantic]; + uniform_sem_t uniform = { uniform_map->data, uniform_map->id, + src.num_components * (unsigned)sizeof(float) }; + + string uniform_id = get_semantic_name(sl_reflection, uniform_map->semantic, 0); + strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); if (src.push_constant) { @@ -131,7 +190,11 @@ static bool slang_process_reflection( for (int i = 0; i < sl_reflection.semantic_float_parameters.size(); i++) { slang_semantic_meta& src = sl_reflection.semantic_float_parameters[i]; - uniform_sem_t uniform = { &shader_info->parameters[i].current, sizeof(float) }; + uniform_sem_t uniform = { &shader_info->parameters[i].current, + "shader_info->parameter[i].current", sizeof(float) }; + + 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) { @@ -145,24 +208,42 @@ static bool slang_process_reflection( } } + out->min_binding = SLANG_NUM_BINDINGS; texture_map_t* texture_map = semantics_map->texture_map; + while (texture_map->texture_data) { - if (texture_map->id < sl_reflection.semantic_textures[texture_map->semantic].size()) + if (texture_map->index < sl_reflection.semantic_textures[texture_map->semantic].size()) { slang_texture_semantic_meta& src = - sl_reflection.semantic_textures[texture_map->semantic][texture_map->id]; + sl_reflection.semantic_textures[texture_map->semantic][texture_map->index]; if (src.stage_mask) { - texture_sem_t texture = { texture_map->texture_data, texture_map->sampler_data }; + texture_sem_t texture = { texture_map->texture_data, texture_map->texture_id, + texture_map->sampler_data, texture_map->sampler_id }; texture.stage_mask = src.stage_mask; texture.binding = src.binding; - if (out->texture_binding_max < src.binding) - out->texture_binding_max = src.binding; + string id = get_semantic_name(sl_reflection, texture_map->semantic, texture_map->index); + + strncpy(texture.id, id.c_str(), sizeof(texture.id)); + + if (out->max_binding < src.binding) + out->max_binding = src.binding; + + if (out->min_binding > src.binding) + out->min_binding = src.binding; + textures.push_back(texture); - uniform_sem_t uniform = { texture_map->size_data, 4 * sizeof(float) }; + uniform_sem_t uniform = { texture_map->size_data, texture_map->size_id, + 4 * sizeof(float) }; + + string uniform_id = + get_size_semantic_name(sl_reflection, texture_map->semantic, texture_map->index); + + strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id)); + if (src.push_constant) { uniform.offset = src.push_constant_offset; @@ -178,6 +259,9 @@ static bool slang_process_reflection( texture_map++; } + if (out->min_binding > out->max_binding) + out->min_binding = out->max_binding; + out->texture_count = textures.size(); textures.push_back({ NULL }); diff --git a/gfx/drivers_shader/slang_process.h b/gfx/drivers_shader/slang_process.h index fd3226e904..b5b14c5869 100644 --- a/gfx/drivers_shader/slang_process.h +++ b/gfx/drivers_shader/slang_process.h @@ -27,17 +27,33 @@ typedef struct { enum slang_semantic semantic; void* data; + const char* id; } uniform_map_t; typedef struct { enum slang_texture_semantic semantic; - int id; + int index; void* texture_data; + const char* texture_id; void* sampler_data; + const char* sampler_id; void* size_data; + const char* size_id; } texture_map_t; +#define SL_UNIFORM_MAP(sem, data) \ + { \ + sem, &data, #data \ + } + +#define SL_TEXTURE_MAP_ARRAY(sem, index, tex, sampl, size) \ + { \ + sem, index, &tex, #tex, &sampl, #sampl, &size, #size \ + } + +#define SL_TEXTURE_MAP(sem, tex, sampl, size) SL_TEXTURE_MAP_ARRAY(sem, 0, tex, sampl, size) + typedef struct { texture_map_t* texture_map; @@ -46,17 +62,22 @@ typedef struct typedef struct { - void* data; - unsigned size; - unsigned offset; + void* data; + const char* data_id; + unsigned size; + unsigned offset; + char id[64]; } uniform_sem_t; typedef struct { - void* data; - void* sampler_data; - unsigned stage_mask; - unsigned binding; + void* texture_data; + const char* texture_id; + void* sampler_data; + const char* sampler_id; + unsigned stage_mask; + unsigned binding; + char id[64]; } texture_sem_t; typedef struct @@ -72,7 +93,8 @@ typedef struct { int texture_count; texture_sem_t* textures; - int texture_binding_max; + int max_binding; + int min_binding; cbuffer_sem_t cbuffers[SLANG_CBUFFER_MAX]; } pass_semantics_t;