mirror of
https://github.com/AsahiLinux/m1n1
synced 2025-02-16 21:58:27 +00:00
m1n1.agx.render: Lots and lots of updates for new structs, etc.
Also add GPUFrame to represent saved GPU frame dumps, and save/load support. Signed-off-by: Asahi Lina <lina@asahilina.net>
This commit is contained in:
parent
d476c03b19
commit
bbdd86a998
2 changed files with 228 additions and 114 deletions
|
@ -1,16 +1,15 @@
|
|||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: MIT
|
||||
import sys
|
||||
import sys, json, zipfile
|
||||
|
||||
json.c_make_encoder = None
|
||||
|
||||
from m1n1.proxy import *
|
||||
from .context import *
|
||||
from .event import GPUEventManager
|
||||
from .uapi import *
|
||||
from m1n1.constructutils import ConstructClass
|
||||
|
||||
ASAHI_ATTACHMENT_C = 0
|
||||
ASAHI_ATTACHMENT_Z = 1
|
||||
ASAHI_ATTACHMENT_S = 2
|
||||
|
||||
def unswizzle(agx, addr, w, h, psize, dump=None, grid=False):
|
||||
iface = agx.u.iface
|
||||
|
||||
|
@ -46,63 +45,143 @@ def unswizzle(agx, addr, w, h, psize, dump=None, grid=False):
|
|||
open(dump, "wb").write(data[:w*h*psize])
|
||||
#iface.writemem(addr, data)
|
||||
|
||||
class GPUFrame:
|
||||
def __init__(self, context, filename=None, track=False):
|
||||
self.ctx = context
|
||||
self.agx = context.agx
|
||||
self.objects = []
|
||||
self.cmdbuf = None
|
||||
self.track = track
|
||||
if filename is not None:
|
||||
self.load(filename)
|
||||
|
||||
class GPURenderer(object):
|
||||
def __init__(self, agx):
|
||||
self.agx = agx
|
||||
self.ctx_id = 3
|
||||
self.ctx_something = 2
|
||||
def add_object(self, obj):
|
||||
self.objects.append(obj)
|
||||
|
||||
self.ctx = ctx = GPUContext(agx)
|
||||
self.ctx.bind(self.ctx_id)
|
||||
def save(self, filename):
|
||||
cmdbuf = self.cmdbuf
|
||||
with zipfile.ZipFile(filename, "w") as zf:
|
||||
cmdbuf_data = json.dumps(cmdbuf, indent=4).encode("utf-8")
|
||||
zf.writestr("cmdbuf.json", cmdbuf_data)
|
||||
|
||||
self.buffer_mgr = GPUBufferManager(agx, ctx, 16)
|
||||
obj_info = []
|
||||
for obj in self.objects:
|
||||
if obj._data == bytes(obj._size):
|
||||
filename = None
|
||||
else:
|
||||
filename = f"obj_{obj._addr:x}.bin"
|
||||
zf.writestr(filename, obj._data)
|
||||
obj_info.append({
|
||||
"file": filename,
|
||||
"name": obj._name,
|
||||
"addr": obj._addr,
|
||||
"size": obj._size,
|
||||
"map_flags": obj._map_flags,
|
||||
})
|
||||
|
||||
obj_info_data = json.dumps(obj_info, indent=4).encode("utf-8")
|
||||
zf.writestr("objects.json", obj_info_data)
|
||||
|
||||
def load(self, filename):
|
||||
with zipfile.ZipFile(filename, "r") as zf:
|
||||
with zf.open("cmdbuf.json", "r") as fd:
|
||||
self.cmdbuf = drm_asahi_cmdbuf_t.from_json(fd)
|
||||
with zf.open("objects.json", "r") as fd:
|
||||
obj_info = json.load(fd)
|
||||
|
||||
self.objects = []
|
||||
for i in obj_info:
|
||||
filename = i["file"]
|
||||
obj = self.ctx.new_at(i["addr"], Bytes(i["size"]), name=i["name"], track=self.track,
|
||||
**i["map_flags"])
|
||||
if filename is not None:
|
||||
with zf.open(i["file"], "r") as fd:
|
||||
data = fd.read()
|
||||
obj.val = data
|
||||
obj.push()
|
||||
else:
|
||||
obj.val = bytes(i["size"])
|
||||
obj.push()
|
||||
self.objects.append(obj)
|
||||
|
||||
class GPUWork:
|
||||
pass
|
||||
|
||||
class GPURenderer:
|
||||
def __init__(self, ctx, buffers=16, bm_slot=0, queue=0):
|
||||
self.agx = agx = ctx.agx
|
||||
self.queue = queue
|
||||
|
||||
# 0..63
|
||||
self.ctx = ctx
|
||||
self.ctx_id = ctx.ctx
|
||||
|
||||
# 0..255
|
||||
self.buffers = buffers
|
||||
self.buffer_mgr_slot = bm_slot
|
||||
|
||||
## These MUST go together
|
||||
self.buffer_mgr = GPUBufferManager(agx, ctx, buffers)
|
||||
self.buffer_mgr_initialized = False
|
||||
self.unk_emptybuf = agx.kobj.new_buf(0x40, "unk_emptybuf")
|
||||
self.tvb_something_size = 0x8000
|
||||
self.tvb_something = ctx.uobj.new_buf(self.tvb_something_size, "TVB Something", track=True).push()
|
||||
|
||||
self.wq_3d = GPU3DWorkQueue(agx, ctx)
|
||||
self.wq_ta = GPUTAWorkQueue(agx, ctx)
|
||||
##### Job group
|
||||
|
||||
self.job_list = agx.kshared.new(JobList)
|
||||
self.job_list.first_job = 0
|
||||
self.job_list.last_head = self.job_list._addr # Empty list has self as last_head
|
||||
self.job_list.unkptr_10 = 0
|
||||
self.job_list.push()
|
||||
|
||||
##### Work Queues
|
||||
|
||||
self.wq_3d = GPU3DWorkQueue(agx, ctx, self.job_list)
|
||||
self.wq_ta = GPUTAWorkQueue(agx, ctx, self.job_list)
|
||||
|
||||
self.stamp_value = 0
|
||||
|
||||
##### TA stamps
|
||||
|
||||
# start?
|
||||
self.stamp_ta1 = agx.kshared.new(BarrierCounter, name="TA stamp 1")
|
||||
self.stamp_ta1 = agx.kshared.new(StampCounter, name="TA stamp 1")
|
||||
self.stamp_ta1.value = self.stamp_value
|
||||
self.stamp_ta1.push()
|
||||
|
||||
# complete?
|
||||
self.stamp_ta2 = agx.kobj.new(BarrierCounter, name="TA stamp 2")
|
||||
self.stamp_ta2 = agx.kobj.new(StampCounter, name="TA stamp 2")
|
||||
self.stamp_ta2.value = self.stamp_value
|
||||
self.stamp_ta2.push()
|
||||
|
||||
##### 3D stamps
|
||||
|
||||
# start?
|
||||
self.stamp_3d1 = agx.kshared.new(BarrierCounter, name="3D stamp 1")
|
||||
self.stamp_3d1 = agx.kshared.new(StampCounter, name="3D stamp 1")
|
||||
self.stamp_3d1.value = self.stamp_value
|
||||
self.stamp_3d1.push()
|
||||
|
||||
# complete?
|
||||
self.stamp_3d2 = agx.kobj.new(BarrierCounter, name="3D stamp 2")
|
||||
self.stamp_3d2 = agx.kobj.new(StampCounter, name="3D stamp 2")
|
||||
self.stamp_3d2.value = self.stamp_value
|
||||
self.stamp_3d2.push()
|
||||
|
||||
|
||||
##### Things userspace deals with for macOS
|
||||
|
||||
self.aux_fb = ctx.uobj.new_buf(0x8000, "Aux FB thing")
|
||||
#self.deflake_1 = ctx.uobj.new_buf(0x20, "Deflake 1")
|
||||
#self.deflake_2 = ctx.uobj.new_buf(0x280, "Deflake 2")
|
||||
#self.deflake_3 = ctx.uobj.new_buf(0x540, "Deflake 3")
|
||||
self.deflake = ctx.uobj.new_buf(0x7e0, "Deflake")
|
||||
self.unk_buf = ctx.uobj.new(Array(0x800, Int64ul), "Unknown Buffer")
|
||||
self.unk_buf.value = [0, *range(1, 0x400), *(0x400 * [0])]
|
||||
#self.aux_fb = ctx.uobj.new_buf(0x8000, "Aux FB thing")
|
||||
##self.deflake_1 = ctx.uobj.new_buf(0x20, "Deflake 1")
|
||||
##self.deflake_2 = ctx.uobj.new_buf(0x280, "Deflake 2")
|
||||
##self.deflake_3 = ctx.uobj.new_buf(0x540, "Deflake 3")
|
||||
#self.deflake = ctx.uobj.new_buf(0x7e0, "Deflake")
|
||||
#self.unk_buf = ctx.uobj.new(Array(0x800, Int64ul), "Unknown Buffer")
|
||||
#self.unk_buf.val = [0, *range(1, 0x400), *(0x400 * [0])]
|
||||
#self.unk_buf.push()
|
||||
|
||||
##### Some kind of feedback/status buffer, GPU managed?
|
||||
|
||||
self.event_control = agx.kobj.new(EventControl)
|
||||
self.event_control.event_count = agx.kobj.new(Int32ul, "event_control")
|
||||
self.event_control.event_count = agx.kobj.new(Int32ul, "event_count")
|
||||
self.event_control.event_count.val = 0
|
||||
self.event_control.event_count.push()
|
||||
|
||||
|
@ -112,30 +191,54 @@ class GPURenderer(object):
|
|||
self.event_control.push()
|
||||
|
||||
self.frames = 0
|
||||
self.rframes = 0
|
||||
|
||||
self.ev_ta = ev_ta = self.agx.event_mgr.allocate_event()
|
||||
self.ev_3d = ev_3d = self.agx.event_mgr.allocate_event()
|
||||
|
||||
self.work = []
|
||||
|
||||
def submit(self, cmdbuf):
|
||||
self.buffer_mgr.increment()
|
||||
|
||||
aux_fb = self.ctx.uobj.new_buf(0x8000, "Aux FB thing")
|
||||
#self.deflake_1 = ctx.uobj.new_buf(0x20, "Deflake 1")
|
||||
#self.deflake_2 = ctx.uobj.new_buf(0x280, "Deflake 2")
|
||||
#self.deflake_3 = ctx.uobj.new_buf(0x540, "Deflake 3")
|
||||
deflake = self.ctx.uobj.new_buf(0x7e0, "Deflake")
|
||||
unk_buf = self.ctx.uobj.new(Array(0x800, Int64ul), "Unknown Buffer")
|
||||
unk_buf.val = [0, *range(1, 0x400), *(0x400 * [0])]
|
||||
unk_buf.push()
|
||||
|
||||
work = GPUWork()
|
||||
self.work.append(work)
|
||||
|
||||
work.cmdbuf = cmdbuf
|
||||
|
||||
self.frames += 1
|
||||
|
||||
ev_ta = self.agx.event_mgr.allocate_event()
|
||||
ev_3d = self.agx.event_mgr.allocate_event()
|
||||
work.ev_ta = ev_ta = self.ev_ta
|
||||
work.ev_3d = ev_3d = self.ev_3d
|
||||
|
||||
deflake_1 = self.deflake._addr + 0x2a0
|
||||
deflake_2 = self.deflake._addr + 0x20
|
||||
deflake_3 = self.deflake._addr
|
||||
print("ev_ta:", ev_ta.id)
|
||||
print("ev_3d:", ev_3d.id)
|
||||
|
||||
self.event_control.base_stamp = self.stamp_value >> 8
|
||||
self.event_control.push()
|
||||
deflake_1 = deflake._addr + 0x2a0
|
||||
deflake_2 = deflake._addr + 0x20
|
||||
deflake_3 = deflake._addr
|
||||
|
||||
#self.event_control.base_stamp = self.stamp_value >> 8
|
||||
#self.event_control.push()
|
||||
|
||||
self.prev_stamp_value = self.stamp_value
|
||||
self.stamp_value += 0x100
|
||||
self.event_control.event_count.val = 2
|
||||
self.event_control.event_count.val += 2
|
||||
self.event_control.event_count.push()
|
||||
|
||||
agx = self.agx
|
||||
ctx = self.ctx
|
||||
|
||||
width = cmdbuf.fb_width
|
||||
height = cmdbuf.fb_height
|
||||
work.width = width = cmdbuf.fb_width
|
||||
work.height = height = cmdbuf.fb_height
|
||||
|
||||
##### TVB allocations / Tiler config
|
||||
|
||||
|
@ -163,19 +266,19 @@ class GPURenderer(object):
|
|||
tiling_params.unk_24 = 0x100
|
||||
tiling_params.unk_28 = 0x8000
|
||||
|
||||
tvb_something_size = 0x800 * tile_blocks
|
||||
tvb_something = ctx.uobj.new_buf(tvb_something_size, "TVB Something")
|
||||
#tvb_something_size = 0x800 * tile_blocks
|
||||
#tvb_something = ctx.uobj.new_buf(tvb_something_size, "TVB Something", track=False).push()
|
||||
|
||||
tvb_tilemap_size = 0x800 * tile_blocks
|
||||
tvb_tilemap = ctx.uobj.new_buf(tvb_tilemap_size, "TVB Tilemap")
|
||||
tvb_tilemap = ctx.uobj.new_buf(tvb_tilemap_size, "TVB Tilemap", track=False).push()
|
||||
|
||||
tvb_heapmeta_size = 0x4000
|
||||
tvb_heapmeta = ctx.uobj.new_buf(tvb_heapmeta_size, "TVB Heap Meta")
|
||||
tvb_heapmeta_size = 0x200
|
||||
tvb_heapmeta = ctx.uobj.new_buf(tvb_heapmeta_size, "TVB Heap Meta", track=False).push()
|
||||
|
||||
##### Buffer stuff?
|
||||
|
||||
# buffer related?
|
||||
buf_desc = agx.kobj.new(BufferThing)
|
||||
work.buf_desc = buf_desc = agx.kobj.new(BufferThing)
|
||||
buf_desc.unk_0 = 0x0
|
||||
buf_desc.unk_8 = 0x0
|
||||
buf_desc.unk_10 = 0x0
|
||||
|
@ -191,6 +294,10 @@ class GPURenderer(object):
|
|||
uuid_ta = cmdbuf.cmd_ta_id
|
||||
encoder_id = cmdbuf.encoder_id
|
||||
|
||||
#print(barrier_cmd)
|
||||
|
||||
#self.wq_ta.submit(ta_barrier_cmd)
|
||||
|
||||
##### 3D barrier command
|
||||
|
||||
barrier_cmd = agx.kobj.new(WorkCommandBarrier)
|
||||
|
@ -200,23 +307,19 @@ class GPURenderer(object):
|
|||
barrier_cmd.event = ev_ta.id
|
||||
barrier_cmd.uuid = uuid_3d
|
||||
|
||||
|
||||
#stamp.add_to_mon(mon)
|
||||
#stamp2.add_to_mon(mon)
|
||||
|
||||
#print(barrier_cmd)
|
||||
|
||||
self.wq_3d.submit(barrier_cmd)
|
||||
|
||||
##### 3D execution
|
||||
|
||||
wc_3d = agx.kobj.new(WorkCommand3D)
|
||||
work.wc_3d = wc_3d = agx.kobj.new(WorkCommand3D)
|
||||
wc_3d.context_id = self.ctx_id
|
||||
wc_3d.unk_8 = 0
|
||||
wc_3d.event_control = self.event_control
|
||||
wc_3d.buffer_mgr = self.buffer_mgr.info
|
||||
wc_3d.buf_thing = buf_desc
|
||||
wc_3d.unk_emptybuf_addr = agx.kobj.buf(0x100, "unk_emptybuf")
|
||||
wc_3d.unk_emptybuf_addr = self.unk_emptybuf._addr
|
||||
wc_3d.tvb_tilemap = tvb_tilemap._addr
|
||||
wc_3d.unk_40 = 0x88
|
||||
wc_3d.unk_48 = 0x1
|
||||
|
@ -229,15 +332,17 @@ class GPURenderer(object):
|
|||
wc_3d.unk_68 = 0x0
|
||||
wc_3d.tile_count = tiles
|
||||
|
||||
wc_3d.unk_758 = Flag()
|
||||
wc_3d.unk_75c = Flag()
|
||||
wc_3d.unk_buf = WorkCommand1_UnkBuf()
|
||||
wc_3d.unk_word = BarrierCounter()
|
||||
wc_3d.busy_flag = Flag()
|
||||
wc_3d.unk_buf2 = WorkCommand1_UnkBuf2()
|
||||
wc_3d.unk_buf2.unk_0 = 0
|
||||
wc_3d.unk_buf2.unk_8 = 0
|
||||
wc_3d.unk_buf2.unk_10 = 1
|
||||
wc_3d.ts1 = Timestamp(agx.initdata.regionC._addr + 0x9058)
|
||||
wc_3d.ts2 = Timestamp(agx.initdata.regionC._addr + 0x9060)
|
||||
wc_3d.ts3 = Timestamp(agx.initdata.regionC._addr + 0x9068)
|
||||
wc_3d.ts1 = Timestamp(0)
|
||||
wc_3d.ts2 = Timestamp(0)
|
||||
wc_3d.ts3 = Timestamp(0)
|
||||
wc_3d.unk_914 = 0
|
||||
wc_3d.unk_918 = 0
|
||||
wc_3d.unk_920 = 0
|
||||
|
@ -329,7 +434,7 @@ class GPURenderer(object):
|
|||
wc_3d.struct_2.unk_e8 = 0x50000000 * tile_blocks
|
||||
wc_3d.struct_2.tvb_heapmeta_addr2 = tvb_heapmeta._addr
|
||||
wc_3d.struct_2.unk_f8 = 0x10280 # TODO: varies 0, 0x280, 0x10000, 0x10280
|
||||
wc_3d.struct_2.aux_fb_ptr = self.aux_fb._addr
|
||||
wc_3d.struct_2.aux_fb_ptr = aux_fb._addr
|
||||
wc_3d.struct_2.unk_108 = [0x0, 0x0, 0x0, 0x0, 0x0, 0x0]
|
||||
wc_3d.struct_2.pipeline_base = self.ctx.pipeline_base
|
||||
wc_3d.struct_2.unk_140 = 0x8c60
|
||||
|
@ -340,12 +445,12 @@ class GPURenderer(object):
|
|||
|
||||
if True:
|
||||
wc_3d.struct_6 = Start3DStruct6()
|
||||
wc_3d.struct_6.unk_0 = 0x0
|
||||
wc_3d.struct_6.tvb_overflow_count = 0x0
|
||||
wc_3d.struct_6.unk_8 = 0x0
|
||||
wc_3d.struct_6.unk_10 = 0x0
|
||||
wc_3d.struct_6.encoder_id = cmdbuf.encoder_id
|
||||
wc_3d.struct_6.unk_1c = 0xffffffff
|
||||
wc_3d.struct_6.unknown_buffer = self.unk_buf._addr
|
||||
wc_3d.struct_6.unknown_buffer = unk_buf._addr
|
||||
wc_3d.struct_6.unk_28 = 0x0
|
||||
wc_3d.struct_6.unk_30 = 0x1
|
||||
wc_3d.struct_6.unk_34 = 0x1
|
||||
|
@ -360,7 +465,7 @@ class GPURenderer(object):
|
|||
wc_3d.struct_7.unk_20 = 0x0
|
||||
wc_3d.struct_7.unk_24 = 0x0 # check
|
||||
wc_3d.struct_7.uuid = uuid_3d
|
||||
wc_3d.struct_7.prev_stamp_value = 0x0
|
||||
wc_3d.struct_7.prev_stamp_value = self.prev_stamp_value >> 8
|
||||
wc_3d.struct_7.unk_30 = 0x0
|
||||
|
||||
wc_3d.set_addr() # Update inner structure addresses
|
||||
|
@ -376,8 +481,8 @@ class GPURenderer(object):
|
|||
start_3d.struct1 = wc_3d.struct_1
|
||||
start_3d.struct2 = wc_3d.struct_2
|
||||
start_3d.buf_thing = buf_desc
|
||||
start_3d.unkptr_1c = agx.initdata.regionB.unkptr_178 + 8
|
||||
start_3d.unkptr_24 = wc_3d.unk_word._addr
|
||||
start_3d.stats_ptr = agx.initdata.regionB.stats_3d.stats._addr
|
||||
start_3d.busy_flag_ptr = wc_3d.busy_flag._addr
|
||||
start_3d.struct6 = wc_3d.struct_6
|
||||
start_3d.struct7 = wc_3d.struct_7
|
||||
start_3d.cmdqueue_ptr = self.wq_3d.info._addr
|
||||
|
@ -385,11 +490,11 @@ class GPURenderer(object):
|
|||
start_3d.context_id = self.ctx_id
|
||||
start_3d.unk_50 = 0x1
|
||||
start_3d.unk_54 = 0x0
|
||||
start_3d.unk_58 = 0x2
|
||||
start_3d.buffer_mgr_slot = self.buffer_mgr_slot
|
||||
start_3d.unk_5c = 0x0
|
||||
start_3d.prev_stamp_value = 0x0
|
||||
start_3d.prev_stamp_value = self.prev_stamp_value >> 8
|
||||
start_3d.unk_68 = 0x0
|
||||
start_3d.unk_buf_ptr = wc_3d.unk_buf._addr
|
||||
start_3d.unk_buf_ptr = wc_3d.unk_758._addr
|
||||
start_3d.unk_buf2_ptr = wc_3d.unk_buf2._addr
|
||||
start_3d.unk_7c = 0x0
|
||||
start_3d.unk_80 = 0x0
|
||||
|
@ -402,21 +507,21 @@ class GPURenderer(object):
|
|||
ASAHI_ATTACHMENT_S: 0x4100, # ???
|
||||
}
|
||||
|
||||
fb = None
|
||||
depth = None
|
||||
work.fb = None
|
||||
work.depth = None
|
||||
|
||||
for i in cmdbuf.attachments[:cmdbuf.attachment_count]:
|
||||
atype = att_map[i.type]
|
||||
start_3d.attachments.append(Attachment(i.pointer, att_map[i.type], 0x10017)) # FIXME check
|
||||
if fb is None and i.type == ASAHI_ATTACHMENT_C:
|
||||
fb = i.pointer
|
||||
if depth is None and i.type == ASAHI_ATTACHMENT_Z:
|
||||
depth = i.pointer
|
||||
if work.fb is None and i.type == ASAHI_ATTACHMENT_C:
|
||||
work.fb = i.pointer
|
||||
if work.depth is None and i.type == ASAHI_ATTACHMENT_Z:
|
||||
work.depth = i.pointer
|
||||
start_3d.attachments += [Attachment(0, 0, 0)] * (16 - len(start_3d.attachments))
|
||||
start_3d.num_attachments = cmdbuf.attachment_count
|
||||
start_3d.unk_190 = 0x0
|
||||
|
||||
ms.append(start_3d)
|
||||
start_3d_offset = ms.append(start_3d)
|
||||
|
||||
ts1 = TimestampCmd()
|
||||
ts1.unk_1 = 0x0
|
||||
|
@ -455,19 +560,19 @@ class GPURenderer(object):
|
|||
finish_3d.buf_thing = buf_desc
|
||||
finish_3d.buffer_mgr = self.buffer_mgr.info
|
||||
finish_3d.unk_2c = 1
|
||||
finish_3d.unkptr_34 = agx.initdata.regionB.unkptr_178 + 8
|
||||
finish_3d.stats_ptr = agx.initdata.regionB.stats_3d.stats._addr
|
||||
finish_3d.struct7 = wc_3d.struct_7
|
||||
finish_3d.unkptr_44 = wc_3d.unk_word._addr
|
||||
finish_3d.busy_flag_ptr = wc_3d.busy_flag._addr
|
||||
finish_3d.cmdqueue_ptr = self.wq_3d.info._addr
|
||||
finish_3d.workitem_ptr = wc_3d._addr
|
||||
finish_3d.unk_5c = self.ctx_id
|
||||
finish_3d.unk_buf_ptr = wc_3d.unk_buf._addr
|
||||
finish_3d.unk_buf_ptr = wc_3d.unk_758._addr
|
||||
finish_3d.unk_6c = 0
|
||||
finish_3d.unk_74 = 0
|
||||
finish_3d.unk_7c = 0
|
||||
finish_3d.unk_84 = 0
|
||||
finish_3d.unk_8c = 0
|
||||
finish_3d.startcmd_offset = -0x200
|
||||
finish_3d.restart_branch_offset = start_3d_offset - ms.off
|
||||
finish_3d.unk_98 = 1
|
||||
ms.append(finish_3d)
|
||||
ms.finalize()
|
||||
|
@ -488,7 +593,7 @@ class GPURenderer(object):
|
|||
if not self.buffer_mgr_initialized:
|
||||
wc_initbm = agx.kobj.new(WorkCommandInitBM)
|
||||
wc_initbm.context_id = self.ctx_id
|
||||
wc_initbm.unk_8 = self.ctx_something
|
||||
wc_initbm.buffer_mgr_slot = self.buffer_mgr_slot
|
||||
wc_initbm.unk_c = 0
|
||||
wc_initbm.unk_10 = self.buffer_mgr.info.block_count
|
||||
wc_initbm.buffer_mgr = self.buffer_mgr.info
|
||||
|
@ -496,13 +601,15 @@ class GPURenderer(object):
|
|||
|
||||
self.wq_ta.submit(wc_initbm)
|
||||
|
||||
self.buffer_mgr_initialized = True
|
||||
|
||||
##### TA execution
|
||||
|
||||
wc_ta = agx.kobj.new(WorkCommandTA)
|
||||
work.wc_ta = wc_ta = agx.kobj.new(WorkCommandTA)
|
||||
wc_ta.context_id = self.ctx_id
|
||||
wc_ta.unk_8 = 0
|
||||
wc_ta.event_control = self.event_control
|
||||
wc_ta.unk_14 = self.ctx_something
|
||||
wc_ta.buffer_mgr_slot = self.buffer_mgr_slot
|
||||
wc_ta.buffer_mgr = self.buffer_mgr.info
|
||||
wc_ta.buf_thing = buf_desc
|
||||
wc_ta.unk_emptybuf_addr = wc_3d.unk_emptybuf_addr
|
||||
|
@ -512,9 +619,9 @@ class GPURenderer(object):
|
|||
wc_ta.unk_3e8 = bytes(0x74)
|
||||
wc_ta.unk_594 = WorkCommand0_UnkBuf()
|
||||
|
||||
wc_ta.ts1 = Timestamp()
|
||||
wc_ta.ts2 = Timestamp()
|
||||
wc_ta.ts3 = Timestamp()
|
||||
wc_ta.ts1 = Timestamp(0)
|
||||
wc_ta.ts2 = Timestamp(0)
|
||||
wc_ta.ts3 = Timestamp(0)
|
||||
wc_ta.unk_5c4 = 0
|
||||
wc_ta.unk_5c8 = 0
|
||||
wc_ta.unk_5cc = 0
|
||||
|
@ -532,7 +639,7 @@ class GPURenderer(object):
|
|||
wc_ta.struct_2.unk_c = 0x1e3ce508 # fixed
|
||||
wc_ta.struct_2.tvb_tilemap = tvb_tilemap._addr
|
||||
wc_ta.struct_2.unkptr_18 = 0x0
|
||||
wc_ta.struct_2.unkptr_20 = tvb_something._addr
|
||||
wc_ta.struct_2.unkptr_20 = self.tvb_something._addr
|
||||
wc_ta.struct_2.tvb_heapmeta_addr = tvb_heapmeta._addr | 0x8000000000000000
|
||||
wc_ta.struct_2.iogpu_unk_54 = 0x6b0003 # fixed
|
||||
wc_ta.struct_2.iogpu_unk_55 = 0x3a0012 # fixed
|
||||
|
@ -605,12 +712,12 @@ class GPURenderer(object):
|
|||
start_ta.struct2 = wc_ta.struct_2
|
||||
start_ta.buffer_mgr = self.buffer_mgr.info
|
||||
start_ta.buf_thing = buf_desc
|
||||
start_ta.unkptr_24 = agx.initdata.regionB.unkptr_170 + 4
|
||||
start_ta.stats_ptr = agx.initdata.regionB.stats_ta.stats._addr
|
||||
start_ta.cmdqueue_ptr = self.wq_ta.info._addr
|
||||
start_ta.context_id = self.ctx_id
|
||||
start_ta.unk_38 = 1
|
||||
start_ta.unk_3c = 1 #0
|
||||
start_ta.unk_40 = self.ctx_something
|
||||
start_ta.buffer_mgr_slot = self.buffer_mgr_slot
|
||||
start_ta.unk_48 = 1 #0
|
||||
start_ta.unk_50 = 0
|
||||
start_ta.struct3 = wc_ta.struct_3
|
||||
|
@ -629,7 +736,8 @@ class GPURenderer(object):
|
|||
start_ta.unk_16c = 0x0 # fixed
|
||||
start_ta.unk_170 = 0x0 # fixed
|
||||
start_ta.unk_178 = 0x0 # fixed
|
||||
ms.append(start_ta)
|
||||
|
||||
start_ta_offset = ms.append(start_ta)
|
||||
|
||||
ts1 = TimestampCmd()
|
||||
ts1.unk_1 = 0x0
|
||||
|
@ -662,7 +770,7 @@ class GPURenderer(object):
|
|||
finish_ta = FinalizeTACmd()
|
||||
finish_ta.buf_thing = buf_desc
|
||||
finish_ta.buffer_mgr = self.buffer_mgr.info
|
||||
finish_ta.unkptr_14 = agx.initdata.regionB.unkptr_170 + 4
|
||||
finish_ta.stats_ptr = agx.initdata.regionB.stats_ta.stats._addr
|
||||
finish_ta.cmdqueue_ptr = self.wq_ta.info._addr
|
||||
finish_ta.context_id = self.ctx_id
|
||||
finish_ta.unk_28 = 0x0 # fixed
|
||||
|
@ -678,60 +786,64 @@ class GPURenderer(object):
|
|||
finish_ta.unk_60 = 0x0 # fixed
|
||||
finish_ta.unk_64 = 0x0 # fixed
|
||||
finish_ta.unk_68 = 0x0 # fixed
|
||||
finish_ta.startcmd_offset = -0x1e8 # fixed
|
||||
finish_ta.restart_branch_offset = start_ta_offset - ms.off
|
||||
finish_ta.unk_70 = 0x0 # fixed
|
||||
ms.append(finish_ta)
|
||||
|
||||
ms.finalize()
|
||||
|
||||
wc_ta.unkptr_45c = tvb_something._addr
|
||||
wc_ta.tvb_size = tvb_something_size
|
||||
wc_ta.unkptr_45c = self.tvb_something._addr
|
||||
wc_ta.tvb_size = tvb_tilemap_size
|
||||
wc_ta.microsequence_ptr = ms.obj._addr
|
||||
wc_ta.microsequence_size = ms.size
|
||||
wc_ta.ev_3d = ev_3d.id
|
||||
wc_ta.stamp_value = self.stamp_value
|
||||
|
||||
#ms.dump()
|
||||
|
||||
#agx.mon.poll()
|
||||
|
||||
#print(wc_ta)
|
||||
self.wq_ta.submit(wc_ta)
|
||||
|
||||
return work
|
||||
|
||||
def run(self):
|
||||
##### Run queues
|
||||
agx.ch.queue[0].q_3D.run(self.wq_3d, ev_3d.id)
|
||||
agx.ch.queue[0].q_TA.run(self.wq_ta, ev_ta.id)
|
||||
self.agx.ch.queue[self.queue].q_3D.run(self.wq_3d, self.ev_3d.id)
|
||||
self.agx.ch.queue[self.queue].q_TA.run(self.wq_ta, self.ev_ta.id)
|
||||
|
||||
##### Wait for work
|
||||
while not ev_3d.fired:
|
||||
agx.wait_for_events()
|
||||
def wait(self):
|
||||
work = self.work[-1]
|
||||
|
||||
if not ev_3d.fired:
|
||||
##### Wait for work completion
|
||||
while not self.ev_3d.fired:
|
||||
self.agx.wait_for_events(timeout=2.0)
|
||||
|
||||
if not self.ev_3d.fired:
|
||||
print("3D event didn't fire")
|
||||
|
||||
#print("Stamps:")
|
||||
#print(self.stamp_ta1.pull())
|
||||
#print(self.stamp_ta2.pull())
|
||||
#print(self.stamp_3d1.pull())
|
||||
#print(self.stamp_3d2.pull())
|
||||
print("Stamps:")
|
||||
print(self.stamp_ta1.pull())
|
||||
print(self.stamp_ta2.pull())
|
||||
print(self.stamp_3d1.pull())
|
||||
print(self.stamp_3d2.pull())
|
||||
|
||||
if fb is not None:
|
||||
print(f"Render {width}x{height}")
|
||||
base, obj = agx.find_object(fb)
|
||||
#print("WCs:")
|
||||
#print(work.wc_3d.pull())
|
||||
#print(work.wc_ta.pull())
|
||||
|
||||
if work.fb is not None:
|
||||
print(f"Render {work.width}x{work.height} @ {work.fb:#x}")
|
||||
base, obj = self.agx.find_object(work.fb, self.ctx_id)
|
||||
|
||||
#unswizzle(agx, obj._paddr, width, height, 4, "fb.bin", grid=False)
|
||||
#os.system(f"convert -size {width}x{height} -depth 8 rgba:fb.bin frame{self.frames}.png")
|
||||
self.rframes += 1
|
||||
if not self.rframes & 1:
|
||||
agx.p.fb_blit(0, 0, width, height, obj._paddr, width, PIX_FMT.XBGR)
|
||||
self.agx.p.fb_blit(0, 0, work.width, work.height, obj._paddr, work.width, PIX_FMT.XBGR)
|
||||
|
||||
if False and depth is not None:
|
||||
base, obj = agx.find_object(depth)
|
||||
base, obj = self.agx.find_object(depth, self.ctx_id)
|
||||
|
||||
width = align_up(width, 64)
|
||||
height = align_up(height, 64)
|
||||
width = align_up(work.width, 64)
|
||||
height = align_up(work.height, 64)
|
||||
|
||||
unswizzle(agx, obj._paddr, width, height, 4, "depth.bin", grid=False)
|
||||
unswizzle(self.agx, obj._paddr, work.width, work.height, 4, "depth.bin", grid=False)
|
||||
os.system(f"convert -size {width}x{height} -depth 8 rgba:depth.bin depth.png")
|
||||
|
||||
#sys.exit(0)
|
||||
self.work = []
|
||||
|
|
|
@ -122,6 +122,8 @@ class DRMAsahiShim:
|
|||
obj.push(True)
|
||||
|
||||
self.renderer.submit(cmdbuf)
|
||||
self.renderer.run()
|
||||
self.renderer.wait()
|
||||
|
||||
if self.pull_buffers:
|
||||
for i in cmdbuf.attachments:
|
||||
|
|
Loading…
Add table
Reference in a new issue