Commit | Line | Data |
---|---|---|
d80efd5c | 1 | /************************************************************************** |
54fbde8a | 2 | * Copyright © 2014-2015 VMware, Inc., Palo Alto, CA., USA |
d80efd5c TH |
3 | * All Rights Reserved. |
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_drv.h" | |
28 | #include "vmwgfx_resource_priv.h" | |
29 | #include "vmwgfx_so.h" | |
30 | #include "vmwgfx_binding.h" | |
31 | ||
32 | /* | |
33 | * The currently only reason we need to keep track of views is that if we | |
34 | * destroy a hardware surface, all views pointing to it must also be destroyed, | |
35 | * otherwise the device will error. | |
36 | * So in particuar if a surface is evicted, we must destroy all views pointing | |
37 | * to it, and all context bindings of that view. Similarly we must restore | |
38 | * the view bindings, views and surfaces pointed to by the views when a | |
39 | * context is referenced in the command stream. | |
40 | */ | |
41 | ||
42 | /** | |
43 | * struct vmw_view - view metadata | |
44 | * | |
45 | * @res: The struct vmw_resource we derive from | |
46 | * @ctx: Non-refcounted pointer to the context this view belongs to. | |
47 | * @srf: Refcounted pointer to the surface pointed to by this view. | |
48 | * @cotable: Refcounted pointer to the cotable holding this view. | |
49 | * @srf_head: List head for the surface-to-view list. | |
50 | * @cotable_head: List head for the cotable-to_view list. | |
51 | * @view_type: View type. | |
52 | * @view_id: User-space per context view id. Currently used also as per | |
53 | * context device view id. | |
54 | * @cmd_size: Size of the SVGA3D define view command that we've copied from the | |
55 | * command stream. | |
56 | * @committed: Whether the view is actually created or pending creation at the | |
57 | * device level. | |
58 | * @cmd: The SVGA3D define view command copied from the command stream. | |
59 | */ | |
60 | struct vmw_view { | |
61 | struct rcu_head rcu; | |
62 | struct vmw_resource res; | |
63 | struct vmw_resource *ctx; /* Immutable */ | |
64 | struct vmw_resource *srf; /* Immutable */ | |
65 | struct vmw_resource *cotable; /* Immutable */ | |
66 | struct list_head srf_head; /* Protected by binding_mutex */ | |
67 | struct list_head cotable_head; /* Protected by binding_mutex */ | |
68 | unsigned view_type; /* Immutable */ | |
69 | unsigned view_id; /* Immutable */ | |
70 | u32 cmd_size; /* Immutable */ | |
71 | bool committed; /* Protected by binding_mutex */ | |
72 | u32 cmd[1]; /* Immutable */ | |
73 | }; | |
74 | ||
75 | static int vmw_view_create(struct vmw_resource *res); | |
76 | static int vmw_view_destroy(struct vmw_resource *res); | |
77 | static void vmw_hw_view_destroy(struct vmw_resource *res); | |
78 | static void vmw_view_commit_notify(struct vmw_resource *res, | |
79 | enum vmw_cmdbuf_res_state state); | |
80 | ||
81 | static const struct vmw_res_func vmw_view_func = { | |
82 | .res_type = vmw_res_view, | |
83 | .needs_backup = false, | |
84 | .may_evict = false, | |
85 | .type_name = "DX view", | |
86 | .backup_placement = NULL, | |
87 | .create = vmw_view_create, | |
88 | .commit_notify = vmw_view_commit_notify, | |
89 | }; | |
90 | ||
91 | /** | |
92 | * struct vmw_view - view define command body stub | |
93 | * | |
94 | * @view_id: The device id of the view being defined | |
95 | * @sid: The surface id of the view being defined | |
96 | * | |
97 | * This generic struct is used by the code to change @view_id and @sid of a | |
98 | * saved view define command. | |
99 | */ | |
100 | struct vmw_view_define { | |
101 | uint32 view_id; | |
102 | uint32 sid; | |
103 | }; | |
104 | ||
105 | /** | |
106 | * vmw_view - Convert a struct vmw_resource to a struct vmw_view | |
107 | * | |
108 | * @res: Pointer to the resource to convert. | |
109 | * | |
110 | * Returns a pointer to a struct vmw_view. | |
111 | */ | |
112 | static struct vmw_view *vmw_view(struct vmw_resource *res) | |
113 | { | |
114 | return container_of(res, struct vmw_view, res); | |
115 | } | |
116 | ||
117 | /** | |
118 | * vmw_view_commit_notify - Notify that a view operation has been committed to | |
119 | * hardware from a user-supplied command stream. | |
120 | * | |
121 | * @res: Pointer to the view resource. | |
122 | * @state: Indicating whether a creation or removal has been committed. | |
123 | * | |
124 | */ | |
125 | static void vmw_view_commit_notify(struct vmw_resource *res, | |
126 | enum vmw_cmdbuf_res_state state) | |
127 | { | |
128 | struct vmw_view *view = vmw_view(res); | |
129 | struct vmw_private *dev_priv = res->dev_priv; | |
130 | ||
131 | mutex_lock(&dev_priv->binding_mutex); | |
132 | if (state == VMW_CMDBUF_RES_ADD) { | |
133 | struct vmw_surface *srf = vmw_res_to_srf(view->srf); | |
134 | ||
135 | list_add_tail(&view->srf_head, &srf->view_list); | |
136 | vmw_cotable_add_resource(view->cotable, &view->cotable_head); | |
137 | view->committed = true; | |
138 | res->id = view->view_id; | |
139 | ||
140 | } else { | |
141 | list_del_init(&view->cotable_head); | |
142 | list_del_init(&view->srf_head); | |
143 | view->committed = false; | |
144 | res->id = -1; | |
145 | } | |
146 | mutex_unlock(&dev_priv->binding_mutex); | |
147 | } | |
148 | ||
149 | /** | |
150 | * vmw_view_create - Create a hardware view. | |
151 | * | |
152 | * @res: Pointer to the view resource. | |
153 | * | |
154 | * Create a hardware view. Typically used if that view has previously been | |
155 | * destroyed by an eviction operation. | |
156 | */ | |
157 | static int vmw_view_create(struct vmw_resource *res) | |
158 | { | |
159 | struct vmw_view *view = vmw_view(res); | |
160 | struct vmw_surface *srf = vmw_res_to_srf(view->srf); | |
161 | struct vmw_private *dev_priv = res->dev_priv; | |
162 | struct { | |
163 | SVGA3dCmdHeader header; | |
164 | struct vmw_view_define body; | |
165 | } *cmd; | |
166 | ||
167 | mutex_lock(&dev_priv->binding_mutex); | |
168 | if (!view->committed) { | |
169 | mutex_unlock(&dev_priv->binding_mutex); | |
170 | return 0; | |
171 | } | |
172 | ||
173 | cmd = vmw_fifo_reserve_dx(res->dev_priv, view->cmd_size, | |
174 | view->ctx->id); | |
175 | if (!cmd) { | |
176 | DRM_ERROR("Failed reserving FIFO space for view creation.\n"); | |
177 | mutex_unlock(&dev_priv->binding_mutex); | |
178 | return -ENOMEM; | |
179 | } | |
180 | memcpy(cmd, &view->cmd, view->cmd_size); | |
181 | WARN_ON(cmd->body.view_id != view->view_id); | |
182 | /* Sid may have changed due to surface eviction. */ | |
183 | WARN_ON(view->srf->id == SVGA3D_INVALID_ID); | |
184 | cmd->body.sid = view->srf->id; | |
185 | vmw_fifo_commit(res->dev_priv, view->cmd_size); | |
186 | res->id = view->view_id; | |
187 | list_add_tail(&view->srf_head, &srf->view_list); | |
188 | vmw_cotable_add_resource(view->cotable, &view->cotable_head); | |
189 | mutex_unlock(&dev_priv->binding_mutex); | |
190 | ||
191 | return 0; | |
192 | } | |
193 | ||
194 | /** | |
195 | * vmw_view_destroy - Destroy a hardware view. | |
196 | * | |
197 | * @res: Pointer to the view resource. | |
198 | * | |
199 | * Destroy a hardware view. Typically used on unexpected termination of the | |
200 | * owning process or if the surface the view is pointing to is destroyed. | |
201 | */ | |
202 | static int vmw_view_destroy(struct vmw_resource *res) | |
203 | { | |
204 | struct vmw_private *dev_priv = res->dev_priv; | |
205 | struct vmw_view *view = vmw_view(res); | |
206 | struct { | |
207 | SVGA3dCmdHeader header; | |
208 | union vmw_view_destroy body; | |
209 | } *cmd; | |
210 | ||
211 | WARN_ON_ONCE(!mutex_is_locked(&dev_priv->binding_mutex)); | |
212 | vmw_binding_res_list_scrub(&res->binding_head); | |
213 | ||
214 | if (!view->committed || res->id == -1) | |
215 | return 0; | |
216 | ||
217 | cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), view->ctx->id); | |
218 | if (!cmd) { | |
219 | DRM_ERROR("Failed reserving FIFO space for view " | |
220 | "destruction.\n"); | |
221 | return -ENOMEM; | |
222 | } | |
223 | ||
224 | cmd->header.id = vmw_view_destroy_cmds[view->view_type]; | |
225 | cmd->header.size = sizeof(cmd->body); | |
226 | cmd->body.view_id = view->view_id; | |
227 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | |
228 | res->id = -1; | |
229 | list_del_init(&view->cotable_head); | |
230 | list_del_init(&view->srf_head); | |
231 | ||
232 | return 0; | |
233 | } | |
234 | ||
235 | /** | |
236 | * vmw_hw_view_destroy - Destroy a hardware view as part of resource cleanup. | |
237 | * | |
238 | * @res: Pointer to the view resource. | |
239 | * | |
240 | * Destroy a hardware view if it's still present. | |
241 | */ | |
242 | static void vmw_hw_view_destroy(struct vmw_resource *res) | |
243 | { | |
244 | struct vmw_private *dev_priv = res->dev_priv; | |
245 | ||
246 | mutex_lock(&dev_priv->binding_mutex); | |
247 | WARN_ON(vmw_view_destroy(res)); | |
248 | res->id = -1; | |
249 | mutex_unlock(&dev_priv->binding_mutex); | |
250 | } | |
251 | ||
252 | /** | |
253 | * vmw_view_key - Compute a view key suitable for the cmdbuf resource manager | |
254 | * | |
255 | * @user_key: The user-space id used for the view. | |
256 | * @view_type: The view type. | |
257 | * | |
258 | * Destroy a hardware view if it's still present. | |
259 | */ | |
260 | static u32 vmw_view_key(u32 user_key, enum vmw_view_type view_type) | |
261 | { | |
262 | return user_key | (view_type << 20); | |
263 | } | |
264 | ||
265 | /** | |
266 | * vmw_view_id_ok - Basic view id and type range checks. | |
267 | * | |
268 | * @user_key: The user-space id used for the view. | |
269 | * @view_type: The view type. | |
270 | * | |
271 | * Checks that the view id and type (typically provided by user-space) is | |
272 | * valid. | |
273 | */ | |
274 | static bool vmw_view_id_ok(u32 user_key, enum vmw_view_type view_type) | |
275 | { | |
276 | return (user_key < SVGA_COTABLE_MAX_IDS && | |
277 | view_type < vmw_view_max); | |
278 | } | |
279 | ||
280 | /** | |
281 | * vmw_view_res_free - resource res_free callback for view resources | |
282 | * | |
283 | * @res: Pointer to a struct vmw_resource | |
284 | * | |
285 | * Frees memory and memory accounting held by a struct vmw_view. | |
286 | */ | |
287 | static void vmw_view_res_free(struct vmw_resource *res) | |
288 | { | |
289 | struct vmw_view *view = vmw_view(res); | |
290 | size_t size = offsetof(struct vmw_view, cmd) + view->cmd_size; | |
291 | struct vmw_private *dev_priv = res->dev_priv; | |
292 | ||
293 | vmw_resource_unreference(&view->cotable); | |
294 | vmw_resource_unreference(&view->srf); | |
295 | kfree_rcu(view, rcu); | |
296 | ttm_mem_global_free(vmw_mem_glob(dev_priv), size); | |
297 | } | |
298 | ||
299 | /** | |
300 | * vmw_view_add - Create a view resource and stage it for addition | |
301 | * as a command buffer managed resource. | |
302 | * | |
303 | * @man: Pointer to the compat shader manager identifying the shader namespace. | |
304 | * @ctx: Pointer to a struct vmw_resource identifying the active context. | |
305 | * @srf: Pointer to a struct vmw_resource identifying the surface the view | |
306 | * points to. | |
307 | * @view_type: The view type deduced from the view create command. | |
308 | * @user_key: The key that is used to identify the shader. The key is | |
309 | * unique to the view type and to the context. | |
310 | * @cmd: Pointer to the view create command in the command stream. | |
311 | * @cmd_size: Size of the view create command in the command stream. | |
312 | * @list: Caller's list of staged command buffer resource actions. | |
313 | */ | |
314 | int vmw_view_add(struct vmw_cmdbuf_res_manager *man, | |
315 | struct vmw_resource *ctx, | |
316 | struct vmw_resource *srf, | |
317 | enum vmw_view_type view_type, | |
318 | u32 user_key, | |
319 | const void *cmd, | |
320 | size_t cmd_size, | |
321 | struct list_head *list) | |
322 | { | |
323 | static const size_t vmw_view_define_sizes[] = { | |
324 | [vmw_view_sr] = sizeof(SVGA3dCmdDXDefineShaderResourceView), | |
325 | [vmw_view_rt] = sizeof(SVGA3dCmdDXDefineRenderTargetView), | |
326 | [vmw_view_ds] = sizeof(SVGA3dCmdDXDefineDepthStencilView) | |
327 | }; | |
328 | ||
329 | struct vmw_private *dev_priv = ctx->dev_priv; | |
330 | struct vmw_resource *res; | |
331 | struct vmw_view *view; | |
332 | size_t size; | |
333 | int ret; | |
334 | ||
335 | if (cmd_size != vmw_view_define_sizes[view_type] + | |
336 | sizeof(SVGA3dCmdHeader)) { | |
337 | DRM_ERROR("Illegal view create command size.\n"); | |
338 | return -EINVAL; | |
339 | } | |
340 | ||
341 | if (!vmw_view_id_ok(user_key, view_type)) { | |
342 | DRM_ERROR("Illegal view add view id.\n"); | |
343 | return -EINVAL; | |
344 | } | |
345 | ||
346 | size = offsetof(struct vmw_view, cmd) + cmd_size; | |
347 | ||
348 | ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), size, false, true); | |
349 | if (ret) { | |
350 | if (ret != -ERESTARTSYS) | |
351 | DRM_ERROR("Out of graphics memory for view" | |
352 | " creation.\n"); | |
353 | return ret; | |
354 | } | |
355 | ||
356 | view = kmalloc(size, GFP_KERNEL); | |
357 | if (!view) { | |
358 | ttm_mem_global_free(vmw_mem_glob(dev_priv), size); | |
359 | return -ENOMEM; | |
360 | } | |
361 | ||
362 | res = &view->res; | |
363 | view->ctx = ctx; | |
364 | view->srf = vmw_resource_reference(srf); | |
365 | view->cotable = vmw_context_cotable(ctx, vmw_view_cotables[view_type]); | |
366 | view->view_type = view_type; | |
367 | view->view_id = user_key; | |
368 | view->cmd_size = cmd_size; | |
369 | view->committed = false; | |
370 | INIT_LIST_HEAD(&view->srf_head); | |
371 | INIT_LIST_HEAD(&view->cotable_head); | |
372 | memcpy(&view->cmd, cmd, cmd_size); | |
373 | ret = vmw_resource_init(dev_priv, res, true, | |
374 | vmw_view_res_free, &vmw_view_func); | |
375 | if (ret) | |
376 | goto out_resource_init; | |
377 | ||
378 | ret = vmw_cmdbuf_res_add(man, vmw_cmdbuf_res_view, | |
379 | vmw_view_key(user_key, view_type), | |
380 | res, list); | |
381 | if (ret) | |
382 | goto out_resource_init; | |
383 | ||
384 | res->id = view->view_id; | |
385 | vmw_resource_activate(res, vmw_hw_view_destroy); | |
386 | ||
387 | out_resource_init: | |
388 | vmw_resource_unreference(&res); | |
389 | ||
390 | return ret; | |
391 | } | |
392 | ||
393 | /** | |
394 | * vmw_view_remove - Stage a view for removal. | |
395 | * | |
396 | * @man: Pointer to the view manager identifying the shader namespace. | |
397 | * @user_key: The key that is used to identify the view. The key is | |
398 | * unique to the view type. | |
399 | * @view_type: View type | |
400 | * @list: Caller's list of staged command buffer resource actions. | |
401 | * @res_p: If the resource is in an already committed state, points to the | |
402 | * struct vmw_resource on successful return. The pointer will be | |
403 | * non ref-counted. | |
404 | */ | |
405 | int vmw_view_remove(struct vmw_cmdbuf_res_manager *man, | |
406 | u32 user_key, enum vmw_view_type view_type, | |
407 | struct list_head *list, | |
408 | struct vmw_resource **res_p) | |
409 | { | |
410 | if (!vmw_view_id_ok(user_key, view_type)) { | |
411 | DRM_ERROR("Illegal view remove view id.\n"); | |
412 | return -EINVAL; | |
413 | } | |
414 | ||
415 | return vmw_cmdbuf_res_remove(man, vmw_cmdbuf_res_view, | |
416 | vmw_view_key(user_key, view_type), | |
417 | list, res_p); | |
418 | } | |
419 | ||
420 | /** | |
421 | * vmw_view_cotable_list_destroy - Evict all views belonging to a cotable. | |
422 | * | |
423 | * @dev_priv: Pointer to a device private struct. | |
424 | * @list: List of views belonging to a cotable. | |
425 | * @readback: Unused. Needed for function interface only. | |
426 | * | |
427 | * This function evicts all views belonging to a cotable. | |
428 | * It must be called with the binding_mutex held, and the caller must hold | |
429 | * a reference to the view resource. This is typically called before the | |
430 | * cotable is paged out. | |
431 | */ | |
432 | void vmw_view_cotable_list_destroy(struct vmw_private *dev_priv, | |
433 | struct list_head *list, | |
434 | bool readback) | |
435 | { | |
436 | struct vmw_view *entry, *next; | |
437 | ||
438 | WARN_ON_ONCE(!mutex_is_locked(&dev_priv->binding_mutex)); | |
439 | ||
440 | list_for_each_entry_safe(entry, next, list, cotable_head) | |
441 | WARN_ON(vmw_view_destroy(&entry->res)); | |
442 | } | |
443 | ||
444 | /** | |
445 | * vmw_view_surface_list_destroy - Evict all views pointing to a surface | |
446 | * | |
447 | * @dev_priv: Pointer to a device private struct. | |
448 | * @list: List of views pointing to a surface. | |
449 | * | |
450 | * This function evicts all views pointing to a surface. This is typically | |
451 | * called before the surface is evicted. | |
452 | */ | |
453 | void vmw_view_surface_list_destroy(struct vmw_private *dev_priv, | |
454 | struct list_head *list) | |
455 | { | |
456 | struct vmw_view *entry, *next; | |
457 | ||
458 | WARN_ON_ONCE(!mutex_is_locked(&dev_priv->binding_mutex)); | |
459 | ||
460 | list_for_each_entry_safe(entry, next, list, srf_head) | |
461 | WARN_ON(vmw_view_destroy(&entry->res)); | |
462 | } | |
463 | ||
464 | /** | |
465 | * vmw_view_srf - Return a non-refcounted pointer to the surface a view is | |
466 | * pointing to. | |
467 | * | |
468 | * @res: pointer to a view resource. | |
469 | * | |
470 | * Note that the view itself is holding a reference, so as long | |
471 | * the view resource is alive, the surface resource will be. | |
472 | */ | |
473 | struct vmw_resource *vmw_view_srf(struct vmw_resource *res) | |
474 | { | |
475 | return vmw_view(res)->srf; | |
476 | } | |
477 | ||
478 | /** | |
479 | * vmw_view_lookup - Look up a view. | |
480 | * | |
481 | * @man: The context's cmdbuf ref manager. | |
482 | * @view_type: The view type. | |
483 | * @user_key: The view user id. | |
484 | * | |
485 | * returns a refcounted pointer to a view or an error pointer if not found. | |
486 | */ | |
487 | struct vmw_resource *vmw_view_lookup(struct vmw_cmdbuf_res_manager *man, | |
488 | enum vmw_view_type view_type, | |
489 | u32 user_key) | |
490 | { | |
491 | return vmw_cmdbuf_res_lookup(man, vmw_cmdbuf_res_view, | |
492 | vmw_view_key(user_key, view_type)); | |
493 | } | |
494 | ||
495 | const u32 vmw_view_destroy_cmds[] = { | |
496 | [vmw_view_sr] = SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW, | |
497 | [vmw_view_rt] = SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW, | |
498 | [vmw_view_ds] = SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW, | |
499 | }; | |
500 | ||
501 | const SVGACOTableType vmw_view_cotables[] = { | |
502 | [vmw_view_sr] = SVGA_COTABLE_SRVIEW, | |
503 | [vmw_view_rt] = SVGA_COTABLE_RTVIEW, | |
504 | [vmw_view_ds] = SVGA_COTABLE_DSVIEW, | |
505 | }; | |
506 | ||
507 | const SVGACOTableType vmw_so_cotables[] = { | |
508 | [vmw_so_el] = SVGA_COTABLE_ELEMENTLAYOUT, | |
509 | [vmw_so_bs] = SVGA_COTABLE_BLENDSTATE, | |
510 | [vmw_so_ds] = SVGA_COTABLE_DEPTHSTENCIL, | |
511 | [vmw_so_rs] = SVGA_COTABLE_RASTERIZERSTATE, | |
512 | [vmw_so_ss] = SVGA_COTABLE_SAMPLER, | |
513 | [vmw_so_so] = SVGA_COTABLE_STREAMOUTPUT | |
514 | }; | |
515 | ||
516 | ||
517 | /* To remove unused function warning */ | |
518 | static void vmw_so_build_asserts(void) __attribute__((used)); | |
519 | ||
520 | ||
521 | /* | |
522 | * This function is unused at run-time, and only used to dump various build | |
523 | * asserts important for code optimization assumptions. | |
524 | */ | |
525 | static void vmw_so_build_asserts(void) | |
526 | { | |
527 | /* Assert that our vmw_view_cmd_to_type() function is correct. */ | |
528 | BUILD_BUG_ON(SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW != | |
529 | SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 1); | |
530 | BUILD_BUG_ON(SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW != | |
531 | SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 2); | |
532 | BUILD_BUG_ON(SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW != | |
533 | SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 3); | |
534 | BUILD_BUG_ON(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW != | |
535 | SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 4); | |
536 | BUILD_BUG_ON(SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW != | |
537 | SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 5); | |
538 | ||
539 | /* Assert that our "one body fits all" assumption is valid */ | |
540 | BUILD_BUG_ON(sizeof(union vmw_view_destroy) != sizeof(u32)); | |
541 | ||
542 | /* Assert that the view key space can hold all view ids. */ | |
543 | BUILD_BUG_ON(SVGA_COTABLE_MAX_IDS >= ((1 << 20) - 1)); | |
544 | ||
545 | /* | |
546 | * Assert that the offset of sid in all view define commands | |
547 | * is what we assume it to be. | |
548 | */ | |
549 | BUILD_BUG_ON(offsetof(struct vmw_view_define, sid) != | |
550 | offsetof(SVGA3dCmdDXDefineShaderResourceView, sid)); | |
551 | BUILD_BUG_ON(offsetof(struct vmw_view_define, sid) != | |
552 | offsetof(SVGA3dCmdDXDefineRenderTargetView, sid)); | |
553 | BUILD_BUG_ON(offsetof(struct vmw_view_define, sid) != | |
554 | offsetof(SVGA3dCmdDXDefineDepthStencilView, sid)); | |
555 | } |