lavapipe: Use more Vulkan NIR heleprs
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17644>
This commit is contained in:
parent
8e99a7f5e3
commit
9965863a13
|
@ -22,6 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lvp_private.h"
|
#include "lvp_private.h"
|
||||||
|
#include "vk_pipeline.h"
|
||||||
#include "vk_render_pass.h"
|
#include "vk_render_pass.h"
|
||||||
#include "vk_util.h"
|
#include "vk_util.h"
|
||||||
#include "glsl_types.h"
|
#include "glsl_types.h"
|
||||||
|
@ -915,31 +916,16 @@ lvp_shader_optimize(nir_shader *nir)
|
||||||
nir_sweep(nir);
|
nir_sweep(nir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static VkResult
|
||||||
can_remove_var(nir_variable *var, void *data)
|
|
||||||
{
|
|
||||||
return var->data.mode != nir_var_shader_out || (!var->data.explicit_xfb_buffer && !var->data.explicit_xfb_stride);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
|
lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
|
||||||
uint32_t size,
|
const VkPipelineShaderStageCreateInfo *sinfo)
|
||||||
const void *module,
|
|
||||||
const char *entrypoint_name,
|
|
||||||
gl_shader_stage stage,
|
|
||||||
const VkSpecializationInfo *spec_info)
|
|
||||||
{
|
{
|
||||||
nir_shader *nir;
|
|
||||||
const nir_shader_compiler_options *drv_options = pipeline->device->pscreen->get_compiler_options(pipeline->device->pscreen, PIPE_SHADER_IR_NIR, st_shader_stage_to_ptarget(stage));
|
|
||||||
const uint32_t *spirv = module;
|
|
||||||
assert(spirv[0] == SPIR_V_MAGIC_NUMBER);
|
|
||||||
assert(size % 4 == 0);
|
|
||||||
|
|
||||||
uint32_t num_spec_entries = 0;
|
|
||||||
struct nir_spirv_specialization *spec_entries =
|
|
||||||
vk_spec_info_to_nir_spirv(spec_info, &num_spec_entries);
|
|
||||||
|
|
||||||
struct lvp_device *pdevice = pipeline->device;
|
struct lvp_device *pdevice = pipeline->device;
|
||||||
|
gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
|
||||||
|
const nir_shader_compiler_options *drv_options = pdevice->pscreen->get_compiler_options(pipeline->device->pscreen, PIPE_SHADER_IR_NIR, st_shader_stage_to_ptarget(stage));
|
||||||
|
VkResult result;
|
||||||
|
nir_shader *nir;
|
||||||
|
|
||||||
const struct spirv_to_nir_options spirv_options = {
|
const struct spirv_to_nir_options spirv_options = {
|
||||||
.environment = NIR_SPIRV_VULKAN,
|
.environment = NIR_SPIRV_VULKAN,
|
||||||
.caps = {
|
.caps = {
|
||||||
|
@ -986,17 +972,11 @@ lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
|
||||||
.shared_addr_format = nir_address_format_32bit_offset,
|
.shared_addr_format = nir_address_format_32bit_offset,
|
||||||
};
|
};
|
||||||
|
|
||||||
nir = spirv_to_nir(spirv, size / 4,
|
result = vk_pipeline_shader_stage_to_nir(&pdevice->vk, sinfo,
|
||||||
spec_entries, num_spec_entries,
|
&spirv_options, drv_options,
|
||||||
stage, entrypoint_name, &spirv_options, drv_options);
|
NULL, &nir);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
if (!nir) {
|
return result;
|
||||||
free(spec_entries);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
nir_validate_shader(nir, NULL);
|
|
||||||
|
|
||||||
free(spec_entries);
|
|
||||||
|
|
||||||
if (nir->info.stage != MESA_SHADER_TESS_CTRL)
|
if (nir->info.stage != MESA_SHADER_TESS_CTRL)
|
||||||
NIR_PASS_V(nir, remove_scoped_barriers, nir->info.stage == MESA_SHADER_COMPUTE);
|
NIR_PASS_V(nir, remove_scoped_barriers, nir->info.stage == MESA_SHADER_COMPUTE);
|
||||||
|
@ -1007,30 +987,12 @@ lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
|
||||||
};
|
};
|
||||||
NIR_PASS_V(nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings);
|
NIR_PASS_V(nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings);
|
||||||
|
|
||||||
NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
|
|
||||||
NIR_PASS_V(nir, nir_lower_returns);
|
|
||||||
NIR_PASS_V(nir, nir_inline_functions);
|
|
||||||
NIR_PASS_V(nir, nir_copy_prop);
|
|
||||||
NIR_PASS_V(nir, nir_opt_deref);
|
|
||||||
|
|
||||||
/* Pick off the single entrypoint that we want */
|
|
||||||
nir_remove_non_entrypoints(nir);
|
|
||||||
|
|
||||||
struct nir_lower_subgroups_options subgroup_opts = {0};
|
struct nir_lower_subgroups_options subgroup_opts = {0};
|
||||||
subgroup_opts.lower_quad = true;
|
subgroup_opts.lower_quad = true;
|
||||||
subgroup_opts.ballot_components = 4;
|
subgroup_opts.ballot_components = 4;
|
||||||
subgroup_opts.ballot_bit_size = 32;
|
subgroup_opts.ballot_bit_size = 32;
|
||||||
NIR_PASS_V(nir, nir_lower_subgroups, &subgroup_opts);
|
NIR_PASS_V(nir, nir_lower_subgroups, &subgroup_opts);
|
||||||
|
|
||||||
NIR_PASS_V(nir, nir_lower_variable_initializers, ~0);
|
|
||||||
NIR_PASS_V(nir, nir_split_var_copies);
|
|
||||||
NIR_PASS_V(nir, nir_split_per_member_structs);
|
|
||||||
|
|
||||||
nir_remove_dead_variables_options var_opts = {0};
|
|
||||||
var_opts.can_remove_var = can_remove_var;
|
|
||||||
NIR_PASS_V(nir, nir_remove_dead_variables,
|
|
||||||
nir_var_shader_in | nir_var_shader_out | nir_var_system_value, &var_opts);
|
|
||||||
|
|
||||||
if (stage == MESA_SHADER_FRAGMENT)
|
if (stage == MESA_SHADER_FRAGMENT)
|
||||||
lvp_lower_input_attachments(nir, false);
|
lvp_lower_input_attachments(nir, false);
|
||||||
NIR_PASS_V(nir, nir_lower_is_helper_invocation);
|
NIR_PASS_V(nir, nir_lower_is_helper_invocation);
|
||||||
|
@ -1038,7 +1000,6 @@ lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
|
||||||
NIR_PASS_V(nir, nir_lower_system_values);
|
NIR_PASS_V(nir, nir_lower_system_values);
|
||||||
NIR_PASS_V(nir, nir_lower_compute_system_values, NULL);
|
NIR_PASS_V(nir, nir_lower_compute_system_values, NULL);
|
||||||
|
|
||||||
NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);
|
|
||||||
NIR_PASS_V(nir, nir_remove_dead_variables,
|
NIR_PASS_V(nir, nir_remove_dead_variables,
|
||||||
nir_var_uniform | nir_var_image, NULL);
|
nir_var_uniform | nir_var_image, NULL);
|
||||||
|
|
||||||
|
@ -1088,11 +1049,6 @@ lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
|
||||||
|
|
||||||
nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
|
nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
|
||||||
|
|
||||||
if (nir->info.stage == MESA_SHADER_VERTEX ||
|
|
||||||
nir->info.stage == MESA_SHADER_GEOMETRY ||
|
|
||||||
nir->info.stage == MESA_SHADER_TESS_EVAL)
|
|
||||||
nir_shader_gather_xfb_info(nir);
|
|
||||||
|
|
||||||
if (nir->info.stage != MESA_SHADER_VERTEX)
|
if (nir->info.stage != MESA_SHADER_VERTEX)
|
||||||
nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs, nir->info.stage);
|
nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs, nir->info.stage);
|
||||||
else {
|
else {
|
||||||
|
@ -1105,6 +1061,8 @@ lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
|
||||||
nir->info.stage);
|
nir->info.stage);
|
||||||
|
|
||||||
pipeline->pipeline_nir[stage] = nir;
|
pipeline->pipeline_nir[stage] = nir;
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1146,28 +1104,6 @@ merge_tess_info(struct shader_info *tes_info,
|
||||||
tes_info->tess.point_mode |= tcs_info->tess.point_mode;
|
tes_info->tess.point_mode |= tcs_info->tess.point_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gl_shader_stage
|
|
||||||
lvp_shader_stage(VkShaderStageFlagBits stage)
|
|
||||||
{
|
|
||||||
switch (stage) {
|
|
||||||
case VK_SHADER_STAGE_VERTEX_BIT:
|
|
||||||
return MESA_SHADER_VERTEX;
|
|
||||||
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
|
|
||||||
return MESA_SHADER_TESS_CTRL;
|
|
||||||
case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
|
|
||||||
return MESA_SHADER_TESS_EVAL;
|
|
||||||
case VK_SHADER_STAGE_GEOMETRY_BIT:
|
|
||||||
return MESA_SHADER_GEOMETRY;
|
|
||||||
case VK_SHADER_STAGE_FRAGMENT_BIT:
|
|
||||||
return MESA_SHADER_FRAGMENT;
|
|
||||||
case VK_SHADER_STAGE_COMPUTE_BIT:
|
|
||||||
return MESA_SHADER_COMPUTE;
|
|
||||||
default:
|
|
||||||
unreachable("invalid VkShaderStageFlagBits");
|
|
||||||
return MESA_SHADER_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lvp_pipeline_xfb_init(struct lvp_pipeline *pipeline)
|
lvp_pipeline_xfb_init(struct lvp_pipeline *pipeline)
|
||||||
{
|
{
|
||||||
|
@ -1343,6 +1279,8 @@ lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline,
|
||||||
struct lvp_pipeline_cache *cache,
|
struct lvp_pipeline_cache *cache,
|
||||||
const VkGraphicsPipelineCreateInfo *pCreateInfo)
|
const VkGraphicsPipelineCreateInfo *pCreateInfo)
|
||||||
{
|
{
|
||||||
|
VkResult result;
|
||||||
|
|
||||||
const VkGraphicsPipelineLibraryCreateInfoEXT *libinfo = vk_find_struct_const(pCreateInfo,
|
const VkGraphicsPipelineLibraryCreateInfoEXT *libinfo = vk_find_struct_const(pCreateInfo,
|
||||||
GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT);
|
GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT);
|
||||||
const VkPipelineLibraryCreateInfoKHR *libstate = vk_find_struct_const(pCreateInfo,
|
const VkPipelineLibraryCreateInfoKHR *libstate = vk_find_struct_const(pCreateInfo,
|
||||||
|
@ -1413,9 +1351,8 @@ lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline,
|
||||||
pipeline->device = device;
|
pipeline->device = device;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
|
for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
|
||||||
VK_FROM_HANDLE(vk_shader_module, module,
|
const VkPipelineShaderStageCreateInfo *sinfo = &pCreateInfo->pStages[i];
|
||||||
pCreateInfo->pStages[i].module);
|
gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
|
||||||
gl_shader_stage stage = lvp_shader_stage(pCreateInfo->pStages[i].stage);
|
|
||||||
if (stage == MESA_SHADER_FRAGMENT) {
|
if (stage == MESA_SHADER_FRAGMENT) {
|
||||||
if (!(pipeline->stages & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT))
|
if (!(pipeline->stages & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1423,21 +1360,9 @@ lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline,
|
||||||
if (!(pipeline->stages & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT))
|
if (!(pipeline->stages & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (module) {
|
result = lvp_shader_compile_to_ir(pipeline, sinfo);
|
||||||
lvp_shader_compile_to_ir(pipeline, module->size, module->data,
|
if (result != VK_SUCCESS)
|
||||||
pCreateInfo->pStages[i].pName,
|
goto fail;
|
||||||
stage,
|
|
||||||
pCreateInfo->pStages[i].pSpecializationInfo);
|
|
||||||
} else {
|
|
||||||
const VkShaderModuleCreateInfo *info = vk_find_struct_const(pCreateInfo->pStages[i].pNext, SHADER_MODULE_CREATE_INFO);
|
|
||||||
assert(info);
|
|
||||||
lvp_shader_compile_to_ir(pipeline, info->codeSize, info->pCode,
|
|
||||||
pCreateInfo->pStages[i].pName,
|
|
||||||
stage,
|
|
||||||
pCreateInfo->pStages[i].pSpecializationInfo);
|
|
||||||
}
|
|
||||||
if (!pipeline->pipeline_nir[stage])
|
|
||||||
return VK_ERROR_FEATURE_NOT_PRESENT;
|
|
||||||
|
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case MESA_SHADER_GEOMETRY:
|
case MESA_SHADER_GEOMETRY:
|
||||||
|
@ -1520,7 +1445,9 @@ lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline,
|
||||||
if (!pipeline->library) {
|
if (!pipeline->library) {
|
||||||
bool has_fragment_shader = false;
|
bool has_fragment_shader = false;
|
||||||
for (uint32_t i = 0; i < pipeline->graphics_create_info.stageCount; i++) {
|
for (uint32_t i = 0; i < pipeline->graphics_create_info.stageCount; i++) {
|
||||||
gl_shader_stage stage = lvp_shader_stage(pipeline->graphics_create_info.pStages[i].stage);
|
const VkPipelineShaderStageCreateInfo *sinfo =
|
||||||
|
&pipeline->graphics_create_info.pStages[i];
|
||||||
|
gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
|
||||||
lvp_pipeline_compile(pipeline, stage);
|
lvp_pipeline_compile(pipeline, stage);
|
||||||
if (stage == MESA_SHADER_FRAGMENT)
|
if (stage == MESA_SHADER_FRAGMENT)
|
||||||
has_fragment_shader = true;
|
has_fragment_shader = true;
|
||||||
|
@ -1539,6 +1466,14 @@ lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
for (unsigned i = 0; i < ARRAY_SIZE(pipeline->pipeline_nir); i++) {
|
||||||
|
if (pipeline->pipeline_nir[i])
|
||||||
|
ralloc_free(pipeline->pipeline_nir[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkResult
|
static VkResult
|
||||||
|
@ -1630,23 +1565,10 @@ lvp_compute_pipeline_init(struct lvp_pipeline *pipeline,
|
||||||
&pipeline->compute_create_info, pCreateInfo);
|
&pipeline->compute_create_info, pCreateInfo);
|
||||||
pipeline->is_compute_pipeline = true;
|
pipeline->is_compute_pipeline = true;
|
||||||
|
|
||||||
if (pCreateInfo->stage.module) {
|
VkResult result = lvp_shader_compile_to_ir(pipeline, &pCreateInfo->stage);
|
||||||
VK_FROM_HANDLE(vk_shader_module, module,
|
if (result != VK_SUCCESS)
|
||||||
pCreateInfo->stage.module);
|
return result;
|
||||||
lvp_shader_compile_to_ir(pipeline, module->size, module->data,
|
|
||||||
pCreateInfo->stage.pName,
|
|
||||||
MESA_SHADER_COMPUTE,
|
|
||||||
pCreateInfo->stage.pSpecializationInfo);
|
|
||||||
} else {
|
|
||||||
const VkShaderModuleCreateInfo *info = vk_find_struct_const(pCreateInfo->stage.pNext, SHADER_MODULE_CREATE_INFO);
|
|
||||||
assert(info);
|
|
||||||
lvp_shader_compile_to_ir(pipeline, info->codeSize, info->pCode,
|
|
||||||
pCreateInfo->stage.pName,
|
|
||||||
MESA_SHADER_COMPUTE,
|
|
||||||
pCreateInfo->stage.pSpecializationInfo);
|
|
||||||
}
|
|
||||||
if (!pipeline->pipeline_nir[MESA_SHADER_COMPUTE])
|
|
||||||
return VK_ERROR_FEATURE_NOT_PRESENT;
|
|
||||||
lvp_pipeline_compile(pipeline, MESA_SHADER_COMPUTE);
|
lvp_pipeline_compile(pipeline, MESA_SHADER_COMPUTE);
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue