// SPDX-License-Identifier: GPL-2.0 OR MIT /************************************************************************** * * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ #include <drm/ttm/ttm_placement.h> #include "vmwgfx_binding.h" #include "vmwgfx_bo.h" #include "vmwgfx_drv.h" #include "vmwgfx_resource_priv.h" struct vmw_shader { … }; struct vmw_user_shader { … }; struct vmw_dx_shader { … }; static void vmw_user_shader_free(struct vmw_resource *res); static struct vmw_resource * vmw_user_shader_base_to_res(struct ttm_base_object *base); static int vmw_gb_shader_create(struct vmw_resource *res); static int vmw_gb_shader_bind(struct vmw_resource *res, struct ttm_validate_buffer *val_buf); static int vmw_gb_shader_unbind(struct vmw_resource *res, bool readback, struct ttm_validate_buffer *val_buf); static int vmw_gb_shader_destroy(struct vmw_resource *res); static int vmw_dx_shader_create(struct vmw_resource *res); static int vmw_dx_shader_bind(struct vmw_resource *res, struct ttm_validate_buffer *val_buf); static int vmw_dx_shader_unbind(struct vmw_resource *res, bool readback, struct ttm_validate_buffer *val_buf); static void vmw_dx_shader_commit_notify(struct vmw_resource *res, enum vmw_cmdbuf_res_state state); static bool vmw_shader_id_ok(u32 user_key, SVGA3dShaderType shader_type); static u32 vmw_shader_key(u32 user_key, SVGA3dShaderType shader_type); static const struct vmw_user_resource_conv user_shader_conv = …; const struct vmw_user_resource_conv *user_shader_converter = …; static const struct vmw_res_func vmw_gb_shader_func = …; static const struct vmw_res_func vmw_dx_shader_func = …; /* * Shader management: */ static inline struct vmw_shader * vmw_res_to_shader(struct vmw_resource *res) { … } /** * vmw_res_to_dx_shader - typecast a struct vmw_resource to a * struct vmw_dx_shader * * @res: Pointer to the struct vmw_resource. */ static inline struct vmw_dx_shader * vmw_res_to_dx_shader(struct vmw_resource *res) { … } static void vmw_hw_shader_destroy(struct vmw_resource *res) { … } static int vmw_gb_shader_init(struct vmw_private *dev_priv, struct vmw_resource *res, uint32_t size, uint64_t offset, SVGA3dShaderType type, uint8_t num_input_sig, uint8_t num_output_sig, struct vmw_bo *byte_code, void (*res_free) (struct vmw_resource *res)) { … } /* * GB shader code: */ static int vmw_gb_shader_create(struct vmw_resource *res) { … } static int vmw_gb_shader_bind(struct vmw_resource *res, struct ttm_validate_buffer *val_buf) { … } static int vmw_gb_shader_unbind(struct vmw_resource *res, bool readback, struct ttm_validate_buffer *val_buf) { … } static int vmw_gb_shader_destroy(struct vmw_resource *res) { … } /* * DX shader code: */ /** * vmw_dx_shader_commit_notify - Notify that a shader operation has been * committed to hardware from a user-supplied command stream. * * @res: Pointer to the shader resource. * @state: Indicating whether a creation or removal has been committed. * */ static void vmw_dx_shader_commit_notify(struct vmw_resource *res, enum vmw_cmdbuf_res_state state) { … } /** * vmw_dx_shader_unscrub - Have the device reattach a MOB to a DX shader. * * @res: The shader resource * * This function reverts a scrub operation. */ static int vmw_dx_shader_unscrub(struct vmw_resource *res) { … } /** * vmw_dx_shader_create - The DX shader create callback * * @res: The DX shader resource * * The create callback is called as part of resource validation and * makes sure that we unscrub the shader if it's previously been scrubbed. */ static int vmw_dx_shader_create(struct vmw_resource *res) { … } /** * vmw_dx_shader_bind - The DX shader bind callback * * @res: The DX shader resource * @val_buf: Pointer to the validate buffer. * */ static int vmw_dx_shader_bind(struct vmw_resource *res, struct ttm_validate_buffer *val_buf) { … } /** * vmw_dx_shader_scrub - Have the device unbind a MOB from a DX shader. * * @res: The shader resource * * This function unbinds a MOB from the DX shader without requiring the * MOB dma_buffer to be reserved. The driver still considers the MOB bound. * However, once the driver eventually decides to unbind the MOB, it doesn't * need to access the context. */ static int vmw_dx_shader_scrub(struct vmw_resource *res) { … } /** * vmw_dx_shader_unbind - The dx shader unbind callback. * * @res: The shader resource * @readback: Whether this is a readback unbind. Currently unused. * @val_buf: MOB buffer information. */ static int vmw_dx_shader_unbind(struct vmw_resource *res, bool readback, struct ttm_validate_buffer *val_buf) { … } /** * vmw_dx_shader_cotable_list_scrub - The cotable unbind_func callback for * DX shaders. * * @dev_priv: Pointer to device private structure. * @list: The list of cotable resources. * @readback: Whether the call was part of a readback unbind. * * Scrubs all shader MOBs so that any subsequent shader unbind or shader * destroy operation won't need to swap in the context. */ void vmw_dx_shader_cotable_list_scrub(struct vmw_private *dev_priv, struct list_head *list, bool readback) { … } /** * vmw_dx_shader_res_free - The DX shader free callback * * @res: The shader resource * * Frees the DX shader resource. */ static void vmw_dx_shader_res_free(struct vmw_resource *res) { … } /** * vmw_dx_shader_add - Add a shader resource as a command buffer managed * resource. * * @man: The command buffer resource manager. * @ctx: Pointer to the context resource. * @user_key: The id used for this shader. * @shader_type: The shader type. * @list: The list of staged command buffer managed resources. */ int vmw_dx_shader_add(struct vmw_cmdbuf_res_manager *man, struct vmw_resource *ctx, u32 user_key, SVGA3dShaderType shader_type, struct list_head *list) { … } /* * User-space shader management: */ static struct vmw_resource * vmw_user_shader_base_to_res(struct ttm_base_object *base) { … } static void vmw_user_shader_free(struct vmw_resource *res) { … } static void vmw_shader_free(struct vmw_resource *res) { … } /* * This function is called when user space has no more references on the * base object. It releases the base-object's reference on the resource object. */ static void vmw_user_shader_base_release(struct ttm_base_object **p_base) { … } int vmw_shader_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { … } static int vmw_user_shader_alloc(struct vmw_private *dev_priv, struct vmw_bo *buffer, size_t shader_size, size_t offset, SVGA3dShaderType shader_type, uint8_t num_input_sig, uint8_t num_output_sig, struct ttm_object_file *tfile, u32 *handle) { … } static struct vmw_resource *vmw_shader_alloc(struct vmw_private *dev_priv, struct vmw_bo *buffer, size_t shader_size, size_t offset, SVGA3dShaderType shader_type) { … } static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv, enum drm_vmw_shader_type shader_type_drm, u32 buffer_handle, size_t size, size_t offset, uint8_t num_input_sig, uint8_t num_output_sig, uint32_t *shader_handle) { … } /** * vmw_shader_id_ok - Check whether a compat shader user key and * shader type are within valid bounds. * * @user_key: User space id of the shader. * @shader_type: Shader type. * * Returns true if valid false if not. */ static bool vmw_shader_id_ok(u32 user_key, SVGA3dShaderType shader_type) { … } /** * vmw_shader_key - Compute a hash key suitable for a compat shader. * * @user_key: User space id of the shader. * @shader_type: Shader type. * * Returns a hash key suitable for a command buffer managed resource * manager hash table. */ static u32 vmw_shader_key(u32 user_key, SVGA3dShaderType shader_type) { … } /** * vmw_shader_remove - Stage a compat shader for removal. * * @man: Pointer to the compat shader manager identifying the shader namespace. * @user_key: The key that is used to identify the shader. The key is * unique to the shader type. * @shader_type: Shader type. * @list: Caller's list of staged command buffer resource actions. */ int vmw_shader_remove(struct vmw_cmdbuf_res_manager *man, u32 user_key, SVGA3dShaderType shader_type, struct list_head *list) { … } /** * vmw_compat_shader_add - Create a compat shader and stage it for addition * as a command buffer managed resource. * * @dev_priv: Pointer to device private structure. * @man: Pointer to the compat shader manager identifying the shader namespace. * @user_key: The key that is used to identify the shader. The key is * unique to the shader type. * @bytecode: Pointer to the bytecode of the shader. * @shader_type: Shader type. * @size: Command size. * @list: Caller's list of staged command buffer resource actions. * */ int vmw_compat_shader_add(struct vmw_private *dev_priv, struct vmw_cmdbuf_res_manager *man, u32 user_key, const void *bytecode, SVGA3dShaderType shader_type, size_t size, struct list_head *list) { … } /** * vmw_shader_lookup - Look up a compat shader * * @man: Pointer to the command buffer managed resource manager identifying * the shader namespace. * @user_key: The user space id of the shader. * @shader_type: The shader type. * * Returns a refcounted pointer to a struct vmw_resource if the shader was * found. An error pointer otherwise. */ struct vmw_resource * vmw_shader_lookup(struct vmw_cmdbuf_res_manager *man, u32 user_key, SVGA3dShaderType shader_type) { … } int vmw_shader_define_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { … }