1 /* 2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved. 3 * Copyright (c) Imagination Technologies Limited, UK 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 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: 26 * Waldo Bastian <waldo.bastian (at) intel.com> 27 * Zeng Li <zeng.li (at) intel.com> 28 * 29 */ 30 31 32 #include "pnw_cmdbuf.h" 33 34 #include <unistd.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <errno.h> 38 #include <string.h> 39 #include <wsbm/wsbm_manager.h> 40 41 #include "psb_def.h" 42 #include "psb_drv_debug.h" 43 #include "pnw_hostcode.h" 44 #include "psb_ws_driver.h" 45 46 /* 47 * Buffer layout: 48 * cmd_base <= cmd_idx < CMD_END() == reloc_base 49 * reloc_base <= reloc_idx < RELOC_END() == (reloc_size) 50 */ 51 52 #define RELOC_END(cmdbuf) (cmdbuf->cmd_base + cmdbuf->size) 53 54 #define CMD_END(cmdbuf) (cmdbuf->reloc_base) 55 56 #define RELOC_SIZE (0x3000) 57 58 #define CMD_SIZE (0x3000) 59 60 #define RELOC_MARGIN (0x0800) 61 62 #define CMD_MARGIN (0x0400) 63 64 65 #define MAX_CMD_COUNT 12 66 67 #define MTX_SEG_SIZE (0x0800) 68 69 70 /* 71 * Create command buffer 72 */ 73 VAStatus pnw_cmdbuf_create( 74 object_context_p obj_context, 75 psb_driver_data_p driver_data, 76 pnw_cmdbuf_p cmdbuf) 77 { 78 context_ENC_p ctx = (context_ENC_p) obj_context->format_data; 79 VAStatus vaStatus = VA_STATUS_SUCCESS; 80 unsigned int size = CMD_SIZE + RELOC_SIZE; 81 82 cmdbuf->size = 0; 83 cmdbuf->cmd_base = NULL; 84 cmdbuf->cmd_idx = NULL; 85 cmdbuf->reloc_base = NULL; 86 cmdbuf->reloc_idx = NULL; 87 cmdbuf->buffer_refs_count = 0; 88 cmdbuf->buffer_refs_allocated = 10; 89 cmdbuf->buffer_refs = (psb_buffer_p *) calloc(1, sizeof(psb_buffer_p) * cmdbuf->buffer_refs_allocated); 90 if (NULL == cmdbuf->buffer_refs) { 91 cmdbuf->buffer_refs_allocated = 0; 92 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 93 } 94 if (VA_STATUS_SUCCESS == vaStatus) { 95 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_only, &cmdbuf->buf); 96 cmdbuf->size = size; 97 } 98 99 if (VA_STATUS_SUCCESS != vaStatus) { 100 free(cmdbuf->buffer_refs); 101 cmdbuf->buffer_refs = NULL; 102 cmdbuf->buffer_refs_allocated = 0; 103 return vaStatus; 104 } 105 106 /* create topaz parameter buffer */ 107 vaStatus = psb_buffer_create(driver_data, ctx->pic_params_size * MAX_TOPAZ_CORES, psb_bt_cpu_vpu, &cmdbuf->pic_params); 108 if (VA_STATUS_SUCCESS != vaStatus) 109 goto error_out5; 110 111 /* create header buffer */ 112 vaStatus = psb_buffer_create(driver_data, ctx->header_buffer_size, psb_bt_cpu_vpu, &cmdbuf->header_mem); 113 if (VA_STATUS_SUCCESS != vaStatus) 114 goto error_out2; 115 116 /* create slice parameter buffer */ 117 vaStatus = psb_buffer_create(driver_data, ctx->sliceparam_buffer_size, psb_bt_cpu_vpu, &cmdbuf->slice_params); 118 if (VA_STATUS_SUCCESS != vaStatus) 119 goto error_out1; 120 121 /* all cmdbuf share one MTX_CURRENT_IN_PARAMS since every MB has a MTX_CURRENT_IN_PARAMS structure 122 * and filling this structure for all MB is very time-consuming 123 */ 124 125 cmdbuf->topaz_in_params_I = &ctx->topaz_in_params_I; 126 cmdbuf->topaz_in_params_P = &ctx->topaz_in_params_P; 127 128 cmdbuf->topaz_below_params = &ctx->topaz_below_params; 129 cmdbuf->topaz_above_params = &ctx->topaz_above_params; 130 131 return vaStatus; 132 133 error_out1: 134 psb_buffer_destroy(&cmdbuf->header_mem); 135 error_out2: 136 psb_buffer_destroy(&cmdbuf->pic_params); 137 error_out5: 138 pnw_cmdbuf_destroy(cmdbuf); 139 140 return vaStatus; 141 } 142 143 /* 144 * Destroy buffer 145 */ 146 void pnw_cmdbuf_destroy(pnw_cmdbuf_p cmdbuf) 147 { 148 if (cmdbuf->size) { 149 psb_buffer_destroy(&cmdbuf->buf); 150 cmdbuf->size = 0; 151 } 152 if (cmdbuf->buffer_refs_allocated) { 153 free(cmdbuf->buffer_refs); 154 cmdbuf->buffer_refs = NULL; 155 cmdbuf->buffer_refs_allocated = 0; 156 } 157 158 psb_buffer_destroy(&cmdbuf->pic_params); 159 psb_buffer_destroy(&cmdbuf->header_mem); 160 psb_buffer_destroy(&cmdbuf->slice_params); 161 162 } 163 164 /* 165 * Reset buffer & map 166 * 167 * Returns 0 on success 168 */ 169 int pnw_cmdbuf_reset(pnw_cmdbuf_p cmdbuf) 170 { 171 int ret; 172 173 cmdbuf->cmd_base = NULL; 174 cmdbuf->cmd_idx = NULL; 175 cmdbuf->reloc_base = NULL; 176 cmdbuf->reloc_idx = NULL; 177 178 cmdbuf->buffer_refs_count = 0; 179 cmdbuf->cmd_count = 0; 180 181 ret = psb_buffer_map(&cmdbuf->buf, &cmdbuf->cmd_base); 182 if (ret) { 183 return ret; 184 } 185 186 cmdbuf->cmd_start = cmdbuf->cmd_base; 187 cmdbuf->cmd_idx = (uint32_t *) cmdbuf->cmd_base; 188 189 cmdbuf->reloc_base = cmdbuf->cmd_base + CMD_SIZE; 190 cmdbuf->reloc_idx = (struct drm_psb_reloc *) cmdbuf->reloc_base; 191 192 /* Add ourselves to the buffer list */ 193 pnw_cmdbuf_buffer_ref(cmdbuf, &cmdbuf->buf); /* cmd buf == 0 */ 194 return ret; 195 } 196 197 /* 198 * Unmap buffer 199 * 200 * Returns 0 on success 201 */ 202 int pnw_cmdbuf_unmap(pnw_cmdbuf_p cmdbuf) 203 { 204 cmdbuf->cmd_base = NULL; 205 cmdbuf->cmd_start = NULL; 206 cmdbuf->cmd_idx = NULL; 207 cmdbuf->reloc_base = NULL; 208 cmdbuf->reloc_idx = NULL; 209 cmdbuf->cmd_count = 0; 210 psb_buffer_unmap(&cmdbuf->buf); 211 return 0; 212 } 213 214 215 /* 216 * Reference an addtional buffer "buf" in the command stream 217 * Returns a reference index that can be used to refer to "buf" in 218 * relocation records, -1 on error 219 */ 220 int pnw_cmdbuf_buffer_ref(pnw_cmdbuf_p cmdbuf, psb_buffer_p buf) 221 { 222 int item_loc = 0; 223 224 /*Reserve the same TTM BO twice will cause kernel lock up*/ 225 while ((item_loc < cmdbuf->buffer_refs_count) 226 && (wsbmKBufHandle(wsbmKBuf(cmdbuf->buffer_refs[item_loc]->drm_buf)) 227 != wsbmKBufHandle(wsbmKBuf(buf->drm_buf)))) 228 //while( (item_loc < cmdbuf->buffer_refs_count) && (cmdbuf->buffer_refs[item_loc] != buf) ) 229 { 230 item_loc++; 231 } 232 if (item_loc == cmdbuf->buffer_refs_count) { 233 /* Add new entry */ 234 if (item_loc >= cmdbuf->buffer_refs_allocated) { 235 /* Allocate more entries */ 236 int new_size = cmdbuf->buffer_refs_allocated + 10; 237 psb_buffer_p *new_array; 238 new_array = (psb_buffer_p *) calloc(1, sizeof(psb_buffer_p) * new_size); 239 if (NULL == new_array) { 240 return -1; /* Allocation failure */ 241 } 242 memcpy(new_array, cmdbuf->buffer_refs, sizeof(psb_buffer_p) * cmdbuf->buffer_refs_allocated); 243 free(cmdbuf->buffer_refs); 244 cmdbuf->buffer_refs_allocated = new_size; 245 cmdbuf->buffer_refs = new_array; 246 } 247 cmdbuf->buffer_refs[item_loc] = buf; 248 cmdbuf->buffer_refs_count++; 249 buf->status = psb_bs_queued; 250 } 251 return item_loc; 252 } 253 254 /* Creates a relocation record for a DWORD in the mapped "cmdbuf" at address 255 * "addr_in_cmdbuf" 256 * The relocation is based on the device virtual address of "ref_buffer" 257 * "buf_offset" is be added to the device virtual address, and the sum is then 258 * right shifted with "align_shift". 259 * "mask" determines which bits of the target DWORD will be updated with the so 260 * constructed address. The remaining bits will be filled with bits from "background". 261 */ 262 void pnw_cmdbuf_add_relocation(pnw_cmdbuf_p cmdbuf, 263 uint32_t *addr_in_dst_buffer,/*addr of dst_buffer for the DWORD*/ 264 psb_buffer_p ref_buffer, 265 uint32_t buf_offset, 266 uint32_t mask, 267 uint32_t background, 268 uint32_t align_shift, 269 uint32_t dst_buffer, 270 uint32_t *start_of_dst_buffer) /*Index of the list refered by cmdbuf->buffer_refs */ 271 { 272 struct drm_psb_reloc *reloc = cmdbuf->reloc_idx; 273 uint64_t presumed_offset = wsbmBOOffsetHint(ref_buffer->drm_buf); 274 275 reloc->where = addr_in_dst_buffer - start_of_dst_buffer; /* Offset in DWORDs */ 276 277 reloc->buffer = pnw_cmdbuf_buffer_ref(cmdbuf, ref_buffer); 278 ASSERT(reloc->buffer != -1); 279 280 reloc->reloc_op = PSB_RELOC_OP_OFFSET; 281 #ifndef VA_EMULATOR 282 if (presumed_offset) { 283 uint32_t new_val = presumed_offset + buf_offset; 284 285 new_val = ((new_val >> align_shift) << (align_shift << PSB_RELOC_ALSHIFT_SHIFT)); 286 new_val = (background & ~mask) | (new_val & mask); 287 *addr_in_dst_buffer = new_val; 288 } else { 289 *addr_in_dst_buffer = PSB_RELOC_MAGIC; 290 } 291 #else 292 /* indicate subscript of relocation buffer */ 293 *addr_in_dst_buffer = reloc - (struct drm_psb_reloc *)cmdbuf->reloc_base; 294 #endif 295 reloc->mask = mask; 296 reloc->shift = align_shift << PSB_RELOC_ALSHIFT_SHIFT; 297 reloc->pre_add = buf_offset; 298 reloc->background = background; 299 reloc->dst_buffer = dst_buffer; 300 cmdbuf->reloc_idx++; 301 302 ASSERT(((unsigned char *)(cmdbuf->reloc_idx)) < RELOC_END(cmdbuf)); 303 } 304 305 /* Prepare one command package */ 306 void pnw_cmdbuf_insert_command_package(object_context_p obj_context, 307 int32_t core, 308 uint32_t cmd_id, 309 psb_buffer_p command_data, 310 uint32_t offset) 311 { 312 uint32_t cmd_word; 313 context_ENC_p ctx = (context_ENC_p) obj_context->format_data; 314 pnw_cmdbuf_p cmdbuf = obj_context->pnw_cmdbuf; 315 int interrupt_flags; 316 317 /* only MTX_CMDID_END_PIC by master core generate interrupt */ 318 interrupt_flags = (cmd_id == MTX_CMDID_END_PIC) | (core == 0); 319 interrupt_flags = 0; /*CMD composed by user space does not generate Interrupt*/ 320 321 /* Calculate command word */ 322 cmd_id &= MTX_CMDWORD_ID_MASK; 323 core &= MTX_CMDWORD_CORE_MASK; 324 325 core %= MAX_TOPAZ_CORES; 326 327 cmd_word = ((ctx->CmdCount & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT) 328 | ((0 & MTX_CMDWORD_INT_MASK) << MTX_CMDWORD_INT_SHIFT) /* Do not generate interrupt */ 329 | (core << MTX_CMDWORD_CORE_SHIFT) 330 | (cmd_id << MTX_CMDWORD_ID_SHIFT); 331 332 /* write command word into cmdbuf */ 333 *cmdbuf->cmd_idx++ = cmd_word; 334 335 /* Command data address */ 336 if (command_data) { 337 RELOC_CMDBUF_PNW(cmdbuf->cmd_idx, offset, command_data); 338 cmdbuf->cmd_idx++; 339 } else { 340 *cmdbuf->cmd_idx++ = 0; 341 } 342 343 344 *cmdbuf->cmd_idx++ = 0; /* Write back buffer address */ 345 346 *cmdbuf->cmd_idx++ = 0; /*ctx->CmdCount; */ /* Write back value */ 347 348 ctx->LastSync[(ctx->FrmIdx) & 0x1][core] = ctx->CmdCount; 349 350 /* increment the command counter */ 351 ctx->CmdCount = (ctx->CmdCount + 1) % MAX_TOPAZ_CMD_COUNT; 352 } 353 354 /* 355 * Advances "obj_context" to the next cmdbuf 356 * 357 * Returns 0 on success 358 */ 359 int pnw_context_get_next_cmdbuf(object_context_p obj_context) 360 { 361 pnw_cmdbuf_p cmdbuf; 362 int ret; 363 364 if (obj_context->pnw_cmdbuf) { 365 return 0; 366 } 367 368 obj_context->cmdbuf_current++; 369 if (obj_context->cmdbuf_current >= PNW_MAX_CMDBUFS_ENCODE) { 370 obj_context->cmdbuf_current = 0; 371 } 372 373 cmdbuf = obj_context->pnw_cmdbuf_list[obj_context->cmdbuf_current]; 374 ret = pnw_cmdbuf_reset(cmdbuf); 375 if (!ret) { 376 /* Success */ 377 obj_context->pnw_cmdbuf = cmdbuf; 378 } 379 380 /* added pic_params/slice_params into ref, so the index is 1/2 */ 381 pnw_cmdbuf_buffer_ref(cmdbuf, &cmdbuf->pic_params); 382 pnw_cmdbuf_buffer_ref(cmdbuf, &cmdbuf->slice_params); 383 384 return ret; 385 } 386 387 /* 388 * This is the user-space do-it-all interface to the drm cmdbuf ioctl. 389 * It allows different buffers as command- and reloc buffer. A list of 390 * cliprects to apply and whether to copy the clipRect content to all 391 * scanout buffers (damage = 1). 392 */ 393 /* 394 * Don't add debug statements in this function, it gets called with the 395 * DRM lock held and output to an X terminal can cause X to deadlock 396 */ 397 static int 398 pnwDRMCmdBuf(int fd, int ioctl_offset, psb_buffer_p *buffer_list, int buffer_count, unsigned cmdBufHandle, 399 unsigned cmdBufOffset, unsigned cmdBufSize, 400 unsigned relocBufHandle, unsigned relocBufOffset, 401 unsigned numRelocs, int __maybe_unused damage, 402 unsigned engine, unsigned fence_flags, struct psb_ttm_fence_rep *fence_rep) 403 { 404 drm_psb_cmdbuf_arg_t ca; 405 struct psb_validate_arg *arg_list; 406 int i; 407 int ret; 408 uint64_t mask = PSB_GPU_ACCESS_MASK; 409 410 arg_list = (struct psb_validate_arg *) calloc(1, sizeof(struct psb_validate_arg) * buffer_count); 411 if (arg_list == NULL) { 412 drv_debug_msg(VIDEO_DEBUG_ERROR, "Allocate memory failed\n"); 413 return -ENOMEM; 414 } 415 416 for (i = 0; i < buffer_count; i++) { 417 struct psb_validate_arg *arg = &(arg_list[i]); 418 struct psb_validate_req *req = &arg->d.req; 419 420 req->next = (unsigned long) & (arg_list[i+1]); 421 422 req->buffer_handle = wsbmKBufHandle(wsbmKBuf(buffer_list[i]->drm_buf)); 423 //req->group = 0; 424 req->set_flags = (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE) & mask; 425 req->clear_flags = (~(PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)) & mask; 426 #if 1 427 req->presumed_gpu_offset = (uint64_t)wsbmBOOffsetHint(buffer_list[i]->drm_buf); 428 req->presumed_flags = PSB_USE_PRESUMED; 429 #else 430 req->presumed_flags = 0; 431 #endif 432 req->pad64 = (uint32_t)buffer_list[i]->pl_flags; 433 } 434 arg_list[buffer_count-1].d.req.next = 0; 435 436 ca.buffer_list = (uint64_t)((unsigned long)arg_list); 437 ca.cmdbuf_handle = cmdBufHandle; 438 ca.cmdbuf_offset = cmdBufOffset; 439 ca.cmdbuf_size = cmdBufSize; 440 ca.reloc_handle = relocBufHandle; 441 ca.reloc_offset = relocBufOffset; 442 ca.num_relocs = numRelocs; 443 ca.engine = engine; 444 ca.fence_flags = fence_flags; 445 ca.fence_arg = (uint64_t)((unsigned long)fence_rep); 446 447 do { 448 ret = drmCommandWrite(fd, ioctl_offset, &ca, sizeof(ca)); 449 } while (ret == EAGAIN); 450 451 if (ret) 452 goto out; 453 454 for (i = 0; i < buffer_count; i++) { 455 struct psb_validate_arg *arg = &(arg_list[i]); 456 struct psb_validate_rep *rep = &arg->d.rep; 457 458 if (!arg->handled) { 459 ret = -EFAULT; 460 goto out; 461 } 462 if (arg->ret != 0) { 463 ret = arg->ret; 464 goto out; 465 } 466 wsbmUpdateKBuf(wsbmKBuf(buffer_list[i]->drm_buf), 467 rep->gpu_offset, rep->placement, rep->fence_type_mask); 468 } 469 out: 470 free(arg_list); 471 for (i = 0; i < buffer_count; i++) { 472 /* 473 * Buffer no longer queued in userspace 474 */ 475 switch (buffer_list[i]->status) { 476 case psb_bs_queued: 477 buffer_list[i]->status = psb_bs_ready; 478 break; 479 480 case psb_bs_abandoned: 481 psb_buffer_destroy(buffer_list[i]); 482 free(buffer_list[i]); 483 break; 484 485 default: 486 /* Not supposed to happen */ 487 ASSERT(0); 488 } 489 } 490 491 return ret; 492 } 493 494 #if 0 495 static struct _WsbmFenceObject * 496 lnc_fence_wait(psb_driver_data_p driver_data, 497 struct psb_ttm_fence_rep *fence_rep, int *status) 498 499 { 500 struct _WsbmFenceObject *fence = NULL; 501 int ret = -1; 502 503 /* copy fence information */ 504 if (fence_rep->error != 0) { 505 drv_debug_msg(VIDEO_DEBUG_ERROR, "drm failed to create a fence" 506 " and has idled the HW\n"); 507 DEBUG_FAILURE_RET; 508 return NULL; 509 } 510 511 fence = wsbmFenceCreate(driver_data->fence_mgr, fence_rep->fence_class, 512 fence_rep->fence_type, 513 (unsigned char *)fence_rep->handle, 514 0); 515 if (fence) 516 *status = wsbmFenceFinish(fence, fence_rep->fence_type, 0); 517 518 return fence; 519 } 520 #endif 521 522 /* 523 * Submits the current cmdbuf 524 * 525 * Returns 0 on success 526 */ 527 int pnw_context_submit_cmdbuf(object_context_p __maybe_unused obj_context) 528 { 529 return 0; 530 } 531 532 533 534 /* 535 * FrameSkip is only meaningful for RC enabled mode 536 * Topaz raises this flag after surface N encoding is finished (vaSyncSurface gets back) 537 * then for the next encode surface N+1 (ctx->src_surface) frameskip flag is cleared in vaBeginPicuture 538 * and is always set in vaEndPicture:lnc_PatchRCMode 539 * vaQuerySurfaceStatus is supposed only to be called after vaEndPicture/vaSyncSurface, 540 * The caller should ensure the surface pertains to an encode context 541 */ 542 int pnw_surface_get_frameskip(psb_driver_data_p __maybe_unused driver_data, 543 psb_surface_p surface, 544 int *frame_skip) 545 { 546 /* bit31 indicate if frameskip is already settled, it is used to record the frame skip flag for old surfaces 547 * bit31 is cleared when the surface is used as encode render target or reference/reconstrucure target 548 */ 549 if (GET_SURFACE_INFO_skipped_flag(surface) & SURFACE_INFO_SKIP_FLAG_SETTLED) { 550 *frame_skip = GET_SURFACE_INFO_skipped_flag(surface) & 1; 551 } else 552 *frame_skip = 0; 553 554 return 0; 555 } 556 557 558 /* 559 * Flushes all cmdbufs 560 */ 561 int pnw_context_flush_cmdbuf(object_context_p obj_context) 562 { 563 pnw_cmdbuf_p cmdbuf = obj_context->pnw_cmdbuf; 564 psb_driver_data_p driver_data = obj_context->driver_data; 565 unsigned int fence_flags; 566 struct psb_ttm_fence_rep fence_rep; 567 unsigned int reloc_offset; 568 unsigned int num_relocs; 569 int ret; 570 unsigned int cmdbuffer_size = (unsigned char *) cmdbuf->cmd_idx - cmdbuf->cmd_start; /* In bytes */ 571 572 ASSERT(cmdbuffer_size < CMD_SIZE); 573 ASSERT((unsigned char *) cmdbuf->cmd_idx < CMD_END(cmdbuf)); 574 /* LOCK */ 575 ret = LOCK_HARDWARE(driver_data); 576 if (ret) { 577 UNLOCK_HARDWARE(driver_data); 578 DEBUG_FAILURE_RET; 579 return ret; 580 } 581 582 /* Now calculate the total number of relocations */ 583 reloc_offset = cmdbuf->reloc_base - cmdbuf->cmd_base; 584 num_relocs = (((unsigned char *) cmdbuf->reloc_idx) - cmdbuf->reloc_base) / sizeof(struct drm_psb_reloc); 585 586 pnw_cmdbuf_unmap(cmdbuf); 587 588 ASSERT(NULL == cmdbuf->reloc_base); 589 590 if (psb_video_trace_fp) 591 fence_flags = 0; 592 else 593 fence_flags = DRM_PSB_FENCE_NO_USER; 594 595 #ifndef LNC_ENGINE_ENCODE 596 #define LNC_ENGINE_ENCODE 5 597 #endif 598 599 wsbmWriteLockKernelBO(); 600 ret = pnwDRMCmdBuf(driver_data->drm_fd, driver_data->execIoctlOffset, /* FIXME Still use ioctl cmd? */ 601 cmdbuf->buffer_refs, cmdbuf->buffer_refs_count, wsbmKBufHandle(wsbmKBuf(cmdbuf->buf.drm_buf)), 602 0, cmdbuffer_size,/*unsigned cmdBufSize*/ 603 wsbmKBufHandle(wsbmKBuf(cmdbuf->buf.drm_buf)), reloc_offset, num_relocs, 604 0, LNC_ENGINE_ENCODE, fence_flags, &fence_rep); /* FIXME use LNC_ENGINE_ENCODE */ 605 606 wsbmWriteUnlockKernelBO(); 607 UNLOCK_HARDWARE(driver_data); 608 609 if (ret) { 610 obj_context->pnw_cmdbuf = NULL; 611 612 DEBUG_FAILURE_RET; 613 return ret; 614 } 615 616 #if 0 617 int status = -1; 618 struct _WsbmFenceObject *fence = NULL; 619 620 fence = lnc_fence_wait(driver_data, &fence_rep, &status); 621 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_fence_wait returns: %d (fence=0x%08x)\n", status, fence); 622 623 if (fence) 624 wsbmFenceUnreference(fence); 625 #endif 626 627 obj_context->pnw_cmdbuf = NULL; 628 629 return 0; 630 } 631 632 633 int pnw_get_parallel_core_number(object_context_p obj_context) 634 { 635 636 context_ENC_p ctx = (context_ENC_p)(obj_context->format_data); 637 return ctx->ParallelCores; 638 639 } 640