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 MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 638
#define BUILD_REVISION 639
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
......
......@@ -330,7 +330,12 @@ void Context::markAllStateDirty()
{
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;
......@@ -2004,63 +2009,78 @@ void Context::applyShaders()
// Applies the textures and sampler states to the Direct3D 9 device
void Context::applyTextures()
{
applyTextures(SAMPLER_PIXEL);
if (mSupportsVertexTexture)
{
applyTextures(SAMPLER_VERTEX);
}
}
void Context::applyTextures(SamplerType type)
{
IDirect3DDevice9 *device = getDevice();
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)
{
TextureType textureType = programObject->getSamplerTextureType(sampler);
TextureType textureType = programObject->getSamplerTextureType(type, samplerIndex);
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();
if (d3dTexture)
{
if (mAppliedTextureSerial[sampler] != texture->getSerial() || texture->isDirtyParameter())
if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyParameter())
{
GLenum wrapS = texture->getWrapS();
GLenum wrapT = texture->getWrapT();
GLenum minFilter = texture->getMinFilter();
GLenum magFilter = texture->getMagFilter();
device->SetSamplerState(sampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS));
device->SetSamplerState(sampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT));
device->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS));
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;
es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter);
device->SetSamplerState(sampler, D3DSAMP_MINFILTER, d3dMinFilter);
device->SetSamplerState(sampler, D3DSAMP_MIPFILTER, d3dMipFilter);
device->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
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
{
device->SetTexture(sampler, getIncompleteTexture(textureType)->getTexture());
device->SetTexture(d3dSampler, getIncompleteTexture(textureType)->getTexture());
}
mAppliedTextureSerial[sampler] = texture->getSerial();
appliedTextureSerial[samplerIndex] = texture->getSerial();
texture->resetDirty();
}
}
else
{
if (mAppliedTextureSerial[sampler] != 0)
if (appliedTextureSerial[samplerIndex] != 0)
{
device->SetTexture(sampler, NULL);
mAppliedTextureSerial[sampler] = 0;
device->SetTexture(d3dSampler, NULL);
appliedTextureSerial[samplerIndex] = 0;
}
}
}
}
}
......
......@@ -405,13 +405,6 @@ class Context
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 clear(GLbitfield mask);
void drawArrays(GLenum mode, GLint first, GLsizei count);
......@@ -466,6 +459,14 @@ class Context
private:
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 detachTexture(GLuint texture);
void detachFramebuffer(GLuint framebuffer);
......@@ -512,7 +513,8 @@ class Context
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 mAppliedRenderTargetSerial;
unsigned int mAppliedDepthbufferSerial;
......
......@@ -193,15 +193,29 @@ int Program::getSemanticIndex(int attributeIndex)
// Returns the index of the texture unit corresponding to a Direct3D 9 sampler
// 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;
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)
......@@ -212,12 +226,22 @@ GLint Program::getSamplerMapping(unsigned int samplerIndex)
return -1;
}
TextureType Program::getSamplerTextureType(unsigned int samplerIndex)
TextureType Program::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
{
assert(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0]));
assert(mSamplers[samplerIndex].active);
switch (type)
{
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)
......@@ -1666,7 +1690,8 @@ bool Program::linkUniforms(ID3DXConstantTable *constantTable)
for (unsigned int constantIndex = 0; constantIndex < constantTableDescription.Constants; 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))
{
......@@ -1685,11 +1710,21 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT
{
for (unsigned int samplerIndex = constantDescription.RegisterIndex; samplerIndex < constantDescription.RegisterIndex + constantDescription.RegisterCount; samplerIndex++)
{
ASSERT(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0]));
mSamplers[samplerIndex].active = true;
mSamplers[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D;
mSamplers[samplerIndex].logicalTextureUnit = 0;
if (mConstantTablePS->GetConstantByName(NULL, constantDescription.Name) != NULL)
{
ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0]));
mSamplersPS[samplerIndex].active = true;
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
D3DXCONSTANT_DESC fieldDescription;
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) + "]") : "";
......@@ -2239,11 +2275,7 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
D3DXCONSTANT_DESC constantDescription;
UINT descriptionCount = 1;
HRESULT result = mConstantTablePS->GetConstantDesc(constantPS, &constantDescription, &descriptionCount);
if (FAILED(result))
{
return false;
}
ASSERT(SUCCEEDED(result));
if (constantDescription.RegisterSet == D3DXRS_SAMPLER)
{
......@@ -2255,23 +2287,43 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
{
ASSERT(mSamplers[samplerIndex].active);
mSamplers[samplerIndex].logicalTextureUnit = v[i];
ASSERT(mSamplersPS[samplerIndex].active);
mSamplersPS[samplerIndex].logicalTextureUnit = v[i];
}
}
return true;
}
}
if (constantPS)
{
mConstantTablePS->SetIntArray(device, constantPS, v, count);
else
{
mConstantTablePS->SetIntArray(device, constantPS, v, count);
}
}
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;
......@@ -2468,7 +2520,12 @@ void Program::unlink(bool destroy)
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())
......@@ -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
// texture image unit, and this is the current program, then ValidateProgram will fail, and
// 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)
{
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;
}
}
else
{
samplerMap[mSamplers[i].logicalTextureUnit] = mSamplers[i].textureType;
textureUnitType[unit] = mSamplersVS[i].textureType;
}
}
}
......
......@@ -72,8 +72,8 @@ class Program
GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex);
GLint getSamplerMapping(unsigned int samplerIndex);
TextureType getSamplerTextureType(unsigned int samplerIndex);
GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex);
TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
GLint getUniformLocation(const char *name, bool decorated);
bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
......@@ -191,7 +191,8 @@ class Program
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;
UniformArray mUniforms;
......
......@@ -31,7 +31,14 @@ enum TextureType
TEXTURE_2D,
TEXTURE_CUBE,
TEXTURE_TYPE_COUNT
TEXTURE_TYPE_COUNT,
TEXTURE_UNKNOWN
};
enum SamplerType
{
SAMPLER_PIXEL,
SAMPLER_VERTEX
};
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