radv: rework generating all graphics state for compiling pipelines
This introduces a new helper that will be used to generate a graphics pipeline hash from a pCreateInfo struct only. Similar to RT. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30049>
This commit is contained in:
committed by
Marge Bot
parent
8f102c9d61
commit
d1c97a1a50
@@ -601,13 +601,10 @@ radv_graphics_pipeline_import_layout(struct radv_pipeline_layout *dst, const str
|
||||
dst->push_constant_size = MAX2(dst->push_constant_size, src->push_constant_size);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
static void
|
||||
radv_pipeline_import_graphics_info(struct radv_device *device, struct radv_graphics_pipeline *pipeline,
|
||||
struct vk_graphics_pipeline_state *state,
|
||||
const VkGraphicsPipelineCreateInfo *pCreateInfo)
|
||||
{
|
||||
VkResult result;
|
||||
|
||||
/* Mark all states declared dynamic at pipeline creation. */
|
||||
if (pCreateInfo->pDynamicState) {
|
||||
uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount;
|
||||
@@ -623,18 +620,11 @@ radv_pipeline_import_graphics_info(struct radv_device *device, struct radv_graph
|
||||
pipeline->active_stages |= sinfo->stage;
|
||||
}
|
||||
|
||||
result = vk_graphics_pipeline_state_fill(&device->vk, state, pCreateInfo, NULL, 0, NULL, NULL,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, &pipeline->state_data);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
if (pipeline->active_stages & VK_SHADER_STAGE_MESH_BIT_EXT) {
|
||||
pipeline->last_vgt_api_stage = MESA_SHADER_MESH;
|
||||
} else {
|
||||
pipeline->last_vgt_api_stage = util_last_bit(pipeline->active_stages & BITFIELD_MASK(MESA_SHADER_FRAGMENT)) - 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -646,7 +636,7 @@ radv_should_import_lib_binaries(const VkPipelineCreateFlags2KHR create_flags)
|
||||
|
||||
static void
|
||||
radv_graphics_pipeline_import_lib(const struct radv_device *device, struct radv_graphics_pipeline *pipeline,
|
||||
struct vk_graphics_pipeline_state *state, struct radv_graphics_lib_pipeline *lib)
|
||||
struct radv_graphics_lib_pipeline *lib)
|
||||
{
|
||||
bool import_binaries = false;
|
||||
|
||||
@@ -658,8 +648,6 @@ radv_graphics_pipeline_import_lib(const struct radv_device *device, struct radv_
|
||||
pipeline->dynamic_states |= lib->base.dynamic_states;
|
||||
pipeline->active_stages |= lib->base.active_stages;
|
||||
|
||||
vk_graphics_pipeline_state_merge(state, &lib->graphics_state);
|
||||
|
||||
/* Import binaries when LTO is disabled and when the library doesn't retain any shaders. */
|
||||
if (radv_should_import_lib_binaries(pipeline->base.create_flags)) {
|
||||
import_binaries = true;
|
||||
@@ -680,9 +668,6 @@ radv_graphics_pipeline_import_lib(const struct radv_device *device, struct radv_
|
||||
pipeline->base.gs_copy_shader = radv_shader_ref(lib->base.base.gs_copy_shader);
|
||||
}
|
||||
}
|
||||
|
||||
/* Import the pipeline layout. */
|
||||
radv_graphics_pipeline_import_layout(&pipeline->layout, &lib->base.layout);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2245,7 +2230,7 @@ radv_pipeline_import_retained_shaders(const struct radv_device *device, struct r
|
||||
const VkPipelineShaderStageCreateInfo *sinfo = &lib->stages[i];
|
||||
gl_shader_stage s = vk_to_mesa_shader_stage(sinfo->stage);
|
||||
|
||||
radv_pipeline_stage_init(sinfo, &lib->base.layout, &lib->stage_keys[s], &stages[s]);
|
||||
radv_pipeline_stage_init(sinfo, &lib->layout, &lib->stage_keys[s], &stages[s]);
|
||||
}
|
||||
|
||||
/* Import the NIR shaders (after SPIRV->NIR). */
|
||||
@@ -2267,7 +2252,7 @@ radv_pipeline_import_retained_shaders(const struct radv_device *device, struct r
|
||||
memcpy(stages[s].shader_sha1, retained_shaders->stages[s].shader_sha1, sizeof(stages[s].shader_sha1));
|
||||
memcpy(&stages[s].key, &retained_shaders->stages[s].key, sizeof(stages[s].key));
|
||||
|
||||
radv_shader_layout_init(&lib->base.layout, s, &stages[s].layout);
|
||||
radv_shader_layout_init(&lib->layout, s, &stages[s].layout);
|
||||
|
||||
stages[s].feedback.flags |= VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
|
||||
|
||||
@@ -2340,10 +2325,15 @@ radv_is_fast_linking_enabled(const VkGraphicsPipelineCreateInfo *pCreateInfo)
|
||||
static bool
|
||||
radv_skip_graphics_pipeline_compile(const struct radv_device *device, const VkGraphicsPipelineCreateInfo *pCreateInfo)
|
||||
{
|
||||
const VkPipelineCreateFlags2KHR create_flags = vk_graphics_pipeline_create_flags(pCreateInfo);
|
||||
const struct radv_physical_device *pdev = radv_device_physical(device);
|
||||
VkShaderStageFlagBits binary_stages = 0;
|
||||
VkShaderStageFlags active_stages = 0;
|
||||
|
||||
/* Do not skip for libraries. */
|
||||
if (create_flags & VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR)
|
||||
return false;
|
||||
|
||||
/* Do not skip when fast-linking isn't enabled. */
|
||||
if (!radv_is_fast_linking_enabled(pCreateInfo))
|
||||
return false;
|
||||
@@ -2579,25 +2569,135 @@ radv_should_compute_pipeline_hash(const struct radv_device *device, const enum r
|
||||
((instance->vk.trace_mode & RADV_TRACE_MODE_RGP) && pipeline_type == RADV_PIPELINE_GRAPHICS);
|
||||
}
|
||||
|
||||
struct radv_graphics_pipeline_state {
|
||||
struct vk_graphics_pipeline_state vk;
|
||||
void *vk_data;
|
||||
|
||||
bool compilation_required;
|
||||
|
||||
struct radv_shader_stage *stages;
|
||||
|
||||
struct radv_graphics_pipeline_key key;
|
||||
|
||||
struct radv_pipeline_layout layout;
|
||||
};
|
||||
|
||||
static void
|
||||
radv_graphics_pipeline_hash(const struct radv_device *device, const struct radv_shader_stage *stages,
|
||||
uint32_t stage_count, const struct radv_pipeline_layout *layout,
|
||||
const struct radv_graphics_state_key *gfx_state, unsigned char *hash)
|
||||
radv_graphics_pipeline_state_finish(struct radv_device *device, struct radv_graphics_pipeline_state *gfx_state)
|
||||
{
|
||||
radv_pipeline_layout_finish(device, &gfx_state->layout);
|
||||
vk_free(&device->vk.alloc, gfx_state->vk_data);
|
||||
|
||||
if (gfx_state->stages) {
|
||||
for (uint32_t i = 0; i < MESA_VULKAN_SHADER_STAGES; i++)
|
||||
ralloc_free(gfx_state->stages[i].nir);
|
||||
free(gfx_state->stages);
|
||||
}
|
||||
}
|
||||
|
||||
static VkResult
|
||||
radv_generate_graphics_pipeline_state(struct radv_device *device, const VkGraphicsPipelineCreateInfo *pCreateInfo,
|
||||
struct radv_graphics_pipeline_state *gfx_state)
|
||||
{
|
||||
VK_FROM_HANDLE(radv_pipeline_layout, pipeline_layout, pCreateInfo->layout);
|
||||
const VkPipelineCreateFlags2KHR create_flags = vk_graphics_pipeline_create_flags(pCreateInfo);
|
||||
const bool fast_linking_enabled = radv_is_fast_linking_enabled(pCreateInfo);
|
||||
enum radv_pipeline_type pipeline_type = RADV_PIPELINE_GRAPHICS;
|
||||
VkResult result;
|
||||
|
||||
memset(gfx_state, 0, sizeof(*gfx_state));
|
||||
|
||||
VkGraphicsPipelineLibraryFlagBitsEXT needed_lib_flags = ALL_GRAPHICS_LIB_FLAGS;
|
||||
if (create_flags & VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR) {
|
||||
const VkGraphicsPipelineLibraryCreateInfoEXT *lib_info =
|
||||
vk_find_struct_const(pCreateInfo->pNext, GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT);
|
||||
needed_lib_flags = lib_info ? lib_info->flags : 0;
|
||||
pipeline_type = RADV_PIPELINE_GRAPHICS_LIB;
|
||||
}
|
||||
|
||||
radv_pipeline_layout_init(device, &gfx_state->layout, false);
|
||||
|
||||
/* If we have libraries, import them first. */
|
||||
const VkPipelineLibraryCreateInfoKHR *libs_info =
|
||||
vk_find_struct_const(pCreateInfo->pNext, PIPELINE_LIBRARY_CREATE_INFO_KHR);
|
||||
if (libs_info) {
|
||||
for (uint32_t i = 0; i < libs_info->libraryCount; i++) {
|
||||
VK_FROM_HANDLE(radv_pipeline, pipeline_lib, libs_info->pLibraries[i]);
|
||||
const struct radv_graphics_lib_pipeline *gfx_pipeline_lib = radv_pipeline_to_graphics_lib(pipeline_lib);
|
||||
|
||||
vk_graphics_pipeline_state_merge(&gfx_state->vk, &gfx_pipeline_lib->graphics_state);
|
||||
|
||||
radv_graphics_pipeline_import_layout(&gfx_state->layout, &gfx_pipeline_lib->layout);
|
||||
|
||||
needed_lib_flags &= ~gfx_pipeline_lib->lib_flags;
|
||||
}
|
||||
}
|
||||
|
||||
result = vk_graphics_pipeline_state_fill(&device->vk, &gfx_state->vk, pCreateInfo, NULL, 0, NULL, NULL,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, &gfx_state->vk_data);
|
||||
if (result != VK_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
if (pipeline_layout)
|
||||
radv_graphics_pipeline_import_layout(&gfx_state->layout, pipeline_layout);
|
||||
|
||||
if (radv_should_compute_pipeline_hash(device, pipeline_type, fast_linking_enabled))
|
||||
radv_pipeline_layout_hash(&gfx_state->layout);
|
||||
|
||||
gfx_state->compilation_required = !radv_skip_graphics_pipeline_compile(device, pCreateInfo);
|
||||
if (gfx_state->compilation_required) {
|
||||
gfx_state->key = radv_generate_graphics_pipeline_key(device, pCreateInfo, &gfx_state->vk, needed_lib_flags);
|
||||
|
||||
gfx_state->stages = malloc(sizeof(struct radv_shader_stage) * MESA_VULKAN_SHADER_STAGES);
|
||||
if (!gfx_state->stages) {
|
||||
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < MESA_VULKAN_SHADER_STAGES; i++) {
|
||||
gfx_state->stages[i].entrypoint = NULL;
|
||||
gfx_state->stages[i].nir = NULL;
|
||||
gfx_state->stages[i].spirv.size = 0;
|
||||
gfx_state->stages[i].next_stage = MESA_SHADER_NONE;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
|
||||
const VkPipelineShaderStageCreateInfo *sinfo = &pCreateInfo->pStages[i];
|
||||
gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
|
||||
|
||||
radv_pipeline_stage_init(sinfo, &gfx_state->layout, &gfx_state->key.stage_info[stage],
|
||||
&gfx_state->stages[stage]);
|
||||
}
|
||||
|
||||
radv_pipeline_load_retained_shaders(device, pCreateInfo, gfx_state->stages);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
fail:
|
||||
radv_graphics_pipeline_state_finish(device, gfx_state);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
radv_graphics_pipeline_hash(const struct radv_device *device, const struct radv_graphics_pipeline_state *gfx_state,
|
||||
unsigned char *hash)
|
||||
{
|
||||
struct mesa_sha1 ctx;
|
||||
|
||||
_mesa_sha1_init(&ctx);
|
||||
radv_pipeline_hash(device, layout, &ctx);
|
||||
radv_pipeline_hash(device, &gfx_state->layout, &ctx);
|
||||
|
||||
if (gfx_state)
|
||||
_mesa_sha1_update(&ctx, gfx_state, sizeof(*gfx_state));
|
||||
_mesa_sha1_update(&ctx, &gfx_state->key.gfx_state, sizeof(gfx_state->key.gfx_state));
|
||||
|
||||
for (unsigned s = 0; s < stage_count; s++) {
|
||||
if (!stages[s].entrypoint)
|
||||
for (unsigned s = 0; s < MESA_VULKAN_SHADER_STAGES; s++) {
|
||||
const struct radv_shader_stage *stage = &gfx_state->stages[s];
|
||||
|
||||
if (!stage->entrypoint)
|
||||
continue;
|
||||
|
||||
_mesa_sha1_update(&ctx, stages[s].shader_sha1, sizeof(stages[s].shader_sha1));
|
||||
_mesa_sha1_update(&ctx, &stages[s].key, sizeof(stages[s].key));
|
||||
_mesa_sha1_update(&ctx, stage->shader_sha1, sizeof(stage->shader_sha1));
|
||||
_mesa_sha1_update(&ctx, &stage->key, sizeof(stage->key));
|
||||
}
|
||||
|
||||
_mesa_sha1_final(&ctx, hash);
|
||||
@@ -2605,15 +2705,14 @@ radv_graphics_pipeline_hash(const struct radv_device *device, const struct radv_
|
||||
|
||||
static VkResult
|
||||
radv_graphics_pipeline_compile(struct radv_graphics_pipeline *pipeline, const VkGraphicsPipelineCreateInfo *pCreateInfo,
|
||||
struct radv_pipeline_layout *pipeline_layout, struct radv_device *device,
|
||||
struct vk_pipeline_cache *cache, const struct radv_graphics_pipeline_key *pipeline_key,
|
||||
bool fast_linking_enabled)
|
||||
const struct radv_graphics_pipeline_state *gfx_state, struct radv_device *device,
|
||||
struct vk_pipeline_cache *cache, bool fast_linking_enabled)
|
||||
{
|
||||
struct radv_shader_binary *binaries[MESA_VULKAN_SHADER_STAGES] = {NULL};
|
||||
struct radv_shader_binary *gs_copy_binary = NULL;
|
||||
bool keep_executable_info = radv_pipeline_capture_shaders(device, pipeline->base.create_flags);
|
||||
bool keep_statistic_info = radv_pipeline_capture_shader_stats(device, pipeline->base.create_flags);
|
||||
struct radv_shader_stage *stages = malloc(sizeof(struct radv_shader_stage) * MESA_VULKAN_SHADER_STAGES);
|
||||
struct radv_shader_stage *stages = gfx_state->stages;
|
||||
const VkPipelineCreationFeedbackCreateInfo *creation_feedback =
|
||||
vk_find_struct_const(pCreateInfo->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
|
||||
VkPipelineCreationFeedback pipeline_feedback = {
|
||||
@@ -2625,30 +2724,10 @@ radv_graphics_pipeline_compile(struct radv_graphics_pipeline *pipeline, const Vk
|
||||
!!(pipeline->base.create_flags & VK_PIPELINE_CREATE_2_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT);
|
||||
struct radv_retained_shaders *retained_shaders = NULL;
|
||||
|
||||
if (!stages)
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
|
||||
int64_t pipeline_start = os_time_get_nano();
|
||||
|
||||
for (unsigned i = 0; i < MESA_VULKAN_SHADER_STAGES; i++) {
|
||||
stages[i].entrypoint = NULL;
|
||||
stages[i].nir = NULL;
|
||||
stages[i].spirv.size = 0;
|
||||
stages[i].next_stage = MESA_SHADER_NONE;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
|
||||
const VkPipelineShaderStageCreateInfo *sinfo = &pCreateInfo->pStages[i];
|
||||
gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
|
||||
|
||||
radv_pipeline_stage_init(sinfo, pipeline_layout, &pipeline_key->stage_info[stage], &stages[stage]);
|
||||
}
|
||||
|
||||
radv_pipeline_load_retained_shaders(device, pCreateInfo, stages);
|
||||
|
||||
if (radv_should_compute_pipeline_hash(device, pipeline->base.type, fast_linking_enabled)) {
|
||||
radv_graphics_pipeline_hash(device, stages, MESA_VULKAN_SHADER_STAGES, pipeline_layout, &pipeline_key->gfx_state,
|
||||
pipeline->base.sha1);
|
||||
radv_graphics_pipeline_hash(device, gfx_state, pipeline->base.sha1);
|
||||
|
||||
pipeline->base.pipeline_hash = *(uint64_t *)pipeline->base.sha1;
|
||||
}
|
||||
@@ -2686,16 +2765,14 @@ radv_graphics_pipeline_compile(struct radv_graphics_pipeline *pipeline, const Vk
|
||||
|
||||
gfx_pipeline_lib->stages = radv_copy_shader_stage_create_info(device, pCreateInfo->stageCount,
|
||||
pCreateInfo->pStages, gfx_pipeline_lib->mem_ctx);
|
||||
if (!gfx_pipeline_lib->stages) {
|
||||
free(stages);
|
||||
if (!gfx_pipeline_lib->stages)
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
gfx_pipeline_lib->stage_count = pCreateInfo->stageCount;
|
||||
|
||||
for (unsigned i = 0; i < pCreateInfo->stageCount; i++) {
|
||||
gl_shader_stage s = vk_to_mesa_shader_stage(pCreateInfo->pStages[i].stage);
|
||||
gfx_pipeline_lib->stage_keys[s] = pipeline_key->stage_info[s];
|
||||
gfx_pipeline_lib->stage_keys[s] = gfx_state->key.stage_info[s];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2703,19 +2780,17 @@ radv_graphics_pipeline_compile(struct radv_graphics_pipeline *pipeline, const Vk
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (pipeline->base.create_flags & VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR) {
|
||||
free(stages);
|
||||
if (pipeline->base.create_flags & VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR)
|
||||
return VK_PIPELINE_COMPILE_REQUIRED;
|
||||
}
|
||||
|
||||
if (retain_shaders) {
|
||||
struct radv_graphics_lib_pipeline *gfx_pipeline_lib = radv_pipeline_to_graphics_lib(&pipeline->base);
|
||||
retained_shaders = &gfx_pipeline_lib->retained_shaders;
|
||||
}
|
||||
|
||||
const bool noop_fs = radv_pipeline_needs_noop_fs(pipeline, &pipeline_key->gfx_state);
|
||||
const bool noop_fs = radv_pipeline_needs_noop_fs(pipeline, &gfx_state->key.gfx_state);
|
||||
|
||||
radv_graphics_shaders_compile(device, cache, stages, &pipeline_key->gfx_state, keep_executable_info,
|
||||
radv_graphics_shaders_compile(device, cache, stages, &gfx_state->key.gfx_state, keep_executable_info,
|
||||
keep_statistic_info, pipeline->base.is_internal, retained_shaders, noop_fs,
|
||||
pipeline->base.shaders, binaries, &pipeline->base.gs_copy_shader, &gs_copy_binary);
|
||||
|
||||
@@ -2734,9 +2809,6 @@ radv_graphics_pipeline_compile(struct radv_graphics_pipeline *pipeline, const Vk
|
||||
}
|
||||
|
||||
done:
|
||||
for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
|
||||
ralloc_free(stages[i].nir);
|
||||
}
|
||||
pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
|
||||
|
||||
if (creation_feedback) {
|
||||
@@ -2774,7 +2846,6 @@ done:
|
||||
}
|
||||
}
|
||||
|
||||
free(stages);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3058,10 +3129,8 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv
|
||||
struct vk_pipeline_cache *cache, const VkGraphicsPipelineCreateInfo *pCreateInfo,
|
||||
const struct radv_graphics_pipeline_create_info *extra)
|
||||
{
|
||||
VK_FROM_HANDLE(radv_pipeline_layout, pipeline_layout, pCreateInfo->layout);
|
||||
VkGraphicsPipelineLibraryFlagBitsEXT needed_lib_flags = ALL_GRAPHICS_LIB_FLAGS;
|
||||
bool fast_linking_enabled = radv_is_fast_linking_enabled(pCreateInfo);
|
||||
struct vk_graphics_pipeline_state state = {0};
|
||||
struct radv_graphics_pipeline_state gfx_state;
|
||||
VkResult result = VK_SUCCESS;
|
||||
|
||||
pipeline->last_vgt_api_stage = MESA_SHADER_NONE;
|
||||
@@ -3069,8 +3138,6 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv
|
||||
const VkPipelineLibraryCreateInfoKHR *libs_info =
|
||||
vk_find_struct_const(pCreateInfo->pNext, PIPELINE_LIBRARY_CREATE_INFO_KHR);
|
||||
|
||||
radv_pipeline_layout_init(device, &pipeline->layout, false);
|
||||
|
||||
/* If we have libraries, import them first. */
|
||||
if (libs_info) {
|
||||
for (uint32_t i = 0; i < libs_info->libraryCount; i++) {
|
||||
@@ -3079,40 +3146,31 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv
|
||||
|
||||
assert(pipeline_lib->type == RADV_PIPELINE_GRAPHICS_LIB);
|
||||
|
||||
radv_graphics_pipeline_import_lib(device, pipeline, &state, gfx_pipeline_lib);
|
||||
|
||||
needed_lib_flags &= ~gfx_pipeline_lib->lib_flags;
|
||||
radv_graphics_pipeline_import_lib(device, pipeline, gfx_pipeline_lib);
|
||||
}
|
||||
}
|
||||
|
||||
/* Import graphics pipeline info that was not included in the libraries. */
|
||||
result = radv_pipeline_import_graphics_info(device, pipeline, &state, pCreateInfo);
|
||||
radv_pipeline_import_graphics_info(device, pipeline, pCreateInfo);
|
||||
|
||||
result = radv_generate_graphics_pipeline_state(device, pCreateInfo, &gfx_state);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
if (pipeline_layout)
|
||||
radv_graphics_pipeline_import_layout(&pipeline->layout, pipeline_layout);
|
||||
|
||||
if (radv_should_compute_pipeline_hash(device, pipeline->base.type, fast_linking_enabled))
|
||||
radv_pipeline_layout_hash(&pipeline->layout);
|
||||
|
||||
if (!radv_skip_graphics_pipeline_compile(device, pCreateInfo)) {
|
||||
struct radv_graphics_pipeline_key key =
|
||||
radv_generate_graphics_pipeline_key(device, pCreateInfo, &state, needed_lib_flags);
|
||||
|
||||
result = radv_graphics_pipeline_compile(pipeline, pCreateInfo, &pipeline->layout, device, cache, &key,
|
||||
fast_linking_enabled);
|
||||
if (result != VK_SUCCESS)
|
||||
if (gfx_state.compilation_required) {
|
||||
result = radv_graphics_pipeline_compile(pipeline, pCreateInfo, &gfx_state, device, cache, fast_linking_enabled);
|
||||
if (result != VK_SUCCESS) {
|
||||
radv_graphics_pipeline_state_finish(device, &gfx_state);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t vgt_gs_out_prim_type = radv_pipeline_init_vgt_gs_out(pipeline, &state);
|
||||
uint32_t vgt_gs_out_prim_type = radv_pipeline_init_vgt_gs_out(pipeline, &gfx_state.vk);
|
||||
|
||||
radv_pipeline_init_multisample_state(device, pipeline, pCreateInfo, &state);
|
||||
radv_pipeline_init_multisample_state(device, pipeline, pCreateInfo, &gfx_state.vk);
|
||||
|
||||
if (!radv_pipeline_has_stage(pipeline, MESA_SHADER_MESH))
|
||||
radv_pipeline_init_input_assembly_state(device, pipeline);
|
||||
radv_pipeline_init_dynamic_state(device, pipeline, &state, pCreateInfo);
|
||||
radv_pipeline_init_dynamic_state(device, pipeline, &gfx_state.vk, pCreateInfo);
|
||||
|
||||
const struct radv_shader *ps = pipeline->base.shaders[MESA_SHADER_FRAGMENT];
|
||||
if (ps && !ps->info.has_epilog) {
|
||||
@@ -3126,7 +3184,7 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv
|
||||
}
|
||||
|
||||
if (!radv_pipeline_has_stage(pipeline, MESA_SHADER_MESH))
|
||||
radv_pipeline_init_vertex_input_state(device, pipeline, &state);
|
||||
radv_pipeline_init_vertex_input_state(device, pipeline, &gfx_state.vk);
|
||||
|
||||
radv_pipeline_init_shader_stages_state(device, pipeline);
|
||||
|
||||
@@ -3135,18 +3193,19 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv
|
||||
pipeline->is_ngg && pipeline->base.shaders[pipeline->last_vgt_api_stage]->info.has_ngg_culling;
|
||||
pipeline->force_vrs_per_vertex = pipeline->base.shaders[pipeline->last_vgt_api_stage]->info.force_vrs_per_vertex;
|
||||
pipeline->rast_prim = vgt_gs_out_prim_type;
|
||||
pipeline->uses_out_of_order_rast = state.rs->rasterization_order_amd == VK_RASTERIZATION_ORDER_RELAXED_AMD;
|
||||
pipeline->uses_vrs = radv_is_vrs_enabled(&state);
|
||||
pipeline->uses_vrs_attachment = radv_pipeline_uses_vrs_attachment(pipeline, &state);
|
||||
pipeline->uses_out_of_order_rast = gfx_state.vk.rs->rasterization_order_amd == VK_RASTERIZATION_ORDER_RELAXED_AMD;
|
||||
pipeline->uses_vrs = radv_is_vrs_enabled(&gfx_state.vk);
|
||||
pipeline->uses_vrs_attachment = radv_pipeline_uses_vrs_attachment(pipeline, &gfx_state.vk);
|
||||
pipeline->uses_vrs_coarse_shading = !pipeline->uses_vrs && gfx103_pipeline_vrs_coarse_shading(device, pipeline);
|
||||
|
||||
pipeline->base.push_constant_size = pipeline->layout.push_constant_size;
|
||||
pipeline->base.dynamic_offset_count = pipeline->layout.dynamic_offset_count;
|
||||
pipeline->base.push_constant_size = gfx_state.layout.push_constant_size;
|
||||
pipeline->base.dynamic_offset_count = gfx_state.layout.dynamic_offset_count;
|
||||
|
||||
if (extra) {
|
||||
radv_pipeline_init_extra(pipeline, extra, &state);
|
||||
radv_pipeline_init_extra(pipeline, extra, &gfx_state.vk);
|
||||
}
|
||||
|
||||
radv_graphics_pipeline_state_finish(device, &gfx_state);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3182,8 +3241,6 @@ radv_graphics_pipeline_create(VkDevice _device, VkPipelineCache _cache, const Vk
|
||||
void
|
||||
radv_destroy_graphics_pipeline(struct radv_device *device, struct radv_graphics_pipeline *pipeline)
|
||||
{
|
||||
radv_pipeline_layout_finish(device, &pipeline->layout);
|
||||
|
||||
for (unsigned i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
|
||||
if (pipeline->base.shaders[i])
|
||||
radv_shader_unref(device, pipeline->base.shaders[i]);
|
||||
@@ -3191,8 +3248,6 @@ radv_destroy_graphics_pipeline(struct radv_device *device, struct radv_graphics_
|
||||
|
||||
if (pipeline->base.gs_copy_shader)
|
||||
radv_shader_unref(device, pipeline->base.gs_copy_shader);
|
||||
|
||||
vk_free(&device->vk.alloc, pipeline->state_data);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
@@ -3200,11 +3255,11 @@ radv_graphics_lib_pipeline_init(struct radv_graphics_lib_pipeline *pipeline, str
|
||||
struct vk_pipeline_cache *cache, const VkGraphicsPipelineCreateInfo *pCreateInfo)
|
||||
{
|
||||
VK_FROM_HANDLE(radv_pipeline_layout, pipeline_layout, pCreateInfo->layout);
|
||||
struct radv_graphics_pipeline_state gfx_state;
|
||||
VkResult result;
|
||||
|
||||
const VkGraphicsPipelineLibraryCreateInfoEXT *lib_info =
|
||||
vk_find_struct_const(pCreateInfo->pNext, GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT);
|
||||
VkGraphicsPipelineLibraryFlagBitsEXT needed_lib_flags = lib_info ? lib_info->flags : 0;
|
||||
const VkPipelineLibraryCreateInfoKHR *libs_info =
|
||||
vk_find_struct_const(pCreateInfo->pNext, PIPELINE_LIBRARY_CREATE_INFO_KHR);
|
||||
bool fast_linking_enabled = radv_is_fast_linking_enabled(pCreateInfo);
|
||||
@@ -3212,9 +3267,9 @@ radv_graphics_lib_pipeline_init(struct radv_graphics_lib_pipeline *pipeline, str
|
||||
struct vk_graphics_pipeline_state *state = &pipeline->graphics_state;
|
||||
|
||||
pipeline->base.last_vgt_api_stage = MESA_SHADER_NONE;
|
||||
pipeline->lib_flags = needed_lib_flags;
|
||||
pipeline->lib_flags = lib_info ? lib_info->flags : 0;
|
||||
|
||||
radv_pipeline_layout_init(device, &pipeline->base.layout, false);
|
||||
radv_pipeline_layout_init(device, &pipeline->layout, false);
|
||||
|
||||
/* If we have libraries, import them first. */
|
||||
if (libs_info) {
|
||||
@@ -3222,29 +3277,35 @@ radv_graphics_lib_pipeline_init(struct radv_graphics_lib_pipeline *pipeline, str
|
||||
VK_FROM_HANDLE(radv_pipeline, pipeline_lib, libs_info->pLibraries[i]);
|
||||
struct radv_graphics_lib_pipeline *gfx_pipeline_lib = radv_pipeline_to_graphics_lib(pipeline_lib);
|
||||
|
||||
radv_graphics_pipeline_import_lib(device, &pipeline->base, state, gfx_pipeline_lib);
|
||||
vk_graphics_pipeline_state_merge(state, &gfx_pipeline_lib->graphics_state);
|
||||
|
||||
radv_graphics_pipeline_import_layout(&pipeline->layout, &gfx_pipeline_lib->layout);
|
||||
|
||||
radv_graphics_pipeline_import_lib(device, &pipeline->base, gfx_pipeline_lib);
|
||||
|
||||
pipeline->lib_flags |= gfx_pipeline_lib->lib_flags;
|
||||
|
||||
needed_lib_flags &= ~gfx_pipeline_lib->lib_flags;
|
||||
}
|
||||
}
|
||||
|
||||
result = radv_pipeline_import_graphics_info(device, &pipeline->base, state, pCreateInfo);
|
||||
result = vk_graphics_pipeline_state_fill(&device->vk, state, pCreateInfo, NULL, 0, NULL, NULL,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, &pipeline->state_data);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
radv_pipeline_import_graphics_info(device, &pipeline->base, pCreateInfo);
|
||||
|
||||
if (pipeline_layout)
|
||||
radv_graphics_pipeline_import_layout(&pipeline->base.layout, pipeline_layout);
|
||||
radv_graphics_pipeline_import_layout(&pipeline->layout, pipeline_layout);
|
||||
|
||||
if (radv_should_compute_pipeline_hash(device, pipeline->base.base.type, fast_linking_enabled))
|
||||
radv_pipeline_layout_hash(&pipeline->base.layout);
|
||||
result = radv_generate_graphics_pipeline_state(device, pCreateInfo, &gfx_state);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
struct radv_graphics_pipeline_key key =
|
||||
radv_generate_graphics_pipeline_key(device, pCreateInfo, state, needed_lib_flags);
|
||||
result =
|
||||
radv_graphics_pipeline_compile(&pipeline->base, pCreateInfo, &gfx_state, device, cache, fast_linking_enabled);
|
||||
|
||||
return radv_graphics_pipeline_compile(&pipeline->base, pCreateInfo, &pipeline->base.layout, device, cache, &key,
|
||||
fast_linking_enabled);
|
||||
radv_graphics_pipeline_state_finish(device, &gfx_state);
|
||||
return result;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
@@ -3282,6 +3343,10 @@ radv_destroy_graphics_lib_pipeline(struct radv_device *device, struct radv_graph
|
||||
{
|
||||
struct radv_retained_shaders *retained_shaders = &pipeline->retained_shaders;
|
||||
|
||||
radv_pipeline_layout_finish(device, &pipeline->layout);
|
||||
|
||||
vk_free(&device->vk.alloc, pipeline->state_data);
|
||||
|
||||
for (unsigned i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
|
||||
free(retained_shaders->stages[i].serialized_nir);
|
||||
}
|
||||
|
||||
@@ -68,8 +68,6 @@ struct radv_sqtt_shaders_reloc {
|
||||
struct radv_graphics_pipeline {
|
||||
struct radv_pipeline base;
|
||||
|
||||
struct radv_pipeline_layout layout;
|
||||
|
||||
bool uses_drawid;
|
||||
bool uses_baseinstance;
|
||||
|
||||
@@ -108,8 +106,6 @@ struct radv_graphics_pipeline {
|
||||
|
||||
unsigned rast_prim;
|
||||
|
||||
/* For vk_graphics_pipeline_state */
|
||||
void *state_data;
|
||||
|
||||
/* Custom blend mode for internal operations. */
|
||||
unsigned custom_blend_mode;
|
||||
@@ -146,6 +142,11 @@ struct radv_graphics_lib_pipeline {
|
||||
|
||||
struct vk_graphics_pipeline_state graphics_state;
|
||||
|
||||
/* For vk_graphics_pipeline_state */
|
||||
void *state_data;
|
||||
|
||||
struct radv_pipeline_layout layout;
|
||||
|
||||
VkGraphicsPipelineLibraryFlagsEXT lib_flags;
|
||||
|
||||
struct radv_retained_shaders retained_shaders;
|
||||
|
||||
Reference in New Issue
Block a user