assembler: add support for render targets

This commit is contained in:
Zack Buhman 2025-10-28 09:41:44 -05:00
parent c8ae311e60
commit 9aecbbfc6f
8 changed files with 93 additions and 44 deletions

View File

@ -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)

View File

@ -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
)

View File

@ -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):

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -0,0 +1,18 @@
0x00007807,
0x02400000,
0xe401f600,
0x00000000,
0x00000000,
0x00000000,
0x00078001,
0x08020000,
0x08020080,
0x1c440220,
0x1cc18003,
0x00000005,
0x00078005,
0x08020001,
0x08020001,
0x3c440220,
0x3c60c003,
0x00000005,