Refactor cg2glsl.py.

This commit is contained in:
Felix Laurie von Massenbach 2015-08-08 20:53:17 +01:00
parent da4cc54b8c
commit f272431b5d
1 changed files with 104 additions and 141 deletions

View File

@ -25,21 +25,18 @@ def log(*arg):
print(*arg) print(*arg)
def remove_comments(source_lines):
ret = []
killed_comments = [line.split('//')[0] for line in source_lines]
for i in filter(lambda line: len(line) > 0, killed_comments):
ret.append(i)
return ret
def keep_line_if(func, lines): def keep_line_if(func, lines):
ret = [] ret = []
for i in filter(func, lines): for line in filter(func, lines):
ret.append(i) ret.append(line)
return ret return ret
def remove_comments(source_lines):
lines_without_comments = [line.split('//')[0] for line in source_lines]
return keep_line_if(lambda line: line, lines_without_comments)
def replace_global_in(source): def replace_global_in(source):
split_source = source.split('\n') split_source = source.split('\n')
replace_table = [ replace_table = [
@ -53,21 +50,20 @@ def replace_global_in(source):
for line in split_source: for line in split_source:
if ('//var' in line) or ('#var' in line): if ('//var' in line) or ('#var' in line):
for index, replace in enumerate(replace_table): for index, replace in enumerate(replace_table):
orig = line.split(' ')[2] orig = line.split()[2]
if replace[0] == orig: if replace[0] == orig:
replace_table[index] = (line.split(':')[2].split(' ')[1], replace_table[index][1]) replace_table[index] = (line.split(':')[2].split(' ')[1], replace_table[index][1])
log('Replace globals:', replace_table) log('Replace globals:', replace_table)
for replace in replace_table: for orig, new in replace_table:
if replace[0]: if orig:
source = source.replace(replace[0], replace[1]) source = source.replace(orig, new)
return source return source
def replace_global_vertex(source): def replace_global_vertex(source):
source = replace_global_in(source) source = replace_global_in(source)
replace_table = [ replace_table = [
('attribute', 'COMPAT_ATTRIBUTE'), ('attribute', 'COMPAT_ATTRIBUTE'),
@ -90,8 +86,8 @@ def replace_global_vertex(source):
('output', 'output_dummy'), # 'output' is reserved in GLSL. ('output', 'output_dummy'), # 'output' is reserved in GLSL.
] ]
for replacement in replace_table: for orig, new in replace_table:
source = source.replace(replacement[0], replacement[1]) source = source.replace(orig, new)
return source return source
@ -142,7 +138,7 @@ def destructify_varyings(source, direction):
struct_types = [] struct_types = []
for line in source[1:]: for line in source[1:]:
if 'struct' in line: if 'struct' in line:
struct_type = line.split(' ')[1] struct_type = line.split()[1]
if struct_type not in struct_types: if struct_type not in struct_types:
struct_types.append(struct_type) struct_types.append(struct_type)
@ -161,7 +157,7 @@ def destructify_varyings(source, direction):
lines = ['COMPAT_VARYING ' + string for string in source[(i + 1):j]] lines = ['COMPAT_VARYING ' + string for string in source[(i + 1):j]]
varyings.extend(lines) varyings.extend(lines)
names = [string.strip().split(' ')[1].split(';')[0].strip() for string in source[(i + 1):j]] names = [string.split()[1].split(';')[0].strip() for string in source[(i + 1):j]]
varyings_name.extend(names) varyings_name.extend(names)
log('Found elements in struct', struct + ':', names) log('Found elements in struct', struct + ':', names)
last_struct_decl_line = j last_struct_decl_line = j
@ -183,16 +179,13 @@ def destructify_varyings(source, direction):
# the actual varyings we just declared ... # the actual varyings we just declared ...
# Globals only come before main() ... # Globals only come before main() ...
# Make sure to only look after all struct declarations as there might be overlap. # Make sure to only look after all struct declarations as there might be overlap.
for line in source[last_struct_decl_line:]: for line in remove_comments(source[last_struct_decl_line:]):
if 'void main()' in line: if 'void main()' in line:
break break
for struct in struct_types: for struct in struct_types:
if struct in line: if struct in line:
decomment_line = line.split('//')[0].strip() variable = line.split()[1].split(';')[0]
if len(decomment_line) == 0:
continue
variable = decomment_line.split(' ')[1].split(';')[0]
# Only redirect if the struct is actually used as vertex output. # Only redirect if the struct is actually used as vertex output.
for vout_line in vout_lines: for vout_line in vout_lines:
@ -218,7 +211,7 @@ def destructify_varyings(source, direction):
for varying_name in varyings_dict: for varying_name in varyings_dict:
trans_from = variable + '.' + varying_name trans_from = variable + '.' + varying_name
trans_to = varyings_dict[varying_name] trans_to = varyings_dict[varying_name]
source[index] = source[index].replace(trans_from, trans_to); source[index] = source[index].replace(trans_from, trans_to)
for index, _ in enumerate(source): for index, _ in enumerate(source):
for varying_name in varyings_name: for varying_name in varyings_name:
@ -337,19 +330,19 @@ def replace_varyings(source):
uniforms = [] uniforms = []
for index, line in enumerate(source): for index, line in enumerate(source):
if (('//var' in line) or ('#var' in line)) and ('$vin.' in line): if (('//var' in line) or ('#var' in line)) and ('$vin.' in line):
orig = line.split(' ')[2] orig = line.split()[2]
translated = translate_varying(orig) translated = translate_varying(orig)
if translated != orig and translated not in attribs: if translated != orig and translated not in attribs:
cg_attrib = line.split(':')[2].split(' ')[1] cg_attrib = line.split(':')[2].split(' ')[1]
if len(cg_attrib.strip()) > 0: if cg_attrib:
translations.append((cg_attrib, translated)) translations.append((cg_attrib, translated))
attribs.append(translated) attribs.append(translated)
elif ('//var' in line) or ('#var' in line): elif ('//var' in line) or ('#var' in line):
orig = line.split(' ')[2] orig = line.split()[2]
translated = translate_texture_size(orig) translated = translate_texture_size(orig)
if translated != orig and translated not in uniforms: if translated != orig and translated not in uniforms:
cg_uniform = line.split(':')[2].split(' ')[1] cg_uniform = line.split(':')[2].split(' ')[1]
if len(cg_uniform.strip()) > 0: if cg_uniform:
translations.append((cg_uniform, translated)) translations.append((cg_uniform, translated))
uniforms.append(translated) uniforms.append(translated)
@ -372,6 +365,51 @@ def replace_varyings(source):
return ret return ret
def fix_samplers(log_prefix, ref_index, source):
translations = []
added_samplers = []
translated_samplers = []
uniforms = []
struct_texunit0 = False # If True, we have to append uniform sampler2D Texture manually ...
for line in source:
if ('TEXUNIT0' in line) and ('semantic' not in line):
main_sampler = (line.split(':')[2].split(' ')[1], 'Texture')
if main_sampler[0]:
translations.append(main_sampler)
log(log_prefix, 'Sampler:', main_sampler[0], '->', main_sampler[1])
struct_texunit0 = '.' in main_sampler[0]
elif ('//var sampler2D' in line) or ('#var sampler2D' in line):
cg_texture = line.split()[2]
translated = translate_texture(cg_texture)
orig_name = translated
new_name = line.split(':')[2].split(' ')[1]
log(log_prefix, 'Sampler:', new_name, '->', orig_name)
if new_name:
if translated != cg_texture and translated not in translated_samplers:
translated_samplers.append(translated)
added_samplers.append('uniform sampler2D ' + translated + ';')
translations.append((new_name, orig_name))
elif ('//var' in line) or ('#var' in line):
orig = line.split()[2]
translated = translate_texture_size(orig)
if translated != orig and translated not in uniforms:
cg_uniform = line.split(':')[2].split(' ')[1]
if cg_uniform:
translations.append((cg_uniform, translated))
uniforms.append(translated)
for sampler in added_samplers:
source.insert(ref_index, sampler)
if struct_texunit0:
source.insert(ref_index, 'uniform sampler2D Texture;')
for index, line in enumerate(source):
for orig, new in translations:
log(log_prefix, 'Translation:', orig, '->', new)
source[index] = source[index].replace(orig, new)
return source
def hack_source_vertex(source): def hack_source_vertex(source):
ref_index = 0 ref_index = 0
for index, line in enumerate(source): for index, line in enumerate(source):
@ -387,37 +425,7 @@ def hack_source_vertex(source):
break break
# Fix samplers in vertex shader (supported by GLSL). # Fix samplers in vertex shader (supported by GLSL).
translations = [] source = fix_samplers('Vertex:', ref_index, source)
added_samplers = []
translated_samplers = []
struct_texunit0 = False # If True, we have to append uniform sampler2D Texture manually ...
for line in source:
if ('TEXUNIT0' in line) and ('semantic' not in line):
main_sampler = (line.split(':')[2].split(' ')[1], 'Texture')
if len(main_sampler[0]) > 0:
translations.append(main_sampler)
log('Vertex: Sampler:', main_sampler[0], '->', main_sampler[1])
struct_texunit0 = '.' in main_sampler[0]
elif ('//var sampler2D' in line) or ('#var sampler2D' in line):
cg_texture = line.split(' ')[2]
translated = translate_texture(cg_texture)
orig_name = translated
new_name = line.split(':')[2].split(' ')[1]
log('Vertex: Sampler:', new_name, '->', orig_name)
if len(new_name) > 0:
if translated != cg_texture and translated not in translated_samplers:
translated_samplers.append(translated)
added_samplers.append('uniform sampler2D ' + translated + ';')
translations.append((new_name, orig_name))
for sampler in added_samplers:
source.insert(ref_index, sampler)
if struct_texunit0:
source.insert(ref_index, 'uniform sampler2D Texture;')
for index, line in enumerate(source):
for translation in translations:
source[index] = source[index].replace(translation[0], translation[1])
source = destructify_varyings(source, '$vout.') source = destructify_varyings(source, '$vout.')
source = replace_varyings(source) source = replace_varyings(source)
return source return source
@ -487,54 +495,9 @@ def hack_source_fragment(source):
ref_index = index ref_index = index
break break
translations = [] source = fix_samplers('Fragment:', ref_index, source)
added_samplers = [] source = destructify_varyings(source, '$vin.')
translated_samplers = [] return source
uniforms = []
struct_texunit0 = False # If True, we have to append uniform sampler2D Texture manually ...
for line in source:
if ('TEXUNIT0' in line) and ('semantic' not in line):
main_sampler = (line.split(':')[2].split(' ')[1], 'Texture')
if len(main_sampler[0]) > 0:
translations.append(main_sampler)
log('Fragment: Sampler:', main_sampler[0], '->', main_sampler[1])
struct_texunit0 = '.' in main_sampler[0]
elif ('//var sampler2D' in line) or ('#var sampler2D' in line):
cg_texture = line.split(' ')[2]
translated = translate_texture(cg_texture)
orig_name = translated
new_name = line.split(':')[2].split(' ')[1]
log('Fragment: Sampler:', new_name, '->', orig_name)
if len(new_name) > 0:
if translated != cg_texture and translated not in translated_samplers:
translated_samplers.append(translated)
added_samplers.append('uniform sampler2D ' + translated + ';')
translations.append((new_name, orig_name))
elif ('//var' in line) or ('#var' in line):
orig = line.split(' ')[2]
translated = translate_texture_size(orig)
if translated != orig and translated not in uniforms:
cg_uniform = line.split(':')[2].split(' ')[1]
if len(cg_uniform.strip()) > 0:
translations.append((cg_uniform, translated))
uniforms.append(translated)
for sampler in added_samplers:
source.insert(ref_index, sampler)
for uniform in uniforms:
source.insert(ref_index, 'uniform COMPAT_PRECISION vec2 ' + uniform + ';')
if struct_texunit0:
source.insert(ref_index, 'uniform sampler2D Texture;')
ret = []
for line in source:
for translation in translations:
log('Translation:', translation[0], '->', translation[1])
line = line.replace(translation[0], translation[1])
ret.append(line)
ret = destructify_varyings(ret, '$vin.')
return ret
def validate_shader(source, target): def validate_shader(source, target):