mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 19:50:11 +01:00
st/wgl: Properly support non-displayble pixel formats, and implement float pixelformats as as one.
WGL_ARB_pixel_format establishes the existence of pixel formats which are invisible to GDI. However we still need to pass a valid pixelformat to GDI, so that context creation/binding works. The actual WGL_TYPE_RGBA_FLOAT_ARB implementation is from Brian Paul.
This commit is contained in:
parent
90a95f4d2c
commit
9646762261
6 changed files with 109 additions and 16 deletions
|
|
@ -138,6 +138,7 @@ stw_create_context_attribs(
|
|||
int contextFlags, int profileMask)
|
||||
{
|
||||
int iPixelFormat;
|
||||
struct stw_framebuffer *fb;
|
||||
const struct stw_pixelformat_info *pfi;
|
||||
struct st_context_attribs attribs;
|
||||
struct stw_context *ctx = NULL;
|
||||
|
|
@ -154,6 +155,19 @@ stw_create_context_attribs(
|
|||
if(!iPixelFormat)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* GDI only knows about displayable pixel formats, so determine the pixel format
|
||||
* from the framebuffer.
|
||||
*
|
||||
* TODO: Remove the GetPixelFormat() above, and stop relying on GDI.
|
||||
*/
|
||||
fb = stw_framebuffer_from_hdc( hdc );
|
||||
if (fb) {
|
||||
assert(iPixelFormat == fb->iDisplayablePixelFormat);
|
||||
iPixelFormat = fb->iPixelFormat;
|
||||
stw_framebuffer_release(fb);
|
||||
}
|
||||
|
||||
pfi = stw_pixelformat_get_info( iPixelFormat );
|
||||
|
||||
if (hShareContext != 0) {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
|
||||
HPBUFFERARB WINAPI
|
||||
wglCreatePbufferARB(HDC _hDC,
|
||||
wglCreatePbufferARB(HDC hCurrentDC,
|
||||
int iPixelFormat,
|
||||
int iWidth,
|
||||
int iHeight,
|
||||
|
|
@ -81,6 +81,9 @@ wglCreatePbufferARB(HDC _hDC,
|
|||
RECT rect;
|
||||
HWND hWnd;
|
||||
HDC hDC;
|
||||
int iDisplayablePixelFormat;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
BOOL bRet;
|
||||
|
||||
info = stw_pixelformat_get_info(iPixelFormat);
|
||||
if (!info) {
|
||||
|
|
@ -204,15 +207,28 @@ wglCreatePbufferARB(HDC _hDC,
|
|||
return 0;
|
||||
}
|
||||
|
||||
SetPixelFormat(hDC, iPixelFormat, &info->pfd);
|
||||
|
||||
/*
|
||||
* We can't pass non-displayable pixel formats to GDI, which is why we
|
||||
* create the framebuffer object before calling SetPixelFormat().
|
||||
*/
|
||||
fb = stw_framebuffer_create(hDC, iPixelFormat);
|
||||
if (!fb) {
|
||||
SetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
||||
} else {
|
||||
stw_framebuffer_release(fb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fb->bPbuffer = TRUE;
|
||||
iDisplayablePixelFormat = fb->iDisplayablePixelFormat;
|
||||
|
||||
stw_framebuffer_release(fb);
|
||||
|
||||
/*
|
||||
* We need to set a displayable pixel format on the hidden window DC
|
||||
* so that wglCreateContext and wglMakeCurrent are not overruled by GDI.
|
||||
*/
|
||||
bRet = SetPixelFormat(hDC, iDisplayablePixelFormat, &pfd);
|
||||
assert(bRet);
|
||||
|
||||
return (HPBUFFERARB)fb;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include <GL/wglext.h>
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "stw_device.h"
|
||||
#include "stw_pixelformat.h"
|
||||
|
|
@ -147,7 +148,12 @@ stw_query_attrib(
|
|||
case WGL_PIXEL_TYPE_ARB:
|
||||
switch (pfi->pfd.iPixelType) {
|
||||
case PFD_TYPE_RGBA:
|
||||
if (util_format_is_float(pfi->stvis.color_format)) {
|
||||
*pvalue = WGL_TYPE_RGBA_FLOAT_ARB;
|
||||
}
|
||||
else {
|
||||
*pvalue = WGL_TYPE_RGBA_ARB;
|
||||
}
|
||||
break;
|
||||
case PFD_TYPE_COLORINDEX:
|
||||
*pvalue = WGL_TYPE_COLORINDEX_ARB;
|
||||
|
|
|
|||
|
|
@ -262,6 +262,12 @@ stw_framebuffer_create(
|
|||
fb->hWnd = hWnd;
|
||||
fb->iPixelFormat = iPixelFormat;
|
||||
|
||||
/*
|
||||
* We often need a displayable pixel format to make GDI happy. Set it here (always 1, i.e.,
|
||||
* out first pixel format) where appropriat.
|
||||
*/
|
||||
fb->iDisplayablePixelFormat = iPixelFormat <= stw_dev->pixelformat_count ? iPixelFormat : 1;
|
||||
|
||||
fb->pfi = pfi = stw_pixelformat_get_info( iPixelFormat );
|
||||
fb->stfb = stw_st_create_framebuffer( fb );
|
||||
if (!fb->stfb) {
|
||||
|
|
@ -445,15 +451,21 @@ DrvSetPixelFormat(
|
|||
return FALSE;
|
||||
|
||||
index = (uint) iPixelFormat - 1;
|
||||
count = stw_pixelformat_get_extended_count();
|
||||
count = stw_pixelformat_get_count();
|
||||
if (index >= count)
|
||||
return FALSE;
|
||||
|
||||
fb = stw_framebuffer_from_hdc_locked(hdc);
|
||||
if(fb) {
|
||||
/* SetPixelFormat must be called only once */
|
||||
/*
|
||||
* SetPixelFormat must be called only once. However ignore
|
||||
* pbuffers, for which the framebuffer object is created first.
|
||||
*/
|
||||
boolean bPbuffer = fb->bPbuffer;
|
||||
|
||||
stw_framebuffer_release( fb );
|
||||
return FALSE;
|
||||
|
||||
return bPbuffer;
|
||||
}
|
||||
|
||||
fb = stw_framebuffer_create(hdc, iPixelFormat);
|
||||
|
|
@ -467,7 +479,8 @@ DrvSetPixelFormat(
|
|||
* function instead of SetPixelFormat, so we call SetPixelFormat here to
|
||||
* avoid opengl32.dll's wglCreateContext to fail */
|
||||
if (GetPixelFormat(hdc) == 0) {
|
||||
SetPixelFormat(hdc, iPixelFormat, NULL);
|
||||
BOOL bRet = SetPixelFormat(hdc, iPixelFormat, NULL);
|
||||
assert(bRet);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,10 @@ struct stw_framebuffer
|
|||
int iPixelFormat;
|
||||
const struct stw_pixelformat_info *pfi;
|
||||
|
||||
/* A pixel format that can be used by GDI */
|
||||
int iDisplayablePixelFormat;
|
||||
boolean bPbuffer;
|
||||
|
||||
struct st_framebuffer_iface *stfb;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -85,6 +85,10 @@ stw_pf_color[] = {
|
|||
{ PIPE_FORMAT_B4G4R4A4_UNORM, { 4, 4, 4, 4}, {16, 4, 0, 12} }
|
||||
};
|
||||
|
||||
static const struct stw_pf_color_info
|
||||
stw_pf_color_extended[] = {
|
||||
{ PIPE_FORMAT_R32G32B32A32_FLOAT, { 32, 32, 32, 32}, { 0, 32, 64, 96} }
|
||||
};
|
||||
|
||||
static const struct stw_pf_depth_info
|
||||
stw_pf_depth_stencil[] = {
|
||||
|
|
@ -116,13 +120,13 @@ stw_pf_multisample[] = {
|
|||
static void
|
||||
stw_pixelformat_add(
|
||||
struct stw_device *stw_dev,
|
||||
boolean extended,
|
||||
const struct stw_pf_color_info *color,
|
||||
const struct stw_pf_depth_info *depth,
|
||||
unsigned accum,
|
||||
boolean doublebuffer,
|
||||
unsigned samples )
|
||||
{
|
||||
boolean extended = FALSE;
|
||||
struct stw_pixelformat_info *pfi;
|
||||
|
||||
assert(stw_dev->pixelformat_extended_count < STW_MAX_PIXELFORMATS);
|
||||
|
|
@ -146,7 +150,9 @@ stw_pixelformat_add(
|
|||
pfi->pfd.dwFlags = PFD_SUPPORT_OPENGL;
|
||||
|
||||
/* TODO: also support non-native pixel formats */
|
||||
if (!extended) {
|
||||
pfi->pfd.dwFlags |= PFD_DRAW_TO_WINDOW;
|
||||
}
|
||||
|
||||
/* See http://www.opengl.org/pipeline/article/vol003_7/ */
|
||||
pfi->pfd.dwFlags |= PFD_SUPPORT_COMPOSITION;
|
||||
|
|
@ -238,8 +244,42 @@ stw_pixelformat_init( void )
|
|||
0, PIPE_BIND_DEPTH_STENCIL))
|
||||
continue;
|
||||
|
||||
stw_pixelformat_add( stw_dev, color, depth, 0, doublebuffer, samples );
|
||||
stw_pixelformat_add( stw_dev, color, depth, 16, doublebuffer, samples );
|
||||
stw_pixelformat_add( stw_dev, FALSE, color, depth, 0, doublebuffer, samples );
|
||||
stw_pixelformat_add( stw_dev, FALSE, color, depth, 16, doublebuffer, samples );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as above, but for the extended color formats (e.g, float) and without PIPE_BIND_DISPLAY_TARGET bit.
|
||||
*/
|
||||
for(i = 0; i < Elements(stw_pf_multisample); ++i) {
|
||||
unsigned samples = stw_pf_multisample[i];
|
||||
|
||||
/* FIXME: re-enabled MSAA when we can query it */
|
||||
if(samples)
|
||||
continue;
|
||||
|
||||
for(j = 0; j < Elements(stw_pf_color_extended); ++j) {
|
||||
const struct stw_pf_color_info *color = &stw_pf_color_extended[j];
|
||||
|
||||
if(!screen->is_format_supported(screen, color->format, PIPE_TEXTURE_2D,
|
||||
0, PIPE_BIND_RENDER_TARGET))
|
||||
continue;
|
||||
|
||||
for(k = 0; k < Elements(stw_pf_doublebuffer); ++k) {
|
||||
unsigned doublebuffer = stw_pf_doublebuffer[k];
|
||||
|
||||
for(l = 0; l < Elements(stw_pf_depth_stencil); ++l) {
|
||||
const struct stw_pf_depth_info *depth = &stw_pf_depth_stencil[l];
|
||||
|
||||
if(!screen->is_format_supported(screen, depth->format, PIPE_TEXTURE_2D,
|
||||
0, PIPE_BIND_DEPTH_STENCIL))
|
||||
continue;
|
||||
|
||||
stw_pixelformat_add( stw_dev, TRUE, color, depth, 0, doublebuffer, samples );
|
||||
stw_pixelformat_add( stw_dev, TRUE, color, depth, 16, doublebuffer, samples );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -294,7 +334,7 @@ DrvDescribePixelFormat(
|
|||
if (!stw_dev)
|
||||
return 0;
|
||||
|
||||
count = stw_pixelformat_get_extended_count();
|
||||
count = stw_pixelformat_get_count();
|
||||
|
||||
if (ppfd == NULL)
|
||||
return count;
|
||||
|
|
@ -370,7 +410,7 @@ int stw_pixelformat_choose( HDC hdc,
|
|||
|
||||
(void) hdc;
|
||||
|
||||
count = stw_pixelformat_get_count();
|
||||
count = stw_pixelformat_get_extended_count();
|
||||
bestindex = 0;
|
||||
bestdelta = ~0U;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue