kvm-guest-drivers-windows

Форк
0
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

11
VOID
12
GetPitches(
13
    _In_ CONST BLT_INFO* pBltInfo,
14
    _Out_ LONG* pPixelPitch,
15
    _Out_ LONG* pRowPitch
16
)
17
{
18
    switch (pBltInfo->Rotation) {
19
    case D3DKMDT_VPPR_IDENTITY:
20
        *pPixelPitch = (pBltInfo->BitsPerPel / BITS_PER_BYTE);
21
        *pRowPitch = pBltInfo->Pitch;
22
        return;
23
    case D3DKMDT_VPPR_ROTATE90:
24
        *pPixelPitch = -((LONG)pBltInfo->Pitch);
25
        *pRowPitch = (pBltInfo->BitsPerPel / BITS_PER_BYTE);
26
        return;
27
    case D3DKMDT_VPPR_ROTATE180:
28
        *pPixelPitch = -((LONG)pBltInfo->BitsPerPel / BITS_PER_BYTE);
29
        *pRowPitch = -((LONG)pBltInfo->Pitch);
30
        return;
31
    case D3DKMDT_VPPR_ROTATE270:
32
        *pPixelPitch = pBltInfo->Pitch;
33
        *pRowPitch = -((LONG)pBltInfo->BitsPerPel / BITS_PER_BYTE);
34
        return;
35
    default:
36
        VioGpuDbgBreak();
37
        VIOGPU_LOG_ASSERTION1("Invalid rotation (0x%I64x) specified", pBltInfo->Rotation);
38
        *pPixelPitch = 0;
39
        *pRowPitch = 0;
40
        return;
41
    }
42
}
43

44
BYTE* GetRowStart(_In_ CONST BLT_INFO* pBltInfo, _In_ CONST RECT* pRect)
45
{
46
    BYTE* pRet = NULL;
47
    LONG OffLeft = pRect->left + pBltInfo->Offset.x;
48
    LONG OffTop = pRect->top + pBltInfo->Offset.y;
49
    LONG BytesPerPixel = (pBltInfo->BitsPerPel / BITS_PER_BYTE);
50

51
    switch (pBltInfo->Rotation) {
52
    case D3DKMDT_VPPR_IDENTITY:
53
        pRet = ((BYTE*)pBltInfo->pBits +
54
            (ULONGLONG)OffTop * pBltInfo->Pitch +
55
            (ULONGLONG)OffLeft * BytesPerPixel);
56
        break;
57
    case D3DKMDT_VPPR_ROTATE90:
58
        pRet = ((BYTE*)pBltInfo->pBits +
59
            ((ULONGLONG)pBltInfo->Height - 1 - OffLeft) * pBltInfo->Pitch +
60
            (ULONGLONG)OffTop * BytesPerPixel);
61
        break;
62
    case D3DKMDT_VPPR_ROTATE180:
63
        pRet = ((BYTE*)pBltInfo->pBits +
64
            ((ULONGLONG)pBltInfo->Height - 1 - OffTop) * pBltInfo->Pitch +
65
            ((ULONGLONG)pBltInfo->Width - 1 - OffLeft) * BytesPerPixel);
66
        break;
67
    case D3DKMDT_VPPR_ROTATE270:
68
        pRet = ((PBYTE)pBltInfo->pBits +
69
            (ULONGLONG)OffLeft * pBltInfo->Pitch +
70
            ((ULONGLONG)pBltInfo->Width - 1 - OffTop) * BytesPerPixel);
71
        break;
72
    default:
73
    {
74
        VIOGPU_LOG_ASSERTION1("Invalid rotation (0x%I64x) specified", pBltInfo->Rotation);
75
    }
76
    }
77

78
    return pRet;
79
}
80

81
VOID CopyBitsGeneric(
82
    _In_  BLT_INFO* pDst,
83
    _In_ CONST BLT_INFO* pSrc,
84
    _In_ CONST RECT *pRect)
85
{
86
    LONG DstPixelPitch = 0;
87
    LONG DstRowPitch = 0;
88
    LONG SrcPixelPitch = 0;
89
    LONG SrcRowPitch = 0;
90

91
    DbgPrint(TRACE_LEVEL_VERBOSE, ("---> %s Dst = %p Src = %p\n", __FUNCTION__, pDst->pBits, pSrc->pBits));
92

93
    GetPitches(pDst, &DstPixelPitch, &DstRowPitch);
94
    GetPitches(pSrc, &SrcPixelPitch, &SrcRowPitch);
95

96
    VIOGPU_ASSERT(pRect->right >= pRect->left);
97
    VIOGPU_ASSERT(pRect->bottom >= pRect->top);
98

99
    UINT NumPixels = pRect->right - pRect->left;
100
    UINT NumRows = pRect->bottom - pRect->top;
101

102
    BYTE* pDstRow = GetRowStart(pDst, pRect);
103
    CONST BYTE* pSrcRow = GetRowStart(pSrc, pRect);
104

105
    for (UINT y = 0; y < NumRows; y++) {
106
        BYTE* pDstPixel = pDstRow;
107
        CONST BYTE* pSrcPixel = pSrcRow;
108

109
        for (UINT x = 0; x < NumPixels; x++) {
110
            if (pDst->BitsPerPel == 32 && pSrc->BitsPerPel == 32) {
111
                UINT32* pDstPixelAs32 = (UINT32*)pDstPixel;
112
                UINT32* pSrcPixelAs32 = (UINT32*)pSrcPixel;
113
                *pDstPixelAs32 = *pSrcPixelAs32;
114
            }
115
            else if ((pDst->BitsPerPel == 24) ||
116
                (pSrc->BitsPerPel == 24)) {
117
                pDstPixel[0] = pSrcPixel[0];
118
                pDstPixel[1] = pSrcPixel[1];
119
                pDstPixel[2] = pSrcPixel[2];
120
            }
121
            else {
122
                VioGpuDbgBreak();
123
            }
124
            pDstPixel += DstPixelPitch;
125
            pSrcPixel += SrcPixelPitch;
126
        }
127
        pDstRow += DstRowPitch;
128
        pSrcRow += SrcRowPitch;
129
    }
130
}
131

132
VOID CopyBits32_32(
133
    _In_ BLT_INFO* pDst,
134
    _In_ CONST BLT_INFO* pSrc,
135
    _In_ CONST RECT *pRect)
136
{
137
    VIOGPU_ASSERT((pDst->BitsPerPel == 32) &&
138
        (pSrc->BitsPerPel == 32));
139
    VIOGPU_ASSERT((pDst->Rotation == D3DKMDT_VPPR_IDENTITY) &&
140
        (pSrc->Rotation == D3DKMDT_VPPR_IDENTITY));
141

142
    DbgPrint(TRACE_LEVEL_VERBOSE, ("---> %s\n", __FUNCTION__));
143

144
    VIOGPU_ASSERT(pRect->right >= pRect->left);
145
    VIOGPU_ASSERT(pRect->bottom >= pRect->top);
146

147
    UINT NumPixels = pRect->right - pRect->left;
148
    UINT NumRows = pRect->bottom - pRect->top;
149
    UINT BytesToCopy = NumPixels * 4;
150
    BYTE* pStartDst = ((BYTE*)pDst->pBits +
151
        ((ULONGLONG)pRect->top + pDst->Offset.y) * pDst->Pitch +
152
        ((ULONGLONG)pRect->left + pDst->Offset.x) * 4);
153
    CONST BYTE* pStartSrc = ((BYTE*)pSrc->pBits +
154
        ((ULONGLONG)pRect->top + pSrc->Offset.y) * pSrc->Pitch +
155
        ((ULONGLONG)pRect->left + pSrc->Offset.x) * 4);
156

157
    for (UINT i = 0; i < NumRows; ++i) {
158
        RtlCopyMemory(pStartDst, pStartSrc, BytesToCopy);
159
        pStartDst += pDst->Pitch;
160
        pStartSrc += pSrc->Pitch;
161
    }
162
}
163

164
VOID BltBits(
165
    _In_ BLT_INFO* pDst,
166
    _In_ CONST BLT_INFO* pSrc,
167
    _In_ CONST RECT *pRect)
168
{
169
    DbgPrint(TRACE_LEVEL_VERBOSE, ("---> %s\n", __FUNCTION__));
170
    __try {
171
        if ((pDst->Rotation == D3DKMDT_VPPR_IDENTITY &&
172
            pSrc->Rotation == D3DKMDT_VPPR_IDENTITY) &&
173
            (pDst->BitsPerPel == 32 &&
174
             pSrc->BitsPerPel == 32)) {
175
            CopyBits32_32(pDst, pSrc, pRect);
176
        }
177
        else {
178
            CopyBitsGeneric(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
    {
184
        DbgPrint(TRACE_LEVEL_ERROR, ("Either dst (0x%p) or src (0x%p) bits encountered exception during access.\n", pDst->pBits, pSrc->pBits));
185
    }
186
}
187

188
UINT BPPFromPixelFormat(_In_ D3DDDIFORMAT Format)
189
{
190
    switch (Format)
191
    {
192
    case D3DDDIFMT_UNKNOWN: return 0;
193
    case D3DDDIFMT_A1: return 1;
194
    case D3DDDIFMT_P8: return 8;
195
    case D3DDDIFMT_R5G6B5: return 16;
196
    case D3DDDIFMT_R8G8B8: return 24;
197
    case D3DDDIFMT_X8R8G8B8:
198
    case D3DDDIFMT_A8R8G8B8: return 32;
199
    default:
200
        VIOGPU_LOG_ASSERTION1("Unknown D3DDDIFORMAT 0x%I64x", Format);
201
        VioGpuDbgBreak();
202
        return 32;
203
    }
204
}
205

206
#pragma code_seg(pop) // End Non-Paged Code
207

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.