mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 22:30:12 +01:00
vulkan: Add generic graphics and compute VkPipeline implementations
These implementations are built on top of vk_shader. For the most part, the driver shouldn't notice a difference between draws consuming pipelines vs. draws consuming shaders. The only real difference is that, when vk_driver_shader_ops::compile() is called for pipelines, a struct vk_graphics_pipeline_state is provided. For shader objects, the state object will be NULL indicating that all state is unknown. Besides that, all the rest of the differences between Vulkan 1.0 pipelines, VK_EXT_graphics_pipeline_library, and VK_EXT_shader_object are handled by the Vulkan runtime code. Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27024>
This commit is contained in:
parent
c488dc9f50
commit
9308e8d90d
6 changed files with 1830 additions and 2 deletions
|
|
@ -185,6 +185,14 @@ struct vk_command_buffer {
|
|||
struct vk_attachment_state _attachments[8];
|
||||
|
||||
VkRenderPassSampleLocationsBeginInfoEXT *pass_sample_locations;
|
||||
|
||||
/**
|
||||
* Bitmask of shader stages bound via a vk_pipeline since the last call to
|
||||
* vkBindShadersEXT().
|
||||
*
|
||||
* Used by the common vk_pipeline implementation
|
||||
*/
|
||||
VkShaderStageFlags pipeline_shader_stages;
|
||||
};
|
||||
|
||||
VK_DEFINE_HANDLE_CASTS(vk_command_buffer, base, VkCommandBuffer,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@
|
|||
#ifndef VK_LIMITS_H
|
||||
#define VK_LIMITS_H
|
||||
|
||||
/* Maximun number of shader stages in a single graphics pipeline */
|
||||
#define MESA_VK_MAX_GRAPHICS_PIPELINE_STAGES 5
|
||||
|
||||
#define MESA_VK_MAX_DESCRIPTOR_SETS 32
|
||||
|
||||
/* From the Vulkan 1.3.274 spec:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -199,6 +199,10 @@ void vk_pipeline_free(struct vk_device *device,
|
|||
const VkAllocationCallbacks *alloc,
|
||||
struct vk_pipeline *pipeline);
|
||||
|
||||
void
|
||||
vk_cmd_unbind_pipelines_for_stages(struct vk_command_buffer *cmd_buffer,
|
||||
VkShaderStageFlags stages);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -369,7 +369,10 @@ vk_common_GetShaderBinaryDataEXT(VkDevice _device,
|
|||
return result;
|
||||
}
|
||||
|
||||
#define VK_MAX_LINKED_SHADER_STAGES 5
|
||||
/* The only place where we have "real" linking is graphics shaders and there
|
||||
* is a limit as to how many of them can be linked together at one time.
|
||||
*/
|
||||
#define VK_MAX_LINKED_SHADER_STAGES MESA_VK_MAX_GRAPHICS_PIPELINE_STAGES
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
vk_common_CreateShadersEXT(VkDevice _device,
|
||||
|
|
@ -552,10 +555,16 @@ vk_common_CmdBindShadersEXT(VkCommandBuffer commandBuffer,
|
|||
STACK_ARRAY(gl_shader_stage, stages, stageCount);
|
||||
STACK_ARRAY(struct vk_shader *, shaders, stageCount);
|
||||
|
||||
VkShaderStageFlags vk_stages = 0;
|
||||
for (uint32_t i = 0; i < stageCount; i++) {
|
||||
vk_stages |= pStages[i];
|
||||
stages[i] = vk_to_mesa_shader_stage(pStages[i]);
|
||||
shaders[i] = pShaders != NULL ? vk_shader_from_handle(pShaders[i]) : NULL;
|
||||
}
|
||||
|
||||
vk_cmd_unbind_pipelines_for_stages(cmd_buffer, vk_stages);
|
||||
if (vk_stages & ~VK_SHADER_STAGE_COMPUTE_BIT)
|
||||
vk_cmd_set_rp_attachments(cmd_buffer, ~0);
|
||||
|
||||
ops->cmd_bind_shaders(cmd_buffer, stageCount, stages, shaders);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#include "vk_limits.h"
|
||||
#include "vk_pipeline_cache.h"
|
||||
|
||||
#include "util/mesa-blake3.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
@ -45,6 +47,8 @@ struct vk_pipeline_robustness_state;
|
|||
|
||||
int vk_shader_cmp_graphics_stages(gl_shader_stage a, gl_shader_stage b);
|
||||
|
||||
#define VK_SHADER_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_MESA 0x1000
|
||||
|
||||
struct vk_shader_compile_info {
|
||||
gl_shader_stage stage;
|
||||
VkShaderCreateFlagsEXT flags;
|
||||
|
|
@ -62,12 +66,30 @@ struct vk_shader_compile_info {
|
|||
|
||||
struct vk_shader_ops;
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic error "-Wpadded"
|
||||
#endif
|
||||
struct vk_shader_pipeline_cache_key {
|
||||
gl_shader_stage stage;
|
||||
blake3_hash blake3;
|
||||
};
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
struct vk_shader {
|
||||
struct vk_object_base base;
|
||||
|
||||
const struct vk_shader_ops *ops;
|
||||
|
||||
gl_shader_stage stage;
|
||||
|
||||
/* Used for the generic VkPipeline implementation */
|
||||
struct {
|
||||
struct vk_pipeline_cache_object cache_obj;
|
||||
struct vk_shader_pipeline_cache_key cache_key;
|
||||
} pipeline;
|
||||
};
|
||||
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(vk_shader, base, VkShaderEXT,
|
||||
|
|
@ -90,6 +112,39 @@ struct vk_shader_ops {
|
|||
bool (*serialize)(struct vk_device *device,
|
||||
const struct vk_shader *shader,
|
||||
struct blob *blob);
|
||||
|
||||
/** Returns executable properties for this shader
|
||||
*
|
||||
* This is equivalent to vkGetPipelineExecutableProperties(), only for a
|
||||
* single vk_shader.
|
||||
*/
|
||||
VkResult (*get_executable_properties)(struct vk_device *device,
|
||||
const struct vk_shader *shader,
|
||||
uint32_t *executable_count,
|
||||
VkPipelineExecutablePropertiesKHR *properties);
|
||||
|
||||
/** Returns executable statistics for this shader
|
||||
*
|
||||
* This is equivalent to vkGetPipelineExecutableStatistics(), only for a
|
||||
* single vk_shader.
|
||||
*/
|
||||
VkResult (*get_executable_statistics)(struct vk_device *device,
|
||||
const struct vk_shader *shader,
|
||||
uint32_t executable_index,
|
||||
uint32_t *statistic_count,
|
||||
VkPipelineExecutableStatisticKHR *statistics);
|
||||
|
||||
/** Returns executable internal representations for this shader
|
||||
*
|
||||
* This is equivalent to vkGetPipelineExecutableInternalRepresentations(),
|
||||
* only for a single vk_shader.
|
||||
*/
|
||||
VkResult (*get_executable_internal_representations)(
|
||||
struct vk_device *device,
|
||||
const struct vk_shader *shader,
|
||||
uint32_t executable_index,
|
||||
uint32_t *internal_representation_count,
|
||||
VkPipelineExecutableInternalRepresentationKHR *internal_representations);
|
||||
};
|
||||
|
||||
void *vk_shader_zalloc(struct vk_device *device,
|
||||
|
|
@ -143,6 +198,23 @@ struct vk_device_shader_ops {
|
|||
*/
|
||||
void (*preprocess_nir)(struct vk_physical_device *device, nir_shader *nir);
|
||||
|
||||
/** True if the driver wants geometry stages linked
|
||||
*
|
||||
* If set to true, geometry stages will always be compiled with
|
||||
* VK_SHADER_CREATE_LINK_STAGE_BIT_EXT when pipelines are used.
|
||||
*/
|
||||
bool link_geom_stages;
|
||||
|
||||
/** Hash a vk_graphics_state object
|
||||
*
|
||||
* This callback hashes whatever bits of vk_graphics_pipeline_state might
|
||||
* be used to compile a shader in one of the given stages.
|
||||
*/
|
||||
void (*hash_graphics_state)(struct vk_physical_device *device,
|
||||
const struct vk_graphics_pipeline_state *state,
|
||||
VkShaderStageFlags stages,
|
||||
blake3_hash blake3_out);
|
||||
|
||||
/** Compile (and potentially link) a set of shaders
|
||||
*
|
||||
* Unlike vkCreateShadersEXT, this callback will only ever be called with
|
||||
|
|
@ -175,6 +247,10 @@ struct vk_device_shader_ops {
|
|||
uint32_t stage_count,
|
||||
const gl_shader_stage *stages,
|
||||
struct vk_shader ** const shaders);
|
||||
|
||||
/** Sets dynamic state */
|
||||
void (*cmd_set_dynamic_graphics_state)(struct vk_command_buffer *cmd_buffer,
|
||||
const struct vk_dynamic_graphics_state *state);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue