PFND3DDDI_RENDERCB回调函数 (d3dumddi.h)

pfnRenderCb 函数提交当前命令缓冲区以呈现到显示微型端口驱动程序。

语法

PFND3DDDI_RENDERCB Pfnd3dddiRendercb;

HRESULT Pfnd3dddiRendercb(
  HANDLE hDevice,
  D3DDDICB_RENDER *unnamedParam2
)
{...}

参数

hDevice

显示设备 (图形上下文) 句柄。

unnamedParam2

pData [in, out]

指向描述要呈现的当前命令缓冲区 的D3DDDICB_RENDER 结构的指针。

返回值

pfnRenderCb 返回以下值之一:

返回代码 说明
S_OK 已成功呈现命令缓冲区。
D3DDDIERR_PRIVILEGEDINSTRUCTION 显示微型端口驱动程序在命令缓冲区中检测到特权指令;特权指令不能存在于命令缓冲区中。
D3DDDIERR_ILLEGALINSTRUCTION 显示微型端口驱动程序检测到图形硬件不支持的说明。
D3DDDIERR_INVALIDHANDLE 显示微型端口驱动程序检测到命令缓冲区中的句柄无效。
D3DDDIERR_CANTRENDERLOCKEDALLOCATION 视频内存管理器检测到对分配列表中的锁定分配的引用。 请注意,仅当视频内存管理器无法将分配重新定位到 AGP 或系统内存段时,才会返回此错误。
D3DDDIERR_INVALIDUSERBUFFER 显示微型端口驱动程序检测到数据或指令不足或溢出。 也就是说,驱动程序收到的指令或数据少于预期。
E_OUTOFMEMORY 由于内存不足,pfnRenderCb 无法完成。
E_INVALIDARG 参数已验证并确定不正确。

此函数也可能返回其他 HRESULT 值。

注解

当用户模式显示驱动程序必须提交当前命令缓冲区以呈现到显示微型端口驱动程序 (例如,在调用用户模式显示驱动程序的 Flush 或 Flush (D3D10) 函数) 时,用户模式显示驱动程序必须调用 pfnRenderCb 函数。 用户模式显示驱动程序应将 hDevice 参数设置为 CreateDevice 或 CreateDevice (D3D10) 调用期间提供的 Microsoft Direct3D 运行时的值。 在 pData 参数指向的D3DDDICB_RENDER结构中,用户模式显示驱动程序还应设置:

  • CommandLength 成员到从偏移量零开始的命令缓冲区中的命令字节数。
  • 如果用户模式显示驱动程序必须指定命令缓冲区中第一个硬件命令的偏移量,则 CommandOffset 成员为非零。
  • 分配列表中的元素数的 NumAllocations 成员。
  • NumPatchLocations 成员到修补程序位置列表中的元素数。
调用 pfnRenderCb 后,用户模式显示驱动程序必须确定命令缓冲区的基址和大小,该缓冲区的基址和大小应用于其下一次提交,这些缓冲区应从 D3DDDICB_RENDERpNewCommandBufferNewCommandBufferSize 成员返回的值。 同样,驱动程序必须分别从 pNewAllocationListNewAllocationListSize 成员和 pNewPatchLocationListSize 成员和 NewPatchLocationListSize 成员中返回的值确定下一个分配列表和修补程序位置列表的基址和元素数。

如果用户模式显示驱动程序检测到大多数命令缓冲区刷新是因为驱动程序在命令缓冲区、分配列表或修补程序位置列表中空间不足,则驱动程序可以请求调整其大小。 若要调整命令缓冲区的大小,驱动程序在D3DDDICB_RENDER的 Flags 成员中设置 ResizeCommandBuffer 位字段标志,并将请求的大小置于 D3DDDICB_RENDER 的 NewCommandBufferSize 成员中。 同样,若要调整分配列表的大小,驱动程序在D3DDDICB_RENDER的 Flags 成员中设置 ResizeAllocationList 位字段标志,并将请求的元素数置于 D3DDDICB_RENDER 的 NewAllocationListSize 成员中。 若要调整修补程序位置列表的大小,驱动程序在D3DDDICB_RENDER的 Flags 成员中设置 ResizePatchLocationList 位字段标志,并将请求的元素数置于 D3DDDICB_RENDER 的 NewPatchLocationListSize 成员中。

注意 尽管驱动程序可以请求调整命令缓冲区和分配和修补程序位置列表的大小,但视频内存管理器可能无法遵守。 因此,无论对 pfnRenderCb 的调用是否成功,驱动程序都应验证在 D3DDDICB_RENDER 的 NewCommandBufferSizeNewAllocationListSizeNewPatchLocationListSize 成员中返回的值。
 
如果用户模式显示驱动程序将 pData 参数指向的D3DDDICB_RENDER结构的 hContext 成员设置为 NULL,Microsoft Direct3D 运行时会将呈现操作发送到设备的默认上下文。 如果用户模式显示驱动程序将 hContext 设置为 pfnCreateContextCb 函数先前返回的有效句柄,并且表示设备上下文,则 Direct3D 运行时会将呈现操作发送到该上下文。 Direct3D 版本 11 注意: 有关驱动程序如何调用 pfnRenderCb 的详细信息,请参阅 Direct3D 10 中的更改

示例

下面的代码示例演示如何提交当前命令缓冲区以呈现到显示微型端口驱动程序。 此代码示例在生成命令缓冲区和修补程序列表后生成分配列表。 这不适合性能,因为命令缓冲区被分析得比必要多。 但是,此实现更易于显示。 在生产驱动程序中,在分配和修补程序列表的同时生成命令缓冲区更高效。

VOID CD3DContext::SubmitDXVABuffer(DWORD Size) {
    D3DDDICB_RENDER     renderCBData = {0};
    DWORD               dwAllocationListUsed;
    HRESULT             hr;

    if (GenerateAllocationListFromCmdBuf(R200UpdateQSParamsForDXVASubmit(m_pR200Ctx, Size), m_sContexts[MULTI_ENGINE_NODE_VIDEO].pHwCmdBufAllocList, m_dwHwCmdBufAllocListSize, &dwAllocationListUsed) == FALSE)
    {
        DBG_BREAK;
        return;
    }

    // 3-D and video packets must be in sync. If the last packet that was sent went to 
    // the 3-D engine, that packet must finish before the new packet runs on the hardware.

    renderCBData.CommandOffset  = 0;
    renderCBData.CommandLength  = Size + sizeof(UMD_CMDBUF_INFO);
    renderCBData.NumAllocations = dwAllocationListUsed;
    renderCBData.hContext = m_sContexts[MULTI_ENGINE_NODE_VIDEO].hContext;

    // Copy command-buffer data from the internal buffer to the buffer that was created by dxgkrnl
    memcpy(m_sContexts[MULTI_ENGINE_NODE_VIDEO].pHwCmdBuf, m_pHwCmdBuf + GetCmdBufPreambleSize(m_pR200Ctx), renderCBData.CommandLength);
 
    m_d3dCallbacks.pfnRenderCb(m_hD3D, &renderCBData);

        // Makes video the last engine that work was submitted to
        m_LastEngineSubmit = MULTI_ENGINE_NODE_VIDEO;
    }

要求

   
最低受支持的客户端 在 Windows Vista 和更高版本的 Windows 操作系统中可用。
目标平台 桌面
Header d3dumddi.h (包括 D3dumddi.h)

另请参阅

CreateDevice

D3DDDICB_RENDER

D3DDDI_DEVICECALLBACKS

刷新

pfnCreateContextCb