mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-18 04:21:00 +00:00
rsx: Migrate vertex fetch out of the cpp file
This commit is contained in:
parent
89c81d9f22
commit
fb3aa9628d
@ -129,210 +129,12 @@ namespace glsl
|
||||
// Note: Tested on Mesa iris with HD 530 and compilant path works fine, may be a bug on Windows proprietary drivers
|
||||
if (!glsl4_compliant)
|
||||
{
|
||||
OS <<
|
||||
"void mov(inout uvec4 vector, const in int index, const in uint scalar)\n"
|
||||
"{\n"
|
||||
" switch(index)\n"
|
||||
" {\n"
|
||||
" case 0: vector.x = scalar; return;\n"
|
||||
" case 1: vector.y = scalar; return;\n"
|
||||
" case 2: vector.z = scalar; return;\n"
|
||||
" case 3: vector.w = scalar; return;\n"
|
||||
" }\n"
|
||||
"}\n\n"
|
||||
|
||||
"uint ref(const in uvec4 vector, const in int index)\n"
|
||||
"{\n"
|
||||
" switch(index)\n"
|
||||
" {\n"
|
||||
" case 0: return vector.x;\n"
|
||||
" case 1: return vector.y;\n"
|
||||
" case 2: return vector.z;\n"
|
||||
" case 3: return vector.w;\n"
|
||||
" }\n"
|
||||
"}\n\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
OS <<
|
||||
"#define mov(v, i, s) v[i] = s\n"
|
||||
"#define ref(v, i) v[i]\n\n";
|
||||
OS << "#define _INTEL_GLSL\n";
|
||||
}
|
||||
|
||||
OS <<
|
||||
"struct attribute_desc\n"
|
||||
"{\n"
|
||||
" uint type;\n"
|
||||
" uint attribute_size;\n"
|
||||
" uint starting_offset;\n"
|
||||
" uint stride;\n"
|
||||
" uint frequency;\n"
|
||||
" bool swap_bytes;\n"
|
||||
" bool is_volatile;\n"
|
||||
" bool modulo;\n"
|
||||
"};\n\n"
|
||||
|
||||
"uint gen_bits(const in uint x, const in uint y, const in uint z, const in uint w, const in bool swap)\n"
|
||||
"{\n"
|
||||
" return (swap) ?\n"
|
||||
" _set_bits(_set_bits(_set_bits(w, z, 8, 8), y, 16, 8), x, 24, 8) :\n"
|
||||
" _set_bits(_set_bits(_set_bits(x, y, 8, 8), z, 16, 8), w, 24, 8);\n"
|
||||
"}\n\n"
|
||||
|
||||
"uint gen_bits(const in uint x, const in uint y, const in bool swap)\n"
|
||||
"{\n"
|
||||
" return (swap)? _set_bits(y, x, 8, 8) : _set_bits(x, y, 8, 8);\n"
|
||||
"}\n\n"
|
||||
|
||||
// NOTE: (int(n) or int(n)) is broken on some NVIDIA and INTEL hardware when the sign bit is involved.
|
||||
// See https://github.com/RPCS3/rpcs3/issues/8990
|
||||
"vec4 sext(const in ivec4 bits)\n"
|
||||
"{\n"
|
||||
" // convert raw 16 bit values into signed 32-bit float4 counterpart\n"
|
||||
" bvec4 sign_check = lessThan(bits, ivec4(0x8000));\n"
|
||||
" return _select(bits - 65536, bits, sign_check);\n"
|
||||
"}\n\n"
|
||||
|
||||
"float sext(const in int bits)\n"
|
||||
"{\n"
|
||||
" return (bits < 0x8000) ? float(bits) : float(bits - 65536); \n"
|
||||
"}\n\n"
|
||||
|
||||
"vec4 fetch_attribute(const in attribute_desc desc, const in int vertex_id, usamplerBuffer input_stream)\n"
|
||||
"{\n"
|
||||
" const int elem_size_table[] = { 0, 2, 4, 2, 1, 2, 4, 1 };\n"
|
||||
" const float scaling_table[] = { 1., 32767.5, 1., 1., 255., 1., 32767., 1. };\n"
|
||||
" const int elem_size = elem_size_table[desc.type];\n"
|
||||
" const vec4 scale = scaling_table[desc.type].xxxx;\n\n"
|
||||
|
||||
" uvec4 tmp, result = uvec4(0u);\n"
|
||||
" vec4 ret;\n"
|
||||
" int n, i = int((vertex_id * desc.stride) + desc.starting_offset);\n\n"
|
||||
|
||||
" for (n = 0; n < desc.attribute_size; n++)\n"
|
||||
" {\n"
|
||||
" tmp.x = texelFetch(input_stream, i++).x;\n"
|
||||
" if (elem_size == 2)\n"
|
||||
" {\n"
|
||||
" tmp.y = texelFetch(input_stream, i++).x;\n"
|
||||
" tmp.x = gen_bits(tmp.x, tmp.y, desc.swap_bytes);\n"
|
||||
" }\n"
|
||||
" else if (elem_size == 4)\n"
|
||||
" {\n"
|
||||
" tmp.y = texelFetch(input_stream, i++).x;\n"
|
||||
" tmp.z = texelFetch(input_stream, i++).x;\n"
|
||||
" tmp.w = texelFetch(input_stream, i++).x;\n"
|
||||
" tmp.x = gen_bits(tmp.x, tmp.y, tmp.z, tmp.w, desc.swap_bytes);\n"
|
||||
" }\n\n"
|
||||
|
||||
" mov(result, n, tmp.x);\n"
|
||||
" }\n\n"
|
||||
|
||||
" // Actual decoding step is done in vector space, outside the loop\n"
|
||||
" if (desc.type == VTX_FMT_SNORM16 || desc.type == VTX_FMT_SINT16)\n"
|
||||
" {\n"
|
||||
" ret = sext(ivec4(result));\n"
|
||||
" ret = fma(vec4(0.5), vec4(desc.type == VTX_FMT_SNORM16), ret);\n"
|
||||
" }\n"
|
||||
" else if (desc.type == VTX_FMT_FLOAT32)\n"
|
||||
" {\n"
|
||||
" ret = uintBitsToFloat(result);\n"
|
||||
" }\n"
|
||||
" else if (desc.type == VTX_FMT_FLOAT16)\n"
|
||||
" {\n"
|
||||
" tmp.x = _set_bits(result.x, result.y, 16, 16);\n"
|
||||
" tmp.y = _set_bits(result.z, result.w, 16, 16);\n"
|
||||
" ret.xy = unpackHalf2x16(tmp.x);\n"
|
||||
" ret.zw = unpackHalf2x16(tmp.y);\n"
|
||||
" }\n"
|
||||
" else if (elem_size == 1) //(desc.type == VTX_FMT_UINT8 || desc.type == VTX_FMT_UNORM8)\n"
|
||||
" {\n"
|
||||
" // Ignore bswap on single byte channels\n"
|
||||
" ret = vec4(result);\n"
|
||||
" }\n"
|
||||
" else //if (desc.type == VTX_FMT_COMP32)\n"
|
||||
" {\n"
|
||||
" result = uvec4(_get_bits(result.x, 0, 11),\n"
|
||||
" _get_bits(result.x, 11, 11),\n"
|
||||
" _get_bits(result.x, 22, 10),\n"
|
||||
" uint(scale.x));\n"
|
||||
" ret = sext(ivec4(result) << ivec4(5, 5, 6, 0));\n"
|
||||
" }\n\n"
|
||||
|
||||
" if (desc.attribute_size < 4)\n"
|
||||
" {\n"
|
||||
" ret.w = scale.x;\n"
|
||||
" }\n\n"
|
||||
|
||||
" return ret / scale; \n"
|
||||
"}\n\n"
|
||||
|
||||
"attribute_desc fetch_desc(const in int location)\n"
|
||||
"{\n"
|
||||
" // Each descriptor is 64 bits wide\n"
|
||||
" // [0-8] attribute stride\n"
|
||||
" // [8-24] attribute divisor\n"
|
||||
" // [24-27] attribute type\n"
|
||||
" // [27-30] attribute size\n"
|
||||
" // [30-31] reserved\n"
|
||||
" // [32-60] starting offset\n"
|
||||
" // [60-61] swap bytes flag\n"
|
||||
" // [61-62] volatile flag\n"
|
||||
" // [62-63] modulo enable flag\n\n";
|
||||
|
||||
if (rules == glsl_rules_opengl4)
|
||||
{
|
||||
// Data is packed into a ubo
|
||||
OS <<
|
||||
" int block = (location >> 1);\n"
|
||||
" int sub_block = (location & 1) << 1;\n"
|
||||
" uvec2 attrib = uvec2(\n"
|
||||
" ref(input_attributes_blob[block], sub_block + 0),\n"
|
||||
" ref(input_attributes_blob[block], sub_block + 1));\n\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fetch parameters streamed separately from draw parameters
|
||||
OS <<
|
||||
" uvec2 attrib = texelFetch(vertex_layout_stream, location + int(layout_ptr_offset)).xy;\n\n";
|
||||
}
|
||||
|
||||
OS <<
|
||||
" attribute_desc result;\n"
|
||||
" result.stride = _get_bits(attrib.x, 0, 8);\n"
|
||||
" result.frequency = _get_bits(attrib.x, 8, 16);\n"
|
||||
" result.type = _get_bits(attrib.x, 24, 3);\n"
|
||||
" result.attribute_size = _get_bits(attrib.x, 27, 3);\n"
|
||||
" result.starting_offset = _get_bits(attrib.y, 0, 29);\n"
|
||||
" result.swap_bytes = _test_bit(attrib.y, 29);\n"
|
||||
" result.is_volatile = _test_bit(attrib.y, 30);\n"
|
||||
" result.modulo = _test_bit(attrib.y, 31);\n"
|
||||
" return result;\n"
|
||||
"}\n\n"
|
||||
|
||||
"vec4 read_location(const in int location)\n"
|
||||
"{\n"
|
||||
" attribute_desc desc = fetch_desc(location);\n"
|
||||
" int vertex_id = " << vertex_id_name << " - int(vertex_base_index);\n"
|
||||
" if (desc.frequency == 0)\n"
|
||||
" {\n"
|
||||
" vertex_id = 0;\n"
|
||||
" }\n"
|
||||
" else if (desc.modulo)\n"
|
||||
" {\n"
|
||||
" //if a vertex modifier is active; vertex_base must be 0 and is ignored\n"
|
||||
" vertex_id = (" << vertex_id_name << " + int(vertex_index_offset)) % int(desc.frequency);\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" vertex_id /= int(desc.frequency); \n"
|
||||
" }\n\n"
|
||||
|
||||
" if (desc.is_volatile)\n"
|
||||
" return fetch_attribute(desc, vertex_id, volatile_input_stream);\n"
|
||||
" else\n"
|
||||
" return fetch_attribute(desc, vertex_id, persistent_input_stream);\n"
|
||||
"}\n\n";
|
||||
#include "GLSLSnippets/RSXProg/RSXVertexFetch.glsl"
|
||||
;
|
||||
}
|
||||
|
||||
void insert_rop_init(std::ostream& OS)
|
||||
|
209
rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXVertexFetch.glsl
Normal file
209
rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXVertexFetch.glsl
Normal file
@ -0,0 +1,209 @@
|
||||
R"(
|
||||
#ifdef _INTEL_GLSL
|
||||
// For intel GPUs which cannot access vectors in indexed mode (driver bug? or glsl version too low?)
|
||||
// Note: Tested on Mesa iris with HD 530 and compilant path works fine, may be a bug on Windows proprietary drivers
|
||||
void mov(inout uvec4 vector, const in int index, const in uint scalar)
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
case 0: vector.x = scalar; return;
|
||||
case 1: vector.y = scalar; return;
|
||||
case 2: vector.z = scalar; return;
|
||||
case 3: vector.w = scalar; return;
|
||||
}
|
||||
}
|
||||
|
||||
uint ref(const in uvec4 vector, const in int index)
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
case 0: return vector.x;
|
||||
case 1: return vector.y;
|
||||
case 2: return vector.z;
|
||||
case 3: return vector.w;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define mov(v, i, s) v[i] = s
|
||||
#define ref(v, i) v[i]
|
||||
#endif
|
||||
|
||||
#ifdef VULKAN
|
||||
#define _gl_VertexID gl_VertexIndex
|
||||
#else
|
||||
#define _gl_VertexID gl_VertexID
|
||||
#endif
|
||||
|
||||
struct attribute_desc
|
||||
{
|
||||
uint type;
|
||||
uint attribute_size;
|
||||
uint starting_offset;
|
||||
uint stride;
|
||||
uint frequency;
|
||||
bool swap_bytes;
|
||||
bool is_volatile;
|
||||
bool modulo;
|
||||
};
|
||||
|
||||
uint gen_bits(const in uint x, const in uint y, const in uint z, const in uint w, const in bool swap)
|
||||
{
|
||||
return (swap) ?
|
||||
_set_bits(_set_bits(_set_bits(w, z, 8, 8), y, 16, 8), x, 24, 8) :
|
||||
_set_bits(_set_bits(_set_bits(x, y, 8, 8), z, 16, 8), w, 24, 8);
|
||||
}
|
||||
|
||||
uint gen_bits(const in uint x, const in uint y, const in bool swap)
|
||||
{
|
||||
return (swap)? _set_bits(y, x, 8, 8) : _set_bits(x, y, 8, 8);
|
||||
}
|
||||
|
||||
// NOTE: (int(n) or int(n)) is broken on some NVIDIA and INTEL hardware when the sign bit is involved.
|
||||
// See https://github.com/RPCS3/rpcs3/issues/8990
|
||||
vec4 sext(const in ivec4 bits)
|
||||
{
|
||||
// convert raw 16 bit values into signed 32-bit float4 counterpart
|
||||
bvec4 sign_check = lessThan(bits, ivec4(0x8000));
|
||||
return _select(bits - 65536, bits, sign_check);
|
||||
}
|
||||
|
||||
float sext(const in int bits)
|
||||
{
|
||||
return (bits < 0x8000) ? float(bits) : float(bits - 65536);
|
||||
}
|
||||
|
||||
vec4 fetch_attribute(const in attribute_desc desc, const in int vertex_id, usamplerBuffer input_stream)
|
||||
{
|
||||
const int elem_size_table[] = { 0, 2, 4, 2, 1, 2, 4, 1 };
|
||||
const float scaling_table[] = { 1., 32767.5, 1., 1., 255., 1., 32767., 1. };
|
||||
const int elem_size = elem_size_table[desc.type];
|
||||
const vec4 scale = scaling_table[desc.type].xxxx;
|
||||
|
||||
uvec4 tmp, result = uvec4(0u);
|
||||
vec4 ret;
|
||||
int n, i = int((vertex_id * desc.stride) + desc.starting_offset);
|
||||
|
||||
for (n = 0; n < desc.attribute_size; n++)
|
||||
{
|
||||
tmp.x = texelFetch(input_stream, i++).x;
|
||||
if (elem_size == 2)
|
||||
{
|
||||
tmp.y = texelFetch(input_stream, i++).x;
|
||||
tmp.x = gen_bits(tmp.x, tmp.y, desc.swap_bytes);
|
||||
}
|
||||
else if (elem_size == 4)
|
||||
{
|
||||
tmp.y = texelFetch(input_stream, i++).x;
|
||||
tmp.z = texelFetch(input_stream, i++).x;
|
||||
tmp.w = texelFetch(input_stream, i++).x;
|
||||
tmp.x = gen_bits(tmp.x, tmp.y, tmp.z, tmp.w, desc.swap_bytes);
|
||||
}
|
||||
|
||||
mov(result, n, tmp.x);
|
||||
}
|
||||
|
||||
// Actual decoding step is done in vector space, outside the loop
|
||||
if (desc.type == VTX_FMT_SNORM16 || desc.type == VTX_FMT_SINT16)
|
||||
{
|
||||
ret = sext(ivec4(result));
|
||||
ret = fma(vec4(0.5), vec4(desc.type == VTX_FMT_SNORM16), ret);
|
||||
}
|
||||
else if (desc.type == VTX_FMT_FLOAT32)
|
||||
{
|
||||
ret = uintBitsToFloat(result);
|
||||
}
|
||||
else if (desc.type == VTX_FMT_FLOAT16)
|
||||
{
|
||||
tmp.x = _set_bits(result.x, result.y, 16, 16);
|
||||
tmp.y = _set_bits(result.z, result.w, 16, 16);
|
||||
ret.xy = unpackHalf2x16(tmp.x);
|
||||
ret.zw = unpackHalf2x16(tmp.y);
|
||||
}
|
||||
else if (elem_size == 1) // (desc.type == VTX_FMT_UINT8 || desc.type == VTX_FMT_UNORM8)
|
||||
{
|
||||
// Ignore bswap on single byte channels
|
||||
ret = vec4(result);
|
||||
}
|
||||
else // if (desc.type == VTX_FMT_COMP32)
|
||||
{
|
||||
result = uvec4(_get_bits(result.x, 0, 11),
|
||||
_get_bits(result.x, 11, 11),
|
||||
_get_bits(result.x, 22, 10),
|
||||
uint(scale.x));
|
||||
ret = sext(ivec4(result) << ivec4(5, 5, 6, 0));
|
||||
}
|
||||
|
||||
if (desc.attribute_size < 4)
|
||||
{
|
||||
ret.w = scale.x;
|
||||
}
|
||||
|
||||
return ret / scale;
|
||||
}
|
||||
|
||||
attribute_desc fetch_desc(const in int location)
|
||||
{
|
||||
// Each descriptor is 64 bits wide
|
||||
// [0-8] attribute stride
|
||||
// [8-24] attribute divisor
|
||||
// [24-27] attribute type
|
||||
// [27-30] attribute size
|
||||
// [30-31] reserved
|
||||
// [32-60] starting offset
|
||||
// [60-61] swap bytes flag
|
||||
// [61-62] volatile flag
|
||||
// [62-63] modulo enable flag;
|
||||
|
||||
#ifdef VULKAN
|
||||
// Fetch parameters streamed separately from draw parameters
|
||||
uvec2 attrib = texelFetch(vertex_layout_stream, location + int(layout_ptr_offset)).xy;
|
||||
#else
|
||||
// Data is packed into a ubo
|
||||
int block = (location >> 1);
|
||||
int sub_block = (location & 1) << 1;
|
||||
uvec2 attrib = uvec2(
|
||||
ref(input_attributes_blob[block], sub_block + 0),
|
||||
ref(input_attributes_blob[block], sub_block + 1));
|
||||
#endif
|
||||
|
||||
attribute_desc result;
|
||||
result.stride = _get_bits(attrib.x, 0, 8);
|
||||
result.frequency = _get_bits(attrib.x, 8, 16);
|
||||
result.type = _get_bits(attrib.x, 24, 3);
|
||||
result.attribute_size = _get_bits(attrib.x, 27, 3);
|
||||
result.starting_offset = _get_bits(attrib.y, 0, 29);
|
||||
result.swap_bytes = _test_bit(attrib.y, 29);
|
||||
result.is_volatile = _test_bit(attrib.y, 30);
|
||||
result.modulo = _test_bit(attrib.y, 31);
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 read_location(const in int location)
|
||||
{
|
||||
attribute_desc desc = fetch_desc(location);
|
||||
int vertex_id = _gl_VertexID - int(vertex_base_index);
|
||||
if (desc.frequency == 0)
|
||||
{
|
||||
vertex_id = 0;
|
||||
}
|
||||
else if (desc.modulo)
|
||||
{
|
||||
// if a vertex modifier is active; vertex_base must be 0 and is ignored
|
||||
vertex_id = (_gl_VertexID + int(vertex_index_offset)) % int(desc.frequency);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex_id /= int(desc.frequency);
|
||||
}
|
||||
|
||||
if (desc.is_volatile)
|
||||
{
|
||||
return fetch_attribute(desc, vertex_id, volatile_input_stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
return fetch_attribute(desc, vertex_id, persistent_input_stream);
|
||||
}
|
||||
}
|
||||
|
||||
)"
|
@ -911,6 +911,7 @@
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\RSXProg\RSXFragmentTextureMSAAOpsInternal.glsl" />
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\RSXProg\RSXFragmentTextureOps.glsl" />
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\RSXProg\RSXProgramCommon.glsl" />
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\RSXProg\RSXVertexFetch.glsl" />
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\RSXProg\RSXVertexPrologue.glsl" />
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\ShuffleBytes.glsl" />
|
||||
</ItemGroup>
|
||||
|
@ -2430,5 +2430,8 @@
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\RSXProg\RSXDefines2.glsl">
|
||||
<Filter>Emu\GPU\RSX\Program\Snippets\RSXProg</Filter>
|
||||
</None>
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\RSXProg\RSXVertexFetch.glsl">
|
||||
<Filter>Emu\GPU\RSX\Program\Snippets\RSXProg</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
x
Reference in New Issue
Block a user