mesa,glsl: add mesh shader subrotine handling

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36751>
This commit is contained in:
Qiang Yu 2025-02-11 11:27:47 +08:00 committed by Marge Bot
parent 7ba64547ae
commit 9acaa409b9
4 changed files with 79 additions and 3 deletions

View file

@ -841,6 +841,8 @@ write_program_resource_data(struct blob *metadata,
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
case GL_UNIFORM:
if (((gl_uniform_storage *)res->Data)->builtin ||
res->Type != GL_UNIFORM) {
@ -888,6 +890,8 @@ write_program_resource_data(struct blob *metadata,
case GL_GEOMETRY_SUBROUTINE:
case GL_FRAGMENT_SUBROUTINE:
case GL_COMPUTE_SUBROUTINE:
case GL_TASK_SUBROUTINE_EXT:
case GL_MESH_SUBROUTINE_EXT:
sh =
prog->_LinkedShaders[_mesa_shader_stage_from_subroutine(res->Type)];
write_shader_subroutine_index(metadata, sh, res);
@ -938,6 +942,8 @@ read_program_resource_data(struct blob_reader *metadata,
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
case GL_UNIFORM: {
enum uniform_type type = (enum uniform_type) blob_read_uint32(metadata);
if (type == uniform_not_remapped) {
@ -964,6 +970,8 @@ read_program_resource_data(struct blob_reader *metadata,
case GL_GEOMETRY_SUBROUTINE:
case GL_FRAGMENT_SUBROUTINE:
case GL_COMPUTE_SUBROUTINE:
case GL_TASK_SUBROUTINE_EXT:
case GL_MESH_SUBROUTINE_EXT:
sh =
prog->_LinkedShaders[_mesa_shader_stage_from_subroutine(res->Type)];
res->Data =

View file

@ -61,6 +61,11 @@ supported_interface_enum(struct gl_context *ctx, GLenum iface)
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
return _mesa_has_tessellation(ctx) && _mesa_has_ARB_shader_subroutine(ctx);
case GL_TASK_SUBROUTINE_EXT:
case GL_MESH_SUBROUTINE_EXT:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
return _mesa_has_EXT_mesh_shader(ctx);
default:
return false;
}
@ -188,6 +193,10 @@ _mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface,
case GL_FRAGMENT_SUBROUTINE:
case GL_VERTEX_SUBROUTINE_UNIFORM:
case GL_FRAGMENT_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_EXT:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
case GL_PROGRAM_INPUT:
case GL_PROGRAM_OUTPUT:
case GL_UNIFORM:
@ -319,6 +328,11 @@ _mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface,
if (!_mesa_has_tessellation(ctx) || !_mesa_has_ARB_shader_subroutine(ctx))
goto fail;
break;
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
if (!_mesa_has_EXT_mesh_shader(ctx))
goto fail;
break;
default:
goto fail;
}

View file

@ -478,6 +478,8 @@ _mesa_program_resource_name(struct gl_program_resource *res)
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
return RESOURCE_UNI(res)->name.string + MESA_SUBROUTINE_PREFIX_LEN;
case GL_VERTEX_SUBROUTINE:
case GL_GEOMETRY_SUBROUTINE:
@ -485,6 +487,8 @@ _mesa_program_resource_name(struct gl_program_resource *res)
case GL_COMPUTE_SUBROUTINE:
case GL_TESS_CONTROL_SUBROUTINE:
case GL_TESS_EVALUATION_SUBROUTINE:
case GL_TASK_SUBROUTINE_EXT:
case GL_MESH_SUBROUTINE_EXT:
return RESOURCE_SUB(res)->name.string;
default:
break;
@ -513,6 +517,8 @@ _mesa_program_resource_name_length(struct gl_program_resource *res)
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
return RESOURCE_UNI(res)->name.length - MESA_SUBROUTINE_PREFIX_LEN;
case GL_VERTEX_SUBROUTINE:
case GL_GEOMETRY_SUBROUTINE:
@ -520,6 +526,8 @@ _mesa_program_resource_name_length(struct gl_program_resource *res)
case GL_COMPUTE_SUBROUTINE:
case GL_TESS_CONTROL_SUBROUTINE:
case GL_TESS_EVALUATION_SUBROUTINE:
case GL_TASK_SUBROUTINE_EXT:
case GL_MESH_SUBROUTINE_EXT:
return RESOURCE_SUB(res)->name.length;
default:
break;
@ -553,6 +561,8 @@ _mesa_program_get_resource_name(struct gl_program_resource *res,
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
*out = RESOURCE_UNI(res)->name;
out->string += MESA_SUBROUTINE_PREFIX_LEN;
out->length -= MESA_SUBROUTINE_PREFIX_LEN;
@ -564,6 +574,8 @@ _mesa_program_get_resource_name(struct gl_program_resource *res,
case GL_COMPUTE_SUBROUTINE:
case GL_TESS_CONTROL_SUBROUTINE:
case GL_TESS_EVALUATION_SUBROUTINE:
case GL_TASK_SUBROUTINE_EXT:
case GL_MESH_SUBROUTINE_EXT:
*out = RESOURCE_SUB(res)->name;
return out->string != NULL;
default:
@ -588,6 +600,8 @@ _mesa_program_resource_array_size(struct gl_program_resource *res)
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
return RESOURCE_UNI(res)->array_elements;
case GL_BUFFER_VARIABLE:
/* Unsized arrays */
@ -602,6 +616,8 @@ _mesa_program_resource_array_size(struct gl_program_resource *res)
case GL_COMPUTE_SUBROUTINE:
case GL_TESS_CONTROL_SUBROUTINE:
case GL_TESS_EVALUATION_SUBROUTINE:
case GL_TASK_SUBROUTINE_EXT:
case GL_MESH_SUBROUTINE_EXT:
case GL_ATOMIC_COUNTER_BUFFER:
case GL_UNIFORM_BLOCK:
case GL_SHADER_STORAGE_BLOCK:
@ -758,12 +774,16 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg,
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
case GL_VERTEX_SUBROUTINE:
case GL_GEOMETRY_SUBROUTINE:
case GL_FRAGMENT_SUBROUTINE:
case GL_COMPUTE_SUBROUTINE:
case GL_TESS_CONTROL_SUBROUTINE:
case GL_TESS_EVALUATION_SUBROUTINE:
case GL_TASK_SUBROUTINE_EXT:
case GL_MESH_SUBROUTINE_EXT:
if (name[rname.length] == '.') {
return res;
}
@ -932,6 +952,8 @@ _mesa_program_resource_index(struct gl_shader_program *shProg,
case GL_COMPUTE_SUBROUTINE:
case GL_TESS_CONTROL_SUBROUTINE:
case GL_TESS_EVALUATION_SUBROUTINE:
case GL_TASK_SUBROUTINE_EXT:
case GL_MESH_SUBROUTINE_EXT:
return RESOURCE_SUB(res)->index;
case GL_UNIFORM_BLOCK:
case GL_SHADER_STORAGE_BLOCK:
@ -989,12 +1011,16 @@ _mesa_program_resource_find_index(struct gl_shader_program *shProg,
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
case GL_VERTEX_SUBROUTINE:
case GL_GEOMETRY_SUBROUTINE:
case GL_FRAGMENT_SUBROUTINE:
case GL_COMPUTE_SUBROUTINE:
case GL_TESS_CONTROL_SUBROUTINE:
case GL_TESS_EVALUATION_SUBROUTINE:
case GL_TASK_SUBROUTINE_EXT:
case GL_MESH_SUBROUTINE_EXT:
case GL_BUFFER_VARIABLE:
if (++idx == (int) index)
return res;
@ -1167,6 +1193,8 @@ program_resource_location(struct gl_program_resource *res, unsigned array_index)
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
/* If the uniform is an array, fail if the index is out of bounds. */
if (array_index > 0
&& array_index >= RESOURCE_UNI(res)->array_elements) {
@ -1496,6 +1524,8 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
/* Test if a buffer variable is an array or an unsized array.
* Unsized arrays return zero as array size.
@ -1592,6 +1622,8 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
case GL_PROGRAM_INPUT:
case GL_PROGRAM_OUTPUT:
*val = program_resource_location(res, 0);
@ -1625,7 +1657,9 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
res->Type != GL_GEOMETRY_SUBROUTINE_UNIFORM &&
res->Type != GL_COMPUTE_SUBROUTINE_UNIFORM &&
res->Type != GL_TESS_CONTROL_SUBROUTINE_UNIFORM &&
res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM)
res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM &&
res->Type != GL_TASK_SUBROUTINE_UNIFORM_EXT &&
res->Type != GL_MESH_SUBROUTINE_UNIFORM_EXT)
goto invalid_operation;
*val = RESOURCE_UNI(res)->num_compatible_subroutines;
return 1;
@ -1640,7 +1674,9 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
res->Type != GL_GEOMETRY_SUBROUTINE_UNIFORM &&
res->Type != GL_COMPUTE_SUBROUTINE_UNIFORM &&
res->Type != GL_TESS_CONTROL_SUBROUTINE_UNIFORM &&
res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM)
res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM &&
res->Type != GL_TASK_SUBROUTINE_UNIFORM_EXT &&
res->Type != GL_MESH_SUBROUTINE_UNIFORM_EXT)
goto invalid_operation;
uni = RESOURCE_UNI(res);
@ -1855,7 +1891,9 @@ _mesa_get_program_interfaceiv(struct gl_shader_program *shProg,
case GL_GEOMETRY_SUBROUTINE_UNIFORM:
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: {
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
case GL_MESH_SUBROUTINE_UNIFORM_EXT: {
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type == programInterface) {
struct gl_uniform_storage *uni =

View file

@ -181,6 +181,10 @@ _mesa_shader_stage_from_subroutine_uniform(GLenum subuniform)
return MESA_SHADER_TESS_CTRL;
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
return MESA_SHADER_TESS_EVAL;
case GL_TASK_SUBROUTINE_UNIFORM_EXT:
return MESA_SHADER_TASK;
case GL_MESH_SUBROUTINE_UNIFORM_EXT:
return MESA_SHADER_MESH;
}
UNREACHABLE("not reached");
}
@ -201,6 +205,10 @@ _mesa_shader_stage_from_subroutine(GLenum subroutine)
return MESA_SHADER_TESS_CTRL;
case GL_TESS_EVALUATION_SUBROUTINE:
return MESA_SHADER_TESS_EVAL;
case GL_TASK_SUBROUTINE_EXT:
return MESA_SHADER_TASK;
case GL_MESH_SUBROUTINE_EXT:
return MESA_SHADER_MESH;
default:
UNREACHABLE("not reached");
}
@ -222,6 +230,10 @@ _mesa_shader_stage_to_subroutine(mesa_shader_stage stage)
return GL_TESS_CONTROL_SUBROUTINE;
case MESA_SHADER_TESS_EVAL:
return GL_TESS_EVALUATION_SUBROUTINE;
case MESA_SHADER_TASK:
return GL_TASK_SUBROUTINE_EXT;
case MESA_SHADER_MESH:
return GL_MESH_SUBROUTINE_EXT;
default:
UNREACHABLE("not reached");
}
@ -243,6 +255,10 @@ _mesa_shader_stage_to_subroutine_uniform(mesa_shader_stage stage)
return GL_TESS_CONTROL_SUBROUTINE_UNIFORM;
case MESA_SHADER_TESS_EVAL:
return GL_TESS_EVALUATION_SUBROUTINE_UNIFORM;
case MESA_SHADER_TASK:
return GL_TASK_SUBROUTINE_UNIFORM_EXT;
case MESA_SHADER_MESH:
return GL_MESH_SUBROUTINE_UNIFORM_EXT;
default:
UNREACHABLE("not reached");
}