DXGKDDI_DSITRANSMISSION回呼函式 (dispmprt.h)
DxgkddiDsiTransmission 回呼函式會執行顯示序列介面 (DSI) 傳輸。
語法
DXGKDDI_DSITRANSMISSION DxgkddiDsitransmission;
NTSTATUS DxgkddiDsitransmission(
[in] HANDLE Context,
[in] D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId,
[out] PDXGK_DSI_TRANSMISSION pArgs
)
{...}
參數
[in] Context
[in] TargetId
監視器的目標標識碼。
[out] pArgs
DXGI_DSI_TRANSMISSION 結構的指標。
傳回值
DxgkddiDsiTransmission 如果成功,則會傳回STATUS_SUCCESS;否則會傳回 Ntstatus.h中定義的其中一個錯誤碼。
言論
若要允許 OEM 面板驅動程式透過圖形適配卡和面板硬體之間的私用介面互動,交易必須沒有圖形驅動程式效果,而不是佔用總線的時間,或者必須完整定義它們,才能控制圖形驅動程式。 由於允許 OEM 面板驅動程式互動的重點是提供對圖形驅動程式不透明的自定義面板功能的支援,因此完整定義的作業將僅限於面板驅動程式需要執行標準化作業的交易,而不需要圖形驅動程式介入即可執行。 這類交易會被視為明確路由的例外狀況,而不是傳輸。
每個 DSI 傳輸要求都包含由 OEM 面板驅動程式填滿的單一緩衝區、傳遞至監視堆疊,並傳回傳輸結果,如果有的話。 緩衝區包含傳輸的整體資訊,包含輸入和輸出欄位,後面接著可變大小的 DXGK_DSI_PACKET 結構陣列。 封包會以 DSI 詞彙描述,因此可以描述任何 DSI 封包,不過 OS 會剖析封包並拒絕任何傳輸,其中包括不允許的封包。 除了最後一個封包之外,所有封包都是根據 DSI 定義,寫入封包可能是簡短寫入,在此情況下,Payload
緩衝區未使用,或是符合 Payload
緩衝區內的長寫入。 傳輸中的最後一個封包,可能是讀取或寫入,可藉由配置和描述較大的緩衝區來使用擴充承載,以允許讀取或寫入大小上限為 64K-1 數據位元組的任何大小空間。 這可讓小型寫入封包序列在單一呼叫中排入驅動程式佇列,但確實需要個別傳送較大的封包。 [FinalPacketExtraPayload
] 欄位的值表示已配置多少個額外的位元組,但這也必須在 [TotalBufferSize
] 字段中考慮。
OEM 面板驅動程式負責確保其要求的傳輸不會衝突或干擾圖形驅動程式用於與面板正常互動的其他傳輸,因為要求過多或要求作業,因而造成處理其他傳輸的延遲。 面板驅動程式不得變更任何會導致圖形驅動程式後續失敗的狀態,例如透過MCS命令變更面板計時。 同樣地,如果作系統已要求顯示變更,透過圖形驅動程式,例如增加亮度,面板驅動程式不得使用 DSI 命令來復原該變更,不論是回應或其他用途。
IOCTL_MIPI_DSI_TRANSMISSION 可用來要求傳輸至包含一或多個 DSI 封包的周邊。 面板驅動程序必須一律初始化 TotalBufferSize
、PacketCount
和每個封包的前三個 BYTES。 面板驅動程式可以使用 TransmissionMode
、ReportMipiErrors
、ClearMipiErrors
、SecondaryPort
、ManufacturingMode
和 FinalCommandExtraPayload
的非零值來覆寫預設行為。 所有未初始化的值都必須設定為零。
OS 可確保 DSI 封包的順序格式正確,且所有已定義欄位都有有效的資訊,以及正確的緩衝區大小。 OS 負責將 [FailedPacket
] 字段初始化為 DXGK_DSI_INVALID_PACKET_INDEX,如此一來,如果發現特定封包的問題,OS 或驅動程式中的進一步驗證才需要設定字段。 如果 DXGK_DSI_TRANSMISSION 格式不正確,OS 會在 [HostErrors
] 字段中設定DXGK_HOST_DSI_INVALID_TRANSMISSION旗標,以區別其他無效的參數錯誤。
若要視為格式正確,下列各項必須全部成立:
- TotalBufferSize >= sizeof(DXGK_DSI_TRANSMISSION) + ((PacketCount - 1) * sizeof(DXGK_DSI_PACKET)) + FinalPacketExtraPayload
- FinalPacketExtraPayload <= 64K-1-DXGK_DSI_PACKET_EMBEDDED_PAYLOAD_SIZE (0xFFF7)
- TotalBufferSize <= ROUND_TO_PAGES(sizeof(DXGK_DSI_TRANSMISSION) + (0xFE * sizeof(DXGK_DSI_PACKET)) + 0xFFF7 )
- PacketCount != 0
- 只允許最後一個封包成為讀取
- 只有最後一個長寫入封包可以有大於 [DXGK_DSI_PACKET_EMBEDDED_PAYLOAD_SIZE] 的
LongWriteWordCount
值
封包驗證
雖然 OS 不會嘗試完整驗證所有封包的內容,但它會拒絕包含下列任何 DSI 命令的傳輸,而不需要呼叫圖形驅動程式即可完成 IOCTL:
數據類型值 | 描述 |
---|---|
0x03 | 一般簡短寫入,無參數 |
0x13 | 一般簡短寫入,1 個參數 |
0x23 | 一般簡短寫入,2 個參數 |
0x04 | 一般 READ,沒有參數 |
0x14 | 一般 READ,1 個參數 |
0x24 | 一般 READ,2 個參數 |
0x05 | DCS 簡短寫入,無參數 |
0x15 | DCS 簡短寫入,1 個參數 |
0x06 | DCS READ,無參數 |
0x29 | 一般長寫入 |
0x39 | DCS 長寫入/write_LUT |
一般讀取和寫入命令需要瞭解面板規格,因此預期只要總線未過度使用,面板驅動程式就可以自由使用這些命令,而不會造成圖形驅動程序的問題。 同樣地,DCS MCS 命令會針對製造商使用明確定義,因此圖形驅動程式與面板驅動程式之間的干擾應該不會有問題。
對於 DCS UCS,圖形驅動程式不會使用未定義的命令,因此 OS 會允許面板驅動程式使用它們,不過未來 MIPI-DCS 規格變更會定義命令,因此最好使用 MCS 命令。
標準化的DCS UCS命令會在正常作業期間由圖形驅動程式使用,而且面板驅動程式可能會使用,因此OEM面板驅動程式傳送的命令風險會導致後續圖形驅動程式命令的問題需要減輕。 若要這樣做,除非 OEM 面板驅動程式設定 ManufacturingMode
旗標,而且 OS 會確認系統處於製造模式,否則 OS 會剖析 DCS 命令並拒絕預期會造成衝突的封包。 如果已設定旗標,但系統不在製造模式中,傳輸IOCTL將會完成,並在 HostErrors
字段中設定DXGK_HOST_DSI_INVALID_TRANSMISSION旗標,而不呼叫圖形驅動程式。
需要完整定義交易而不是使用傳輸的條件會是:
- 在或之後需要計時閑置期間,例如DCS soft_reset
- 變更框架輸出的作業環境,例如 DCS set_vsync_timing 和 enter_sleep_mode
- 使用具有開始/繼續語意的交易,圖形驅動程式可能也需要存取相同的數據,例如 DCS write_memory_start/write_memory_continue
此外,當以傳輸方式傳送時,OS 會拒絕 DCS 命令的類別:
- 任何需要完整定義的命令,如上所述
- 可用於螢幕抓取的像素數據讀取
- 寫入像素數據
OS 將傳遞至圖形驅動程式的 UCS 命令:
十六進位 | 命令 |
---|---|
00h | nop |
26 小時 | set_gamma_curve |
2Dh | write_LUT |
51 小時 | set_display_brightness |
52 小時 | get_display_brightness |
53 小時 | write_control_display |
54 小時 | get_control_display |
55 小時 | write_power_save |
56 小時 | get_power_save |
5Eh | set_CABC_min_brightness |
5Fh | get_CABC_min_brightness |
03h | get_compression_mode |
05h | get_error_count_on_DSI |
06h | get_red_channel |
07h | get_green_channel |
08h | get_blue_channel |
0Ah | get_power_mode |
0Bh | get_address_mode |
0Ch | get_pixel_format |
0Dh | get_display_mode |
0Eh | get_signal_mode |
0Fh | get_diagnostic_result |
14 小時 | get_image_checksum_rgb |
15 小時 | get_image_checksum_ct |
3Fh | get_3D_control |
45 小時 | get_scanline |
OS 將拒絕的 UCS 命令:
十六進位 | 命令 |
---|---|
01h | soft_reset(必須透過 IOCTL_MIPI_DSI_RESET傳送) |
10 小時 | enter_sleep_mode |
11 小時 | exit_sleep_mode |
12 小時 | enter_partial_mode |
13 小時 | enter_normal_mode |
20 小時 | exit_invert_mode |
21 小時 | enter_invert_mode |
28 小時 | set_display_off |
29 小時 | set_display_on |
2Ah | set_column_address |
2Bh | set_page_address |
2Ch | write_memory_start |
2Eh | read_memory_start |
30 小時 | set_partial_rows |
31 小時 | set_partial_columns |
33 小時 | set_scroll_area |
34 小時 | set_tear_off |
35 小時 | set_tear_on |
36 小時 | set_address_mode |
37 小時 | set_scroll_start |
38 小時 | exit_idle_mode |
39 小時 | enter_idle_mode |
3Ah | set_pixel_format |
3Ch | write_memory_continue |
3Dh | set_3D_control |
3Eh | read_memory_continue |
40 小時 | set_vsync_timing |
44 小時 | set_tear_scanline |
A1h | read_DDB_start |
A2h | read_PPS_start |
A8h | read_DDB_continue |
A9h | read_PPS_continue |
圖形驅動程序實作
如果傳輸通過OS驗證,則OS會呼叫 DxgkDsiTransmission DDI,將緩衝區傳遞至圖形驅動程式。
將 OEM 傳輸新增至介面中,該介面已用來根據 OS 要求傳送圖元和控制數據,以及周邊控制的需求,這不可避免地表示圖形驅動程式需要增強其內部排序,以確保可以正確納入這個額外的封包數據流。 圖形驅動程式不得從 OEM 面板驅動程式重新排序傳輸內的封包,而且必須不中斷且不會交錯其他封包傳送整個序列。 圖形驅動程式不需要在 OEM 面板傳輸要求抵達時維持自己的封包順序,因此可以選擇在傳送 OEM 面板傳輸之前(或之後)傳送封包來設定下列畫面。 如果啟動的 OEM 面板傳輸完成可能會造成重大封包遺漏其時間範圍,則驅動程式應將傳輸報告為取消。 如果傳輸尚未啟動,但驅動程式預期它會造成重大封包遺漏其時間範圍,則驅動程式應該延遲開始傳輸,直到下一個空白期間為止。 如果延遲 OEM 面板傳輸會導致它等待兩個以上的畫面開始,驅動程式應該將傳輸報告為已卸除。
圖形驅動程式無法確保它代表面板驅動程式傳送的傳輸不會與其擁有控制權的傳輸發生衝突。 驅動程式可以選擇檢查傳輸內的封包,並在傳輸中造成問題時拒絕傳輸,但任何被視為不安全的封包都應該標幟為OS層級拒絕,因此驅動程式層級拒絕最好是因為圖形廠商的特定考慮。 驅動程式不得嘗試快取或優化讀取或寫入,即使封包似乎為標準化命令也一樣。
如果圖形驅動程式因為封包發生問題而拒絕傳輸,它就必須使用第一個封包的索引更新 FailedPacket
字段,讓傳輸遭到拒絕,並在傳回之前設定 HostErrors
DXGK_HOST_DSI_DRIVER_REJECTED_PACKET 旗標。 如果提供傳輸模式覆寫,驅動程式應該先確認覆寫與其硬體條件約束相容,如果不是,請在傳回之前設定 HostErrors
DXGK_HOST_DSI_BAD_TRANSMISSION_MODE 旗標。
如果通訊期間發生失敗,圖形驅動程式應該使用封包的索引來更新 FailedPacket
欄位,但驅動程式可能無法識別封包,因此驅動程式應該保留預設值,DXGK_DSI_INVALID_PACKET_INDEX這類情況。
圖形驅動程式負責封包的通訊,因此必須確保計算和驗證任何檢查總和。 以讀取結尾的任何傳輸都會是簡短的封包,因此 Data0 和 Data1 字段包含任何參數,而回應可能是短封包或長封包。 圖形驅動程式可能不知道傳回數據的格式和時間長度,但最大大小是最終封包承載的完整大小,包括 FinalPacketExtraPayload
。 OS 會驗證此值是否大於驅動程式在其目標功能中所報告的 TargetMaximumReturnPacketSize
,但驅動程式必須確保此緩衝區不會由周邊報告更多數據,而且來自周邊的數據不會因為大於目前套用至周邊的 MaximumReturnPacketSize 而截斷來自周邊的數據。 驅動程式會將讀取到緩衝區的位元組數目寫入描述傳輸的 ReadWordCount
欄位中。
在某些情況下,圖形驅動程式會強制將通訊介面重設為面板,或整個面板因錯誤而可能未與 OEM 面板驅動程式相關聯,而且可能無法觀察到。 若要解決此問題,驅動程式必須在重設之後,於 HostErrors
字段中回報DXGK_HOST_DSI_INTERFACE_RESET或DXGK_HOST_DSI_DEVICE_RESET設定,讓 OEM 面板驅動程式能夠偵測到情況並復原。 驅動程式不得將此傳輸傳送至硬體,但如果不需要復原,OEM 面板驅動程式可能會直接重試相同的命令,在此情況下,驅動程式應該像往常一樣繼續處理傳輸。
完成傳輸
當 IOCTL 完成讀取 FailedPacket
、ReadWordCount
、MipiErrors
、HostErrors
和讀取封包的承載時,可能會根據結果更新。 如果在處理傳輸時發現錯誤,OEM 面板驅動程式必須使用 MipiErrors
和 HostErrors
輸出值來判斷如何復原並繼續。
為了確保輸出傳回給呼叫端,以提供任何錯誤的詳細數據,即使找到錯誤,IOCTL 和 DDI 呼叫也需要回報成功。 成功並不表示交易成功,表示已適當地設定處理交易的呼叫,並已設定錯誤旗標。 可能仍會針對不支援的 DDI 呼叫等狀況回報失敗(大概因為驅動程式不符)、記憶體配置失敗或傳遞完全不正確的參數,例如傳遞 NULL 緩衝區。 如果成功呼叫時未回報任何錯誤,呼叫端應該假設交易成功。
要求
要求 | 價值 |
---|---|
最低支援的用戶端 | Windows 10 版本 2004 |
標頭 | dispmprt.h |