_mesa_sha1_final(&ctx, sha1_out);
}
+void
+radv_pipeline_stage_init(const VkPipelineShaderStageCreateInfo *sinfo,
+ struct radv_pipeline_stage *out_stage, gl_shader_stage stage)
+{
+ struct vk_shader_module *module = vk_shader_module_from_handle(sinfo->module);
+
+ memset(out_stage, 0, sizeof(*out_stage));
+
+ out_stage->stage = stage;
+ out_stage->entrypoint = sinfo->pName;
+ out_stage->spec_info = sinfo->pSpecializationInfo;
+ out_stage->feedback.flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
+
+ out_stage->spirv.data = module->data;
+ out_stage->spirv.size = module->size;
+ out_stage->spirv.object = &module->base;
+
+ if (module->nir) {
+ out_stage->internal_nir = module->nir;
+ _mesa_sha1_compute(module->nir->info.name, strlen(module->nir->info.name),
+ out_stage->spirv.sha1);
+ } else {
+ assert(sizeof(out_stage->spirv.sha1) == sizeof(module->sha1));
+ memcpy(out_stage->spirv.sha1, module->sha1, sizeof(out_stage->spirv.sha1));
+ }
+
+ radv_pipeline_hash_shader(out_stage->spirv.sha1, sizeof(out_stage->spirv.sha1),
+ out_stage->entrypoint, stage, out_stage->spec_info,
+ out_stage->shader_sha1);
+}
+
VkResult
radv_create_shaders(struct radv_pipeline *pipeline, struct radv_pipeline_layout *pipeline_layout,
struct radv_device *device, struct radv_pipeline_cache *cache,
const VkPipelineShaderStageCreateInfo *sinfo = &pStages[i];
gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
- stages[stage].stage = stage;
- stages[stage].module = vk_shader_module_from_handle(sinfo->module);
- stages[stage].entrypoint = sinfo->pName;
- stages[stage].spec_info = sinfo->pSpecializationInfo;
- stages[stage].feedback.flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
-
- if (stages[stage].module->nir) {
- _mesa_sha1_compute(stages[stage].module->nir->info.name,
- strlen(stages[stage].module->nir->info.name),
- stages[stage].module->sha1);
- }
-
- radv_pipeline_hash_shader(stages[stage].module->sha1, sizeof(stages[stage].module->sha1),
- stages[stage].entrypoint, stage, stages[stage].spec_info,
- stages[stage].shader_sha1);
+ radv_pipeline_stage_init(sinfo, &stages[stage], stage);
pipeline->active_stages |= sinfo->stage;
}
}
ASSERTED bool primitive_shading =
- stages[MESA_SHADER_VERTEX].module || stages[MESA_SHADER_TESS_CTRL].module ||
- stages[MESA_SHADER_TESS_EVAL].module || stages[MESA_SHADER_GEOMETRY].module;
+ stages[MESA_SHADER_VERTEX].entrypoint || stages[MESA_SHADER_TESS_CTRL].entrypoint ||
+ stages[MESA_SHADER_TESS_EVAL].entrypoint || stages[MESA_SHADER_GEOMETRY].entrypoint;
ASSERTED bool mesh_shading =
- stages[MESA_SHADER_MESH].module;
+ stages[MESA_SHADER_MESH].entrypoint;
/* Primitive and mesh shading must not be mixed in the same pipeline. */
assert(!primitive_shading || !mesh_shading);
/* Mesh shaders are mandatory in mesh shading pipelines. */
- assert(mesh_shading == !!stages[MESA_SHADER_MESH].module);
+ assert(mesh_shading == !!stages[MESA_SHADER_MESH].entrypoint);
/* Mesh shaders always need NGG. */
assert(!mesh_shading || pipeline_key->use_ngg);
goto done;
}
- if (!stages[MESA_SHADER_FRAGMENT].module && !stages[MESA_SHADER_COMPUTE].module) {
+ if (!stages[MESA_SHADER_FRAGMENT].entrypoint && !stages[MESA_SHADER_COMPUTE].entrypoint) {
nir_builder fs_b = radv_meta_init_shader(MESA_SHADER_FRAGMENT, "noop_fs");
- fs_m = vk_shader_module_from_nir(fs_b.shader);
stages[MESA_SHADER_FRAGMENT] = (struct radv_pipeline_stage) {
.stage = MESA_SHADER_FRAGMENT,
- .module = &fs_m,
+ .internal_nir = fs_b.shader,
.entrypoint = noop_fs_entrypoint,
.feedback = {
.flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
if (!shader)
continue;
- struct vk_shader_module *module = stages[i].module;
-
- if (!module || module->nir)
+ if (!stages[i].spirv.size)
continue;
- shader->spirv = malloc(module->size);
- memcpy(shader->spirv, module->data, module->size);
- shader->spirv_size = module->size;
+ shader->spirv = malloc(stages[i].spirv.size);
+ memcpy(shader->spirv, stages[i].spirv.data, stages[i].spirv.size);
+ shader->spirv_size = stages[i].spirv.size;
}
}
struct radv_pipeline_key key;
memset(&key, 0, sizeof(key));
- struct radv_pipeline_stage rt_stage = {
- .stage = vk_to_mesa_shader_stage(sinfo->stage),
- .module = vk_shader_module_from_handle(sinfo->module),
- .entrypoint = sinfo->pName,
- .spec_info = sinfo->pSpecializationInfo,
- .feedback = {
- .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
- },
- };
+ struct radv_pipeline_stage rt_stage;
+
+ radv_pipeline_stage_init(sinfo, &rt_stage, vk_to_mesa_shader_stage(sinfo->stage));
nir_shader *shader = radv_shader_compile_to_nir(device, &rt_stage, &key);
struct radv_pipeline_key;
+void radv_pipeline_stage_init(const VkPipelineShaderStageCreateInfo *sinfo,
+ struct radv_pipeline_stage *out_stage, gl_shader_stage stage);
+
void radv_hash_shaders(unsigned char *hash, const struct radv_pipeline_stage *stages,
const struct radv_pipeline_layout *layout,
const struct radv_pipeline_key *key, uint32_t flags);
struct radv_pipeline_stage {
gl_shader_stage stage;
- struct vk_shader_module *module;
+ struct {
+ const struct vk_object_base *object;
+ const char *data;
+ uint32_t size;
+ unsigned char sha1[20];
+ } spirv;
+
const char *entrypoint;
const VkSpecializationInfo *spec_info;
unsigned char shader_sha1[20];
nir_shader *nir;
+ nir_shader *internal_nir; /* meta shaders */
struct radv_shader_info info;
struct radv_shader_args args;
struct radv_shader_debug_data {
struct radv_device *device;
- const struct vk_shader_module *module;
+ const struct vk_object_base *object;
};
static void
snprintf(buffer, sizeof(buffer), "SPIR-V offset %lu: %s", (unsigned long)spirv_offset, message);
- vk_debug_report(&instance->vk, vk_flags[level], &debug_data->module->base, 0, 0, "radv", buffer);
+ vk_debug_report(&instance->vk, vk_flags[level], debug_data->object, 0, 0, "radv", buffer);
}
static void
radv_shader_compile_to_nir(struct radv_device *device, const struct radv_pipeline_stage *stage,
const struct radv_pipeline_key *key)
{
- struct vk_shader_module *module = stage->module;
-
unsigned subgroup_size = 64, ballot_bit_size = 64;
if (key->cs.compute_subgroup_size) {
/* Only compute shaders currently support requiring a
nir_shader *nir;
- if (module->nir) {
+ if (stage->internal_nir) {
/* Some things such as our meta clear/blit code will give us a NIR
* shader directly. In that case, we just ignore the SPIR-V entirely
* and just use the NIR shader. We don't want to alter meta and RT
* shaders IR directly, so clone it first. */
- nir = nir_shader_clone(NULL, module->nir);
+ nir = nir_shader_clone(NULL, stage->internal_nir);
nir->options = &device->physical_device->nir_options[stage->stage];
nir_validate_shader(nir, "in internal shader");
assert(exec_list_length(&nir->functions) == 1);
} else {
- uint32_t *spirv = (uint32_t *)module->data;
- assert(module->size % 4 == 0);
+ uint32_t *spirv = (uint32_t *)stage->spirv.data;
+ assert(stage->spirv.size % 4 == 0);
if (device->instance->debug_flags & RADV_DEBUG_DUMP_SPIRV)
- radv_print_spirv(module->data, module->size, stderr);
+ radv_print_spirv(stage->spirv.data, stage->spirv.size, stderr);
uint32_t num_spec_entries = 0;
struct nir_spirv_specialization *spec_entries =
vk_spec_info_to_nir_spirv(stage->spec_info, &num_spec_entries);
struct radv_shader_debug_data spirv_debug_data = {
.device = device,
- .module = module,
+ .object = stage->spirv.object,
};
const struct spirv_to_nir_options spirv_options = {
.caps =
.private_data = &spirv_debug_data,
},
};
- nir = spirv_to_nir(spirv, module->size / 4, spec_entries, num_spec_entries, stage->stage,
+ nir = spirv_to_nir(spirv, stage->spirv.size / 4, spec_entries, num_spec_entries, stage->stage,
stage->entrypoint, &spirv_options,
&device->physical_device->nir_options[stage->stage]);
assert(nir->info.stage == stage->stage);
struct radv_shader_debug_data debug_data = {
.device = device,
- .module = NULL,
+ .object = NULL,
};
options->family = chip_family;