diff --git a/regs/assembler/fs/alu_emitter.py b/regs/assembler/fs/alu_emitter.py index 932ac18..7a0973f 100644 --- a/regs/assembler/fs/alu_emitter.py +++ b/regs/assembler/fs/alu_emitter.py @@ -5,12 +5,17 @@ from assembler.fs.common_emitter import US_ALU_RGB_INST, US_ALU_ALPHA_INST, US_A def emit_alpha_op(code, alpha_op): # dest + if alpha_op.dest.addrd is not None: + assert type(alpha_op.dest.addrd) is int + US_ALU_ALPHA_INST.ALPHA_ADDRD(code, alpha_op.dest.addrd) + if alpha_op.dest.target is not None: + assert type(alpha_op.dest.target) is int + US_ALU_ALPHA_INST.TARGET(code, alpha_op.dest.target) + if alpha_op.dest.wmask is not None: US_CMN_INST.ALPHA_WMASK(code, alpha_op.dest.wmask.value) if alpha_op.dest.omask is not None: US_CMN_INST.ALPHA_OMASK(code, alpha_op.dest.omask.value) - assert type(alpha_op.dest.addrd) is int - US_ALU_ALPHA_INST.ALPHA_ADDRD(code, alpha_op.dest.addrd) # opcode US_ALU_ALPHA_INST.ALPHA_OP(code, alpha_op.opcode.value) @@ -42,12 +47,17 @@ def emit_alpha_op(code, alpha_op): def emit_rgb_op(code, rgb_op): # dest + if rgb_op.dest.addrd is not None: + assert type(rgb_op.dest.addrd) is int + US_ALU_RGBA_INST.RGB_ADDRD(code, rgb_op.dest.addrd) + if rgb_op.dest.target is not None: + assert type(rgb_op.dest.target) is int + US_ALU_RGB_INST.TARGET(code, rgb_op.dest.target) + if rgb_op.dest.wmask is not None: US_CMN_INST.RGB_WMASK(code, rgb_op.dest.wmask.value) if rgb_op.dest.omask is not None: US_CMN_INST.RGB_OMASK(code, rgb_op.dest.omask.value) - assert type(rgb_op.dest.addrd) is int - US_ALU_RGBA_INST.RGB_ADDRD(code, rgb_op.dest.addrd) # opcode US_ALU_RGBA_INST.RGB_OP(code, rgb_op.opcode.value) diff --git a/regs/assembler/fs/alu_validator.py b/regs/assembler/fs/alu_validator.py index 3920adb..bbf2491 100644 --- a/regs/assembler/fs/alu_validator.py +++ b/regs/assembler/fs/alu_validator.py @@ -83,12 +83,14 @@ class AlphaOp(IntEnum): @dataclass class RGBDest: addrd: int + target: int wmask: RGBMask omask: RGBMask @dataclass class AlphaDest: addrd: int + target: int wmask: AlphaMask omask: AlphaMask @@ -345,25 +347,26 @@ def infer_operation_units(operations): yield units[i], operation def validate_instruction_operation_dest(dest_addr_swizzles, mask_lookup, type_cls): - addrs = set() + addrd = None + target = None wmask = None omask = None for dest_addr_swizzle in dest_addr_swizzles: dest = validate_dest_keyword(dest_addr_swizzle.dest_keyword) addr = validate_identifier_number(dest_addr_swizzle.addr_identifier) mask = mask_lookup[dest_addr_swizzle.swizzle_identifier.lexeme.lower()] - addrs.add(addr) if dest == KW.OUT: omask = mask + target = addr elif dest == KW.TEMP: wmask = mask + addrd = addr else: assert False, dest - if len(addrs) > 1: - raise ValidatorError(f"too many destination addresses", operation.dest_addr_swizzles[-1].addr_identifier) - addrd, = addrs if addrs else [0] + return type_cls( addrd=addrd, + target=target, wmask=wmask, omask=omask ) diff --git a/regs/assembler/fs/common_validator.py b/regs/assembler/fs/common_validator.py index 02c44c1..29aa833 100644 --- a/regs/assembler/fs/common_validator.py +++ b/regs/assembler/fs/common_validator.py @@ -36,7 +36,7 @@ def validate_dest_keyword(dest_keyword): dest_keyword_strs = keywords_to_string(dest_keywords) dest = dest_keyword.keyword if dest not in dest_keywords: - raise ValidatorError(f"invalid dest keyword, expected one of {dest_keyword_strs}", dest_addr_swizzle.dest_keyword) + raise ValidatorError(f"invalid dest keyword, expected one of {dest_keyword_strs}", dest_keyword) return dest def keywords_to_string(keywords): diff --git a/regs/assembler/fs/tex_emitter.py b/regs/assembler/fs/tex_emitter.py index 8defe1f..94845fd 100644 --- a/regs/assembler/fs/tex_emitter.py +++ b/regs/assembler/fs/tex_emitter.py @@ -14,8 +14,6 @@ def emit_instruction(code, ins): US_CMN_INST.ALU_WAIT(code, int(KW.ALU_WAIT in ins.tags)) US_CMN_INST.RGB_WMASK(code, ins.masks.rgb_wmask.value) US_CMN_INST.ALPHA_WMASK(code, ins.masks.alpha_wmask.value) - US_CMN_INST.RGB_OMASK(code, ins.masks.rgb_omask.value) - US_CMN_INST.ALPHA_OMASK(code, ins.masks.alpha_omask.value) US_TEX_INST.TEX_ID(code, ins.tex_id) US_TEX_INST.INST(code, ins.opcode.value) diff --git a/regs/assembler/fs/tex_validator.py b/regs/assembler/fs/tex_validator.py index d81bf05..f1e4268 100644 --- a/regs/assembler/fs/tex_validator.py +++ b/regs/assembler/fs/tex_validator.py @@ -7,15 +7,13 @@ from assembler.validator import ValidatorError from assembler.fs import parser from assembler.fs.keywords import KW from assembler.fs.common_validator import RGBMask, AlphaMask -from assembler.fs.common_validator import validate_identifier_number, validate_dest_keyword +from assembler.fs.common_validator import validate_identifier_number from assembler.fs.common_validator import keywords_to_string @dataclass class Masks: alpha_wmask: AlphaMask rgb_wmask: RGBMask - alpha_omask: AlphaMask - rgb_omask: RGBMask class TEXOp(IntEnum): NOP = 0 @@ -85,16 +83,13 @@ def validate_masks(ins_ast: parser.TEXInstruction): masks = Masks( alpha_wmask = AlphaMask.NONE, rgb_wmask = RGBMask.NONE, - alpha_omask = AlphaMask.NONE, - rgb_omask = RGBMask.NONE, ) for dest_addr_swizzle in ins_ast.operation.dest_addr_swizzles: dest_keyword = dest_addr_swizzle.dest_keyword - dest = validate_dest_keyword(dest_keyword) - if dest in dests: - raise ValidatorError(f"duplicate destination keyword {dest}", dest_keyword) - dests.add(dest) + if dest_keyword.keyword is not KW.TEMP: + raise ValidatorError(f"invalid dest keyword, expected `temp`", dest_keyword) + dests.add(dest_keyword.keyword) addr_identifier = dest_addr_swizzle.addr_identifier addr = validate_identifier_number(addr_identifier) @@ -103,14 +98,8 @@ def validate_masks(ins_ast: parser.TEXInstruction): swizzle_identifier = dest_addr_swizzle.swizzle_identifier alpha_mask, rgb_mask = validate_mask_swizzle(swizzle_identifier) - if dest is KW.OUT: - masks.alpha_omask = alpha_mask - masks.rgb_omask = rgb_mask - elif dest is KW.TEMP: - masks.alpha_wmask = alpha_mask - masks.rgb_wmask = rgb_mask - else: - assert False, type(dest) + masks.alpha_wmask = alpha_mask + masks.rgb_wmask = rgb_mask if len(addresses) > 1: raise ValidatorError("contradictory destination address", ins_ast.operation.dest_addr_swizzles[-1].addr_identifier) diff --git a/regs/us_disassemble2.py b/regs/us_disassemble2.py index 937a2df..7404d3e 100644 --- a/regs/us_disassemble2.py +++ b/regs/us_disassemble2.py @@ -207,10 +207,22 @@ def disassemble_alu_dest(code): rgb_omask, rgb_omask_str, _ = US_CMN_INST._RGB_OMASK(code) a_omask, a_omask_str, _ = US_CMN_INST._ALPHA_OMASK(code) - a_out_str = f"out[{a_addrd}].{a_omask_str.lower().ljust(4)} = " if a_omask != 0 else "" + rgb_target = US_ALU_RGB_INST.TARGET(code) + a_target = US_ALU_ALPHA_INST.TARGET(code) + + if a_omask == 0: + assert a_target == 0 + if rgb_omask == 0: + assert rgb_target == 0 + if a_wmask == 0: + assert a_addrd == 0 + if rgb_wmask == 0: + assert rgb_addrd == 0 + + a_out_str = f"out[{a_target}].{a_omask_str.lower().ljust(4)} = " if a_omask != 0 else "" a_temp_str = f"temp[{a_addrd}].{a_wmask_str.lower().ljust(4)} = " if a_wmask != 0 else "" - rgb_out_str = f"out[{rgb_addrd}].{rgb_omask_str.lower().ljust(4)} = " if rgb_omask != 0 else "" + rgb_out_str = f"out[{rgb_target}].{rgb_omask_str.lower().ljust(4)} = " if rgb_omask != 0 else "" rgb_temp_str = f"temp[{rgb_addrd}].{rgb_wmask_str.lower().ljust(4)} = " if rgb_wmask != 0 else "" return (a_out_str, a_temp_str), (rgb_out_str, rgb_temp_str) @@ -239,17 +251,13 @@ def assert_zeros_common(code): def assert_zeros_alu(code): rgb_omod = US_ALU_RGB_INST.OMOD(code) - rgb_target = US_ALU_RGB_INST.TARGET(code) alu_wmask = US_ALU_RGB_INST.ALU_WMASK(code) assert rgb_omod in {0, 7} - assert rgb_target == 0 assert alu_wmask == 0 a_omod = US_ALU_ALPHA_INST.OMOD(code) - a_target = US_ALU_ALPHA_INST.TARGET(code) w_omask = US_ALU_ALPHA_INST.W_OMASK(code) assert a_omod in {0, 7} - assert a_target == 0 assert w_omask == 0 def assert_zeros_tex(code): @@ -418,13 +426,14 @@ def disassemble_tex_dest(code): rgb_omask, rgb_omask_str, _ = US_CMN_INST._RGB_OMASK(code) a_omask, a_omask_str, _ = US_CMN_INST._ALPHA_OMASK(code) - omask_bool = rgb_omask != 0 or a_omask != 0 - rgba_omask = (a_omask_str if a_omask else "") + (rgb_omask_str if rgb_omask else "") + assert rgb_omask == 0 + assert a_omask == 0 + #omask_bool = rgb_omask != 0 or a_omask != 0 + #rgba_omask = (a_omask_str if a_omask else "") + (rgb_omask_str if rgb_omask else "") + #out_str = f"out[{dst_addr}].{rgba_omask.lower().ljust(4)} = " if omask_bool else "" - out_str = f"out[{dst_addr}].{rgba_omask.lower().ljust(4)} = " if omask_bool else "" - - return out_str, temp_str + return temp_str def disassemble_tex(code): assert_zeros_common(code) @@ -436,9 +445,7 @@ def disassemble_tex(code): src_addr = US_TEX_ADDR.SRC_ADDR(code) src_swiz, dst_swiz = disassemble_tex_swizzle_str(code) - out_str, temp_str = disassemble_tex_dest(code) - - temp_out_str = ''.join([out_str, temp_str]) + temp_str = disassemble_tex_dest(code) tags = ["TEX"] if US_CMN_INST.TEX_SEM_WAIT(code): @@ -449,7 +456,7 @@ def disassemble_tex(code): tags.append("ALU_WAIT") print(" ".join(tags)) - print(f" {temp_out_str}{inst} tex[{tex_id}].{dst_swiz} temp[{src_addr}].{src_swiz} ;") + print(f" {temp_str}{inst} tex[{tex_id}].{dst_swiz} temp[{src_addr}].{src_swiz} ;") def disassemble(code): assert len(code) == 6, len(code) diff --git a/shader_examples/mesa/vertex_color_fp_render.fs.txt b/shader_examples/mesa/vertex_color_fp_render.fs.txt new file mode 100644 index 0000000..2e80a24 --- /dev/null +++ b/shader_examples/mesa/vertex_color_fp_render.fs.txt @@ -0,0 +1,24 @@ +0x00048001, +0x08020000, +0x08020080, +0x20850420, +0x3cc18003, +0x00000001, +0x00078001, +0x08020000, +0x08020080, +0x1c440220, +0x1cc18003, +0x00000005, +0x00010001, +0x08020000, +0x08020080, +0x20848400, +0x20000000, +0x00000001, +0x00020005, +0x08020000, +0x08020080, +0x20848448, +0x20000000, +0x00000001, diff --git a/shader_examples/mesa/vertex_color_fp_render_texture.fs.txt b/shader_examples/mesa/vertex_color_fp_render_texture.fs.txt new file mode 100644 index 0000000..8f4dbf1 --- /dev/null +++ b/shader_examples/mesa/vertex_color_fp_render_texture.fs.txt @@ -0,0 +1,18 @@ +0x00007807, +0x02400000, +0xe401f600, +0x00000000, +0x00000000, +0x00000000, +0x00078001, +0x08020000, +0x08020080, +0x1c440220, +0x1cc18003, +0x00000005, +0x00078005, +0x08020001, +0x08020001, +0x3c440220, +0x3c60c003, +0x00000005,