From d5b58d96da44967367dedb2b469f26fd45ce88cf Mon Sep 17 00:00:00 2001 From: CakeLancelot Date: Tue, 13 Feb 2024 03:17:25 -0600 Subject: [PATCH] dx2cg: Implement RECT, CUBE texture types Also tried to implement 3D texture type, but that will likely require a few other instructions to get working - namely texldp and dcl_volume. --- dx2cg/disassembler.py | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/dx2cg/disassembler.py b/dx2cg/disassembler.py index d3c1556..42d9a85 100644 --- a/dx2cg/disassembler.py +++ b/dx2cg/disassembler.py @@ -54,7 +54,7 @@ ops = { "slt": "{0} = float4(({1}.x < {2}.x) ? 1.0f : 0.0f, ({1}.y < {2}.y) ? 1.0f : 0.0f, ({1}.z < {2}.z) ? 1.0f : 0.0f, ({1}.w < {2}.w) ? 1.0f : 0.0f);", "sge": "{0} = float4(({1}.x >= {2}.x) ? 1.0f : 0.0f, ({1}.y >= {2}.y) ? 1.0f : 0.0f, ({1}.z >= {2}.z) ? 1.0f : 0.0f, ({1}.w >= {2}.w) ? 1.0f : 0.0f);", "rcp": "{0} = ({1} == 0.0f) ? FLT_MAX : (({1} == 1.0f) ? {1} : (1 / {1}));", - "texld": "{0} = tex2D({2}, (float2){1});", + "texld": "{0} = {3}({2}, (float2){1});", } struct_a2v = """struct a2v { @@ -186,12 +186,21 @@ def process_header(prog): i = i - 1 elif line.startswith("SetTexture"): dec = line.split(' ') - if dec[2] != "{2D}": + texture_type = None + if dec[2] == "{2D}": + texture_type = "sampler2D" + elif dec[2] == "{3D}": + texture_type = "sampler3D" + elif dec[2] == "{RECT}": + texture_type = "samplerRECT" + elif dec[2] == "{CUBE}": + texture_type = "samplerCUBE" + else: raise ValueError(f"Unknown texture type {dec[2]}") key = f"s{textures}" val = dec[1][1:-1] loctab[key] = val - locdecl.append(f"sampler2D {val};") + locdecl.append(f"{texture_type} {val};") textures = textures + 1 del prog[i] @@ -218,7 +227,6 @@ def resolve_args(args, loctab, consts): arg = arg[:dot] else: swiz = "" - if arg[0] == 'r': pass elif arg[0] == 'v': @@ -239,7 +247,7 @@ def resolve_args(args, loctab, consts): args[a] = neg + arg + swiz -def decode(code, args): +def decode(code, args, locdecl): if code in decls: return [decls[code].format(*args)] elif code in ops: @@ -254,14 +262,31 @@ def decode(code, args): else: swiz = "xyzw" - lines = [ops[code].format("tmp", *args[1:])] + lines = [] + if code == "texld": + cg_tex_type = None + for loc in locdecl: + loc = loc.split(' ') + if args[2] == loc[1][:-1]: + if loc[0] == 'sampler2D': + cg_tex_type = "tex2D" + elif loc[0] == 'sampler3D': + cg_tex_type = "tex3D" + elif loc[0] == 'samplerCUBE': + cg_tex_type = "texCUBE" + elif loc[0] == 'samplerRECT': + cg_tex_type = "texRECT" + lines = [ops[code].format("tmp", *args[1:], cg_tex_type)] + else: + lines = [ops[code].format("tmp", *args[1:])] + for c in swiz: lines.append(f"{target}.{c} = tmp.{c};") return lines else: raise ValueError(f"Unknown opcode {code}") -def process_asm(asm, loctab): +def process_asm(asm, loctab, locdecl): shadertype = "" if asm[0] == "\"vs_1_1": shadertype = "vertex" @@ -294,7 +319,7 @@ def process_asm(asm, loctab): code = code[:pp] resolve_args(args, loctab, consts) - disasm = decode(code, args) + disasm = decode(code, args, locdecl) # print(f"{instruction} \t==>\t{disasm}") disasm.insert(0, f"// {instruction}") translated.extend(disasm) @@ -317,7 +342,7 @@ def disassemble(blocks): binds.update(bds) lighting |= light - (shadertype, disasm) = process_asm(asm, ltab) + (shadertype, disasm) = process_asm(asm, ltab, locdecl) shaders[shadertype] = disasm text = ""