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:
Asahi Lina 2022-08-17 13:36:16 +09:00
parent d476c03b19
commit bbdd86a998
2 changed files with 228 additions and 114 deletions

View file

@ -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 = []

View file

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