Improve batching by binding up to 8 simultaneous textures.

This commit is contained in:
Paul Chote
2018-05-31 23:57:48 +00:00
committed by reaperrr
parent 131496ebf8
commit bfcbe8c004
5 changed files with 92 additions and 23 deletions

View File

@@ -20,9 +20,11 @@ namespace OpenRA.Graphics
readonly IShader shader;
readonly Vertex[] vertices;
Sheet currentSheet;
readonly Sheet[] sheets = new Sheet[8];
BlendMode currentBlend = BlendMode.Alpha;
int nv = 0;
int ns = 0;
public SpriteRenderer(Renderer renderer, IShader shader)
{
@@ -35,8 +37,11 @@ namespace OpenRA.Graphics
{
if (nv > 0)
{
if (currentSheet != null)
shader.SetTexture("DiffuseTexture", currentSheet.GetTexture());
for (var i = 0; i < ns; i++)
{
shader.SetTexture("Texture{0}".F(i), sheets[i].GetTexture());
sheets[i] = null;
}
renderer.Device.SetBlendMode(currentBlend);
shader.PrepareRender();
@@ -44,25 +49,45 @@ namespace OpenRA.Graphics
renderer.Device.SetBlendMode(BlendMode.None);
nv = 0;
currentSheet = null;
ns = 0;
}
}
void SetRenderStateForSprite(Sprite s)
int2 SetRenderStateForSprite(Sprite s)
{
renderer.CurrentBatchRenderer = this;
if (s.BlendMode != currentBlend || s.Sheet != currentSheet || nv + 6 > renderer.TempBufferSize)
if (s.BlendMode != currentBlend || nv + 6 > renderer.TempBufferSize)
Flush();
currentBlend = s.BlendMode;
currentSheet = s.Sheet;
var sheet = s.Sheet;
var sheetIndex = 0;
for (; sheetIndex < ns; sheetIndex++)
if (sheets[sheetIndex] == sheet)
break;
if (sheetIndex == ns)
{
if (sheetIndex == sheets.Length)
{
Flush();
sheetIndex = 0;
}
sheets[sheetIndex] = sheet;
ns += 1;
}
// TODO: Add support for secondary channels on different sheets
return new int2(sheetIndex, sheetIndex);
}
internal void DrawSprite(Sprite s, float3 location, float paletteTextureIndex, float3 size)
{
SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, paletteTextureIndex, nv, size);
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, samplers, paletteTextureIndex, nv, size);
nv += 6;
}
@@ -78,14 +103,14 @@ namespace OpenRA.Graphics
public void DrawSprite(Sprite s, float3 a, float3 b, float3 c, float3 d)
{
SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, a, b, c, d, s, 0, nv);
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, 0, nv);
nv += 6;
}
public void DrawVertexBuffer(IVertexBuffer<Vertex> buffer, int start, int length, PrimitiveType type, Sheet sheet, BlendMode blendMode)
{
shader.SetTexture("DiffuseTexture", sheet.GetTexture());
shader.SetTexture("Texture0", sheet.GetTexture());
renderer.Device.SetBlendMode(blendMode);
shader.PrepareRender();
renderer.DrawBatch(buffer, start, length, type);

View File

@@ -92,7 +92,7 @@ namespace OpenRA.Graphics
return;
var offset = rowStride * uv.V + 6 * uv.U;
Util.FastCreateQuad(vertices, pos, sprite, palette.TextureIndex, offset, sprite.Size);
Util.FastCreateQuad(vertices, pos, sprite, int2.Zero, palette.TextureIndex, offset, sprite.Size);
dirtyRows.Add(uv.V);
}

View File

@@ -20,15 +20,15 @@ namespace OpenRA.Graphics
// yes, our channel order is nuts.
static readonly int[] ChannelMasks = { 2, 1, 0, 3 };
public static void FastCreateQuad(Vertex[] vertices, float3 o, Sprite r, float paletteTextureIndex, int nv, float3 size)
public static void FastCreateQuad(Vertex[] vertices, float3 o, Sprite r, int2 samplers, float paletteTextureIndex, int nv, float3 size)
{
var b = new float3(o.X + size.X, o.Y, o.Z);
var c = new float3(o.X + size.X, o.Y + size.Y, o.Z + size.Z);
var d = new float3(o.X, o.Y + size.Y, o.Z + size.Z);
FastCreateQuad(vertices, o, b, c, d, r, paletteTextureIndex, nv);
FastCreateQuad(vertices, o, b, c, d, r, samplers, paletteTextureIndex, nv);
}
public static void FastCreateQuad(Vertex[] vertices, float3 a, float3 b, float3 c, float3 d, Sprite r, float paletteTextureIndex, int nv)
public static void FastCreateQuad(Vertex[] vertices, float3 a, float3 b, float3 c, float3 d, Sprite r, int2 samplers, float paletteTextureIndex, int nv)
{
float sl = 0;
float st = 0;
@@ -37,7 +37,7 @@ namespace OpenRA.Graphics
// See shp.vert for documentation on the channel attribute format
var attribC = r.Channel == TextureChannel.RGBA ? 0x02 : ((byte)r.Channel) << 1 | 0x01;
attribC |= samplers.X << 6;
var ss = r as SpriteWithSecondaryData;
if (ss != null)
{
@@ -47,6 +47,7 @@ namespace OpenRA.Graphics
sb = ss.SecondaryBottom;
attribC |= ((byte)ss.SecondaryChannel) << 4 | 0x08;
attribC |= samplers.Y << 9;
}
var fAttribC = (float)attribC;