mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 20:00:11 +01:00
vulkan/meta: Insert a geometry shader when needed
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
parent
af3400a957
commit
74e8be6545
4 changed files with 98 additions and 16 deletions
|
|
@ -276,24 +276,46 @@ create_rect_list_pipeline(struct vk_device *device,
|
|||
|
||||
VkGraphicsPipelineCreateInfo info_local = *info;
|
||||
|
||||
STACK_ARRAY(VkPipelineShaderStageCreateInfo, stages, info->stageCount + 1);
|
||||
for (uint32_t i = 0; i < info->stageCount; i++) {
|
||||
assert(info->pStages[i].stage != VK_SHADER_STAGE_VERTEX_BIT);
|
||||
stages[i + 1] = info->pStages[i];
|
||||
}
|
||||
/* We always configure for layered rendering for now */
|
||||
bool use_gs = meta->use_gs_for_layer;
|
||||
|
||||
STACK_ARRAY(VkPipelineShaderStageCreateInfo, stages,
|
||||
info->stageCount + 1 + use_gs);
|
||||
uint32_t stage_count = 0;
|
||||
|
||||
VkPipelineShaderStageNirCreateInfoMESA vs_nir_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_NIR_CREATE_INFO_MESA,
|
||||
.nir = vk_meta_draw_rects_vs_nir(meta),
|
||||
.nir = vk_meta_draw_rects_vs_nir(meta, use_gs),
|
||||
};
|
||||
stages[0] = (VkPipelineShaderStageCreateInfo) {
|
||||
stages[stage_count++] = (VkPipelineShaderStageCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.pNext = &vs_nir_info,
|
||||
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.pName = "main",
|
||||
};
|
||||
|
||||
info_local.stageCount = info->stageCount + 1;
|
||||
VkPipelineShaderStageNirCreateInfoMESA gs_nir_info;
|
||||
if (use_gs) {
|
||||
gs_nir_info = (VkPipelineShaderStageNirCreateInfoMESA) {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_NIR_CREATE_INFO_MESA,
|
||||
.nir = vk_meta_draw_rects_gs_nir(meta),
|
||||
};
|
||||
stages[stage_count++] = (VkPipelineShaderStageCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.pNext = &gs_nir_info,
|
||||
.stage = VK_SHADER_STAGE_GEOMETRY_BIT,
|
||||
.pName = "main",
|
||||
};
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < info->stageCount; i++) {
|
||||
assert(info->pStages[i].stage != VK_SHADER_STAGE_VERTEX_BIT);
|
||||
if (use_gs)
|
||||
assert(info->pStages[i].stage != VK_SHADER_STAGE_GEOMETRY_BIT);
|
||||
stages[stage_count++] = info->pStages[i];
|
||||
}
|
||||
|
||||
info_local.stageCount = stage_count;
|
||||
info_local.pStages = stages;
|
||||
info_local.pVertexInputState = &vk_meta_draw_rects_vi_state;
|
||||
info_local.pViewportState = &vk_meta_draw_rects_vs_state;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ struct vk_meta_device {
|
|||
|
||||
uint32_t max_bind_map_buffer_size_B;
|
||||
bool use_layered_rendering;
|
||||
bool use_gs_for_layer;
|
||||
bool use_stencil_export;
|
||||
|
||||
VkResult (*cmd_bind_map_buffer)(struct vk_command_buffer *cmd,
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ const VkPipelineViewportStateCreateInfo vk_meta_draw_rects_vs_state = {
|
|||
};
|
||||
|
||||
nir_shader *
|
||||
vk_meta_draw_rects_vs_nir(struct vk_meta_device *device)
|
||||
vk_meta_draw_rects_vs_nir(struct vk_meta_device *device, bool use_gs)
|
||||
{
|
||||
nir_builder build = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, NULL,
|
||||
"vk-meta-draw-rects-vs");
|
||||
|
|
@ -69,13 +69,15 @@ vk_meta_draw_rects_vs_nir(struct vk_meta_device *device)
|
|||
glsl_uvec4_type(), "vtx_in");
|
||||
in->data.location = VERT_ATTRIB_GENERIC0;
|
||||
|
||||
nir_variable *pos = nir_variable_create(b->shader, nir_var_shader_out,
|
||||
glsl_vec4_type(), "gl_Position");
|
||||
pos->data.location = VARYING_SLOT_POS;
|
||||
nir_variable *pos =
|
||||
nir_variable_create(b->shader, nir_var_shader_out, glsl_vec4_type(),
|
||||
use_gs ? "pos_out" : "gl_Position");
|
||||
pos->data.location = use_gs ? VARYING_SLOT_VAR0 : VARYING_SLOT_POS;
|
||||
|
||||
nir_variable *layer = nir_variable_create(b->shader, nir_var_shader_out,
|
||||
glsl_int_type(), "gl_Layer");
|
||||
layer->data.location = VARYING_SLOT_LAYER;
|
||||
nir_variable *layer =
|
||||
nir_variable_create(b->shader, nir_var_shader_out, glsl_int_type(),
|
||||
use_gs ? "layer_out" : "gl_Layer");
|
||||
layer->data.location = use_gs ? VARYING_SLOT_VAR1 : VARYING_SLOT_LAYER;
|
||||
|
||||
nir_ssa_def *vtx = nir_load_var(b, in);
|
||||
nir_store_var(b, pos, nir_vec4(b, nir_channel(b, vtx, 0),
|
||||
|
|
@ -83,6 +85,7 @@ vk_meta_draw_rects_vs_nir(struct vk_meta_device *device)
|
|||
nir_channel(b, vtx, 2),
|
||||
nir_imm_float(b, 1)),
|
||||
0xf);
|
||||
|
||||
nir_store_var(b, layer, nir_iadd(b, nir_load_instance_id(b),
|
||||
nir_channel(b, vtx, 3)),
|
||||
0x1);
|
||||
|
|
@ -90,6 +93,58 @@ vk_meta_draw_rects_vs_nir(struct vk_meta_device *device)
|
|||
return b->shader;
|
||||
}
|
||||
|
||||
nir_shader *
|
||||
vk_meta_draw_rects_gs_nir(struct vk_meta_device *device)
|
||||
{
|
||||
nir_builder build =
|
||||
nir_builder_init_simple_shader(MESA_SHADER_GEOMETRY, NULL,
|
||||
"vk-meta-draw-rects-gs");
|
||||
nir_builder *b = &build;
|
||||
|
||||
nir_variable *pos_in =
|
||||
nir_variable_create(b->shader, nir_var_shader_in,
|
||||
glsl_array_type(glsl_vec4_type(), 3, 0), "pos_in");
|
||||
pos_in->data.location = VARYING_SLOT_VAR0;
|
||||
|
||||
nir_variable *layer_in =
|
||||
nir_variable_create(b->shader, nir_var_shader_in,
|
||||
glsl_array_type(glsl_int_type(), 3, 0), "layer_in");
|
||||
layer_in->data.location = VARYING_SLOT_VAR1;
|
||||
|
||||
nir_variable *pos_out =
|
||||
nir_variable_create(b->shader, nir_var_shader_out,
|
||||
glsl_vec4_type(), "gl_Position");
|
||||
pos_out->data.location = VARYING_SLOT_POS;
|
||||
|
||||
nir_variable *layer_out =
|
||||
nir_variable_create(b->shader, nir_var_shader_out,
|
||||
glsl_int_type(), "gl_Layer");
|
||||
layer_out->data.location = VARYING_SLOT_LAYER;
|
||||
|
||||
for (unsigned i = 0; i < 3; i++) {
|
||||
nir_deref_instr *pos_in_deref =
|
||||
nir_build_deref_array_imm(b, nir_build_deref_var(b, pos_in), i);
|
||||
nir_deref_instr *layer_in_deref =
|
||||
nir_build_deref_array_imm(b, nir_build_deref_var(b, layer_in), i);
|
||||
|
||||
nir_store_var(b, pos_out, nir_load_deref(b, pos_in_deref), 0xf);
|
||||
nir_store_var(b, layer_out, nir_load_deref(b, layer_in_deref), 1);
|
||||
nir_emit_vertex(b);
|
||||
}
|
||||
|
||||
nir_end_primitive(b);
|
||||
|
||||
struct shader_info *info = &build.shader->info;
|
||||
info->gs.input_primitive = MESA_PRIM_TRIANGLES;
|
||||
info->gs.output_primitive = MESA_PRIM_TRIANGLE_STRIP;
|
||||
info->gs.vertices_in = 3;
|
||||
info->gs.vertices_out = 3;
|
||||
info->gs.invocations = 1;
|
||||
info->gs.active_stream_mask = 1;
|
||||
|
||||
return b->shader;
|
||||
}
|
||||
|
||||
struct vertex {
|
||||
float x, y, z;
|
||||
uint32_t layer;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,11 @@ extern const VkPipelineVertexInputStateCreateInfo vk_meta_draw_rects_vi_state;
|
|||
extern const VkPipelineInputAssemblyStateCreateInfo vk_meta_draw_rects_ia_state;
|
||||
extern const VkPipelineViewportStateCreateInfo vk_meta_draw_rects_vs_state;
|
||||
|
||||
struct nir_shader *vk_meta_draw_rects_vs_nir(struct vk_meta_device *device);
|
||||
struct nir_shader *
|
||||
vk_meta_draw_rects_vs_nir(struct vk_meta_device *device, bool use_gs);
|
||||
|
||||
struct nir_shader *
|
||||
vk_meta_draw_rects_gs_nir(struct vk_meta_device *device);
|
||||
|
||||
static inline void
|
||||
vk_meta_rendering_info_copy(struct vk_meta_rendering_info *dst,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue