wined3d: Start a framework for color conversion shaders in blits.

This commit is contained in:
Stefan Dösinger 2008-08-01 13:21:10 -05:00 committed by Alexandre Julliard
parent 6a24b28b75
commit fc6b977486
4 changed files with 78 additions and 6 deletions

View File

@ -2170,6 +2170,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
TRACE("Fragment pipeline private data couldn't be allocated\n");
goto err_out;
}
hr = This->blitter->alloc_private(iface);
if(FAILED(hr)) {
TRACE("Blitter private data couldn't be allocated\n");
goto err_out;
}
/* Set up some starting GL setup */
@ -2254,6 +2259,7 @@ err_out:
IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->stateBlock);
This->stateBlock = NULL;
}
This->blitter->free_private(iface);
This->frag_pipe->free_private(iface);
This->shader_backend->shader_free_private(iface);
return hr;
@ -2371,6 +2377,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D
}
/* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */
This->blitter->free_private(iface);
This->frag_pipe->free_private(iface);
This->shader_backend->shader_free_private(iface);
@ -7220,6 +7227,7 @@ void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_
This->depth_blt_rb_w = 0;
This->depth_blt_rb_h = 0;
}
This->blitter->free_private(iface);
This->frag_pipe->free_private(iface);
This->shader_backend->shader_free_private(iface);
@ -7263,15 +7271,26 @@ HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *
hr = This->shader_backend->shader_alloc_private(iface);
if(FAILED(hr)) {
ERR("Failed to recreate shader private data\n");
return hr;
goto err_out;
}
hr = This->frag_pipe->alloc_private(iface);
if(FAILED(hr)) {
TRACE("Fragment pipeline private data couldn't be allocated\n");
return hr;
goto err_out;
}
hr = This->blitter->alloc_private(iface);
if(FAILED(hr)) {
TRACE("Blitter private data couldn't be allocated\n");
goto err_out;
}
return WINED3D_OK;
err_out:
This->blitter->free_private(iface);
This->frag_pipe->free_private(iface);
This->shader_backend->shader_free_private(iface);
return hr;
}
static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters) {

View File

@ -2933,6 +2933,15 @@ static const struct fragment_pipeline *select_fragment_implementation(UINT Adapt
}
}
static const struct blit_shader *select_blit_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType) {
int vs_selected_mode;
int ps_selected_mode;
select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
return &ffp_blit;
}
/* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
subset of a D3DCAPS9 structure. However, it has to come via a void *
as the d3d8 interface cannot import the d3d9 header */
@ -3568,6 +3577,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
object->frag_pipe = frag_pipeline;
compile_state_table(object->StateTable, object->multistate_funcs, &GLINFO_LOCATION,
ffp_vertexstate_template, frag_pipeline, misc_state_template);
object->blitter = select_blit_implementation(Adapter, DeviceType);
/* Prefer the vtable with functions optimized for single dirtifyable objects if the shader
* model can deal with that. It is essentially the same, just with adjusted

View File

@ -3467,8 +3467,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
glDrawBuffer(buffer);
checkGLcall("glDrawBuffer");
glEnable(Src->glDescription.target);
checkGLcall("glEnable(Src->glDescription.target)");
myDevice->blitter->set_shader((IWineD3DDevice *) myDevice, Src->resource.format,
Src->glDescription.target, Src->pow2Width, Src->pow2Height);
/* Bind the texture */
glBindTexture(Src->glDescription.target, Src->glDescription.textureName);
@ -3537,8 +3537,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
glBindTexture(Src->glDescription.target, 0);
checkGLcall("glBindTexture(Src->glDescription.target, 0)");
/* Leave the opengl state valid for blitting */
glDisable(Src->glDescription.target);
checkGLcall("glDisable(Src->glDescription.target)");
myDevice->blitter->unset_shader((IWineD3DDevice *) myDevice);
/* The draw buffer should only need to be restored if we were drawing to the front buffer, and there is a back buffer.
* otherwise the context manager should choose between GL_BACK / offscreenDrawBuffer
@ -4623,3 +4622,35 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
IWineD3DSurfaceImpl_GetImplType,
IWineD3DSurfaceImpl_DrawOverlay
};
#undef GLINFO_LOCATION
#define GLINFO_LOCATION device->adapter->gl_info
static HRESULT ffp_blit_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
static void ffp_blit_free(IWineD3DDevice *iface) { }
static HRESULT ffp_blit_set(IWineD3DDevice *iface, WINED3DFORMAT fmt, GLenum textype, UINT width, UINT height) {
glEnable(textype);
checkGLcall("glEnable(textype)");
return WINED3D_OK;
}
static void ffp_blit_unset(IWineD3DDevice *iface) {
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
glDisable(GL_TEXTURE_2D);
checkGLcall("glDisable(GL_TEXTURE_2D)");
if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
}
if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
glDisable(GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
}
}
const struct blit_shader ffp_blit = {
ffp_blit_alloc,
ffp_blit_free,
ffp_blit_set,
ffp_blit_unset
};

View File

@ -575,6 +575,16 @@ void compile_state_table(struct StateEntry *StateTable,
const struct fragment_pipeline *fragment,
const struct StateEntryTemplate *misc);
/* Shaders for color conversions in blits */
struct blit_shader {
HRESULT (*alloc_private)(IWineD3DDevice *iface);
void (*free_private)(IWineD3DDevice *iface);
HRESULT (*set_shader)(IWineD3DDevice *iface, WINED3DFORMAT fmt, GLenum textype, UINT width, UINT height);
void (*unset_shader)(IWineD3DDevice *iface);
};
extern const struct blit_shader ffp_blit;
/* The new context manager that should deal with onscreen and offscreen rendering */
struct WineD3DContext {
/* State dirtification
@ -829,10 +839,12 @@ struct IWineD3DDeviceImpl
const shader_backend_t *shader_backend;
void *shader_priv;
void *fragment_priv;
void *blit_priv;
struct StateEntry StateTable[STATE_HIGHEST + 1];
/* Array of functions for states which are handled by more than one pipeline part */
APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1];
const struct fragment_pipeline *frag_pipe;
const struct blit_shader *blitter;
/* To store */
BOOL view_ident; /* true iff view matrix is identity */