kvm-guest-drivers-windows
206 строк · 6.4 Кб
1#include "bitops.h"
2#include "viogpu.h"
3
4#if !DBG
5#include "bitops.tmh"
6#endif
7
8#pragma code_seg(push)
9#pragma code_seg()
10
11VOID
12GetPitches(
13_In_ CONST BLT_INFO* pBltInfo,
14_Out_ LONG* pPixelPitch,
15_Out_ LONG* pRowPitch
16)
17{
18switch (pBltInfo->Rotation) {
19case D3DKMDT_VPPR_IDENTITY:
20*pPixelPitch = (pBltInfo->BitsPerPel / BITS_PER_BYTE);
21*pRowPitch = pBltInfo->Pitch;
22return;
23case D3DKMDT_VPPR_ROTATE90:
24*pPixelPitch = -((LONG)pBltInfo->Pitch);
25*pRowPitch = (pBltInfo->BitsPerPel / BITS_PER_BYTE);
26return;
27case D3DKMDT_VPPR_ROTATE180:
28*pPixelPitch = -((LONG)pBltInfo->BitsPerPel / BITS_PER_BYTE);
29*pRowPitch = -((LONG)pBltInfo->Pitch);
30return;
31case D3DKMDT_VPPR_ROTATE270:
32*pPixelPitch = pBltInfo->Pitch;
33*pRowPitch = -((LONG)pBltInfo->BitsPerPel / BITS_PER_BYTE);
34return;
35default:
36VioGpuDbgBreak();
37VIOGPU_LOG_ASSERTION1("Invalid rotation (0x%I64x) specified", pBltInfo->Rotation);
38*pPixelPitch = 0;
39*pRowPitch = 0;
40return;
41}
42}
43
44BYTE* GetRowStart(_In_ CONST BLT_INFO* pBltInfo, _In_ CONST RECT* pRect)
45{
46BYTE* pRet = NULL;
47LONG OffLeft = pRect->left + pBltInfo->Offset.x;
48LONG OffTop = pRect->top + pBltInfo->Offset.y;
49LONG BytesPerPixel = (pBltInfo->BitsPerPel / BITS_PER_BYTE);
50
51switch (pBltInfo->Rotation) {
52case D3DKMDT_VPPR_IDENTITY:
53pRet = ((BYTE*)pBltInfo->pBits +
54(ULONGLONG)OffTop * pBltInfo->Pitch +
55(ULONGLONG)OffLeft * BytesPerPixel);
56break;
57case D3DKMDT_VPPR_ROTATE90:
58pRet = ((BYTE*)pBltInfo->pBits +
59((ULONGLONG)pBltInfo->Height - 1 - OffLeft) * pBltInfo->Pitch +
60(ULONGLONG)OffTop * BytesPerPixel);
61break;
62case D3DKMDT_VPPR_ROTATE180:
63pRet = ((BYTE*)pBltInfo->pBits +
64((ULONGLONG)pBltInfo->Height - 1 - OffTop) * pBltInfo->Pitch +
65((ULONGLONG)pBltInfo->Width - 1 - OffLeft) * BytesPerPixel);
66break;
67case D3DKMDT_VPPR_ROTATE270:
68pRet = ((PBYTE)pBltInfo->pBits +
69(ULONGLONG)OffLeft * pBltInfo->Pitch +
70((ULONGLONG)pBltInfo->Width - 1 - OffTop) * BytesPerPixel);
71break;
72default:
73{
74VIOGPU_LOG_ASSERTION1("Invalid rotation (0x%I64x) specified", pBltInfo->Rotation);
75}
76}
77
78return pRet;
79}
80
81VOID CopyBitsGeneric(
82_In_ BLT_INFO* pDst,
83_In_ CONST BLT_INFO* pSrc,
84_In_ CONST RECT *pRect)
85{
86LONG DstPixelPitch = 0;
87LONG DstRowPitch = 0;
88LONG SrcPixelPitch = 0;
89LONG SrcRowPitch = 0;
90
91DbgPrint(TRACE_LEVEL_VERBOSE, ("---> %s Dst = %p Src = %p\n", __FUNCTION__, pDst->pBits, pSrc->pBits));
92
93GetPitches(pDst, &DstPixelPitch, &DstRowPitch);
94GetPitches(pSrc, &SrcPixelPitch, &SrcRowPitch);
95
96VIOGPU_ASSERT(pRect->right >= pRect->left);
97VIOGPU_ASSERT(pRect->bottom >= pRect->top);
98
99UINT NumPixels = pRect->right - pRect->left;
100UINT NumRows = pRect->bottom - pRect->top;
101
102BYTE* pDstRow = GetRowStart(pDst, pRect);
103CONST BYTE* pSrcRow = GetRowStart(pSrc, pRect);
104
105for (UINT y = 0; y < NumRows; y++) {
106BYTE* pDstPixel = pDstRow;
107CONST BYTE* pSrcPixel = pSrcRow;
108
109for (UINT x = 0; x < NumPixels; x++) {
110if (pDst->BitsPerPel == 32 && pSrc->BitsPerPel == 32) {
111UINT32* pDstPixelAs32 = (UINT32*)pDstPixel;
112UINT32* pSrcPixelAs32 = (UINT32*)pSrcPixel;
113*pDstPixelAs32 = *pSrcPixelAs32;
114}
115else if ((pDst->BitsPerPel == 24) ||
116(pSrc->BitsPerPel == 24)) {
117pDstPixel[0] = pSrcPixel[0];
118pDstPixel[1] = pSrcPixel[1];
119pDstPixel[2] = pSrcPixel[2];
120}
121else {
122VioGpuDbgBreak();
123}
124pDstPixel += DstPixelPitch;
125pSrcPixel += SrcPixelPitch;
126}
127pDstRow += DstRowPitch;
128pSrcRow += SrcRowPitch;
129}
130}
131
132VOID CopyBits32_32(
133_In_ BLT_INFO* pDst,
134_In_ CONST BLT_INFO* pSrc,
135_In_ CONST RECT *pRect)
136{
137VIOGPU_ASSERT((pDst->BitsPerPel == 32) &&
138(pSrc->BitsPerPel == 32));
139VIOGPU_ASSERT((pDst->Rotation == D3DKMDT_VPPR_IDENTITY) &&
140(pSrc->Rotation == D3DKMDT_VPPR_IDENTITY));
141
142DbgPrint(TRACE_LEVEL_VERBOSE, ("---> %s\n", __FUNCTION__));
143
144VIOGPU_ASSERT(pRect->right >= pRect->left);
145VIOGPU_ASSERT(pRect->bottom >= pRect->top);
146
147UINT NumPixels = pRect->right - pRect->left;
148UINT NumRows = pRect->bottom - pRect->top;
149UINT BytesToCopy = NumPixels * 4;
150BYTE* pStartDst = ((BYTE*)pDst->pBits +
151((ULONGLONG)pRect->top + pDst->Offset.y) * pDst->Pitch +
152((ULONGLONG)pRect->left + pDst->Offset.x) * 4);
153CONST BYTE* pStartSrc = ((BYTE*)pSrc->pBits +
154((ULONGLONG)pRect->top + pSrc->Offset.y) * pSrc->Pitch +
155((ULONGLONG)pRect->left + pSrc->Offset.x) * 4);
156
157for (UINT i = 0; i < NumRows; ++i) {
158RtlCopyMemory(pStartDst, pStartSrc, BytesToCopy);
159pStartDst += pDst->Pitch;
160pStartSrc += pSrc->Pitch;
161}
162}
163
164VOID BltBits(
165_In_ BLT_INFO* pDst,
166_In_ CONST BLT_INFO* pSrc,
167_In_ CONST RECT *pRect)
168{
169DbgPrint(TRACE_LEVEL_VERBOSE, ("---> %s\n", __FUNCTION__));
170__try {
171if ((pDst->Rotation == D3DKMDT_VPPR_IDENTITY &&
172pSrc->Rotation == D3DKMDT_VPPR_IDENTITY) &&
173(pDst->BitsPerPel == 32 &&
174pSrc->BitsPerPel == 32)) {
175CopyBits32_32(pDst, pSrc, pRect);
176}
177else {
178CopyBitsGeneric(pDst, pSrc, pRect);
179}
180}
181#pragma prefast(suppress: __WARNING_EXCEPTIONEXECUTEHANDLER, "try/except is only able to protect against user-mode errors and these are the only errors we try to catch here");
182__except (EXCEPTION_EXECUTE_HANDLER)
183{
184DbgPrint(TRACE_LEVEL_ERROR, ("Either dst (0x%p) or src (0x%p) bits encountered exception during access.\n", pDst->pBits, pSrc->pBits));
185}
186}
187
188UINT BPPFromPixelFormat(_In_ D3DDDIFORMAT Format)
189{
190switch (Format)
191{
192case D3DDDIFMT_UNKNOWN: return 0;
193case D3DDDIFMT_A1: return 1;
194case D3DDDIFMT_P8: return 8;
195case D3DDDIFMT_R5G6B5: return 16;
196case D3DDDIFMT_R8G8B8: return 24;
197case D3DDDIFMT_X8R8G8B8:
198case D3DDDIFMT_A8R8G8B8: return 32;
199default:
200VIOGPU_LOG_ASSERTION1("Unknown D3DDDIFORMAT 0x%I64x", Format);
201VioGpuDbgBreak();
202return 32;
203}
204}
205
206#pragma code_seg(pop) // End Non-Paged Code
207