vk/gl: Factorize shared GLSL code

- prep vulkan for shared glsl backend
This commit is contained in:
kd-11 2017-08-04 17:11:39 +03:00
parent c0409a819e
commit 6a707f515e
14 changed files with 294 additions and 372 deletions

View file

@ -9,7 +9,7 @@
std::string GLVertexDecompilerThread::getFloatTypeName(size_t elementCount)
{
return getFloatTypeNameImpl(elementCount);
return glsl::getFloatTypeNameImpl(elementCount);
}
std::string GLVertexDecompilerThread::getIntTypeName(size_t elementCount)
@ -25,7 +25,7 @@ std::string GLVertexDecompilerThread::getFunction(FUNCTION f)
std::string GLVertexDecompilerThread::compareFunction(COMPARE f, const std::string &Op0, const std::string &Op1)
{
return compareFunctionImpl(f, Op0, Op1);
return glsl::compareFunctionImpl(f, Op0, Op1);
}
void GLVertexDecompilerThread::insertHeader(std::stringstream &OS)
@ -151,193 +151,13 @@ void GLVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::
namespace
{
std::string expand_to_vec4(std::string value, u8 vector_size)
{
switch (vector_size)
{
case 2:
return "vec4(" + value + ", " + value + ", 1., 1.)";
case 3:
return "vec4(" + value + ", " + value + ", " + value + ", 1.)";
default:
LOG_ERROR(RSX, "invalid vector size %d" HERE, vector_size);
case 1:
case 4:
//Expand not required
//In case its one component, read is swizzled as .xxxx (GOW1 loading screen)
return value;
}
}
void insert_vertex_input_fetch(std::stringstream& OS)
{
//Actually decode a vertex attribute from a raw byte stream
OS << "struct attribute_desc\n";
OS << "{\n";
OS << " int type;\n";
OS << " int attribute_size;\n";
OS << " int starting_offset;\n";
OS << " int stride;\n";
OS << " int swap_bytes;\n";
OS << " int is_volatile;\n";
OS << " int frequency;\n";
OS << " int divisor;\n";
OS << " int modulo;\n";
OS << "};\n\n";
OS << "uint get_bits(uvec4 v, int swap)\n";
OS << "{\n";
OS << " if (swap != 0) return (v.w | v.z << 8 | v.y << 16 | v.x << 24);\n";
OS << " return (v.x | v.y << 8 | v.z << 16 | v.w << 24);\n";
OS << "}\n\n";
OS << "uint get_bits(uvec2 v, int swap)\n";
OS << "{\n";
OS << " if (swap != 0) return (v.y | v.x << 8);\n";
OS << " return (v.x | v.y << 8);\n";
OS << "}\n\n";
OS << "int preserve_sign_s16(uint bits)\n";
OS << "{\n";
OS << " //convert raw 16 bit value into signed 32-bit integer counterpart\n";
OS << " uint sign = bits & 0x8000;\n";
OS << " if (sign != 0) return int(bits | 0xFFFF0000);\n";
OS << " return int(bits);\n";
OS << "}\n\n";
OS << "float convert_to_f32(uint bits)\n";
OS << "{\n";
OS << " uint sign = (bits >> 31) & 1;\n";
OS << " uint exp = (bits >> 23) & 0xff;\n";
OS << " uint mantissa = bits & 0x7fffff;\n";
OS << " float base = (sign != 0)? -1.f: 1.f;\n";
OS << " base *= exp2(exp - 127);\n";
OS << " float scale = 0.f;\n\n";
OS << " for (int x = 0; x < 23; x++)\n";
OS << " {\n";
OS << " int inv = (22 - x);\n";
OS << " if ((mantissa & (1 << inv)) == 0) continue;\n";
OS << " scale += 1.f / pow(2.f, float(inv));\n";
OS << " }\n";
OS << " return base * scale;\n";
OS << "}\n";
OS << "#define get_s16(v, s) preserve_sign_s16(get_bits(v, s))\n\n";
OS << "vec4 fetch_attribute(attribute_desc desc, int vertex_id, usamplerBuffer input_stream)\n";
OS << "{\n";
OS << " vec4 result = vec4(0., 0., 0., 1.);\n";
OS << " vec4 scale = vec4(1.);\n";
OS << " uvec4 tmp;\n";
OS << " uint bits;\n";
OS << " bool reverse_order = false;\n";
OS << "\n";
OS << " int first_byte = (vertex_id * desc.stride) + desc.starting_offset;\n";
OS << " for (int n = 0; n < desc.attribute_size; n++)\n";
OS << " {\n";
OS << " switch (desc.type)\n";
OS << " {\n";
OS << " case 0:\n";
OS << " //signed normalized 16-bit\n";
OS << " tmp[0] = texelFetch(input_stream, first_byte++).x;\n";
OS << " tmp[1] = texelFetch(input_stream, first_byte++).x;\n";
OS << " result[n] = get_s16(tmp.xy, desc.swap_bytes);\n";
OS << " scale[n] = 32767.;\n";
OS << " break;\n";
OS << " case 1:\n";
OS << " //float\n";
OS << " tmp[0] = texelFetch(input_stream, first_byte++).x;\n";
OS << " tmp[1] = texelFetch(input_stream, first_byte++).x;\n";
OS << " tmp[2] = texelFetch(input_stream, first_byte++).x;\n";
OS << " tmp[3] = texelFetch(input_stream, first_byte++).x;\n";
OS << " result[n] = uintBitsToFloat(get_bits(tmp, desc.swap_bytes));\n";
OS << " break;\n";
OS << " case 2:\n";
OS << " //half\n";
OS << " tmp[0] = texelFetch(input_stream, first_byte++).x;\n";
OS << " tmp[1] = texelFetch(input_stream, first_byte++).x;\n";
OS << " result[n] = unpackHalf2x16(uint(get_bits(tmp.xy, desc.swap_bytes))).x;\n";
OS << " break;\n";
OS << " case 3:\n";
OS << " //unsigned byte\n";
OS << " result[n] = texelFetch(input_stream, first_byte++).x;\n";
OS << " scale[n] = 255.;\n";
OS << " reverse_order = (desc.swap_bytes != 0);\n";
OS << " break;\n";
OS << " case 4:\n";
OS << " //signed word\n";
OS << " tmp[0] = texelFetch(input_stream, first_byte++).x;\n";
OS << " tmp[1] = texelFetch(input_stream, first_byte++).x;\n";
OS << " result[n] = get_s16(tmp.xy, desc.swap_bytes);\n";
OS << " break;\n";
OS << " case 5:\n";
OS << " //cmp\n";
OS << " tmp[0] = texelFetch(input_stream, first_byte++).x;\n";
OS << " tmp[1] = texelFetch(input_stream, first_byte++).x;\n";
OS << " tmp[2] = texelFetch(input_stream, first_byte++).x;\n";
OS << " tmp[3] = texelFetch(input_stream, first_byte++).x;\n";
OS << " bits = get_bits(tmp, desc.swap_bytes);\n";
OS << " result.x = preserve_sign_s16((bits & 0x7FF) << 5);\n";
OS << " result.y = preserve_sign_s16(((bits >> 11) & 0x7FF) << 5);\n";
OS << " result.z = preserve_sign_s16(((bits >> 22) & 0x3FF) << 6);\n";
OS << " result.w = 1.;\n";
OS << " scale = vec4(32767., 32767., 32767., 1.);\n";
OS << " break;\n";
OS << " case 6:\n";
OS << " //ub256\n";
OS << " result[n] = float(texelFetch(input_stream, first_byte++).x);\n";
OS << " reverse_order = (desc.swap_bytes != 0);\n";
OS << " break;\n";
OS << " }\n";
OS << " }\n\n";
OS << " result /= scale;\n";
OS << " return (reverse_order)? result.wzyx: result;\n";
OS << "}\n\n";
OS << "attribute_desc fetch_desc(int location)\n";
OS << "{\n";
OS << " attribute_desc result;\n";
OS << " int attribute_flags = input_attributes[location].w;\n";
OS << " result.type = input_attributes[location].x;\n";
OS << " result.attribute_size = input_attributes[location].y;\n";
OS << " result.starting_offset = input_attributes[location].z;\n";
OS << " result.stride = attribute_flags & 0xFF;\n";
OS << " result.swap_bytes = (attribute_flags >> 8) & 0x1;\n";
OS << " result.is_volatile = (attribute_flags >> 9) & 0x1;\n";
OS << " result.frequency = (attribute_flags >> 10) & 0x3;\n";
OS << " result.modulo = (attribute_flags >> 12) & 0x1;\n";
OS << " result.divisor = (attribute_flags >> 13) & 0xFFFF;\n";
OS << " return result;\n";
OS << "}\n\n";
OS << "vec4 read_location(int location)\n";
OS << "{\n";
OS << " attribute_desc desc = fetch_desc(location);\n";
OS << "\n";
OS << " int vertex_id = gl_VertexID - int(vertex_base_index);\n";
OS << " if (desc.frequency == 0)\n";
OS << " vertex_id = 0;\n";
OS << " else if (desc.frequency > 1)\n";
OS << " {\n";
OS << " //if a vertex modifier is active; vertex_base must be 0 and is ignored\n";
OS << " if (desc.modulo != 0)\n";
OS << " vertex_id = gl_VertexID % desc.divisor;\n";
OS << " else\n";
OS << " vertex_id = gl_VertexID / desc.divisor;\n";
OS << " }\n";
OS << "\n";
OS << " if (desc.is_volatile != 0)\n";
OS << " return fetch_attribute(desc, vertex_id, volatile_input_stream);\n";
OS << " else\n";
OS << " return fetch_attribute(desc, vertex_id, persistent_input_stream);\n";
OS << "}\n\n";
}
}
void GLVertexDecompilerThread::insertMainStart(std::stringstream & OS)
{
insert_glsl_legacy_function(OS, gl::glsl::glsl_vertex_program);
insert_vertex_input_fetch(OS);
insert_glsl_legacy_function(OS, glsl::glsl_vertex_program);
glsl::insert_vertex_input_fetch(OS);
std::string parameters = "";
for (int i = 0; i < 16; ++i)