Rev 5078 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5078 | Rev 6296 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /************************************************************************** |
1 | /************************************************************************** |
2 | * |
2 | * |
3 | * Copyright © 2009-2012 VMware, Inc., Palo Alto, CA., USA |
3 | * Copyright © 2009-2015 VMware, Inc., Palo Alto, CA., USA |
4 | * All Rights Reserved. |
4 | * All Rights Reserved. |
5 | * |
5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
7 | * copy of this software and associated documentation files (the |
7 | * copy of this software and associated documentation files (the |
8 | * "Software"), to deal in the Software without restriction, including |
8 | * "Software"), to deal in the Software without restriction, including |
Line 25... | Line 25... | ||
25 | * |
25 | * |
26 | **************************************************************************/ |
26 | **************************************************************************/ |
Line 27... | Line 27... | ||
27 | 27 | ||
28 | #include "vmwgfx_drv.h" |
28 | #include "vmwgfx_drv.h" |
- | 29 | #include "vmwgfx_resource_priv.h" |
|
29 | #include "vmwgfx_resource_priv.h" |
30 | #include "vmwgfx_binding.h" |
Line 30... | Line 31... | ||
30 | #include "ttm/ttm_placement.h" |
31 | #include "ttm/ttm_placement.h" |
Line 31... | Line 32... | ||
31 | 32 | ||
32 | #define VMW_COMPAT_SHADER_HT_ORDER 12 |
33 | #define VMW_COMPAT_SHADER_HT_ORDER 12 |
33 | 34 | ||
34 | #if 0 |
35 | #if 0 |
35 | struct vmw_shader { |
36 | struct vmw_shader { |
- | 37 | struct vmw_resource res; |
|
- | 38 | SVGA3dShaderType type; |
|
36 | struct vmw_resource res; |
39 | uint32_t size; |
Line 37... | Line 40... | ||
37 | SVGA3dShaderType type; |
40 | uint8_t num_input_sig; |
38 | uint32_t size; |
41 | uint8_t num_output_sig; |
39 | }; |
42 | }; |
40 | 43 | ||
Line 41... | Line -... | ||
41 | struct vmw_user_shader { |
- | |
42 | struct ttm_base_object base; |
- | |
43 | struct vmw_shader shader; |
- | |
44 | }; |
44 | struct vmw_user_shader { |
45 | - | ||
46 | /** |
- | |
47 | * enum vmw_compat_shader_state - Staging state for compat shaders |
- | |
48 | */ |
- | |
49 | enum vmw_compat_shader_state { |
- | |
50 | VMW_COMPAT_COMMITED, |
- | |
51 | VMW_COMPAT_ADD, |
45 | struct ttm_base_object base; |
52 | VMW_COMPAT_DEL |
- | |
53 | }; |
- | |
54 | - | ||
55 | /** |
- | |
56 | * struct vmw_compat_shader - Metadata for compat shaders. |
- | |
57 | * |
- | |
58 | * @handle: The TTM handle of the guest backed shader. |
46 | struct vmw_shader shader; |
59 | * @tfile: The struct ttm_object_file the guest backed shader is registered |
- | |
60 | * with. |
- | |
61 | * @hash: Hash item for lookup. |
- | |
62 | * @head: List head for staging lists or the compat shader manager list. |
47 | }; |
63 | * @state: Staging state. |
48 | |
64 | * |
- | |
65 | * The structure is protected by the cmdbuf lock. |
49 | struct vmw_dx_shader { |
66 | */ |
50 | struct vmw_resource res; |
67 | struct vmw_compat_shader { |
- | |
68 | u32 handle; |
51 | struct vmw_resource *ctx; |
Line 69... | Line -... | ||
69 | struct ttm_object_file *tfile; |
- | |
70 | struct drm_hash_item hash; |
- | |
71 | struct list_head head; |
- | |
72 | enum vmw_compat_shader_state state; |
- | |
73 | }; |
- | |
74 | - | ||
75 | /** |
- | |
76 | * struct vmw_compat_shader_manager - Compat shader manager. |
- | |
77 | * |
- | |
78 | * @shaders: Hash table containing staged and commited compat shaders |
52 | struct vmw_resource *cotable; |
79 | * @list: List of commited shaders. |
53 | u32 id; |
80 | * @dev_priv: Pointer to a device private structure. |
- | |
81 | * |
54 | bool committed; |
82 | * @shaders and @list are protected by the cmdbuf mutex for now. |
- | |
Line 83... | Line 55... | ||
83 | */ |
55 | struct list_head cotable_head; |
84 | struct vmw_compat_shader_manager { |
56 | }; |
85 | struct drm_open_hash shaders; |
57 | |
Line 97... | Line 69... | ||
97 | static int vmw_gb_shader_unbind(struct vmw_resource *res, |
69 | static int vmw_gb_shader_unbind(struct vmw_resource *res, |
98 | bool readback, |
70 | bool readback, |
99 | struct ttm_validate_buffer *val_buf); |
71 | struct ttm_validate_buffer *val_buf); |
100 | static int vmw_gb_shader_destroy(struct vmw_resource *res); |
72 | static int vmw_gb_shader_destroy(struct vmw_resource *res); |
Line -... | Line 73... | ||
- | 73 | ||
- | 74 | static int vmw_dx_shader_create(struct vmw_resource *res); |
|
- | 75 | static int vmw_dx_shader_bind(struct vmw_resource *res, |
|
- | 76 | struct ttm_validate_buffer *val_buf); |
|
- | 77 | static int vmw_dx_shader_unbind(struct vmw_resource *res, |
|
- | 78 | bool readback, |
|
- | 79 | struct ttm_validate_buffer *val_buf); |
|
- | 80 | static void vmw_dx_shader_commit_notify(struct vmw_resource *res, |
|
- | 81 | enum vmw_cmdbuf_res_state state); |
|
- | 82 | static bool vmw_shader_id_ok(u32 user_key, SVGA3dShaderType shader_type); |
|
- | 83 | static u32 vmw_shader_key(u32 user_key, SVGA3dShaderType shader_type); |
|
- | 84 | static uint64_t vmw_user_shader_size; |
|
101 | 85 | ||
102 | static const struct vmw_user_resource_conv user_shader_conv = { |
86 | static const struct vmw_user_resource_conv user_shader_conv = { |
103 | .object_type = VMW_RES_SHADER, |
87 | .object_type = VMW_RES_SHADER, |
104 | .base_obj_to_res = vmw_user_shader_base_to_res, |
88 | .base_obj_to_res = vmw_user_shader_base_to_res, |
105 | .res_free = vmw_user_shader_free |
89 | .res_free = vmw_user_shader_free |
Line 119... | Line 103... | ||
119 | .destroy = vmw_gb_shader_destroy, |
103 | .destroy = vmw_gb_shader_destroy, |
120 | .bind = vmw_gb_shader_bind, |
104 | .bind = vmw_gb_shader_bind, |
121 | .unbind = vmw_gb_shader_unbind |
105 | .unbind = vmw_gb_shader_unbind |
122 | }; |
106 | }; |
Line -... | Line 107... | ||
- | 107 | ||
- | 108 | static const struct vmw_res_func vmw_dx_shader_func = { |
|
- | 109 | .res_type = vmw_res_shader, |
|
- | 110 | .needs_backup = true, |
|
- | 111 | .may_evict = false, |
|
- | 112 | .type_name = "dx shaders", |
|
- | 113 | .backup_placement = &vmw_mob_placement, |
|
- | 114 | .create = vmw_dx_shader_create, |
|
- | 115 | /* |
|
- | 116 | * The destroy callback is only called with a committed resource on |
|
- | 117 | * context destroy, in which case we destroy the cotable anyway, |
|
- | 118 | * so there's no need to destroy DX shaders separately. |
|
- | 119 | */ |
|
- | 120 | .destroy = NULL, |
|
- | 121 | .bind = vmw_dx_shader_bind, |
|
- | 122 | .unbind = vmw_dx_shader_unbind, |
|
- | 123 | .commit_notify = vmw_dx_shader_commit_notify, |
|
- | 124 | }; |
|
123 | 125 | ||
124 | /** |
126 | /** |
125 | * Shader management: |
127 | * Shader management: |
Line 126... | Line 128... | ||
126 | */ |
128 | */ |
127 | 129 | ||
128 | static inline struct vmw_shader * |
130 | static inline struct vmw_shader * |
129 | vmw_res_to_shader(struct vmw_resource *res) |
131 | vmw_res_to_shader(struct vmw_resource *res) |
130 | { |
132 | { |
Line -... | Line 133... | ||
- | 133 | return container_of(res, struct vmw_shader, res); |
|
- | 134 | } |
|
- | 135 | ||
- | 136 | /** |
|
- | 137 | * vmw_res_to_dx_shader - typecast a struct vmw_resource to a |
|
- | 138 | * struct vmw_dx_shader |
|
- | 139 | * |
|
- | 140 | * @res: Pointer to the struct vmw_resource. |
|
- | 141 | */ |
|
- | 142 | static inline struct vmw_dx_shader * |
|
- | 143 | vmw_res_to_dx_shader(struct vmw_resource *res) |
|
- | 144 | { |
|
131 | return container_of(res, struct vmw_shader, res); |
145 | return container_of(res, struct vmw_dx_shader, res); |
132 | } |
146 | } |
- | 147 | ||
133 | 148 | static void vmw_hw_shader_destroy(struct vmw_resource *res) |
|
- | 149 | { |
|
- | 150 | if (likely(res->func->destroy)) |
|
134 | static void vmw_hw_shader_destroy(struct vmw_resource *res) |
151 | (void) res->func->destroy(res); |
Line -... | Line 152... | ||
- | 152 | else |
|
135 | { |
153 | res->id = -1; |
136 | (void) vmw_gb_shader_destroy(res); |
154 | } |
137 | } |
155 | |
138 | 156 | ||
139 | static int vmw_gb_shader_init(struct vmw_private *dev_priv, |
157 | static int vmw_gb_shader_init(struct vmw_private *dev_priv, |
- | 158 | struct vmw_resource *res, |
|
- | 159 | uint32_t size, |
|
140 | struct vmw_resource *res, |
160 | uint64_t offset, |
141 | uint32_t size, |
161 | SVGA3dShaderType type, |
142 | uint64_t offset, |
162 | uint8_t num_input_sig, |
143 | SVGA3dShaderType type, |
163 | uint8_t num_output_sig, |
144 | struct vmw_dma_buffer *byte_code, |
164 | struct vmw_dma_buffer *byte_code, |
Line 145... | Line 165... | ||
145 | void (*res_free) (struct vmw_resource *res)) |
165 | void (*res_free) (struct vmw_resource *res)) |
146 | { |
166 | { |
147 | struct vmw_shader *shader = vmw_res_to_shader(res); |
- | |
Line 148... | Line 167... | ||
148 | int ret; |
167 | struct vmw_shader *shader = vmw_res_to_shader(res); |
149 | 168 | int ret; |
|
150 | ret = vmw_resource_init(dev_priv, res, true, |
169 | |
151 | res_free, &vmw_gb_shader_func); |
170 | ret = vmw_resource_init(dev_priv, res, true, res_free, |
Line 164... | Line 183... | ||
164 | res->backup = vmw_dmabuf_reference(byte_code); |
183 | res->backup = vmw_dmabuf_reference(byte_code); |
165 | res->backup_offset = offset; |
184 | res->backup_offset = offset; |
166 | } |
185 | } |
167 | shader->size = size; |
186 | shader->size = size; |
168 | shader->type = type; |
187 | shader->type = type; |
- | 188 | shader->num_input_sig = num_input_sig; |
|
- | 189 | shader->num_output_sig = num_output_sig; |
|
Line 169... | Line 190... | ||
169 | 190 | ||
170 | vmw_resource_activate(res, vmw_hw_shader_destroy); |
191 | vmw_resource_activate(res, vmw_hw_shader_destroy); |
171 | return 0; |
192 | return 0; |
Line -... | Line 193... | ||
- | 193 | } |
|
- | 194 | ||
- | 195 | /* |
|
- | 196 | * GB shader code: |
|
172 | } |
197 | */ |
173 | 198 | ||
174 | static int vmw_gb_shader_create(struct vmw_resource *res) |
199 | static int vmw_gb_shader_create(struct vmw_resource *res) |
175 | { |
200 | { |
176 | struct vmw_private *dev_priv = res->dev_priv; |
201 | struct vmw_private *dev_priv = res->dev_priv; |
Line 207... | Line 232... | ||
207 | cmd->header.size = sizeof(cmd->body); |
232 | cmd->header.size = sizeof(cmd->body); |
208 | cmd->body.shid = res->id; |
233 | cmd->body.shid = res->id; |
209 | cmd->body.type = shader->type; |
234 | cmd->body.type = shader->type; |
210 | cmd->body.sizeInBytes = shader->size; |
235 | cmd->body.sizeInBytes = shader->size; |
211 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
236 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
212 | (void) vmw_3d_resource_inc(dev_priv, false); |
237 | vmw_fifo_resource_inc(dev_priv); |
Line 213... | Line 238... | ||
213 | 238 | ||
Line 214... | Line 239... | ||
214 | return 0; |
239 | return 0; |
215 | 240 | ||
Line 240... | Line 265... | ||
240 | 265 | ||
241 | cmd->header.id = SVGA_3D_CMD_BIND_GB_SHADER; |
266 | cmd->header.id = SVGA_3D_CMD_BIND_GB_SHADER; |
242 | cmd->header.size = sizeof(cmd->body); |
267 | cmd->header.size = sizeof(cmd->body); |
243 | cmd->body.shid = res->id; |
268 | cmd->body.shid = res->id; |
244 | cmd->body.mobid = bo->mem.start; |
269 | cmd->body.mobid = bo->mem.start; |
245 | cmd->body.offsetInBytes = 0; |
270 | cmd->body.offsetInBytes = res->backup_offset; |
246 | res->backup_dirty = false; |
271 | res->backup_dirty = false; |
Line 247... | Line 272... | ||
247 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
272 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
248 | 273 | ||
Line 301... | Line 326... | ||
301 | 326 | ||
302 | if (likely(res->id == -1)) |
327 | if (likely(res->id == -1)) |
Line 303... | Line 328... | ||
303 | return 0; |
328 | return 0; |
304 | 329 | ||
Line 305... | Line 330... | ||
305 | mutex_lock(&dev_priv->binding_mutex); |
330 | mutex_lock(&dev_priv->binding_mutex); |
306 | vmw_context_binding_res_list_scrub(&res->binding_head); |
331 | vmw_binding_res_list_scrub(&res->binding_head); |
307 | 332 | ||
308 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); |
333 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); |
Line 317... | Line 342... | ||
317 | cmd->header.size = sizeof(cmd->body); |
342 | cmd->header.size = sizeof(cmd->body); |
318 | cmd->body.shid = res->id; |
343 | cmd->body.shid = res->id; |
319 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
344 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
320 | mutex_unlock(&dev_priv->binding_mutex); |
345 | mutex_unlock(&dev_priv->binding_mutex); |
321 | vmw_resource_release_id(res); |
346 | vmw_resource_release_id(res); |
322 | vmw_3d_resource_dec(dev_priv, false); |
347 | vmw_fifo_resource_dec(dev_priv); |
Line 323... | Line 348... | ||
323 | 348 | ||
324 | return 0; |
349 | return 0; |
Line 325... | Line 350... | ||
325 | } |
350 | } |
Line 373... | Line 398... | ||
373 | static int vmw_user_shader_alloc(struct vmw_private *dev_priv, |
398 | static int vmw_user_shader_alloc(struct vmw_private *dev_priv, |
374 | struct vmw_dma_buffer *buffer, |
399 | struct vmw_dma_buffer *buffer, |
375 | size_t shader_size, |
400 | size_t shader_size, |
376 | size_t offset, |
401 | size_t offset, |
377 | SVGA3dShaderType shader_type, |
402 | SVGA3dShaderType shader_type, |
- | 403 | uint8_t num_input_sig, |
|
- | 404 | uint8_t num_output_sig, |
|
378 | struct ttm_object_file *tfile, |
405 | struct ttm_object_file *tfile, |
379 | u32 *handle) |
406 | u32 *handle) |
380 | { |
407 | { |
381 | struct vmw_user_shader *ushader; |
408 | struct vmw_user_shader *ushader; |
382 | struct vmw_resource *res, *tmp; |
409 | struct vmw_resource *res, *tmp; |
Line 415... | Line 442... | ||
415 | /* |
442 | /* |
416 | * From here on, the destructor takes over resource freeing. |
443 | * From here on, the destructor takes over resource freeing. |
417 | */ |
444 | */ |
Line 418... | Line 445... | ||
418 | 445 | ||
419 | ret = vmw_gb_shader_init(dev_priv, res, shader_size, |
446 | ret = vmw_gb_shader_init(dev_priv, res, shader_size, |
- | 447 | offset, shader_type, num_input_sig, |
|
420 | offset, shader_type, buffer, |
448 | num_output_sig, buffer, |
421 | vmw_user_shader_free); |
449 | vmw_user_shader_free); |
422 | if (unlikely(ret != 0)) |
450 | if (unlikely(ret != 0)) |
Line 423... | Line 451... | ||
423 | goto out; |
451 | goto out; |
Line 439... | Line 467... | ||
439 | out: |
467 | out: |
440 | return ret; |
468 | return ret; |
441 | } |
469 | } |
Line -... | Line 470... | ||
- | 470 | ||
- | 471 | ||
- | 472 | static struct vmw_resource *vmw_shader_alloc(struct vmw_private *dev_priv, |
|
- | 473 | struct vmw_dma_buffer *buffer, |
|
- | 474 | size_t shader_size, |
|
- | 475 | size_t offset, |
|
- | 476 | SVGA3dShaderType shader_type) |
|
- | 477 | { |
|
- | 478 | struct vmw_shader *shader; |
|
- | 479 | struct vmw_resource *res; |
|
- | 480 | int ret; |
|
- | 481 | ||
- | 482 | /* |
|
- | 483 | * Approximate idr memory usage with 128 bytes. It will be limited |
|
- | 484 | * by maximum number_of shaders anyway. |
|
- | 485 | */ |
|
- | 486 | if (unlikely(vmw_shader_size == 0)) |
|
- | 487 | vmw_shader_size = |
|
- | 488 | ttm_round_pot(sizeof(struct vmw_shader)) + 128; |
|
- | 489 | ||
- | 490 | ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), |
|
- | 491 | vmw_shader_size, |
|
- | 492 | false, true); |
|
- | 493 | if (unlikely(ret != 0)) { |
|
- | 494 | if (ret != -ERESTARTSYS) |
|
- | 495 | DRM_ERROR("Out of graphics memory for shader " |
|
- | 496 | "creation.\n"); |
|
- | 497 | goto out_err; |
|
- | 498 | } |
|
- | 499 | ||
- | 500 | shader = kzalloc(sizeof(*shader), GFP_KERNEL); |
|
- | 501 | if (unlikely(shader == NULL)) { |
|
- | 502 | ttm_mem_global_free(vmw_mem_glob(dev_priv), |
|
- | 503 | vmw_shader_size); |
|
- | 504 | ret = -ENOMEM; |
|
- | 505 | goto out_err; |
|
- | 506 | } |
|
- | 507 | ||
- | 508 | res = &shader->res; |
|
- | 509 | ||
- | 510 | /* |
|
- | 511 | * From here on, the destructor takes over resource freeing. |
|
- | 512 | */ |
|
- | 513 | ret = vmw_gb_shader_init(dev_priv, res, shader_size, |
|
- | 514 | offset, shader_type, 0, 0, buffer, |
|
- | 515 | vmw_shader_free); |
|
- | 516 | ||
- | 517 | out_err: |
|
- | 518 | return ret ? ERR_PTR(ret) : res; |
|
- | 519 | } |
|
442 | 520 | ||
- | 521 | ||
- | 522 | static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv, |
|
- | 523 | enum drm_vmw_shader_type shader_type_drm, |
|
443 | 524 | u32 buffer_handle, size_t size, size_t offset, |
|
444 | int vmw_shader_define_ioctl(struct drm_device *dev, void *data, |
525 | uint8_t num_input_sig, uint8_t num_output_sig, |
445 | struct drm_file *file_priv) |
526 | uint32_t *shader_handle) |
446 | { |
- | |
447 | struct vmw_private *dev_priv = vmw_priv(dev); |
- | |
448 | struct drm_vmw_shader_create_arg *arg = |
527 | { |
449 | (struct drm_vmw_shader_create_arg *)data; |
528 | struct vmw_private *dev_priv = vmw_priv(dev); |
450 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; |
529 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; |
451 | struct vmw_dma_buffer *buffer = NULL; |
530 | struct vmw_dma_buffer *buffer = NULL; |
Line 452... | Line 531... | ||
452 | SVGA3dShaderType shader_type; |
531 | SVGA3dShaderType shader_type; |
453 | int ret; |
532 | int ret; |
454 | 533 | ||
455 | if (arg->buffer_handle != SVGA3D_INVALID_ID) { |
534 | if (buffer_handle != SVGA3D_INVALID_ID) { |
456 | ret = vmw_user_dmabuf_lookup(tfile, arg->buffer_handle, |
535 | ret = vmw_user_dmabuf_lookup(tfile, buffer_handle, |
457 | &buffer); |
536 | &buffer, NULL); |
458 | if (unlikely(ret != 0)) { |
537 | if (unlikely(ret != 0)) { |
459 | DRM_ERROR("Could not find buffer for shader " |
538 | DRM_ERROR("Could not find buffer for shader " |
Line 460... | Line 539... | ||
460 | "creation.\n"); |
539 | "creation.\n"); |
461 | return ret; |
540 | return ret; |
462 | } |
541 | } |
463 | 542 | ||
464 | if ((u64)buffer->base.num_pages * PAGE_SIZE < |
543 | if ((u64)buffer->base.num_pages * PAGE_SIZE < |
465 | (u64)arg->size + (u64)arg->offset) { |
544 | (u64)size + (u64)offset) { |
466 | DRM_ERROR("Illegal buffer- or shader size.\n"); |
545 | DRM_ERROR("Illegal buffer- or shader size.\n"); |
Line 467... | Line 546... | ||
467 | ret = -EINVAL; |
546 | ret = -EINVAL; |
468 | goto out_bad_arg; |
547 | goto out_bad_arg; |
469 | } |
548 | } |
470 | } |
549 | } |
471 | 550 | ||
472 | switch (arg->shader_type) { |
551 | switch (shader_type_drm) { |
473 | case drm_vmw_shader_type_vs: |
552 | case drm_vmw_shader_type_vs: |
474 | shader_type = SVGA3D_SHADERTYPE_VS; |
- | |
475 | break; |
- | |
476 | case drm_vmw_shader_type_ps: |
- | |
477 | shader_type = SVGA3D_SHADERTYPE_PS; |
553 | shader_type = SVGA3D_SHADERTYPE_VS; |
478 | break; |
554 | break; |
479 | case drm_vmw_shader_type_gs: |
555 | case drm_vmw_shader_type_ps: |
480 | shader_type = SVGA3D_SHADERTYPE_GS; |
556 | shader_type = SVGA3D_SHADERTYPE_PS; |
481 | break; |
557 | break; |
Line 482... | Line 558... | ||
482 | default: |
558 | default: |
483 | DRM_ERROR("Illegal shader type.\n"); |
559 | DRM_ERROR("Illegal shader type.\n"); |
484 | ret = -EINVAL; |
560 | ret = -EINVAL; |
Line 485... | Line 561... | ||
485 | goto out_bad_arg; |
561 | goto out_bad_arg; |
- | 562 | } |
|
486 | } |
563 | |
Line 487... | Line 564... | ||
487 | 564 | ret = ttm_read_lock(&dev_priv->reservation_sem, true); |
|
488 | ret = ttm_read_lock(&dev_priv->reservation_sem, true); |
565 | if (unlikely(ret != 0)) |
489 | if (unlikely(ret != 0)) |
566 | goto out_bad_arg; |
490 | goto out_bad_arg; |
567 | |
491 | 568 | ret = vmw_user_shader_alloc(dev_priv, buffer, size, offset, |
|
Line 492... | Line 569... | ||
492 | ret = vmw_user_shader_alloc(dev_priv, buffer, arg->size, arg->offset, |
569 | shader_type, num_input_sig, |
493 | shader_type, tfile, &arg->shader_handle); |
570 | num_output_sig, tfile, shader_handle); |
494 | 571 | ||
495 | ttm_read_unlock(&dev_priv->reservation_sem); |
572 | ttm_read_unlock(&dev_priv->reservation_sem); |
496 | out_bad_arg: |
573 | out_bad_arg: |
497 | vmw_dmabuf_unreference(&buffer); |
574 | vmw_dmabuf_unreference(&buffer); |
498 | return ret; |
575 | return ret; |
499 | } |
576 | } |
500 | 577 | ||
501 | /** |
578 | /** |
502 | * vmw_compat_shader_id_ok - Check whether a compat shader user key and |
579 | * vmw_shader_id_ok - Check whether a compat shader user key and |
503 | * shader type are within valid bounds. |
580 | * shader type are within valid bounds. |
504 | * |
581 | * |
Line 505... | Line 582... | ||
505 | * @user_key: User space id of the shader. |
582 | * @user_key: User space id of the shader. |
506 | * @shader_type: Shader type. |
583 | * @shader_type: Shader type. |
507 | * |
584 | * |
508 | * Returns true if valid false if not. |
585 | * Returns true if valid false if not. |
509 | */ |
586 | */ |
510 | static bool vmw_compat_shader_id_ok(u32 user_key, SVGA3dShaderType shader_type) |
587 | static bool vmw_shader_id_ok(u32 user_key, SVGA3dShaderType shader_type) |
511 | { |
588 | { |
512 | return user_key <= ((1 << 20) - 1) && (unsigned) shader_type < 16; |
589 | return user_key <= ((1 << 20) - 1) && (unsigned) shader_type < 16; |
513 | } |
590 | } |
514 | 591 | ||
515 | /** |
592 | /** |
516 | * vmw_compat_shader_key - Compute a hash key suitable for a compat shader. |
593 | * vmw_shader_key - Compute a hash key suitable for a compat shader. |
517 | * |
594 | * |
Line 518... | Line 595... | ||
518 | * @user_key: User space id of the shader. |
595 | * @user_key: User space id of the shader. |
519 | * @shader_type: Shader type. |
596 | * @shader_type: Shader type. |
520 | * |
597 | * |
521 | * Returns a hash key suitable for a command buffer managed resource |
598 | * Returns a hash key suitable for a command buffer managed resource |
522 | * manager hash table. |
599 | * manager hash table. |
523 | */ |
600 | */ |
524 | static u32 vmw_compat_shader_key(u32 user_key, SVGA3dShaderType shader_type) |
601 | static u32 vmw_shader_key(u32 user_key, SVGA3dShaderType shader_type) |
525 | { |
602 | { |
526 | return user_key | (shader_type << 20); |
603 | return user_key | (shader_type << 20); |
527 | } |
604 | } |
528 | 605 | ||
529 | /** |
606 | /** |
530 | * vmw_compat_shader_remove - Stage a compat shader for removal. |
607 | * vmw_shader_remove - Stage a compat shader for removal. |
- | 608 | * |
|
- | 609 | * @man: Pointer to the compat shader manager identifying the shader namespace. |
|
531 | * |
610 | * @user_key: The key that is used to identify the shader. The key is |
532 | * @man: Pointer to the compat shader manager identifying the shader namespace. |
611 | * unique to the shader type. |
Line 533... | Line 612... | ||
533 | * @user_key: The key that is used to identify the shader. The key is |
612 | * @shader_type: Shader type. |
534 | * unique to the shader type. |
613 | * @list: Caller's list of staged command buffer resource actions. |
535 | * @shader_type: Shader type. |
- | |
536 | * @list: Caller's list of staged command buffer resource actions. |
614 | */ |
537 | */ |
615 | int vmw_shader_remove(struct vmw_cmdbuf_res_manager *man, |
Line 538... | Line 616... | ||
538 | int vmw_compat_shader_remove(struct vmw_cmdbuf_res_manager *man, |
616 | u32 user_key, SVGA3dShaderType shader_type, |
539 | u32 user_key, SVGA3dShaderType shader_type, |
617 | struct list_head *list) |
540 | struct list_head *list) |
618 | { |
Line 573... | Line 651... | ||
573 | struct ttm_bo_kmap_obj map; |
651 | struct ttm_bo_kmap_obj map; |
574 | bool is_iomem; |
652 | bool is_iomem; |
575 | int ret; |
653 | int ret; |
576 | struct vmw_resource *res; |
654 | struct vmw_resource *res; |
Line 577... | Line 655... | ||
577 | 655 | ||
578 | if (!vmw_compat_shader_id_ok(user_key, shader_type)) |
656 | if (!vmw_shader_id_ok(user_key, shader_type)) |
Line 579... | Line 657... | ||
579 | return -EINVAL; |
657 | return -EINVAL; |
580 | 658 | ||
581 | /* Allocate and pin a DMA buffer */ |
659 | /* Allocate and pin a DMA buffer */ |
Line 610... | Line 688... | ||
610 | 688 | ||
611 | res = vmw_shader_alloc(dev_priv, buf, size, 0, shader_type); |
689 | res = vmw_shader_alloc(dev_priv, buf, size, 0, shader_type); |
612 | if (unlikely(ret != 0)) |
690 | if (unlikely(ret != 0)) |
Line 613... | Line 691... | ||
613 | goto no_reserve; |
691 | goto no_reserve; |
614 | 692 | ||
615 | ret = vmw_cmdbuf_res_add(man, vmw_cmdbuf_res_compat_shader, |
693 | ret = vmw_cmdbuf_res_add(man, vmw_cmdbuf_res_shader, |
616 | vmw_compat_shader_key(user_key, shader_type), |
694 | vmw_shader_key(user_key, shader_type), |
617 | res, list); |
695 | res, list); |
618 | vmw_resource_unreference(&res); |
696 | vmw_resource_unreference(&res); |
619 | no_reserve: |
697 | no_reserve: |
620 | vmw_dmabuf_unreference(&buf); |
698 | vmw_dmabuf_unreference(&buf); |
621 | out: |
699 | out: |
Line 622... | Line 700... | ||
622 | return ret; |
700 | return ret; |
623 | } |
701 | } |
624 | 702 | ||
625 | /** |
703 | /** |
626 | * vmw_compat_shader_lookup - Look up a compat shader |
704 | * vmw_shader_lookup - Look up a compat shader |
627 | * |
705 | * |
628 | * @man: Pointer to the command buffer managed resource manager identifying |
706 | * @man: Pointer to the command buffer managed resource manager identifying |
629 | * the shader namespace. |
707 | * the shader namespace. |
630 | * @user_key: The user space id of the shader. |
708 | * @user_key: The user space id of the shader. |
631 | * @shader_type: The shader type. |
709 | * @shader_type: The shader type. |
632 | * |
710 | * |
633 | * Returns a refcounted pointer to a struct vmw_resource if the shader was |
711 | * Returns a refcounted pointer to a struct vmw_resource if the shader was |
634 | * found. An error pointer otherwise. |
712 | * found. An error pointer otherwise. |
635 | */ |
713 | */ |
636 | struct vmw_resource * |
714 | struct vmw_resource * |
637 | vmw_compat_shader_lookup(struct vmw_cmdbuf_res_manager *man, |
715 | vmw_shader_lookup(struct vmw_cmdbuf_res_manager *man, |
638 | u32 user_key, |
716 | u32 user_key, |
639 | SVGA3dShaderType shader_type) |
717 | SVGA3dShaderType shader_type) |
Line 640... | Line 718... | ||
640 | { |
718 | { |
641 | if (!vmw_compat_shader_id_ok(user_key, shader_type)) |
719 | if (!vmw_shader_id_ok(user_key, shader_type)) |
- | 720 | return ERR_PTR(-EINVAL); |
|
- | 721 | ||
- | 722 | return vmw_cmdbuf_res_lookup(man, vmw_cmdbuf_res_shader, |
|
- | 723 | vmw_shader_key(user_key, shader_type)); |
|
- | 724 | } |
|
- | 725 | ||
- | 726 | int vmw_shader_define_ioctl(struct drm_device *dev, void *data, |
|
- | 727 | struct drm_file *file_priv) |
|
- | 728 | { |
|
- | 729 | struct drm_vmw_shader_create_arg *arg = |
|
- | 730 | (struct drm_vmw_shader_create_arg *)data; |
|
- | 731 | ||
642 | return ERR_PTR(-EINVAL); |
732 | return vmw_shader_define(dev, file_priv, arg->shader_type, |
643 | 733 | arg->buffer_handle, |
|
644 | return vmw_cmdbuf_res_lookup(man, vmw_cmdbuf_res_compat_shader, |
734 | arg->size, arg->offset, |