wined3d: Store dirty states per context.
This commit is contained in:
parent
e6c9a073b0
commit
380930dc54
|
@ -2007,6 +2007,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
|
||||||
|
|
||||||
/* Initialize the current view state */
|
/* Initialize the current view state */
|
||||||
This->view_ident = 1;
|
This->view_ident = 1;
|
||||||
|
This->numContexts = 1;
|
||||||
This->contexts[0].last_was_rhw = 0;
|
This->contexts[0].last_was_rhw = 0;
|
||||||
glGetIntegerv(GL_MAX_LIGHTS, &This->maxConcurrentLights);
|
glGetIntegerv(GL_MAX_LIGHTS, &This->maxConcurrentLights);
|
||||||
TRACE("(%p) All defaults now set up, leaving Init3D with %p\n", This, This);
|
TRACE("(%p) All defaults now set up, leaving Init3D with %p\n", This, This);
|
||||||
|
@ -6978,11 +6979,18 @@ void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) {
|
||||||
DWORD rep = StateTable[state].representative;
|
DWORD rep = StateTable[state].representative;
|
||||||
DWORD idx;
|
DWORD idx;
|
||||||
BYTE shift;
|
BYTE shift;
|
||||||
|
UINT i;
|
||||||
|
WineD3DContext *context;
|
||||||
|
|
||||||
if(!rep || isStateDirty(This, rep)) return;
|
if(!rep) return;
|
||||||
|
|
||||||
This->dirtyArray[This->numDirtyEntries++] = rep;
|
for(i = 0; i < This->numContexts; i++) {
|
||||||
|
context = &This->contexts[i];
|
||||||
|
if(isStateDirty(context, rep)) continue;
|
||||||
|
|
||||||
|
context->dirtyArray[context->numDirtyEntries++] = rep;
|
||||||
idx = rep >> 5;
|
idx = rep >> 5;
|
||||||
shift = rep & 0x1f;
|
shift = rep & 0x1f;
|
||||||
This->isStateDirty[idx] |= (1 << shift);
|
context->isStateDirty[idx] |= (1 << shift);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1202,14 +1202,14 @@ void drawPrimitive(IWineD3DDevice *iface,
|
||||||
context = &This->contexts[This->activeContext];
|
context = &This->contexts[This->activeContext];
|
||||||
|
|
||||||
/* Apply dirty states */
|
/* Apply dirty states */
|
||||||
for(i=0; i < This->numDirtyEntries; i++) {
|
for(i=0; i < context->numDirtyEntries; i++) {
|
||||||
dirtyState = This->dirtyArray[i];
|
dirtyState = context->dirtyArray[i];
|
||||||
idx = dirtyState >> 5;
|
idx = dirtyState >> 5;
|
||||||
shift = dirtyState & 0x1f;
|
shift = dirtyState & 0x1f;
|
||||||
This->isStateDirty[idx] &= ~(1 << shift);
|
context->isStateDirty[idx] &= ~(1 << shift);
|
||||||
StateTable[dirtyState].apply(dirtyState, This->stateBlock, context);
|
StateTable[dirtyState].apply(dirtyState, This->stateBlock, context);
|
||||||
}
|
}
|
||||||
This->numDirtyEntries = 0; /* This makes the whole list clean */
|
context->numDirtyEntries = 0; /* This makes the whole list clean */
|
||||||
|
|
||||||
if (TRACE_ON(d3d_draw) && wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
|
if (TRACE_ON(d3d_draw) && wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
|
||||||
check_fbo_status(iface);
|
check_fbo_status(iface);
|
||||||
|
|
|
@ -87,7 +87,7 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
|
||||||
* vertex declaration appplying function calls this function for updating
|
* vertex declaration appplying function calls this function for updating
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(isStateDirty(stateblock->wineD3DDevice, STATE_VDECL)) {
|
if(isStateDirty(context, STATE_VDECL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,7 +820,8 @@ static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
|
||||||
/* Depends on the decoded vertex declaration to read the existance of diffuse data.
|
/* Depends on the decoded vertex declaration to read the existance of diffuse data.
|
||||||
* The vertex declaration will call this function if the fixed function pipeline is used.
|
* The vertex declaration will call this function if the fixed function pipeline is used.
|
||||||
*/
|
*/
|
||||||
if(isStateDirty(device, STATE_VDECL)) {
|
|
||||||
|
if(isStateDirty(context, STATE_VDECL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1486,7 +1487,7 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
|
||||||
/* The sampler will also activate the correct texture dimensions, so no need to do it here
|
/* The sampler will also activate the correct texture dimensions, so no need to do it here
|
||||||
* if the sampler for this stage is dirty
|
* if the sampler for this stage is dirty
|
||||||
*/
|
*/
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_SAMPLER(stage))) {
|
if(!isStateDirty(context, STATE_SAMPLER(stage))) {
|
||||||
if (mapped_stage != -1) activate_dimensions(stage, stateblock);
|
if (mapped_stage != -1) activate_dimensions(stage, stateblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1734,11 +1735,11 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the texture matrix */
|
/* Update the texture matrix */
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
|
if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
|
||||||
transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage), stateblock, context);
|
transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage), stateblock, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_VDECL) && context->namedArraysLoaded) {
|
if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
|
||||||
/* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
|
/* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
|
||||||
* source. Call loadVertexData directly because there is no need to reparse the vertex declaration
|
* source. Call loadVertexData directly because there is no need to reparse the vertex declaration
|
||||||
* and do all the things linked to it
|
* and do all the things linked to it
|
||||||
|
@ -1864,7 +1865,7 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
|
||||||
glEnable(stateblock->textureDimensions[sampler]);
|
glEnable(stateblock->textureDimensions[sampler]);
|
||||||
checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
|
checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
|
||||||
} else if(sampler < stateblock->lowest_disabled_stage) {
|
} else if(sampler < stateblock->lowest_disabled_stage) {
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
|
if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
|
||||||
activate_dimensions(sampler, stateblock);
|
activate_dimensions(sampler, stateblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1878,7 +1879,7 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
|
||||||
} else if(sampler < GL_LIMITS(texture_stages)) {
|
} else if(sampler < GL_LIMITS(texture_stages)) {
|
||||||
if(sampler < stateblock->lowest_disabled_stage) {
|
if(sampler < stateblock->lowest_disabled_stage) {
|
||||||
/* TODO: What should I do with pixel shaders here ??? */
|
/* TODO: What should I do with pixel shaders here ??? */
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
|
if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
|
||||||
activate_dimensions(sampler, stateblock);
|
activate_dimensions(sampler, stateblock);
|
||||||
}
|
}
|
||||||
} /* Otherwise tex_colorop disables the stage */
|
} /* Otherwise tex_colorop disables the stage */
|
||||||
|
@ -1893,8 +1894,8 @@ static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
|
||||||
/* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
|
/* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
|
||||||
* has an update pending
|
* has an update pending
|
||||||
*/
|
*/
|
||||||
if(isStateDirty(device, STATE_VDECL) ||
|
if(isStateDirty(context, STATE_VDECL) ||
|
||||||
isStateDirty(device, STATE_PIXELSHADER)) {
|
isStateDirty(context, STATE_PIXELSHADER)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1913,7 +1914,7 @@ static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
|
||||||
* make sure to enable them
|
* make sure to enable them
|
||||||
*/
|
*/
|
||||||
for(i=0; i < MAX_SAMPLERS; i++) {
|
for(i=0; i < MAX_SAMPLERS; i++) {
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_SAMPLER(i))) {
|
if(!isStateDirty(context, STATE_SAMPLER(i))) {
|
||||||
sampler(STATE_SAMPLER(i), stateblock, context);
|
sampler(STATE_SAMPLER(i), stateblock, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1926,13 +1927,13 @@ static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
|
||||||
/* Compile and bind the shader */
|
/* Compile and bind the shader */
|
||||||
IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
|
IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
|
||||||
|
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, StateTable[STATE_VSHADER].representative)) {
|
if(!isStateDirty(context, StateTable[STATE_VSHADER].representative)) {
|
||||||
stateblock->wineD3DDevice->shader_backend->shader_select(
|
stateblock->wineD3DDevice->shader_backend->shader_select(
|
||||||
(IWineD3DDevice *) stateblock->wineD3DDevice,
|
(IWineD3DDevice *) stateblock->wineD3DDevice,
|
||||||
TRUE,
|
TRUE,
|
||||||
!stateblock->vertexShader ? FALSE : ((IWineD3DVertexShaderImpl *) stateblock->vertexShader)->baseShader.function != NULL);
|
!stateblock->vertexShader ? FALSE : ((IWineD3DVertexShaderImpl *) stateblock->vertexShader)->baseShader.function != NULL);
|
||||||
|
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_VERTEXSHADERCONSTANT)) {
|
if(!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)) {
|
||||||
shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
|
shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1942,19 +1943,19 @@ static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
|
||||||
* while it was enabled, so re-apply them.
|
* while it was enabled, so re-apply them.
|
||||||
*/
|
*/
|
||||||
for(i=0; i < MAX_TEXTURES; i++) {
|
for(i=0; i < MAX_TEXTURES; i++) {
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
|
if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
|
||||||
tex_colorop(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
|
tex_colorop(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
context->last_was_pshader = FALSE;
|
context->last_was_pshader = FALSE;
|
||||||
|
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, StateTable[STATE_VSHADER].representative)) {
|
if(!isStateDirty(context, StateTable[STATE_VSHADER].representative)) {
|
||||||
stateblock->wineD3DDevice->shader_backend->shader_select(
|
stateblock->wineD3DDevice->shader_backend->shader_select(
|
||||||
(IWineD3DDevice *) stateblock->wineD3DDevice,
|
(IWineD3DDevice *) stateblock->wineD3DDevice,
|
||||||
FALSE,
|
FALSE,
|
||||||
!stateblock->vertexShader ? FALSE : ((IWineD3DVertexShaderImpl *) stateblock->vertexShader)->baseShader.function != NULL);
|
!stateblock->vertexShader ? FALSE : ((IWineD3DVertexShaderImpl *) stateblock->vertexShader)->baseShader.function != NULL);
|
||||||
|
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_VERTEXSHADERCONSTANT)) {
|
if(!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)) {
|
||||||
shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
|
shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2031,7 +2032,7 @@ static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
|
||||||
/* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
|
/* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
|
||||||
* No need to do it here if the state is scheduled for update.
|
* No need to do it here if the state is scheduled for update.
|
||||||
*/
|
*/
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
|
if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
|
||||||
transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
|
transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2692,8 +2693,8 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
||||||
updateFog = TRUE;
|
updateFog = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reapply lighting if it is not scheduled for reapplication already */
|
/* Reapply lighting if it is not sheduled for reapplication already */
|
||||||
if(!isStateDirty(device, STATE_RENDER(WINED3DRS_LIGHTING))) {
|
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
|
||||||
state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
|
state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2726,8 +2727,8 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
||||||
* or transformed / untransformed was switched
|
* or transformed / untransformed was switched
|
||||||
*/
|
*/
|
||||||
if(wasrhw != context->last_was_rhw &&
|
if(wasrhw != context->last_was_rhw &&
|
||||||
!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
|
!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
|
||||||
!isStateDirty(stateblock->wineD3DDevice, STATE_VIEWPORT)) {
|
!isStateDirty(context, STATE_VIEWPORT)) {
|
||||||
transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
|
transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
|
||||||
}
|
}
|
||||||
/* World matrix needs reapplication here only if we're switching between rhw and non-rhw
|
/* World matrix needs reapplication here only if we're switching between rhw and non-rhw
|
||||||
|
@ -2742,12 +2743,12 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
||||||
* dirty
|
* dirty
|
||||||
*/
|
*/
|
||||||
if(transformed != wasrhw &&
|
if(transformed != wasrhw &&
|
||||||
!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
|
!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
|
||||||
!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_VIEW))) {
|
!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
|
||||||
transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
|
transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
|
if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
|
||||||
state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
|
state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2765,10 +2766,10 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
|
||||||
/* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
|
/* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
|
||||||
* application
|
* application
|
||||||
*/
|
*/
|
||||||
if(!isStateDirty(device, STATE_PIXELSHADER)) {
|
if(!isStateDirty(context, STATE_PIXELSHADER)) {
|
||||||
device->shader_backend->shader_select((IWineD3DDevice *) device, usePixelShaderFunction, useVertexShaderFunction);
|
device->shader_backend->shader_select((IWineD3DDevice *) device, usePixelShaderFunction, useVertexShaderFunction);
|
||||||
|
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
|
if(!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
|
||||||
shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
|
shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2793,7 +2794,7 @@ static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCon
|
||||||
|
|
||||||
stateblock->wineD3DDevice->posFixup[2] = 0.9 / stateblock->viewport.Width;
|
stateblock->wineD3DDevice->posFixup[2] = 0.9 / stateblock->viewport.Width;
|
||||||
stateblock->wineD3DDevice->posFixup[3] = -0.9 / stateblock->viewport.Height;
|
stateblock->wineD3DDevice->posFixup[3] = -0.9 / stateblock->viewport.Height;
|
||||||
if(!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(D3DTS_PROJECTION))) {
|
if(!isStateDirty(context, STATE_TRANSFORM(D3DTS_PROJECTION))) {
|
||||||
transform_projection(STATE_TRANSFORM(D3DTS_PROJECTION), stateblock, context);
|
transform_projection(STATE_TRANSFORM(D3DTS_PROJECTION), stateblock, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -405,23 +405,8 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType);
|
||||||
#define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \
|
#define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \
|
||||||
(((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1)
|
(((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1)
|
||||||
|
|
||||||
/* The new context manager that should deal with onscreen and offscreen rendering */
|
|
||||||
typedef struct WineD3DContext {
|
|
||||||
/* TODO: Dirty State list */
|
|
||||||
/* TODO: Render target / swapchain this ctx belongs to */
|
|
||||||
/* TODO: Thread this ctx belongs to */
|
|
||||||
|
|
||||||
/* Stores some inforation about the context state for optimization */
|
|
||||||
BOOL last_was_rhw; /* true iff last draw_primitive was in xyzrhw mode */
|
|
||||||
BOOL last_was_pshader;
|
|
||||||
BOOL last_was_vshader;
|
|
||||||
BOOL last_was_foggy_shader;
|
|
||||||
BOOL namedArraysLoaded, numberedArraysLoaded;
|
|
||||||
BOOL lastWasPow2Texture[MAX_TEXTURES];
|
|
||||||
GLenum tracking_parm; /* Which source is tracking current colour */
|
|
||||||
} WineD3DContext;
|
|
||||||
|
|
||||||
/* Routines and structures related to state management */
|
/* Routines and structures related to state management */
|
||||||
|
typedef struct WineD3DContext WineD3DContext;
|
||||||
typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *ctx);
|
typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *ctx);
|
||||||
|
|
||||||
#define STATE_RENDER(a) (a)
|
#define STATE_RENDER(a) (a)
|
||||||
|
@ -468,6 +453,31 @@ struct StateEntry
|
||||||
/* Global state table */
|
/* Global state table */
|
||||||
extern const struct StateEntry StateTable[];
|
extern const struct StateEntry StateTable[];
|
||||||
|
|
||||||
|
/* The new context manager that should deal with onscreen and offscreen rendering */
|
||||||
|
struct WineD3DContext {
|
||||||
|
/* State dirtification
|
||||||
|
* dirtyArray is an array that contains markers for dirty states. numDirtyEntries states are dirty, their numbers are in indices
|
||||||
|
* 0...numDirtyEntries - 1. isStateDirty is a redundant copy of the dirtyArray. Technically only one of them would be needed,
|
||||||
|
* but with the help of both it is easy to find out if a state is dirty(just check the array index), and for applying dirty states
|
||||||
|
* only numDirtyEntries array elements have to be checked, not STATE_HIGHEST states.
|
||||||
|
*/
|
||||||
|
DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */
|
||||||
|
DWORD numDirtyEntries;
|
||||||
|
DWORD isStateDirty[STATE_HIGHEST/32 + 1]; /* Bitmap to find out quickly if a state is dirty */
|
||||||
|
|
||||||
|
/* TODO: Render target / swapchain this ctx belongs to */
|
||||||
|
/* TODO: Thread this ctx belongs to */
|
||||||
|
|
||||||
|
/* Stores some inforation about the context state for optimization */
|
||||||
|
BOOL last_was_rhw; /* true iff last draw_primitive was in xyzrhw mode */
|
||||||
|
BOOL last_was_pshader;
|
||||||
|
BOOL last_was_vshader;
|
||||||
|
BOOL last_was_foggy_shader;
|
||||||
|
BOOL namedArraysLoaded, numberedArraysLoaded;
|
||||||
|
BOOL lastWasPow2Texture[MAX_TEXTURES];
|
||||||
|
GLenum tracking_parm; /* Which source is tracking current colour */
|
||||||
|
};
|
||||||
|
|
||||||
/* Routine to fill gl caps for swapchains and IWineD3D */
|
/* Routine to fill gl caps for swapchains and IWineD3D */
|
||||||
BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display);
|
BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display);
|
||||||
|
|
||||||
|
@ -665,16 +675,6 @@ typedef struct IWineD3DDeviceImpl
|
||||||
/* Final position fixup constant */
|
/* Final position fixup constant */
|
||||||
float posFixup[4];
|
float posFixup[4];
|
||||||
|
|
||||||
/* State dirtification
|
|
||||||
* dirtyArray is an array that contains markers for dirty states. numDirtyEntries states are dirty, their numbers are in indices
|
|
||||||
* 0...numDirtyEntries - 1. isStateDirty is a redundant copy of the dirtyArray. Technically only one of them would be needed,
|
|
||||||
* but with the help of both it is easy to find out if a state is dirty(just check the array index), and for applying dirty states
|
|
||||||
* only numDirtyEntries array elements have to be checked, not STATE_HIGHEST states.
|
|
||||||
*/
|
|
||||||
DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */
|
|
||||||
DWORD numDirtyEntries;
|
|
||||||
DWORD isStateDirty[STATE_HIGHEST/32 + 1]; /* Bitmap to find out quickly if a state is dirty */
|
|
||||||
|
|
||||||
/* With register combiners we can skip junk texture stages */
|
/* With register combiners we can skip junk texture stages */
|
||||||
DWORD texUnitMap[MAX_SAMPLERS];
|
DWORD texUnitMap[MAX_SAMPLERS];
|
||||||
BOOL oneToOneTexUnitMap;
|
BOOL oneToOneTexUnitMap;
|
||||||
|
@ -687,15 +687,16 @@ typedef struct IWineD3DDeviceImpl
|
||||||
/* Context management */
|
/* Context management */
|
||||||
WineD3DContext contexts[1]; /* Dynamic array later */
|
WineD3DContext contexts[1]; /* Dynamic array later */
|
||||||
UINT activeContext; /* Only 0 for now */
|
UINT activeContext; /* Only 0 for now */
|
||||||
|
UINT numContexts; /* Always 1 for now */
|
||||||
} IWineD3DDeviceImpl;
|
} IWineD3DDeviceImpl;
|
||||||
|
|
||||||
extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl;
|
extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl;
|
||||||
|
|
||||||
void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state);
|
void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state);
|
||||||
static inline BOOL isStateDirty(IWineD3DDeviceImpl *This, DWORD state) {
|
static inline BOOL isStateDirty(WineD3DContext *context, DWORD state) {
|
||||||
DWORD idx = state >> 5;
|
DWORD idx = state >> 5;
|
||||||
BYTE shift = state & 0x1f;
|
BYTE shift = state & 0x1f;
|
||||||
return This->isStateDirty[idx] & (1 << shift);
|
return context->isStateDirty[idx] & (1 << shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Support for IWineD3DResource ::Set/Get/FreePrivateData. I don't think
|
/* Support for IWineD3DResource ::Set/Get/FreePrivateData. I don't think
|
||||||
|
|
Loading…
Reference in New Issue