This source file includes following definitions.
- vmw_view_commit_notify
 
- vmw_view_create
 
- vmw_view_destroy
 
- vmw_hw_view_destroy
 
- vmw_view_key
 
- vmw_view_id_ok
 
- vmw_view_res_free
 
- vmw_view_add
 
- vmw_view_remove
 
- vmw_view_cotable_list_destroy
 
- vmw_view_surface_list_destroy
 
- vmw_view_srf
 
- vmw_view_lookup
 
- vmw_view_dirtying
 
- vmw_so_build_asserts
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  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 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 
  44 
  45 
  46 
  47 
  48 
  49 
  50 
  51 
  52 
  53 
  54 
  55 
  56 
  57 
  58 
  59 
  60 struct vmw_view {
  61         struct rcu_head rcu;
  62         struct vmw_resource res;
  63         struct vmw_resource *ctx;      
  64         struct vmw_resource *srf;      
  65         struct vmw_resource *cotable;  
  66         struct list_head srf_head;     
  67         struct list_head cotable_head; 
  68         unsigned view_type;            
  69         unsigned view_id;              
  70         u32 cmd_size;                  
  71         bool committed;                
  72         u32 cmd[1];                    
  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 
  93 
  94 
  95 
  96 
  97 
  98 
  99 
 100 struct vmw_view_define {
 101         uint32 view_id;
 102         uint32 sid;
 103 };
 104 
 105 
 106 
 107 
 108 
 109 
 110 
 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 
 119 
 120 
 121 
 122 
 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 
 151 
 152 
 153 
 154 
 155 
 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, view->ctx->id);
 174         if (!cmd) {
 175                 mutex_unlock(&dev_priv->binding_mutex);
 176                 return -ENOMEM;
 177         }
 178 
 179         memcpy(cmd, &view->cmd, view->cmd_size);
 180         WARN_ON(cmd->body.view_id != view->view_id);
 181         
 182         WARN_ON(view->srf->id == SVGA3D_INVALID_ID);
 183         cmd->body.sid = view->srf->id;
 184         vmw_fifo_commit(res->dev_priv, view->cmd_size);
 185         res->id = view->view_id;
 186         list_add_tail(&view->srf_head, &srf->view_list);
 187         vmw_cotable_add_resource(view->cotable, &view->cotable_head);
 188         mutex_unlock(&dev_priv->binding_mutex);
 189 
 190         return 0;
 191 }
 192 
 193 
 194 
 195 
 196 
 197 
 198 
 199 
 200 
 201 static int vmw_view_destroy(struct vmw_resource *res)
 202 {
 203         struct vmw_private *dev_priv = res->dev_priv;
 204         struct vmw_view *view = vmw_view(res);
 205         struct {
 206                 SVGA3dCmdHeader header;
 207                 union vmw_view_destroy body;
 208         } *cmd;
 209 
 210         lockdep_assert_held_once(&dev_priv->binding_mutex);
 211         vmw_binding_res_list_scrub(&res->binding_head);
 212 
 213         if (!view->committed || res->id == -1)
 214                 return 0;
 215 
 216         cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), view->ctx->id);
 217         if (!cmd)
 218                 return -ENOMEM;
 219 
 220         cmd->header.id = vmw_view_destroy_cmds[view->view_type];
 221         cmd->header.size = sizeof(cmd->body);
 222         cmd->body.view_id = view->view_id;
 223         vmw_fifo_commit(dev_priv, sizeof(*cmd));
 224         res->id = -1;
 225         list_del_init(&view->cotable_head);
 226         list_del_init(&view->srf_head);
 227 
 228         return 0;
 229 }
 230 
 231 
 232 
 233 
 234 
 235 
 236 
 237 
 238 static void vmw_hw_view_destroy(struct vmw_resource *res)
 239 {
 240         struct vmw_private *dev_priv = res->dev_priv;
 241 
 242         mutex_lock(&dev_priv->binding_mutex);
 243         WARN_ON(vmw_view_destroy(res));
 244         res->id = -1;
 245         mutex_unlock(&dev_priv->binding_mutex);
 246 }
 247 
 248 
 249 
 250 
 251 
 252 
 253 
 254 
 255 
 256 static u32 vmw_view_key(u32 user_key, enum vmw_view_type view_type)
 257 {
 258         return user_key | (view_type << 20);
 259 }
 260 
 261 
 262 
 263 
 264 
 265 
 266 
 267 
 268 
 269 
 270 static bool vmw_view_id_ok(u32 user_key, enum vmw_view_type view_type)
 271 {
 272         return (user_key < SVGA_COTABLE_MAX_IDS &&
 273                 view_type < vmw_view_max);
 274 }
 275 
 276 
 277 
 278 
 279 
 280 
 281 
 282 
 283 static void vmw_view_res_free(struct vmw_resource *res)
 284 {
 285         struct vmw_view *view = vmw_view(res);
 286         size_t size = offsetof(struct vmw_view, cmd) + view->cmd_size;
 287         struct vmw_private *dev_priv = res->dev_priv;
 288 
 289         vmw_resource_unreference(&view->cotable);
 290         vmw_resource_unreference(&view->srf);
 291         kfree_rcu(view, rcu);
 292         ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
 293 }
 294 
 295 
 296 
 297 
 298 
 299 
 300 
 301 
 302 
 303 
 304 
 305 
 306 
 307 
 308 
 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         };
 324 
 325         struct vmw_private *dev_priv = ctx->dev_priv;
 326         struct vmw_resource *res;
 327         struct vmw_view *view;
 328         struct ttm_operation_ctx ttm_opt_ctx = {
 329                 .interruptible = true,
 330                 .no_wait_gpu = false
 331         };
 332         size_t size;
 333         int ret;
 334 
 335         if (cmd_size != vmw_view_define_sizes[view_type] +
 336             sizeof(SVGA3dCmdHeader)) {
 337                 VMW_DEBUG_USER("Illegal view create command size.\n");
 338                 return -EINVAL;
 339         }
 340 
 341         if (!vmw_view_id_ok(user_key, view_type)) {
 342                 VMW_DEBUG_USER("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, &ttm_opt_ctx);
 349         if (ret) {
 350                 if (ret != -ERESTARTSYS)
 351                         DRM_ERROR("Out of graphics memory for view creation\n");
 352                 return ret;
 353         }
 354 
 355         view = kmalloc(size, GFP_KERNEL);
 356         if (!view) {
 357                 ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
 358                 return -ENOMEM;
 359         }
 360 
 361         res = &view->res;
 362         view->ctx = ctx;
 363         view->srf = vmw_resource_reference(srf);
 364         view->cotable = vmw_resource_reference
 365                 (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         res->hw_destroy = vmw_hw_view_destroy;
 386 
 387 out_resource_init:
 388         vmw_resource_unreference(&res);
 389 
 390         return ret;
 391 }
 392 
 393 
 394 
 395 
 396 
 397 
 398 
 399 
 400 
 401 
 402 
 403 
 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                 VMW_DEBUG_USER("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 
 422 
 423 
 424 
 425 
 426 
 427 
 428 
 429 
 430 
 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         lockdep_assert_held_once(&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 
 446 
 447 
 448 
 449 
 450 
 451 
 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         lockdep_assert_held_once(&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 
 466 
 467 
 468 
 469 
 470 
 471 
 472 
 473 struct vmw_resource *vmw_view_srf(struct vmw_resource *res)
 474 {
 475         return vmw_view(res)->srf;
 476 }
 477 
 478 
 479 
 480 
 481 
 482 
 483 
 484 
 485 
 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 
 496 
 497 
 498 
 499 
 500 
 501 
 502 
 503 
 504 
 505 
 506 
 507 u32 vmw_view_dirtying(struct vmw_resource *res)
 508 {
 509         static u32 view_is_dirtying[vmw_view_max] = {
 510                 [vmw_view_rt] = VMW_RES_DIRTY_SET,
 511                 [vmw_view_ds] = VMW_RES_DIRTY_SET,
 512         };
 513 
 514         
 515         BUILD_BUG_ON(vmw_view_max != 3);
 516         return view_is_dirtying[vmw_view(res)->view_type];
 517 }
 518 
 519 const u32 vmw_view_destroy_cmds[] = {
 520         [vmw_view_sr] = SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW,
 521         [vmw_view_rt] = SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW,
 522         [vmw_view_ds] = SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW,
 523 };
 524 
 525 const SVGACOTableType vmw_view_cotables[] = {
 526         [vmw_view_sr] = SVGA_COTABLE_SRVIEW,
 527         [vmw_view_rt] = SVGA_COTABLE_RTVIEW,
 528         [vmw_view_ds] = SVGA_COTABLE_DSVIEW,
 529 };
 530 
 531 const SVGACOTableType vmw_so_cotables[] = {
 532         [vmw_so_el] = SVGA_COTABLE_ELEMENTLAYOUT,
 533         [vmw_so_bs] = SVGA_COTABLE_BLENDSTATE,
 534         [vmw_so_ds] = SVGA_COTABLE_DEPTHSTENCIL,
 535         [vmw_so_rs] = SVGA_COTABLE_RASTERIZERSTATE,
 536         [vmw_so_ss] = SVGA_COTABLE_SAMPLER,
 537         [vmw_so_so] = SVGA_COTABLE_STREAMOUTPUT
 538 };
 539 
 540 
 541 
 542 static void vmw_so_build_asserts(void) __attribute__((used));
 543 
 544 
 545 
 546 
 547 
 548 
 549 static void vmw_so_build_asserts(void)
 550 {
 551         
 552         BUILD_BUG_ON(SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW !=
 553                      SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 1);
 554         BUILD_BUG_ON(SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW !=
 555                      SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 2);
 556         BUILD_BUG_ON(SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW !=
 557                      SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 3);
 558         BUILD_BUG_ON(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW !=
 559                      SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 4);
 560         BUILD_BUG_ON(SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW !=
 561                      SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW + 5);
 562 
 563         
 564         BUILD_BUG_ON(sizeof(union vmw_view_destroy) != sizeof(u32));
 565 
 566         
 567         BUILD_BUG_ON(SVGA_COTABLE_MAX_IDS >= ((1 << 20) - 1));
 568 
 569         
 570 
 571 
 572 
 573         BUILD_BUG_ON(offsetof(struct vmw_view_define, sid) !=
 574                      offsetof(SVGA3dCmdDXDefineShaderResourceView, sid));
 575         BUILD_BUG_ON(offsetof(struct vmw_view_define, sid) !=
 576                      offsetof(SVGA3dCmdDXDefineRenderTargetView, sid));
 577         BUILD_BUG_ON(offsetof(struct vmw_view_define, sid) !=
 578                      offsetof(SVGA3dCmdDXDefineDepthStencilView, sid));
 579 }