Apply vertex textures and sampler states to the D3D9 device.

Issue=95 TRAC #16568 Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@639 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 0e64dd6d
#define MAJOR_VERSION 0 #define MAJOR_VERSION 0
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 638 #define BUILD_REVISION 639
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -330,7 +330,12 @@ void Context::markAllStateDirty() ...@@ -330,7 +330,12 @@ void Context::markAllStateDirty()
{ {
for (int t = 0; t < MAX_TEXTURE_IMAGE_UNITS; t++) for (int t = 0; t < MAX_TEXTURE_IMAGE_UNITS; t++)
{ {
mAppliedTextureSerial[t] = 0; mAppliedTextureSerialPS[t] = 0;
}
for (int t = 0; t < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; t++)
{
mAppliedTextureSerialVS[t] = 0;
} }
mAppliedProgramSerial = 0; mAppliedProgramSerial = 0;
...@@ -2004,63 +2009,78 @@ void Context::applyShaders() ...@@ -2004,63 +2009,78 @@ void Context::applyShaders()
// Applies the textures and sampler states to the Direct3D 9 device // Applies the textures and sampler states to the Direct3D 9 device
void Context::applyTextures() void Context::applyTextures()
{ {
applyTextures(SAMPLER_PIXEL);
if (mSupportsVertexTexture)
{
applyTextures(SAMPLER_VERTEX);
}
}
void Context::applyTextures(SamplerType type)
{
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
Program *programObject = getCurrentProgram(); Program *programObject = getCurrentProgram();
for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++) int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF;
for (int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
{ {
int textureUnit = programObject->getSamplerMapping(sampler); int textureUnit = programObject->getSamplerMapping(type, samplerIndex);
int d3dSampler = (type == SAMPLER_PIXEL) ? samplerIndex : D3DVERTEXTEXTURESAMPLER0 + samplerIndex;
unsigned int *appliedTextureSerial = (type == SAMPLER_PIXEL) ? mAppliedTextureSerialPS : mAppliedTextureSerialVS;
if (textureUnit != -1) if (textureUnit != -1)
{ {
TextureType textureType = programObject->getSamplerTextureType(sampler); TextureType textureType = programObject->getSamplerTextureType(type, samplerIndex);
Texture *texture = getSamplerTexture(textureUnit, textureType); Texture *texture = getSamplerTexture(textureUnit, textureType);
if (mAppliedTextureSerial[sampler] != texture->getSerial() || texture->isDirtyParameter() || texture->isDirtyImage()) if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyParameter() || texture->isDirtyImage())
{ {
IDirect3DBaseTexture9 *d3dTexture = texture->getTexture(); IDirect3DBaseTexture9 *d3dTexture = texture->getTexture();
if (d3dTexture) if (d3dTexture)
{ {
if (mAppliedTextureSerial[sampler] != texture->getSerial() || texture->isDirtyParameter()) if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyParameter())
{ {
GLenum wrapS = texture->getWrapS(); GLenum wrapS = texture->getWrapS();
GLenum wrapT = texture->getWrapT(); GLenum wrapT = texture->getWrapT();
GLenum minFilter = texture->getMinFilter(); GLenum minFilter = texture->getMinFilter();
GLenum magFilter = texture->getMagFilter(); GLenum magFilter = texture->getMagFilter();
device->SetSamplerState(sampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS)); device->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS));
device->SetSamplerState(sampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT)); device->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT));
device->SetSamplerState(sampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter)); device->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter));
D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter); es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter);
device->SetSamplerState(sampler, D3DSAMP_MINFILTER, d3dMinFilter); device->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
device->SetSamplerState(sampler, D3DSAMP_MIPFILTER, d3dMipFilter); device->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
} }
if (mAppliedTextureSerial[sampler] != texture->getSerial() || texture->isDirtyImage()) if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyImage())
{ {
device->SetTexture(sampler, d3dTexture); device->SetTexture(d3dSampler, d3dTexture);
} }
} }
else else
{ {
device->SetTexture(sampler, getIncompleteTexture(textureType)->getTexture()); device->SetTexture(d3dSampler, getIncompleteTexture(textureType)->getTexture());
} }
mAppliedTextureSerial[sampler] = texture->getSerial(); appliedTextureSerial[samplerIndex] = texture->getSerial();
texture->resetDirty(); texture->resetDirty();
} }
} }
else else
{ {
if (mAppliedTextureSerial[sampler] != 0) if (appliedTextureSerial[samplerIndex] != 0)
{ {
device->SetTexture(sampler, NULL); device->SetTexture(d3dSampler, NULL);
mAppliedTextureSerial[sampler] = 0; appliedTextureSerial[samplerIndex] = 0;
} }
} }
} }
} }
......
...@@ -405,13 +405,6 @@ class Context ...@@ -405,13 +405,6 @@ class Context
bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams); bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
bool applyRenderTarget(bool ignoreViewport);
void applyState(GLenum drawMode);
GLenum applyVertexBuffer(GLint first, GLsizei count);
GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
void applyShaders();
void applyTextures();
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
void clear(GLbitfield mask); void clear(GLbitfield mask);
void drawArrays(GLenum mode, GLint first, GLsizei count); void drawArrays(GLenum mode, GLint first, GLsizei count);
...@@ -466,6 +459,14 @@ class Context ...@@ -466,6 +459,14 @@ class Context
private: private:
DISALLOW_COPY_AND_ASSIGN(Context); DISALLOW_COPY_AND_ASSIGN(Context);
bool applyRenderTarget(bool ignoreViewport);
void applyState(GLenum drawMode);
GLenum applyVertexBuffer(GLint first, GLsizei count);
GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
void applyShaders();
void applyTextures();
void applyTextures(SamplerType type);
void detachBuffer(GLuint buffer); void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture); void detachTexture(GLuint texture);
void detachFramebuffer(GLuint framebuffer); void detachFramebuffer(GLuint framebuffer);
...@@ -512,7 +513,8 @@ class Context ...@@ -512,7 +513,8 @@ class Context
bool mHasBeenCurrent; bool mHasBeenCurrent;
unsigned int mAppliedTextureSerial[MAX_TEXTURE_IMAGE_UNITS]; unsigned int mAppliedTextureSerialPS[MAX_TEXTURE_IMAGE_UNITS];
unsigned int mAppliedTextureSerialVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
unsigned int mAppliedProgramSerial; unsigned int mAppliedProgramSerial;
unsigned int mAppliedRenderTargetSerial; unsigned int mAppliedRenderTargetSerial;
unsigned int mAppliedDepthbufferSerial; unsigned int mAppliedDepthbufferSerial;
......
...@@ -193,15 +193,29 @@ int Program::getSemanticIndex(int attributeIndex) ...@@ -193,15 +193,29 @@ int Program::getSemanticIndex(int attributeIndex)
// Returns the index of the texture unit corresponding to a Direct3D 9 sampler // Returns the index of the texture unit corresponding to a Direct3D 9 sampler
// index referenced in the compiled HLSL shader // index referenced in the compiled HLSL shader
GLint Program::getSamplerMapping(unsigned int samplerIndex) GLint Program::getSamplerMapping(SamplerType type, unsigned int samplerIndex)
{ {
assert(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0]));
GLint logicalTextureUnit = -1; GLint logicalTextureUnit = -1;
if (mSamplers[samplerIndex].active) switch (type)
{ {
logicalTextureUnit = mSamplers[samplerIndex].logicalTextureUnit; case SAMPLER_PIXEL:
ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0]));
if (mSamplersPS[samplerIndex].active)
{
logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
}
break;
case SAMPLER_VERTEX:
ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0]));
if (mSamplersVS[samplerIndex].active)
{
logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
}
break;
default: UNREACHABLE();
} }
if (logicalTextureUnit >= 0 && logicalTextureUnit < MAX_TEXTURE_IMAGE_UNITS) if (logicalTextureUnit >= 0 && logicalTextureUnit < MAX_TEXTURE_IMAGE_UNITS)
...@@ -212,12 +226,22 @@ GLint Program::getSamplerMapping(unsigned int samplerIndex) ...@@ -212,12 +226,22 @@ GLint Program::getSamplerMapping(unsigned int samplerIndex)
return -1; return -1;
} }
TextureType Program::getSamplerTextureType(unsigned int samplerIndex) TextureType Program::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
{ {
assert(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0])); switch (type)
assert(mSamplers[samplerIndex].active); {
case SAMPLER_PIXEL:
ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0]));
ASSERT(mSamplersPS[samplerIndex].active);
return mSamplersPS[samplerIndex].textureType;
case SAMPLER_VERTEX:
ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0]));
ASSERT(mSamplersVS[samplerIndex].active);
return mSamplersVS[samplerIndex].textureType;
default: UNREACHABLE();
}
return mSamplers[samplerIndex].textureType; return TEXTURE_2D;
} }
GLint Program::getUniformLocation(const char *name, bool decorated) GLint Program::getUniformLocation(const char *name, bool decorated)
...@@ -1666,7 +1690,8 @@ bool Program::linkUniforms(ID3DXConstantTable *constantTable) ...@@ -1666,7 +1690,8 @@ bool Program::linkUniforms(ID3DXConstantTable *constantTable)
for (unsigned int constantIndex = 0; constantIndex < constantTableDescription.Constants; constantIndex++) for (unsigned int constantIndex = 0; constantIndex < constantTableDescription.Constants; constantIndex++)
{ {
D3DXHANDLE constantHandle = constantTable->GetConstant(0, constantIndex); D3DXHANDLE constantHandle = constantTable->GetConstant(0, constantIndex);
constantTable->GetConstantDesc(constantHandle, &constantDescription, &descriptionCount); HRESULT result = constantTable->GetConstantDesc(constantHandle, &constantDescription, &descriptionCount);
ASSERT(SUCCEEDED(result));
if (!defineUniform(constantHandle, constantDescription)) if (!defineUniform(constantHandle, constantDescription))
{ {
...@@ -1685,11 +1710,21 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT ...@@ -1685,11 +1710,21 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT
{ {
for (unsigned int samplerIndex = constantDescription.RegisterIndex; samplerIndex < constantDescription.RegisterIndex + constantDescription.RegisterCount; samplerIndex++) for (unsigned int samplerIndex = constantDescription.RegisterIndex; samplerIndex < constantDescription.RegisterIndex + constantDescription.RegisterCount; samplerIndex++)
{ {
ASSERT(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0])); if (mConstantTablePS->GetConstantByName(NULL, constantDescription.Name) != NULL)
{
mSamplers[samplerIndex].active = true; ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0]));
mSamplers[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D; mSamplersPS[samplerIndex].active = true;
mSamplers[samplerIndex].logicalTextureUnit = 0; mSamplersPS[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D;
mSamplersPS[samplerIndex].logicalTextureUnit = 0;
}
if (mConstantTableVS->GetConstantByName(NULL, constantDescription.Name) != NULL)
{
ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0]));
mSamplersVS[samplerIndex].active = true;
mSamplersVS[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D;
mSamplersVS[samplerIndex].logicalTextureUnit = 0;
}
} }
} }
...@@ -1706,7 +1741,8 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT ...@@ -1706,7 +1741,8 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT
D3DXCONSTANT_DESC fieldDescription; D3DXCONSTANT_DESC fieldDescription;
UINT descriptionCount = 1; UINT descriptionCount = 1;
mConstantTablePS->GetConstantDesc(fieldHandle, &fieldDescription, &descriptionCount); HRESULT result = mConstantTablePS->GetConstantDesc(fieldHandle, &fieldDescription, &descriptionCount);
ASSERT(SUCCEEDED(result));
std::string structIndex = (constantDescription.Elements > 1) ? ("[" + str(arrayIndex) + "]") : ""; std::string structIndex = (constantDescription.Elements > 1) ? ("[" + str(arrayIndex) + "]") : "";
...@@ -2239,11 +2275,7 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v) ...@@ -2239,11 +2275,7 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
D3DXCONSTANT_DESC constantDescription; D3DXCONSTANT_DESC constantDescription;
UINT descriptionCount = 1; UINT descriptionCount = 1;
HRESULT result = mConstantTablePS->GetConstantDesc(constantPS, &constantDescription, &descriptionCount); HRESULT result = mConstantTablePS->GetConstantDesc(constantPS, &constantDescription, &descriptionCount);
ASSERT(SUCCEEDED(result));
if (FAILED(result))
{
return false;
}
if (constantDescription.RegisterSet == D3DXRS_SAMPLER) if (constantDescription.RegisterSet == D3DXRS_SAMPLER)
{ {
...@@ -2255,23 +2287,43 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v) ...@@ -2255,23 +2287,43 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS) if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
{ {
ASSERT(mSamplers[samplerIndex].active); ASSERT(mSamplersPS[samplerIndex].active);
mSamplers[samplerIndex].logicalTextureUnit = v[i]; mSamplersPS[samplerIndex].logicalTextureUnit = v[i];
} }
} }
return true;
} }
} else
{
if (constantPS) mConstantTablePS->SetIntArray(device, constantPS, v, count);
{ }
mConstantTablePS->SetIntArray(device, constantPS, v, count);
} }
if (constantVS) if (constantVS)
{ {
mConstantTableVS->SetIntArray(device, constantVS, v, count); D3DXCONSTANT_DESC constantDescription;
UINT descriptionCount = 1;
HRESULT result = mConstantTableVS->GetConstantDesc(constantVS, &constantDescription, &descriptionCount);
ASSERT(SUCCEEDED(result));
if (constantDescription.RegisterSet == D3DXRS_SAMPLER)
{
unsigned int firstIndex = mConstantTableVS->GetSamplerIndex(constantVS);
for (int i = 0; i < count; i++)
{
unsigned int samplerIndex = firstIndex + i;
if (samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF)
{
ASSERT(mSamplersVS[samplerIndex].active);
mSamplersVS[samplerIndex].logicalTextureUnit = v[i];
}
}
}
else
{
mConstantTableVS->SetIntArray(device, constantVS, v, count);
}
} }
return true; return true;
...@@ -2468,7 +2520,12 @@ void Program::unlink(bool destroy) ...@@ -2468,7 +2520,12 @@ void Program::unlink(bool destroy)
for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++) for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
{ {
mSamplers[index].active = false; mSamplersPS[index].active = false;
}
for (int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; index++)
{
mSamplersVS[index].active = false;
} }
while (!mUniforms.empty()) while (!mUniforms.empty())
...@@ -2790,19 +2847,52 @@ bool Program::validateSamplers() const ...@@ -2790,19 +2847,52 @@ bool Program::validateSamplers() const
// if any two active samplers in a program are of different types, but refer to the same // if any two active samplers in a program are of different types, but refer to the same
// texture image unit, and this is the current program, then ValidateProgram will fail, and // texture image unit, and this is the current program, then ValidateProgram will fail, and
// DrawArrays and DrawElements will issue the INVALID_OPERATION error. // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
std::map<int, TextureType> samplerMap;
TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF];
for (unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; ++i)
{
textureUnitType[i] = TEXTURE_UNKNOWN;
}
for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i) for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
{ {
if (mSamplers[i].active) if (mSamplersPS[i].active)
{
int unit = mSamplersPS[i].logicalTextureUnit;
ASSERT(unit >= 0 && unit < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF);
if (textureUnitType[unit] != TEXTURE_UNKNOWN)
{
if (mSamplersPS[i].textureType != textureUnitType[unit])
{
return false;
}
}
else
{
textureUnitType[unit] = mSamplersPS[i].textureType;
}
}
}
for (unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; ++i)
{
if (mSamplersVS[i].active)
{ {
if (samplerMap.find(mSamplers[i].logicalTextureUnit) != samplerMap.end()) int unit = mSamplersVS[i].logicalTextureUnit;
ASSERT(unit >= 0 && unit < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF);
if (textureUnitType[unit] != TEXTURE_UNKNOWN)
{ {
if (mSamplers[i].textureType != samplerMap[mSamplers[i].logicalTextureUnit]) if (mSamplersVS[i].textureType != textureUnitType[unit])
{
return false; return false;
}
} }
else else
{ {
samplerMap[mSamplers[i].logicalTextureUnit] = mSamplers[i].textureType; textureUnitType[unit] = mSamplersVS[i].textureType;
} }
} }
} }
......
...@@ -72,8 +72,8 @@ class Program ...@@ -72,8 +72,8 @@ class Program
GLuint getAttributeLocation(const char *name); GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex); int getSemanticIndex(int attributeIndex);
GLint getSamplerMapping(unsigned int samplerIndex); GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex);
TextureType getSamplerTextureType(unsigned int samplerIndex); TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
GLint getUniformLocation(const char *name, bool decorated); GLint getUniformLocation(const char *name, bool decorated);
bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v); bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
...@@ -191,7 +191,8 @@ class Program ...@@ -191,7 +191,8 @@ class Program
TextureType textureType; TextureType textureType;
}; };
Sampler mSamplers[MAX_TEXTURE_IMAGE_UNITS]; Sampler mSamplersPS[MAX_TEXTURE_IMAGE_UNITS];
Sampler mSamplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
typedef std::vector<Uniform*> UniformArray; typedef std::vector<Uniform*> UniformArray;
UniformArray mUniforms; UniformArray mUniforms;
......
...@@ -31,7 +31,14 @@ enum TextureType ...@@ -31,7 +31,14 @@ enum TextureType
TEXTURE_2D, TEXTURE_2D,
TEXTURE_CUBE, TEXTURE_CUBE,
TEXTURE_TYPE_COUNT TEXTURE_TYPE_COUNT,
TEXTURE_UNKNOWN
};
enum SamplerType
{
SAMPLER_PIXEL,
SAMPLER_VERTEX
}; };
class ResourceManager class ResourceManager
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment