mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-29 06:51:10 +00:00
1a85d569e3
This heaves over an inital chunk of code from the Vulkan renderer to execute shaders. The only shader that exists for now is a shader that draws a single texture. We use that to replace the blit op we were doing before.
292 lines
11 KiB
Python
292 lines
11 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
import re
|
|
import os
|
|
|
|
name = os.path.splitext(os.path.splitext(os.path.basename(sys.argv[1]))[0])[0][6:]
|
|
var_name = "gsk_gpu_" + name.replace('-', '_')
|
|
struct_name = "GskGpu" + name.title().replace('-', '') + "Instance"
|
|
|
|
with open(sys.argv[1]) as f:
|
|
lines = f.readlines()
|
|
matches = []
|
|
|
|
for line in lines:
|
|
match = re.search(r"^IN\(([0-9]+)\) ([a-z0-9]+) ([a-zA-Z0-9_]+);$", line)
|
|
if not match:
|
|
if re.search(r"layout.*\sin\s.*", line):
|
|
raise Exception("Failed to parse file")
|
|
continue
|
|
if not match.group(3).startswith('in'):
|
|
raise Exception("Variable doesn't start with 'in'")
|
|
matches.append({'name': ''.join('_' + char.lower() if char.isupper() else char for char in match.group(3))[3:],
|
|
'location': int(match.group(1)),
|
|
'type': match.group(2)})
|
|
|
|
print(f'''/* This file is auto-generated; any change will not be preserved */
|
|
#pragma once
|
|
|
|
typedef struct _{struct_name} {struct_name};
|
|
|
|
struct _{struct_name} {{''')
|
|
|
|
expected = 0
|
|
for match in matches:
|
|
if expected != int(match['location']):
|
|
raise Exception(f"Should be layout location {expected} but is {match['location']}") # noqa
|
|
|
|
if match['type'] == 'float':
|
|
print(f" float {match['name']};")
|
|
expected += 1
|
|
elif match['type'] == 'int':
|
|
print(f" gint32 {match['name']};")
|
|
expected += 1
|
|
elif match['type'] == 'uint':
|
|
print(f" guint32 {match['name']};")
|
|
expected += 1
|
|
elif match['type'] == 'uvec2':
|
|
print(f" guint32 {match['name']}[2];")
|
|
expected += 1
|
|
elif match['type'] == 'vec2':
|
|
print(f" float {match['name']}[2];")
|
|
expected += 1
|
|
elif match['type'] == 'vec4':
|
|
print(f" float {match['name']}[4];")
|
|
expected += 1
|
|
elif match['type'] == 'mat3x4':
|
|
print(f" float {match['name']}[12];")
|
|
expected += 3
|
|
elif match['type'] == 'mat4':
|
|
print(f" float {match['name']}[16];")
|
|
expected += 4
|
|
else:
|
|
raise Exception(f"Don't know what a {match['type']} is")
|
|
|
|
print(f'''}};
|
|
''')
|
|
|
|
print(f'''static inline void
|
|
{var_name}_setup_vao (gsize offset)
|
|
{{''')
|
|
for i, match in enumerate(matches):
|
|
if match['type'] == 'float':
|
|
print(f''' glEnableVertexAttribArray ({match['location']});
|
|
glVertexAttribDivisor ({match['location']}, 1);
|
|
glVertexAttribPointer ({match['location']},
|
|
1,
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
sizeof ({struct_name}),
|
|
GSIZE_TO_POINTER (offset + G_STRUCT_OFFSET({struct_name}, {match['name']})));''');
|
|
elif match['type'] == 'uint':
|
|
print(f''' glEnableVertexAttribArray ({match['location']});
|
|
glVertexAttribDivisor ({match['location']}, 1);
|
|
glVertexAttribIPointer ({match['location']},
|
|
1,
|
|
GL_UNSIGNED_INT,
|
|
sizeof ({struct_name}),
|
|
GSIZE_TO_POINTER (offset + G_STRUCT_OFFSET({struct_name}, {match['name']})));''');
|
|
elif match['type'] == 'uvec2':
|
|
print(f''' glEnableVertexAttribArray ({match['location']});
|
|
glVertexAttribDivisor ({match['location']}, 1);
|
|
glVertexAttribIPointer ({match['location']},
|
|
2,
|
|
GL_UNSIGNED_INT,
|
|
sizeof ({struct_name}),
|
|
GSIZE_TO_POINTER (offset + G_STRUCT_OFFSET({struct_name}, {match['name']})));''');
|
|
elif match['type'] == 'vec2':
|
|
print(f''' glEnableVertexAttribArray ({match['location']});
|
|
glVertexAttribDivisor ({match['location']}, 1);
|
|
glVertexAttribPointer ({match['location']},
|
|
2,
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
sizeof ({struct_name}),
|
|
GSIZE_TO_POINTER (offset + G_STRUCT_OFFSET({struct_name}, {match['name']})));''');
|
|
elif match['type'] == 'vec4':
|
|
print(f''' glEnableVertexAttribArray ({match['location']});
|
|
glVertexAttribDivisor ({match['location']}, 1);
|
|
glVertexAttribPointer ({match['location']},
|
|
4,
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
sizeof ({struct_name}),
|
|
GSIZE_TO_POINTER (offset + G_STRUCT_OFFSET({struct_name}, {match['name']})));''');
|
|
elif match['type'] == 'mat3x4':
|
|
print(f''' glEnableVertexAttribArray ({match['location']});
|
|
glVertexAttribDivisor ({match['location']}, 1);
|
|
glVertexAttribPointer ({match['location']},
|
|
4,
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
sizeof ({struct_name}),
|
|
GSIZE_TO_POINTER (offset + G_STRUCT_OFFSET({struct_name}, {match['name']})));
|
|
glEnableVertexAttribArray ({int(match['location'] + 1)});
|
|
glVertexAttribDivisor ({int(match['location'] + 1)}, 1);
|
|
glVertexAttribPointer ({int(match['location']) + 1},
|
|
4,
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
sizeof ({struct_name}),
|
|
GSIZE_TO_POINTER (offset + G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 4));
|
|
glEnableVertexAttribArray ({int(match['location'] + 2)});
|
|
glVertexAttribDivisor ({int(match['location'] + 2)}, 1);
|
|
glVertexAttribPointer ({int(match['location']) + 2},
|
|
4,
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
sizeof ({struct_name}),
|
|
GSIZE_TO_POINTER (offset + G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 8));''')
|
|
elif match['type'] == 'mat4':
|
|
print(f''' glEnableVertexAttribArray ({match['location']});
|
|
glVertexAttribDivisor ({match['location']}, 1);
|
|
glVertexAttribPointer ({match['location']},
|
|
4,
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
sizeof ({struct_name}),
|
|
GSIZE_TO_POINTER (offset + G_STRUCT_OFFSET({struct_name}, {match['name']})));
|
|
glEnableVertexAttribArray ({int(match['location'] + 1)});
|
|
glVertexAttribDivisor ({int(match['location'] + 1)}, 1);
|
|
glVertexAttribPointer ({int(match['location']) + 1},
|
|
4,
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
sizeof ({struct_name}),
|
|
GSIZE_TO_POINTER (offset + G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 4));
|
|
glEnableVertexAttribArray ({int(match['location'] + 2)});
|
|
glVertexAttribDivisor ({int(match['location'] + 2)}, 1);
|
|
glVertexAttribPointer ({int(match['location']) + 2},
|
|
4,
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
sizeof ({struct_name}),
|
|
GSIZE_TO_POINTER (offset + G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 8));
|
|
glEnableVertexAttribArray ({int(match['location'] + 3)});
|
|
glVertexAttribDivisor ({int(match['location'] + 3)}, 1);
|
|
glVertexAttribPointer ({int(match['location']) + 3},
|
|
4,
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
sizeof ({struct_name}),
|
|
GSIZE_TO_POINTER (offset + G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 12));''')
|
|
else:
|
|
raise Exception(f"Don't know what a {match['type']} is")
|
|
|
|
print(f'''}}
|
|
|
|
''');
|
|
|
|
print(f'''#ifdef GDK_RENDERING_VULKAN
|
|
|
|
static const VkPipelineVertexInputStateCreateInfo {var_name}_info = {{
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
|
.vertexBindingDescriptionCount = 1,
|
|
.pVertexBindingDescriptions = (VkVertexInputBindingDescription[1]) {{
|
|
{{
|
|
.binding = 0,
|
|
.stride = sizeof ({struct_name}),
|
|
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
|
|
}}
|
|
}},
|
|
.vertexAttributeDescriptionCount = {expected},
|
|
.pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[{expected}]) {{''')
|
|
|
|
for match in matches:
|
|
if match['type'] == 'float':
|
|
print(f''' {{
|
|
.location = {match['location']},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32_SFLOAT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
|
|
}},''')
|
|
elif match['type'] == 'int':
|
|
print(f''' {{
|
|
.location = {match['location']},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32_SINT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
|
|
}},''')
|
|
|
|
elif match['type'] == 'uint':
|
|
print(f''' {{
|
|
.location = {match['location']},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32_UINT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
|
|
}},''')
|
|
elif match['type'] == 'uvec2':
|
|
print(f''' {{
|
|
.location = {match['location']},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32G32_UINT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
|
|
}},''')
|
|
elif match['type'] == 'vec2':
|
|
print(f''' {{
|
|
.location = {match['location']},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32G32_SFLOAT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
|
|
}},''')
|
|
elif match['type'] == 'vec4':
|
|
print(f''' {{
|
|
.location = {match['location']},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
|
|
}},''')
|
|
elif match['type'] == 'mat3x4':
|
|
print(f''' {{
|
|
.location = {match['location']},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
|
|
}},
|
|
{{
|
|
.location = {int(match['location']) + 1},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 4,
|
|
}},
|
|
{{
|
|
.location = {int(match['location']) + 2},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 8,
|
|
}},''')
|
|
elif match['type'] == 'mat4':
|
|
print(f''' {{
|
|
.location = {match['location']},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}),
|
|
}},
|
|
{{
|
|
.location = {int(match['location']) + 1},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 4,
|
|
}},
|
|
{{
|
|
.location = {int(match['location']) + 2},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 8,
|
|
}},
|
|
{{
|
|
.location = {int(match['location']) + 3},
|
|
.binding = 0,
|
|
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
.offset = G_STRUCT_OFFSET({struct_name}, {match['name']}) + sizeof (float) * 12,
|
|
}},''')
|
|
else:
|
|
raise Exception(f"Don't know what a {match['type']} is")
|
|
|
|
print(f''' }},
|
|
}};
|
|
|
|
#endif
|
|
''');
|