CM_RT_API INT CmQueue::EnqueueWithGroup(CmTask * pTask, CmEvent * &pEvent, const CmThreadGroupSpace * pTGS) { INT result; if (pTask == NULL) { CM_ASSERTMESSAGE("Kernel array is NULL."); return CM_INVALID_ARG_VALUE; } UINT count = 0; count = pTask->GetKernelCount(); if (count == 0) { CM_ASSERTMESSAGE("There are no valid kernels."); return CM_FAILURE; } typedef CmKernel *pCmKernel; CmKernel **pTmp = new(std::nothrow) pCmKernel[count + 1]; if (pTmp == NULL) { CM_ASSERT(0); return CM_OUT_OF_HOST_MEMORY; } UINT totalThreadNumber = 0; for (UINT i = 0; i < count; i++) { UINT singleThreadNumber = 0; pTmp[i] = pTask->GetKernelPointer(i); if (pTmp[i]->IsThreadArgExisted()) { CM_ASSERTMESSAGE ("No thread Args allowed when using group space"); CmSafeDeleteArray(pTmp); return CM_THREAD_ARG_NOT_ALLOWED; } pTmp[i]->GetThreadCount(singleThreadNumber); totalThreadNumber += singleThreadNumber; } pTmp[count] = NULL; result = Enqueue_RT(pTmp, count, totalThreadNumber, pEvent, pTGS, pTask->GetSyncBitmap(), pTask->GetPreemptionMode()); if (pEvent) { pEvent->SetKernelNames(pTask, NULL, const_cast < CmThreadGroupSpace * >(pTGS)); } CmSafeDeleteArray(pTmp); return result; }
INT CmQueue::Enqueue_RT(CmKernel * pKernelArray[], const UINT uiKernelCount, const UINT uiTotalThreadCount, CmEvent * &pEvent, const CmThreadSpace * pTS, UINT64 uiSyncBitmap, PCM_HAL_POWER_OPTION_PARAM pPowerOption) { if (pKernelArray == NULL) { CM_ASSERTMESSAGE("Kernel array is NULL."); return CM_INVALID_ARG_VALUE; } if (uiKernelCount == 0) { CM_ASSERTMESSAGE("There are no valid kernels."); return CM_INVALID_ARG_VALUE; } BOOL bIsEventVisible = (pEvent == CM_NO_EVENT) ? FALSE : TRUE; CmTaskInternal *pTask = NULL; INT result = CmTaskInternal::Create(uiKernelCount, uiTotalThreadCount, pKernelArray, pTS, m_pDevice, uiSyncBitmap, pTask); if (result != CM_SUCCESS) { CM_ASSERT(0); return result; } m_CriticalSection_Queue.Acquire(); if (!m_EnqueuedTasks.Push(pTask)) { m_CriticalSection_Queue.Release(); CM_ASSERT(0); return CM_FAILURE; } INT taskDriverId = -1; result = CreateEvent(pTask, bIsEventVisible, taskDriverId, pEvent); if (result != CM_SUCCESS) { m_CriticalSection_Queue.Release(); CM_ASSERT(0); return result; } pTask->SetPowerOption(pPowerOption); UpdateSurfaceStateOnPush(pTask); result = FlushTaskWithoutSync(); m_CriticalSection_Queue.Release(); return result; }
INT CmQueue::Enqueue_RT(CmKernel * pKernelArray[], const UINT uiKernelCount, const UINT uiTotalThreadCount, CmEvent * &pEvent, const CmThreadGroupSpace * pTGS, UINT64 uiSyncBitmap, CM_HAL_PREEMPTION_MODE preemptionMode) { if (pKernelArray == NULL) { CM_ASSERTMESSAGE("Kernel array is NULL."); return CM_INVALID_ARG_VALUE; } if (uiKernelCount == 0) { CM_ASSERTMESSAGE("There are no valid kernels."); return CM_INVALID_ARG_VALUE; } CmTaskInternal *pTask = NULL; INT result = CmTaskInternal::Create(uiKernelCount, uiTotalThreadCount, pKernelArray, pTGS, m_pDevice, uiSyncBitmap, pTask); if (result != CM_SUCCESS) { CM_ASSERT(0); return result; } m_CriticalSection_Queue.Acquire(); pTask->SetPreemptionMode(preemptionMode); if (!m_EnqueuedTasks.Push(pTask)) { m_CriticalSection_Queue.Release(); CM_ASSERT(0); return CM_FAILURE; } INT taskDriverId = -1; result = CreateEvent(pTask, !(pEvent == CM_NO_EVENT), taskDriverId, pEvent); if (result != CM_SUCCESS) { m_CriticalSection_Queue.Release(); CM_ASSERT(0); return result; } UpdateSurfaceStateOnPush(pTask); result = FlushTaskWithoutSync(); m_CriticalSection_Queue.Release(); return result; }
INT CmDevice_RT::CreateQueue_Internel(void) { if (m_pQueue) { CM_ASSERTMESSAGE("Failed to create more than one queue."); return CM_FAILURE; } INT result = CmQueue_RT::Create(this, m_pQueue); if (result != CM_SUCCESS) { CM_ASSERTMESSAGE("Failed to create queue."); return CM_FAILURE; } return result; }
INT CmDevice_RT::GetCapsInternal(PVOID pCaps, PUINT puSize) { PDXVA_CM_QUERY_CAPS pQueryCaps; PCM_CONTEXT pCmData; PCM_HAL_STATE pCmHalState; CM_RETURN_CODE hr = CM_SUCCESS; if ((!puSize) || (!pCaps) || (*puSize < sizeof(DXVA_CM_QUERY_CAPS))) { CM_ASSERTMESSAGE("Invalid Arguments."); hr = CM_FAILURE; goto finish; } pQueryCaps = (PDXVA_CM_QUERY_CAPS) pCaps; *puSize = sizeof(DXVA_CM_QUERY_CAPS); if (pQueryCaps->Type == DXVA_CM_QUERY_VERSION) { pQueryCaps->iVersion = DXVA_CM_VERSION; hr = CM_SUCCESS; goto finish; } pCmData = (PCM_CONTEXT) GetAccelData(); CMCHK_NULL(pCmData); pCmHalState = pCmData->pCmHalState; CMCHK_NULL(pCmHalState); switch (pQueryCaps->Type) { case DXVA_CM_QUERY_REG_HANDLE: pQueryCaps->hRegistration = (HANDLE *) & pCmHalState->SurfaceRegTable; break; case DXVA_CM_MAX_VALUES: CHK_GENOSSTATUS_RETURN_CMERROR(pCmHalState->pfnGetMaxValues (pCmHalState, &pQueryCaps->MaxValues)); break; case DXVA_CM_MAX_VALUES_EX: CHK_GENOSSTATUS_RETURN_CMERROR(pCmHalState->pfnGetMaxValuesEx (pCmHalState, &pQueryCaps->MaxValuesEx)); break; case DXVA_CM_QUERY_GPU: pQueryCaps->genCore = pCmHalState->pHwInterface->Platform.eRenderCoreFamily; break; case DXVA_CM_QUERY_GT: if (GFX_IS_PRODUCT (pCmHalState->pHwInterface->Platform, IGFX_CHERRYVIEW)) { pQueryCaps->genGT = PLATFORM_INTEL_GTCHV; } else if (pCmHalState->pHwInterface->Platform.GtType == GTTYPE_GT1) { pQueryCaps->genGT = PLATFORM_INTEL_GT1; } else if (pCmHalState->pHwInterface->Platform.GtType == GTTYPE_GT2) { pQueryCaps->genGT = PLATFORM_INTEL_GT2; } else if (pCmHalState->pHwInterface->Platform.GtType == GTTYPE_GT3) { pQueryCaps->genGT = PLATFORM_INTEL_GT3; } break; case DXVA_CM_QUERY_STEP: pQueryCaps->genStepId = pCmHalState->Platform.usRevId; break; case DXVA_CM_QUERY_GPU_FREQ: CHK_GENOSSTATUS_RETURN_CMERROR (pCmHalState->pfnGetGPUCurrentFrequency (pCmHalState, &pQueryCaps->GPUCurrentFreq)); break; case DXVA_CM_QUERY_SURFACE2D_FORMAT_COUNT: pQueryCaps->Surface2DCount = CM_MAX_SURFACE2D_FORMAT_COUNT_INTERNAL; break; case DXVA_CM_QUERY_SURFACE2D_FORMATS: if (pQueryCaps->pSurface2DFormats) { CM_SURFACE_FORMAT formats[CM_MAX_SURFACE2D_FORMAT_COUNT_INTERNAL] = { CM_SURFACE_FORMAT_X8R8G8B8, CM_SURFACE_FORMAT_A8R8G8B8, CM_SURFACE_FORMAT_R32F, CM_SURFACE_FORMAT_V8U8, CM_SURFACE_FORMAT_P8, CM_SURFACE_FORMAT_YUY2, CM_SURFACE_FORMAT_A8, CM_SURFACE_FORMAT_NV12, CM_SURFACE_FORMAT_UYVY, CM_SURFACE_FORMAT_R8_UINT, CM_SURFACE_FORMAT_R16_UINT, CM_SURFACE_FORMAT_411P, CM_SURFACE_FORMAT_422H, CM_SURFACE_FORMAT_444P, CM_SURFACE_FORMAT_IMC3, CM_SURFACE_FORMAT_422V, CM_SURFACE_FORMAT_YV12,}; CmSafeMemCopy(pQueryCaps->pSurface2DFormats, formats, CM_MAX_SURFACE2D_FORMAT_COUNT_INTERNAL * sizeof(CM_SURFACE_FORMAT)); break; } else { hr = CM_FAILURE; goto finish; } default: hr = CM_FAILURE; goto finish; } finish: return hr; }
INT CmQueue::Enqueue_RT(CmKernel * pKernelArray[], CmEvent * &pEvent, UINT numTasksGenerated, BOOLEAN isLastTask, UINT hints, PCM_HAL_POWER_OPTION_PARAM pPowerOption) { INT result = CM_FAILURE; UINT kernelCount = 0; CmTaskInternal *pTask = NULL; INT taskDriverId = -1; BOOL bIsEventVisible = (pEvent == CM_NO_EVENT) ? FALSE : TRUE; BOOLEAN threadArgExists = FALSE; if (pKernelArray == NULL) { CM_ASSERTMESSAGE("Kernel array is NULL."); return CM_INVALID_ARG_VALUE; } while (pKernelArray[kernelCount]) { kernelCount++; } if (kernelCount < CM_MINIMUM_NUM_KERNELS_ENQWHINTS) { CM_ASSERTMESSAGE ("EnqueueWithHints requires at least 2 kernels."); return CM_FAILURE; } UINT totalThreadCount = 0; for (UINT i = 0; i < kernelCount; i++) { UINT threadCount = 0; pKernelArray[i]->GetThreadCount(threadCount); totalThreadCount += threadCount; } if (GetTaskHasThreadArg(pKernelArray, kernelCount, threadArgExists) != CM_SUCCESS) { CM_ASSERTMESSAGE ("Error checking if Task has any thread arguments."); return CM_FAILURE; } if (!threadArgExists) { if (totalThreadCount > m_pHalMaxValues->iMaxUserThreadsPerTaskNoThreadArg) { CM_ASSERTMESSAGE ("Maximum number of threads per task exceeded."); return CM_EXCEED_MAX_THREAD_AMOUNT_PER_ENQUEUE; } } else { if (totalThreadCount > m_pHalMaxValues->iMaxUserThreadsPerTask) { CM_ASSERTMESSAGE ("Maximum number of threads per task exceeded."); return CM_EXCEED_MAX_THREAD_AMOUNT_PER_ENQUEUE; } } result = CmTaskInternal::Create(kernelCount, totalThreadCount, pKernelArray, pTask, numTasksGenerated, isLastTask, hints, m_pDevice); if (result != CM_SUCCESS) { CM_ASSERT(0); return result; } m_CriticalSection_Queue.Acquire(); if (!m_EnqueuedTasks.Push(pTask)) { m_CriticalSection_Queue.Release(); CM_ASSERT(0); return CM_FAILURE; } result = CreateEvent(pTask, bIsEventVisible, taskDriverId, pEvent); if (result != CM_SUCCESS) { m_CriticalSection_Queue.Release(); CM_ASSERT(0); return result; } for (UINT i = 0; i < kernelCount; ++i) { CmKernel *pKernel = NULL; pTask->GetKernel(i, pKernel); if (pKernel != NULL) { pKernel->SetAdjustedYCoord(0); } } pTask->SetPowerOption(pPowerOption); UpdateSurfaceStateOnPush(pTask); result = FlushTaskWithoutSync(); m_CriticalSection_Queue.Release(); return result; }