d3d10umd: Use flush_frontbuffer for Present

This is required to allow gallium drivers to display instead of
forcing software display. On llvmpipe/softpipe for sw display
gdi_sw_winsys will be used. While "hardware" drivers will be
able to call pfnPresentCb to present without CPU copy.

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Reviewed-by: Jose Fonseca <jose.fonseca@broadcom.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27333>
This commit is contained in:
Max R 2024-01-29 13:17:03 +03:00 committed by Marge Bot
parent 2b5e257690
commit 253968fc60
2 changed files with 6 additions and 116 deletions

View file

@ -58,124 +58,11 @@ _Present(DXGI_DDI_ARG_PRESENT *pPresentData)
LOG_ENTRYPOINT();
struct pipe_context *pipe = CastPipeDevice(pPresentData->hDevice);
struct Device *device = CastDevice(pPresentData->hDevice);
Resource *pSrcResource = CastResource(pPresentData->hSurfaceToPresent);
D3DKMT_PRESENT *pPresentInfo = (D3DKMT_PRESENT *)pPresentData->pDXGIContext;
HWND hWnd = pPresentInfo->hWindow;
if (0) {
DebugPrintf(" hWindow = 0x%08lx\n", pPresentInfo->hWindow);
if (pPresentInfo->Flags.SrcRectValid) {
DebugPrintf(" SrcRect.left = %li\n", pPresentInfo->SrcRect.left);
DebugPrintf(" SrcRect.top = %li\n", pPresentInfo->SrcRect.top);
DebugPrintf(" SrcRect.right = %li\n", pPresentInfo->SrcRect.right);
DebugPrintf(" SrcRect.bottom = %li\n", pPresentInfo->SrcRect.bottom);
}
if (pPresentInfo->Flags.DstRectValid) {
DebugPrintf(" DstRect.left = %li\n", pPresentInfo->DstRect.left);
DebugPrintf(" DstRect.top = %li\n", pPresentInfo->DstRect.top);
DebugPrintf(" DstRect.right = %li\n", pPresentInfo->DstRect.right);
DebugPrintf(" DstRect.bottom = %li\n", pPresentInfo->DstRect.bottom);
}
}
RECT rect;
if (!GetClientRect(hWnd, &rect)) {
DebugPrintf("Invalid window.\n");
return S_OK;
}
int windowWidth = rect.right - rect.left;
int windowHeight = rect.bottom - rect.top;
HDC hDC = GetDC(hWnd);
unsigned w = pSrcResource->resource->width0;
unsigned h = pSrcResource->resource->height0;
void *map;
struct pipe_transfer *transfer;
map = pipe_texture_map(pipe,
pSrcResource->resource,
0, 0, PIPE_MAP_READ,
0, 0, w, h,
&transfer);
if (map) {
BITMAPINFO bmi;
memset(&bmi, 0, sizeof bmi);
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = w;
bmi.bmiHeader.biHeight= -(long)h;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
DWORD *pixels = NULL;
// http://www.daniweb.com/software-development/cpp/code/241875/fast-animation-with-the-windows-gdi
HBITMAP hBmp = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pixels, NULL, 0);
util_format_translate(
PIPE_FORMAT_B8G8R8X8_UNORM,
(void *)pixels, w * 4,
0, 0,
pSrcResource->resource->format,
map, transfer->stride,
0, 0, w, h);
if (0) {
/*
* Save a BMP for debugging.
*/
FILE *fp = fopen("present.bmp", "wb");
if (fp) {
BITMAPFILEHEADER bmf;
bmf.bfType = 0x4d42;
bmf.bfSize = sizeof bmf + sizeof bmi + h * w * 4;
bmf.bfReserved1 = 0;
bmf.bfReserved2 = 0;
bmf.bfOffBits = sizeof bmf + sizeof bmi;
fwrite(&bmf, sizeof bmf, 1, fp);
fwrite(&bmi, sizeof bmi, 1, fp);
fwrite(pixels, h, w * 4, fp);
fclose(fp);
}
}
HDC hdcMem;
hdcMem = CreateCompatibleDC(hDC);
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hBmp);
int iStretchMode = SetStretchBltMode(hDC, HALFTONE);
StretchBlt(hDC, 0, 0, windowWidth, windowHeight,
hdcMem, 0, 0, w, h,
SRCCOPY);
if (iStretchMode) {
SetStretchBltMode(hDC, iStretchMode);
}
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
DeleteObject(hBmp);
pipe_texture_unmap(pipe, transfer);
}
ReleaseDC(hWnd, hDC);
device->pipe->screen->flush_frontbuffer(device->pipe->screen, device->pipe,
pSrcResource->resource, 0, 0, pPresentData->pDXGIContext, NULL);
return S_OK;
}

View file

@ -118,6 +118,9 @@ translate_resource_flags(UINT flags)
if (flags & D3D10_DDI_BIND_STREAM_OUTPUT)
bind |= PIPE_BIND_STREAM_OUTPUT;
if (flags & D3D10_DDI_BIND_PRESENT)
bind |= PIPE_BIND_DISPLAY_TARGET;
return bind;
}