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 31... Line 31...
31
 
31
 
32
struct vmw_user_context {
32
struct vmw_user_context {
33
	struct ttm_base_object base;
33
	struct ttm_base_object base;
34
	struct vmw_resource res;
34
	struct vmw_resource res;
-
 
35
	struct vmw_ctx_binding_state cbs;
35
	struct vmw_ctx_binding_state cbs;
36
	struct vmw_cmdbuf_res_manager *man;
Line 36... Line 37...
36
};
37
};
Line 37... Line 38...
37
 
38
 
38
 
39
 
39
 
40
 
Line 48... Line 49...
48
			       struct ttm_validate_buffer *val_buf);
49
			       struct ttm_validate_buffer *val_buf);
49
static int vmw_gb_context_unbind(struct vmw_resource *res,
50
static int vmw_gb_context_unbind(struct vmw_resource *res,
50
				 bool readback,
51
				 bool readback,
51
				 struct ttm_validate_buffer *val_buf);
52
				 struct ttm_validate_buffer *val_buf);
52
static int vmw_gb_context_destroy(struct vmw_resource *res);
53
static int vmw_gb_context_destroy(struct vmw_resource *res);
53
static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi);
54
static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi, bool rebind);
54
static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi);
55
static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi,
-
 
56
					   bool rebind);
55
static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi);
57
static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi, bool rebind);
-
 
58
static void vmw_context_binding_state_scrub(struct vmw_ctx_binding_state *cbs);
56
static void vmw_context_binding_state_kill(struct vmw_ctx_binding_state *cbs);
59
static void vmw_context_binding_state_kill(struct vmw_ctx_binding_state *cbs);
57
static uint64_t vmw_user_context_size;
60
static uint64_t vmw_user_context_size;
Line 58... Line 61...
58
 
61
 
59
static const struct vmw_user_resource_conv user_context_conv = {
62
static const struct vmw_user_resource_conv user_context_conv = {
Line 99... Line 102...
99
 * Context management:
102
 * Context management:
100
 */
103
 */
Line 101... Line 104...
101
 
104
 
102
static void vmw_hw_context_destroy(struct vmw_resource *res)
105
static void vmw_hw_context_destroy(struct vmw_resource *res)
103
{
-
 
-
 
106
{
-
 
107
	struct vmw_user_context *uctx =
104
 
108
		container_of(res, struct vmw_user_context, res);
105
	struct vmw_private *dev_priv = res->dev_priv;
109
	struct vmw_private *dev_priv = res->dev_priv;
106
	struct {
110
	struct {
107
		SVGA3dCmdHeader header;
111
		SVGA3dCmdHeader header;
108
		SVGA3dCmdDestroyContext body;
112
		SVGA3dCmdDestroyContext body;
Line 109... Line 113...
109
	} *cmd;
113
	} *cmd;
110
 
114
 
-
 
115
 
-
 
116
	if (res->func->destroy == vmw_gb_context_destroy) {
-
 
117
		mutex_lock(&dev_priv->cmdbuf_mutex);
111
 
118
		vmw_cmdbuf_res_man_destroy(uctx->man);
-
 
119
		mutex_lock(&dev_priv->binding_mutex);
112
	if (res->func->destroy == vmw_gb_context_destroy) {
120
		(void) vmw_context_binding_state_kill(&uctx->cbs);
113
		mutex_lock(&dev_priv->cmdbuf_mutex);
121
		(void) vmw_gb_context_destroy(res);
114
		(void) vmw_gb_context_destroy(res);
122
		mutex_unlock(&dev_priv->binding_mutex);
115
		if (dev_priv->pinned_bo != NULL &&
123
		if (dev_priv->pinned_bo != NULL &&
116
		    !dev_priv->query_cid_valid)
124
		    !dev_priv->query_cid_valid)
Line 144... Line 152...
144
		container_of(res, struct vmw_user_context, res);
152
		container_of(res, struct vmw_user_context, res);
Line 145... Line 153...
145
 
153
 
146
	ret = vmw_resource_init(dev_priv, res, true,
154
	ret = vmw_resource_init(dev_priv, res, true,
147
				res_free, &vmw_gb_context_func);
155
				res_free, &vmw_gb_context_func);
-
 
156
	res->backup_size = SVGA3D_CONTEXT_DATA_SIZE;
-
 
157
	if (unlikely(ret != 0))
Line 148... Line 158...
148
	res->backup_size = SVGA3D_CONTEXT_DATA_SIZE;
158
		goto out_err;
-
 
159
 
149
 
160
	if (dev_priv->has_mob) {
150
	if (unlikely(ret != 0)) {
161
		uctx->man = vmw_cmdbuf_res_man_create(dev_priv);
151
		if (res_free)
162
		if (unlikely(IS_ERR(uctx->man))) {
152
			res_free(res);
163
			ret = PTR_ERR(uctx->man);
153
		else
164
			uctx->man = NULL;
154
			kfree(res);
165
			goto out_err;
Line 155... Line 166...
155
		return ret;
166
		}
156
	}
167
	}
Line 157... Line 168...
157
 
168
 
158
	memset(&uctx->cbs, 0, sizeof(uctx->cbs));
169
	memset(&uctx->cbs, 0, sizeof(uctx->cbs));
-
 
170
	INIT_LIST_HEAD(&uctx->cbs.list);
-
 
171
 
-
 
172
	vmw_resource_activate(res, vmw_hw_context_destroy);
-
 
173
	return 0;
-
 
174
 
-
 
175
out_err:
-
 
176
	if (res_free)
159
	INIT_LIST_HEAD(&uctx->cbs.list);
177
		res_free(res);
Line 160... Line 178...
160
 
178
	else
161
	vmw_resource_activate(res, vmw_hw_context_destroy);
179
		kfree(res);
162
	return 0;
180
	return ret;
Line 326... Line 344...
326
 
344
 
Line 327... Line 345...
327
 
345
 
328
	BUG_ON(bo->mem.mem_type != VMW_PL_MOB);
346
	BUG_ON(bo->mem.mem_type != VMW_PL_MOB);
Line 329... Line 347...
329
 
347
 
Line 330... Line 348...
330
	mutex_lock(&dev_priv->binding_mutex);
348
	mutex_lock(&dev_priv->binding_mutex);
331
	vmw_context_binding_state_kill(&uctx->cbs);
349
	vmw_context_binding_state_scrub(&uctx->cbs);
Line 376... Line 394...
376
	struct vmw_private *dev_priv = res->dev_priv;
394
	struct vmw_private *dev_priv = res->dev_priv;
377
	struct {
395
	struct {
378
		SVGA3dCmdHeader header;
396
		SVGA3dCmdHeader header;
379
		SVGA3dCmdDestroyGBContext body;
397
		SVGA3dCmdDestroyGBContext body;
380
	} *cmd;
398
	} *cmd;
381
	struct vmw_user_context *uctx =
-
 
382
		container_of(res, struct vmw_user_context, res);
-
 
383
 
-
 
384
	BUG_ON(!list_empty(&uctx->cbs.list));
-
 
Line 385... Line 399...
385
 
399
 
386
	if (likely(res->id == -1))
400
	if (likely(res->id == -1))
Line 387... Line 401...
387
		return 0;
401
		return 0;
Line 459... Line 473...
459
	struct vmw_user_context *ctx;
473
	struct vmw_user_context *ctx;
460
	struct vmw_resource *res;
474
	struct vmw_resource *res;
461
	struct vmw_resource *tmp;
475
	struct vmw_resource *tmp;
462
	struct drm_vmw_context_arg *arg = (struct drm_vmw_context_arg *)data;
476
	struct drm_vmw_context_arg *arg = (struct drm_vmw_context_arg *)data;
463
	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
477
	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
464
	struct vmw_master *vmaster = vmw_master(file_priv->master);
-
 
465
	int ret;
478
	int ret;
Line 466... Line 479...
466
 
479
 
467
 
480
 
468
	/*
481
	/*
469
	 * Approximate idr memory usage with 128 bytes. It will be limited
482
	 * Approximate idr memory usage with 128 bytes. It will be limited
Line 470... Line 483...
470
	 * by maximum number_of contexts anyway.
483
	 * by maximum number_of contexts anyway.
471
	 */
484
	 */
-
 
485
 
Line 472... Line 486...
472
 
486
	if (unlikely(vmw_user_context_size == 0))
473
	if (unlikely(vmw_user_context_size == 0))
487
		vmw_user_context_size = ttm_round_pot(sizeof(*ctx)) + 128 +
474
		vmw_user_context_size = ttm_round_pot(sizeof(*ctx)) + 128;
488
		  ((dev_priv->has_mob) ? vmw_cmdbuf_res_man_size() : 0);
Line 475... Line 489...
475
 
489
 
476
	ret = ttm_read_lock(&vmaster->lock, true);
490
	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
Line 518... Line 532...
518
 
532
 
519
	arg->cid = ctx->base.hash.key;
533
	arg->cid = ctx->base.hash.key;
520
out_err:
534
out_err:
521
	vmw_resource_unreference(&res);
535
	vmw_resource_unreference(&res);
522
out_unlock:
536
out_unlock:
523
	ttm_read_unlock(&vmaster->lock);
537
	ttm_read_unlock(&dev_priv->reservation_sem);
Line 524... Line 538...
524
	return ret;
538
	return ret;
525
 
539
 
Line 526... Line 540...
526
}
540
}
527
#endif
541
#endif
528
 
542
 
529
/**
543
/**
-
 
544
 * vmw_context_scrub_shader - scrub a shader binding from a context.
530
 * vmw_context_scrub_shader - scrub a shader binding from a context.
545
 *
531
 *
546
 * @bi: single binding information.
532
 * @bi: single binding information.
547
 * @rebind: Whether to issue a bind instead of scrub command.
533
 */
548
 */
534
static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi)
549
static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi, bool rebind)
535
{
550
{
536
	struct vmw_private *dev_priv = bi->ctx->dev_priv;
551
	struct vmw_private *dev_priv = bi->ctx->dev_priv;
Line 548... Line 563...
548
 
563
 
549
	cmd->header.id = SVGA_3D_CMD_SET_SHADER;
564
	cmd->header.id = SVGA_3D_CMD_SET_SHADER;
550
	cmd->header.size = sizeof(cmd->body);
565
	cmd->header.size = sizeof(cmd->body);
551
	cmd->body.cid = bi->ctx->id;
566
	cmd->body.cid = bi->ctx->id;
552
	cmd->body.type = bi->i1.shader_type;
567
	cmd->body.type = bi->i1.shader_type;
553
	cmd->body.shid = SVGA3D_INVALID_ID;
568
	cmd->body.shid = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID);
Line 554... Line 569...
554
	vmw_fifo_commit(dev_priv, sizeof(*cmd));
569
	vmw_fifo_commit(dev_priv, sizeof(*cmd));
555
 
570
 
Line 556... Line 571...
556
	return 0;
571
	return 0;
557
}
572
}
558
 
573
 
559
/**
574
/**
560
 * vmw_context_scrub_render_target - scrub a render target binding
575
 * vmw_context_scrub_render_target - scrub a render target binding
-
 
576
 * from a context.
561
 * from a context.
577
 *
562
 *
578
 * @bi: single binding information.
-
 
579
 * @rebind: Whether to issue a bind instead of scrub command.
563
 * @bi: single binding information.
580
 */
564
 */
581
static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi,
565
static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi)
582
					   bool rebind)
566
{
583
{
567
	struct vmw_private *dev_priv = bi->ctx->dev_priv;
584
	struct vmw_private *dev_priv = bi->ctx->dev_priv;
Line 579... Line 596...
579
 
596
 
580
	cmd->header.id = SVGA_3D_CMD_SETRENDERTARGET;
597
	cmd->header.id = SVGA_3D_CMD_SETRENDERTARGET;
581
	cmd->header.size = sizeof(cmd->body);
598
	cmd->header.size = sizeof(cmd->body);
582
	cmd->body.cid = bi->ctx->id;
599
	cmd->body.cid = bi->ctx->id;
583
	cmd->body.type = bi->i1.rt_type;
600
	cmd->body.type = bi->i1.rt_type;
584
	cmd->body.target.sid = SVGA3D_INVALID_ID;
601
	cmd->body.target.sid = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID);
585
	cmd->body.target.face = 0;
602
	cmd->body.target.face = 0;
586
	cmd->body.target.mipmap = 0;
603
	cmd->body.target.mipmap = 0;
Line 587... Line 604...
587
	vmw_fifo_commit(dev_priv, sizeof(*cmd));
604
	vmw_fifo_commit(dev_priv, sizeof(*cmd));
Line 591... Line 608...
591
 
608
 
592
/**
609
/**
593
 * vmw_context_scrub_texture - scrub a texture binding from a context.
610
 * vmw_context_scrub_texture - scrub a texture binding from a context.
594
 *
611
 *
-
 
612
 * @bi: single binding information.
595
 * @bi: single binding information.
613
 * @rebind: Whether to issue a bind instead of scrub command.
596
 *
614
 *
597
 * TODO: Possibly complement this function with a function that takes
615
 * TODO: Possibly complement this function with a function that takes
598
 * a list of texture bindings and combines them to a single command.
616
 * a list of texture bindings and combines them to a single command.
599
 */
617
 */
-
 
618
static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi,
600
static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi)
619
				     bool rebind)
601
{
620
{
602
	struct vmw_private *dev_priv = bi->ctx->dev_priv;
621
	struct vmw_private *dev_priv = bi->ctx->dev_priv;
603
	struct {
622
	struct {
604
		SVGA3dCmdHeader header;
623
		SVGA3dCmdHeader header;
Line 619... Line 638...
619
	cmd->header.id = SVGA_3D_CMD_SETTEXTURESTATE;
638
	cmd->header.id = SVGA_3D_CMD_SETTEXTURESTATE;
620
	cmd->header.size = sizeof(cmd->body);
639
	cmd->header.size = sizeof(cmd->body);
621
	cmd->body.c.cid = bi->ctx->id;
640
	cmd->body.c.cid = bi->ctx->id;
622
	cmd->body.s1.stage = bi->i1.texture_stage;
641
	cmd->body.s1.stage = bi->i1.texture_stage;
623
	cmd->body.s1.name = SVGA3D_TS_BIND_TEXTURE;
642
	cmd->body.s1.name = SVGA3D_TS_BIND_TEXTURE;
624
	cmd->body.s1.value = (uint32) SVGA3D_INVALID_ID;
643
	cmd->body.s1.value = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID);
625
	vmw_fifo_commit(dev_priv, sizeof(*cmd));
644
	vmw_fifo_commit(dev_priv, sizeof(*cmd));
Line 626... Line 645...
626
 
645
 
627
	return 0;
646
	return 0;
Line 692... Line 711...
692
 
711
 
693
	if (loc->bi.ctx != NULL)
712
	if (loc->bi.ctx != NULL)
Line 694... Line 713...
694
		vmw_context_binding_drop(loc);
713
		vmw_context_binding_drop(loc);
-
 
714
 
695
 
715
	loc->bi = *bi;
696
	loc->bi = *bi;
716
	loc->bi.scrubbed = false;
Line 697... Line 717...
697
	list_add_tail(&loc->ctx_list, &cbs->list);
717
	list_add_tail(&loc->ctx_list, &cbs->list);
698
	INIT_LIST_HEAD(&loc->res_list);
718
	INIT_LIST_HEAD(&loc->res_list);
Line 727... Line 747...
727
	}
747
	}
Line 728... Line 748...
728
 
748
 
729
	if (loc->bi.ctx != NULL)
749
	if (loc->bi.ctx != NULL)
Line -... Line 750...
-
 
750
		vmw_context_binding_drop(loc);
730
		vmw_context_binding_drop(loc);
751
 
731
 
752
	if (bi->res != NULL) {
732
	loc->bi = *bi;
-
 
733
	list_add_tail(&loc->ctx_list, &cbs->list);
753
	loc->bi = *bi;
734
	if (bi->res != NULL)
754
	list_add_tail(&loc->ctx_list, &cbs->list);
735
		list_add_tail(&loc->res_list, &bi->res->binding_head);
-
 
736
	else
755
		list_add_tail(&loc->res_list, &bi->res->binding_head);
Line 737... Line 756...
737
		INIT_LIST_HEAD(&loc->res_list);
756
	}
738
}
757
}
739
 
758
 
Line 746... Line 765...
746
 * Emits FIFO commands to scrub a binding represented by @cb.
765
 * Emits FIFO commands to scrub a binding represented by @cb.
747
 * Then stops tracking the binding and re-initializes its storage.
766
 * Then stops tracking the binding and re-initializes its storage.
748
 */
767
 */
749
static void vmw_context_binding_kill(struct vmw_ctx_binding *cb)
768
static void vmw_context_binding_kill(struct vmw_ctx_binding *cb)
750
{
769
{
-
 
770
	if (!cb->bi.scrubbed) {
751
	(void) vmw_scrub_funcs[cb->bi.bt](&cb->bi);
771
		(void) vmw_scrub_funcs[cb->bi.bt](&cb->bi, false);
-
 
772
		cb->bi.scrubbed = true;
-
 
773
	}
752
	vmw_context_binding_drop(cb);
774
	vmw_context_binding_drop(cb);
753
}
775
}
Line 754... Line 776...
754
 
776
 
755
/**
777
/**
Line 768... Line 790...
768
	list_for_each_entry_safe(entry, next, &cbs->list, ctx_list)
790
	list_for_each_entry_safe(entry, next, &cbs->list, ctx_list)
769
		vmw_context_binding_kill(entry);
791
		vmw_context_binding_kill(entry);
770
}
792
}
Line 771... Line 793...
771
 
793
 
-
 
794
/**
-
 
795
 * vmw_context_binding_state_scrub - Scrub all bindings associated with a
-
 
796
 * struct vmw_ctx_binding state structure.
-
 
797
 *
-
 
798
 * @cbs: Pointer to the context binding state tracker.
-
 
799
 *
-
 
800
 * Emits commands to scrub all bindings associated with the
-
 
801
 * context binding state tracker.
-
 
802
 */
-
 
803
static void vmw_context_binding_state_scrub(struct vmw_ctx_binding_state *cbs)
-
 
804
{
-
 
805
	struct vmw_ctx_binding *entry;
-
 
806
 
-
 
807
	list_for_each_entry(entry, &cbs->list, ctx_list) {
-
 
808
		if (!entry->bi.scrubbed) {
-
 
809
			(void) vmw_scrub_funcs[entry->bi.bt](&entry->bi, false);
-
 
810
			entry->bi.scrubbed = true;
-
 
811
		}
-
 
812
	}
-
 
813
}
-
 
814
 
772
/**
815
/**
773
 * vmw_context_binding_res_list_kill - Kill all bindings on a
816
 * vmw_context_binding_res_list_kill - Kill all bindings on a
774
 * resource binding list
817
 * resource binding list
775
 *
818
 *
776
 * @head: list head of resource binding list
819
 * @head: list head of resource binding list
Line 785... Line 828...
785
	list_for_each_entry_safe(entry, next, head, res_list)
828
	list_for_each_entry_safe(entry, next, head, res_list)
786
		vmw_context_binding_kill(entry);
829
		vmw_context_binding_kill(entry);
787
}
830
}
Line 788... Line 831...
788
 
831
 
-
 
832
/**
-
 
833
 * vmw_context_binding_res_list_scrub - Scrub all bindings on a
-
 
834
 * resource binding list
-
 
835
 *
-
 
836
 * @head: list head of resource binding list
-
 
837
 *
-
 
838
 * Scrub all bindings associated with a specific resource. Typically
-
 
839
 * called before the resource is evicted.
-
 
840
 */
-
 
841
void vmw_context_binding_res_list_scrub(struct list_head *head)
-
 
842
{
-
 
843
	struct vmw_ctx_binding *entry;
-
 
844
 
-
 
845
	list_for_each_entry(entry, head, res_list) {
-
 
846
		if (!entry->bi.scrubbed) {
-
 
847
			(void) vmw_scrub_funcs[entry->bi.bt](&entry->bi, false);
-
 
848
			entry->bi.scrubbed = true;
-
 
849
		}
-
 
850
	}
-
 
851
}
-
 
852
 
789
/**
853
/**
790
 * vmw_context_binding_state_transfer - Commit staged binding info
854
 * vmw_context_binding_state_transfer - Commit staged binding info
791
 *
855
 *
792
 * @ctx: Pointer to context to commit the staged binding info to.
856
 * @ctx: Pointer to context to commit the staged binding info to.
793
 * @from: Staged binding info built during execbuf.
857
 * @from: Staged binding info built during execbuf.
Line 803... Line 867...
803
	struct vmw_ctx_binding *entry, *next;
867
	struct vmw_ctx_binding *entry, *next;
Line 804... Line 868...
804
 
868
 
805
	list_for_each_entry_safe(entry, next, &from->list, ctx_list)
869
	list_for_each_entry_safe(entry, next, &from->list, ctx_list)
806
		vmw_context_binding_transfer(&uctx->cbs, &entry->bi);
870
		vmw_context_binding_transfer(&uctx->cbs, &entry->bi);
-
 
871
}
-
 
872
 
-
 
873
/**
-
 
874
 * vmw_context_rebind_all - Rebind all scrubbed bindings of a context
-
 
875
 *
-
 
876
 * @ctx: The context resource
-
 
877
 *
-
 
878
 * Walks through the context binding list and rebinds all scrubbed
-
 
879
 * resources.
-
 
880
 */
-
 
881
int vmw_context_rebind_all(struct vmw_resource *ctx)
-
 
882
{
-
 
883
	struct vmw_ctx_binding *entry;
-
 
884
	struct vmw_user_context *uctx =
-
 
885
		container_of(ctx, struct vmw_user_context, res);
-
 
886
	struct vmw_ctx_binding_state *cbs = &uctx->cbs;
-
 
887
	int ret;
-
 
888
 
-
 
889
	list_for_each_entry(entry, &cbs->list, ctx_list) {
-
 
890
		if (likely(!entry->bi.scrubbed))
-
 
891
			continue;
-
 
892
 
-
 
893
		if (WARN_ON(entry->bi.res == NULL || entry->bi.res->id ==
-
 
894
			    SVGA3D_INVALID_ID))
-
 
895
			continue;
-
 
896
 
-
 
897
		ret = vmw_scrub_funcs[entry->bi.bt](&entry->bi, true);
-
 
898
		if (unlikely(ret != 0))
-
 
899
			return ret;
-
 
900
 
-
 
901
		entry->bi.scrubbed = false;
-
 
902
	}
-
 
903
 
-
 
904
	return 0;
-
 
905
}
-
 
906
 
-
 
907
/**
-
 
908
 * vmw_context_binding_list - Return a list of context bindings
-
 
909
 *
-
 
910
 * @ctx: The context resource
-
 
911
 *
-
 
912
 * Returns the current list of bindings of the given context. Note that
-
 
913
 * this list becomes stale as soon as the dev_priv::binding_mutex is unlocked.
-
 
914
 */
-
 
915
struct list_head *vmw_context_binding_list(struct vmw_resource *ctx)
-
 
916
{
-
 
917
	return &(container_of(ctx, struct vmw_user_context, res)->cbs.list);
-
 
918
}
-
 
919
 
-
 
920
struct vmw_cmdbuf_res_manager *vmw_context_res_man(struct vmw_resource *ctx)
-
 
921
{
-
 
922
	return container_of(ctx, struct vmw_user_context, res)->man;