मैं हार्डवेयर इंस्ट्रक्शन करने की कोशिश कर रहा हूं लेकिन मैं कुछ अजीब परफॉर्मेंस प्रॉब्लम मार रहा हूं। औसत फ्रैमरेट लगभग 45 है, लेकिन यह बेहद तड़का हुआ है।
- विंडोड
- सिंक्रोनाइज़डिथवर्थिकल रीट्रेस = गलत
- IsFixedTimeStep = false
- प्रस्तुतिइंटरवल = PresentInterval.Immediate
नीचे दी गई छवि मेरी मापी गई समय (के साथ Stopwatch
) दिखाती है । सबसे ऊपरी ग्राफ Draw
विधि में बिताया गया समय है और नीचे का ग्राफ Draw
शुरुआत से अंत तक का समय हैUpdate
स्पाइक्स लगभग 1 सेकंड अलग हैं और हमेशा सामान्य समय से 2,3,4 या 5 गुना अधिक होते हैं। स्पाइक के तुरंत बाद के फ्रेम को बिल्कुल भी समय नहीं लगता है। मैंने जाँच की है कि यह कचरा संग्रहकर्ता नहीं है।
मैं वर्तमान में एक त्रिकोण सूची के रूप में 12 त्रिकोण और 36 कोने से मिलकर एक जाल बना रहा हूं (मुझे पता है कि यह इष्टतम नहीं है, लेकिन यह परीक्षण के लिए है) 1 मिलियन उदाहरणों के साथ। अगर मैं इंस्टेंस ड्रॉइंग 250 कॉल के छोटे हिस्सों में कॉल करता हूं, तो प्रत्येक समस्या कम हो जाती है, लेकिन सीपीयू का उपयोग काफी बढ़ जाता है। उपर्युक्त रन 10000 कॉल प्रति ड्रॉ कॉल पर है, जो सीपीयू पर बहुत आसान है।
अगर मैं फुलस्क्रीन में गेम चलाता हूं तो नीचे का ग्राफ लगभग न के बराबर है, लेकिन Draw
विधि में भी यही समस्या है ।
यहाँ PIX के अंदर एक रन है , जिससे मुझे कोई मतलब नहीं है। ऐसा लगता है कि कुछ फ़्रेमों के लिए कोई प्रतिपादन नहीं किया गया है ...
किसी भी विचार, यह क्या कारण हो सकता है?
संपादित करें : अनुरोध के अनुसार, रेंडर कोड के प्रासंगिक अंश
ए CubeBuffer
बनाया और शुरू किया गया है, फिर क्यूब्स से भरा है। यदि क्यूब्स की मात्रा एक निश्चित सीमा से ऊपर है, तो एक नया CubeBuffer
बनाया जाता है, और इसी तरह। प्रत्येक बफ़र एक कॉल में सभी उदाहरणों को खींचता है।
केवल एक बार जानकारी की जरूरत है static
(वर्टेक्स, इंडेक्स बफर और वर्टेक्स डिक्लेरेशन; हालांकि इससे अब तक कोई फर्क नहीं पड़ता)। बनावट 512x512 है
ड्रा ()
device.Clear(Color.DarkSlateGray);
device.RasterizerState = new RasterizerState() { };
device.BlendState = new BlendState { };
device.DepthStencilState = new DepthStencilState() { DepthBufferEnable = true };
//samplerState=new SamplerState() { AddressU = TextureAddressMode.Mirror, AddressV = TextureAddressMode.Mirror, Filter = TextureFilter.Linear };
device.SamplerStates[0] = samplerState
effect.CurrentTechnique = effect.Techniques["InstancingTexColorLight"];
effect.Parameters["xView"].SetValue(cam.viewMatrix);
effect.Parameters["xProjection"].SetValue(projectionMatrix);
effect.Parameters["xWorld"].SetValue(worldMatrix);
effect.Parameters["cubeTexture"].SetValue(texAtlas);
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
pass.Apply();
foreach (var buf in CubeBuffers)
buf.Draw();
base.Draw(gameTime);
CubeBuffer
[StructLayout(LayoutKind.Sequential)]
struct InstanceInfoOpt9
{
public Matrix World;
public Vector2 Texture;
public Vector4 Light;
};
static VertexBuffer geometryBuffer = null;
static IndexBuffer geometryIndexBuffer = null;
static VertexDeclaration instanceVertexDeclaration = null;
VertexBuffer instanceBuffer = null;
InstanceInfoOpt9[] Buffer = new InstanceInfoOpt9[MaxCubeCount];
Int32 bufferCount=0
Init()
{
if (geometryBuffer == null)
{
geometryBuffer = new VertexBuffer(Device, typeof (VertexPositionTexture), 36, BufferUsage.WriteOnly);
geometryIndexBuffer = new IndexBuffer(Device, typeof (Int32), 36, BufferUsage.WriteOnly);
vertices = new[]{...}
geometryBuffer.SetData(vertices);
indices = new[]{...}
geometryIndexBuffer.SetData(indices);
var instanceStreamElements = new VertexElement[6];
instanceStreamElements[0] = new VertexElement(sizeof (float)*0, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 1);
instanceStreamElements[1] = new VertexElement(sizeof (float)*4, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 2);
instanceStreamElements[2] = new VertexElement(sizeof (float)*8, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 3);
instanceStreamElements[3] = new VertexElement(sizeof (float)*12, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 4);
instanceStreamElements[4] = new VertexElement(sizeof (float)*16, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 5);
instanceStreamElements[5] = new VertexElement(sizeof (float)*18, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 6);
instanceVertexDeclaration = new VertexDeclaration(instanceStreamElements);
}
instanceBuffer = new VertexBuffer(Device, instanceVertexDeclaration, MaxCubeCount, BufferUsage.WriteOnly);
instanceBuffer.SetData(Buffer);
bindings = new[]
{
new VertexBufferBinding(geometryBuffer),
new VertexBufferBinding(instanceBuffer, 0, 1),
};
}
AddRandomCube(Vector3 pos)
{
if(cubes.Count >= MaxCubeCount)
return null;
Vector2 tex = new Vector2(rnd.Next(0, 16), rnd.Next(0, 16))
Vector4 l= new Vector4((float)rnd.Next(), (float)rnd.Next(), (float)rnd.Next(), (float)rnd.Next());
var cube = new InstanceInfoOpt9(Matrix.CreateTranslation(pos),tex, l);
Buffer[bufferCount++] = cube;
return cube;
}
Draw()
{
Device.Indices = geometryIndexBuffer;
Device.SetVertexBuffers(bindings);
Device.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 36, 0, 12, bufferCount);
}
शेडर
float4x4 xView;
float4x4 xProjection;
float4x4 xWorld;
texture cubeTexture;
sampler TexColorLightSampler = sampler_state
{
texture = <cubeTexture>;
mipfilter = LINEAR;
minfilter = LINEAR;
magfilter = LINEAR;
};
struct InstancingVSTexColorLightInput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
};
struct InstancingVSTexColorLightOutput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
float4 Light : TEXCOORD1;
};
InstancingVSTexColorLightOutput InstancingVSTexColorLight(InstancingVSTexColorLightInput input, float4x4 instanceTransform : TEXCOORD1, float2 instanceTex : TEXCOORD5, float4 instanceLight : TEXCOORD6)
{
float4x4 preViewProjection = mul (xView, xProjection);
float4x4 preWorldViewProjection = mul (xWorld, preViewProjection);
InstancingVSTexColorLightOutput output;
float4 pos = input.Position;
pos = mul(pos, transpose(instanceTransform));
pos = mul(pos, preWorldViewProjection);
output.Position = pos;
output.Light = instanceLight;
output.TexCoord = float2((input.TexCoord.x / 16.0f) + (1.0f / 16.0f * instanceTex.x),
(input.TexCoord.y / 16.0f) + (1.0f / 16.0f * instanceTex.y));
return output;
}
float4 InstancingPSTexColorLight(InstancingVSTexColorLightOutput input) : COLOR0
{
float4 color = tex2D(TexColorLightSampler, input.TexCoord);
color.r = color.r * input.Light.r;
color.g = color.g * input.Light.g;
color.b = color.b * input.Light.b;
color.a = color.a * input.Light.a;
return color;
}
technique InstancingTexColorLight
{
pass Pass0
{
VertexShader = compile vs_3_0 InstancingVSTexColorLight();
PixelShader = compile ps_3_0 InstancingPSTexColorLight();
}
}