mirror of https://github.com/aap/librw.git
implemented some render state caching for d3d
This commit is contained in:
parent
3902ab328e
commit
0c77e505f0
|
@ -27,21 +27,19 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
|||
|
||||
InstanceData *inst = header->inst;
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
if(inst->material->texture)
|
||||
setTexture(inst->material->texture);
|
||||
else
|
||||
device->SetTexture(0, NULL);
|
||||
setMaterial(inst->material);
|
||||
device->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
|
||||
device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
d3d::setTexture(0, inst->material->texture);
|
||||
d3d::setMaterial(inst->material);
|
||||
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
|
||||
d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
if(geo->geoflags & Geometry::PRELIT)
|
||||
device->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
|
||||
device->SetFVF(inst->vertexShader);
|
||||
device->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride);
|
||||
device->SetIndices((IDirect3DIndexBuffer9*)inst->indexBuffer);
|
||||
uint32 numPrim = inst->primType == D3DPT_TRIANGLESTRIP ? inst->numIndices-2 : inst->numIndices/3;
|
||||
d3d::flushCache();
|
||||
device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)inst->primType, inst->baseIndex,
|
||||
0, inst->numVertices, 0, numPrim);
|
||||
inst++;
|
||||
|
|
|
@ -32,16 +32,14 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
|||
|
||||
InstanceData *inst = header->inst;
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
if(inst->material->texture)
|
||||
setTexture(inst->material->texture);
|
||||
else
|
||||
device->SetTexture(0, NULL);
|
||||
setMaterial(inst->material);
|
||||
device->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
|
||||
device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
d3d::setTexture(0, inst->material->texture);
|
||||
d3d::setMaterial(inst->material);
|
||||
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
|
||||
d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
if(geo->geoflags & Geometry::PRELIT)
|
||||
device->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
d3d::flushCache();
|
||||
device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex,
|
||||
0, inst->numVertices,
|
||||
inst->startIndex, inst->numPrimitives);
|
||||
|
|
|
@ -11,10 +11,118 @@
|
|||
|
||||
namespace rw {
|
||||
namespace d3d {
|
||||
|
||||
#ifdef RW_D3D9
|
||||
|
||||
#define MAXNUMSTATES D3DRS_BLENDOPALPHA
|
||||
#define MAXNUMSTAGES 8
|
||||
#define MAXNUMTEXSTATES D3DTSS_CONSTANT
|
||||
#define MAXNUMSAMPLERSTATES D3DSAMP_DMAPOFFSET
|
||||
|
||||
static int32 numDirtyStates;
|
||||
static uint32 dirtyStates[MAXNUMSTATES];
|
||||
static struct {
|
||||
uint32 value;
|
||||
bool32 dirty;
|
||||
} stateCache[MAXNUMSTATES];
|
||||
static uint32 d3dStates[MAXNUMSTATES];
|
||||
|
||||
static int32 numDirtyTextureStageStates;
|
||||
static struct {
|
||||
uint32 stage;
|
||||
uint32 type;
|
||||
} dirtyTextureStageStates[MAXNUMTEXSTATES*MAXNUMSTAGES];
|
||||
static struct {
|
||||
uint32 value;
|
||||
bool32 dirty;
|
||||
} textureStageStateCache[MAXNUMSTATES][MAXNUMSTAGES];
|
||||
static uint32 d3dTextureStageStates[MAXNUMSTATES][MAXNUMSTAGES];
|
||||
|
||||
static uint32 d3dSamplerStates[MAXNUMSAMPLERSTATES][MAXNUMSTAGES];
|
||||
|
||||
static Raster *d3dRaster[MAXNUMSTAGES];
|
||||
|
||||
static D3DMATERIAL9 d3dmaterial;
|
||||
|
||||
void
|
||||
setTexture(Texture *tex)
|
||||
setRenderState(uint32 state, uint32 value)
|
||||
{
|
||||
if(stateCache[state].value != value){
|
||||
stateCache[state].value = value;
|
||||
if(!stateCache[state].dirty){
|
||||
stateCache[state].dirty = 1;
|
||||
dirtyStates[numDirtyStates++] = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setTextureStageState(uint32 stage, uint32 type, uint32 value)
|
||||
{
|
||||
if(textureStageStateCache[type][stage].value != value){
|
||||
textureStageStateCache[type][stage].value = value;
|
||||
if(!textureStageStateCache[type][stage].dirty){
|
||||
textureStageStateCache[type][stage].dirty = 1;
|
||||
dirtyTextureStageStates[numDirtyTextureStageStates].stage = stage;
|
||||
dirtyTextureStageStates[numDirtyTextureStageStates].type = type;
|
||||
numDirtyTextureStageStates++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
flushCache(void)
|
||||
{
|
||||
uint32 s, t;
|
||||
uint32 v;
|
||||
for(int32 i = 0; i < numDirtyStates; i++){
|
||||
s = dirtyStates[i];
|
||||
v = stateCache[s].value;
|
||||
stateCache[s].dirty = 0;
|
||||
if(d3dStates[s] != v){
|
||||
device->SetRenderState((D3DRENDERSTATETYPE)s, v);
|
||||
d3dStates[s] = v;
|
||||
}
|
||||
}
|
||||
numDirtyStates = 0;
|
||||
for(int32 i = 0; i < numDirtyTextureStageStates; i++){
|
||||
s = dirtyTextureStageStates[i].stage;
|
||||
t = dirtyTextureStageStates[i].type;
|
||||
v = textureStageStateCache[t][s].value;
|
||||
textureStageStateCache[t][s].dirty = 0;
|
||||
if(d3dTextureStageStates[t][s] != v){
|
||||
device->SetTextureStageState(s, (D3DTEXTURESTAGESTATETYPE)t, v);
|
||||
d3dTextureStageStates[t][s] = v;
|
||||
}
|
||||
}
|
||||
numDirtyTextureStageStates = 0;
|
||||
}
|
||||
|
||||
void
|
||||
setSamplerState(uint32 stage, uint32 type, uint32 value)
|
||||
{
|
||||
if(d3dSamplerStates[type][stage] != value){
|
||||
device->SetSamplerState(stage, (D3DSAMPLERSTATETYPE)type, value);
|
||||
d3dSamplerStates[type][stage] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setRasterStage(uint32 stage, Raster *raster)
|
||||
{
|
||||
D3dRaster *d3draster = NULL;
|
||||
if(raster != d3dRaster[stage]){
|
||||
d3dRaster[stage] = raster;
|
||||
if(raster){
|
||||
d3draster = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||
device->SetTexture(stage, (IDirect3DTexture9*)d3draster->texture);
|
||||
}else
|
||||
device->SetTexture(stage, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setTexture(uint32 stage, Texture *tex)
|
||||
{
|
||||
static DWORD filternomip[] = {
|
||||
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
|
||||
|
@ -25,16 +133,17 @@ setTexture(Texture *tex)
|
|||
0, D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR,
|
||||
D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER
|
||||
};
|
||||
|
||||
D3dRaster *raster = PLUGINOFFSET(D3dRaster, tex->raster, nativeRasterOffset);
|
||||
if(tex->raster && raster->texture){
|
||||
device->SetTexture(0, (IDirect3DTexture9*)raster->texture);
|
||||
device->SetSamplerState(0, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||
device->SetSamplerState(0, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||
device->SetSamplerState(0, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
|
||||
device->SetSamplerState(0, D3DSAMP_ADDRESSV, wrap[(tex->filterAddressing >> 12) & 0xF]);
|
||||
}else
|
||||
device->SetTexture(0, NULL);
|
||||
if(tex == NULL){
|
||||
setRasterStage(stage, NULL);
|
||||
return;
|
||||
}
|
||||
if(tex->raster){
|
||||
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
|
||||
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[(tex->filterAddressing >> 12) & 0xF]);
|
||||
}
|
||||
setRasterStage(stage, tex->raster);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -55,7 +164,17 @@ setMaterial(Material *mat)
|
|||
mat9.Power = 0.0f;
|
||||
mat9.Emissive = black;
|
||||
mat9.Specular = black;
|
||||
if(d3dmaterial.Diffuse.r != mat9.Diffuse.r ||
|
||||
d3dmaterial.Diffuse.g != mat9.Diffuse.g ||
|
||||
d3dmaterial.Diffuse.b != mat9.Diffuse.b ||
|
||||
d3dmaterial.Diffuse.a != mat9.Diffuse.a ||
|
||||
d3dmaterial.Ambient.r != mat9.Ambient.r ||
|
||||
d3dmaterial.Ambient.g != mat9.Ambient.g ||
|
||||
d3dmaterial.Ambient.b != mat9.Ambient.b ||
|
||||
d3dmaterial.Ambient.a != mat9.Ambient.a){
|
||||
device->SetMaterial(&mat9);
|
||||
d3dmaterial = mat9;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -400,6 +400,7 @@ Geometry::generateTriangles(int8 *adc)
|
|||
tri->v[1] = m->indices[j+1];
|
||||
tri->v[2] = m->indices[j+2];
|
||||
tri->matId = matid;
|
||||
tri++;
|
||||
}
|
||||
adcbits += m->numIndices;
|
||||
m++;
|
||||
|
|
|
@ -910,8 +910,10 @@ defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh
|
|||
v.n[1] = norms[1]/127.0f;
|
||||
v.n[2] = norms[2]/127.0f;
|
||||
}
|
||||
if(mask & 0x100)
|
||||
if(mask & 0x100){
|
||||
memcpy(&v.c, colors, 4);
|
||||
//v.c[3] = 0xFF;
|
||||
}
|
||||
if(mask & 0x1000)
|
||||
memcpy(&v.t, texcoords, 8);
|
||||
if(mask & 0x2000)
|
||||
|
|
|
@ -99,7 +99,12 @@ void registerNativeRaster(void);
|
|||
|
||||
// Rendering
|
||||
|
||||
void setTexture(Texture *tex);
|
||||
void setRenderState(uint32 state, uint32 value);
|
||||
void setTextureStageState(uint32 stage, uint32 type, uint32 value);
|
||||
void flushCache(void);
|
||||
void setSamplerState(uint32 stage, uint32 type, uint32 value);
|
||||
|
||||
void setTexture(uint32 stage, Texture *tex);
|
||||
void setMaterial(Material *mat);
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue