wined3d: Start a framework for color conversion shaders in blits.
This commit is contained in:
parent
6a24b28b75
commit
fc6b977486
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue