| #version 450 |
| #extension GL_ARB_separate_shader_objects : enable |
| |
| layout(std140, set = 0, binding = 0) uniform VertexBuffer |
| { |
| mat4 scale_offset_mat; |
| uint vertex_base_index; |
| ivec4 input_attributes[16]; |
| }; |
| layout(set=0, binding=3) uniform usamplerBuffer buff_in_1; |
| layout(set=0, binding=4) uniform usamplerBuffer buff_in_2; |
| |
| layout(location=10) out vec4 back_color; |
| layout(location=0) out vec4 tc0; |
| |
| layout(std140, set=0, binding = 1) uniform VertexConstantsBuffer |
| { |
| vec4 vc[16]; |
| }; |
| |
| struct attr_desc |
| { |
| int type; |
| int attribute_size; |
| int starting_offset; |
| int stride; |
| int swap_bytes; |
| int is_volatile; |
| }; |
| |
| uint get_bits(uvec4 v, int swap) |
| { |
| if (swap != 0) return (v.w | v.z << 8 | v.y << 16 | v.x << 24); |
| return (v.x | v.y << 8 | v.z << 16 | v.w << 24); |
| } |
| |
| vec4 fetch_attr(attr_desc desc, int vertex_id, usamplerBuffer input_stream) |
| { |
| vec4 result = vec4(0.0f, 0.0f, 0.0f, 1.0f); |
| uvec4 tmp; |
| uint bits; |
| bool reverse_order = false; |
| |
| int first_byte = (vertex_id * desc.stride) + desc.starting_offset; |
| for (int n = 0; n < 4; n++) |
| { |
| if (n == desc.attribute_size) break; |
| |
| switch (desc.type) |
| { |
| case 0: |
| //signed normalized 16-bit |
| tmp.x = texelFetch(input_stream, first_byte++).x; |
| tmp.y = texelFetch(input_stream, first_byte++).x; |
| result[n] = get_bits(tmp, desc.swap_bytes); |
| break; |
| case 1: |
| //float |
| tmp.x = texelFetch(input_stream, first_byte++).x; |
| tmp.y = texelFetch(input_stream, first_byte++).x; |
| tmp.z = texelFetch(input_stream, first_byte++).x; |
| tmp.w = texelFetch(input_stream, first_byte++).x; |
| result[n] = uintBitsToFloat(get_bits(tmp, desc.swap_bytes)); |
| break; |
| case 2: |
| //unsigned byte |
| result[n] = texelFetch(input_stream, first_byte++).x; |
| reverse_order = (desc.swap_bytes != 0); |
| break; |
| } |
| } |
| |
| return (reverse_order)? result.wzyx: result; |
| } |
| |
| attr_desc fetch_desc(int location) |
| { |
| attr_desc result; |
| int attribute_flags = input_attributes[location].w; |
| result.type = input_attributes[location].x; |
| result.attribute_size = input_attributes[location].y; |
| result.starting_offset = input_attributes[location].z; |
| result.stride = attribute_flags & 0xFF; |
| result.swap_bytes = (attribute_flags >> 8) & 0x1; |
| result.is_volatile = (attribute_flags >> 9) & 0x1; |
| return result; |
| } |
| |
| vec4 read_location(int location) |
| { |
| attr_desc desc = fetch_desc(location); |
| |
| int vertex_id = gl_VertexIndex - int(vertex_base_index); |
| if (desc.is_volatile != 0) |
| return fetch_attr(desc, vertex_id, buff_in_2); |
| else |
| return fetch_attr(desc, vertex_id, buff_in_1); |
| } |
| |
| void vs_adjust(inout vec4 dst_reg0, inout vec4 dst_reg1, inout vec4 dst_reg7) |
| { |
| vec4 tmp0; |
| vec4 tmp1; |
| vec4 in_diff_color= read_location(3); |
| vec4 in_pos= read_location(0); |
| vec4 in_tc0= read_location(8); |
| dst_reg1 = (in_diff_color * vc[13]); |
| tmp0.x = vec4(dot(vec4(in_pos.xyzx.xyz, 1.0), vc[4])).x; |
| tmp0.y = vec4(dot(vec4(in_pos.xyzx.xyz, 1.0), vc[5])).y; |
| tmp0.z = vec4(dot(vec4(in_pos.xyzx.xyz, 1.0), vc[6])).z; |
| tmp1.xy = in_tc0.xyxx.xy; |
| tmp1.z = vc[15].xxxx.z; |
| dst_reg7.y = vec4(dot(vec4(tmp1.xyzx.xyz, 1.0), vc[8])).y; |
| dst_reg7.x = vec4(dot(vec4(tmp1.xyzx.xyz, 1.0), vc[7])).x; |
| dst_reg0.y = vec4(dot(vec4(tmp0.xyzx.xyz, 1.0), vc[1])).y; |
| dst_reg0.x = vec4(dot(vec4(tmp0.xyzx.xyz, 1.0), vc[0])).x; |
| } |
| |
| void main () |
| { |
| vec4 dst_reg0= vec4(0.0f, 0.0f, 0.0f, 1.0f); |
| vec4 dst_reg1= vec4(0.0, 0.0, 0.0, 0.0); |
| vec4 dst_reg7= vec4(0.0, 0.0, 0.0, 0.0); |
| |
| vs_adjust(dst_reg0, dst_reg1, dst_reg7); |
| |
| gl_Position = dst_reg0; |
| back_color = dst_reg1; |
| tc0 = dst_reg7; |
| gl_Position = gl_Position * scale_offset_mat; |
| } |
| |