1-- Parse cmdstream dump and check for common errors 2-- 1) Check for overflowing HLSQ_xS_CNTL.CONSTLEN 3-- 2) Check for constant uploades that overwrite each other. The 4-- range checking is reset on each draw, since it is a valid 5-- use-case to do partial constant upload. But if we see two 6-- CP_LOAD_STATE* that overwrite the same range of constants 7-- within the same draw, that is almost certainly unintentional. 8-- 9-- TODO add more checks 10-- TODO maybe some parts could be shared across 11-- different generations 12 13--local posix = require "posix" 14 15function printf(fmt, ...) 16 return io.write(string.format(fmt, ...)) 17end 18 19function dbg(fmt, ...) 20 --printf(fmt, ...) 21end 22 23stages = { 24 "SB6_VS_SHADER", 25 "SB6_HS_SHADER", 26 "SB6_DS_SHADER", 27 "SB6_GS_SHADER", 28 "SB6_FS_SHADER", 29 "SB6_CS_SHADER", 30} 31 32-- maps shader stage to HLSQ_xS_CNTL register name: 33cntl_regs = { 34 ["SB6_VS_SHADER"] = "HLSQ_VS_CNTL", 35 ["SB6_HS_SHADER"] = "HLSQ_HS_CNTL", 36 ["SB6_DS_SHADER"] = "HLSQ_DS_CNTL", 37 ["SB6_GS_SHADER"] = "HLSQ_GS_CNTL", 38 ["SB6_FS_SHADER"] = "HLSQ_FS_CNTL", 39 ["SB6_CS_SHADER"] = "HLSQ_CS_CNTL", 40} 41 42-- initialize constant updated ranges: 43-- constranges[stagename] -> table of offsets that have been uploaded 44constranges = {} 45function reset_constranges() 46 for i,stage in ipairs(stages) do 47 constranges[stage] = {} 48 end 49end 50 51reset_constranges() 52 53printf("Checking cmdstream...\n") 54 55local r = rnn.init("a630") 56 57function draw(primtype, nindx) 58 printf("draw!\n") 59 -- reset ranges of uploaded consts on each draw: 60 reset_constranges() 61end 62 63function CP_LOAD_STATE6(pkt, size) 64 if tostring(pkt[0].STATE_TYPE) ~= "ST6_CONSTANTS" then 65 return 66 end 67 dbg("got CP_LOAD_STATE6\n") 68 stage = tostring(pkt[0].STATE_BLOCK) 69 max = pkt[0].DST_OFF + pkt[0].NUM_UNIT 70 cntl_reg = cntl_regs[stage] 71 dbg("looking for %s.. max=%d vs %d\n", cntl_reg, max, r[cntl_reg].CONSTLEN) 72 if max > r[cntl_reg].CONSTLEN then 73 printf("ERROR: invalid max constant offset for stage %s: %d vs %d\n", stage, max, r[cntl_reg].CONSTLEN) 74 end 75 76end 77