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;
|
InstanceData *inst = header->inst;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
if(inst->material->texture)
|
d3d::setTexture(0, inst->material->texture);
|
||||||
setTexture(inst->material->texture);
|
d3d::setMaterial(inst->material);
|
||||||
else
|
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
|
||||||
device->SetTexture(0, NULL);
|
d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||||
setMaterial(inst->material);
|
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||||
device->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
|
|
||||||
device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
|
||||||
device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
|
||||||
if(geo->geoflags & Geometry::PRELIT)
|
if(geo->geoflags & Geometry::PRELIT)
|
||||||
device->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||||
|
|
||||||
device->SetFVF(inst->vertexShader);
|
device->SetFVF(inst->vertexShader);
|
||||||
device->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride);
|
device->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride);
|
||||||
device->SetIndices((IDirect3DIndexBuffer9*)inst->indexBuffer);
|
device->SetIndices((IDirect3DIndexBuffer9*)inst->indexBuffer);
|
||||||
uint32 numPrim = inst->primType == D3DPT_TRIANGLESTRIP ? inst->numIndices-2 : inst->numIndices/3;
|
uint32 numPrim = inst->primType == D3DPT_TRIANGLESTRIP ? inst->numIndices-2 : inst->numIndices/3;
|
||||||
|
d3d::flushCache();
|
||||||
device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)inst->primType, inst->baseIndex,
|
device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)inst->primType, inst->baseIndex,
|
||||||
0, inst->numVertices, 0, numPrim);
|
0, inst->numVertices, 0, numPrim);
|
||||||
inst++;
|
inst++;
|
||||||
|
|
|
@ -32,16 +32,14 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
||||||
|
|
||||||
InstanceData *inst = header->inst;
|
InstanceData *inst = header->inst;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
if(inst->material->texture)
|
d3d::setTexture(0, inst->material->texture);
|
||||||
setTexture(inst->material->texture);
|
d3d::setMaterial(inst->material);
|
||||||
else
|
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
|
||||||
device->SetTexture(0, NULL);
|
d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||||
setMaterial(inst->material);
|
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||||
device->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
|
|
||||||
device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
|
||||||
device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
|
||||||
if(geo->geoflags & Geometry::PRELIT)
|
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,
|
device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex,
|
||||||
0, inst->numVertices,
|
0, inst->numVertices,
|
||||||
inst->startIndex, inst->numPrimitives);
|
inst->startIndex, inst->numPrimitives);
|
||||||
|
|
|
@ -11,10 +11,118 @@
|
||||||
|
|
||||||
namespace rw {
|
namespace rw {
|
||||||
namespace d3d {
|
namespace d3d {
|
||||||
|
|
||||||
#ifdef RW_D3D9
|
#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
|
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[] = {
|
static DWORD filternomip[] = {
|
||||||
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
|
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
|
||||||
|
@ -25,16 +133,17 @@ setTexture(Texture *tex)
|
||||||
0, D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR,
|
0, D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR,
|
||||||
D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER
|
D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER
|
||||||
};
|
};
|
||||||
|
if(tex == NULL){
|
||||||
D3dRaster *raster = PLUGINOFFSET(D3dRaster, tex->raster, nativeRasterOffset);
|
setRasterStage(stage, NULL);
|
||||||
if(tex->raster && raster->texture){
|
return;
|
||||||
device->SetTexture(0, (IDirect3DTexture9*)raster->texture);
|
}
|
||||||
device->SetSamplerState(0, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
if(tex->raster){
|
||||||
device->SetSamplerState(0, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||||
device->SetSamplerState(0, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
|
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||||
device->SetSamplerState(0, D3DSAMP_ADDRESSV, wrap[(tex->filterAddressing >> 12) & 0xF]);
|
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
|
||||||
}else
|
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[(tex->filterAddressing >> 12) & 0xF]);
|
||||||
device->SetTexture(0, NULL);
|
}
|
||||||
|
setRasterStage(stage, tex->raster);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -55,7 +164,17 @@ setMaterial(Material *mat)
|
||||||
mat9.Power = 0.0f;
|
mat9.Power = 0.0f;
|
||||||
mat9.Emissive = black;
|
mat9.Emissive = black;
|
||||||
mat9.Specular = black;
|
mat9.Specular = black;
|
||||||
device->SetMaterial(&mat9);
|
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
|
#endif
|
||||||
|
|
|
@ -400,6 +400,7 @@ Geometry::generateTriangles(int8 *adc)
|
||||||
tri->v[1] = m->indices[j+1];
|
tri->v[1] = m->indices[j+1];
|
||||||
tri->v[2] = m->indices[j+2];
|
tri->v[2] = m->indices[j+2];
|
||||||
tri->matId = matid;
|
tri->matId = matid;
|
||||||
|
tri++;
|
||||||
}
|
}
|
||||||
adcbits += m->numIndices;
|
adcbits += m->numIndices;
|
||||||
m++;
|
m++;
|
||||||
|
|
|
@ -910,8 +910,10 @@ defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh
|
||||||
v.n[1] = norms[1]/127.0f;
|
v.n[1] = norms[1]/127.0f;
|
||||||
v.n[2] = norms[2]/127.0f;
|
v.n[2] = norms[2]/127.0f;
|
||||||
}
|
}
|
||||||
if(mask & 0x100)
|
if(mask & 0x100){
|
||||||
memcpy(&v.c, colors, 4);
|
memcpy(&v.c, colors, 4);
|
||||||
|
//v.c[3] = 0xFF;
|
||||||
|
}
|
||||||
if(mask & 0x1000)
|
if(mask & 0x1000)
|
||||||
memcpy(&v.t, texcoords, 8);
|
memcpy(&v.t, texcoords, 8);
|
||||||
if(mask & 0x2000)
|
if(mask & 0x2000)
|
||||||
|
|
|
@ -99,7 +99,12 @@ void registerNativeRaster(void);
|
||||||
|
|
||||||
// Rendering
|
// 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);
|
void setMaterial(Material *mat);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue