Home | History | Annotate | Line # | Download | only in vmwgfx
      1 /*	$NetBSD: vmwgfx_binding.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $	*/
      2 
      3 // SPDX-License-Identifier: GPL-2.0 OR MIT
      4 /**************************************************************************
      5  *
      6  * Copyright 2015 VMware, Inc., Palo Alto, CA., USA
      7  *
      8  * Permission is hereby granted, free of charge, to any person obtaining a
      9  * copy of this software and associated documentation files (the
     10  * "Software"), to deal in the Software without restriction, including
     11  * without limitation the rights to use, copy, modify, merge, publish,
     12  * distribute, sub license, and/or sell copies of the Software, and to
     13  * permit persons to whom the Software is furnished to do so, subject to
     14  * the following conditions:
     15  *
     16  * The above copyright notice and this permission notice (including the
     17  * next paragraph) shall be included in all copies or substantial portions
     18  * of the Software.
     19  *
     20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     22  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     23  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
     24  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     25  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     26  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     27  *
     28  **************************************************************************/
     29 /*
     30  * This file implements the vmwgfx context binding manager,
     31  * The sole reason for having to use this code is that vmware guest
     32  * backed contexts can be swapped out to their backing mobs by the device
     33  * at any time, also swapped in at any time. At swapin time, the device
     34  * validates the context bindings to make sure they point to valid resources.
     35  * It's this outside-of-drawcall validation (that can happen at any time),
     36  * that makes this code necessary.
     37  *
     38  * We therefore need to kill any context bindings pointing to a resource
     39  * when the resource is swapped out. Furthermore, if the vmwgfx driver has
     40  * swapped out the context we can't swap it in again to kill bindings because
     41  * of backing mob reservation lockdep violations, so as part of
     42  * context swapout, also kill all bindings of a context, so that they are
     43  * already killed if a resource to which a binding points
     44  * needs to be swapped out.
     45  *
     46  * Note that a resource can be pointed to by bindings from multiple contexts,
     47  * Therefore we can't easily protect this data by a per context mutex
     48  * (unless we use deadlock-safe WW mutexes). So we use a global binding_mutex
     49  * to protect all binding manager data.
     50  *
     51  * Finally, any association between a context and a global resource
     52  * (surface, shader or even DX query) is conceptually a context binding that
     53  * needs to be tracked by this code.
     54  */
     55 
     56 #include <sys/cdefs.h>
     57 __KERNEL_RCSID(0, "$NetBSD: vmwgfx_binding.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $");
     58 
     59 #include "vmwgfx_drv.h"
     60 #include "vmwgfx_binding.h"
     61 #include "device_include/svga3d_reg.h"
     62 
     63 #define VMW_BINDING_RT_BIT     0
     64 #define VMW_BINDING_PS_BIT     1
     65 #define VMW_BINDING_SO_BIT     2
     66 #define VMW_BINDING_VB_BIT     3
     67 #define VMW_BINDING_NUM_BITS   4
     68 
     69 #define VMW_BINDING_PS_SR_BIT  0
     70 
     71 /**
     72  * struct vmw_ctx_binding_state - per context binding state
     73  *
     74  * @dev_priv: Pointer to device private structure.
     75  * @list: linked list of individual active bindings.
     76  * @render_targets: Render target bindings.
     77  * @texture_units: Texture units bindings.
     78  * @ds_view: Depth-stencil view binding.
     79  * @so_targets: StreamOutput target bindings.
     80  * @vertex_buffers: Vertex buffer bindings.
     81  * @index_buffer: Index buffer binding.
     82  * @per_shader: Per shader-type bindings.
     83  * @dirty: Bitmap tracking per binding-type changes that have not yet
     84  * been emitted to the device.
     85  * @dirty_vb: Bitmap tracking individual vertex buffer binding changes that
     86  * have not yet been emitted to the device.
     87  * @bind_cmd_buffer: Scratch space used to construct binding commands.
     88  * @bind_cmd_count: Number of binding command data entries in @bind_cmd_buffer
     89  * @bind_first_slot: Used together with @bind_cmd_buffer to indicate the
     90  * device binding slot of the first command data entry in @bind_cmd_buffer.
     91  *
     92  * Note that this structure also provides storage space for the individual
     93  * struct vmw_ctx_binding objects, so that no dynamic allocation is needed
     94  * for individual bindings.
     95  *
     96  */
     97 struct vmw_ctx_binding_state {
     98 	struct vmw_private *dev_priv;
     99 	struct list_head list;
    100 	struct vmw_ctx_bindinfo_view render_targets[SVGA3D_RT_MAX];
    101 	struct vmw_ctx_bindinfo_tex texture_units[SVGA3D_NUM_TEXTURE_UNITS];
    102 	struct vmw_ctx_bindinfo_view ds_view;
    103 	struct vmw_ctx_bindinfo_so so_targets[SVGA3D_DX_MAX_SOTARGETS];
    104 	struct vmw_ctx_bindinfo_vb vertex_buffers[SVGA3D_DX_MAX_VERTEXBUFFERS];
    105 	struct vmw_ctx_bindinfo_ib index_buffer;
    106 	struct vmw_dx_shader_bindings per_shader[SVGA3D_NUM_SHADERTYPE_DX10];
    107 
    108 	unsigned long dirty;
    109 	DECLARE_BITMAP(dirty_vb, SVGA3D_DX_MAX_VERTEXBUFFERS);
    110 
    111 	u32 bind_cmd_buffer[VMW_MAX_VIEW_BINDINGS];
    112 	u32 bind_cmd_count;
    113 	u32 bind_first_slot;
    114 };
    115 
    116 static int vmw_binding_scrub_shader(struct vmw_ctx_bindinfo *bi, bool rebind);
    117 static int vmw_binding_scrub_render_target(struct vmw_ctx_bindinfo *bi,
    118 					   bool rebind);
    119 static int vmw_binding_scrub_texture(struct vmw_ctx_bindinfo *bi, bool rebind);
    120 static int vmw_binding_scrub_cb(struct vmw_ctx_bindinfo *bi, bool rebind);
    121 static int vmw_binding_scrub_dx_rt(struct vmw_ctx_bindinfo *bi, bool rebind);
    122 static int vmw_binding_scrub_sr(struct vmw_ctx_bindinfo *bi, bool rebind);
    123 static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind);
    124 static int vmw_binding_emit_dirty(struct vmw_ctx_binding_state *cbs);
    125 static int vmw_binding_scrub_dx_shader(struct vmw_ctx_bindinfo *bi,
    126 				       bool rebind);
    127 static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo *bi, bool rebind);
    128 static int vmw_binding_scrub_vb(struct vmw_ctx_bindinfo *bi, bool rebind);
    129 static void vmw_binding_build_asserts(void) __attribute__ ((unused));
    130 
    131 typedef int (*vmw_scrub_func)(struct vmw_ctx_bindinfo *, bool);
    132 
    133 /**
    134  * struct vmw_binding_info - Per binding type information for the binding
    135  * manager
    136  *
    137  * @size: The size of the struct binding derived from a struct vmw_ctx_bindinfo.
    138  * @offsets: array[shader_slot] of offsets to the array[slot]
    139  * of struct bindings for the binding type.
    140  * @scrub_func: Pointer to the scrub function for this binding type.
    141  *
    142  * Holds static information to help optimize the binding manager and avoid
    143  * an excessive amount of switch statements.
    144  */
    145 struct vmw_binding_info {
    146 	size_t size;
    147 	const size_t *offsets;
    148 	vmw_scrub_func scrub_func;
    149 };
    150 
    151 /*
    152  * A number of static variables that help determine the scrub func and the
    153  * location of the struct vmw_ctx_bindinfo slots for each binding type.
    154  */
    155 static const size_t vmw_binding_shader_offsets[] = {
    156 	offsetof(struct vmw_ctx_binding_state, per_shader[0].shader),
    157 	offsetof(struct vmw_ctx_binding_state, per_shader[1].shader),
    158 	offsetof(struct vmw_ctx_binding_state, per_shader[2].shader),
    159 };
    160 static const size_t vmw_binding_rt_offsets[] = {
    161 	offsetof(struct vmw_ctx_binding_state, render_targets),
    162 };
    163 static const size_t vmw_binding_tex_offsets[] = {
    164 	offsetof(struct vmw_ctx_binding_state, texture_units),
    165 };
    166 static const size_t vmw_binding_cb_offsets[] = {
    167 	offsetof(struct vmw_ctx_binding_state, per_shader[0].const_buffers),
    168 	offsetof(struct vmw_ctx_binding_state, per_shader[1].const_buffers),
    169 	offsetof(struct vmw_ctx_binding_state, per_shader[2].const_buffers),
    170 };
    171 static const size_t vmw_binding_dx_ds_offsets[] = {
    172 	offsetof(struct vmw_ctx_binding_state, ds_view),
    173 };
    174 static const size_t vmw_binding_sr_offsets[] = {
    175 	offsetof(struct vmw_ctx_binding_state, per_shader[0].shader_res),
    176 	offsetof(struct vmw_ctx_binding_state, per_shader[1].shader_res),
    177 	offsetof(struct vmw_ctx_binding_state, per_shader[2].shader_res),
    178 };
    179 static const size_t vmw_binding_so_offsets[] = {
    180 	offsetof(struct vmw_ctx_binding_state, so_targets),
    181 };
    182 static const size_t vmw_binding_vb_offsets[] = {
    183 	offsetof(struct vmw_ctx_binding_state, vertex_buffers),
    184 };
    185 static const size_t vmw_binding_ib_offsets[] = {
    186 	offsetof(struct vmw_ctx_binding_state, index_buffer),
    187 };
    188 
    189 static const struct vmw_binding_info vmw_binding_infos[] = {
    190 	[vmw_ctx_binding_shader] = {
    191 		.size = sizeof(struct vmw_ctx_bindinfo_shader),
    192 		.offsets = vmw_binding_shader_offsets,
    193 		.scrub_func = vmw_binding_scrub_shader},
    194 	[vmw_ctx_binding_rt] = {
    195 		.size = sizeof(struct vmw_ctx_bindinfo_view),
    196 		.offsets = vmw_binding_rt_offsets,
    197 		.scrub_func = vmw_binding_scrub_render_target},
    198 	[vmw_ctx_binding_tex] = {
    199 		.size = sizeof(struct vmw_ctx_bindinfo_tex),
    200 		.offsets = vmw_binding_tex_offsets,
    201 		.scrub_func = vmw_binding_scrub_texture},
    202 	[vmw_ctx_binding_cb] = {
    203 		.size = sizeof(struct vmw_ctx_bindinfo_cb),
    204 		.offsets = vmw_binding_cb_offsets,
    205 		.scrub_func = vmw_binding_scrub_cb},
    206 	[vmw_ctx_binding_dx_shader] = {
    207 		.size = sizeof(struct vmw_ctx_bindinfo_shader),
    208 		.offsets = vmw_binding_shader_offsets,
    209 		.scrub_func = vmw_binding_scrub_dx_shader},
    210 	[vmw_ctx_binding_dx_rt] = {
    211 		.size = sizeof(struct vmw_ctx_bindinfo_view),
    212 		.offsets = vmw_binding_rt_offsets,
    213 		.scrub_func = vmw_binding_scrub_dx_rt},
    214 	[vmw_ctx_binding_sr] = {
    215 		.size = sizeof(struct vmw_ctx_bindinfo_view),
    216 		.offsets = vmw_binding_sr_offsets,
    217 		.scrub_func = vmw_binding_scrub_sr},
    218 	[vmw_ctx_binding_ds] = {
    219 		.size = sizeof(struct vmw_ctx_bindinfo_view),
    220 		.offsets = vmw_binding_dx_ds_offsets,
    221 		.scrub_func = vmw_binding_scrub_dx_rt},
    222 	[vmw_ctx_binding_so] = {
    223 		.size = sizeof(struct vmw_ctx_bindinfo_so),
    224 		.offsets = vmw_binding_so_offsets,
    225 		.scrub_func = vmw_binding_scrub_so},
    226 	[vmw_ctx_binding_vb] = {
    227 		.size = sizeof(struct vmw_ctx_bindinfo_vb),
    228 		.offsets = vmw_binding_vb_offsets,
    229 		.scrub_func = vmw_binding_scrub_vb},
    230 	[vmw_ctx_binding_ib] = {
    231 		.size = sizeof(struct vmw_ctx_bindinfo_ib),
    232 		.offsets = vmw_binding_ib_offsets,
    233 		.scrub_func = vmw_binding_scrub_ib},
    234 };
    235 
    236 /**
    237  * vmw_cbs_context - Return a pointer to the context resource of a
    238  * context binding state tracker.
    239  *
    240  * @cbs: The context binding state tracker.
    241  *
    242  * Provided there are any active bindings, this function will return an
    243  * unreferenced pointer to the context resource that owns the context
    244  * binding state tracker. If there are no active bindings, this function
    245  * will return NULL. Note that the caller must somehow ensure that a reference
    246  * is held on the context resource prior to calling this function.
    247  */
    248 static const struct vmw_resource *
    249 vmw_cbs_context(const struct vmw_ctx_binding_state *cbs)
    250 {
    251 	if (list_empty(&cbs->list))
    252 		return NULL;
    253 
    254 	return list_first_entry(&cbs->list, struct vmw_ctx_bindinfo,
    255 				ctx_list)->ctx;
    256 }
    257 
    258 /**
    259  * vmw_binding_loc - determine the struct vmw_ctx_bindinfo slot location.
    260  *
    261  * @cbs: Pointer to a struct vmw_ctx_binding state which holds the slot.
    262  * @bt: The binding type.
    263  * @shader_slot: The shader slot of the binding. If none, then set to 0.
    264  * @slot: The slot of the binding.
    265  */
    266 static struct vmw_ctx_bindinfo *
    267 vmw_binding_loc(struct vmw_ctx_binding_state *cbs,
    268 		enum vmw_ctx_binding_type bt, u32 shader_slot, u32 slot)
    269 {
    270 	const struct vmw_binding_info *b = &vmw_binding_infos[bt];
    271 	size_t offset = b->offsets[shader_slot] + b->size*slot;
    272 
    273 	return (struct vmw_ctx_bindinfo *)((u8 *) cbs + offset);
    274 }
    275 
    276 /**
    277  * vmw_binding_drop: Stop tracking a context binding
    278  *
    279  * @bi: Pointer to binding tracker storage.
    280  *
    281  * Stops tracking a context binding, and re-initializes its storage.
    282  * Typically used when the context binding is replaced with a binding to
    283  * another (or the same, for that matter) resource.
    284  */
    285 static void vmw_binding_drop(struct vmw_ctx_bindinfo *bi)
    286 {
    287 	list_del(&bi->ctx_list);
    288 	if (!list_empty(&bi->res_list))
    289 		list_del(&bi->res_list);
    290 	bi->ctx = NULL;
    291 }
    292 
    293 /**
    294  * vmw_binding_add: Start tracking a context binding
    295  *
    296  * @cbs: Pointer to the context binding state tracker.
    297  * @bi: Information about the binding to track.
    298  *
    299  * Starts tracking the binding in the context binding
    300  * state structure @cbs.
    301  */
    302 void vmw_binding_add(struct vmw_ctx_binding_state *cbs,
    303 		    const struct vmw_ctx_bindinfo *bi,
    304 		    u32 shader_slot, u32 slot)
    305 {
    306 	struct vmw_ctx_bindinfo *loc =
    307 		vmw_binding_loc(cbs, bi->bt, shader_slot, slot);
    308 	const struct vmw_binding_info *b = &vmw_binding_infos[bi->bt];
    309 
    310 	if (loc->ctx != NULL)
    311 		vmw_binding_drop(loc);
    312 
    313 	memcpy(loc, bi, b->size);
    314 	loc->scrubbed = false;
    315 	list_add(&loc->ctx_list, &cbs->list);
    316 	INIT_LIST_HEAD(&loc->res_list);
    317 }
    318 
    319 /**
    320  * vmw_binding_transfer: Transfer a context binding tracking entry.
    321  *
    322  * @cbs: Pointer to the persistent context binding state tracker.
    323  * @bi: Information about the binding to track.
    324  *
    325  */
    326 static void vmw_binding_transfer(struct vmw_ctx_binding_state *cbs,
    327 				 const struct vmw_ctx_binding_state *from,
    328 				 const struct vmw_ctx_bindinfo *bi)
    329 {
    330 	size_t offset = (unsigned long)bi - (unsigned long)from;
    331 	struct vmw_ctx_bindinfo *loc = (struct vmw_ctx_bindinfo *)
    332 		((unsigned long) cbs + offset);
    333 
    334 	if (loc->ctx != NULL) {
    335 		WARN_ON(bi->scrubbed);
    336 
    337 		vmw_binding_drop(loc);
    338 	}
    339 
    340 	if (bi->res != NULL) {
    341 		memcpy(loc, bi, vmw_binding_infos[bi->bt].size);
    342 		list_add_tail(&loc->ctx_list, &cbs->list);
    343 		list_add_tail(&loc->res_list, &loc->res->binding_head);
    344 	}
    345 }
    346 
    347 /**
    348  * vmw_binding_state_kill - Kill all bindings associated with a
    349  * struct vmw_ctx_binding state structure, and re-initialize the structure.
    350  *
    351  * @cbs: Pointer to the context binding state tracker.
    352  *
    353  * Emits commands to scrub all bindings associated with the
    354  * context binding state tracker. Then re-initializes the whole structure.
    355  */
    356 void vmw_binding_state_kill(struct vmw_ctx_binding_state *cbs)
    357 {
    358 	struct vmw_ctx_bindinfo *entry, *next;
    359 
    360 	vmw_binding_state_scrub(cbs);
    361 	list_for_each_entry_safe(entry, next, &cbs->list, ctx_list)
    362 		vmw_binding_drop(entry);
    363 }
    364 
    365 /**
    366  * vmw_binding_state_scrub - Scrub all bindings associated with a
    367  * struct vmw_ctx_binding state structure.
    368  *
    369  * @cbs: Pointer to the context binding state tracker.
    370  *
    371  * Emits commands to scrub all bindings associated with the
    372  * context binding state tracker.
    373  */
    374 void vmw_binding_state_scrub(struct vmw_ctx_binding_state *cbs)
    375 {
    376 	struct vmw_ctx_bindinfo *entry;
    377 
    378 	list_for_each_entry(entry, &cbs->list, ctx_list) {
    379 		if (!entry->scrubbed) {
    380 			(void) vmw_binding_infos[entry->bt].scrub_func
    381 				(entry, false);
    382 			entry->scrubbed = true;
    383 		}
    384 	}
    385 
    386 	(void) vmw_binding_emit_dirty(cbs);
    387 }
    388 
    389 /**
    390  * vmw_binding_res_list_kill - Kill all bindings on a
    391  * resource binding list
    392  *
    393  * @head: list head of resource binding list
    394  *
    395  * Kills all bindings associated with a specific resource. Typically
    396  * called before the resource is destroyed.
    397  */
    398 void vmw_binding_res_list_kill(struct list_head *head)
    399 {
    400 	struct vmw_ctx_bindinfo *entry, *next;
    401 
    402 	vmw_binding_res_list_scrub(head);
    403 	list_for_each_entry_safe(entry, next, head, res_list)
    404 		vmw_binding_drop(entry);
    405 }
    406 
    407 /**
    408  * vmw_binding_res_list_scrub - Scrub all bindings on a
    409  * resource binding list
    410  *
    411  * @head: list head of resource binding list
    412  *
    413  * Scrub all bindings associated with a specific resource. Typically
    414  * called before the resource is evicted.
    415  */
    416 void vmw_binding_res_list_scrub(struct list_head *head)
    417 {
    418 	struct vmw_ctx_bindinfo *entry;
    419 
    420 	list_for_each_entry(entry, head, res_list) {
    421 		if (!entry->scrubbed) {
    422 			(void) vmw_binding_infos[entry->bt].scrub_func
    423 				(entry, false);
    424 			entry->scrubbed = true;
    425 		}
    426 	}
    427 
    428 	list_for_each_entry(entry, head, res_list) {
    429 		struct vmw_ctx_binding_state *cbs =
    430 			vmw_context_binding_state(entry->ctx);
    431 
    432 		(void) vmw_binding_emit_dirty(cbs);
    433 	}
    434 }
    435 
    436 
    437 /**
    438  * vmw_binding_state_commit - Commit staged binding info
    439  *
    440  * @ctx: Pointer to context to commit the staged binding info to.
    441  * @from: Staged binding info built during execbuf.
    442  * @scrubbed: Transfer only scrubbed bindings.
    443  *
    444  * Transfers binding info from a temporary structure
    445  * (typically used by execbuf) to the persistent
    446  * structure in the context. This can be done once commands have been
    447  * submitted to hardware
    448  */
    449 void vmw_binding_state_commit(struct vmw_ctx_binding_state *to,
    450 			      struct vmw_ctx_binding_state *from)
    451 {
    452 	struct vmw_ctx_bindinfo *entry, *next;
    453 
    454 	list_for_each_entry_safe(entry, next, &from->list, ctx_list) {
    455 		vmw_binding_transfer(to, from, entry);
    456 		vmw_binding_drop(entry);
    457 	}
    458 }
    459 
    460 /**
    461  * vmw_binding_rebind_all - Rebind all scrubbed bindings of a context
    462  *
    463  * @ctx: The context resource
    464  *
    465  * Walks through the context binding list and rebinds all scrubbed
    466  * resources.
    467  */
    468 int vmw_binding_rebind_all(struct vmw_ctx_binding_state *cbs)
    469 {
    470 	struct vmw_ctx_bindinfo *entry;
    471 	int ret;
    472 
    473 	list_for_each_entry(entry, &cbs->list, ctx_list) {
    474 		if (likely(!entry->scrubbed))
    475 			continue;
    476 
    477 		if ((entry->res == NULL || entry->res->id ==
    478 			    SVGA3D_INVALID_ID))
    479 			continue;
    480 
    481 		ret = vmw_binding_infos[entry->bt].scrub_func(entry, true);
    482 		if (unlikely(ret != 0))
    483 			return ret;
    484 
    485 		entry->scrubbed = false;
    486 	}
    487 
    488 	return vmw_binding_emit_dirty(cbs);
    489 }
    490 
    491 /**
    492  * vmw_binding_scrub_shader - scrub a shader binding from a context.
    493  *
    494  * @bi: single binding information.
    495  * @rebind: Whether to issue a bind instead of scrub command.
    496  */
    497 static int vmw_binding_scrub_shader(struct vmw_ctx_bindinfo *bi, bool rebind)
    498 {
    499 	struct vmw_ctx_bindinfo_shader *binding =
    500 		container_of(bi, typeof(*binding), bi);
    501 	struct vmw_private *dev_priv = bi->ctx->dev_priv;
    502 	struct {
    503 		SVGA3dCmdHeader header;
    504 		SVGA3dCmdSetShader body;
    505 	} *cmd;
    506 
    507 	cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
    508 	if (unlikely(cmd == NULL))
    509 		return -ENOMEM;
    510 
    511 	cmd->header.id = SVGA_3D_CMD_SET_SHADER;
    512 	cmd->header.size = sizeof(cmd->body);
    513 	cmd->body.cid = bi->ctx->id;
    514 	cmd->body.type = binding->shader_slot + SVGA3D_SHADERTYPE_MIN;
    515 	cmd->body.shid = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID);
    516 	vmw_fifo_commit(dev_priv, sizeof(*cmd));
    517 
    518 	return 0;
    519 }
    520 
    521 /**
    522  * vmw_binding_scrub_render_target - scrub a render target binding
    523  * from a context.
    524  *
    525  * @bi: single binding information.
    526  * @rebind: Whether to issue a bind instead of scrub command.
    527  */
    528 static int vmw_binding_scrub_render_target(struct vmw_ctx_bindinfo *bi,
    529 					   bool rebind)
    530 {
    531 	struct vmw_ctx_bindinfo_view *binding =
    532 		container_of(bi, typeof(*binding), bi);
    533 	struct vmw_private *dev_priv = bi->ctx->dev_priv;
    534 	struct {
    535 		SVGA3dCmdHeader header;
    536 		SVGA3dCmdSetRenderTarget body;
    537 	} *cmd;
    538 
    539 	cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
    540 	if (unlikely(cmd == NULL))
    541 		return -ENOMEM;
    542 
    543 	cmd->header.id = SVGA_3D_CMD_SETRENDERTARGET;
    544 	cmd->header.size = sizeof(cmd->body);
    545 	cmd->body.cid = bi->ctx->id;
    546 	cmd->body.type = binding->slot;
    547 	cmd->body.target.sid = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID);
    548 	cmd->body.target.face = 0;
    549 	cmd->body.target.mipmap = 0;
    550 	vmw_fifo_commit(dev_priv, sizeof(*cmd));
    551 
    552 	return 0;
    553 }
    554 
    555 /**
    556  * vmw_binding_scrub_texture - scrub a texture binding from a context.
    557  *
    558  * @bi: single binding information.
    559  * @rebind: Whether to issue a bind instead of scrub command.
    560  *
    561  * TODO: Possibly complement this function with a function that takes
    562  * a list of texture bindings and combines them to a single command.
    563  */
    564 static int vmw_binding_scrub_texture(struct vmw_ctx_bindinfo *bi,
    565 				     bool rebind)
    566 {
    567 	struct vmw_ctx_bindinfo_tex *binding =
    568 		container_of(bi, typeof(*binding), bi);
    569 	struct vmw_private *dev_priv = bi->ctx->dev_priv;
    570 	struct {
    571 		SVGA3dCmdHeader header;
    572 		struct {
    573 			SVGA3dCmdSetTextureState c;
    574 			SVGA3dTextureState s1;
    575 		} body;
    576 	} *cmd;
    577 
    578 	cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
    579 	if (unlikely(cmd == NULL))
    580 		return -ENOMEM;
    581 
    582 	cmd->header.id = SVGA_3D_CMD_SETTEXTURESTATE;
    583 	cmd->header.size = sizeof(cmd->body);
    584 	cmd->body.c.cid = bi->ctx->id;
    585 	cmd->body.s1.stage = binding->texture_stage;
    586 	cmd->body.s1.name = SVGA3D_TS_BIND_TEXTURE;
    587 	cmd->body.s1.value = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID);
    588 	vmw_fifo_commit(dev_priv, sizeof(*cmd));
    589 
    590 	return 0;
    591 }
    592 
    593 /**
    594  * vmw_binding_scrub_dx_shader - scrub a dx shader binding from a context.
    595  *
    596  * @bi: single binding information.
    597  * @rebind: Whether to issue a bind instead of scrub command.
    598  */
    599 static int vmw_binding_scrub_dx_shader(struct vmw_ctx_bindinfo *bi, bool rebind)
    600 {
    601 	struct vmw_ctx_bindinfo_shader *binding =
    602 		container_of(bi, typeof(*binding), bi);
    603 	struct vmw_private *dev_priv = bi->ctx->dev_priv;
    604 	struct {
    605 		SVGA3dCmdHeader header;
    606 		SVGA3dCmdDXSetShader body;
    607 	} *cmd;
    608 
    609 	cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id);
    610 	if (unlikely(cmd == NULL))
    611 		return -ENOMEM;
    612 
    613 	cmd->header.id = SVGA_3D_CMD_DX_SET_SHADER;
    614 	cmd->header.size = sizeof(cmd->body);
    615 	cmd->body.type = binding->shader_slot + SVGA3D_SHADERTYPE_MIN;
    616 	cmd->body.shaderId = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID);
    617 	vmw_fifo_commit(dev_priv, sizeof(*cmd));
    618 
    619 	return 0;
    620 }
    621 
    622 /**
    623  * vmw_binding_scrub_cb - scrub a constant buffer binding from a context.
    624  *
    625  * @bi: single binding information.
    626  * @rebind: Whether to issue a bind instead of scrub command.
    627  */
    628 static int vmw_binding_scrub_cb(struct vmw_ctx_bindinfo *bi, bool rebind)
    629 {
    630 	struct vmw_ctx_bindinfo_cb *binding =
    631 		container_of(bi, typeof(*binding), bi);
    632 	struct vmw_private *dev_priv = bi->ctx->dev_priv;
    633 	struct {
    634 		SVGA3dCmdHeader header;
    635 		SVGA3dCmdDXSetSingleConstantBuffer body;
    636 	} *cmd;
    637 
    638 	cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id);
    639 	if (unlikely(cmd == NULL))
    640 		return -ENOMEM;
    641 
    642 	cmd->header.id = SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER;
    643 	cmd->header.size = sizeof(cmd->body);
    644 	cmd->body.slot = binding->slot;
    645 	cmd->body.type = binding->shader_slot + SVGA3D_SHADERTYPE_MIN;
    646 	if (rebind) {
    647 		cmd->body.offsetInBytes = binding->offset;
    648 		cmd->body.sizeInBytes = binding->size;
    649 		cmd->body.sid = bi->res->id;
    650 	} else {
    651 		cmd->body.offsetInBytes = 0;
    652 		cmd->body.sizeInBytes = 0;
    653 		cmd->body.sid = SVGA3D_INVALID_ID;
    654 	}
    655 	vmw_fifo_commit(dev_priv, sizeof(*cmd));
    656 
    657 	return 0;
    658 }
    659 
    660 /**
    661  * vmw_collect_view_ids - Build view id data for a view binding command
    662  * without checking which bindings actually need to be emitted
    663  *
    664  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
    665  * @bi: Pointer to where the binding info array is stored in @cbs
    666  * @max_num: Maximum number of entries in the @bi array.
    667  *
    668  * Scans the @bi array for bindings and builds a buffer of view id data.
    669  * Stops at the first non-existing binding in the @bi array.
    670  * On output, @cbs->bind_cmd_count contains the number of bindings to be
    671  * emitted, @cbs->bind_first_slot is set to zero, and @cbs->bind_cmd_buffer
    672  * contains the command data.
    673  */
    674 static void vmw_collect_view_ids(struct vmw_ctx_binding_state *cbs,
    675 				 const struct vmw_ctx_bindinfo *bi,
    676 				 u32 max_num)
    677 {
    678 	const struct vmw_ctx_bindinfo_view *biv =
    679 		container_of(bi, struct vmw_ctx_bindinfo_view, bi);
    680 	unsigned long i;
    681 
    682 	cbs->bind_cmd_count = 0;
    683 	cbs->bind_first_slot = 0;
    684 
    685 	for (i = 0; i < max_num; ++i, ++biv) {
    686 		if (!biv->bi.ctx)
    687 			break;
    688 
    689 		cbs->bind_cmd_buffer[cbs->bind_cmd_count++] =
    690 			((biv->bi.scrubbed) ?
    691 			 SVGA3D_INVALID_ID : biv->bi.res->id);
    692 	}
    693 }
    694 
    695 /**
    696  * vmw_collect_dirty_view_ids - Build view id data for a view binding command
    697  *
    698  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
    699  * @bi: Pointer to where the binding info array is stored in @cbs
    700  * @dirty: Bitmap indicating which bindings need to be emitted.
    701  * @max_num: Maximum number of entries in the @bi array.
    702  *
    703  * Scans the @bi array for bindings that need to be emitted and
    704  * builds a buffer of view id data.
    705  * On output, @cbs->bind_cmd_count contains the number of bindings to be
    706  * emitted, @cbs->bind_first_slot indicates the index of the first emitted
    707  * binding, and @cbs->bind_cmd_buffer contains the command data.
    708  */
    709 static void vmw_collect_dirty_view_ids(struct vmw_ctx_binding_state *cbs,
    710 				       const struct vmw_ctx_bindinfo *bi,
    711 				       unsigned long *dirty,
    712 				       u32 max_num)
    713 {
    714 	const struct vmw_ctx_bindinfo_view *biv =
    715 		container_of(bi, struct vmw_ctx_bindinfo_view, bi);
    716 	unsigned long i, next_bit;
    717 
    718 	cbs->bind_cmd_count = 0;
    719 	i = find_first_bit(dirty, max_num);
    720 	next_bit = i;
    721 	cbs->bind_first_slot = i;
    722 
    723 	biv += i;
    724 	for (; i < max_num; ++i, ++biv) {
    725 		cbs->bind_cmd_buffer[cbs->bind_cmd_count++] =
    726 			((!biv->bi.ctx || biv->bi.scrubbed) ?
    727 			 SVGA3D_INVALID_ID : biv->bi.res->id);
    728 
    729 		if (next_bit == i) {
    730 			next_bit = find_next_bit(dirty, max_num, i + 1);
    731 			if (next_bit >= max_num)
    732 				break;
    733 		}
    734 	}
    735 }
    736 
    737 /**
    738  * vmw_binding_emit_set_sr - Issue delayed DX shader resource binding commands
    739  *
    740  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
    741  */
    742 static int vmw_emit_set_sr(struct vmw_ctx_binding_state *cbs,
    743 			   int shader_slot)
    744 {
    745 	const struct vmw_ctx_bindinfo *loc =
    746 		&cbs->per_shader[shader_slot].shader_res[0].bi;
    747 	struct {
    748 		SVGA3dCmdHeader header;
    749 		SVGA3dCmdDXSetShaderResources body;
    750 	} *cmd;
    751 	size_t cmd_size, view_id_size;
    752 	const struct vmw_resource *ctx = vmw_cbs_context(cbs);
    753 
    754 	vmw_collect_dirty_view_ids(cbs, loc,
    755 				   cbs->per_shader[shader_slot].dirty_sr,
    756 				   SVGA3D_DX_MAX_SRVIEWS);
    757 	if (cbs->bind_cmd_count == 0)
    758 		return 0;
    759 
    760 	view_id_size = cbs->bind_cmd_count*sizeof(uint32);
    761 	cmd_size = sizeof(*cmd) + view_id_size;
    762 	cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id);
    763 	if (unlikely(cmd == NULL))
    764 		return -ENOMEM;
    765 
    766 	cmd->header.id = SVGA_3D_CMD_DX_SET_SHADER_RESOURCES;
    767 	cmd->header.size = sizeof(cmd->body) + view_id_size;
    768 	cmd->body.type = shader_slot + SVGA3D_SHADERTYPE_MIN;
    769 	cmd->body.startView = cbs->bind_first_slot;
    770 
    771 	memcpy(&cmd[1], cbs->bind_cmd_buffer, view_id_size);
    772 
    773 	vmw_fifo_commit(ctx->dev_priv, cmd_size);
    774 	bitmap_clear(cbs->per_shader[shader_slot].dirty_sr,
    775 		     cbs->bind_first_slot, cbs->bind_cmd_count);
    776 
    777 	return 0;
    778 }
    779 
    780 /**
    781  * vmw_binding_emit_set_rt - Issue delayed DX rendertarget binding commands
    782  *
    783  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
    784  */
    785 static int vmw_emit_set_rt(struct vmw_ctx_binding_state *cbs)
    786 {
    787 	const struct vmw_ctx_bindinfo *loc = &cbs->render_targets[0].bi;
    788 	struct {
    789 		SVGA3dCmdHeader header;
    790 		SVGA3dCmdDXSetRenderTargets body;
    791 	} *cmd;
    792 	size_t cmd_size, view_id_size;
    793 	const struct vmw_resource *ctx = vmw_cbs_context(cbs);
    794 
    795 	vmw_collect_view_ids(cbs, loc, SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS);
    796 	view_id_size = cbs->bind_cmd_count*sizeof(uint32);
    797 	cmd_size = sizeof(*cmd) + view_id_size;
    798 	cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id);
    799 	if (unlikely(cmd == NULL))
    800 		return -ENOMEM;
    801 
    802 	cmd->header.id = SVGA_3D_CMD_DX_SET_RENDERTARGETS;
    803 	cmd->header.size = sizeof(cmd->body) + view_id_size;
    804 
    805 	if (cbs->ds_view.bi.ctx && !cbs->ds_view.bi.scrubbed)
    806 		cmd->body.depthStencilViewId = cbs->ds_view.bi.res->id;
    807 	else
    808 		cmd->body.depthStencilViewId = SVGA3D_INVALID_ID;
    809 
    810 	memcpy(&cmd[1], cbs->bind_cmd_buffer, view_id_size);
    811 
    812 	vmw_fifo_commit(ctx->dev_priv, cmd_size);
    813 
    814 	return 0;
    815 
    816 }
    817 
    818 /**
    819  * vmw_collect_so_targets - Build SVGA3dSoTarget data for a binding command
    820  * without checking which bindings actually need to be emitted
    821  *
    822  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
    823  * @bi: Pointer to where the binding info array is stored in @cbs
    824  * @max_num: Maximum number of entries in the @bi array.
    825  *
    826  * Scans the @bi array for bindings and builds a buffer of SVGA3dSoTarget data.
    827  * Stops at the first non-existing binding in the @bi array.
    828  * On output, @cbs->bind_cmd_count contains the number of bindings to be
    829  * emitted, @cbs->bind_first_slot is set to zero, and @cbs->bind_cmd_buffer
    830  * contains the command data.
    831  */
    832 static void vmw_collect_so_targets(struct vmw_ctx_binding_state *cbs,
    833 				   const struct vmw_ctx_bindinfo *bi,
    834 				   u32 max_num)
    835 {
    836 	const struct vmw_ctx_bindinfo_so *biso =
    837 		container_of(bi, struct vmw_ctx_bindinfo_so, bi);
    838 	unsigned long i;
    839 	SVGA3dSoTarget *so_buffer = (SVGA3dSoTarget *) cbs->bind_cmd_buffer;
    840 
    841 	cbs->bind_cmd_count = 0;
    842 	cbs->bind_first_slot = 0;
    843 
    844 	for (i = 0; i < max_num; ++i, ++biso, ++so_buffer,
    845 		    ++cbs->bind_cmd_count) {
    846 		if (!biso->bi.ctx)
    847 			break;
    848 
    849 		if (!biso->bi.scrubbed) {
    850 			so_buffer->sid = biso->bi.res->id;
    851 			so_buffer->offset = biso->offset;
    852 			so_buffer->sizeInBytes = biso->size;
    853 		} else {
    854 			so_buffer->sid = SVGA3D_INVALID_ID;
    855 			so_buffer->offset = 0;
    856 			so_buffer->sizeInBytes = 0;
    857 		}
    858 	}
    859 }
    860 
    861 /**
    862  * vmw_binding_emit_set_so - Issue delayed streamout binding commands
    863  *
    864  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
    865  */
    866 static int vmw_emit_set_so(struct vmw_ctx_binding_state *cbs)
    867 {
    868 	const struct vmw_ctx_bindinfo *loc = &cbs->so_targets[0].bi;
    869 	struct {
    870 		SVGA3dCmdHeader header;
    871 		SVGA3dCmdDXSetSOTargets body;
    872 	} *cmd;
    873 	size_t cmd_size, so_target_size;
    874 	const struct vmw_resource *ctx = vmw_cbs_context(cbs);
    875 
    876 	vmw_collect_so_targets(cbs, loc, SVGA3D_DX_MAX_SOTARGETS);
    877 	if (cbs->bind_cmd_count == 0)
    878 		return 0;
    879 
    880 	so_target_size = cbs->bind_cmd_count*sizeof(SVGA3dSoTarget);
    881 	cmd_size = sizeof(*cmd) + so_target_size;
    882 	cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id);
    883 	if (unlikely(cmd == NULL))
    884 		return -ENOMEM;
    885 
    886 	cmd->header.id = SVGA_3D_CMD_DX_SET_SOTARGETS;
    887 	cmd->header.size = sizeof(cmd->body) + so_target_size;
    888 	memcpy(&cmd[1], cbs->bind_cmd_buffer, so_target_size);
    889 
    890 	vmw_fifo_commit(ctx->dev_priv, cmd_size);
    891 
    892 	return 0;
    893 
    894 }
    895 
    896 /**
    897  * vmw_binding_emit_dirty_ps - Issue delayed per shader binding commands
    898  *
    899  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
    900  *
    901  */
    902 static int vmw_binding_emit_dirty_ps(struct vmw_ctx_binding_state *cbs)
    903 {
    904 	struct vmw_dx_shader_bindings *sb = &cbs->per_shader[0];
    905 	u32 i;
    906 	int ret;
    907 
    908 	for (i = 0; i < SVGA3D_NUM_SHADERTYPE_DX10; ++i, ++sb) {
    909 		if (!test_bit(VMW_BINDING_PS_SR_BIT, &sb->dirty))
    910 			continue;
    911 
    912 		ret = vmw_emit_set_sr(cbs, i);
    913 		if (ret)
    914 			break;
    915 
    916 		__clear_bit(VMW_BINDING_PS_SR_BIT, &sb->dirty);
    917 	}
    918 
    919 	return 0;
    920 }
    921 
    922 /**
    923  * vmw_collect_dirty_vbs - Build SVGA3dVertexBuffer data for a
    924  * SVGA3dCmdDXSetVertexBuffers command
    925  *
    926  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
    927  * @bi: Pointer to where the binding info array is stored in @cbs
    928  * @dirty: Bitmap indicating which bindings need to be emitted.
    929  * @max_num: Maximum number of entries in the @bi array.
    930  *
    931  * Scans the @bi array for bindings that need to be emitted and
    932  * builds a buffer of SVGA3dVertexBuffer data.
    933  * On output, @cbs->bind_cmd_count contains the number of bindings to be
    934  * emitted, @cbs->bind_first_slot indicates the index of the first emitted
    935  * binding, and @cbs->bind_cmd_buffer contains the command data.
    936  */
    937 static void vmw_collect_dirty_vbs(struct vmw_ctx_binding_state *cbs,
    938 				  const struct vmw_ctx_bindinfo *bi,
    939 				  unsigned long *dirty,
    940 				  u32 max_num)
    941 {
    942 	const struct vmw_ctx_bindinfo_vb *biv =
    943 		container_of(bi, struct vmw_ctx_bindinfo_vb, bi);
    944 	unsigned long i, next_bit;
    945 	SVGA3dVertexBuffer *vbs = (SVGA3dVertexBuffer *) &cbs->bind_cmd_buffer;
    946 
    947 	cbs->bind_cmd_count = 0;
    948 	i = find_first_bit(dirty, max_num);
    949 	next_bit = i;
    950 	cbs->bind_first_slot = i;
    951 
    952 	biv += i;
    953 	for (; i < max_num; ++i, ++biv, ++vbs) {
    954 		if (!biv->bi.ctx || biv->bi.scrubbed) {
    955 			vbs->sid = SVGA3D_INVALID_ID;
    956 			vbs->stride = 0;
    957 			vbs->offset = 0;
    958 		} else {
    959 			vbs->sid = biv->bi.res->id;
    960 			vbs->stride = biv->stride;
    961 			vbs->offset = biv->offset;
    962 		}
    963 		cbs->bind_cmd_count++;
    964 		if (next_bit == i) {
    965 			next_bit = find_next_bit(dirty, max_num, i + 1);
    966 			if (next_bit >= max_num)
    967 				break;
    968 		}
    969 	}
    970 }
    971 
    972 /**
    973  * vmw_binding_emit_set_vb - Issue delayed vertex buffer binding commands
    974  *
    975  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
    976  *
    977  */
    978 static int vmw_emit_set_vb(struct vmw_ctx_binding_state *cbs)
    979 {
    980 	const struct vmw_ctx_bindinfo *loc =
    981 		&cbs->vertex_buffers[0].bi;
    982 	struct {
    983 		SVGA3dCmdHeader header;
    984 		SVGA3dCmdDXSetVertexBuffers body;
    985 	} *cmd;
    986 	size_t cmd_size, set_vb_size;
    987 	const struct vmw_resource *ctx = vmw_cbs_context(cbs);
    988 
    989 	vmw_collect_dirty_vbs(cbs, loc, cbs->dirty_vb,
    990 			     SVGA3D_DX_MAX_VERTEXBUFFERS);
    991 	if (cbs->bind_cmd_count == 0)
    992 		return 0;
    993 
    994 	set_vb_size = cbs->bind_cmd_count*sizeof(SVGA3dVertexBuffer);
    995 	cmd_size = sizeof(*cmd) + set_vb_size;
    996 	cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id);
    997 	if (unlikely(cmd == NULL))
    998 		return -ENOMEM;
    999 
   1000 	cmd->header.id = SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS;
   1001 	cmd->header.size = sizeof(cmd->body) + set_vb_size;
   1002 	cmd->body.startBuffer = cbs->bind_first_slot;
   1003 
   1004 	memcpy(&cmd[1], cbs->bind_cmd_buffer, set_vb_size);
   1005 
   1006 	vmw_fifo_commit(ctx->dev_priv, cmd_size);
   1007 	bitmap_clear(cbs->dirty_vb,
   1008 		     cbs->bind_first_slot, cbs->bind_cmd_count);
   1009 
   1010 	return 0;
   1011 }
   1012 
   1013 /**
   1014  * vmw_binding_emit_dirty - Issue delayed binding commands
   1015  *
   1016  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
   1017  *
   1018  * This function issues the delayed binding commands that arise from
   1019  * previous scrub / unscrub calls. These binding commands are typically
   1020  * commands that batch a number of bindings and therefore it makes sense
   1021  * to delay them.
   1022  */
   1023 static int vmw_binding_emit_dirty(struct vmw_ctx_binding_state *cbs)
   1024 {
   1025 	int ret = 0;
   1026 	unsigned long hit = 0;
   1027 
   1028 	while ((hit = find_next_bit(&cbs->dirty, VMW_BINDING_NUM_BITS, hit))
   1029 	      < VMW_BINDING_NUM_BITS) {
   1030 
   1031 		switch (hit) {
   1032 		case VMW_BINDING_RT_BIT:
   1033 			ret = vmw_emit_set_rt(cbs);
   1034 			break;
   1035 		case VMW_BINDING_PS_BIT:
   1036 			ret = vmw_binding_emit_dirty_ps(cbs);
   1037 			break;
   1038 		case VMW_BINDING_SO_BIT:
   1039 			ret = vmw_emit_set_so(cbs);
   1040 			break;
   1041 		case VMW_BINDING_VB_BIT:
   1042 			ret = vmw_emit_set_vb(cbs);
   1043 			break;
   1044 		default:
   1045 			BUG();
   1046 		}
   1047 		if (ret)
   1048 			return ret;
   1049 
   1050 		__clear_bit(hit, &cbs->dirty);
   1051 		hit++;
   1052 	}
   1053 
   1054 	return 0;
   1055 }
   1056 
   1057 /**
   1058  * vmw_binding_scrub_sr - Schedule a dx shaderresource binding
   1059  * scrub from a context
   1060  *
   1061  * @bi: single binding information.
   1062  * @rebind: Whether to issue a bind instead of scrub command.
   1063  */
   1064 static int vmw_binding_scrub_sr(struct vmw_ctx_bindinfo *bi, bool rebind)
   1065 {
   1066 	struct vmw_ctx_bindinfo_view *biv =
   1067 		container_of(bi, struct vmw_ctx_bindinfo_view, bi);
   1068 	struct vmw_ctx_binding_state *cbs =
   1069 		vmw_context_binding_state(bi->ctx);
   1070 
   1071 	__set_bit(biv->slot, cbs->per_shader[biv->shader_slot].dirty_sr);
   1072 	__set_bit(VMW_BINDING_PS_SR_BIT,
   1073 		  &cbs->per_shader[biv->shader_slot].dirty);
   1074 	__set_bit(VMW_BINDING_PS_BIT, &cbs->dirty);
   1075 
   1076 	return 0;
   1077 }
   1078 
   1079 /**
   1080  * vmw_binding_scrub_dx_rt - Schedule a dx rendertarget binding
   1081  * scrub from a context
   1082  *
   1083  * @bi: single binding information.
   1084  * @rebind: Whether to issue a bind instead of scrub command.
   1085  */
   1086 static int vmw_binding_scrub_dx_rt(struct vmw_ctx_bindinfo *bi, bool rebind)
   1087 {
   1088 	struct vmw_ctx_binding_state *cbs =
   1089 		vmw_context_binding_state(bi->ctx);
   1090 
   1091 	__set_bit(VMW_BINDING_RT_BIT, &cbs->dirty);
   1092 
   1093 	return 0;
   1094 }
   1095 
   1096 /**
   1097  * vmw_binding_scrub_so - Schedule a dx streamoutput buffer binding
   1098  * scrub from a context
   1099  *
   1100  * @bi: single binding information.
   1101  * @rebind: Whether to issue a bind instead of scrub command.
   1102  */
   1103 static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind)
   1104 {
   1105 	struct vmw_ctx_binding_state *cbs =
   1106 		vmw_context_binding_state(bi->ctx);
   1107 
   1108 	__set_bit(VMW_BINDING_SO_BIT, &cbs->dirty);
   1109 
   1110 	return 0;
   1111 }
   1112 
   1113 /**
   1114  * vmw_binding_scrub_vb - Schedule a dx vertex buffer binding
   1115  * scrub from a context
   1116  *
   1117  * @bi: single binding information.
   1118  * @rebind: Whether to issue a bind instead of scrub command.
   1119  */
   1120 static int vmw_binding_scrub_vb(struct vmw_ctx_bindinfo *bi, bool rebind)
   1121 {
   1122 	struct vmw_ctx_bindinfo_vb *bivb =
   1123 		container_of(bi, struct vmw_ctx_bindinfo_vb, bi);
   1124 	struct vmw_ctx_binding_state *cbs =
   1125 		vmw_context_binding_state(bi->ctx);
   1126 
   1127 	__set_bit(bivb->slot, cbs->dirty_vb);
   1128 	__set_bit(VMW_BINDING_VB_BIT, &cbs->dirty);
   1129 
   1130 	return 0;
   1131 }
   1132 
   1133 /**
   1134  * vmw_binding_scrub_ib - scrub a dx index buffer binding from a context
   1135  *
   1136  * @bi: single binding information.
   1137  * @rebind: Whether to issue a bind instead of scrub command.
   1138  */
   1139 static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo *bi, bool rebind)
   1140 {
   1141 	struct vmw_ctx_bindinfo_ib *binding =
   1142 		container_of(bi, typeof(*binding), bi);
   1143 	struct vmw_private *dev_priv = bi->ctx->dev_priv;
   1144 	struct {
   1145 		SVGA3dCmdHeader header;
   1146 		SVGA3dCmdDXSetIndexBuffer body;
   1147 	} *cmd;
   1148 
   1149 	cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id);
   1150 	if (unlikely(cmd == NULL))
   1151 		return -ENOMEM;
   1152 
   1153 	cmd->header.id = SVGA_3D_CMD_DX_SET_INDEX_BUFFER;
   1154 	cmd->header.size = sizeof(cmd->body);
   1155 	if (rebind) {
   1156 		cmd->body.sid = bi->res->id;
   1157 		cmd->body.format = binding->format;
   1158 		cmd->body.offset = binding->offset;
   1159 	} else {
   1160 		cmd->body.sid = SVGA3D_INVALID_ID;
   1161 		cmd->body.format = 0;
   1162 		cmd->body.offset = 0;
   1163 	}
   1164 
   1165 	vmw_fifo_commit(dev_priv, sizeof(*cmd));
   1166 
   1167 	return 0;
   1168 }
   1169 
   1170 /**
   1171  * vmw_binding_state_alloc - Allocate a struct vmw_ctx_binding_state with
   1172  * memory accounting.
   1173  *
   1174  * @dev_priv: Pointer to a device private structure.
   1175  *
   1176  * Returns a pointer to a newly allocated struct or an error pointer on error.
   1177  */
   1178 struct vmw_ctx_binding_state *
   1179 vmw_binding_state_alloc(struct vmw_private *dev_priv)
   1180 {
   1181 	struct vmw_ctx_binding_state *cbs;
   1182 	struct ttm_operation_ctx ctx = {
   1183 		.interruptible = false,
   1184 		.no_wait_gpu = false
   1185 	};
   1186 	int ret;
   1187 
   1188 	ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), sizeof(*cbs),
   1189 				&ctx);
   1190 	if (ret)
   1191 		return ERR_PTR(ret);
   1192 
   1193 	cbs = vzalloc(sizeof(*cbs));
   1194 	if (!cbs) {
   1195 		ttm_mem_global_free(vmw_mem_glob(dev_priv), sizeof(*cbs));
   1196 		return ERR_PTR(-ENOMEM);
   1197 	}
   1198 
   1199 	cbs->dev_priv = dev_priv;
   1200 	INIT_LIST_HEAD(&cbs->list);
   1201 
   1202 	return cbs;
   1203 }
   1204 
   1205 /**
   1206  * vmw_binding_state_free - Free a struct vmw_ctx_binding_state and its
   1207  * memory accounting info.
   1208  *
   1209  * @cbs: Pointer to the struct vmw_ctx_binding_state to be freed.
   1210  */
   1211 void vmw_binding_state_free(struct vmw_ctx_binding_state *cbs)
   1212 {
   1213 	struct vmw_private *dev_priv = cbs->dev_priv;
   1214 
   1215 	vfree(cbs);
   1216 	ttm_mem_global_free(vmw_mem_glob(dev_priv), sizeof(*cbs));
   1217 }
   1218 
   1219 /**
   1220  * vmw_binding_state_list - Get the binding list of a
   1221  * struct vmw_ctx_binding_state
   1222  *
   1223  * @cbs: Pointer to the struct vmw_ctx_binding_state
   1224  *
   1225  * Returns the binding list which can be used to traverse through the bindings
   1226  * and access the resource information of all bindings.
   1227  */
   1228 struct list_head *vmw_binding_state_list(struct vmw_ctx_binding_state *cbs)
   1229 {
   1230 	return &cbs->list;
   1231 }
   1232 
   1233 /**
   1234  * vmwgfx_binding_state_reset - clear a struct vmw_ctx_binding_state
   1235  *
   1236  * @cbs: Pointer to the struct vmw_ctx_binding_state to be cleared
   1237  *
   1238  * Drops all bindings registered in @cbs. No device binding actions are
   1239  * performed.
   1240  */
   1241 void vmw_binding_state_reset(struct vmw_ctx_binding_state *cbs)
   1242 {
   1243 	struct vmw_ctx_bindinfo *entry, *next;
   1244 
   1245 	list_for_each_entry_safe(entry, next, &cbs->list, ctx_list)
   1246 		vmw_binding_drop(entry);
   1247 }
   1248 
   1249 /**
   1250  * vmw_binding_dirtying - Return whether a binding type is dirtying its resource
   1251  * @binding_type: The binding type
   1252  *
   1253  * Each time a resource is put on the validation list as the result of a
   1254  * context binding referencing it, we need to determine whether that resource
   1255  * will be dirtied (written to by the GPU) as a result of the corresponding
   1256  * GPU operation. Currently rendertarget-, depth-stencil-, and
   1257  * stream-output-target bindings are capable of dirtying its resource.
   1258  *
   1259  * Return: Whether the binding type dirties the resource its binding points to.
   1260  */
   1261 u32 vmw_binding_dirtying(enum vmw_ctx_binding_type binding_type)
   1262 {
   1263 	static u32 is_binding_dirtying[vmw_ctx_binding_max] = {
   1264 		[vmw_ctx_binding_rt] = VMW_RES_DIRTY_SET,
   1265 		[vmw_ctx_binding_dx_rt] = VMW_RES_DIRTY_SET,
   1266 		[vmw_ctx_binding_ds] = VMW_RES_DIRTY_SET,
   1267 		[vmw_ctx_binding_so] = VMW_RES_DIRTY_SET,
   1268 	};
   1269 
   1270 	/* Review this function as new bindings are added. */
   1271 	BUILD_BUG_ON(vmw_ctx_binding_max != 11);
   1272 	return is_binding_dirtying[binding_type];
   1273 }
   1274 
   1275 /*
   1276  * This function is unused at run-time, and only used to hold various build
   1277  * asserts important for code optimization assumptions.
   1278  */
   1279 static void vmw_binding_build_asserts(void)
   1280 {
   1281 	BUILD_BUG_ON(SVGA3D_NUM_SHADERTYPE_DX10 != 3);
   1282 	BUILD_BUG_ON(SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS > SVGA3D_RT_MAX);
   1283 	BUILD_BUG_ON(sizeof(uint32) != sizeof(u32));
   1284 
   1285 	/*
   1286 	 * struct vmw_ctx_binding_state::bind_cmd_buffer is used for various
   1287 	 * view id arrays.
   1288 	 */
   1289 	BUILD_BUG_ON(VMW_MAX_VIEW_BINDINGS < SVGA3D_RT_MAX);
   1290 	BUILD_BUG_ON(VMW_MAX_VIEW_BINDINGS < SVGA3D_DX_MAX_SRVIEWS);
   1291 	BUILD_BUG_ON(VMW_MAX_VIEW_BINDINGS < SVGA3D_DX_MAX_CONSTBUFFERS);
   1292 
   1293 	/*
   1294 	 * struct vmw_ctx_binding_state::bind_cmd_buffer is used for
   1295 	 * u32 view ids, SVGA3dSoTargets and SVGA3dVertexBuffers
   1296 	 */
   1297 	BUILD_BUG_ON(SVGA3D_DX_MAX_SOTARGETS*sizeof(SVGA3dSoTarget) >
   1298 		     VMW_MAX_VIEW_BINDINGS*sizeof(u32));
   1299 	BUILD_BUG_ON(SVGA3D_DX_MAX_VERTEXBUFFERS*sizeof(SVGA3dVertexBuffer) >
   1300 		     VMW_MAX_VIEW_BINDINGS*sizeof(u32));
   1301 }
   1302