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 参数设置为 Microsoft Direct3D 运行时在 CreateDevice 或 CreateDevice (D3D10) 调用期间提供的值。 在 pData 参数指向的D3DDDICB_RENDER结构中,用户模式显示驱动程序还应设置:

  • CommandLength 成员,表示命令缓冲区中从偏移量零开始的命令字节数。
  • 如果用户模式显示驱动程序必须指定命令缓冲区中第一个硬件命令的偏移量,则 CommandOffset 成员为非零。
  • 分配列表中的元素数的 NumAllocations 成员。
  • 修补程序位置列表中的元素数的 NumPatchLocations 成员。
调用 pfnRenderCb 后,用户模式显示驱动程序必须从D3DDDICB_RENDER的 pNewCommandBuffer 和 NewCommandBufferSize 成员中返回的值确定命令缓冲区的基址和大小,以便下一次提交。 同样,驱动程序必须根据 pNewAllocationList 和 NewAllocationListSize 成员以及 pNewPatchLocationList 和 NewPatchLocationListSize 成员中分别返回的值来确定下一个分配列表和修补程序位置列表的基址和元素数

如果用户模式显示驱动程序检测到大部分命令缓冲区刷新是由于驱动程序在命令缓冲区、分配列表或修补程序位置列表中空间不足,则驱动程序可以请求调整其大小。 若要调整命令缓冲区的大小,驱动程序在 D3DDDICB_RENDERFlags 成员中设置 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 操作系统中可用。
目标平台 桌面
标头 d3dumddi.h (包括 D3dumddi.h)

另请参阅

CreateDevice

D3DDDICB_RENDER

D3DDDI_DEVICECALLBACKS

刷新

pfnCreateContextCb