1 | // SPDX-License-Identifier: GPL-2.0 OR MIT |
2 | /************************************************************************** |
3 | * Copyright 2014-2015 VMware, Inc., Palo Alto, CA., USA |
4 | * |
5 | * Permission is hereby granted, free of charge, to any person obtaining a |
6 | * copy of this software and associated documentation files (the |
7 | * "Software"), to deal in the Software without restriction, including |
8 | * without limitation the rights to use, copy, modify, merge, publish, |
9 | * distribute, sub license, and/or sell copies of the Software, and to |
10 | * permit persons to whom the Software is furnished to do so, subject to |
11 | * the following conditions: |
12 | * |
13 | * The above copyright notice and this permission notice (including the |
14 | * next paragraph) shall be included in all copies or substantial portions |
15 | * of the Software. |
16 | * |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL |
20 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, |
21 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
22 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
23 | * USE OR OTHER DEALINGS IN THE SOFTWARE. |
24 | * |
25 | **************************************************************************/ |
26 | |
27 | #include "vmwgfx_bo.h" |
28 | #include "vmwgfx_drv.h" |
29 | #include "vmwgfx_resource_priv.h" |
30 | #include "vmwgfx_so.h" |
31 | #include "vmwgfx_binding.h" |
32 | |
33 | /* |
34 | * The currently only reason we need to keep track of views is that if we |
35 | * destroy a hardware surface, all views pointing to it must also be destroyed, |
36 | * otherwise the device will error. |
37 | * So in particular if a surface is evicted, we must destroy all views pointing |
38 | * to it, and all context bindings of that view. Similarly we must restore |
39 | * the view bindings, views and surfaces pointed to by the views when a |
40 | * context is referenced in the command stream. |
41 | */ |
42 | |
43 | /** |
44 | * struct vmw_view - view metadata |
45 | * |
46 | * @rcu: RCU callback head |
47 | * @res: The struct vmw_resource we derive from |
48 | * @ctx: Non-refcounted pointer to the context this view belongs to. |
49 | * @srf: Refcounted pointer to the surface pointed to by this view. |
50 | * @cotable: Refcounted pointer to the cotable holding this view. |
51 | * @srf_head: List head for the surface-to-view list. |
52 | * @cotable_head: List head for the cotable-to_view list. |
53 | * @view_type: View type. |
54 | * @view_id: User-space per context view id. Currently used also as per |
55 | * context device view id. |
56 | * @cmd_size: Size of the SVGA3D define view command that we've copied from the |
57 | * command stream. |
58 | * @committed: Whether the view is actually created or pending creation at the |
59 | * device level. |
60 | * @cmd: The SVGA3D define view command copied from the command stream. |
61 | */ |
62 | struct vmw_view { |
63 | struct rcu_head rcu; |
64 | struct vmw_resource res; |
65 | struct vmw_resource *ctx; /* Immutable */ |
66 | struct vmw_resource *srf; /* Immutable */ |
67 | struct vmw_resource *cotable; /* Immutable */ |
68 | struct list_head srf_head; /* Protected by binding_mutex */ |
69 | struct list_head cotable_head; /* Protected by binding_mutex */ |
70 | unsigned view_type; /* Immutable */ |
71 | unsigned view_id; /* Immutable */ |
72 | u32 cmd_size; /* Immutable */ |
73 | bool committed; /* Protected by binding_mutex */ |
74 | u32 cmd[]; /* Immutable */ |
75 | }; |
76 | |
77 | static int vmw_view_create(struct vmw_resource *res); |
78 | static int vmw_view_destroy(struct vmw_resource *res); |
79 | static void vmw_hw_view_destroy(struct vmw_resource *res); |
80 | static void vmw_view_commit_notify(struct vmw_resource *res, |
81 | enum vmw_cmdbuf_res_state state); |
82 | |
83 | static const struct vmw_res_func vmw_view_func = { |
84 | .res_type = vmw_res_view, |
85 | .needs_guest_memory = false, |
86 | .may_evict = false, |
87 | .type_name = "DX view" , |
88 | .domain = VMW_BO_DOMAIN_SYS, |
89 | .busy_domain = VMW_BO_DOMAIN_SYS, |
90 | .create = vmw_view_create, |
91 | .commit_notify = vmw_view_commit_notify, |
92 | }; |
93 | |
94 | /** |
95 | * struct vmw_view_define - view define command body stub |
96 | * |
97 | * @view_id: The device id of the view being defined |
98 | * @sid: The surface id of the view being defined |
99 | * |
100 | * This generic struct is used by the code to change @view_id and @sid of a |
101 | * saved view define command. |
102 | */ |
103 | struct vmw_view_define { |
104 | uint32 view_id; |
105 | uint32 sid; |
106 | }; |
107 | |
108 | /** |
109 | * vmw_view - Convert a struct vmw_resource to a struct vmw_view |
110 | * |
111 | * @res: Pointer to the resource to convert. |
112 | * |
113 | * Returns a pointer to a struct vmw_view. |
114 | */ |
115 | static struct vmw_view *vmw_view(struct vmw_resource *res) |
116 | { |
117 | return container_of(res, struct vmw_view, res); |
118 | } |
119 | |
120 | /** |
121 | * vmw_view_commit_notify - Notify that a view operation has been committed to |
122 | * hardware from a user-supplied command stream. |
123 | * |
124 | * @res: Pointer to the view resource. |
125 | * @state: Indicating whether a creation or removal has been committed. |
126 | * |
127 | */ |
128 | static void vmw_view_commit_notify(struct vmw_resource *res, |
129 | enum vmw_cmdbuf_res_state state) |
130 | { |
131 | struct vmw_view *view = vmw_view(res); |
132 | struct vmw_private *dev_priv = res->dev_priv; |
133 | |
134 | mutex_lock(&dev_priv->binding_mutex); |
135 | if (state == VMW_CMDBUF_RES_ADD) { |
136 | struct vmw_surface *srf = vmw_res_to_srf(res: view->srf); |
137 | |
138 | list_add_tail(new: &view->srf_head, head: &srf->view_list); |
139 | vmw_cotable_add_resource(ctx: view->cotable, head: &view->cotable_head); |
140 | view->committed = true; |
141 | res->id = view->view_id; |
142 | |
143 | } else { |
144 | list_del_init(entry: &view->cotable_head); |
145 | list_del_init(entry: &view->srf_head); |
146 | view->committed = false; |
147 | res->id = -1; |
148 | } |
149 | mutex_unlock(lock: &dev_priv->binding_mutex); |
150 | } |
151 | |
152 | /** |
153 | * vmw_view_create - Create a hardware view. |
154 | * |
155 | * @res: Pointer to the view resource. |
156 | * |
157 | * Create a hardware view. Typically used if that view has previously been |
158 | * destroyed by an eviction operation. |
159 | */ |
160 | static int vmw_view_create(struct vmw_resource *res) |
161 | { |
162 | struct vmw_view *view = vmw_view(res); |
163 | struct vmw_surface *srf = vmw_res_to_srf(res: view->srf); |
164 | struct vmw_private *dev_priv = res->dev_priv; |
165 | struct { |
166 | SVGA3dCmdHeader ; |
167 | struct vmw_view_define body; |
168 | } *cmd; |
169 | |
170 | mutex_lock(&dev_priv->binding_mutex); |
171 | if (!view->committed) { |
172 | mutex_unlock(lock: &dev_priv->binding_mutex); |
173 | return 0; |
174 | } |
175 | |
176 | cmd = VMW_CMD_CTX_RESERVE(res->dev_priv, view->cmd_size, view->ctx->id); |
177 | if (!cmd) { |
178 | mutex_unlock(lock: &dev_priv->binding_mutex); |
179 | return -ENOMEM; |
180 | } |
181 | |
182 | memcpy(cmd, &view->cmd, view->cmd_size); |
183 | WARN_ON(cmd->body.view_id != view->view_id); |
184 | /* Sid may have changed due to surface eviction. */ |
185 | WARN_ON(view->srf->id == SVGA3D_INVALID_ID); |
186 | cmd->body.sid = view->srf->id; |
187 | vmw_cmd_commit(dev_priv: res->dev_priv, bytes: view->cmd_size); |
188 | res->id = view->view_id; |
189 | list_add_tail(new: &view->srf_head, head: &srf->view_list); |
190 | vmw_cotable_add_resource(ctx: view->cotable, head: &view->cotable_head); |
191 | mutex_unlock(lock: &dev_priv->binding_mutex); |
192 | |
193 | return 0; |
194 | } |
195 | |
196 | /** |
197 | * vmw_view_destroy - Destroy a hardware view. |
198 | * |
199 | * @res: Pointer to the view resource. |
200 | * |
201 | * Destroy a hardware view. Typically used on unexpected termination of the |
202 | * owning process or if the surface the view is pointing to is destroyed. |
203 | */ |
204 | static int vmw_view_destroy(struct vmw_resource *res) |
205 | { |
206 | struct vmw_private *dev_priv = res->dev_priv; |
207 | struct vmw_view *view = vmw_view(res); |
208 | struct { |
209 | SVGA3dCmdHeader ; |
210 | union vmw_view_destroy body; |
211 | } *cmd; |
212 | |
213 | lockdep_assert_held_once(&dev_priv->binding_mutex); |
214 | vmw_binding_res_list_scrub(head: &res->binding_head); |
215 | |
216 | if (!view->committed || res->id == -1) |
217 | return 0; |
218 | |
219 | cmd = VMW_CMD_CTX_RESERVE(dev_priv, sizeof(*cmd), view->ctx->id); |
220 | if (!cmd) |
221 | return -ENOMEM; |
222 | |
223 | cmd->header.id = vmw_view_destroy_cmds[view->view_type]; |
224 | cmd->header.size = sizeof(cmd->body); |
225 | cmd->body.view_id = view->view_id; |
226 | vmw_cmd_commit(dev_priv, bytes: sizeof(*cmd)); |
227 | res->id = -1; |
228 | list_del_init(entry: &view->cotable_head); |
229 | list_del_init(entry: &view->srf_head); |
230 | |
231 | return 0; |
232 | } |
233 | |
234 | /** |
235 | * vmw_hw_view_destroy - Destroy a hardware view as part of resource cleanup. |
236 | * |
237 | * @res: Pointer to the view resource. |
238 | * |
239 | * Destroy a hardware view if it's still present. |
240 | */ |
241 | static void vmw_hw_view_destroy(struct vmw_resource *res) |
242 | { |
243 | struct vmw_private *dev_priv = res->dev_priv; |
244 | |
245 | mutex_lock(&dev_priv->binding_mutex); |
246 | WARN_ON(vmw_view_destroy(res)); |
247 | res->id = -1; |
248 | mutex_unlock(lock: &dev_priv->binding_mutex); |
249 | } |
250 | |
251 | /** |
252 | * vmw_view_key - Compute a view key suitable for the cmdbuf resource manager |
253 | * |
254 | * @user_key: The user-space id used for the view. |
255 | * @view_type: The view type. |
256 | * |
257 | * Destroy a hardware view if it's still present. |
258 | */ |
259 | static u32 vmw_view_key(u32 user_key, enum vmw_view_type view_type) |
260 | { |
261 | return user_key | (view_type << 20); |
262 | } |
263 | |
264 | /** |
265 | * vmw_view_id_ok - Basic view id and type range checks. |
266 | * |
267 | * @user_key: The user-space id used for the view. |
268 | * @view_type: The view type. |
269 | * |
270 | * Checks that the view id and type (typically provided by user-space) is |
271 | * valid. |
272 | */ |
273 | static bool vmw_view_id_ok(u32 user_key, enum vmw_view_type view_type) |
274 | { |
275 | return (user_key < SVGA_COTABLE_MAX_IDS && |
276 | view_type < vmw_view_max); |
277 | } |
278 | |
279 | /** |
280 | * vmw_view_res_free - resource res_free callback for view resources |
281 | * |
282 | * @res: Pointer to a struct vmw_resource |
283 | * |
284 | * Frees memory held by the struct vmw_view. |
285 | */ |
286 | static void vmw_view_res_free(struct vmw_resource *res) |
287 | { |
288 | struct vmw_view *view = vmw_view(res); |
289 | |
290 | vmw_resource_unreference(p_res: &view->cotable); |
291 | vmw_resource_unreference(p_res: &view->srf); |
292 | kfree_rcu(view, rcu); |
293 | } |
294 | |
295 | /** |
296 | * vmw_view_add - Create a view resource and stage it for addition |
297 | * as a command buffer managed resource. |
298 | * |
299 | * @man: Pointer to the compat shader manager identifying the shader namespace. |
300 | * @ctx: Pointer to a struct vmw_resource identifying the active context. |
301 | * @srf: Pointer to a struct vmw_resource identifying the surface the view |
302 | * points to. |
303 | * @view_type: The view type deduced from the view create command. |
304 | * @user_key: The key that is used to identify the shader. The key is |
305 | * unique to the view type and to the context. |
306 | * @cmd: Pointer to the view create command in the command stream. |
307 | * @cmd_size: Size of the view create command in the command stream. |
308 | * @list: Caller's list of staged command buffer resource actions. |
309 | */ |
310 | int vmw_view_add(struct vmw_cmdbuf_res_manager *man, |
311 | struct vmw_resource *ctx, |
312 | struct vmw_resource *srf, |
313 | enum vmw_view_type view_type, |
314 | u32 user_key, |
315 | const void *cmd, |
316 | size_t cmd_size, |
317 | struct list_head *list) |
318 | { |
319 | static const size_t vmw_view_define_sizes[] = { |
320 | [vmw_view_sr] = sizeof(SVGA3dCmdDXDefineShaderResourceView), |
321 | [vmw_view_rt] = sizeof(SVGA3dCmdDXDefineRenderTargetView), |
322 | [vmw_view_ds] = sizeof(SVGA3dCmdDXDefineDepthStencilView), |
323 | [vmw_view_ua] = sizeof(SVGA3dCmdDXDefineUAView) |
324 | }; |
325 | |
326 | struct vmw_private *dev_priv = ctx->dev_priv; |
327 | struct vmw_resource *res; |
328 | struct vmw_view *view; |
329 | size_t size; |
330 | int ret; |
331 | |
332 | if (cmd_size != vmw_view_define_sizes[view_type] + |
333 | sizeof(SVGA3dCmdHeader)) { |
334 | VMW_DEBUG_USER("Illegal view create command size.\n" ); |
335 | return -EINVAL; |
336 | } |
337 | |
338 | if (!vmw_view_id_ok(user_key, view_type)) { |
339 | VMW_DEBUG_USER("Illegal view add view id.\n" ); |
340 | return -EINVAL; |
341 | } |
342 | |
343 | size = offsetof(struct vmw_view, cmd) + cmd_size; |
344 | |
345 | view = kmalloc(size, GFP_KERNEL); |
346 | if (!view) { |
347 | return -ENOMEM; |
348 | } |
349 | |
350 | res = &view->res; |
351 | view->ctx = ctx; |
352 | view->srf = vmw_resource_reference(res: srf); |
353 | view->cotable = vmw_resource_reference |
354 | (res: vmw_context_cotable(ctx, cotable_type: vmw_view_cotables[view_type])); |
355 | view->view_type = view_type; |
356 | view->view_id = user_key; |
357 | view->cmd_size = cmd_size; |
358 | view->committed = false; |
359 | INIT_LIST_HEAD(list: &view->srf_head); |
360 | INIT_LIST_HEAD(list: &view->cotable_head); |
361 | memcpy(&view->cmd, cmd, cmd_size); |
362 | ret = vmw_resource_init(dev_priv, res, delay_id: true, |
363 | res_free: vmw_view_res_free, func: &vmw_view_func); |
364 | if (ret) |
365 | goto out_resource_init; |
366 | |
367 | ret = vmw_cmdbuf_res_add(man, res_type: vmw_cmdbuf_res_view, |
368 | user_key: vmw_view_key(user_key, view_type), |
369 | res, list); |
370 | if (ret) |
371 | goto out_resource_init; |
372 | |
373 | res->id = view->view_id; |
374 | res->hw_destroy = vmw_hw_view_destroy; |
375 | |
376 | out_resource_init: |
377 | vmw_resource_unreference(p_res: &res); |
378 | |
379 | return ret; |
380 | } |
381 | |
382 | /** |
383 | * vmw_view_remove - Stage a view for removal. |
384 | * |
385 | * @man: Pointer to the view manager identifying the shader namespace. |
386 | * @user_key: The key that is used to identify the view. The key is |
387 | * unique to the view type. |
388 | * @view_type: View type |
389 | * @list: Caller's list of staged command buffer resource actions. |
390 | * @res_p: If the resource is in an already committed state, points to the |
391 | * struct vmw_resource on successful return. The pointer will be |
392 | * non ref-counted. |
393 | */ |
394 | int vmw_view_remove(struct vmw_cmdbuf_res_manager *man, |
395 | u32 user_key, enum vmw_view_type view_type, |
396 | struct list_head *list, |
397 | struct vmw_resource **res_p) |
398 | { |
399 | if (!vmw_view_id_ok(user_key, view_type)) { |
400 | VMW_DEBUG_USER("Illegal view remove view id.\n" ); |
401 | return -EINVAL; |
402 | } |
403 | |
404 | return vmw_cmdbuf_res_remove(man, res_type: vmw_cmdbuf_res_view, |
405 | user_key: vmw_view_key(user_key, view_type), |
406 | list, res: res_p); |
407 | } |
408 | |
409 | /** |
410 | * vmw_view_cotable_list_destroy - Evict all views belonging to a cotable. |
411 | * |
412 | * @dev_priv: Pointer to a device private struct. |
413 | * @list: List of views belonging to a cotable. |
414 | * @readback: Unused. Needed for function interface only. |
415 | * |
416 | * This function evicts all views belonging to a cotable. |
417 | * It must be called with the binding_mutex held, and the caller must hold |
418 | * a reference to the view resource. This is typically called before the |
419 | * cotable is paged out. |
420 | */ |
421 | void vmw_view_cotable_list_destroy(struct vmw_private *dev_priv, |
422 | struct list_head *list, |
423 | bool readback) |
424 | { |
425 | struct vmw_view *entry, *next; |
426 | |
427 | lockdep_assert_held_once(&dev_priv->binding_mutex); |
428 | |
429 | list_for_each_entry_safe(entry, next, list, cotable_head) |
430 | WARN_ON(vmw_view_destroy(&entry->res)); |
431 | } |
432 | |
433 | /** |
434 | * vmw_view_surface_list_destroy - Evict all views pointing to a surface |
435 | * |
436 | * @dev_priv: Pointer to a device private struct. |
437 | * @list: List of views pointing to a surface. |
438 | * |
439 | * This function evicts all views pointing to a surface. This is typically |
440 | * called before the surface is evicted. |
441 | */ |
442 | void vmw_view_surface_list_destroy(struct vmw_private *dev_priv, |
443 | struct list_head *list) |
444 | { |
445 | struct vmw_view *entry, *next; |
446 | |
447 | lockdep_assert_held_once(&dev_priv->binding_mutex); |
448 | |
449 | list_for_each_entry_safe(entry, next, list, srf_head) |
450 | WARN_ON(vmw_view_destroy(&entry->res)); |
451 | } |
452 | |
453 | /** |
454 | * vmw_view_srf - Return a non-refcounted pointer to the surface a view is |
455 | * pointing to. |
456 | * |
457 | * @res: pointer to a view resource. |
458 | * |
459 | * Note that the view itself is holding a reference, so as long |
460 | * the view resource is alive, the surface resource will be. |
461 | */ |
462 | struct vmw_resource *vmw_view_srf(struct vmw_resource *res) |
463 | { |
464 | return vmw_view(res)->srf; |
465 | } |
466 | |
467 | /** |
468 | * vmw_view_lookup - Look up a view. |
469 | * |
470 | * @man: The context's cmdbuf ref manager. |
471 | * @view_type: The view type. |
472 | * @user_key: The view user id. |
473 | * |
474 | * returns a refcounted pointer to a view or an error pointer if not found. |
475 | */ |
476 | struct vmw_resource *vmw_view_lookup(struct vmw_cmdbuf_res_manager *man, |
477 | enum vmw_view_type view_type, |
478 | u32 user_key) |
479 | { |
480 | return vmw_cmdbuf_res_lookup(man, res_type: vmw_cmdbuf_res_view, |
481 | user_key: vmw_view_key(user_key, view_type)); |
482 | } |
483 | |
484 | /** |
485 | * vmw_view_dirtying - Return whether a view type is dirtying its resource |
486 | * @res: Pointer to the view |
487 | * |
488 | * Each time a resource is put on the validation list as the result of a |
489 | * view pointing to it, we need to determine whether that resource will |
490 | * be dirtied (written to by the GPU) as a result of the corresponding |
491 | * GPU operation. Currently only rendertarget-, depth-stencil and unordered |
492 | * access views are capable of dirtying its resource. |
493 | * |
494 | * Return: Whether the view type of @res dirties the resource it points to. |
495 | */ |
496 | u32 vmw_view_dirtying(struct vmw_resource *res) |
497 | { |
498 | static u32 view_is_dirtying[vmw_view_max] = { |
499 | [vmw_view_rt] = VMW_RES_DIRTY_SET, |
500 | [vmw_view_ds] = VMW_RES_DIRTY_SET, |
501 | [vmw_view_ua] = VMW_RES_DIRTY_SET, |
502 | }; |
503 | |
504 | /* Update this function as we add more view types */ |
505 | BUILD_BUG_ON(vmw_view_max != 4); |
506 | return view_is_dirtying[vmw_view(res)->view_type]; |
507 | } |
508 | |
509 | const u32 vmw_view_destroy_cmds[] = { |
510 | [vmw_view_sr] = SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW, |
511 | [vmw_view_rt] = SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW, |
512 | [vmw_view_ds] = SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW, |
513 | [vmw_view_ua] = SVGA_3D_CMD_DX_DESTROY_UA_VIEW, |
514 | }; |
515 | |
516 | const SVGACOTableType vmw_view_cotables[] = { |
517 | [vmw_view_sr] = SVGA_COTABLE_SRVIEW, |
518 | [vmw_view_rt] = SVGA_COTABLE_RTVIEW, |
519 | [vmw_view_ds] = SVGA_COTABLE_DSVIEW, |
520 | [vmw_view_ua] = SVGA_COTABLE_UAVIEW, |
521 | }; |
522 | |
523 | const SVGACOTableType vmw_so_cotables[] = { |
524 | [vmw_so_el] = SVGA_COTABLE_ELEMENTLAYOUT, |
525 | [vmw_so_bs] = SVGA_COTABLE_BLENDSTATE, |
526 | [vmw_so_ds] = SVGA_COTABLE_DEPTHSTENCIL, |
527 | [vmw_so_rs] = SVGA_COTABLE_RASTERIZERSTATE, |
528 | [vmw_so_ss] = SVGA_COTABLE_SAMPLER, |
529 | [vmw_so_so] = SVGA_COTABLE_STREAMOUTPUT, |
530 | [vmw_so_max]= SVGA_COTABLE_MAX |
531 | }; |
532 | |
533 | |
534 | /* To remove unused function warning */ |
535 | static void vmw_so_build_asserts(void) __attribute__((used)); |
536 | |
537 | |
538 | /* |
539 | * This function is unused at run-time, and only used to dump various build |
540 | * asserts important for code optimization assumptions. |
541 | */ |
542 | static void vmw_so_build_asserts(void) |
543 | { |
544 | /* Assert that our vmw_view_cmd_to_type() function is correct. */ |
545 | BUILD_BUG_ON(SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW != |
546 | SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 1); |
547 | BUILD_BUG_ON(SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW != |
548 | SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 2); |
549 | BUILD_BUG_ON(SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW != |
550 | SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 3); |
551 | BUILD_BUG_ON(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW != |
552 | SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 4); |
553 | BUILD_BUG_ON(SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW != |
554 | SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 5); |
555 | |
556 | /* Assert that our "one body fits all" assumption is valid */ |
557 | BUILD_BUG_ON(sizeof(union vmw_view_destroy) != sizeof(u32)); |
558 | |
559 | /* Assert that the view key space can hold all view ids. */ |
560 | BUILD_BUG_ON(SVGA_COTABLE_MAX_IDS >= ((1 << 20) - 1)); |
561 | |
562 | /* |
563 | * Assert that the offset of sid in all view define commands |
564 | * is what we assume it to be. |
565 | */ |
566 | BUILD_BUG_ON(offsetof(struct vmw_view_define, sid) != |
567 | offsetof(SVGA3dCmdDXDefineShaderResourceView, sid)); |
568 | BUILD_BUG_ON(offsetof(struct vmw_view_define, sid) != |
569 | offsetof(SVGA3dCmdDXDefineRenderTargetView, sid)); |
570 | BUILD_BUG_ON(offsetof(struct vmw_view_define, sid) != |
571 | offsetof(SVGA3dCmdDXDefineDepthStencilView, sid)); |
572 | BUILD_BUG_ON(offsetof(struct vmw_view_define, sid) != |
573 | offsetof(SVGA3dCmdDXDefineUAView, sid)); |
574 | BUILD_BUG_ON(offsetof(struct vmw_view_define, sid) != |
575 | offsetof(SVGA3dCmdDXDefineDepthStencilView_v2, sid)); |
576 | } |
577 | |