diff options
author | Dave Airlie <airlied@redhat.com> | 2009-04-09 10:14:35 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-04-09 10:31:08 +1000 |
commit | d1a9b1f513109c975a5a7ed5a2d0c329b280afe4 (patch) | |
tree | 5c85af47b4f5af0661acf129e3ce3f59e43cbfd9 /src/gallium/state_trackers/python/retrace | |
parent | 90ffce497395d8c02fee2ea4ee4c025eede3d876 (diff) | |
parent | 8648c2685870174cf620ef15de70ef030a8d5a20 (diff) |
Merge remote branch 'origin/master' into radeon-rewrite
Conflicts:
src/mesa/drivers/dri/r200/r200_tex.c
src/mesa/drivers/dri/r300/r300_cmdbuf.c
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_swtcl.c
src/mesa/drivers/dri/r300/r300_tex.c
src/mesa/drivers/dri/r300/r300_texmem.c
src/mesa/drivers/dri/r300/r300_texstate.c
src/mesa/drivers/dri/radeon/radeon_tex.c
Diffstat (limited to 'src/gallium/state_trackers/python/retrace')
4 files changed, 282 insertions, 68 deletions
diff --git a/src/gallium/state_trackers/python/retrace/format.py b/src/gallium/state_trackers/python/retrace/format.py index 0bf6baf0b9..a4285bfe07 100755 --- a/src/gallium/state_trackers/python/retrace/format.py +++ b/src/gallium/state_trackers/python/retrace/format.py @@ -27,6 +27,9 @@ ########################################################################## +import sys + + class Formatter: '''Plain formatter''' @@ -91,10 +94,80 @@ class AnsiFormatter(Formatter): self._escape(self._normal) +class WindowsConsoleFormatter(Formatter): + '''Formatter for the Windows Console. See + http://code.activestate.com/recipes/496901/ for more information. + ''' + + STD_INPUT_HANDLE = -10 + STD_OUTPUT_HANDLE = -11 + STD_ERROR_HANDLE = -12 + + FOREGROUND_BLUE = 0x01 + FOREGROUND_GREEN = 0x02 + FOREGROUND_RED = 0x04 + FOREGROUND_INTENSITY = 0x08 + BACKGROUND_BLUE = 0x10 + BACKGROUND_GREEN = 0x20 + BACKGROUND_RED = 0x40 + BACKGROUND_INTENSITY = 0x80 + + _normal = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED + _bold = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY + _italic = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED + _red = FOREGROUND_RED | FOREGROUND_INTENSITY + _green = FOREGROUND_GREEN | FOREGROUND_INTENSITY + _blue = FOREGROUND_BLUE | FOREGROUND_INTENSITY + + def __init__(self, stream): + Formatter.__init__(self, stream) + + if stream is sys.stdin: + nStdHandle = self.STD_INPUT_HANDLE + elif stream is sys.stdout: + nStdHandle = self.STD_OUTPUT_HANDLE + elif stream is sys.stderr: + nStdHandle = self.STD_ERROR_HANDLE + else: + nStdHandle = None + + if nStdHandle: + import ctypes + self.handle = ctypes.windll.kernel32.GetStdHandle(nStdHandle) + else: + self.handle = None + + def _attribute(self, attr): + if self.handle: + import ctypes + ctypes.windll.kernel32.SetConsoleTextAttribute(self.handle, attr) + + def function(self, name): + self._attribute(self._bold) + Formatter.function(self, name) + self._attribute(self._normal) + + def variable(self, name): + self._attribute(self._italic) + Formatter.variable(self, name) + self._attribute(self._normal) + + def literal(self, value): + self._attribute(self._blue) + Formatter.literal(self, value) + self._attribute(self._normal) + + def address(self, value): + self._attribute(self._green) + Formatter.address(self, value) + self._attribute(self._normal) + def DefaultFormatter(stream): - if stream.isatty(): + if sys.platform in ('linux2', 'cygwin'): return AnsiFormatter(stream) + elif sys.platform in ('win32',): + return WindowsConsoleFormatter(stream) else: return Formatter(stream) diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index e6999a2211..5ea07724a5 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -54,14 +54,14 @@ def save_image(filename, surface): outimage = make_image(surface) outimage.save(filename, "PNG") -def show_image(surface): +def show_image(surface, title): outimage = make_image(surface) import Tkinter as tk from PIL import Image, ImageTk root = tk.Tk() - root.title('background image') + root.title(title) image1 = ImageTk.PhotoImage(outimage) w = image1.width() @@ -75,9 +75,6 @@ def show_image(surface): root.mainloop() -verbose = 1 - - class Struct: """C-like struct""" @@ -184,8 +181,12 @@ class Global(Object): def pipe_winsys_create(self): return Winsys(self.interpreter, gallium.Device()) - def pipe_screen_create(self, winsys): - return Screen(self.interpreter, winsys.real) + def pipe_screen_create(self, winsys=None): + if winsys is None: + real = gallium.Device() + else: + real = winsys.real + return Screen(self.interpreter, real) def pipe_context_create(self, screen): context = screen.real.context_create() @@ -237,6 +238,16 @@ class Winsys(Object): pass +class Transfer: + + def __init__(self, surface, x, y, w, h): + self.surface = surface + self.x = x + self.y = y + self.w = w + self.h = h + + class Screen(Object): def destroy(self): @@ -257,15 +268,15 @@ class Screen(Object): def is_format_supported(self, format, target, tex_usage, geom_flags): return self.real.is_format_supported(format, target, tex_usage, geom_flags) - def texture_create(self, template): + def texture_create(self, templat): return self.real.texture_create( - format = template.format, - width = template.width[0], - height = template.height[0], - depth = template.depth[0], - last_level = template.last_level, - target = template.target, - tex_usage = template.tex_usage, + format = templat.format, + width = templat.width[0], + height = templat.height[0], + depth = templat.depth[0], + last_level = templat.last_level, + target = templat.target, + tex_usage = templat.tex_usage, ) def texture_destroy(self, texture): @@ -275,7 +286,9 @@ class Screen(Object): pass def get_tex_surface(self, texture, face, level, zslice, usage): - return texture.get_surface(face, level, zslice, usage) + if texture is None: + return None + return texture.get_surface(face, level, zslice) def tex_surface_destroy(self, surface): self.interpreter.unregister_object(surface) @@ -284,9 +297,53 @@ class Screen(Object): pass def surface_write(self, surface, data, stride, size): + if surface is None: + return assert surface.nblocksy * stride == size surface.put_tile_raw(0, 0, surface.width, surface.height, data, stride) + def get_tex_transfer(self, texture, face, level, zslice, usage, x, y, w, h): + if texture is None: + return None + return Transfer(texture.get_surface(face, level, zslice), x, y, w, h) + + def tex_transfer_destroy(self, transfer): + self.interpreter.unregister_object(transfer) + + def transfer_write(self, transfer, stride, data, size): + if transfer is None: + return + transfer.surface.put_tile_raw(transfer.x, transfer.y, transfer.w, transfer.h, data, stride) + + def user_buffer_create(self, data, size): + # We don't really care to distinguish between user and regular buffers + buffer = self.real.buffer_create(size, + 4, + gallium.PIPE_BUFFER_USAGE_CPU_READ | + gallium.PIPE_BUFFER_USAGE_CPU_WRITE ) + assert size == len(data) + buffer.write(data) + return buffer + + def buffer_create(self, alignment, usage, size): + return self.real.buffer_create(size, alignment, usage) + + def buffer_destroy(self, buffer): + pass + + def buffer_write(self, buffer, data, size, offset=0): + assert size == len(data) + buffer.write(data) + + def fence_finish(self, fence, flags): + pass + + def fence_reference(self, dst, src): + pass + + def flush_frontbuffer(self, surface): + pass + class Context(Object): @@ -317,8 +374,8 @@ class Context(Object): def delete_sampler_state(self, state): pass - def bind_sampler_states(self, n, states): - for i in range(n): + def bind_sampler_states(self, num_states, states): + for i in range(num_states): self.real.set_sampler(i, states[i]) def create_rasterizer_state(self, state): @@ -375,7 +432,7 @@ class Context(Object): self.real.set_clip(_state) def dump_constant_buffer(self, buffer): - if verbose < 2: + if not self.interpreter.verbosity(2): return data = buffer.read() @@ -386,17 +443,17 @@ class Context(Object): sys.stdout.write('\tCONST[%2u] = {%10.4f, %10.4f, %10.4f, %10.4f}\n' % (index, x, y, z, w)) index += 1 - def set_constant_buffer(self, shader, index, state): - if state is not None: - self.real.set_constant_buffer(shader, index, state.buffer) + def set_constant_buffer(self, shader, index, buffer): + if buffer is not None: + self.real.set_constant_buffer(shader, index, buffer.buffer) - self.dump_constant_buffer(state.buffer) + self.dump_constant_buffer(buffer.buffer) def set_framebuffer_state(self, state): _state = gallium.Framebuffer() _state.width = state.width _state.height = state.height - _state.num_cbufs = state.num_cbufs + _state.nr_cbufs = state.nr_cbufs for i in range(len(state.cbufs)): _state.set_cbuf(i, state.cbufs[i]) _state.set_zsbuf(state.zsbuf) @@ -414,34 +471,34 @@ class Context(Object): def set_viewport_state(self, state): self.real.set_viewport(state) - def set_sampler_textures(self, n, textures): - for i in range(n): + def set_sampler_textures(self, num_textures, textures): + for i in range(num_textures): self.real.set_sampler_texture(i, textures[i]) - def set_vertex_buffers(self, n, vbufs): - self.vbufs = vbufs[0:n] - for i in range(n): - vbuf = vbufs[i] + def set_vertex_buffers(self, num_buffers, buffers): + self.vbufs = buffers[0:num_buffers] + for i in range(num_buffers): + vbuf = buffers[i] self.real.set_vertex_buffer( i, - pitch = vbuf.pitch, + stride = vbuf.stride, max_index = vbuf.max_index, buffer_offset = vbuf.buffer_offset, buffer = vbuf.buffer, ) - def set_vertex_elements(self, n, elements): - self.velems = elements[0:n] - for i in range(n): + def set_vertex_elements(self, num_elements, elements): + self.velems = elements[0:num_elements] + for i in range(num_elements): self.real.set_vertex_element(i, elements[i]) - self.real.set_vertex_elements(n) + self.real.set_vertex_elements(num_elements) def set_edgeflags(self, bitfield): # FIXME pass def dump_vertices(self, start, count): - if verbose < 2: + if not self.interpreter.verbosity(2): return for index in range(start, start + count): @@ -452,7 +509,7 @@ class Context(Object): for velem in self.velems: vbuf = self.vbufs[velem.vertex_buffer_index] - offset = vbuf.buffer_offset + velem.src_offset + vbuf.pitch*index + offset = vbuf.buffer_offset + velem.src_offset + vbuf.stride*index format = { gallium.PIPE_FORMAT_R32_FLOAT: 'f', gallium.PIPE_FORMAT_R32G32_FLOAT: '2f', @@ -468,7 +525,7 @@ class Context(Object): sys.stdout.write('\t},\n') def dump_indices(self, ibuf, isize, start, count): - if verbose < 2: + if not self.interpreter.verbosity(2): return format = { @@ -500,45 +557,51 @@ class Context(Object): self.dump_vertices(start, count) self.real.draw_arrays(mode, start, count) - - self.dirty = True + self._set_dirty() def draw_elements(self, indexBuffer, indexSize, mode, start, count): - if verbose >= 2: + if self.interpreter.verbosity(2): minindex, maxindex = self.dump_indices(indexBuffer, indexSize, start, count) self.dump_vertices(minindex, maxindex - minindex) self.real.draw_elements(indexBuffer, indexSize, mode, start, count) - - self.dirty = True + self._set_dirty() def draw_range_elements(self, indexBuffer, indexSize, minIndex, maxIndex, mode, start, count): - if verbose >= 2: + if self.interpreter.verbosity(2): minindex, maxindex = self.dump_indices(indexBuffer, indexSize, start, count) minindex = min(minindex, minIndex) maxindex = min(maxindex, maxIndex) self.dump_vertices(minindex, maxindex - minindex) self.real.draw_range_elements(indexBuffer, indexSize, minIndex, maxIndex, mode, start, count) - - self.dirty = True + self._set_dirty() + def _set_dirty(self): + if self.interpreter.options.step: + self._present() + else: + self.dirty = True + def flush(self, flags): self.real.flush(flags) if self.dirty: if flags & gallium.PIPE_FLUSH_FRAME: - self._update() + self._present() self.dirty = False return None - def clear(self, surface, value): - self.real.surface_clear(surface, value) + def clear(self, buffers, rgba, depth, stencil): + _rgba = gallium.FloatArray(4) + for i in range(4): + _rgba[i] = rgba[i] + self.real.clear(buffers, _rgba, depth, stencil) - def _update(self): + def _present(self): self.real.flush() if self.cbufs and self.cbufs[0]: - show_image(self.cbufs[0]) + self.interpreter.present(self.cbufs[0], "cbuf") class Interpreter(parser.TraceDumper): @@ -549,11 +612,13 @@ class Interpreter(parser.TraceDumper): ('pipe_screen', 'get_paramf'), )) - def __init__(self, stream): + def __init__(self, stream, options): parser.TraceDumper.__init__(self, stream) + self.options = options self.objects = {} self.result = None self.globl = Global(self, None) + self.call_no = None def register_object(self, address, object): self.objects[address] = object @@ -570,31 +635,70 @@ class Interpreter(parser.TraceDumper): self.interpret_call(call) def handle_call(self, call): + if self.options.stop and call.no >= self.options.stop: + sys.exit(0) if (call.klass, call.method) in self.ignore_calls: return - if verbose >= 1: + self.call_no = call.no + + if self.verbosity(1): parser.TraceDumper.handle_call(self, call) - args = [self.interpret_arg(arg) for name, arg in call.args] + args = [(str(name), self.interpret_arg(arg)) for name, arg in call.args] if call.klass: - obj = args[0] + name, obj = args[0] args = args[1:] else: obj = self.globl method = getattr(obj, call.method) - ret = method(*args) + ret = method(**dict(args)) if call.ret and isinstance(call.ret, model.Pointer): + if ret is None: + sys.stderr.write('warning: NULL returned\n') self.register_object(call.ret.address, ret) + self.call_no = None + def interpret_arg(self, node): translator = Translator(self) return translator.visit(node) + + def verbosity(self, level): + return self.options.verbosity >= level + + def present(self, surface, description): + if self.call_no < self.options.start: + return + + if self.options.images: + filename = '%s_%04u.png' % (description, self.call_no) + save_image(filename, surface) + else: + title = '%u. %s' % (self.call_no, description) + show_image(surface, title) +class Main(parser.Main): + + def get_optparser(self): + optparser = parser.Main.get_optparser(self) + optparser.add_option("-q", "--quiet", action="store_const", const=0, dest="verbosity", help="no messages") + optparser.add_option("-v", "--verbose", action="count", dest="verbosity", default=1, help="increase verbosity level") + optparser.add_option("-i", "--images", action="store_true", dest="images", default=False, help="save images instead of showing them") + optparser.add_option("-s", "--step", action="store_true", dest="step", default=False, help="step trhough every draw") + optparser.add_option("-f", "--from", action="store", type="int", dest="start", default=0, help="from call no") + optparser.add_option("-t", "--to", action="store", type="int", dest="stop", default=0, help="until call no") + return optparser + + def process_arg(self, stream, options): + parser = Interpreter(stream, options) + parser.parse() + + if __name__ == '__main__': - parser.main(Interpreter) + Main().main() diff --git a/src/gallium/state_trackers/python/retrace/model.py b/src/gallium/state_trackers/python/retrace/model.py index ae0f4327d7..d4a079fb1e 100755 --- a/src/gallium/state_trackers/python/retrace/model.py +++ b/src/gallium/state_trackers/python/retrace/model.py @@ -101,7 +101,8 @@ class Pointer(Node): class Call: - def __init__(self, klass, method, args, ret): + def __init__(self, no, klass, method, args, ret): + self.no = no self.klass = klass self.method = method self.args = args @@ -187,6 +188,7 @@ class PrettyPrinter: self.formatter.address(node.address) def visit_call(self, node): + self.formatter.text('%s ' % node.no) if node.klass is not None: self.formatter.function(node.klass + '::' + node.method) else: diff --git a/src/gallium/state_trackers/python/retrace/parser.py b/src/gallium/state_trackers/python/retrace/parser.py index 5205f2d8dd..b0f3e8a432 100755 --- a/src/gallium/state_trackers/python/retrace/parser.py +++ b/src/gallium/state_trackers/python/retrace/parser.py @@ -30,6 +30,7 @@ import sys import xml.parsers.expat import binascii +import optparse from model import * @@ -189,6 +190,10 @@ class XmlParser: class TraceParser(XmlParser): + def __init__(self, fp): + XmlParser.__init__(self, fp) + self.last_call_no = 0 + def parse(self): self.element_start('trace') while self.token.type not in (ELEMENT_END, EOF): @@ -199,6 +204,13 @@ class TraceParser(XmlParser): def parse_call(self): attrs = self.element_start('call') + try: + no = int(attrs['no']) + except KeyError: + self.last_call_no += 1 + no = self.last_call_no + else: + self.last_call_no = no klass = attrs['class'] method = attrs['method'] args = [] @@ -216,7 +228,7 @@ class TraceParser(XmlParser): raise TokenMismatch("<arg ...> or <ret ...>", self.token) self.element_end('call') - return Call(klass, method, args, ret) + return Call(no, klass, method, args, ret) def parse_arg(self): attrs = self.element_start('arg') @@ -342,16 +354,39 @@ class TraceDumper(TraceParser): self.formatter.newline() -def main(ParserFactory): - for arg in sys.argv[1:]: - if arg.endswith('.gz'): - import gzip - stream = gzip.GzipFile(arg, 'rt') +class Main: + '''Common main class for all retrace command line utilities.''' + + def __init__(self): + pass + + def main(self): + optparser = self.get_optparser() + (options, args) = optparser.parse_args(sys.argv[1:]) + + if args: + for arg in args: + if arg.endswith('.gz'): + from gzip import GzipFile + stream = GzipFile(arg, 'rt') + elif arg.endswith('.bz2'): + from bz2 import BZ2File + stream = BZ2File(arg, 'rt') + else: + stream = open(arg, 'rt') + self.process_arg(stream, options) else: - stream = open(arg, 'rt') - parser = ParserFactory(stream) + self.process_arg(stream, options) + + def get_optparser(self): + optparser = optparse.OptionParser( + usage="\n\t%prog [options] [traces] ...") + return optparser + + def process_arg(self, stream, options): + parser = TraceDumper(stream) parser.parse() if __name__ == '__main__': - main(TraceDumper) + Main().main() |