mirror of
				https://github.com/aap/librw.git
				synced 2025-10-30 14:39:28 +00:00 
			
		
		
		
	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; | ||||
| 	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 | ||||
|  | ||||
| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user