Subversion Repositories Kolibri OS

Rev

Rev 4569 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4569 Rev 5078
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"
Line -... Line 30...
-
 
30
#include "ttm/ttm_placement.h"
-
 
31
 
-
 
32
#define VMW_COMPAT_SHADER_HT_ORDER 12
30
#include "ttm/ttm_placement.h"
33
 
31
 
34
#if 0
32
struct vmw_shader {
35
struct vmw_shader {
33
	struct vmw_resource res;
36
	struct vmw_resource res;
34
	SVGA3dShaderType type;
37
	SVGA3dShaderType type;
Line 38... Line 41...
38
struct vmw_user_shader {
41
struct vmw_user_shader {
39
	struct ttm_base_object base;
42
	struct ttm_base_object base;
40
	struct vmw_shader shader;
43
	struct vmw_shader shader;
41
};
44
};
Line -... Line 45...
-
 
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,
-
 
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.
-
 
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.
-
 
63
 * @state: Staging state.
-
 
64
 *
-
 
65
 * The structure is protected by the cmdbuf lock.
-
 
66
 */
-
 
67
struct vmw_compat_shader {
-
 
68
	u32 handle;
-
 
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
-
 
79
 * @list: List of commited shaders.
-
 
80
 * @dev_priv: Pointer to a device private structure.
-
 
81
 *
-
 
82
 * @shaders and @list are protected by the cmdbuf mutex for now.
-
 
83
 */
-
 
84
struct vmw_compat_shader_manager {
-
 
85
	struct drm_open_hash shaders;
-
 
86
	struct list_head list;
-
 
87
	struct vmw_private *dev_priv;
-
 
88
};
42
 
89
 
43
static void vmw_user_shader_free(struct vmw_resource *res);
90
static void vmw_user_shader_free(struct vmw_resource *res);
44
static struct vmw_resource *
91
static struct vmw_resource *
Line 45... Line 92...
45
vmw_user_shader_base_to_res(struct ttm_base_object *base);
92
vmw_user_shader_base_to_res(struct ttm_base_object *base);
Line 50... Line 97...
50
static int vmw_gb_shader_unbind(struct vmw_resource *res,
97
static int vmw_gb_shader_unbind(struct vmw_resource *res,
51
				 bool readback,
98
				 bool readback,
52
				 struct ttm_validate_buffer *val_buf);
99
				 struct ttm_validate_buffer *val_buf);
53
static int vmw_gb_shader_destroy(struct vmw_resource *res);
100
static int vmw_gb_shader_destroy(struct vmw_resource *res);
Line 54... Line -...
54
 
-
 
55
static uint64_t vmw_user_shader_size;
-
 
56
 
101
 
57
static const struct vmw_user_resource_conv user_shader_conv = {
102
static const struct vmw_user_resource_conv user_shader_conv = {
58
	.object_type = VMW_RES_SHADER,
103
	.object_type = VMW_RES_SHADER,
59
	.base_obj_to_res = vmw_user_shader_base_to_res,
104
	.base_obj_to_res = vmw_user_shader_base_to_res,
60
	.res_free = vmw_user_shader_free
105
	.res_free = vmw_user_shader_free
Line 256... Line 301...
256
 
301
 
257
	if (likely(res->id == -1))
302
	if (likely(res->id == -1))
Line 258... Line 303...
258
		return 0;
303
		return 0;
259
 
304
 
Line 260... Line 305...
260
	mutex_lock(&dev_priv->binding_mutex);
305
	mutex_lock(&dev_priv->binding_mutex);
261
	vmw_context_binding_res_list_kill(&res->binding_head);
306
	vmw_context_binding_res_list_scrub(&res->binding_head);
262
 
307
 
263
	cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
308
	cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
Line 294... Line 339...
294
{
339
{
295
	struct vmw_user_shader *ushader =
340
	struct vmw_user_shader *ushader =
296
		container_of(res, struct vmw_user_shader, shader.res);
341
		container_of(res, struct vmw_user_shader, shader.res);
297
	struct vmw_private *dev_priv = res->dev_priv;
342
	struct vmw_private *dev_priv = res->dev_priv;
Line 298... Line 343...
298
 
343
 
299
//   ttm_base_object_kfree(ushader, base);
344
	ttm_base_object_kfree(ushader, base);
300
//   ttm_mem_global_free(vmw_mem_glob(dev_priv),
345
	ttm_mem_global_free(vmw_mem_glob(dev_priv),
301
//               vmw_user_shader_size);
346
			    vmw_user_shader_size);
Line 302... Line 347...
302
}
347
}
303
 
348
 
304
/**
349
/**
Line 323... Line 368...
323
 
368
 
324
	return ttm_ref_object_base_unref(tfile, arg->handle,
369
	return ttm_ref_object_base_unref(tfile, arg->handle,
325
					 TTM_REF_USAGE);
370
					 TTM_REF_USAGE);
Line -... Line 371...
-
 
371
}
-
 
372
 
-
 
373
static int vmw_user_shader_alloc(struct vmw_private *dev_priv,
-
 
374
		     struct vmw_dma_buffer *buffer,
-
 
375
		     size_t shader_size,
-
 
376
		     size_t offset,
-
 
377
		     SVGA3dShaderType shader_type,
-
 
378
		     struct ttm_object_file *tfile,
-
 
379
		     u32 *handle)
-
 
380
{
-
 
381
	struct vmw_user_shader *ushader;
-
 
382
	struct vmw_resource *res, *tmp;
-
 
383
	int ret;
-
 
384
 
-
 
385
	/*
-
 
386
	 * Approximate idr memory usage with 128 bytes. It will be limited
-
 
387
	 * by maximum number_of shaders anyway.
-
 
388
	 */
-
 
389
	if (unlikely(vmw_user_shader_size == 0))
-
 
390
		vmw_user_shader_size =
-
 
391
			ttm_round_pot(sizeof(struct vmw_user_shader)) + 128;
-
 
392
 
-
 
393
	ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
-
 
394
				   vmw_user_shader_size,
-
 
395
				   false, true);
-
 
396
	if (unlikely(ret != 0)) {
-
 
397
		if (ret != -ERESTARTSYS)
-
 
398
			DRM_ERROR("Out of graphics memory for shader "
-
 
399
				  "creation.\n");
-
 
400
		goto out;
-
 
401
	}
-
 
402
 
-
 
403
	ushader = kzalloc(sizeof(*ushader), GFP_KERNEL);
-
 
404
	if (unlikely(ushader == NULL)) {
-
 
405
		ttm_mem_global_free(vmw_mem_glob(dev_priv),
-
 
406
				    vmw_user_shader_size);
-
 
407
		ret = -ENOMEM;
-
 
408
		goto out;
-
 
409
	}
-
 
410
 
-
 
411
	res = &ushader->shader.res;
-
 
412
	ushader->base.shareable = false;
-
 
413
	ushader->base.tfile = NULL;
-
 
414
 
-
 
415
	/*
-
 
416
	 * From here on, the destructor takes over resource freeing.
-
 
417
	 */
-
 
418
 
-
 
419
	ret = vmw_gb_shader_init(dev_priv, res, shader_size,
-
 
420
				 offset, shader_type, buffer,
-
 
421
				 vmw_user_shader_free);
-
 
422
	if (unlikely(ret != 0))
-
 
423
		goto out;
-
 
424
 
-
 
425
	tmp = vmw_resource_reference(res);
-
 
426
	ret = ttm_base_object_init(tfile, &ushader->base, false,
-
 
427
				   VMW_RES_SHADER,
-
 
428
				   &vmw_user_shader_base_release, NULL);
-
 
429
 
-
 
430
	if (unlikely(ret != 0)) {
-
 
431
		vmw_resource_unreference(&tmp);
-
 
432
		goto out_err;
-
 
433
	}
-
 
434
 
-
 
435
	if (handle)
-
 
436
		*handle = ushader->base.hash.key;
326
}
437
out_err:
-
 
438
	vmw_resource_unreference(&res);
-
 
439
out:
-
 
440
	return ret;
-
 
441
}
327
 
442
 
328
#if 0
443
 
329
int vmw_shader_define_ioctl(struct drm_device *dev, void *data,
444
int vmw_shader_define_ioctl(struct drm_device *dev, void *data,
330
			     struct drm_file *file_priv)
445
			     struct drm_file *file_priv)
331
{
-
 
332
	struct vmw_private *dev_priv = vmw_priv(dev);
-
 
333
	struct vmw_user_shader *ushader;
-
 
334
	struct vmw_resource *res;
446
{
335
	struct vmw_resource *tmp;
447
	struct vmw_private *dev_priv = vmw_priv(dev);
336
	struct drm_vmw_shader_create_arg *arg =
448
	struct drm_vmw_shader_create_arg *arg =
337
		(struct drm_vmw_shader_create_arg *)data;
-
 
338
	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
449
		(struct drm_vmw_shader_create_arg *)data;
339
	struct vmw_master *vmaster = vmw_master(file_priv->master);
450
	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
340
	struct vmw_dma_buffer *buffer = NULL;
451
	struct vmw_dma_buffer *buffer = NULL;
Line 341... Line 452...
341
	SVGA3dShaderType shader_type;
452
	SVGA3dShaderType shader_type;
Line 372... Line 483...
372
		DRM_ERROR("Illegal shader type.\n");
483
		DRM_ERROR("Illegal shader type.\n");
373
		ret = -EINVAL;
484
		ret = -EINVAL;
374
		goto out_bad_arg;
485
		goto out_bad_arg;
375
	}
486
	}
Line 376... Line -...
376
 
-
 
377
	/*
487
 
378
	 * Approximate idr memory usage with 128 bytes. It will be limited
488
	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
379
	 * by maximum number_of shaders anyway.
489
	if (unlikely(ret != 0))
Line 380... Line 490...
380
	 */
490
		goto out_bad_arg;
381
 
491
 
382
	if (unlikely(vmw_user_shader_size == 0))
-
 
Line 383... Line 492...
383
		vmw_user_shader_size = ttm_round_pot(sizeof(*ushader))
492
	ret = vmw_user_shader_alloc(dev_priv, buffer, arg->size, arg->offset,
-
 
493
			       shader_type, tfile, &arg->shader_handle);
384
			+ 128;
494
 
385
 
495
	ttm_read_unlock(&dev_priv->reservation_sem);
-
 
496
out_bad_arg:
Line -... Line 497...
-
 
497
	vmw_dmabuf_unreference(&buffer);
386
	ret = ttm_read_lock(&vmaster->lock, true);
498
	return ret;
387
	if (unlikely(ret != 0))
499
}
-
 
500
 
388
		return ret;
501
/**
389
 
502
 * vmw_compat_shader_id_ok - Check whether a compat shader user key and
-
 
503
 * shader type are within valid bounds.
390
	ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
504
 *
-
 
505
 * @user_key: User space id of the shader.
391
				   vmw_user_shader_size,
506
 * @shader_type: Shader type.
-
 
507
 *
392
				   false, true);
508
 * Returns true if valid false if not.
393
	if (unlikely(ret != 0)) {
-
 
394
		if (ret != -ERESTARTSYS)
509
	 */
Line -... Line 510...
-
 
510
static bool vmw_compat_shader_id_ok(u32 user_key, SVGA3dShaderType shader_type)
-
 
511
{
-
 
512
	return user_key <= ((1 << 20) - 1) && (unsigned) shader_type < 16;
395
			DRM_ERROR("Out of graphics memory for shader"
513
}
396
				  " creation.\n");
514
 
-
 
515
/**
397
		goto out_unlock;
516
 * vmw_compat_shader_key - Compute a hash key suitable for a compat shader.
398
	}
517
 *
399
 
518
 * @user_key: User space id of the shader.
-
 
519
 * @shader_type: Shader type.
-
 
520
 *
400
	ushader = kzalloc(sizeof(*ushader), GFP_KERNEL);
521
 * Returns a hash key suitable for a command buffer managed resource
401
	if (unlikely(ushader == NULL)) {
522
 * manager hash table.
Line -... Line 523...
-
 
523
 */
-
 
524
static u32 vmw_compat_shader_key(u32 user_key, SVGA3dShaderType shader_type)
-
 
525
{
-
 
526
	return user_key | (shader_type << 20);
-
 
527
}
402
		ttm_mem_global_free(vmw_mem_glob(dev_priv),
528
 
403
				    vmw_user_shader_size);
529
/**
-
 
530
 * vmw_compat_shader_remove - Stage a compat shader for removal.
-
 
531
 *
-
 
532
 * @man: Pointer to the compat shader manager identifying the shader namespace.
-
 
533
 * @user_key: The key that is used to identify the shader. The key is
404
		ret = -ENOMEM;
534
 * unique to the shader type.
-
 
535
 * @shader_type: Shader type.
-
 
536
 * @list: Caller's list of staged command buffer resource actions.
-
 
537
 */
-
 
538
int vmw_compat_shader_remove(struct vmw_cmdbuf_res_manager *man,
-
 
539
			     u32 user_key, SVGA3dShaderType shader_type,
-
 
540
			     struct list_head *list)
-
 
541
{
-
 
542
	if (!vmw_compat_shader_id_ok(user_key, shader_type))
-
 
543
		return -EINVAL;
Line 405... Line 544...
405
		goto out_unlock;
544
 
-
 
545
	return vmw_cmdbuf_res_remove(man, vmw_cmdbuf_res_compat_shader,
-
 
546
				     vmw_compat_shader_key(user_key,
-
 
547
							   shader_type),
-
 
548
				     list);
-
 
549
}
-
 
550
 
-
 
551
/**
-
 
552
 * vmw_compat_shader_add - Create a compat shader and stage it for addition
-
 
553
 * as a command buffer managed resource.
-
 
554
 *
406
	}
555
 * @man: Pointer to the compat shader manager identifying the shader namespace.
-
 
556
 * @user_key: The key that is used to identify the shader. The key is
407
 
557
 * unique to the shader type.
-
 
558
 * @bytecode: Pointer to the bytecode of the shader.
-
 
559
 * @shader_type: Shader type.
-
 
560
 * @tfile: Pointer to a struct ttm_object_file that the guest-backed shader is
-
 
561
 * to be created with.
-
 
562
 * @list: Caller's list of staged command buffer resource actions.
-
 
563
 *
-
 
564
	 */
-
 
565
int vmw_compat_shader_add(struct vmw_private *dev_priv,
-
 
566
			  struct vmw_cmdbuf_res_manager *man,
-
 
567
			  u32 user_key, const void *bytecode,
-
 
568
			  SVGA3dShaderType shader_type,
-
 
569
			  size_t size,
Line 408... Line 570...
408
	res = &ushader->shader.res;
570
			  struct list_head *list)
-
 
571
{
-
 
572
	struct vmw_dma_buffer *buf;
409
	ushader->base.shareable = false;
573
	struct ttm_bo_kmap_obj map;
-
 
574
	bool is_iomem;
-
 
575
	int ret;
-
 
576
	struct vmw_resource *res;
-
 
577
 
-
 
578
	if (!vmw_compat_shader_id_ok(user_key, shader_type))
410
	ushader->base.tfile = NULL;
579
		return -EINVAL;
411
 
580
 
412
	/*
581
	/* Allocate and pin a DMA buffer */
Line 413... Line -...
413
	 * From here on, the destructor takes over resource freeing.
-
 
414
	 */
582
	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
415
 
583
	if (unlikely(buf == NULL))
416
	ret = vmw_gb_shader_init(dev_priv, res, arg->size,
584
		return -ENOMEM;
Line -... Line 585...
-
 
585
 
-
 
586
	ret = vmw_dmabuf_init(dev_priv, buf, size, &vmw_sys_ne_placement,
-
 
587
			      true, vmw_dmabuf_bo_free);
417
				 arg->offset, shader_type, buffer,
588
	if (unlikely(ret != 0))
418
				 vmw_user_shader_free);
589
		goto out;
419
	if (unlikely(ret != 0))
590
 
420
		goto out_unlock;
591
	ret = ttm_bo_reserve(&buf->base, false, true, false, NULL);
Line 421... Line 592...
421
 
592
	if (unlikely(ret != 0))
422
	tmp = vmw_resource_reference(res);
593
		goto no_reserve;
-
 
594
 
423
	ret = ttm_base_object_init(tfile, &ushader->base, false,
595
	/* Map and copy shader bytecode. */
-
 
596
	ret = ttm_bo_kmap(&buf->base, 0, PAGE_ALIGN(size) >> PAGE_SHIFT,
424
				   VMW_RES_SHADER,
597
			  &map);
425
				   &vmw_user_shader_base_release, NULL);
598
	if (unlikely(ret != 0)) {
-
 
599
		ttm_bo_unreserve(&buf->base);
-
 
600
		goto no_reserve;
426
 
601
	}
427
	if (unlikely(ret != 0)) {
602
 
Line -... Line 603...
-
 
603
	memcpy(ttm_kmap_obj_virtual(&map, &is_iomem), bytecode, size);
-
 
604
	WARN_ON(is_iomem);
-
 
605
 
-
 
606
	ttm_bo_kunmap(&map);
-
 
607
	ret = ttm_bo_validate(&buf->base, &vmw_sys_placement, false, true);
-
 
608
	WARN_ON(ret != 0);
-
 
609
	ttm_bo_unreserve(&buf->base);
428
		vmw_resource_unreference(&tmp);
610
 
-
 
611
	res = vmw_shader_alloc(dev_priv, buf, size, 0, shader_type);
Line -... Line 612...
-
 
612
	if (unlikely(ret != 0))
-
 
613
		goto no_reserve;
-
 
614
 
-
 
615
	ret = vmw_cmdbuf_res_add(man, vmw_cmdbuf_res_compat_shader,
-
 
616
				 vmw_compat_shader_key(user_key, shader_type),
-
 
617
				 res, list);
-
 
618
	vmw_resource_unreference(&res);
-
 
619
no_reserve:
-
 
620
	vmw_dmabuf_unreference(&buf);
-
 
621
out:
-
 
622
	return ret;
-
 
623
}
-
 
624
 
-
 
625
/**
-
 
626
 * vmw_compat_shader_lookup - Look up a compat shader
-
 
627
 *
-
 
628
 * @man: Pointer to the command buffer managed resource manager identifying
-
 
629
 * the shader namespace.
-
 
630
 * @user_key: The user space id of the shader.
-
 
631
 * @shader_type: The shader type.
-
 
632
 *
-
 
633
 * Returns a refcounted pointer to a struct vmw_resource if the shader was
429
		goto out_err;
634
 * found. An error pointer otherwise.
430
	}
635
 */