wined3d: Use register combiners for texture stage operations.

Make wined3d use register combiners for texture stage operations. In
order to do that the texture unit index needs to be separated from the
texture stage index. For cards that don't support the
NV_register_combiners extension nothing should change.
This commit is contained in:
H. Verbeet 2006-06-27 23:44:26 +02:00 committed by Alexandre Julliard
parent f3a2a9f30a
commit 7f9e61f7d2
5 changed files with 182 additions and 140 deletions

View File

@ -418,7 +418,7 @@ static void delete_glsl_shader_list(IWineD3DDevice* iface) {
/* Apply the current values to the specified texture stage */
static void WINAPI IWineD3DDeviceImpl_SetupTextureStates(IWineD3DDevice *iface, DWORD Sampler, DWORD Flags) {
static void WINAPI IWineD3DDeviceImpl_SetupTextureStates(IWineD3DDevice *iface, DWORD Sampler, DWORD texture_idx, DWORD Flags) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
float col[4];
@ -438,7 +438,7 @@ static void WINAPI IWineD3DDeviceImpl_SetupTextureStates(IWineD3DDevice *iface,
VTRACE(("Activating appropriate texture state %ld\n", Sampler));
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
ENTER_GL();
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + Sampler));
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
checkGLcall("glActiveTextureARB");
LEAVE_GL();
/* Could we use bindTexture and then apply the states instead of GLACTIVETEXTURE */
@ -3824,20 +3824,21 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderState(IWineD3DDevice *iface, D
WARN("Unsupported in local OpenGL implementation: glBlendColor\n");
}
/* And now the default texture color as well */
for (i = 0; i < GL_LIMITS(texture_stages); i++) {
if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
/* And now the default texture color as well */
for (i = 0; i < GL_LIMITS(texture_stages); i++) {
/* Note the D3DRS value applies to all textures, but GL has one
per texture, so apply it now ready to be used! */
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
checkGLcall("glActiveTextureARB");
} else if (i>0) {
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
}
/* Note the D3DRS value applies to all textures, but GL has one
per texture, so apply it now ready to be used! */
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
checkGLcall("glActiveTextureARB");
} else if (i>0) {
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
}
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
}
}
break;

View File

@ -618,7 +618,9 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info, Display* display) {
gl_info->ps_nv_version = PS_VERSION_11;
TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", gl_info->ps_nv_version);
} else if (strcmp(ThisExtn, "GL_NV_register_combiners") == 0) {
TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Register combiners (1) support\n");
glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max);
gl_info->max_texture_stages = min(MAX_TEXTURES, gl_max);
TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Register combiners (1) support - GL_MAX_GENERAL_COMBINERS_NV=%d\n", gl_max);
gl_info->supported[NV_REGISTER_COMBINERS] = TRUE;
} else if (strcmp(ThisExtn, "GL_NV_register_combiners2") == 0) {
TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Register combiners (2) support\n");

View File

@ -1024,6 +1024,7 @@ void loadNumberedArrays(
static void loadVertexData(IWineD3DDevice *iface, WineDirect3DVertexStridedData *sd) {
unsigned int textureNo = 0;
unsigned int texture_idx = 0;
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
GLint curVBO = -1;
@ -1313,7 +1314,7 @@ static void loadVertexData(IWineD3DDevice *iface, WineDirect3DVertexStridedData
/* Texture coords -------------------------------------------*/
for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
for (textureNo = 0, texture_idx = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
/* The code below uses glClientActiveTexture and glMultiTexCoord* which are all part of the GL_ARB_multitexture extension. */
/* Abort if we don't support the extension. */
if (!GL_SUPPORT(ARB_MULTITEXTURE)) {
@ -1321,21 +1322,24 @@ static void loadVertexData(IWineD3DDevice *iface, WineDirect3DVertexStridedData
continue;
}
/* Select the correct texture stage */
GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo));
if (!GL_SUPPORT(NV_REGISTER_COMBINERS) || This->stateBlock->textures[textureNo]) {
/* Select the correct texture stage */
GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
}
if (This->stateBlock->textures[textureNo] != NULL) {
int coordIdx = This->stateBlock->textureState[textureNo][D3DTSS_TEXCOORDINDEX];
TRACE("Setting up texture %u, cordindx %u, data %p\n", textureNo, coordIdx, sd->u.s.texCoords[coordIdx].lpData);
TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n", textureNo, texture_idx, coordIdx, sd->u.s.texCoords[coordIdx].lpData);
if (coordIdx >= MAX_TEXTURES) {
VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
} else if (sd->u.s.texCoords[coordIdx].lpData == NULL && sd->u.s.texCoords[coordIdx].VBO == 0) {
VTRACE(("Bound texture but no texture coordinates supplied, so skipping\n"));
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
} else {
if(curVBO != sd->u.s.texCoords[coordIdx].VBO) {
@ -1347,8 +1351,15 @@ static void loadVertexData(IWineD3DDevice *iface, WineDirect3DVertexStridedData
glTexCoordPointer(WINED3D_ATR_SIZE(texCoords[coordIdx]), WINED3D_ATR_GLTYPE(texCoords[coordIdx]), sd->u.s.texCoords[coordIdx].dwStride, sd->u.s.texCoords[coordIdx].lpData);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
} else {
} else if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
}
if (!GL_SUPPORT(NV_REGISTER_COMBINERS) || This->stateBlock->textures[textureNo]) ++texture_idx;
}
if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
for (textureNo = texture_idx; textureNo < GL_LIMITS(textures); ++textureNo) {
GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo));
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
}
@ -1399,6 +1410,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {
unsigned int textureNo = 0;
unsigned int texture_idx = 0;
const short *pIdxBufS = NULL;
const long *pIdxBufL = NULL;
LONG SkipnStrides = 0;
@ -1509,7 +1521,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
}
/* Texture coords --------------------------- */
for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
for (textureNo = 0, texture_idx = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
@ -1581,7 +1593,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
case D3DTTFF_COUNT1:
VTRACE(("tex:%d, s=%f\n", textureNo, s));
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glMultiTexCoord1fARB(textureNo, s));
GL_EXTCALL(glMultiTexCoord1fARB(texture_idx, s));
} else {
glTexCoord1f(s);
}
@ -1589,7 +1601,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
case D3DTTFF_COUNT2:
VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s, t));
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glMultiTexCoord2fARB(textureNo, s, t));
GL_EXTCALL(glMultiTexCoord2fARB(texture_idx, s, t));
} else {
glTexCoord2f(s, t);
}
@ -1597,7 +1609,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
case D3DTTFF_COUNT3:
VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s, t, r));
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glMultiTexCoord3fARB(textureNo, s, t, r));
GL_EXTCALL(glMultiTexCoord3fARB(texture_idx, s, t, r));
} else {
glTexCoord3f(s, t, r);
}
@ -1605,7 +1617,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
case D3DTTFF_COUNT4:
VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q));
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glMultiTexCoord4fARB(textureNo, s, t, r, q));
GL_EXTCALL(glMultiTexCoord4fARB(texture_idx, s, t, r, q));
} else {
glTexCoord4f(s, t, r, q);
}
@ -1615,6 +1627,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
}
}
}
if (!GL_SUPPORT(NV_REGISTER_COMBINERS) || This->stateBlock->textures[textureNo]) ++texture_idx;
} /* End of textures */
/* Diffuse -------------------------------- */
@ -2111,109 +2124,134 @@ static void drawPrimitiveUploadTexturesPS(IWineD3DDeviceImpl* This) {
/* Upload texture, apply states */
IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) This->stateBlock->textures[i]);
IWineD3DDevice_SetupTextureStates((IWineD3DDevice *)This, i, REAPPLY_ALPHAOP);
IWineD3DDevice_SetupTextureStates((IWineD3DDevice *)This, i, i, REAPPLY_ALPHAOP);
IWineD3DBaseTexture_ApplyStateChanges(This->stateBlock->textures[i], This->stateBlock->textureState[i], This->stateBlock->samplerState[i]);
}
}
/* uploads textures and setup texture states ready for rendering */
void inline drawPrimitiveUploadTextures(IWineD3DDeviceImpl* This) {
static void drawPrimitiveUploadTextures(IWineD3DDeviceImpl* This) {
INT current_sampler = 0;
float constant_color[4];
unsigned int i;
/**
* OK, here we clear down any old junk iect in the context
* enable the new texture and apply any state changes:
*
* Loop through all textures
* select texture unit
* if there is a texture bound to that unit then..
* disable all textures types on that unit
* enable and bind the texture that is bound to that unit.
* otherwise disable all texture types on that unit.
**/
/* upload the textures */
for (i = 0; i< GL_LIMITS(texture_stages); ++i) {
/* Bind the texture to the stage here */
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
checkGLcall("glActiveTextureARB");
} else if (0 < i) {
/* This isn't so much a warn as a message to the user about lack of hardware support */
WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
/* ARB_texture_env_combine is limited to GL_MAX_TEXTURE_UNITS stages. On
* nVidia cards GL_MAX_TEXTURE_UNITS is generally not larger than 4.
* Register combiners however provide up to 8 combiner stages. In order to
* take advantage of this, we need to be separate D3D texture stages from
* GL texture units. When using register combiners GL_MAX_TEXTURE_UNITS
* corresponds to MaxSimultaneousTextures and GL_MAX_GENERAL_COMBINERS_NV
* corresponds to MaxTextureBlendStages in the caps. */
if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
glEnable(GL_REGISTER_COMBINERS_NV);
D3DCOLORTOGLFLOAT4(This->stateBlock->renderState[WINED3DRS_TEXTUREFACTOR], constant_color);
GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &constant_color[0]));
}
for (i = 0; i < GL_LIMITS(texture_stages); ++i) {
INT texture_idx = -1;
/* D3DTOP_DISABLE disables the current & any higher texture stages */
if (This->stateBlock->textureState[i][WINED3DTSS_COLOROP] == D3DTOP_DISABLE) break;
if (!GL_SUPPORT(NV_REGISTER_COMBINERS) || This->stateBlock->textures[i]) {
texture_idx = current_sampler++;
/* Active the texture unit corresponding to the current texture stage */
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
checkGLcall("glActiveTextureARB");
} else if (i) {
WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
}
}
/* don't bother with textures that have a colorop of disable */
if (This->stateBlock->textureState[i][WINED3DTSS_COLOROP] != D3DTOP_DISABLE) {
if (This->stateBlock->textures[i] != NULL) {
glDisable(GL_TEXTURE_1D);
This->stateBlock->textureDimensions[i] = IWineD3DBaseTexture_GetTextureDimensions(This->stateBlock->textures[i]);
/* disable all texture states that aren't the selected textures' dimension */
switch(This->stateBlock->textureDimensions[i]) {
if (This->stateBlock->textures[i]) {
/* Enable the correct target. */
glDisable(GL_TEXTURE_1D);
This->stateBlock->textureDimensions[i] = IWineD3DBaseTexture_GetTextureDimensions(This->stateBlock->textures[i]);
switch(This->stateBlock->textureDimensions[i]) {
case GL_TEXTURE_2D:
glDisable(GL_TEXTURE_3D);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
break;
break;
case GL_TEXTURE_3D:
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glDisable(GL_TEXTURE_2D);
break;
break;
case GLTEXTURECUBEMAP:
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_3D);
break;
}
/* imply GL_SUPPORT(NV_TEXTURE_SHADER) when setting texture_shader_active */
if (This->texture_shader_active && This->stateBlock->textureDimensions[i] == GL_TEXTURE_2D) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
} else {
glEnable(This->stateBlock->textureDimensions[i]);
}
/* Load up the texture now */
IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) This->stateBlock->textures[i]);
IWineD3DDevice_SetupTextureStates((IWineD3DDevice *)This, i, REAPPLY_ALPHAOP);
/* this is a stub function representing the state blocks
* being separated here we are only updating the texture
* state changes, other objects and units get updated when
* they change (or need to be updated), e.g. states that
* relate to a context member line the texture unit are
* only updated when the context needs updating
*/
/* Tell the abse texture to sync it's states */
IWineD3DBaseTexture_ApplyStateChanges(This->stateBlock->textures[i], This->stateBlock->textureState[i], This->stateBlock->samplerState[i]);
}
/* Bind a default texture if no texture has been set, but colour-op is enabled */
else {
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_3D);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glEnable(GL_TEXTURE_1D);
This->stateBlock->textureDimensions[i] = GL_TEXTURE_1D;
glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
break;
}
/** these ops apply to the texture unit, so they are preserved between texture changes, but for now brute force and reapply all
dx9_1pass_emboss_bump_mapping and dx9_2pass_emboss_bump_mapping are good texts to make sure the states are being applied when needed **/
set_tex_op((IWineD3DDevice *)This, FALSE, i, This->stateBlock->textureState[i][WINED3DTSS_COLOROP],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG1],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG2],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG0]);
/* alphaop */
set_tex_op((IWineD3DDevice *)This, TRUE, i, This->stateBlock->textureState[i][WINED3DTSS_ALPHAOP],
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG1],
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG2],
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG0]);
} else {
/* no colorop so disable all the texture states */
glDisable(GL_TEXTURE_1D);
/* imply GL_SUPPORT(NV_TEXTURE_SHADER) when setting texture_shader_active */
if (This->texture_shader_active && This->stateBlock->textureDimensions[i] == GL_TEXTURE_2D) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
} else {
glEnable(This->stateBlock->textureDimensions[i]);
}
/* Upload texture, apply states */
IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) This->stateBlock->textures[i]);
IWineD3DDevice_SetupTextureStates((IWineD3DDevice *)This, i, texture_idx, REAPPLY_ALPHAOP);
IWineD3DBaseTexture_ApplyStateChanges(This->stateBlock->textures[i], This->stateBlock->textureState[i], This->stateBlock->samplerState[i]);
} else if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
/* ARB_texture_env_combine needs a valid texture bound to the
* texture unit, even if it isn't used. Bind a dummy texture. */
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_3D);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
}
glEnable(GL_TEXTURE_1D);
This->stateBlock->textureDimensions[i] = GL_TEXTURE_1D;
glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
}
}
/** these ops apply to the texture unit, so they are preserved between texture changes, but for now brute force and reapply all
dx9_1pass_emboss_bump_mapping and dx9_2pass_emboss_bump_mapping are good texts to make sure the states are being applied when needed **/
if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
set_tex_op_nvrc((IWineD3DDevice *)This, FALSE, i, This->stateBlock->textureState[i][WINED3DTSS_COLOROP],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG1],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG2],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG0],
texture_idx);
/* alphaop */
set_tex_op_nvrc((IWineD3DDevice *)This, TRUE, i, This->stateBlock->textureState[i][WINED3DTSS_ALPHAOP],
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG1],
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG2],
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG0],
texture_idx);
} else {
set_tex_op((IWineD3DDevice *)This, FALSE, i, This->stateBlock->textureState[i][WINED3DTSS_COLOROP],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG1],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG2],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG0]);
/* alphaop */
set_tex_op((IWineD3DDevice *)This, TRUE, i, This->stateBlock->textureState[i][WINED3DTSS_ALPHAOP],
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG1],
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG2],
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG0]);
}
}
/* If we're using register combiners, set the amount of *used* combiners.
* Ie, the number of stages below the first stage to have a color op of
* D3DTOP_DISABLE. */
if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
/* NUM_GENERAL_COMBINERS_NV should be > 0 */
if (!i) glDisable(GL_REGISTER_COMBINERS_NV);
else GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, i));
}
/* Disable the remaining texture units. */
for (i = current_sampler; i < GL_LIMITS(textures); ++i) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_3D);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
}
}
/* Routine common to the draw primitive and draw indexed primitive routines */

View File

@ -819,45 +819,46 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
bound. We emulate this by creating dummy textures and binding them to each
texture stage, but disable all stages by default. Hence if a stage is enabled
then the default texture will kick in until replaced by a SetTexture call */
if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
ENTER_GL();
ENTER_GL();
for (i = 0; i < GL_LIMITS(texture_stages); i++) {
GLubyte white = 255;
for (i = 0; i < GL_LIMITS(texture_stages); i++) {
GLubyte white = 255;
/* Note this avoids calling settexture, so pretend it has been called */
This->set.textures[i] = TRUE;
This->changed.textures[i] = TRUE;
This->textures[i] = NULL;
/* Note this avoids calling settexture, so pretend it has been called */
This->set.textures[i] = TRUE;
This->changed.textures[i] = TRUE;
This->textures[i] = NULL;
/* Make appropriate texture active */
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
checkGLcall("glActiveTextureARB");
} else if (i > 0) {
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
}
/* Make appropriate texture active */
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
checkGLcall("glActiveTextureARB");
} else if (i > 0) {
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
/* Generate an opengl texture name */
glGenTextures(1, &ThisDevice->dummyTextureName[i]);
checkGLcall("glGenTextures");
TRACE("Dummy Texture %d given name %d\n", i, ThisDevice->dummyTextureName[i]);
/* Generate a dummy 1d texture */
This->textureDimensions[i] = GL_TEXTURE_1D;
glBindTexture(GL_TEXTURE_1D, ThisDevice->dummyTextureName[i]);
checkGLcall("glBindTexture");
glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
checkGLcall("glTexImage1D");
#if 1 /* TODO: move the setting texture states off to basetexture */
/* Reapply all the texture state information to this texture */
IWineD3DDevice_SetupTextureStates(device, i, i, REAPPLY_ALL);
#endif
}
/* Generate an opengl texture name */
glGenTextures(1, &ThisDevice->dummyTextureName[i]);
checkGLcall("glGenTextures");
TRACE("Dummy Texture %d given name %d\n", i, ThisDevice->dummyTextureName[i]);
/* Generate a dummy 1d texture */
This->textureDimensions[i] = GL_TEXTURE_1D;
glBindTexture(GL_TEXTURE_1D, ThisDevice->dummyTextureName[i]);
checkGLcall("glBindTexture");
glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
checkGLcall("glTexImage1D");
#if 1 /* TODO: move the setting texture states off to basetexture */
/* Reapply all the texture state information to this texture */
IWineD3DDevice_SetupTextureStates(device, i, REAPPLY_ALL);
#endif
LEAVE_GL();
}
LEAVE_GL();
/* Defaulting palettes - Note these are device wide but reinitialized here for convenience*/
for (i = 0; i < MAX_PALETTES; ++i) {
int j;

View File

@ -497,7 +497,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)
STDMETHOD(GetRenderTargetData)(THIS_ struct IWineD3DSurface* pRenderTarget, struct IWineD3DSurface* pSurface) PURE;
STDMETHOD(GetFrontBufferData)(THIS_ UINT iSwapChain,struct IWineD3DSurface* pSurface) PURE;
/*** Internal use IWineD3Device methods ***/
STDMETHOD_(void, SetupTextureStates)(THIS_ DWORD Stage, DWORD Flags);
STDMETHOD_(void, SetupTextureStates)(THIS_ DWORD Stage, DWORD texture_idx, DWORD Flags);
/*** object tracking ***/
STDMETHOD_(void, ResourceReleased)(THIS_ struct IWineD3DResource *resource);
};
@ -638,7 +638,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)
#define IWineD3DDevice_StretchRect(p,a,b,c,d,e) (p)->lpVtbl->StretchRect(p,a,b,c,d,e)
#define IWineD3DDevice_GetRenderTargetData(p,a,b) (p)->lpVtbl->GetRenderTargetData(p,a,b)
#define IWineD3DDevice_GetFrontBufferData(p,a,b) (p)->lpVtbl->GetFrontBufferData(p,a,b)
#define IWineD3DDevice_SetupTextureStates(p,a,b) (p)->lpVtbl->SetupTextureStates(p,a,b)
#define IWineD3DDevice_SetupTextureStates(p,a,b,c) (p)->lpVtbl->SetupTextureStates(p,a,b,c)
#define IWineD3DDevice_ResourceReleased(p,a) (p)->lpVtbl->ResourceReleased(p,a)
#endif