(view as text)
diff --git a/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp b/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp
index 4c6332d..62954c6 100644
--- a/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp
+++ b/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp
@@ -32,28 +32,44 @@ NativeVertexFormat* VertexManager::CreateNativeVertexFormat()
return new D3DVertexFormat();
}
-DXGI_FORMAT VarToD3D(VarType t, int size)
+DXGI_FORMAT VarToD3D(VarType t, int size, bool integer)
{
DXGI_FORMAT retval = DXGI_FORMAT_UNKNOWN;
+ static const DXGI_FORMAT lookup1i[5] = {
+ DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_UNKNOWN
+ };
+ static const DXGI_FORMAT lookup2i[5] = {
+ DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_UNKNOWN
+ };
+ static const DXGI_FORMAT lookup3i[5] = {
+ DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN
+ };
+ static const DXGI_FORMAT lookup4i[5] = {
+ DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN
+ };
static const DXGI_FORMAT lookup1[5] = {
- DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R32_FLOAT
+ DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_R32_FLOAT
};
static const DXGI_FORMAT lookup2[5] = {
- DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R32G32_FLOAT
+ DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R32G32_FLOAT
};
static const DXGI_FORMAT lookup3[5] = {
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R32G32B32_FLOAT
};
static const DXGI_FORMAT lookup4[5] = {
- DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R32G32B32A32_FLOAT
+ DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R32G32B32A32_FLOAT
};
- switch (size)
+ switch (size*2 + integer)
{
- case 1: retval = lookup1[t]; break;
- case 2: retval = lookup2[t]; break;
- case 3: retval = lookup3[t]; break;
- case 4: retval = lookup4[t]; break;
+ case 2: retval = lookup1[t]; break;
+ case 3: retval = lookup1i[t]; break;
+ case 4: retval = lookup2[t]; break;
+ case 5: retval = lookup2i[t]; break;
+ case 6: retval = lookup3[t]; break;
+ case 7: retval = lookup3i[t]; break;
+ case 8: retval = lookup4[t]; break;
+ case 9: retval = lookup4i[t]; break;
default: break;
}
if (retval == DXGI_FORMAT_UNKNOWN)
@@ -67,21 +83,26 @@ void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
{
vertex_stride = _vtx_decl.stride;
memset(m_elems, 0, sizeof(m_elems));
+ const AttributeFormat* format = &_vtx_decl.position;
- m_elems[m_num_elems].SemanticName = "POSITION";
- m_elems[m_num_elems].AlignedByteOffset = 0;
- m_elems[m_num_elems].Format = DXGI_FORMAT_R32G32B32_FLOAT;
- m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
- ++m_num_elems;
+ if (format->enable)
+ {
+ m_elems[m_num_elems].SemanticName = "POSITION";
+ m_elems[m_num_elems].AlignedByteOffset = format->offset;
+ m_elems[m_num_elems].Format = VarToD3D(format->type, format->components, format->integer);
+ m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+ ++m_num_elems;
+ }
for (int i = 0; i < 3; i++)
{
- if (_vtx_decl.normal_offset[i] > 0)
+ format = &_vtx_decl.normals[i];
+ if (format->enable)
{
m_elems[m_num_elems].SemanticName = "NORMAL";
m_elems[m_num_elems].SemanticIndex = i;
- m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.normal_offset[i];
- m_elems[m_num_elems].Format = VarToD3D(_vtx_decl.normal_gl_type, _vtx_decl.normal_gl_size);
+ m_elems[m_num_elems].AlignedByteOffset = format->offset;
+ m_elems[m_num_elems].Format = VarToD3D(format->type, format->components, format->integer);
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
++m_num_elems;
}
@@ -89,12 +110,13 @@ void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
for (int i = 0; i < 2; i++)
{
- if (_vtx_decl.color_offset[i] > 0)
+ format = &_vtx_decl.colors[i];
+ if (format->enable)
{
m_elems[m_num_elems].SemanticName = "COLOR";
m_elems[m_num_elems].SemanticIndex = i;
- m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.color_offset[i];
- m_elems[m_num_elems].Format = VarToD3D(_vtx_decl.color_gl_type, 4);
+ m_elems[m_num_elems].AlignedByteOffset = format->offset;
+ m_elems[m_num_elems].Format = VarToD3D(format->type, format->components, format->integer);
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
++m_num_elems;
}
@@ -102,22 +124,24 @@ void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
for (int i = 0; i < 8; i++)
{
- if (_vtx_decl.texcoord_offset[i] > 0)
+ format = &_vtx_decl.texcoords[i];
+ if (format->enable)
{
m_elems[m_num_elems].SemanticName = "TEXCOORD";
m_elems[m_num_elems].SemanticIndex = i;
- m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.texcoord_offset[i];
- m_elems[m_num_elems].Format = VarToD3D(_vtx_decl.texcoord_gl_type[i], _vtx_decl.texcoord_size[i]);
+ m_elems[m_num_elems].AlignedByteOffset = format->offset;
+ m_elems[m_num_elems].Format = VarToD3D(format->type, format->components, format->integer);
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
++m_num_elems;
}
}
- if (_vtx_decl.posmtx_offset != -1)
+ format = &_vtx_decl.posmtx;
+ if (format->enable)
{
m_elems[m_num_elems].SemanticName = "BLENDINDICES";
- m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.posmtx_offset;
- m_elems[m_num_elems].Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ m_elems[m_num_elems].AlignedByteOffset = format->offset;
+ m_elems[m_num_elems].Format = VarToD3D(format->type, format->components, format->integer);
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
++m_num_elems;
}
diff --git a/Source/Core/VideoBackends/OGL/NativeVertexFormat.cpp b/Source/Core/VideoBackends/OGL/NativeVertexFormat.cpp
index c0112c4..c3633fd 100644
--- a/Source/Core/VideoBackends/OGL/NativeVertexFormat.cpp
+++ b/Source/Core/VideoBackends/OGL/NativeVertexFormat.cpp
@@ -37,11 +37,22 @@ GLVertexFormat::~GLVertexFormat()
inline GLuint VarToGL(VarType t)
{
static const GLuint lookup[5] = {
- GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FLOAT
+ GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_FLOAT
};
return lookup[t];
}
+static void SetPointer(u32 attrib, u32 stride, const AttributeFormat &format)
+{
+ if(!format.enable) return;
+
+ glEnableVertexAttribArray(attrib);
+ if(format.integer)
+ glVertexAttribIPointer(attrib, format.components, VarToGL(format.type), stride, (u8*)NULL + format.offset);
+ else
+ glVertexAttribPointer(attrib, format.components, VarToGL(format.type), true, stride, (u8*)NULL + format.offset);
+}
+
void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
{
this->vtx_decl = _vtx_decl;
@@ -60,35 +71,21 @@ void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->m_index_buffers);
glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers);
- glEnableVertexAttribArray(SHADER_POSITION_ATTRIB);
- glVertexAttribPointer(SHADER_POSITION_ATTRIB, 3, GL_FLOAT, GL_FALSE, vtx_decl.stride, (u8*)NULL);
+ SetPointer(SHADER_POSITION_ATTRIB, vertex_stride, vtx_decl.position);
for (int i = 0; i < 3; i++) {
- if (vtx_decl.num_normals > i) {
- glEnableVertexAttribArray(SHADER_NORM0_ATTRIB+i);
- glVertexAttribPointer(SHADER_NORM0_ATTRIB+i, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[i]);
- }
+ SetPointer(SHADER_NORM0_ATTRIB+i, vertex_stride, vtx_decl.normals[i]);
}
for (int i = 0; i < 2; i++) {
- if (vtx_decl.color_offset[i] != -1) {
- glEnableVertexAttribArray(SHADER_COLOR0_ATTRIB+i);
- glVertexAttribPointer(SHADER_COLOR0_ATTRIB+i, 4, GL_UNSIGNED_BYTE, GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]);
- }
+ SetPointer(SHADER_COLOR0_ATTRIB+i, vertex_stride, vtx_decl.colors[i]);
}
for (int i = 0; i < 8; i++) {
- if (vtx_decl.texcoord_offset[i] != -1) {
- glEnableVertexAttribArray(SHADER_TEXTURE0_ATTRIB+i);
- glVertexAttribPointer(SHADER_TEXTURE0_ATTRIB+i, vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]),
- GL_FALSE, vtx_decl.stride, (u8*)NULL + vtx_decl.texcoord_offset[i]);
- }
+ SetPointer(SHADER_TEXTURE0_ATTRIB+i, vertex_stride, vtx_decl.texcoords[i]);
}
- if (vtx_decl.posmtx_offset != -1) {
- glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB);
- glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (u8*)NULL + vtx_decl.posmtx_offset);
- }
+ SetPointer(SHADER_POSMTX_ATTRIB, vertex_stride, vtx_decl.posmtx);
vm->m_last_vao = VAO;
}
diff --git a/Source/Core/VideoCommon/NativeVertexFormat.h b/Source/Core/VideoCommon/NativeVertexFormat.h
index b4e83ed..8b41ecd 100644
--- a/Source/Core/VideoCommon/NativeVertexFormat.h
+++ b/Source/Core/VideoCommon/NativeVertexFormat.h
@@ -65,28 +65,31 @@ typedef void (LOADERDECL *TPipelineFunction)();
enum VarType
{
- VAR_BYTE,
- VAR_UNSIGNED_BYTE,
- VAR_SHORT,
- VAR_UNSIGNED_SHORT,
- VAR_FLOAT,
+ VAR_UNSIGNED_BYTE, // GX_U8 = 0
+ VAR_BYTE, // GX_S8 = 1
+ VAR_UNSIGNED_SHORT, // GX_U16 = 2
+ VAR_SHORT, // GX_S16 = 3
+ VAR_FLOAT, // GX_F32 = 4
+};
+
+struct AttributeFormat
+{
+ VarType type;
+ int components;
+ int offset;
+ bool enable;
+ bool integer;
};
struct PortableVertexDeclaration
{
int stride;
- int num_normals;
- int normal_offset[3];
- VarType normal_gl_type;
- int normal_gl_size;
- VarType color_gl_type; // always GL_UNSIGNED_BYTE
- int color_offset[2];
- VarType texcoord_gl_type[8];
- //int texcoord_gl_size[8];
- int texcoord_offset[8];
- int texcoord_size[8];
- int posmtx_offset;
+ AttributeFormat position;
+ AttributeFormat normals[3];
+ AttributeFormat colors[2];
+ AttributeFormat texcoords[8];
+ AttributeFormat posmtx;
};
// The implementation of this class is specific for GL/DX, so NativeVertexFormat.cpp
diff --git a/Source/Core/VideoCommon/VertexLoader.cpp b/Source/Core/VideoCommon/VertexLoader.cpp
index 45bfec3..99e5541 100644
--- a/Source/Core/VideoCommon/VertexLoader.cpp
+++ b/Source/Core/VideoCommon/VertexLoader.cpp
@@ -550,12 +550,6 @@ void VertexLoader::CompileVertexTranslator()
int nat_offset = 0;
PortableVertexDeclaration vtx_decl;
memset(&vtx_decl, 0, sizeof(vtx_decl));
- for (int i = 0; i < 8; i++)
- {
- vtx_decl.texcoord_offset[i] = -1;
- }
-
- // m_VBVertexStride for texmtx and posmtx is computed later when writing.
// Position Matrix Index
if (m_VtxDesc.PosMatIdx)
@@ -587,9 +581,13 @@ void VertexLoader::CompileVertexTranslator()
}
m_VertexSize += VertexLoader_Position::GetSize(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements);
nat_offset += 12;
+ vtx_decl.position.components = 3;
+ vtx_decl.position.enable = true;
+ vtx_decl.position.offset = 0;
+ vtx_decl.position.type = VAR_FLOAT;
+ vtx_decl.position.integer = false;
// Normals
- vtx_decl.num_normals = 0;
if (m_VtxDesc.Normal != NOT_PRESENT)
{
m_VertexSize += VertexLoader_Normal::GetSize(m_VtxDesc.Normal,
@@ -606,20 +604,13 @@ void VertexLoader::CompileVertexTranslator()
}
WriteCall(pFunc);
- vtx_decl.num_normals = vtx_attr.NormalElements ? 3 : 1;
- vtx_decl.normal_offset[0] = -1;
- vtx_decl.normal_offset[1] = -1;
- vtx_decl.normal_offset[2] = -1;
- vtx_decl.normal_gl_type = VAR_FLOAT;
- vtx_decl.normal_gl_size = 3;
- vtx_decl.normal_offset[0] = nat_offset;
- nat_offset += 12;
-
- if (vtx_attr.NormalElements)
+ for (int i = 0; i < (vtx_attr.NormalElements ? 3 : 1); i++)
{
- vtx_decl.normal_offset[1] = nat_offset;
- nat_offset += 12;
- vtx_decl.normal_offset[2] = nat_offset;
+ vtx_decl.normals[i].components = 3;
+ vtx_decl.normals[i].enable = true;
+ vtx_decl.normals[i].offset = nat_offset;
+ vtx_decl.normals[i].type = VAR_FLOAT;
+ vtx_decl.normals[i].integer = false;
nat_offset += 12;
}
@@ -630,17 +621,14 @@ void VertexLoader::CompileVertexTranslator()
components |= VB_HAS_NRM1 | VB_HAS_NRM2;
}
- vtx_decl.color_gl_type = VAR_UNSIGNED_BYTE;
- vtx_decl.color_offset[0] = -1;
- vtx_decl.color_offset[1] = -1;
for (int i = 0; i < 2; i++)
{
- components |= VB_HAS_COL0 << i;
+ vtx_decl.colors[i].components = 4;
+ vtx_decl.colors[i].type = VAR_UNSIGNED_BYTE;
+ vtx_decl.colors[i].integer = false;
switch (col[i])
{
case NOT_PRESENT:
- components &= ~(VB_HAS_COL0 << i);
- vtx_decl.color_offset[i] = -1;
break;
case DIRECT:
switch (m_VtxAttr.color[i].Comp)
@@ -684,7 +672,9 @@ void VertexLoader::CompileVertexTranslator()
// Common for the three bottom cases
if (col[i] != NOT_PRESENT)
{
- vtx_decl.color_offset[i] = nat_offset;
+ components |= VB_HAS_COL0 << i;
+ vtx_decl.colors[i].offset = nat_offset;
+ vtx_decl.colors[i].enable = true;
nat_offset += 4;
}
}
@@ -692,7 +682,10 @@ void VertexLoader::CompileVertexTranslator()
// Texture matrix indices (remove if corresponding texture coordinate isn't enabled)
for (int i = 0; i < 8; i++)
{
- vtx_decl.texcoord_offset[i] = -1;
+ vtx_decl.texcoords[i].offset = nat_offset;
+ vtx_decl.texcoords[i].type = VAR_FLOAT;
+ vtx_decl.texcoords[i].integer = false;
+
const int format = m_VtxAttr.texCoord[i].Format;
const int elements = m_VtxAttr.texCoord[i].Elements;
@@ -713,21 +706,18 @@ void VertexLoader::CompileVertexTranslator()
if (components & (VB_HAS_TEXMTXIDX0 << i))
{
+ vtx_decl.texcoords[i].enable = true;
if (tc[i] != NOT_PRESENT)
{
// if texmtx is included, texcoord will always be 3 floats, z will be the texmtx index
- vtx_decl.texcoord_offset[i] = nat_offset;
- vtx_decl.texcoord_gl_type[i] = VAR_FLOAT;
- vtx_decl.texcoord_size[i] = 3;
+ vtx_decl.texcoords[i].components = 3;
nat_offset += 12;
WriteCall(m_VtxAttr.texCoord[i].Elements ? TexMtx_Write_Float : TexMtx_Write_Float2);
}
else
{
components |= VB_HAS_UV0 << i; // have to include since using now
- vtx_decl.texcoord_offset[i] = nat_offset;
- vtx_decl.texcoord_gl_type[i] = VAR_FLOAT;
- vtx_decl.texcoord_size[i] = 4;
+ vtx_decl.texcoords[i].components = 4;
nat_offset += 16; // still include the texture coordinate, but this time as 6 + 2 bytes
WriteCall(TexMtx_Write_Float4);
}
@@ -736,9 +726,8 @@ void VertexLoader::CompileVertexTranslator()
{
if (tc[i] != NOT_PRESENT)
{
- vtx_decl.texcoord_offset[i] = nat_offset;
- vtx_decl.texcoord_gl_type[i] = VAR_FLOAT;
- vtx_decl.texcoord_size[i] = vtx_attr.texCoord[i].Elements ? 2 : 1;
+ vtx_decl.texcoords[i].enable = true;
+ vtx_decl.texcoords[i].components = vtx_attr.texCoord[i].Elements ? 2 : 1;
nat_offset += 4 * (vtx_attr.texCoord[i].Elements ? 2 : 1);
}
}
@@ -767,13 +756,13 @@ void VertexLoader::CompileVertexTranslator()
if (m_VtxDesc.PosMatIdx)
{
WriteCall(PosMtx_Write);
- vtx_decl.posmtx_offset = nat_offset;
+ vtx_decl.posmtx.components = 4;
+ vtx_decl.posmtx.enable = true;
+ vtx_decl.posmtx.offset = nat_offset;
+ vtx_decl.posmtx.type = VAR_UNSIGNED_BYTE;
+ vtx_decl.posmtx.integer = false;
nat_offset += 4;
}
- else
- {
- vtx_decl.posmtx_offset = -1;
- }
native_stride = nat_offset;
vtx_decl.stride = native_stride;
diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp
index 78d5449..5774288 100644
--- a/Source/Core/VideoCommon/VertexShaderGen.cpp
+++ b/Source/Core/VideoCommon/VertexShaderGen.cpp
@@ -168,7 +168,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
out.Write(" float%d tex%d : TEXCOORD%d,\n", hastexmtx ? 3 : 2, i, i);
}
if (components & VB_HAS_POSMTXIDX)
- out.Write(" float4 blend_indices : BLENDINDICES,\n");
+ out.Write(" float4 fposmtx : BLENDINDICES,\n");
out.Write(" float4 rawpos : POSITION) {\n");
}
out.Write("VS_OUTPUT o;\n");
@@ -176,10 +176,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
// transforms
if (components & VB_HAS_POSMTXIDX)
{
- if (api_type == API_D3D)
- out.Write("int posmtx = blend_indices.x * 255.0;\n"); // TODO: Ugly, should use an integer instead
- else
- out.Write("int posmtx = int(fposmtx);\n");
+ out.Write("int posmtx = int(fposmtx * 255.0);\n"); // TODO: Ugly, should use an integer instead
if (is_writing_shadercode && (DriverDetails::HasBug(DriverDetails::BUG_NODYNUBOACCESS) && !DriverDetails::HasBug(DriverDetails::BUG_ANNIHILATEDUBOS)) )
{