Index: ps/trunk/binaries/data/mods/public/shaders/glsl/minimap.vs
===================================================================
--- ps/trunk/binaries/data/mods/public/shaders/glsl/minimap.vs
+++ ps/trunk/binaries/data/mods/public/shaders/glsl/minimap.vs
@@ -27,23 +27,34 @@
attribute vec2 a_vertex;
#endif
+#if MINIMAP_POINT && USE_GPU_INSTANCING
+attribute vec2 a_uv1;
+attribute vec4 a_uv2;
+
+uniform float width;
+#endif
+
void main()
{
- #if MINIMAP_BASE || MINIMAP_LOS
- gl_Position = transform * vec4(a_vertex, 1.0);
- v_tex = (textureTransform * vec4(a_uv0, 0.0, 1.0)).xy;
- #endif
-
- #if MINIMAP_MASK
- v_maskUV = (maskTextureTransform * vec4(a_uv0, 0.0, 1.0)).xy;
- #endif
-
- #if MINIMAP_POINT
- gl_Position = transform * vec4(a_vertex, 0.0, 1.0);
- color = a_color;
- #endif
-
- #if MINIMAP_LINE
- gl_Position = transform * vec4(a_vertex, 0.0, 1.0);
- #endif
+#if MINIMAP_BASE || MINIMAP_LOS
+ gl_Position = transform * vec4(a_vertex, 1.0);
+ v_tex = (textureTransform * vec4(a_uv0, 0.0, 1.0)).xy;
+#endif
+
+#if MINIMAP_MASK
+ v_maskUV = (maskTextureTransform * vec4(a_uv0, 0.0, 1.0)).xy;
+#endif
+
+#if MINIMAP_POINT
+#if USE_GPU_INSTANCING
+ gl_Position = transform * vec4(a_vertex * width + a_uv1, 0.0, 1.0);
+#else
+ gl_Position = transform * vec4(a_vertex, 0.0, 1.0);
+#endif
+ color = a_color;
+#endif // MINIMAP_POINT
+
+#if MINIMAP_LINE
+ gl_Position = transform * vec4(a_vertex, 0.0, 1.0);
+#endif
}
Index: ps/trunk/binaries/data/mods/public/shaders/glsl/minimap.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/shaders/glsl/minimap.xml
+++ ps/trunk/binaries/data/mods/public/shaders/glsl/minimap.xml
@@ -4,6 +4,7 @@
+
Index: ps/trunk/source/graphics/Canvas2D.cpp
===================================================================
--- ps/trunk/source/graphics/Canvas2D.cpp
+++ ps/trunk/source/graphics/Canvas2D.cpp
@@ -69,13 +69,17 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1);
- deviceCommandContext->SetVertexBufferData(0, vertices.data());
- deviceCommandContext->SetVertexBufferData(1, uvs.data());
+ deviceCommandContext->SetVertexBufferData(
+ 0, vertices.data(), vertices.size() * sizeof(vertices[0]));
+ deviceCommandContext->SetVertexBufferData(
+ 1, uvs.data(), uvs.size() * sizeof(uvs[0]));
deviceCommandContext->Draw(0, vertices.size() / 2);
}
@@ -288,15 +292,17 @@
m->DeviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
m->DeviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1);
- m->DeviceCommandContext->SetVertexBufferData(0, vertices.data());
- m->DeviceCommandContext->SetVertexBufferData(1, uvs.data());
+ m->DeviceCommandContext->SetVertexBufferData(0, vertices.data(), vertices.size() * sizeof(vertices[0]));
+ m->DeviceCommandContext->SetVertexBufferData(1, uvs.data(), uvs.size() * sizeof(uvs[0]));
- m->DeviceCommandContext->SetIndexBufferData(indices.data());
+ m->DeviceCommandContext->SetIndexBufferData(indices.data(), indices.size() * sizeof(indices[0]));
m->DeviceCommandContext->DrawIndexed(0, indices.size(), 0);
}
Index: ps/trunk/source/graphics/LOSTexture.cpp
===================================================================
--- ps/trunk/source/graphics/LOSTexture.cpp
+++ ps/trunk/source/graphics/LOSTexture.cpp
@@ -188,13 +188,17 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1);
- deviceCommandContext->SetVertexBufferData(0, quadVerts);
- deviceCommandContext->SetVertexBufferData(1, quadTex);
+ deviceCommandContext->SetVertexBufferData(
+ 0, quadVerts, std::size(quadVerts) * sizeof(quadVerts[0]));
+ deviceCommandContext->SetVertexBufferData(
+ 1, quadTex, std::size(quadTex) * sizeof(quadTex[0]));
deviceCommandContext->Draw(0, 6);
Index: ps/trunk/source/graphics/MiniMapTexture.h
===================================================================
--- ps/trunk/source/graphics/MiniMapTexture.h
+++ ps/trunk/source/graphics/MiniMapTexture.h
@@ -104,6 +104,11 @@
VertexArray::Attribute m_AttributePos;
VertexArray::Attribute m_AttributeColor;
+ bool m_UseInstancing = false;
+ // Vertex data if instancing is supported.
+ VertexArray m_InstanceVertexArray;
+ VertexArray::Attribute m_InstanceAttributePosition;
+
size_t m_EntitiesDrawn = 0;
double m_PingDuration = 25.0;
Index: ps/trunk/source/graphics/MiniMapTexture.cpp
===================================================================
--- ps/trunk/source/graphics/MiniMapTexture.cpp
+++ ps/trunk/source/graphics/MiniMapTexture.cpp
@@ -36,6 +36,7 @@
#include "ps/CStrInternStatic.h"
#include "ps/Filesystem.h"
#include "ps/Game.h"
+#include "ps/VideoMode.h"
#include "ps/World.h"
#include "ps/XML/Xeromyces.h"
#include "renderer/backend/IDevice.h"
@@ -49,6 +50,8 @@
#include "simulation2/components/ICmpRangeManager.h"
#include "simulation2/system/ParamNode.h"
+#include
+
namespace
{
@@ -96,13 +99,17 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1);
- deviceCommandContext->SetVertexBufferData(0, quadVertices);
- deviceCommandContext->SetVertexBufferData(1, quadUVs);
+ deviceCommandContext->SetVertexBufferData(
+ 0, quadVertices, std::size(quadVertices) * sizeof(quadVertices[0]));
+ deviceCommandContext->SetVertexBufferData(
+ 1, quadUVs, std::size(quadUVs) * sizeof(quadUVs[0]));
deviceCommandContext->Draw(0, 6);
}
@@ -118,8 +125,24 @@
inline void AddEntity(const MinimapUnitVertex& v,
VertexArrayIterator& attrColor,
VertexArrayIterator& attrPos,
- const float entityRadius)
+ const float entityRadius,
+ const bool useInstancing)
{
+ if (useInstancing)
+ {
+ (*attrColor)[0] = v.r;
+ (*attrColor)[1] = v.g;
+ (*attrColor)[2] = v.b;
+ (*attrColor)[3] = v.a;
+ ++attrColor;
+
+ (*attrPos)[0] = v.position.X;
+ (*attrPos)[1] = v.position.Y;
+ ++attrPos;
+
+ return;
+ }
+
const CVector2D offsets[4] =
{
{-entityRadius, 0.0f},
@@ -146,7 +169,8 @@
CMiniMapTexture::CMiniMapTexture(CSimulation2& simulation)
: m_Simulation(simulation), m_IndexArray(false),
- m_VertexArray(Renderer::Backend::IBuffer::Type::VERTEX, true)
+ m_VertexArray(Renderer::Backend::IBuffer::Type::VERTEX, true),
+ m_InstanceVertexArray(Renderer::Backend::IBuffer::Type::VERTEX, false)
{
// Register Relax NG validator.
CXeromyces::AddValidator(g_VFS, "pathfinder", "simulation/data/pathfinder.rng");
@@ -194,6 +218,42 @@
++attrPos;
}
m_VertexArray.Upload();
+
+ if (g_VideoMode.GetBackendDevice()->GetCapabilities().instancing)
+ {
+ m_UseInstancing = true;
+
+ const size_t numberOfCircleSegments = 8;
+
+ m_InstanceAttributePosition.format = Renderer::Backend::Format::R32G32_SFLOAT;
+ m_InstanceVertexArray.AddAttribute(&m_InstanceAttributePosition);
+
+ m_InstanceVertexArray.SetNumberOfVertices(numberOfCircleSegments * 3);
+ m_InstanceVertexArray.Layout();
+
+ VertexArrayIterator attributePosition =
+ m_InstanceAttributePosition.GetIterator();
+ for (size_t segment = 0; segment < numberOfCircleSegments; ++segment)
+ {
+ const float currentAngle = static_cast(segment) / numberOfCircleSegments * 2.0f * M_PI;
+ const float nextAngle = static_cast(segment + 1) / numberOfCircleSegments * 2.0f * M_PI;
+
+ (*attributePosition)[0] = 0.0f;
+ (*attributePosition)[1] = 0.0f;
+ ++attributePosition;
+
+ (*attributePosition)[0] = std::cos(currentAngle);
+ (*attributePosition)[1] = std::sin(currentAngle);
+ ++attributePosition;
+
+ (*attributePosition)[0] = std::cos(nextAngle);
+ (*attributePosition)[1] = std::sin(nextAngle);
+ ++attributePosition;
+ }
+
+ m_InstanceVertexArray.Upload();
+ m_InstanceVertexArray.FreeBackingStore();
+ }
}
CMiniMapTexture::~CMiniMapTexture()
@@ -448,25 +508,11 @@
deviceCommandContext->EndPass();
- CShaderDefines pointDefines;
- pointDefines.Add(str_MINIMAP_POINT, str_1);
- tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, pointDefines);
- deviceCommandContext->SetGraphicsPipelineState(
- tech->GetGraphicsPipelineStateDesc());
- deviceCommandContext->BeginPass();
- shader = tech->GetShader();
- deviceCommandContext->SetUniform(
- shader->GetBindingSlot(str_transform), baseTransform.AsFloatArray());
-
- CMatrix3D unitMatrix;
- unitMatrix.SetIdentity();
- // Convert world space coordinates into [0, 2].
- const float unitScale = invTileMapSize;
- unitMatrix.Scale(unitScale * 2.0f, unitScale * 2.0f, 1.0f);
- // Offset the coordinates to [-1, 1].
- unitMatrix.Translate(CVector3D(-1.0f, -1.0f, 0.0f));
- deviceCommandContext->SetUniform(
- shader->GetBindingSlot(str_transform), unitMatrix.AsFloatArray());
+ // We might scale entities properly in the vertex shader but it requires
+ // additional space in the vertex buffer. So we assume that we don't need
+ // to change an entity size so often.
+ // Radius with instancing is lower because an entity has a more round shape.
+ const float entityRadius = static_cast(m_MapSize) / 128.0f * (m_UseInstancing ? 5.0 : 6.0f);
if (doUpdate)
{
@@ -482,11 +528,6 @@
std::vector pingingVertices;
pingingVertices.reserve(MAX_ENTITIES_DRAWN / 2);
- // We might scale entities properly in the vertex shader but it requires
- // additional space in the vertex buffer. So we assume that we don't need
- // to change an entity size so often.
- const float entityRadius = static_cast(m_MapSize) / 128.0f * 6.0f;
-
if (currentTime > m_NextBlinkTime)
{
m_BlinkState = !m_BlinkState;
@@ -525,7 +566,7 @@
}
else
{
- AddEntity(v, attrColor, attrPos, entityRadius);
+ AddEntity(v, attrColor, attrPos, entityRadius, m_UseInstancing);
++m_EntitiesDrawn;
}
@@ -554,60 +595,118 @@
// Add the pinged vertices at the end, so they are drawn on top
for (const MinimapUnitVertex& vertex : pingingVertices)
{
- AddEntity(vertex, attrColor, attrPos, entityRadius);
+ AddEntity(vertex, attrColor, attrPos, entityRadius, m_UseInstancing);
++m_EntitiesDrawn;
}
ENSURE(m_EntitiesDrawn < MAX_ENTITIES_DRAWN);
- VertexArrayIterator index = m_IndexArray.GetIterator();
- for (size_t entityIndex = 0; entityIndex < m_EntitiesDrawn; ++entityIndex)
+ if (!m_UseInstancing)
{
- index[entityIndex * 6 + 0] = static_cast(entityIndex * 4 + 0);
- index[entityIndex * 6 + 1] = static_cast(entityIndex * 4 + 1);
- index[entityIndex * 6 + 2] = static_cast(entityIndex * 4 + 2);
- index[entityIndex * 6 + 3] = static_cast(entityIndex * 4 + 0);
- index[entityIndex * 6 + 4] = static_cast(entityIndex * 4 + 2);
- index[entityIndex * 6 + 5] = static_cast(entityIndex * 4 + 3);
+ VertexArrayIterator index = m_IndexArray.GetIterator();
+ for (size_t entityIndex = 0; entityIndex < m_EntitiesDrawn; ++entityIndex)
+ {
+ index[entityIndex * 6 + 0] = static_cast(entityIndex * 4 + 0);
+ index[entityIndex * 6 + 1] = static_cast(entityIndex * 4 + 1);
+ index[entityIndex * 6 + 2] = static_cast(entityIndex * 4 + 2);
+ index[entityIndex * 6 + 3] = static_cast(entityIndex * 4 + 0);
+ index[entityIndex * 6 + 4] = static_cast(entityIndex * 4 + 2);
+ index[entityIndex * 6 + 5] = static_cast(entityIndex * 4 + 3);
+ }
+
+ m_IndexArray.Upload();
}
m_VertexArray.Upload();
- m_IndexArray.Upload();
}
m_VertexArray.PrepareForRendering();
if (m_EntitiesDrawn > 0)
{
+ CShaderDefines pointDefines;
+ pointDefines.Add(str_MINIMAP_POINT, str_1);
+ if (m_UseInstancing)
+ pointDefines.Add(str_USE_GPU_INSTANCING, str_1);
+ tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, pointDefines);
+ deviceCommandContext->SetGraphicsPipelineState(
+ tech->GetGraphicsPipelineStateDesc());
+ deviceCommandContext->BeginPass();
+ shader = tech->GetShader();
+ deviceCommandContext->SetUniform(
+ shader->GetBindingSlot(str_transform), baseTransform.AsFloatArray());
+
+ CMatrix3D unitMatrix;
+ unitMatrix.SetIdentity();
+ // Convert world space coordinates into [0, 2].
+ const float unitScale = invTileMapSize;
+ unitMatrix.Scale(unitScale * 2.0f, unitScale * 2.0f, 1.0f);
+ // Offset the coordinates to [-1, 1].
+ unitMatrix.Translate(CVector3D(-1.0f, -1.0f, 0.0f));
+ deviceCommandContext->SetUniform(
+ shader->GetBindingSlot(str_transform), unitMatrix.AsFloatArray());
+
Renderer::Backend::IDeviceCommandContext::Rect scissorRect;
scissorRect.x = scissorRect.y = 1;
scissorRect.width = scissorRect.height = FINAL_TEXTURE_SIZE - 2;
deviceCommandContext->SetScissors(1, &scissorRect);
m_VertexArray.UploadIfNeeded(deviceCommandContext);
- m_IndexArray.UploadIfNeeded(deviceCommandContext);
const uint32_t stride = m_VertexArray.GetStride();
const uint32_t firstVertexOffset = m_VertexArray.GetOffset() * stride;
- deviceCommandContext->SetVertexAttributeFormat(
- Renderer::Backend::VertexAttributeStream::POSITION,
- m_AttributePos.format, firstVertexOffset + m_AttributePos.offset, stride, 0);
- deviceCommandContext->SetVertexAttributeFormat(
- Renderer::Backend::VertexAttributeStream::COLOR,
- m_AttributeColor.format, firstVertexOffset + m_AttributeColor.offset, stride, 0);
+ if (m_UseInstancing)
+ {
+ deviceCommandContext->SetVertexAttributeFormat(
+ Renderer::Backend::VertexAttributeStream::POSITION,
+ m_AttributePos.format,
+ m_InstanceVertexArray.GetOffset() + m_InstanceAttributePosition.offset,
+ m_InstanceVertexArray.GetStride(),
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
+
+ deviceCommandContext->SetVertexAttributeFormat(
+ Renderer::Backend::VertexAttributeStream::UV1,
+ m_AttributePos.format, firstVertexOffset + m_AttributePos.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_INSTANCE, 1);
+ deviceCommandContext->SetVertexAttributeFormat(
+ Renderer::Backend::VertexAttributeStream::COLOR,
+ m_AttributeColor.format, firstVertexOffset + m_AttributeColor.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_INSTANCE, 1);
+
+ deviceCommandContext->SetVertexBuffer(0, m_InstanceVertexArray.GetBuffer());
+ deviceCommandContext->SetVertexBuffer(1, m_VertexArray.GetBuffer());
- deviceCommandContext->SetVertexBuffer(0, m_VertexArray.GetBuffer());
- deviceCommandContext->SetIndexBuffer(m_IndexArray.GetBuffer());
+ deviceCommandContext->SetUniform(shader->GetBindingSlot(str_width), entityRadius);
+
+ deviceCommandContext->DrawInstanced(0, m_InstanceVertexArray.GetNumberOfVertices(), 0, m_EntitiesDrawn);
+ }
+ else
+ {
+ m_IndexArray.UploadIfNeeded(deviceCommandContext);
- deviceCommandContext->DrawIndexed(m_IndexArray.GetOffset(), m_EntitiesDrawn * 6, 0);
+ deviceCommandContext->SetVertexAttributeFormat(
+ Renderer::Backend::VertexAttributeStream::POSITION,
+ m_AttributePos.format, firstVertexOffset + m_AttributePos.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
+ deviceCommandContext->SetVertexAttributeFormat(
+ Renderer::Backend::VertexAttributeStream::COLOR,
+ m_AttributeColor.format, firstVertexOffset + m_AttributeColor.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
+
+ deviceCommandContext->SetVertexBuffer(0, m_VertexArray.GetBuffer());
+ deviceCommandContext->SetIndexBuffer(m_IndexArray.GetBuffer());
+
+ deviceCommandContext->DrawIndexed(m_IndexArray.GetOffset(), m_EntitiesDrawn * 6, 0);
+ }
g_Renderer.GetStats().m_DrawCalls++;
deviceCommandContext->SetScissors(0, nullptr);
+
+ deviceCommandContext->EndPass();
}
- deviceCommandContext->EndPass();
deviceCommandContext->SetFramebuffer(
deviceCommandContext->GetDevice()->GetCurrentBackbuffer());
g_Renderer.SetViewport(oldViewPort);
Index: ps/trunk/source/graphics/ParticleEmitter.cpp
===================================================================
--- ps/trunk/source/graphics/ParticleEmitter.cpp
+++ ps/trunk/source/graphics/ParticleEmitter.cpp
@@ -214,16 +214,20 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- m_AttributePos.format, firstVertexOffset + m_AttributePos.offset, stride, 0);
+ m_AttributePos.format, firstVertexOffset + m_AttributePos.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::COLOR,
- m_AttributeColor.format, firstVertexOffset + m_AttributeColor.offset, stride, 0);
+ m_AttributeColor.format, firstVertexOffset + m_AttributeColor.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- m_AttributeUV.format, firstVertexOffset + m_AttributeUV.offset, stride, 0);
+ m_AttributeUV.format, firstVertexOffset + m_AttributeUV.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
- m_AttributeAxis.format, firstVertexOffset + m_AttributeAxis.offset, stride, 0);
+ m_AttributeAxis.format, firstVertexOffset + m_AttributeAxis.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexBuffer(0, m_VertexArray.GetBuffer());
deviceCommandContext->SetIndexBuffer(m_IndexArray.GetBuffer());
Index: ps/trunk/source/graphics/TextRenderer.cpp
===================================================================
--- ps/trunk/source/graphics/TextRenderer.cpp
+++ ps/trunk/source/graphics/TextRenderer.cpp
@@ -277,13 +277,16 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R16G16_SINT, offsetof(t2f_v2i, x), stride, 0);
+ Renderer::Backend::Format::R16G16_SINT, offsetof(t2f_v2i, x), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- Renderer::Backend::Format::R32G32_SFLOAT, offsetof(t2f_v2i, u), stride, 0);
+ Renderer::Backend::Format::R32G32_SFLOAT, offsetof(t2f_v2i, u), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
- deviceCommandContext->SetVertexBufferData(0, vertexes.data());
- deviceCommandContext->SetIndexBufferData(indexes.data());
+ deviceCommandContext->SetVertexBufferData(
+ 0, vertexes.data(), vertexes.size() * sizeof(vertexes[0]));
+ deviceCommandContext->SetIndexBufferData(indexes.data(), indexes.size() * sizeof(indexes[0]));
deviceCommandContext->DrawIndexed(0, idx * 6, 0);
idx = 0;
Index: ps/trunk/source/gui/ObjectTypes/CMiniMap.cpp
===================================================================
--- ps/trunk/source/gui/ObjectTypes/CMiniMap.cpp
+++ ps/trunk/source/gui/ObjectTypes/CMiniMap.cpp
@@ -127,13 +127,17 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1);
- deviceCommandContext->SetVertexBufferData(0, quadVerts);
- deviceCommandContext->SetVertexBufferData(1, quadTex);
+ deviceCommandContext->SetVertexBufferData(
+ 0, quadVerts, std::size(quadVerts) * sizeof(quadVerts[0]));
+ deviceCommandContext->SetVertexBufferData(
+ 1, quadTex, std::size(quadTex) * sizeof(quadTex[0]));
deviceCommandContext->Draw(0, 6);
}
Index: ps/trunk/source/ps/CStrInternStatic.h
===================================================================
--- ps/trunk/source/ps/CStrInternStatic.h
+++ ps/trunk/source/ps/CStrInternStatic.h
@@ -68,6 +68,7 @@
X(SHADOWS_CASCADE_COUNT)
X(USE_FANCY_EFFECTS)
X(USE_FP_SHADOW)
+X(USE_GPU_INSTANCING)
X(USE_GPU_SKINNING)
X(USE_INSTANCING)
X(USE_NORMALS)
Index: ps/trunk/source/renderer/DebugRenderer.cpp
===================================================================
--- ps/trunk/source/renderer/DebugRenderer.cpp
+++ ps/trunk/source/renderer/DebugRenderer.cpp
@@ -126,8 +126,10 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
- deviceCommandContext->SetVertexBufferData(0, vertices.data());
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
+ deviceCommandContext->SetVertexBufferData(
+ 0, vertices.data(), vertices.size() * sizeof(vertices[0]));
deviceCommandContext->Draw(0, vertices.size() / 3);
@@ -179,8 +181,10 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
- deviceCommandContext->SetVertexBufferData(0, vertices.data());
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
+ deviceCommandContext->SetVertexBufferData(
+ 0, vertices.data(), vertices.size() * sizeof(vertices[0]));
deviceCommandContext->Draw(0, vertices.size() / 3);
@@ -257,8 +261,10 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
- deviceCommandContext->SetVertexBufferData(0, vertices.data());
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
+ deviceCommandContext->SetVertexBufferData(
+ 0, vertices.data(), vertices.size() * sizeof(vertices[0]));
deviceCommandContext->Draw(0, vertices.size() / 3);
@@ -278,8 +284,10 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
- deviceCommandContext->SetVertexBufferData(0, vertices.data());
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
+ deviceCommandContext->SetVertexBufferData(
+ 0, vertices.data(), vertices.size() * sizeof(vertices[0]));
deviceCommandContext->Draw(0, vertices.size() / 3);
#undef ADD
@@ -337,8 +345,10 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
- deviceCommandContext->SetVertexBufferData(0, data.data());
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
+ deviceCommandContext->SetVertexBufferData(
+ 0, data.data(), data.size() * sizeof(data[0]));
deviceCommandContext->Draw(0, 6 * 6);
@@ -389,8 +399,10 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
- deviceCommandContext->SetVertexBufferData(0, data.data());
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
+ deviceCommandContext->SetVertexBufferData(
+ 0, data.data(), data.size() * sizeof(data[0]));
deviceCommandContext->Draw(0, data.size() / 5);
Index: ps/trunk/source/renderer/DecalRData.cpp
===================================================================
--- ps/trunk/source/renderer/DecalRData.cpp
+++ ps/trunk/source/renderer/DecalRData.cpp
@@ -238,15 +238,18 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- offsetof(SDecalVertex, m_Position), stride, 0);
+ offsetof(SDecalVertex, m_Position), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::NORMAL,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- offsetof(SDecalVertex, m_Normal), stride, 0);
+ offsetof(SDecalVertex, m_Normal), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT,
- offsetof(SDecalVertex, m_UV), stride, 0);
+ offsetof(SDecalVertex, m_UV), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexBuffer(0, batch.vertices->m_Owner->GetBuffer());
}
Index: ps/trunk/source/renderer/HWLightingModelRenderer.cpp
===================================================================
--- ps/trunk/source/renderer/HWLightingModelRenderer.cpp
+++ ps/trunk/source/renderer/HWLightingModelRenderer.cpp
@@ -200,13 +200,15 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
m->shadermodeldef->m_UVs[0].format,
- firstVertexOffset + m->shadermodeldef->m_UVs[0].offset, stride, 0);
+ firstVertexOffset + m->shadermodeldef->m_UVs[0].offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
if (def.GetNumUVsPerVertex() >= 2)
{
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
m->shadermodeldef->m_UVs[1].format,
- firstVertexOffset + m->shadermodeldef->m_UVs[1].offset, stride, 0);
+ firstVertexOffset + m->shadermodeldef->m_UVs[1].offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
}
deviceCommandContext->SetVertexBuffer(0, m->shadermodeldef->m_Array.GetBuffer());
@@ -229,11 +231,13 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- firstVertexOffset + shadermodel->m_Position.offset, stride, 1);
+ firstVertexOffset + shadermodel->m_Position.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::NORMAL,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- firstVertexOffset + shadermodel->m_Normal.offset, stride, 1);
+ firstVertexOffset + shadermodel->m_Normal.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1);
deviceCommandContext->SetVertexBuffer(1, shadermodel->m_Array.GetBuffer());
deviceCommandContext->SetIndexBuffer(m->shadermodeldef->m_IndexArray.GetBuffer());
Index: ps/trunk/source/renderer/InstancingModelRenderer.cpp
===================================================================
--- ps/trunk/source/renderer/InstancingModelRenderer.cpp
+++ ps/trunk/source/renderer/InstancingModelRenderer.cpp
@@ -323,11 +323,13 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
m->imodeldef->m_Position.format,
- firstVertexOffset + m->imodeldef->m_Position.offset, stride, 0);
+ firstVertexOffset + m->imodeldef->m_Position.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::NORMAL,
m->imodeldef->m_Normal.format,
- firstVertexOffset + m->imodeldef->m_Normal.offset, stride, 0);
+ firstVertexOffset + m->imodeldef->m_Normal.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
constexpr size_t MAX_UV = 2;
for (size_t uv = 0; uv < std::min(MAX_UV, def.GetNumUVsPerVertex()); ++uv)
@@ -337,7 +339,8 @@
static_cast(Renderer::Backend::VertexAttributeStream::UV0) + uv);
deviceCommandContext->SetVertexAttributeFormat(
stream, m->imodeldef->m_UVs[uv].format,
- firstVertexOffset + m->imodeldef->m_UVs[uv].offset, stride, 0);
+ firstVertexOffset + m->imodeldef->m_UVs[uv].offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
}
// GPU skinning requires extra attributes to compute positions/normals.
@@ -346,11 +349,13 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV2,
m->imodeldef->m_BlendJoints.format,
- firstVertexOffset + m->imodeldef->m_BlendJoints.offset, stride, 0);
+ firstVertexOffset + m->imodeldef->m_BlendJoints.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV3,
m->imodeldef->m_BlendWeights.format,
- firstVertexOffset + m->imodeldef->m_BlendWeights.offset, stride, 0);
+ firstVertexOffset + m->imodeldef->m_BlendWeights.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
}
if (m->calculateTangents)
@@ -358,7 +363,8 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV4,
m->imodeldef->m_Tangent.format,
- firstVertexOffset + m->imodeldef->m_Tangent.offset, stride, 0);
+ firstVertexOffset + m->imodeldef->m_Tangent.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
}
deviceCommandContext->SetVertexBuffer(0, m->imodeldef->m_Array.GetBuffer());
Index: ps/trunk/source/renderer/OverlayRenderer.cpp
===================================================================
--- ps/trunk/source/renderer/OverlayRenderer.cpp
+++ ps/trunk/source/renderer/OverlayRenderer.cpp
@@ -565,16 +565,20 @@
// to the index offset when it's supported.
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- m->quadAttributePos.format, firstVertexOffset + m->quadAttributePos.offset, vertexStride, 0);
+ m->quadAttributePos.format, firstVertexOffset + m->quadAttributePos.offset, vertexStride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::COLOR,
- m->quadAttributeColor.format, firstVertexOffset + m->quadAttributeColor.offset, vertexStride, 0);
+ m->quadAttributeColor.format, firstVertexOffset + m->quadAttributeColor.offset, vertexStride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- m->quadAttributeUV.format, firstVertexOffset + m->quadAttributeUV.offset, vertexStride, 0);
+ m->quadAttributeUV.format, firstVertexOffset + m->quadAttributeUV.offset, vertexStride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
- m->quadAttributeUV.format, firstVertexOffset + m->quadAttributeUV.offset, vertexStride, 0);
+ m->quadAttributeUV.format, firstVertexOffset + m->quadAttributeUV.offset, vertexStride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexBuffer(0, m->quadVertices.GetBuffer());
deviceCommandContext->SetIndexBuffer(m->quadIndices.GetBuffer());
@@ -633,12 +637,15 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1);
- deviceCommandContext->SetVertexBufferData(1, &uvs[0]);
+ deviceCommandContext->SetVertexBufferData(
+ 1, &uvs[0], std::size(uvs) * sizeof(uvs[0]));
const int32_t baseTexBindingSlot = shader->GetBindingSlot(str_baseTex);
const int32_t colorMulBindingSlot = shader->GetBindingSlot(str_colorMul);
@@ -666,7 +673,8 @@
sprite->m_Position + right*sprite->m_X0 + up*sprite->m_Y1
};
- deviceCommandContext->SetVertexBufferData(0, &position[0].X);
+ deviceCommandContext->SetVertexBufferData(
+ 0, &position[0].X, std::size(position) * sizeof(position[0]));
deviceCommandContext->Draw(0, 6);
@@ -774,10 +782,13 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
- deviceCommandContext->SetVertexBufferData(0, m->sphereVertexes.data());
- deviceCommandContext->SetIndexBufferData(m->sphereIndexes.data());
+ deviceCommandContext->SetVertexBufferData(
+ 0, m->sphereVertexes.data(), m->sphereVertexes.size() * sizeof(m->sphereVertexes[0]));
+ deviceCommandContext->SetIndexBufferData(
+ m->sphereIndexes.data(), m->sphereIndexes.size() * sizeof(m->sphereIndexes[0]));
for (size_t i = 0; i < m->spheres.size(); ++i)
{
Index: ps/trunk/source/renderer/PatchRData.cpp
===================================================================
--- ps/trunk/source/renderer/PatchRData.cpp
+++ ps/trunk/source/renderer/PatchRData.cpp
@@ -822,15 +822,18 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- offsetof(SBaseVertex, m_Position), stride, 0);
+ offsetof(SBaseVertex, m_Position), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::NORMAL,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- offsetof(SBaseVertex, m_Normal), stride, 0);
+ offsetof(SBaseVertex, m_Normal), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- offsetof(SBaseVertex, m_Position), stride, 0);
+ offsetof(SBaseVertex, m_Position), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexBuffer(0, itv->first->GetBuffer());
@@ -1071,19 +1074,23 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- offsetof(SBlendVertex, m_Position), stride, 0);
+ offsetof(SBlendVertex, m_Position), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::NORMAL,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- offsetof(SBlendVertex, m_Normal), stride, 0);
+ offsetof(SBlendVertex, m_Normal), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- offsetof(SBlendVertex, m_Position), stride, 0);
+ offsetof(SBlendVertex, m_Position), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
Renderer::Backend::Format::R32G32_SFLOAT,
- offsetof(SBlendVertex, m_AlphaUVs), stride, 0);
+ offsetof(SBlendVertex, m_AlphaUVs), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexBuffer(0, itv->first->GetBuffer());
}
@@ -1145,13 +1152,15 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- offsetof(SBaseVertex, m_Position), stride, 0);
+ offsetof(SBaseVertex, m_Position), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
if (bindPositionAsTexCoord)
{
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- offsetof(SBaseVertex, m_Position), stride, 0);
+ offsetof(SBaseVertex, m_Position), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
}
// Render each batch
@@ -1223,7 +1232,8 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- offsetof(SSideVertex, m_Position), stride, 0);
+ offsetof(SSideVertex, m_Position), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
CVertexBuffer* lastVB = nullptr;
for (CPatchRData* patch : patches)
@@ -1492,13 +1502,15 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- firstVertexOffset + offsetof(SWaterVertex, m_Position), stride, 0);
+ firstVertexOffset + offsetof(SWaterVertex, m_Position), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
if (bindWaterData)
{
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
Renderer::Backend::Format::R32G32_SFLOAT,
- firstVertexOffset + offsetof(SWaterVertex, m_WaterData), stride, 0);
+ firstVertexOffset + offsetof(SWaterVertex, m_WaterData), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
}
deviceCommandContext->SetVertexBuffer(0, m_VBWater->m_Owner->GetBuffer());
@@ -1527,11 +1539,13 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- firstVertexOffset + offsetof(SWaterVertex, m_Position), stride, 0);
+ firstVertexOffset + offsetof(SWaterVertex, m_Position), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
Renderer::Backend::Format::R32G32_SFLOAT,
- firstVertexOffset + offsetof(SWaterVertex, m_WaterData), stride, 0);
+ firstVertexOffset + offsetof(SWaterVertex, m_WaterData), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexBuffer(0, m_VBWaterShore->m_Owner->GetBuffer());
deviceCommandContext->SetIndexBuffer(m_VBWaterIndicesShore->m_Owner->GetBuffer());
Index: ps/trunk/source/renderer/PostprocManager.cpp
===================================================================
--- ps/trunk/source/renderer/PostprocManager.cpp
+++ ps/trunk/source/renderer/PostprocManager.cpp
@@ -233,13 +233,17 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1);
- deviceCommandContext->SetVertexBufferData(0, quadVerts);
- deviceCommandContext->SetVertexBufferData(1, quadTex);
+ deviceCommandContext->SetVertexBufferData(
+ 0, quadVerts, std::size(quadVerts) * sizeof(quadVerts[0]));
+ deviceCommandContext->SetVertexBufferData(
+ 1, quadTex, std::size(quadTex) * sizeof(quadTex[0]));
deviceCommandContext->Draw(0, 6);
@@ -299,13 +303,17 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1);
- deviceCommandContext->SetVertexBufferData(0, quadVerts);
- deviceCommandContext->SetVertexBufferData(1, quadTex);
+ deviceCommandContext->SetVertexBufferData(
+ 0, quadVerts, std::size(quadVerts) * sizeof(quadVerts[0]));
+ deviceCommandContext->SetVertexBufferData(
+ 1, quadTex, std::size(quadTex) * sizeof(quadTex[0]));
deviceCommandContext->Draw(0, 6);
@@ -335,13 +343,17 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1);
- deviceCommandContext->SetVertexBufferData(0, quadVerts);
- deviceCommandContext->SetVertexBufferData(1, quadTex);
+ deviceCommandContext->SetVertexBufferData(
+ 0, quadVerts, std::size(quadVerts) * sizeof(quadVerts[0]));
+ deviceCommandContext->SetVertexBufferData(
+ 1, quadTex, std::size(quadTex) * sizeof(quadTex[0]));
deviceCommandContext->Draw(0, 6);
@@ -465,13 +477,17 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, 1);
+ Renderer::Backend::Format::R32G32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1);
- deviceCommandContext->SetVertexBufferData(0, quadVerts);
- deviceCommandContext->SetVertexBufferData(1, quadTex);
+ deviceCommandContext->SetVertexBufferData(
+ 0, quadVerts, std::size(quadVerts) * sizeof(quadVerts[0]));
+ deviceCommandContext->SetVertexBufferData(
+ 1, quadTex, std::size(quadTex) * sizeof(quadTex[0]));
deviceCommandContext->Draw(0, 6);
Index: ps/trunk/source/renderer/SilhouetteRenderer.cpp
===================================================================
--- ps/trunk/source/renderer/SilhouetteRenderer.cpp
+++ ps/trunk/source/renderer/SilhouetteRenderer.cpp
@@ -498,9 +498,11 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R16G16_SINT, 0, 0, 0);
+ Renderer::Backend::Format::R16G16_SINT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
- deviceCommandContext->SetVertexBufferData(0, verts);
+ deviceCommandContext->SetVertexBufferData(
+ 0, verts, std::size(verts) * sizeof(verts[0]));
deviceCommandContext->Draw(0, 6);
}
Index: ps/trunk/source/renderer/SkyManager.cpp
===================================================================
--- ps/trunk/source/renderer/SkyManager.cpp
+++ ps/trunk/source/renderer/SkyManager.cpp
@@ -254,10 +254,12 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION, m_AttributePosition.format,
- firstVertexOffset + m_AttributePosition.offset, stride, 0);
+ firstVertexOffset + m_AttributePosition.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0, m_AttributeUV.format,
- firstVertexOffset + m_AttributeUV.offset, stride, 0);
+ firstVertexOffset + m_AttributeUV.offset, stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexBuffer(0, m_VertexArray.GetBuffer());
Index: ps/trunk/source/renderer/TerrainOverlay.cpp
===================================================================
--- ps/trunk/source/renderer/TerrainOverlay.cpp
+++ ps/trunk/source/renderer/TerrainOverlay.cpp
@@ -221,9 +221,11 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
- deviceCommandContext->SetVertexBufferData(0, vertices.data());
+ deviceCommandContext->SetVertexBufferData(
+ 0, vertices.data(), vertices.size() * sizeof(vertices[0]));
deviceCommandContext->Draw(0, vertices.size() / 3);
@@ -286,9 +288,11 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
- deviceCommandContext->SetVertexBufferData(0, vertices.data());
+ deviceCommandContext->SetVertexBufferData(
+ 0, vertices.data(), vertices.size() * sizeof(vertices[0]));
deviceCommandContext->Draw(0, vertices.size() / 3);
Index: ps/trunk/source/renderer/TerrainRenderer.cpp
===================================================================
--- ps/trunk/source/renderer/TerrainRenderer.cpp
+++ ps/trunk/source/renderer/TerrainRenderer.cpp
@@ -207,12 +207,15 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
- Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, 0);
+ Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
- deviceCommandContext->SetVertexBufferData(0, waterPos);
+ deviceCommandContext->SetVertexBufferData(
+ 0, waterPos, std::size(waterPos) * sizeof(waterPos[0]));
deviceCommandContext->Draw(0, 6);
}
Index: ps/trunk/source/renderer/TexturedLineRData.cpp
===================================================================
--- ps/trunk/source/renderer/TexturedLineRData.cpp
+++ ps/trunk/source/renderer/TexturedLineRData.cpp
@@ -62,15 +62,18 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- offsetof(CTexturedLineRData::SVertex, m_Position), stride, 0);
+ offsetof(CTexturedLineRData::SVertex, m_Position), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R32G32_SFLOAT,
- offsetof(CTexturedLineRData::SVertex, m_UVs), stride, 0);
+ offsetof(CTexturedLineRData::SVertex, m_UVs), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
Renderer::Backend::Format::R32G32_SFLOAT,
- offsetof(CTexturedLineRData::SVertex, m_UVs), stride, 0);
+ offsetof(CTexturedLineRData::SVertex, m_UVs), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexBuffer(0, m_VB->m_Owner->GetBuffer());
Index: ps/trunk/source/renderer/WaterManager.cpp
===================================================================
--- ps/trunk/source/renderer/WaterManager.cpp
+++ ps/trunk/source/renderer/WaterManager.cpp
@@ -833,28 +833,34 @@
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::POSITION,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- firstVertexOffset + offsetof(SWavesVertex, m_BasePosition), stride, 0);
+ firstVertexOffset + offsetof(SWavesVertex, m_BasePosition), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::NORMAL,
Renderer::Backend::Format::R32G32_SFLOAT,
- firstVertexOffset + offsetof(SWavesVertex, m_PerpVect), stride, 0);
+ firstVertexOffset + offsetof(SWavesVertex, m_PerpVect), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV0,
Renderer::Backend::Format::R8G8_UINT,
- firstVertexOffset + offsetof(SWavesVertex, m_UV), stride, 0);
+ firstVertexOffset + offsetof(SWavesVertex, m_UV), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV1,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- firstVertexOffset + offsetof(SWavesVertex, m_ApexPosition), stride, 0);
+ firstVertexOffset + offsetof(SWavesVertex, m_ApexPosition), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV2,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- firstVertexOffset + offsetof(SWavesVertex, m_SplashPosition), stride, 0);
+ firstVertexOffset + offsetof(SWavesVertex, m_SplashPosition), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetVertexAttributeFormat(
Renderer::Backend::VertexAttributeStream::UV3,
Renderer::Backend::Format::R32G32B32_SFLOAT,
- firstVertexOffset + offsetof(SWavesVertex, m_RetreatPosition), stride, 0);
+ firstVertexOffset + offsetof(SWavesVertex, m_RetreatPosition), stride,
+ Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0);
deviceCommandContext->SetUniform(
shader->GetBindingSlot(str_translation), m_ShoreWaves[a]->m_TimeDiff);
Index: ps/trunk/source/renderer/backend/IDevice.h
===================================================================
--- ps/trunk/source/renderer/backend/IDevice.h
+++ ps/trunk/source/renderer/backend/IDevice.h
@@ -57,6 +57,7 @@
uint32_t maxSampleCount;
float maxAnisotropy;
uint32_t maxTextureSize;
+ bool instancing;
};
virtual ~IDevice() {}
Index: ps/trunk/source/renderer/backend/IDeviceCommandContext.h
===================================================================
--- ps/trunk/source/renderer/backend/IDeviceCommandContext.h
+++ ps/trunk/source/renderer/backend/IDeviceCommandContext.h
@@ -84,12 +84,14 @@
const Format format,
const uint32_t offset,
const uint32_t stride,
+ const VertexAttributeRate rate,
const uint32_t bindingSlot) = 0;
virtual void SetVertexBuffer(const uint32_t bindingSlot, IBuffer* buffer) = 0;
- virtual void SetVertexBufferData(const uint32_t bindingSlot, const void* data) = 0;
+ virtual void SetVertexBufferData(
+ const uint32_t bindingSlot, const void* data, const uint32_t dataSize) = 0;
virtual void SetIndexBuffer(IBuffer* buffer) = 0;
- virtual void SetIndexBufferData(const void* data) = 0;
+ virtual void SetIndexBufferData(const void* data, const uint32_t dataSize) = 0;
virtual void BeginPass() = 0;
virtual void EndPass() = 0;
@@ -97,6 +99,13 @@
virtual void Draw(const uint32_t firstVertex, const uint32_t vertexCount) = 0;
virtual void DrawIndexed(
const uint32_t firstIndex, const uint32_t indexCount, const int32_t vertexOffset) = 0;
+ virtual void DrawInstanced(
+ const uint32_t firstVertex, const uint32_t vertexCount,
+ const uint32_t firstInstance, const uint32_t instanceCount) = 0;
+ virtual void DrawIndexedInstanced(
+ const uint32_t firstIndex, const uint32_t indexCount,
+ const uint32_t firstInstance, const uint32_t instanceCount,
+ const int32_t vertexOffset) = 0;
// TODO: should be removed when performance impact is minimal on slow hardware.
virtual void DrawIndexedInRange(
const uint32_t firstIndex, const uint32_t indexCount,
Index: ps/trunk/source/renderer/backend/IShaderProgram.h
===================================================================
--- ps/trunk/source/renderer/backend/IShaderProgram.h
+++ ps/trunk/source/renderer/backend/IShaderProgram.h
@@ -43,6 +43,12 @@
UV7,
};
+enum class VertexAttributeRate : uint32_t
+{
+ PER_VERTEX,
+ PER_INSTANCE
+};
+
/**
* IShaderProgram is a container for multiple shaders of different types.
*/
Index: ps/trunk/source/renderer/backend/dummy/Device.h
===================================================================
--- ps/trunk/source/renderer/backend/dummy/Device.h
+++ ps/trunk/source/renderer/backend/dummy/Device.h
@@ -78,7 +78,7 @@
const Capabilities& GetCapabilities() const override { return m_Capabilities; }
-private:
+protected:
std::string m_Name;
std::string m_Version;
Index: ps/trunk/source/renderer/backend/dummy/Device.cpp
===================================================================
--- ps/trunk/source/renderer/backend/dummy/Device.cpp
+++ ps/trunk/source/renderer/backend/dummy/Device.cpp
@@ -58,6 +58,7 @@
m_Capabilities.maxSampleCount = 4u;
m_Capabilities.maxAnisotropy = 16.0f;
m_Capabilities.maxTextureSize = 8192u;
+ m_Capabilities.instancing = true;
}
CDevice::~CDevice() = default;
Index: ps/trunk/source/renderer/backend/dummy/DeviceCommandContext.h
===================================================================
--- ps/trunk/source/renderer/backend/dummy/DeviceCommandContext.h
+++ ps/trunk/source/renderer/backend/dummy/DeviceCommandContext.h
@@ -83,12 +83,14 @@
const Format format,
const uint32_t offset,
const uint32_t stride,
+ const VertexAttributeRate rate,
const uint32_t bindingSlot) override;
void SetVertexBuffer(const uint32_t bindingSlot, IBuffer* buffer) override;
- void SetVertexBufferData(const uint32_t bindingSlot, const void* data) override;
+ void SetVertexBufferData(
+ const uint32_t bindingSlot, const void* data, const uint32_t dataSize) override;
void SetIndexBuffer(IBuffer* buffer) override;
- void SetIndexBufferData(const void* data) override;
+ void SetIndexBufferData(const void* data, const uint32_t dataSize) override;
void BeginPass() override;
void EndPass() override;
@@ -96,6 +98,13 @@
void Draw(const uint32_t firstVertex, const uint32_t vertexCount) override;
void DrawIndexed(
const uint32_t firstIndex, const uint32_t indexCount, const int32_t vertexOffset) override;
+ void DrawInstanced(
+ const uint32_t firstVertex, const uint32_t vertexCount,
+ const uint32_t firstInstance, const uint32_t instanceCount) override;
+ void DrawIndexedInstanced(
+ const uint32_t firstIndex, const uint32_t indexCount,
+ const uint32_t firstInstance, const uint32_t instanceCount,
+ const int32_t vertexOffset) override;
void DrawIndexedInRange(
const uint32_t firstIndex, const uint32_t indexCount,
const uint32_t start, const uint32_t end) override;
Index: ps/trunk/source/renderer/backend/dummy/DeviceCommandContext.cpp
===================================================================
--- ps/trunk/source/renderer/backend/dummy/DeviceCommandContext.cpp
+++ ps/trunk/source/renderer/backend/dummy/DeviceCommandContext.cpp
@@ -130,7 +130,7 @@
void CDeviceCommandContext::SetVertexAttributeFormat(
const VertexAttributeStream, const Format,
- const uint32_t, const uint32_t, const uint32_t)
+ const uint32_t, const uint32_t, const VertexAttributeRate, const uint32_t)
{
}
@@ -138,7 +138,8 @@
{
}
-void CDeviceCommandContext::SetVertexBufferData(const uint32_t, const void*)
+void CDeviceCommandContext::SetVertexBufferData(
+ const uint32_t, const void*, const uint32_t)
{
}
@@ -146,7 +147,7 @@
{
}
-void CDeviceCommandContext::SetIndexBufferData(const void*)
+void CDeviceCommandContext::SetIndexBufferData(const void*, const uint32_t)
{
}
@@ -166,6 +167,16 @@
{
}
+void CDeviceCommandContext::DrawInstanced(
+ const uint32_t, const uint32_t, const uint32_t, const uint32_t)
+{
+}
+
+void CDeviceCommandContext::DrawIndexedInstanced(
+ const uint32_t, const uint32_t, const uint32_t, const uint32_t, const int32_t)
+{
+}
+
void CDeviceCommandContext::DrawIndexedInRange(
const uint32_t, const uint32_t, const uint32_t, const uint32_t)
{
Index: ps/trunk/source/renderer/backend/gl/Device.cpp
===================================================================
--- ps/trunk/source/renderer/backend/gl/Device.cpp
+++ ps/trunk/source/renderer/backend/gl/Device.cpp
@@ -382,6 +382,16 @@
}
}
+#if CONFIG2_GLES
+ capabilities.instancing = false;
+#else
+ capabilities.instancing =
+ !device->m_ARB &&
+ (ogl_HaveVersion(3, 3) ||
+ (ogl_HaveExtension("GL_ARB_draw_instanced") &&
+ ogl_HaveExtension("GL_ARB_instanced_arrays")));
+#endif
+
return device;
}
Index: ps/trunk/source/renderer/backend/gl/DeviceCommandContext.h
===================================================================
--- ps/trunk/source/renderer/backend/gl/DeviceCommandContext.h
+++ ps/trunk/source/renderer/backend/gl/DeviceCommandContext.h
@@ -90,12 +90,14 @@
const Format format,
const uint32_t offset,
const uint32_t stride,
+ const VertexAttributeRate rate,
const uint32_t bindingSlot) override;
void SetVertexBuffer(const uint32_t bindingSlot, IBuffer* buffer) override;
- void SetVertexBufferData(const uint32_t bindingSlot, const void* data) override;
+ void SetVertexBufferData(
+ const uint32_t bindingSlot, const void* data, const uint32_t dataSize) override;
void SetIndexBuffer(IBuffer* buffer) override;
- void SetIndexBufferData(const void* data) override;
+ void SetIndexBufferData(const void* data, const uint32_t dataSize) override;
void BeginPass() override;
void EndPass() override;
@@ -103,6 +105,13 @@
void Draw(const uint32_t firstVertex, const uint32_t vertexCount) override;
void DrawIndexed(
const uint32_t firstIndex, const uint32_t indexCount, const int32_t vertexOffset) override;
+ void DrawInstanced(
+ const uint32_t firstVertex, const uint32_t vertexCount,
+ const uint32_t firstInstance, const uint32_t instanceCount) override;
+ void DrawIndexedInstanced(
+ const uint32_t firstIndex, const uint32_t indexCount,
+ const uint32_t firstInstance, const uint32_t instanceCount,
+ const int32_t vertexOffset) override;
void DrawIndexedInRange(
const uint32_t firstIndex, const uint32_t indexCount,
const uint32_t start, const uint32_t end) override;
@@ -206,6 +215,7 @@
Format format;
uint32_t offset;
uint32_t stride;
+ VertexAttributeRate rate;
uint32_t bindingSlot;
bool active;
Index: ps/trunk/source/renderer/backend/gl/DeviceCommandContext.cpp
===================================================================
--- ps/trunk/source/renderer/backend/gl/DeviceCommandContext.cpp
+++ ps/trunk/source/renderer/backend/gl/DeviceCommandContext.cpp
@@ -834,11 +834,12 @@
}
void CDeviceCommandContext::SetVertexAttributeFormat(
- const VertexAttributeStream stream,
- const Format format,
- const uint32_t offset,
- const uint32_t stride,
- const uint32_t bindingSlot)
+ const VertexAttributeStream stream,
+ const Format format,
+ const uint32_t offset,
+ const uint32_t stride,
+ const VertexAttributeRate rate,
+ const uint32_t bindingSlot)
{
const uint32_t index = static_cast(stream);
ENSURE(index < m_VertexAttributeFormat.size());
@@ -848,6 +849,7 @@
m_VertexAttributeFormat[index].format = format;
m_VertexAttributeFormat[index].offset = offset;
m_VertexAttributeFormat[index].stride = stride;
+ m_VertexAttributeFormat[index].rate = rate;
m_VertexAttributeFormat[index].bindingSlot = bindingSlot;
m_VertexAttributeFormat[index].initialized = true;
@@ -870,15 +872,17 @@
m_VertexAttributeFormat[index].format,
m_VertexAttributeFormat[index].offset,
m_VertexAttributeFormat[index].stride,
+ m_VertexAttributeFormat[index].rate,
nullptr);
}
}
void CDeviceCommandContext::SetVertexBufferData(
- const uint32_t bindingSlot, const void* data)
+ const uint32_t bindingSlot, const void* data, const uint32_t dataSize)
{
ENSURE(data);
ENSURE(m_ShaderProgram);
+ ENSURE(dataSize > 0);
BindBuffer(CBuffer::Type::VERTEX, nullptr);
for (size_t index = 0; index < m_VertexAttributeFormat.size(); ++index)
{
@@ -886,10 +890,14 @@
continue;
ENSURE(m_VertexAttributeFormat[index].initialized);
const VertexAttributeStream stream = static_cast(index);
+ // We don't know how many vertices will be used in a draw command, so we
+ // assume at least one vertex.
+ ENSURE(dataSize >= m_VertexAttributeFormat[index].offset + m_VertexAttributeFormat[index].stride);
m_ShaderProgram->VertexAttribPointer(stream,
m_VertexAttributeFormat[index].format,
m_VertexAttributeFormat[index].offset,
m_VertexAttributeFormat[index].stride,
+ m_VertexAttributeFormat[index].rate,
data);
}
}
@@ -902,8 +910,9 @@
BindBuffer(CBuffer::Type::INDEX, m_IndexBuffer);
}
-void CDeviceCommandContext::SetIndexBufferData(const void* data)
+void CDeviceCommandContext::SetIndexBufferData(const void* data, const uint32_t dataSize)
{
+ ENSURE(dataSize > 0);
if (m_IndexBuffer)
{
BindBuffer(CBuffer::Type::INDEX, nullptr);
@@ -960,6 +969,47 @@
ogl_WarnIfError();
}
+void CDeviceCommandContext::DrawInstanced(
+ const uint32_t firstVertex, const uint32_t vertexCount,
+ const uint32_t firstInstance, const uint32_t instanceCount)
+{
+ ENSURE(m_Device->GetCapabilities().instancing);
+ ENSURE(m_ShaderProgram);
+ ENSURE(m_InsidePass);
+ if (vertexCount == 0 || instanceCount == 0)
+ return;
+ ENSURE(firstInstance == 0);
+ m_ShaderProgram->AssertPointersBound();
+ glDrawArraysInstancedARB(GL_TRIANGLES, firstVertex, vertexCount, instanceCount);
+ ogl_WarnIfError();
+}
+
+void CDeviceCommandContext::DrawIndexedInstanced(
+ const uint32_t firstIndex, const uint32_t indexCount,
+ const uint32_t firstInstance, const uint32_t instanceCount,
+ const int32_t vertexOffset)
+{
+ ENSURE(m_Device->GetCapabilities().instancing);
+ ENSURE(m_ShaderProgram);
+ ENSURE(m_InsidePass);
+ ENSURE(m_IndexBuffer || m_IndexBufferData);
+ if (indexCount == 0)
+ return;
+ ENSURE(firstInstance == 0 && vertexOffset == 0);
+ if (m_IndexBuffer)
+ {
+ ENSURE(sizeof(uint16_t) * (firstIndex + indexCount) <= m_IndexBuffer->GetSize());
+ }
+ m_ShaderProgram->AssertPointersBound();
+ // Don't use glMultiDrawElements here since it doesn't have a significant
+ // performance impact and it suffers from various driver bugs (e.g. it breaks
+ // in Mesa 7.10 swrast with index VBOs).
+ glDrawElementsInstancedARB(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT,
+ static_cast((static_cast(m_IndexBufferData) + sizeof(uint16_t) * firstIndex)),
+ instanceCount);
+ ogl_WarnIfError();
+}
+
void CDeviceCommandContext::DrawIndexedInRange(
const uint32_t firstIndex, const uint32_t indexCount,
const uint32_t start, const uint32_t end)
Index: ps/trunk/source/renderer/backend/gl/ShaderProgram.h
===================================================================
--- ps/trunk/source/renderer/backend/gl/ShaderProgram.h
+++ ps/trunk/source/renderer/backend/gl/ShaderProgram.h
@@ -110,7 +110,8 @@
// Vertex attribute pointers (equivalent to glVertexPointer etc).
virtual void VertexAttribPointer(
const VertexAttributeStream stream, const Format format,
- const uint32_t offset, const uint32_t stride, const void* data);
+ const uint32_t offset, const uint32_t stride,
+ const VertexAttributeRate rate, const void* data);
bool IsStreamActive(const VertexAttributeStream stream) const;
@@ -127,7 +128,6 @@
void NormalPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
void ColorPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
void TexCoordPointer(GLenum texture, const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
- void VertexAttribPointer(attrib_id_t id, const Renderer::Backend::Format format, GLboolean normalized, GLsizei stride, const void* pointer);
int m_StreamFlags;
Index: ps/trunk/source/renderer/backend/gl/ShaderProgram.cpp
===================================================================
--- ps/trunk/source/renderer/backend/gl/ShaderProgram.cpp
+++ ps/trunk/source/renderer/backend/gl/ShaderProgram.cpp
@@ -1088,7 +1088,8 @@
void VertexAttribPointer(
const VertexAttributeStream stream, const Format format,
- const uint32_t offset, const uint32_t stride, const void* data) override
+ const uint32_t offset, const uint32_t stride,
+ const VertexAttributeRate rate, const void* data) override
{
const int attributeLocation = GetAttributeLocationFromStream(m_Device, stream);
std::vector::const_iterator it =
@@ -1100,6 +1101,12 @@
const GLboolean normalized = NormalizedFromFormat(format);
glVertexAttribPointer(
attributeLocation, size, type, normalized, stride, static_cast(data) + offset);
+ if (rate == VertexAttributeRate::PER_INSTANCE)
+ ENSURE(m_Device->GetCapabilities().instancing);
+ if (m_Device->GetCapabilities().instancing)
+ {
+ glVertexAttribDivisorARB(attributeLocation, rate == VertexAttributeRate::PER_INSTANCE ? 1 : 0);
+ }
m_ValidStreams |= GetStreamMask(stream);
}
@@ -1310,12 +1317,6 @@
// These should all be overridden by CShaderProgramGLSL, and not used
// if a non-GLSL shader was loaded instead:
-void CShaderProgram::VertexAttribPointer(attrib_id_t UNUSED(id), const Renderer::Backend::Format UNUSED(format),
- GLboolean UNUSED(normalized), GLsizei UNUSED(stride), const void* UNUSED(pointer))
-{
- debug_warn("Shader type doesn't support VertexAttribPointer");
-}
-
#if CONFIG2_GLES
// These should all be overridden by CShaderProgramGLSL
@@ -1449,8 +1450,10 @@
void CShaderProgram::VertexAttribPointer(
const VertexAttributeStream stream, const Format format,
- const uint32_t offset, const uint32_t stride, const void* data)
+ const uint32_t offset, const uint32_t stride,
+ const VertexAttributeRate rate, const void* data)
{
+ ENSURE(rate == VertexAttributeRate::PER_VERTEX);
switch (stream)
{
case VertexAttributeStream::POSITION: