1 /*
2  * Copyright � 2014 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *     Wei Lin<wei.w.lin@intel.com>
26  *     Yuting Yang<yuting.yang@intel.com>
27  *     Lina Sun<lina.sun@intel.com>
28  *     Zhao Yakui <yakui.zhao@intel.com>
29  */
30 
31 #include "cm_device.h"
32 #include "cm_queue.h"
33 #include "cm_surface_manager.h"
34 #include "cm_program.h"
35 #include "cm_kernel.h"
36 #include "cm_task.h"
37 #include "cm_buffer.h"
38 #include "cm_thread_space.h"
39 #include "cm_debug.h"
40 #include "cm_def.h"
41 #include "cm_group_space.h"
42 #include "cm_surface_2d.h"
43 #include "debugger.h"
44 #include "hal_cm.h"
45 #include "readconf.h"
46 
47 CSync CmDevice_RT::GlobalCriticalSection_Surf2DUserDataLock = CSync();
48 CM_DLL_FILE_VERSION CmDevice_RT::m_RTDllVersion = {(WORD)MANVERSION,
49                                                    (WORD)MANREVISION,
50                                                    (WORD)SUBREVISION,
51                                                    (WORD)BUILD_NUMBER};
52 
Create(CmDriverContext * pDriverContext,CmDevice_RT * & pDevice,UINT DevCreateOption)53 INT CmDevice_RT::Create(CmDriverContext * pDriverContext, CmDevice_RT * &pDevice,
54 		     UINT DevCreateOption)
55 {
56 	INT result = CM_FAILURE;
57 
58 	if (pDevice != NULL) {
59 		pDevice->Acquire();
60 		return CM_SUCCESS;
61 	}
62 
63 	pDevice = new(std::nothrow) CmDevice_RT(DevCreateOption);
64 	if (pDevice) {
65 		pDevice->Acquire();
66 		result = pDevice->Initialize(pDriverContext);
67 		if (result != CM_SUCCESS) {
68 			CM_ASSERT(0);
69 			CmDevice_RT::Destroy(pDevice);
70 			pDevice = NULL;
71 		}
72 	} else {
73 		CM_ASSERT(0);
74 		result = CM_OUT_OF_HOST_MEMORY;
75 	}
76 
77     if (result == CM_SUCCESS)
78         DbgNotifyNewDevice(pDevice);
79 
80 	return result;
81 }
82 
Acquire(void)83 INT CmDevice_RT::Acquire(void)
84 {
85 	CLock locker(m_CriticalSection_DeviceRefCount);
86 
87 	m_CmDeviceRefCount++;
88 	return CM_SUCCESS;
89 }
90 
Release(void)91 INT CmDevice_RT::Release(void)
92 {
93 	CLock locker(m_CriticalSection_DeviceRefCount);
94 
95 	m_CmDeviceRefCount--;
96 
97 	return m_CmDeviceRefCount;
98 }
99 
Destroy(CmDevice_RT * & pDevice)100 INT CmDevice_RT::Destroy(CmDevice_RT * &pDevice)
101 {
102 	INT result = CM_SUCCESS;
103 
104 	INT refCount = pDevice->Release();
105 
106 	if (refCount == 0) {
107         DbgNotifyDeviceDestruction(pDevice);
108 		CmSafeDelete(pDevice);
109 	}
110 
111 	return result;
112 }
113 
CmDevice_RT(UINT DevCreateOption)114  CmDevice_RT::CmDevice_RT(UINT DevCreateOption):
115 m_pUmdContext(NULL),
116 m_pAccelData(NULL),
117 m_AccelSize(0),
118 m_pSurfaceMgr(NULL),
119 m_pQueue(NULL),
120 m_ProgramArray(CM_INIT_PROGRAM_COUNT),
121 m_ProgramCount(0),
122 m_KernelArray(CM_INIT_KERNEL_COUNT),
123 m_KernelCount(0),
124 m_ThreadSpaceArray(CM_INIT_THREADSPACE_COUNT),
125 m_ThreadSpaceCount(0),
126 m_hJITDll(NULL),
127 m_fJITCompile(NULL),
128 m_fFreeBlock(NULL),
129 m_fJITVersion(NULL),
130 m_DDIVersion(0),
131 m_Platform(IGFX_UNKNOWN_CORE),
132 m_CmDeviceRefCount(0),
133 m_ThreadGroupSpaceArray(CM_INIT_THREADGROUPSPACE_COUNT),
134 m_ThreadGroupSpaceCount(0), m_TaskArray(CM_INIT_TASK_COUNT), m_TaskCount(0)
135 {
136         CmSafeMemSet(&m_l3_c, 0, sizeof(L3_CONFIG_REGISTER_VALUES));
137 	InitDevCreateOption(m_DevCreateOption, DevCreateOption);
138 }
139 
~CmDevice_RT(void)140 CmDevice_RT::~CmDevice_RT(void)
141 {
142 	for (UINT i = 0; i < m_KernelCount; i++) {
143 		CmKernel_RT *pKernel = (CmKernel_RT *) m_KernelArray.GetElement(i);
144 		if (pKernel) {
145 			CmProgram_RT *pProgram = NULL;
146 			pKernel->GetCmProgram(pProgram);
147 			UINT indexInProgramArray;
148 			for (indexInProgramArray = 0;
149 			     indexInProgramArray < m_ProgramCount;
150 			     indexInProgramArray++) {
151 				if (pProgram ==
152 				    m_ProgramArray.GetElement
153 				    (indexInProgramArray)) {
154 					break;
155 				}
156 			}
157 			CmKernel_RT::Destroy(pKernel, pProgram);
158 			if ((pProgram == NULL)
159 			    && (indexInProgramArray < m_ProgramCount)) {
160 				m_ProgramArray.SetElement(indexInProgramArray,
161 							  NULL);
162 			}
163 		}
164 	}
165 	m_KernelArray.Delete();
166 
167 	for (UINT i = 0; i < m_ProgramCount; i++) {
168 		CmProgram_RT *pProgram =
169 		    (CmProgram_RT *) m_ProgramArray.GetElement(i);
170 		while (pProgram) {
171 			CmProgram_RT::Destroy(pProgram);
172 		}
173 	}
174 	m_ProgramArray.Delete();
175 
176 	UINT ThreadSpaceArrayUsedSize = m_ThreadSpaceArray.GetSize();
177 	for (UINT i = 0; i < ThreadSpaceArrayUsedSize; i++) {
178 		CmThreadSpace *pTS_RT =
179 		    (CmThreadSpace *) m_ThreadSpaceArray.GetElement(i);
180 		if (pTS_RT) {
181 			CmThreadSpace::Destroy(pTS_RT);
182 		}
183 	}
184 	m_ThreadSpaceArray.Delete();
185 
186 	for (UINT i = 0; i < m_ThreadGroupSpaceCount; i++) {
187 		CmThreadGroupSpace *pTGS = (CmThreadGroupSpace *)
188 		    m_ThreadGroupSpaceArray.GetElement(i);
189 		if (pTGS) {
190 			CmThreadGroupSpace_RT::Destroy(pTGS);
191 		}
192 	}
193 	m_ThreadGroupSpaceArray.Delete();
194 
195 	UINT TaskArrayUsedSize = m_TaskArray.GetSize();
196 	for (UINT i = 0; i < TaskArrayUsedSize; i++) {
197 		CmTask_RT *pTask = (CmTask_RT *) m_TaskArray.GetElement(i);
198 		if (pTask) {
199 			CmTask_RT::Destroy(pTask);
200 		}
201 	}
202 	m_TaskArray.Delete();
203 
204 	CmSurfaceManager::Destroy(m_pSurfaceMgr);
205 	DestroyQueue(m_pQueue);
206 
207 	if (m_hJITDll) {
208 		FreeLibrary(m_hJITDll);
209 	}
210 
211 	DestroyAuxDevice();
212 };
213 
Initialize(CmDriverContext * pDriverContext)214 INT CmDevice_RT::Initialize(CmDriverContext * pDriverContext)
215 {
216 	INT result = CreateAuxDevice(pDriverContext);
217 
218 	if (result != CM_SUCCESS) {
219 		CM_ASSERT(0);
220 		return result;
221 	}
222 
223 	m_pSurfaceMgr = NULL;
224 	result = CmSurfaceManager::Create(this,
225 					  m_HalMaxValues,
226 					  m_HalMaxValuesEx, m_pSurfaceMgr);
227 
228 	if (result != CM_SUCCESS) {
229 		CM_ASSERT(0);
230 		return result;
231 	}
232 
233 	result = CreateQueue_Internel();
234 	if (result != CM_SUCCESS) {
235 		CM_ASSERT(0);
236 		return result;
237 	}
238 
239 	return result;
240 }
241 
CreateAuxDevice(CmDriverContext * pDriverContext)242 INT CmDevice_RT::CreateAuxDevice(CmDriverContext * pDriverContext)
243 {
244 	INT hr = CM_SUCCESS;
245 	PCM_HAL_STATE pCmHalState;
246 	PCM_CONTEXT pCmCtx;
247 	PGENOS_CONTEXT pOsContext;
248 
249 	pOsContext =
250 	    (PGENOS_CONTEXT) GENOS_AllocAndZeroMemory(sizeof(GENOS_CONTEXT));
251 	CMCHK_NULL(pOsContext);
252 
253 	if (pDriverContext) {
254 		pOsContext->wDeviceID = pDriverContext->deviceid;
255 		pOsContext->wRevision = pDriverContext->device_rev;
256 		pOsContext->bufmgr = pDriverContext->bufmgr;
257 	}
258 
259 	m_pUmdContext = pOsContext;
260 
261 	CHK_GENOSSTATUS_RETURN_CMERROR(HalCm_Create
262 				       (pOsContext, &m_DevCreateOption,
263 					&pCmHalState));
264 
265 	CHK_GENOSSTATUS_RETURN_CMERROR(pCmHalState->pfnCmAllocate(pCmHalState));
266 
267 	pCmCtx = (PCM_CONTEXT) GENOS_AllocAndZeroMemory(sizeof(CM_CONTEXT));
268 	CMCHK_NULL(pCmCtx);
269 	pCmCtx->GenHwDrvCtx = *pOsContext;
270 	pCmCtx->pCmHalState = pCmHalState;
271 
272 	m_pAccelData = (PVOID) pCmCtx;
273 
274 	CMCHK_HR_MESSAGE(GetMaxValueFromCaps(m_HalMaxValues, m_HalMaxValuesEx),
275 			 "Failed to get Max values.");
276 	CMCHK_HR_MESSAGE(GetGenPlatform(m_Platform), "Failed to get GPU type.");
277 
278 	m_DDIVersion = VA_CM_VERSION;
279 
280  finish:
281 	return hr;
282 }
283 
DestroyAuxDevice()284 INT CmDevice_RT::DestroyAuxDevice()
285 {
286 	PCM_CONTEXT pCmData = (PCM_CONTEXT) m_pAccelData;
287 
288 	if (pCmData && pCmData->pCmHalState) {
289 		HalCm_Destroy(pCmData->pCmHalState);
290 		GENOS_FreeMemory(pCmData);
291 	}
292 
293 	if (m_pUmdContext) {
294 		GENOS_FreeMemAndSetNull(m_pUmdContext);
295 	}
296 
297 	return CM_SUCCESS;
298 }
299 
CreateBuffer(UINT size,CmBuffer * & pSurface)300 CM_RT_API INT CmDevice_RT::CreateBuffer(UINT size, CmBuffer * &pSurface)
301 {
302 	if ((size < CM_MIN_SURF_WIDTH) || (size > CM_MAX_1D_SURF_WIDTH)) {
303 		CM_ASSERT(0);
304 		return CM_INVALID_WIDTH;
305 	}
306 
307 	CLock locker(m_CriticalSection_Surface);
308 
309 	CmBuffer_RT *p = NULL;
310 	VOID *pSysMem = NULL;
311 	int result = m_pSurfaceMgr->CreateBuffer(size, CM_BUFFER_N, p, NULL,
312 						 pSysMem);
313 	pSurface = static_cast < CmBuffer * >(p);
314 
315 	return result;
316 }
317 
318 CM_RT_API INT
CreateBuffer(CmOsResource * pCmOsResource,CmBuffer * & pSurface)319     CmDevice_RT::CreateBuffer(CmOsResource * pCmOsResource, CmBuffer * &pSurface)
320 {
321 	INT result = CM_SUCCESS;
322 	if (pCmOsResource == NULL) {
323 		return CM_INVALID_GENOS_RESOURCE_HANDLE;
324 	}
325 
326 	CLock locker(m_CriticalSection_Surface);
327 	CmBuffer_RT *pBufferRT = NULL;
328 	VOID *pSysMem = NULL;
329 	result =
330 	    m_pSurfaceMgr->CreateBuffer(pCmOsResource->orig_width, CM_BUFFER_N,
331 					pBufferRT, pCmOsResource, pSysMem);
332 
333 	pSurface = static_cast < CmBuffer * >(pBufferRT);
334 
335 	return result;
336 }
337 
338 CM_RT_API INT
CreateBufferUP(UINT size,void * pSysMem,CmBufferUP * & pSurface)339     CmDevice_RT::CreateBufferUP(UINT size, void *pSysMem, CmBufferUP * &pSurface)
340 {
341 	if ((size < CM_MIN_SURF_WIDTH) || (size > CM_MAX_1D_SURF_WIDTH)) {
342 		CM_ASSERT(0);
343 		return CM_INVALID_WIDTH;
344 	}
345 
346 	CLock locker(m_CriticalSection_Surface);
347 
348 	CmBuffer_RT *p = NULL;
349 	int result = m_pSurfaceMgr->CreateBuffer(size, CM_BUFFER_UP, p, NULL,
350 						 pSysMem);
351 	pSurface = static_cast < CmBufferUP * >(p);
352 
353 	return result;
354 }
355 
DestroyBufferUP(CmBufferUP * & pSurface)356 CM_RT_API INT CmDevice_RT::DestroyBufferUP(CmBufferUP * &pSurface)
357 {
358 	CmBuffer_RT *temp = NULL;
359 	if (pSurface && (pSurface->Type() == CM_ENUM_CLASS_TYPE_CMBUFFER_RT)) {
360 		temp = static_cast < CmBuffer_RT * >(pSurface);
361 	} else {
362 		return CM_FAILURE;
363 	}
364 
365 	CLock locker(m_CriticalSection_Surface);
366 
367 	INT status = m_pSurfaceMgr->DestroySurface(temp, APP_DESTROY);
368 
369 	if (status != CM_FAILURE) {
370 		pSurface = NULL;
371 		return CM_SUCCESS;
372 	} else {
373 		return CM_FAILURE;
374 	}
375 	return status;
376 }
377 
ForceDestroyBufferUP(CmBufferUP * & pSurface)378 CM_RT_API INT CmDevice_RT::ForceDestroyBufferUP(CmBufferUP * &pSurface)
379 {
380 	CmBuffer_RT *temp = NULL;
381 	if (pSurface && (pSurface->Type() == CM_ENUM_CLASS_TYPE_CMBUFFER_RT)) {
382 		temp = static_cast < CmBuffer_RT * >(pSurface);
383 	} else {
384 		return CM_FAILURE;
385 	}
386 
387 	CLock locker(m_CriticalSection_Surface);
388 
389 	INT status = m_pSurfaceMgr->DestroySurface(temp, FORCE_DESTROY);
390 
391 	if (status == CM_SUCCESS) {
392 		pSurface = NULL;
393 	}
394 	return status;
395 }
396 
DestroyBufferUP(CmBufferUP * & pSurface,INT iIndexInPool,INT iSurfaceID,SURFACE_DESTROY_KIND kind)397 INT CmDevice_RT::DestroyBufferUP(CmBufferUP * &pSurface, INT iIndexInPool,
398 			      INT iSurfaceID, SURFACE_DESTROY_KIND kind)
399 {
400 	CmBuffer_RT *temp = NULL;
401 
402 	CLock locker(m_CriticalSection_Surface);
403 	INT currentID = m_pSurfaceMgr->GetSurfaceIdInPool(iIndexInPool);
404 	if (currentID > iSurfaceID) {
405 		return CM_SUCCESS;
406 	}
407 
408 	if (pSurface && (pSurface->Type() == CM_ENUM_CLASS_TYPE_CMBUFFER_RT)) {
409 		temp = static_cast < CmBuffer_RT * >(pSurface);
410 	} else {
411 		return CM_FAILURE;
412 	}
413 
414 	INT status = m_pSurfaceMgr->DestroySurface(temp, kind);
415 
416 	if (status == CM_SUCCESS) {
417 		pSurface = NULL;
418 	}
419 
420 	return status;
421 }
422 
423 CM_RT_API INT
CreateSurface2DUP(UINT width,UINT height,CM_SURFACE_FORMAT format,void * pSysMem,CmSurface2DUP * & pSurface)424     CmDevice_RT::CreateSurface2DUP(UINT width, UINT height,
425 				CM_SURFACE_FORMAT format, void *pSysMem,
426 				CmSurface2DUP * &pSurface)
427 {
428 	INT result = m_pSurfaceMgr->Surface2DSanityCheck(width, height, format);
429 	if (result != CM_SUCCESS) {
430 		CM_ASSERT(0);
431 		return result;
432 	}
433 
434 	CLock locker(m_CriticalSection_Surface);
435 	CmSurface2DUP_RT* pSurface_RT = NULL;
436 	result = m_pSurfaceMgr->CreateSurface2DUP(width, height, format, pSysMem, pSurface_RT);
437 	pSurface=(static_cast<CmSurface2DUP *>(pSurface_RT));
438     return result;
439 }
440 
441 CM_RT_API INT
CreateSurface2D(UINT width,UINT height,CM_SURFACE_FORMAT format,CmSurface2D * & pSurface)442     CmDevice_RT::CreateSurface2D(UINT width, UINT height, CM_SURFACE_FORMAT format,
443 			      CmSurface2D * &pSurface)
444 {       INT result;
445 	CLock locker(m_CriticalSection_Surface);
446         CmSurface2D_RT* pSurface_RT = NULL;
447 	result=m_pSurfaceMgr->CreateSurface2D(width, height, 0, TRUE, format,
448 					      pSurface_RT);
449 	pSurface=(static_cast<CmSurface2D *>(pSurface_RT));
450 	return result;
451 }
452 
453 CM_RT_API INT
CreateSurface2D(CmOsResource * pCmOsResource,CmSurface2D * & pSurface)454     CmDevice_RT::CreateSurface2D(CmOsResource * pCmOsResource,
455 			      CmSurface2D * &pSurface)
456 {
457 	INT result;
458 	if (pCmOsResource == NULL) {
459 		return CM_INVALID_GENOS_RESOURCE_HANDLE;
460 	}
461 
462 	CLock locker(m_CriticalSection_Surface);
463         CmSurface2D_RT* pSurface_RT = NULL;
464 	result=m_pSurfaceMgr->CreateSurface2D(pCmOsResource, FALSE, pSurface_RT);
465 	pSurface=(static_cast<CmSurface2D *>(pSurface_RT));
466 	return result;
467 }
468 
DestroySurface(CmBuffer * & pSurface,INT iIndexInPool,INT iSurfaceID,SURFACE_DESTROY_KIND kind)469 INT CmDevice_RT::DestroySurface(CmBuffer * &pSurface, INT iIndexInPool,
470 			     INT iSurfaceID, SURFACE_DESTROY_KIND kind)
471 {
472 	CLock locker(m_CriticalSection_Surface);
473 	INT currentID = m_pSurfaceMgr->GetSurfaceIdInPool(iIndexInPool);
474 	if (currentID > iSurfaceID) {
475 		return CM_SUCCESS;
476 	}
477 
478 	CmBuffer_RT *temp = NULL;
479 	if (pSurface && (pSurface->Type() == CM_ENUM_CLASS_TYPE_CMBUFFER_RT)) {
480 		temp = static_cast < CmBuffer_RT * >(pSurface);
481 	}
482 
483 	if (temp == NULL) {
484 		return CM_FAILURE;
485 	}
486 
487 	INT status = m_pSurfaceMgr->DestroySurface(temp, kind);
488 
489 	if (status == CM_SUCCESS) {
490 		pSurface = NULL;
491 	}
492 
493 	return status;
494 }
495 
DestroySurface(CmBuffer * & pSurface)496 CM_RT_API INT CmDevice_RT::DestroySurface(CmBuffer * &pSurface)
497 {
498 	CmBuffer_RT *temp = NULL;
499 	if (pSurface && (pSurface->Type() == CM_ENUM_CLASS_TYPE_CMBUFFER_RT)) {
500 		temp = static_cast < CmBuffer_RT * >(pSurface);
501 	} else {
502 		return CM_FAILURE;
503 	}
504 
505 	CLock locker(m_CriticalSection_Surface);
506 
507 	INT status = m_pSurfaceMgr->DestroySurface(temp, APP_DESTROY);
508 
509 	if (status != CM_FAILURE) {
510 		pSurface = NULL;
511 		return CM_SUCCESS;
512 	} else {
513 		return CM_FAILURE;
514 	}
515 }
516 
DestroySurface(CmSurface2DUP * & pSurface)517 CM_RT_API INT CmDevice_RT::DestroySurface(CmSurface2DUP * &pSurface)
518 {
519 	CLock locker(m_CriticalSection_Surface);
520 	CmSurface2DUP_RT *pSurface_RT = static_cast<CmSurface2DUP_RT *>(pSurface);
521 	if(pSurface_RT == NULL) {
522 			return CM_FAILURE;
523 	}
524 	INT status = m_pSurfaceMgr->DestroySurface(pSurface_RT, APP_DESTROY);
525 
526 	if (status != CM_FAILURE) {
527 		pSurface = NULL;
528 		return CM_SUCCESS;
529 	} else {
530 		return CM_FAILURE;
531 	}
532 }
533 
DestroySurface(CmSurface2DUP * & pSurface,INT iIndexInPool,INT iSurfaceID,SURFACE_DESTROY_KIND kind)534 INT CmDevice_RT::DestroySurface(CmSurface2DUP * &pSurface, INT iIndexInPool,
535 			     INT iSurfaceID, SURFACE_DESTROY_KIND kind)
536 {
537 	CLock locker(m_CriticalSection_Surface);
538 	INT currentID = m_pSurfaceMgr->GetSurfaceIdInPool(iIndexInPool);
539 	if (currentID > iSurfaceID) {
540 		return CM_SUCCESS;
541 	}
542 	CmSurface2DUP_RT *pSurface_RT = static_cast<CmSurface2DUP_RT *>(pSurface);
543 	if(pSurface_RT == NULL) {
544 			return CM_FAILURE;
545 	}
546 	INT status = m_pSurfaceMgr->DestroySurface(pSurface_RT, kind);
547 
548 	if (status == CM_SUCCESS) {
549 		pSurface = NULL;
550 	}
551 	return status;
552 }
553 
DestroySurface(CmSurface2D * & pSurface,INT iIndexInPool,INT iSurfaceID,SURFACE_DESTROY_KIND kind)554 INT CmDevice_RT::DestroySurface(CmSurface2D * &pSurface, INT iIndexInPool,
555 			     INT iSurfaceID, SURFACE_DESTROY_KIND kind)
556 {
557 	CLock locker(m_CriticalSection_Surface);
558 
559 	INT currentID = m_pSurfaceMgr->GetSurfaceIdInPool(iIndexInPool);
560 	if (currentID > iSurfaceID) {
561 		return CM_SUCCESS;
562 	}
563 	CmSurface2D_RT *pSurface_RT = static_cast<CmSurface2D_RT *>(pSurface);
564 	INT status = m_pSurfaceMgr->DestroySurface(pSurface_RT, kind);
565 
566 	if (status == CM_SUCCESS) {
567 		pSurface = NULL;
568 	}
569 
570 	return status;
571 }
572 
DestroySurface(CmSurface2D * & pSurface)573 CM_RT_API INT CmDevice_RT::DestroySurface(CmSurface2D * &pSurface)
574 {
575 	CLock locker(m_CriticalSection_Surface);
576 
577 	CmSurface2D_RT *pSurface_RT = static_cast<CmSurface2D_RT *>(pSurface);
578 	INT status = m_pSurfaceMgr->DestroySurface(pSurface_RT, APP_DESTROY);
579 
580 	if (status != CM_FAILURE) {
581 		pSurface = NULL;
582 		return CM_SUCCESS;
583 	} else {
584 		return CM_FAILURE;
585 	}
586 
587 	return status;
588 }
589 
GetRTDllVersion(CM_DLL_FILE_VERSION * pFileVersion)590 CM_RT_API INT CmDevice_RT::GetRTDllVersion(CM_DLL_FILE_VERSION* pFileVersion)
591 {
592     if (pFileVersion)
593     {
594         pFileVersion->wMANVERSION   = m_RTDllVersion.wMANVERSION;
595         pFileVersion->wMANREVISION  = m_RTDllVersion.wMANREVISION;
596         pFileVersion->wSUBREVISION  = m_RTDllVersion.wSUBREVISION;
597         pFileVersion->wBUILD_NUMBER = m_RTDllVersion.wBUILD_NUMBER;
598         return CM_SUCCESS;
599     }
600     else
601     {
602         return CM_QUERY_DLL_VERSION_FAILURE;
603     }
604 }
605 
GetJITCompileFnt(pJITCompile & fJITCompile)606 INT CmDevice_RT::GetJITCompileFnt(pJITCompile & fJITCompile)
607 {
608 	if (m_fJITCompile) {
609 		fJITCompile = m_fJITCompile;
610 	} else {
611 		if (!m_hJITDll) {
612 			m_hJITDll = dlopen(GetJitterName(), RTLD_LAZY);
613 			if (NULL == m_hJITDll) {
614 				CM_ASSERT(0);
615 				return CM_JITDLL_LOAD_FAILURE;
616 			}
617 		}
618 
619 		m_fJITCompile =
620 		    (pJITCompile) GetProcAddress(m_hJITDll,
621 						 JITCOMPILE_FUNCTION_STR);
622 		if (NULL == m_fJITCompile) {
623 			CM_ASSERT(0);
624 			return CM_JITDLL_LOAD_FAILURE;
625 		}
626 		fJITCompile = m_fJITCompile;
627 	}
628 	return CM_SUCCESS;
629 }
630 
GetFreeBlockFnt(pFreeBlock & fFreeBlock)631 INT CmDevice_RT::GetFreeBlockFnt(pFreeBlock & fFreeBlock)
632 {
633 	if (m_fFreeBlock) {
634 		fFreeBlock = m_fFreeBlock;
635 	} else {
636 		if (!m_hJITDll) {
637 			m_hJITDll = dlopen(GetJitterName(), RTLD_LAZY);
638 			if (NULL == m_hJITDll) {
639 				CM_ASSERT(0);
640 				return CM_JITDLL_LOAD_FAILURE;
641 			}
642 		}
643 
644 		m_fFreeBlock =
645 		    (pFreeBlock) GetProcAddress(m_hJITDll,
646 						FREEBLOCK_FUNCTION_STR);
647 		if (NULL == m_fFreeBlock) {
648 			CM_ASSERT(0);
649 			return CM_JITDLL_LOAD_FAILURE;
650 		}
651 		fFreeBlock = m_fFreeBlock;
652 	}
653 	return CM_SUCCESS;
654 }
655 
GetJITVersionFnt(pJITVersion & fJITVersion)656 INT CmDevice_RT::GetJITVersionFnt(pJITVersion & fJITVersion)
657 {
658 	if (m_fJITVersion) {
659 		fJITVersion = m_fJITVersion;
660 	} else {
661 		if (!m_hJITDll) {
662 			m_hJITDll = dlopen(GetJitterName(), RTLD_LAZY);
663 			if (NULL == m_hJITDll) {
664 				CM_ASSERT(0);
665 				return CM_JITDLL_LOAD_FAILURE;
666 			}
667 		}
668 
669 		m_fJITVersion =
670 		    (pJITVersion) GetProcAddress(m_hJITDll,
671 						 JITVERSION_FUNCTION_STR);
672 		if (NULL == m_fJITVersion) {
673 			CM_ASSERT(0);
674 			return CM_JITDLL_LOAD_FAILURE;
675 		}
676 		fJITVersion = m_fJITVersion;
677 	}
678 	return CM_SUCCESS;
679 }
680 
LoadJITDll(void)681 INT CmDevice_RT::LoadJITDll(void)
682 {
683 	int result = 0;
684 
685 	if (NULL == m_hJITDll) {
686 		m_hJITDll = dlopen(GetJitterName(), RTLD_LAZY);
687 		if (NULL == m_hJITDll) {
688 			result = CM_JITDLL_LOAD_FAILURE;
689 			CM_ASSERT(0);
690 			return result;
691 		}
692 		if (NULL == m_fJITCompile) {
693 			m_fJITCompile =
694 			    (pJITCompile) GetProcAddress(m_hJITDll,
695 							 JITCOMPILE_FUNCTION_STR);
696 			m_fFreeBlock =
697 			    (pFreeBlock) GetProcAddress(m_hJITDll,
698 							FREEBLOCK_FUNCTION_STR);
699 			m_fJITVersion =
700 			    (pJITVersion) GetProcAddress(m_hJITDll,
701 							 JITVERSION_FUNCTION_STR);
702 		}
703 
704 		if ((NULL == m_fJITCompile) || (NULL == m_fFreeBlock)
705 		    || (NULL == m_fJITVersion)) {
706 			result = CM_JITDLL_LOAD_FAILURE;
707 			CM_ASSERT(0);
708 			return result;
709 		}
710 	}
711 
712 	return result;
713 }
714 
GetGenPlatform(UINT & platform)715 CM_RT_API INT CmDevice_RT::GetGenPlatform(UINT & platform)
716 {
717 	if (m_Platform != IGFX_UNKNOWN_CORE) {
718 		platform = m_Platform;
719 		return CM_SUCCESS;
720 	}
721 
722 	platform = IGFX_UNKNOWN_CORE;
723 
724 	INT hr = 0;
725 	DXVA_CM_QUERY_CAPS queryCaps;
726 	UINT querySize = sizeof(DXVA_CM_QUERY_CAPS);
727 
728 	CmSafeMemSet(&queryCaps, 0, sizeof(queryCaps));
729 	queryCaps.Type = DXVA_CM_QUERY_GPU;
730 
731 	hr = GetCapsInternal(&queryCaps, &querySize);
732 	if (FAILED(hr)) {
733 		CM_ASSERT(0);
734 		return CM_FAILURE;
735 	}
736 	if (queryCaps.iVersion) {
737 		platform = queryCaps.iVersion;
738 	}
739 
740 	return CM_SUCCESS;
741 }
742 
743 CM_RT_API INT
GetSurface2DInfo(UINT width,UINT height,CM_SURFACE_FORMAT format,UINT & pitch,UINT & physicalSize)744     CmDevice_RT::GetSurface2DInfo(UINT width, UINT height,
745 			       CM_SURFACE_FORMAT format, UINT & pitch,
746 			       UINT & physicalSize)
747 {
748 	CM_RETURN_CODE hr = CM_SUCCESS;
749 	CM_HAL_SURFACE2D_UP_PARAM inParam;
750 	PCM_CONTEXT pCmData;
751 	PCM_HAL_STATE pCmHalState;
752 
753 	CMCHK_HR(m_pSurfaceMgr->Surface2DSanityCheck(width, height, format));
754 
755 	CmSafeMemSet(&inParam, 0, sizeof(CM_HAL_SURFACE2D_UP_PARAM));
756 	inParam.iWidth = width;
757 	inParam.iHeight = height;
758 	inParam.format = m_pSurfaceMgr->CmFmtToGenHwFmt(format);
759 
760 	pCmData = (PCM_CONTEXT) GetAccelData();
761 	pCmHalState = pCmData->pCmHalState;
762 	CHK_GENOSSTATUS_RETURN_CMERROR(pCmHalState->pfnGetSurface2DPitchAndSize
763 				       (pCmHalState, &inParam));
764 
765 	pitch = inParam.iPitch;
766 	physicalSize = inParam.iPhysicalSize;
767 
768  finish:
769 	return hr;
770 }
771 
CreateQueue_Internel(void)772 INT CmDevice_RT::CreateQueue_Internel(void)
773 {
774 	if (m_pQueue) {
775 		CM_ASSERTMESSAGE("Failed to create more than one queue.");
776 		return CM_FAILURE;
777 	}
778 
779 	INT result = CmQueue_RT::Create(this, m_pQueue);
780 	if (result != CM_SUCCESS) {
781 		CM_ASSERTMESSAGE("Failed to create queue.");
782 		return CM_FAILURE;
783 	}
784 
785 	return result;
786 }
787 
GetSurfaceManager(CmSurfaceManager * & pSurfaceMgr)788 INT CmDevice_RT::GetSurfaceManager(CmSurfaceManager * &pSurfaceMgr)
789 {
790 	pSurfaceMgr = m_pSurfaceMgr;
791 	return CM_SUCCESS;
792 }
793 
GetSurfaceLock()794 CSync *CmDevice_RT::GetSurfaceLock()
795 {
796 	return &m_CriticalSection_ReadWriteSurface2D;
797 }
798 
GetSurfaceCreationLock()799 CSync *CmDevice_RT::GetSurfaceCreationLock()
800 {
801 	return &m_CriticalSection_Surface;
802 }
803 
GetProgramKernelLock()804 CSync *CmDevice_RT::GetProgramKernelLock()
805 {
806 	return &m_CriticalSection_Program_Kernel;
807 }
808 
GetQueue(CmQueue_RT * & pQueue)809 INT CmDevice_RT::GetQueue(CmQueue_RT * &pQueue)
810 {
811 	pQueue = m_pQueue;
812 	return CM_SUCCESS;
813 }
814 
GetHalMaxValues(CM_HAL_MAX_VALUES * & pHalMaxValues,CM_HAL_MAX_VALUES_EX * & pHalMaxValuesEx)815 INT CmDevice_RT::GetHalMaxValues(CM_HAL_MAX_VALUES * &pHalMaxValues,
816 			      CM_HAL_MAX_VALUES_EX * &pHalMaxValuesEx)
817 {
818 	pHalMaxValues = &m_HalMaxValues;
819 	pHalMaxValuesEx = &m_HalMaxValuesEx;
820 
821 	return CM_SUCCESS;
822 }
823 
GetMaxValueFromCaps(CM_HAL_MAX_VALUES & MaxValues,CM_HAL_MAX_VALUES_EX & MaxValuesEx)824 INT CmDevice_RT::GetMaxValueFromCaps(CM_HAL_MAX_VALUES & MaxValues,
825 				  CM_HAL_MAX_VALUES_EX & MaxValuesEx)
826 {
827 	DXVA_CM_QUERY_CAPS queryCaps;
828 	UINT querySize = sizeof(DXVA_CM_QUERY_CAPS);
829 	CmSafeMemSet(&queryCaps, 0, sizeof(DXVA_CM_QUERY_CAPS));
830 	queryCaps.Type = DXVA_CM_MAX_VALUES;
831 
832 	INT hr = GetCapsInternal(&queryCaps, &querySize);
833 	if (FAILED(hr)) {
834 		CM_ASSERT(0);
835 		return CM_FAILURE;
836 	}
837 
838 	MaxValues = queryCaps.MaxValues;
839 	MaxValues.iMaxArgsPerKernel =
840 	    (queryCaps.MaxValues.iMaxArgsPerKernel >
841 	     CM_MAX_ARGS_PER_KERNEL) ? (CM_MAX_ARGS_PER_KERNEL) :
842 	    queryCaps.MaxValues.iMaxArgsPerKernel;
843 
844 	CmSafeMemSet(&queryCaps, 0, sizeof(DXVA_CM_QUERY_CAPS));
845 	queryCaps.Type = DXVA_CM_MAX_VALUES_EX;
846 
847 	hr = GetCapsInternal(&queryCaps, &querySize);
848 	if (FAILED(hr)) {
849 		CM_ASSERT(0);
850 		return CM_FAILURE;
851 	}
852 	MaxValuesEx = queryCaps.MaxValuesEx;
853 
854 	return CM_SUCCESS;
855 }
856 
GetCapsInternal(PVOID pCaps,PUINT puSize)857 INT CmDevice_RT::GetCapsInternal(PVOID pCaps, PUINT puSize)
858 {
859 	PDXVA_CM_QUERY_CAPS pQueryCaps;
860 	PCM_CONTEXT pCmData;
861 	PCM_HAL_STATE pCmHalState;
862 
863 	CM_RETURN_CODE hr = CM_SUCCESS;
864 
865 	if ((!puSize) || (!pCaps) || (*puSize < sizeof(DXVA_CM_QUERY_CAPS))) {
866 		CM_ASSERTMESSAGE("Invalid Arguments.");
867 		hr = CM_FAILURE;
868 		goto finish;
869 	}
870 
871 	pQueryCaps = (PDXVA_CM_QUERY_CAPS) pCaps;
872 	*puSize = sizeof(DXVA_CM_QUERY_CAPS);
873 
874 	if (pQueryCaps->Type == DXVA_CM_QUERY_VERSION) {
875 		pQueryCaps->iVersion = DXVA_CM_VERSION;
876 		hr = CM_SUCCESS;
877 		goto finish;
878 	}
879 
880 	pCmData = (PCM_CONTEXT) GetAccelData();
881 	CMCHK_NULL(pCmData);
882 
883 	pCmHalState = pCmData->pCmHalState;
884 	CMCHK_NULL(pCmHalState);
885 
886 	switch (pQueryCaps->Type) {
887 	case DXVA_CM_QUERY_REG_HANDLE:
888 		pQueryCaps->hRegistration =
889 		    (HANDLE *) & pCmHalState->SurfaceRegTable;
890 		break;
891 
892 	case DXVA_CM_MAX_VALUES:
893 		CHK_GENOSSTATUS_RETURN_CMERROR(pCmHalState->pfnGetMaxValues
894 					       (pCmHalState,
895 						&pQueryCaps->MaxValues));
896 		break;
897 
898 	case DXVA_CM_MAX_VALUES_EX:
899 		CHK_GENOSSTATUS_RETURN_CMERROR(pCmHalState->pfnGetMaxValuesEx
900 					       (pCmHalState,
901 						&pQueryCaps->MaxValuesEx));
902 		break;
903 
904 	case DXVA_CM_QUERY_GPU:
905 		pQueryCaps->genCore =
906 		    pCmHalState->pHwInterface->Platform.eRenderCoreFamily;
907 		break;
908 
909 	case DXVA_CM_QUERY_GT:
910 		if (GFX_IS_PRODUCT
911 		    (pCmHalState->pHwInterface->Platform, IGFX_CHERRYVIEW)) {
912 			pQueryCaps->genGT = PLATFORM_INTEL_GTCHV;
913 		} else if (pCmHalState->pHwInterface->Platform.GtType ==
914 			   GTTYPE_GT1) {
915 			pQueryCaps->genGT = PLATFORM_INTEL_GT1;
916 		} else if (pCmHalState->pHwInterface->Platform.GtType ==
917 			   GTTYPE_GT1_5) {
918 			pQueryCaps->genGT = PLATFORM_INTEL_GT1_5;
919 		} else if (pCmHalState->pHwInterface->Platform.GtType ==
920 			   GTTYPE_GT2) {
921 			pQueryCaps->genGT = PLATFORM_INTEL_GT2;
922 		} else if (pCmHalState->pHwInterface->Platform.GtType ==
923 			   GTTYPE_GT3) {
924 			pQueryCaps->genGT = PLATFORM_INTEL_GT3;
925 		} else if (pCmHalState->pHwInterface->Platform.GtType ==
926 			   GTTYPE_GT4) {
927 			pQueryCaps->genGT = PLATFORM_INTEL_GT4;
928 		} else if (pCmHalState->pHwInterface->Platform.GtType ==
929 			   GTTYPE_GTA) {
930 			pQueryCaps->genGT = PLATFORM_INTEL_GTA;  //BXT-GTA
931 		} else if (pCmHalState->pHwInterface->Platform.GtType ==
932 			   GTTYPE_GTC) {
933 			pQueryCaps->genGT = PLATFORM_INTEL_GTC; //BXT-GTC
934 		} else if (pCmHalState->pHwInterface->Platform.GtType ==
935 			   GTTYPE_GTX) {
936 			pQueryCaps->genGT = PLATFORM_INTEL_GTX; //BXT-GTX
937 		}
938 		break;
939 
940 	case DXVA_CM_QUERY_STEP:
941 		pQueryCaps->genStepId = pCmHalState->Platform.usRevId;
942 		break;
943 
944 	case DXVA_CM_QUERY_GPU_FREQ:
945 		CHK_GENOSSTATUS_RETURN_CMERROR
946 		    (pCmHalState->pfnGetGPUCurrentFrequency
947 		     (pCmHalState, &pQueryCaps->GPUCurrentFreq));
948 		break;
949 
950 	case DXVA_CM_QUERY_SURFACE2D_FORMAT_COUNT:
951 		pQueryCaps->Surface2DCount =
952 		    CM_MAX_SURFACE2D_FORMAT_COUNT_INTERNAL;
953 		break;
954 
955 	case DXVA_CM_QUERY_SURFACE2D_FORMATS:
956 		if (pQueryCaps->pSurface2DFormats) {
957 			CM_SURFACE_FORMAT
958 			    formats[CM_MAX_SURFACE2D_FORMAT_COUNT_INTERNAL] = {
959 			CM_SURFACE_FORMAT_X8R8G8B8,
960 				    CM_SURFACE_FORMAT_A8R8G8B8,
961 				    CM_SURFACE_FORMAT_R32F,
962 				    CM_SURFACE_FORMAT_V8U8,
963 				    CM_SURFACE_FORMAT_P8,
964 				    CM_SURFACE_FORMAT_YUY2,
965 				    CM_SURFACE_FORMAT_A8,
966 				    CM_SURFACE_FORMAT_NV12,
967 				    CM_SURFACE_FORMAT_UYVY,
968 				    CM_SURFACE_FORMAT_R8_UINT,
969 				    CM_SURFACE_FORMAT_R16_UINT,
970 				    CM_SURFACE_FORMAT_411P,
971 				    CM_SURFACE_FORMAT_422H,
972 				    CM_SURFACE_FORMAT_444P,
973 				    CM_SURFACE_FORMAT_IMC3,
974 				    CM_SURFACE_FORMAT_422V,
975 				    CM_SURFACE_FORMAT_YV12,};
976 			CmSafeMemCopy(pQueryCaps->pSurface2DFormats, formats,
977 				      CM_MAX_SURFACE2D_FORMAT_COUNT_INTERNAL *
978 				      sizeof(CM_SURFACE_FORMAT));
979 			break;
980 		} else {
981 			hr = CM_FAILURE;
982 			goto finish;
983 		}
984 
985 	default:
986 		hr = CM_FAILURE;
987 		goto finish;
988 	}
989 
990  finish:
991 	return hr;
992 }
993 
994 CM_RT_API INT
GetCaps(CM_DEVICE_CAP_NAME capName,size_t & capValueSize,void * pCapValue)995     CmDevice_RT::GetCaps(CM_DEVICE_CAP_NAME capName, size_t & capValueSize,
996 		      void *pCapValue)
997 {
998 	PCM_CONTEXT pCmData;
999 	PCM_HAL_STATE pCmHalState;
1000 
1001 	if (pCapValue == NULL) {
1002 		CM_ASSERT(0);
1003 		return CM_FAILURE;
1004 	}
1005 
1006 	pCmData = (PCM_CONTEXT) GetAccelData();
1007 	if (pCmData == NULL) {
1008 		CM_ASSERT(0);
1009 		return CM_FAILURE;
1010 	}
1011 
1012 	pCmHalState = pCmData->pCmHalState;
1013 	if (pCmHalState == NULL) {
1014 		CM_ASSERT(0);
1015 		return CM_FAILURE;
1016 	}
1017 
1018 	switch (capName) {
1019 	case CAP_KERNEL_COUNT_PER_TASK:
1020 		if (capValueSize >= sizeof(m_HalMaxValues.iMaxKernelsPerTask)) {
1021 			capValueSize =
1022 			    sizeof(m_HalMaxValues.iMaxKernelsPerTask);
1023 			CmSafeMemCopy(pCapValue,
1024 				      &m_HalMaxValues.iMaxKernelsPerTask,
1025 				      capValueSize);
1026 			return CM_SUCCESS;
1027 		} else {
1028 			return CM_FAILURE;
1029 		}
1030 
1031 	case CAP_KERNEL_BINARY_SIZE:
1032 		if (capValueSize >= sizeof(m_HalMaxValues.iMaxKernelBinarySize)) {
1033 			capValueSize =
1034 			    sizeof(m_HalMaxValues.iMaxKernelBinarySize);
1035 			CmSafeMemCopy(pCapValue,
1036 				      &m_HalMaxValues.iMaxKernelBinarySize,
1037 				      capValueSize);
1038 			return CM_SUCCESS;
1039 		} else {
1040 			return CM_FAILURE;
1041 		}
1042 
1043 	case CAP_BUFFER_COUNT:
1044 		if (capValueSize >= sizeof(m_HalMaxValues.iMaxBufferTableSize)) {
1045 			capValueSize =
1046 			    sizeof(m_HalMaxValues.iMaxBufferTableSize);
1047 			CmSafeMemCopy(pCapValue,
1048 				      &m_HalMaxValues.iMaxBufferTableSize,
1049 				      capValueSize);
1050 			return CM_SUCCESS;
1051 		} else {
1052 			return CM_FAILURE;
1053 		}
1054 
1055 	case CAP_SURFACE2D_COUNT:
1056 		if (capValueSize >=
1057 		    sizeof(m_HalMaxValues.iMax2DSurfaceTableSize)) {
1058 			capValueSize =
1059 			    sizeof(m_HalMaxValues.iMax2DSurfaceTableSize);
1060 			CmSafeMemCopy(pCapValue,
1061 				      &m_HalMaxValues.iMax2DSurfaceTableSize,
1062 				      capValueSize);
1063 			return CM_SUCCESS;
1064 		} else {
1065 			return CM_FAILURE;
1066 		}
1067 
1068 	case CAP_SURFACE_COUNT_PER_KERNEL:
1069 		if (capValueSize >=
1070 		    sizeof(m_HalMaxValues.iMaxSurfacesPerKernel)) {
1071 			capValueSize =
1072 			    sizeof(m_HalMaxValues.iMaxSurfacesPerKernel);
1073 			CmSafeMemCopy(pCapValue,
1074 				      &m_HalMaxValues.iMaxSurfacesPerKernel,
1075 				      capValueSize);
1076 			return CM_SUCCESS;
1077 		} else {
1078 			return CM_FAILURE;
1079 		}
1080 
1081 	case CAP_ARG_COUNT_PER_KERNEL:
1082 		if (capValueSize >= sizeof(m_HalMaxValues.iMaxArgsPerKernel)) {
1083 			capValueSize = sizeof(m_HalMaxValues.iMaxArgsPerKernel);
1084 			CmSafeMemCopy(pCapValue,
1085 				      &m_HalMaxValues.iMaxArgsPerKernel,
1086 				      capValueSize);
1087 			return CM_SUCCESS;
1088 		} else {
1089 			return CM_FAILURE;
1090 		}
1091 
1092 	case CAP_ARG_SIZE_PER_KERNEL:
1093 		if (capValueSize >=
1094 		    sizeof(m_HalMaxValues.iMaxArgByteSizePerKernel)) {
1095 			capValueSize =
1096 			    sizeof(m_HalMaxValues.iMaxArgByteSizePerKernel);
1097 			CmSafeMemCopy(pCapValue,
1098 				      &m_HalMaxValues.iMaxArgByteSizePerKernel,
1099 				      capValueSize);
1100 			return CM_SUCCESS;
1101 		} else {
1102 			return CM_FAILURE;
1103 		}
1104 
1105 	case CAP_USER_DEFINED_THREAD_COUNT_PER_TASK:
1106 		if (capValueSize >=
1107 		    sizeof(m_HalMaxValues.iMaxUserThreadsPerTask)) {
1108 			capValueSize =
1109 			    sizeof(m_HalMaxValues.iMaxUserThreadsPerTask);
1110 			CmSafeMemCopy(pCapValue,
1111 				      &m_HalMaxValues.iMaxUserThreadsPerTask,
1112 				      capValueSize);
1113 			return CM_SUCCESS;
1114 		} else {
1115 			return CM_FAILURE;
1116 		}
1117 
1118 	case CAP_USER_DEFINED_THREAD_COUNT_PER_MEDIA_WALKER:
1119 		if (capValueSize >=
1120 		    sizeof(m_HalMaxValuesEx.iMaxUserThreadsPerMediaWalker)) {
1121 			capValueSize =
1122 			    sizeof
1123 			    (m_HalMaxValuesEx.iMaxUserThreadsPerMediaWalker);
1124 			CmSafeMemCopy(pCapValue,
1125 				      &m_HalMaxValuesEx.
1126 				      iMaxUserThreadsPerMediaWalker,
1127 				      capValueSize);
1128 			return CM_SUCCESS;
1129 		} else {
1130 			return CM_FAILURE;
1131 		}
1132 
1133 	case CAP_USER_DEFINED_THREAD_COUNT_PER_THREAD_GROUP:
1134 		if (capValueSize >=
1135 		    sizeof(m_HalMaxValuesEx.iMaxUserThreadsPerThreadGroup)) {
1136 			capValueSize =
1137 			    sizeof
1138 			    (m_HalMaxValuesEx.iMaxUserThreadsPerThreadGroup);
1139 			CmSafeMemCopy(pCapValue,
1140 				      &m_HalMaxValuesEx.
1141 				      iMaxUserThreadsPerThreadGroup,
1142 				      capValueSize);
1143 			return CM_SUCCESS;
1144 		} else {
1145 			return CM_FAILURE;
1146 		}
1147 
1148 	case CAP_USER_DEFINED_THREAD_COUNT_PER_TASK_NO_THREAD_ARG:
1149 		if (capValueSize >=
1150 		    sizeof(m_HalMaxValues.iMaxUserThreadsPerTaskNoThreadArg)) {
1151 			capValueSize =
1152 			    sizeof
1153 			    (m_HalMaxValues.iMaxUserThreadsPerTaskNoThreadArg);
1154 			CmSafeMemCopy(pCapValue,
1155 				      &m_HalMaxValues.
1156 				      iMaxUserThreadsPerTaskNoThreadArg,
1157 				      capValueSize);
1158 			return CM_SUCCESS;
1159 		} else {
1160 			return CM_FAILURE;
1161 		}
1162 
1163 	case CAP_HW_THREAD_COUNT:
1164 		if (capValueSize >= sizeof(m_HalMaxValues.iMaxHwThreads)) {
1165 			capValueSize = sizeof(m_HalMaxValues.iMaxHwThreads);
1166 			CmSafeMemCopy(pCapValue, &m_HalMaxValues.iMaxHwThreads,
1167 				      capValueSize);
1168 			return CM_SUCCESS;
1169 		} else {
1170 			return CM_FAILURE;
1171 		}
1172 
1173 	case CAP_SURFACE2D_FORMAT_COUNT:
1174 		if (capValueSize >= sizeof(UINT)) {
1175 			capValueSize = sizeof(UINT);
1176 			UINT formatCount = CM_MAX_SURFACE2D_FORMAT_COUNT;
1177 			CmSafeMemCopy(pCapValue, &formatCount, capValueSize);
1178 			return CM_SUCCESS;
1179 		} else {
1180 			return CM_FAILURE;
1181 		}
1182 
1183 	case CAP_SURFACE2D_FORMATS:
1184 		if (capValueSize >=
1185 		    CM_MAX_SURFACE2D_FORMAT_COUNT * sizeof(CM_SURFACE_FORMAT)) {
1186 			capValueSize =
1187 			    CM_MAX_SURFACE2D_FORMAT_COUNT *
1188 			    sizeof(CM_SURFACE_FORMAT);
1189 			CM_SURFACE_FORMAT formats[CM_MAX_SURFACE2D_FORMAT_COUNT]
1190 			    = {
1191 				CM_SURFACE_FORMAT_X8R8G8B8,
1192 				CM_SURFACE_FORMAT_A8R8G8B8,
1193 				CM_SURFACE_FORMAT_R32F,
1194 				CM_SURFACE_FORMAT_V8U8,
1195 				CM_SURFACE_FORMAT_P8,
1196 				CM_SURFACE_FORMAT_YUY2,
1197 				CM_SURFACE_FORMAT_A8,
1198 				CM_SURFACE_FORMAT_NV12,
1199 				CM_SURFACE_FORMAT_UYVY,
1200 				CM_SURFACE_FORMAT_R8_UINT,
1201 				CM_SURFACE_FORMAT_R16_UINT,
1202 				CM_SURFACE_FORMAT_411P,
1203 				CM_SURFACE_FORMAT_422H,
1204 				CM_SURFACE_FORMAT_444P,
1205 				CM_SURFACE_FORMAT_IMC3,
1206 				CM_SURFACE_FORMAT_422V,
1207 				CM_SURFACE_FORMAT_YV12,
1208 			};
1209 			CmSafeMemCopy(pCapValue, formats, capValueSize);
1210 			return CM_SUCCESS;
1211 		} else {
1212 			return CM_FAILURE;
1213 		}
1214 
1215 	case CAP_GPU_PLATFORM:
1216 		if (capValueSize >= sizeof(UINT)) {
1217 			UINT platform = PLATFORM_INTEL_UNKNOWN;
1218 			capValueSize = sizeof(UINT);
1219 			switch (m_Platform) {
1220 			case IGFX_GEN7_5_CORE:
1221 				platform = PLATFORM_INTEL_HSW;
1222 				break;
1223 
1224 			case IGFX_GEN8_CORE:
1225 				if (GFX_IS_PRODUCT
1226 				    (pCmHalState->pHwInterface->Platform,
1227 				     IGFX_CHERRYVIEW)) {
1228 					platform = PLATFORM_INTEL_CHV;
1229 				} else {
1230 					platform = PLATFORM_INTEL_BDW;
1231 				}
1232 				break;
1233 
1234 			case IGFX_GEN9_CORE:
1235 				if (GFX_IS_PRODUCT
1236 				    (pCmHalState->pHwInterface->Platform,
1237 				     IGFX_BROXTON)) {
1238 					//change to PLATFORM_INTEL_BXT soon...
1239 					platform = PLATFORM_INTEL_SKL;
1240 				} else {
1241 					platform = PLATFORM_INTEL_SKL;
1242 				}
1243 				break;
1244 			}
1245 
1246 			CmSafeMemCopy(pCapValue, &platform, capValueSize);
1247 			return CM_SUCCESS;
1248 		} else {
1249 			return CM_FAILURE;
1250 		}
1251 
1252 	case CAP_GT_PLATFORM:
1253 		if (capValueSize >= sizeof(UINT)) {
1254 			DXVA_CM_QUERY_CAPS queryCaps;
1255 			queryCaps.Type = DXVA_CM_QUERY_GT;
1256 			UINT queryCapsSize = sizeof(DXVA_CM_QUERY_CAPS);
1257 			GetCapsInternal(&queryCaps, &queryCapsSize);
1258 			capValueSize = sizeof(UINT);
1259 			UINT gtPlatform = queryCaps.genGT;
1260 			CmSafeMemCopy(pCapValue, &gtPlatform, capValueSize);
1261 			return CM_SUCCESS;
1262 		} else {
1263 			return CM_FAILURE;
1264 		}
1265 	case CAP_MIN_FREQUENCY:
1266 		if (capValueSize >= sizeof(UINT)) {
1267 			DXVA_CM_QUERY_CAPS queryCaps;
1268 			queryCaps.Type = DXVA_CM_MIN_RENDER_FREQ;
1269 			UINT queryCapsSize = sizeof(DXVA_CM_QUERY_CAPS);
1270 			GetCapsInternal(&queryCaps, &queryCapsSize);
1271 			UINT frequency = queryCaps.MinRenderFreq;
1272 			capValueSize = sizeof(UINT);
1273 			CmSafeMemCopy(pCapValue, &frequency, capValueSize);
1274 			return CM_SUCCESS;
1275 		} else {
1276 			return CM_FAILURE;
1277 		}
1278 
1279 	case CAP_MAX_FREQUENCY:
1280 		if (capValueSize >= sizeof(UINT)) {
1281 			DXVA_CM_QUERY_CAPS queryCaps;
1282 			queryCaps.Type = DXVA_CM_MAX_RENDER_FREQ;
1283 			UINT queryCapsSize = sizeof(DXVA_CM_QUERY_CAPS);
1284 			GetCapsInternal(&queryCaps, &queryCapsSize);
1285 			UINT frequency = queryCaps.MaxRenderFreq;
1286 			capValueSize = sizeof(UINT);
1287 			CmSafeMemCopy(pCapValue, &frequency, capValueSize);
1288 			return CM_SUCCESS;
1289 		} else {
1290 			return CM_FAILURE;
1291 		}
1292 
1293 	case CAP_GPU_CURRENT_FREQUENCY:
1294 		if (capValueSize >= sizeof(UINT)) {
1295 			DXVA_CM_QUERY_CAPS queryCaps;
1296 			queryCaps.Type = DXVA_CM_QUERY_GPU_FREQ;
1297 			UINT queryCapsSize = sizeof(DXVA_CM_QUERY_CAPS);
1298 			GetCapsInternal(&queryCaps, &queryCapsSize);
1299 			UINT frequency = queryCaps.GPUCurrentFreq;
1300 			capValueSize = sizeof(UINT);
1301 			CmSafeMemCopy(pCapValue, &frequency, capValueSize);
1302 			return CM_SUCCESS;
1303 		} else {
1304 			return CM_FAILURE;
1305 		}
1306 
1307 	default:
1308 		return CM_FAILURE;
1309 	}
1310 }
1311 
1312 CM_RT_API INT
LoadProgram(void * pCommonISACode,const UINT size,CmProgram * & pProgram,const char * options)1313     CmDevice_RT::LoadProgram(void *pCommonISACode, const UINT size,
1314 			  CmProgram * &pProgram, const char *options)
1315 {
1316 	INT result;
1317 
1318 	if ((pCommonISACode == NULL) || (size == 0)) {
1319 		CM_ASSERT(0);
1320 		return CM_INVALID_COMMON_ISA;
1321 	}
1322 
1323 	CLock locker(m_CriticalSection_Program_Kernel);
1324 
1325 	UINT firstfreeslot = m_ProgramArray.GetFirstFreeIndex();
1326 
1327 	CmProgram_RT *pProgram_RT = NULL;
1328 	result =
1329 	    CmProgram_RT::Create(this, pCommonISACode, size, NULL, 0, pProgram_RT,
1330 			      options, firstfreeslot);
1331 	if (result == CM_SUCCESS) {
1332 		m_ProgramArray.SetElement(firstfreeslot, pProgram_RT);
1333 		m_ProgramCount++;
1334 		pProgram = (static_cast<CmProgram *>(pProgram_RT));
1335 	}
1336 	return result;
1337 }
1338 
DestroyProgram(CmProgram * & pProgram)1339 CM_RT_API INT CmDevice_RT::DestroyProgram(CmProgram * &pProgram)
1340 {
1341 	if (pProgram == NULL) {
1342 		return CM_FAILURE;
1343 	}
1344 
1345 	CLock locker(m_CriticalSection_Program_Kernel);
1346         CmProgram_RT * pProgram_RT = (static_cast<CmProgram_RT* >(pProgram));
1347 	UINT indexInProgramArrary = pProgram_RT->GetProgramIndex();
1348 
1349 	if (pProgram_RT == m_ProgramArray.GetElement(indexInProgramArrary)) {
1350 		CmProgram_RT::Destroy(pProgram_RT);
1351 		if (pProgram_RT == NULL) {
1352 			m_ProgramArray.SetElement(indexInProgramArrary, NULL);
1353 		}
1354 		return CM_SUCCESS;
1355 	} else {
1356 		CM_ASSERT(0);
1357 		return CM_FAILURE;
1358 	}
1359 
1360 }
1361 
1362 CM_RT_API INT
CreateKernel(CmProgram * pProgram,const char * kernelName,CmKernel * & pKernel,const char * options)1363     CmDevice_RT::CreateKernel(CmProgram * pProgram, const char *kernelName,
1364 			   CmKernel * &pKernel, const char *options)
1365 {
1366 	if (pProgram == NULL) {
1367 		CM_ASSERT(0);
1368 		return CM_INVALID_ARG_VALUE;
1369 	}
1370 
1371 	CLock locker(m_CriticalSection_Program_Kernel);
1372 
1373 	UINT freeSlotInKernelArray = m_KernelArray.GetFirstFreeIndex();
1374 	CmKernel_RT *pKernel_RT=NULL;
1375         CmProgram_RT* pProgram_RT = static_cast<CmProgram_RT*>(pProgram);
1376 	INT result =
1377 	    CmKernel_RT::Create(this, pProgram_RT, kernelName, freeSlotInKernelArray,
1378 			     m_KernelCount, pKernel_RT, options);
1379 	if (result == CM_SUCCESS) {
1380 		m_KernelArray.SetElement(freeSlotInKernelArray, pKernel_RT);
1381 		m_KernelCount++;
1382 		pKernel = static_cast< CmKernel * >(pKernel_RT);
1383 	}
1384 
1385 	return result;
1386 }
1387 
DestroyKernel(CmKernel * & pKernel)1388 CM_RT_API INT CmDevice_RT::DestroyKernel(CmKernel * &pKernel)
1389 {
1390 	if (pKernel == NULL) {
1391 		return CM_FAILURE;
1392 	}
1393 
1394 	CLock locker(m_CriticalSection_Program_Kernel);
1395     CmKernel_RT *pKernel_RT=static_cast<CmKernel_RT*>(pKernel);
1396 
1397 	UINT indexInKernelArrary = pKernel_RT->GetKernelIndex();
1398     CmProgram_RT *pProgram_RT = NULL;
1399 	if (pKernel_RT == m_KernelArray.GetElement(indexInKernelArrary)) {
1400 	    pKernel_RT->GetCmProgram(pProgram_RT);
1401 		if (pProgram_RT == NULL) {
1402 			CM_ASSERT(0);
1403 			return CM_FAILURE;
1404 		}
1405 
1406 		UINT indexInProgramArray = pProgram_RT->GetProgramIndex();
1407 
1408 		if (pProgram_RT == m_ProgramArray.GetElement(indexInProgramArray)) {
1409 			CmKernel_RT::Destroy(pKernel_RT, pProgram_RT);
1410 
1411 			if (pKernel_RT == NULL) {
1412 				m_KernelArray.SetElement(indexInKernelArrary,
1413 							 NULL);
1414 			}
1415 
1416 			if (pProgram_RT == NULL) {
1417 				m_ProgramArray.SetElement(indexInProgramArray,
1418 							  NULL);
1419 			}
1420 			return CM_SUCCESS;
1421 		} else {
1422 			CM_ASSERT(0);
1423 			return CM_FAILURE;
1424 		}
1425 	} else {
1426 		CM_ASSERT(0);
1427 		return CM_FAILURE;
1428 	}
1429 	return CM_SUCCESS;
1430 }
1431 
CreateQueue(CmQueue * & pQueue)1432 CM_RT_API INT CmDevice_RT::CreateQueue(CmQueue * &pQueue)
1433 {
1434 	pQueue = m_pQueue;
1435 	return CM_SUCCESS;
1436 }
1437 
CreateTask(CmTask * & pTask)1438 CM_RT_API INT CmDevice_RT::CreateTask(CmTask * &pTask)
1439 {
1440 	CLock locker(m_CriticalSection_Task);
1441 
1442 	CmTask_RT* ptask_RT = NULL;
1443 	UINT freeSlotInTaskArray = m_TaskArray.GetFirstFreeIndex();
1444 	INT result = CmTask_RT::Create(this, freeSlotInTaskArray,
1445 				    m_HalMaxValues.iMaxKernelsPerTask, ptask_RT);
1446 	if (result == CM_SUCCESS) {
1447 	    pTask = static_cast< CmTask* >(ptask_RT);
1448 	    m_TaskArray.SetElement(freeSlotInTaskArray, pTask);
1449 	    m_TaskCount++;
1450 	}
1451 	return result;
1452 }
1453 
DestroyQueue(CmQueue_RT * & pQueue)1454 INT CmDevice_RT::DestroyQueue(CmQueue_RT * &pQueue)
1455 {
1456 	if (pQueue == NULL) {
1457 		return CM_FAILURE;
1458 	}
1459 
1460 	return CmQueue_RT::Destroy(pQueue);
1461 }
1462 
DestroyTask(CmTask * & pTask)1463 CM_RT_API INT CmDevice_RT::DestroyTask(CmTask * &pTask)
1464 {
1465 
1466 	CLock locker(m_CriticalSection_Task);
1467 
1468 	if (pTask == NULL) {
1469 		return CM_FAILURE;
1470 	}
1471 
1472         CmTask_RT* pTask_RT = static_cast< CmTask_RT* >(pTask);
1473         if ( pTask_RT == NULL ) {
1474             return CM_FAILURE;
1475         }
1476 	UINT index = pTask_RT->GetIndexInTaskArray();
1477 
1478 	if (pTask == (CmTask_RT *) m_TaskArray.GetElement(index)) {
1479 		INT status = CmTask_RT::Destroy(pTask_RT);
1480 		if (status == CM_SUCCESS) {
1481 			m_TaskArray.SetElement(index, NULL);
1482 			pTask = NULL;
1483 			return CM_SUCCESS;
1484 		} else {
1485 			CM_ASSERT(0);
1486 			return status;
1487 		}
1488 	} else {
1489 		CM_ASSERT(0);
1490 		return CM_FAILURE;
1491 	}
1492 }
1493 
1494 CM_RT_API INT
CreateThreadSpace(UINT width,UINT height,CmThreadSpace * & pTS)1495     CmDevice_RT::CreateThreadSpace(UINT width, UINT height, CmThreadSpace * &pTS)
1496 {
1497 	CLock locker(m_CriticalSection_ThreadSpace);
1498 
1499 	UINT freeSlotInThreadSpaceArray =
1500 	    m_ThreadSpaceArray.GetFirstFreeIndex();
1501 	INT result =
1502 	    CmThreadSpace::Create(this, freeSlotInThreadSpaceArray, width,
1503 				  height,
1504 				  pTS);
1505 	if (result == CM_SUCCESS) {
1506 		m_ThreadSpaceArray.SetElement(freeSlotInThreadSpaceArray, pTS);
1507 		m_ThreadSpaceCount++;
1508 	}
1509 
1510 	return result;
1511 }
1512 
DestroyThreadSpace(CmThreadSpace * & pTS)1513 CM_RT_API INT CmDevice_RT::DestroyThreadSpace(CmThreadSpace * &pTS)
1514 {
1515 	if (pTS == NULL) {
1516 		return CM_FAILURE;
1517 	}
1518 
1519 	UINT indexTs = pTS->GetIndexInTsArray();
1520 
1521 	CLock locker(m_CriticalSection_ThreadSpace);
1522 	if (pTS == m_ThreadSpaceArray.GetElement(indexTs)) {
1523 		INT status = CmThreadSpace::Destroy(pTS);
1524 		if (status == CM_SUCCESS) {
1525 			m_ThreadSpaceArray.SetElement(indexTs, NULL);
1526 			pTS = NULL;
1527 			return CM_SUCCESS;
1528 		} else {
1529 			CM_ASSERT(0);
1530 			return status;
1531 		}
1532 	} else {
1533 		CM_ASSERT(0);
1534 		return CM_FAILURE;
1535 	}
1536 
1537 }
1538 
GetDDIVersion(UINT & DDIVersion)1539 INT CmDevice_RT::GetDDIVersion(UINT & DDIVersion)
1540 {
1541 	DDIVersion = m_DDIVersion;
1542 	return CM_SUCCESS;
1543 }
1544 
1545 CM_RT_API INT
CreateThreadGroupSpace(UINT thrdSpaceWidth,UINT thrdSpaceHeight,UINT grpSpaceWidth,UINT grpSpaceHeight,CmThreadGroupSpace * & pTGS)1546     CmDevice_RT::CreateThreadGroupSpace(UINT thrdSpaceWidth, UINT thrdSpaceHeight,
1547 				     UINT grpSpaceWidth, UINT grpSpaceHeight,
1548 				     CmThreadGroupSpace * &pTGS)
1549 {
1550 	CLock locker(m_CriticalSection_ThreadGroupSpace);
1551 
1552 	UINT firstfreeslot = m_ThreadGroupSpaceArray.GetFirstFreeIndex();
1553 	INT result =
1554 	    CmThreadGroupSpace_RT::Create(this, firstfreeslot, thrdSpaceWidth,
1555 				       thrdSpaceHeight, grpSpaceWidth,
1556 				       grpSpaceHeight, pTGS);
1557 	if (result == CM_SUCCESS) {
1558 		m_ThreadGroupSpaceArray.SetElement(firstfreeslot, pTGS);
1559 		m_ThreadGroupSpaceCount++;
1560 	}
1561 	return result;
1562 }
1563 
DestroyThreadGroupSpace(CmThreadGroupSpace * & pTGS)1564 CM_RT_API INT CmDevice_RT::DestroyThreadGroupSpace(CmThreadGroupSpace * &pTGS)
1565 {
1566 	if (pTGS == NULL) {
1567 		return CM_FAILURE;
1568 	}
1569 
1570 	UINT indexTGs = static_cast<CmThreadGroupSpace_RT*>(pTGS)->GetIndexInTGsArray();
1571 
1572 	CLock locker(m_CriticalSection_ThreadGroupSpace);
1573 
1574 	if (pTGS == static_cast <
1575 	    CmThreadGroupSpace *
1576 	    >(m_ThreadGroupSpaceArray.GetElement(indexTGs))) {
1577 		INT status = CmThreadGroupSpace_RT::Destroy(pTGS);
1578 		if (status == CM_SUCCESS) {
1579 			m_ThreadGroupSpaceArray.SetElement(indexTGs, NULL);
1580 			pTGS = NULL;
1581 			return CM_SUCCESS;
1582 		}
1583 	} else {
1584 		CM_ASSERT(0);
1585 		return CM_FAILURE;
1586 	}
1587 
1588 	return CM_FAILURE;
1589 }
1590 
GetGenStepInfo(UINT platform,char * & stepinfostr)1591 INT CmDevice_RT::GetGenStepInfo(UINT platform, char *&stepinfostr)
1592 {
1593 	INT hr;
1594 
1595 	const char *CmSteppingInfo[MAX_STEPPING_NUM] =
1596 	{
1597 		"A",
1598 		"B",
1599 		"C",
1600 		"D",
1601 		"E",
1602 		"F",
1603 		"G",
1604 		"H",
1605 		"I",
1606 		"J"
1607 	};
1608 
1609 	DXVA_CM_QUERY_CAPS queryCaps;
1610 	CmSafeMemSet(&queryCaps, 0, sizeof(queryCaps));
1611 	queryCaps.Type = DXVA_CM_QUERY_STEP;
1612 	UINT queryCapsSize = sizeof(queryCaps);
1613 
1614 	if (platform < IGFX_GEN7_5_CORE) {
1615 		stepinfostr = NULL;
1616 		return CM_SUCCESS;
1617 	}
1618 
1619 	hr = GetCapsInternal(&queryCaps, &queryCapsSize);
1620 	if (FAILED(hr)) {
1621 		CM_ASSERT(0);
1622 		return CM_FAILURE;
1623 	}
1624 
1625 	UINT stepid = queryCaps.genStepId;
1626 	UINT ulStepId = (1 << stepid);
1627 
1628 	if (platform < IGFX_GEN9_CORE)
1629 	{
1630 		switch (ulStepId) {
1631 		case SIWA_ONLY_BDW_A0:
1632 			stepinfostr = (char *)HW_GT_STEPPING_A0;
1633 			break;
1634 
1635 		case SIWA_ONLY_HSW_A1:
1636 			stepinfostr = (char *)HW_GT_STEPPING_A1;
1637 			break;
1638 
1639 		case SIWA_ONLY_HSW_B0:
1640 			stepinfostr = (char *)HW_GT_STEPPING_B0;
1641 			break;
1642 
1643 		case SIWA_ONLY_HSW_C0:
1644 			stepinfostr = (char *)HW_GT_STEPPING_C0;
1645 			break;
1646 
1647 		default:
1648 			stepinfostr = NULL;
1649 		}
1650 	}
1651 	else if (stepid < MAX_STEPPING_NUM)
1652 	{
1653 		stepinfostr = (char*)CmSteppingInfo[stepid];
1654 	}
1655 	else
1656 	{
1657 		stepinfostr = NULL;
1658 	}
1659 
1660 	return CM_SUCCESS;
1661 }
1662 
SetSuggestedL3Config(L3_SUGGEST_CONFIG l3_s_c)1663 CM_RT_API INT CmDevice_RT::SetSuggestedL3Config( L3_SUGGEST_CONFIG l3_s_c)
1664 {
1665     INT upper_bound;
1666     const L3_CONFIG_REGISTER_VALUES *l3_c;
1667 
1668     switch (m_Platform)
1669     {
1670         case IGFX_GEN6_CORE:
1671             return CM_FAILURE;
1672 
1673         case IGFX_GEN7_CORE:
1674             upper_bound = HSW_L3_CONFIG_NUM;
1675             l3_c = &IVB_L3_PLANE[0];
1676             break;
1677 
1678         case IGFX_GEN7_5_CORE:
1679             upper_bound = HSW_L3_CONFIG_NUM;
1680             l3_c = HSW_L3_PLANE;
1681             break;
1682 
1683         case IGFX_GEN8_CORE:
1684             upper_bound = BDW_L3_CONFIG_NUM;
1685             l3_c = BDW_L3_PLANE;
1686             break;
1687 
1688 	case IGFX_GEN9_CORE:
1689             upper_bound = SKL_L3_CONFIG_NUM;
1690             l3_c = SKL_L3_PLANE;
1691             break;
1692 
1693 	default:
1694             return CM_FAILURE;
1695     }
1696 
1697     if (l3_s_c>=  upper_bound || l3_s_c< 0)
1698         return CM_FAILURE;
1699 ;
1700     m_l3_c.SQCREG1_VALUE  = l3_c[l3_s_c].SQCREG1_VALUE;
1701     m_l3_c.CNTLREG2_VALUE = l3_c[l3_s_c].CNTLREG2_VALUE;
1702     m_l3_c.CNTLREG3_VALUE = l3_c[l3_s_c].CNTLREG3_VALUE;
1703     m_l3_c.CNTLREG_VALUE = l3_c[ l3_s_c ].CNTLREG_VALUE;
1704     SetCapsInternal(CAP_L3_CONFIG, sizeof(L3_CONFIG_REGISTER_VALUES), &m_l3_c);
1705     return CM_SUCCESS;
1706 }
1707 
SetCapsInternal(CM_DEVICE_CAP_NAME capName,size_t capValueSize,void * pCapValue)1708 INT CmDevice_RT::SetCapsInternal(CM_DEVICE_CAP_NAME capName, size_t capValueSize,
1709 			      void *pCapValue)
1710 {
1711 	CM_RETURN_CODE hr = CM_SUCCESS;
1712 
1713 	DXVA_CM_SET_CAPS setCaps;
1714 	UINT maxValue;
1715 	size_t size = sizeof(maxValue);
1716 	CmSafeMemSet(&setCaps, 0, sizeof(setCaps));
1717 
1718 	switch (capName) {
1719 	case CAP_HW_THREAD_COUNT:
1720 		if (capValueSize != sizeof(UINT)) {
1721 			CM_ASSERT(0);
1722 			return CM_INVALID_HARDWARE_THREAD_NUMBER;
1723 		}
1724 
1725 		if (*(UINT *) pCapValue <= 0) {
1726 			CM_ASSERT(0);
1727 			return CM_INVALID_HARDWARE_THREAD_NUMBER;
1728 		}
1729 
1730 		GetCaps(CAP_HW_THREAD_COUNT, size, &maxValue);
1731 		if (*(UINT *) pCapValue > maxValue) {
1732 			CM_ASSERT(0);
1733 			return CM_INVALID_HARDWARE_THREAD_NUMBER;
1734 		}
1735 
1736 		setCaps.Type = DXVA_CM_MAX_HW_THREADS;
1737 		setCaps.MaxValue = *(UINT *) pCapValue;
1738 		break;
1739 
1740 	case CAP_L3_CONFIG:
1741             if (capValueSize != sizeof(L3_CONFIG_REGISTER_VALUES)){
1742                 CM_ASSERT(0);
1743                 return CM_INVALIDE_L3_CONFIGURATION;
1744                }
1745             else {
1746                 L3_CONFIG_REGISTER_VALUES *l3_c = (L3_CONFIG_REGISTER_VALUES *)pCapValue;
1747                 setCaps.L3_SQCREG1 = l3_c->SQCREG1_VALUE;
1748                 setCaps.L3_CNTLREG2 = l3_c->CNTLREG2_VALUE;
1749                 setCaps.L3_CNTLREG3 = l3_c->CNTLREG3_VALUE;
1750                 setCaps.L3_CNTLREG = l3_c->CNTLREG_VALUE;
1751                 setCaps.Type = DXVA_CM_MAX_HW_L3_CONFIG;
1752               }
1753         break;
1754 
1755 	default:
1756 		return CM_FAILURE;
1757 	}
1758 
1759 	PCM_CONTEXT pCmData = (PCM_CONTEXT) this->GetAccelData();
1760 	CHK_GENOSSTATUS_RETURN_CMERROR(pCmData->pCmHalState->
1761 				       pfnSetCaps(pCmData->pCmHalState,
1762 						  (PCM_HAL_MAX_SET_CAPS_PARAM)
1763 						  & setCaps));
1764 
1765  finish:
1766 	return hr;
1767 }
1768 
GetSurf2DLookUpEntry(UINT index,PCMLOOKUP_ENTRY & pLookupEntry)1769 INT CmDevice_RT::GetSurf2DLookUpEntry(UINT index, PCMLOOKUP_ENTRY & pLookupEntry)
1770 {
1771 	PCM_CONTEXT pCmData = (PCM_CONTEXT) GetAccelData();
1772 	if (pCmData) {
1773 		pLookupEntry = &(pCmData->pCmHalState->pSurf2DTable[index]);
1774 	} else {
1775 		return CM_FAILURE;
1776 	}
1777 
1778 	return CM_SUCCESS;
1779 }
1780 
LoadProgramWithGenCode(void * pCISACode,const UINT uiCISACodeSize,void * pGenCode,const UINT uiGenCodeSize,CmProgram_RT * & pProgram,const char * options)1781 INT CmDevice_RT::LoadProgramWithGenCode(void *pCISACode, const UINT uiCISACodeSize,
1782 				     void *pGenCode, const UINT uiGenCodeSize,
1783 				     CmProgram_RT * &pProgram, const char *options)
1784 {
1785 	INT result;
1786 	CLock locker(m_CriticalSection_Program_Kernel);
1787 
1788 	UINT firstfreeslot = m_ProgramArray.GetFirstFreeIndex();
1789 	result =
1790 	    CmProgram_RT::Create(this, pCISACode, uiCISACodeSize, pGenCode,
1791 			      uiGenCodeSize, pProgram, options, firstfreeslot);
1792 	if (result == CM_SUCCESS) {
1793 		m_ProgramArray.SetElement(firstfreeslot, pProgram);
1794 		m_ProgramCount++;
1795 	}
1796 	return result;
1797 }
1798 
GetSurface2DInPool(UINT width,UINT height,CM_SURFACE_FORMAT format,CmSurface2D * & pSurface)1799 INT CmDevice_RT::GetSurface2DInPool(UINT width, UINT height,
1800 				 CM_SURFACE_FORMAT format,
1801 				 CmSurface2D * &pSurface)
1802 {
1803 	CLock locker(m_CriticalSection_Surface);
1804 
1805 	CmSurface2D_RT *pSurface_RT = NULL;
1806 	INT result =
1807 	    m_pSurfaceMgr->GetSurface2dInPool(width, height, format, pSurface_RT);
1808 	pSurface=static_cast<CmSurface2D *>(pSurface_RT);
1809 	return result;
1810 }
1811 
GetSurfaceIDInPool(INT iIndex)1812 INT CmDevice_RT::GetSurfaceIDInPool(INT iIndex)
1813 {
1814 	CLock locker(m_CriticalSection_Surface);
1815 	INT result = m_pSurfaceMgr->GetSurfaceIdInPool(iIndex);
1816 	return result;
1817 }
1818 
DestroySurfaceInPool(UINT & freeSurfNum)1819 INT CmDevice_RT::DestroySurfaceInPool(UINT & freeSurfNum)
1820 {
1821 	CLock locker(m_CriticalSection_Surface);
1822 
1823 	freeSurfNum = m_pSurfaceMgr->TouchSurfaceInPoolForDestroy();
1824 	if ((INT) freeSurfNum < 0) {
1825 		freeSurfNum = 0;
1826 		return CM_FAILURE;
1827 	}
1828 
1829 	return CM_SUCCESS;
1830 }
1831 
InitDevCreateOption(CM_HAL_CREATE_PARAM & DevCreateParam,UINT DevCreateOption)1832 INT CmDevice_RT::InitDevCreateOption(CM_HAL_CREATE_PARAM & DevCreateParam,
1833 				  UINT DevCreateOption)
1834 {
1835 	UINT MaxTaskNumber = 0;
1836 
1837 	DevCreateParam.DisableScratchSpace =
1838 	    (DevCreateOption & CM_DEVICE_CREATE_OPTION_SCRATCH_SPACE_MASK);
1839 
1840 	DevCreateParam.EnableSurfaceReuse =
1841 	    (DevCreateOption & CM_DEVICE_CREATE_OPTION_SURFACE_REUSE_ENABLE);
1842 
1843 	if (DevCreateParam.DisableScratchSpace) {
1844 		DevCreateParam.ScratchSpaceSize = 0;
1845 	} else {
1846 		DevCreateParam.ScratchSpaceSize =
1847 		    (DevCreateOption & CM_DEVICE_CONFIG_SCRATCH_SPACE_SIZE_MASK)
1848 		    >> CM_DEVICE_CONFIG_SCRATCH_SPACE_SIZE_OFFSET;
1849 	}
1850 
1851 	MaxTaskNumber =
1852 	    (DevCreateOption & CM_DEVICE_CONFIG_TASK_NUM_MASK) >>
1853 	    CM_DEVICE_CONFIG_TASK_NUM_OFFSET;
1854 
1855 	DevCreateParam.MaxTaskNumber =
1856 	    (MaxTaskNumber + 1) * CM_DEVICE_CONFIG_TASK_NUM_STEP;
1857 
1858 	DevCreateParam.bMediaReset = FALSE;
1859 
1860 	MaxTaskNumber =
1861 	    (DevCreateOption & CM_DEVICE_CONFIG_EXTRA_TASK_NUM_MASK) >>
1862 	    CM_DEVICE_CONFIG_EXTRA_TASK_NUM_OFFSET;
1863 
1864 	DevCreateParam.MaxTaskNumber =
1865 	    (MaxTaskNumber + 1) * DevCreateParam.MaxTaskNumber;
1866 
1867 	DevCreateParam.bRequestSliceShutdown =
1868 	    (DevCreateOption & CM_DEVICE_CONFIG_SLICESHUTDOWN_ENABLE) ? TRUE :
1869 	    FALSE;
1870 
1871 	DevCreateParam.bRequestCustomGpuContext =
1872 	    (DevCreateOption & CM_DEVICE_CONFIG_GPUCONTEXT_ENABLE) ? TRUE :
1873 	    FALSE;
1874 
1875 	DevCreateParam.bSLMMode =
1876 	    (DevCreateOption & CM_DEVICE_CONFIG_SLM_MODE_ENABLE) ? TRUE : FALSE;
1877 
1878 	return CM_SUCCESS;
1879 }
1880 
IsScratchSpaceDisabled()1881 BOOL CmDevice_RT::IsScratchSpaceDisabled()
1882 {
1883 	return m_DevCreateOption.DisableScratchSpace ? TRUE : FALSE;
1884 }
1885 
IsSurfaceReuseEnabled()1886 BOOL CmDevice_RT::IsSurfaceReuseEnabled()
1887 {
1888 	return m_DevCreateOption.EnableSurfaceReuse ? TRUE : FALSE;
1889 }
1890 
ValidSurfaceIndexStart()1891 UINT CmDevice_RT::ValidSurfaceIndexStart()
1892 {
1893 	UINT genid;
1894 	GetGenPlatform(genid);
1895 
1896 	if (genid >= IGFX_GEN9_CORE) {
1897 		return (CM_GLOBAL_SURFACE_INDEX_START_GEN9_PLUS +
1898 			CM_GLOBAL_SURFACE_NUMBER);
1899 	} else {
1900 		return (CM_NULL_SURFACE_BINDING_INDEX + 1);
1901 	}
1902 }
1903 
MaxIndirectSurfaceCount()1904 UINT CmDevice_RT::MaxIndirectSurfaceCount()
1905 {
1906 	UINT genid;
1907 	GetGenPlatform(genid);
1908 
1909 	if (genid >= IGFX_GEN9_CORE) {
1910 		return (GT_RESERVED_INDEX_START_GEN9_PLUS -
1911 			CM_GLOBAL_SURFACE_NUMBER - 1);
1912 	} else {
1913 		return (GT_RESERVED_INDEX_START - CM_GLOBAL_SURFACE_NUMBER - 1);
1914 	}
1915 }
1916 
IsCmReservedSurfaceIndex(UINT surfBTI)1917 BOOL CmDevice_RT::IsCmReservedSurfaceIndex(UINT surfBTI)
1918 {
1919 	UINT genid;
1920 	GetGenPlatform(genid);
1921 
1922 	if (genid >= IGFX_GEN9_CORE) {
1923 		if (surfBTI >= CM_GLOBAL_SURFACE_INDEX_START_GEN9_PLUS
1924 		    && surfBTI <
1925 		    (CM_GLOBAL_SURFACE_INDEX_START_GEN9_PLUS +
1926 		     CM_GLOBAL_SURFACE_NUMBER))
1927 			return TRUE;
1928 		else
1929 			return FALSE;
1930 	} else {
1931 		if (surfBTI >= CM_GLOBAL_SURFACE_INDEX_START
1932 		    && surfBTI <
1933 		    (CM_GLOBAL_SURFACE_INDEX_START + CM_GLOBAL_SURFACE_NUMBER))
1934 			return TRUE;
1935 		else
1936 			return FALSE;
1937 	}
1938 }
1939 
IsValidSurfaceIndex(UINT surfBTI)1940 BOOL CmDevice_RT::IsValidSurfaceIndex(UINT surfBTI)
1941 {
1942 	UINT genid;
1943 	GetGenPlatform(genid);
1944 
1945 	if (genid >= IGFX_GEN9_CORE) {
1946 		if (surfBTI >=
1947 		    (CM_GLOBAL_SURFACE_INDEX_START_GEN9_PLUS +
1948 		     CM_GLOBAL_SURFACE_NUMBER)
1949 		    && surfBTI < GT_RESERVED_INDEX_START_GEN9_PLUS)
1950 			return TRUE;
1951 		else
1952 			return FALSE;
1953 	} else {
1954 		if (surfBTI > CM_NULL_SURFACE_BINDING_INDEX
1955 		    && surfBTI < CM_GLOBAL_SURFACE_INDEX_START)
1956 			return TRUE;
1957 		else
1958 			return FALSE;
1959 	}
1960 }
1961 
1962 EXTERN_C INT
CreateCmDevice(CmDevice_RT * & pDevice,UINT & version,CmDriverContext * pDriverContext,UINT DevCreateOption)1963 CreateCmDevice(CmDevice_RT * &pDevice, UINT & version,
1964 	       CmDriverContext * pDriverContext, UINT DevCreateOption)
1965 {
1966 	INT result = CM_SUCCESS;
1967 	pDevice = NULL;
1968 
1969 	result = CmDevice_RT::Create(pDriverContext, pDevice, DevCreateOption);
1970 	if (result == CM_SUCCESS) {
1971 		version = CURRENT_CM_VERSION;
1972 	} else {
1973 		version = 0;
1974 	}
1975 
1976 	return result;
1977 }
1978 
DestroyCmDevice(CmDevice_RT * & pDevice)1979 EXTERN_C INT DestroyCmDevice(CmDevice_RT * &pDevice)
1980 {
1981 	INT result = CM_SUCCESS;
1982 
1983 	result = CmDevice_RT::Destroy(pDevice);
1984 	if (result == CM_SUCCESS) {
1985 		pDevice = NULL;
1986 	}
1987 
1988 	return result;
1989 }
1990