mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 00:20:09 +01:00
trace: Bring state dump up to speed.
Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: Roland Scheidegger <sroland@vmware.com> Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17107>
This commit is contained in:
parent
0296050c0e
commit
c5ddb95953
1 changed files with 144 additions and 87 deletions
|
|
@ -1,9 +1,9 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
##########################################################################
|
##########################################################################
|
||||||
#
|
#
|
||||||
# Copyright 2008-2013, VMware, Inc.
|
# Copyright 2008-2021, VMware, Inc.
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
# copy of this software and associated documentation files (the
|
# copy of this software and associated documentation files (the
|
||||||
# "Software"), to deal in the Software without restriction, including
|
# "Software"), to deal in the Software without restriction, including
|
||||||
|
|
@ -11,11 +11,11 @@
|
||||||
# distribute, sub license, and/or sell copies of the Software, and to
|
# distribute, sub license, and/or sell copies of the Software, and to
|
||||||
# permit persons to whom the Software is furnished to do so, subject to
|
# permit persons to whom the Software is furnished to do so, subject to
|
||||||
# the following conditions:
|
# the following conditions:
|
||||||
#
|
#
|
||||||
# The above copyright notice and this permission notice (including the
|
# The above copyright notice and this permission notice (including the
|
||||||
# next paragraph) shall be included in all copies or substantial portions
|
# next paragraph) shall be included in all copies or substantial portions
|
||||||
# of the Software.
|
# of the Software.
|
||||||
#
|
#
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -50,12 +50,7 @@ except ImportError:
|
||||||
#
|
#
|
||||||
# Some constants
|
# Some constants
|
||||||
#
|
#
|
||||||
PIPE_BUFFER = 0
|
PIPE_BUFFER = 'PIPE_BUFFER'
|
||||||
PIPE_SHADER_VERTEX = 0
|
|
||||||
PIPE_SHADER_FRAGMENT = 1
|
|
||||||
PIPE_SHADER_GEOMETRY = 2
|
|
||||||
PIPE_SHADER_COMPUTE = 3
|
|
||||||
PIPE_SHADER_TYPES = 4
|
|
||||||
|
|
||||||
|
|
||||||
def serialize(obj):
|
def serialize(obj):
|
||||||
|
|
@ -89,7 +84,7 @@ def serialize(obj):
|
||||||
|
|
||||||
class Struct:
|
class Struct:
|
||||||
"""C-like struct.
|
"""C-like struct.
|
||||||
|
|
||||||
Python doesn't have C structs, but do its dynamic nature, any object is
|
Python doesn't have C structs, but do its dynamic nature, any object is
|
||||||
pretty close.
|
pretty close.
|
||||||
"""
|
"""
|
||||||
|
|
@ -119,22 +114,22 @@ class Translator(model.Visitor):
|
||||||
self.result = None
|
self.result = None
|
||||||
node.visit(self)
|
node.visit(self)
|
||||||
return self.result
|
return self.result
|
||||||
|
|
||||||
def visit_literal(self, node):
|
def visit_literal(self, node):
|
||||||
self.result = node.value
|
self.result = node.value
|
||||||
|
|
||||||
def visit_blob(self, node):
|
def visit_blob(self, node):
|
||||||
self.result = node
|
self.result = node
|
||||||
|
|
||||||
def visit_named_constant(self, node):
|
def visit_named_constant(self, node):
|
||||||
self.result = node.name
|
self.result = node.name
|
||||||
|
|
||||||
def visit_array(self, node):
|
def visit_array(self, node):
|
||||||
array = []
|
array = []
|
||||||
for element in node.elements:
|
for element in node.elements:
|
||||||
array.append(self.visit(element))
|
array.append(self.visit(element))
|
||||||
self.result = array
|
self.result = array
|
||||||
|
|
||||||
def visit_struct(self, node):
|
def visit_struct(self, node):
|
||||||
struct = Struct()
|
struct = Struct()
|
||||||
for member_name, member_node in node.members:
|
for member_name, member_node in node.members:
|
||||||
|
|
@ -142,17 +137,17 @@ class Translator(model.Visitor):
|
||||||
member_value = self.visit(member_node)
|
member_value = self.visit(member_node)
|
||||||
setattr(struct, member_name, member_value)
|
setattr(struct, member_name, member_value)
|
||||||
self.result = struct
|
self.result = struct
|
||||||
|
|
||||||
def visit_pointer(self, node):
|
def visit_pointer(self, node):
|
||||||
self.result = self.interpreter.lookup_object(node.address)
|
self.result = self.interpreter.lookup_object(node.address)
|
||||||
|
|
||||||
|
|
||||||
class Dispatcher:
|
class Dispatcher:
|
||||||
'''Base class for classes whose methods can dispatch Gallium calls.'''
|
'''Base class for classes whose methods can dispatch Gallium calls.'''
|
||||||
|
|
||||||
def __init__(self, interpreter):
|
def __init__(self, interpreter):
|
||||||
self.interpreter = interpreter
|
self.interpreter = interpreter
|
||||||
|
|
||||||
|
|
||||||
class Global(Dispatcher):
|
class Global(Dispatcher):
|
||||||
'''Global name space.
|
'''Global name space.
|
||||||
|
|
@ -163,11 +158,11 @@ class Global(Dispatcher):
|
||||||
|
|
||||||
def pipe_screen_create(self):
|
def pipe_screen_create(self):
|
||||||
return Screen(self.interpreter)
|
return Screen(self.interpreter)
|
||||||
|
|
||||||
def pipe_context_create(self, screen):
|
def pipe_context_create(self, screen):
|
||||||
return screen.context_create()
|
return screen.context_create()
|
||||||
|
|
||||||
|
|
||||||
class Transfer:
|
class Transfer:
|
||||||
'''pipe_transfer'''
|
'''pipe_transfer'''
|
||||||
|
|
||||||
|
|
@ -180,7 +175,7 @@ class Transfer:
|
||||||
|
|
||||||
class Screen(Dispatcher):
|
class Screen(Dispatcher):
|
||||||
'''pipe_screen'''
|
'''pipe_screen'''
|
||||||
|
|
||||||
def __init__(self, interpreter):
|
def __init__(self, interpreter):
|
||||||
Dispatcher.__init__(self, interpreter)
|
Dispatcher.__init__(self, interpreter)
|
||||||
|
|
||||||
|
|
@ -189,10 +184,7 @@ class Screen(Dispatcher):
|
||||||
|
|
||||||
def context_create(self, priv=None, flags=0):
|
def context_create(self, priv=None, flags=0):
|
||||||
return Context(self.interpreter)
|
return Context(self.interpreter)
|
||||||
|
|
||||||
def is_format_supported(self, format, target, sample_count, bind, geom_flags):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def resource_create(self, templat):
|
def resource_create(self, templat):
|
||||||
resource = templat
|
resource = templat
|
||||||
# Normalize state to avoid spurious differences
|
# Normalize state to avoid spurious differences
|
||||||
|
|
@ -205,18 +197,35 @@ class Screen(Dispatcher):
|
||||||
del resource.format
|
del resource.format
|
||||||
return resource
|
return resource
|
||||||
|
|
||||||
|
resource_create_unbacked = resource_create
|
||||||
|
|
||||||
|
def allocate_memory(screen, size):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def free_memory(screen, pmem):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def map_memory(screen, pmem):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def unmap_memory(screen, pmem):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def resource_bind_backing(screen, resource, pmem, offset):
|
||||||
|
pass
|
||||||
|
|
||||||
def resource_destroy(self, resource):
|
def resource_destroy(self, resource):
|
||||||
self.interpreter.unregister_object(resource)
|
self.interpreter.unregister_object(resource)
|
||||||
|
|
||||||
def fence_finish(self, fence, timeout=None, ctx=None):
|
def fence_finish(self, fence, timeout=None, ctx=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def fence_signalled(self, fence):
|
def fence_signalled(self, fence):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def fence_reference(self, dst, src):
|
def fence_reference(self, dst, src):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def flush_frontbuffer(self, resource):
|
def flush_frontbuffer(self, resource):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -225,7 +234,7 @@ class Context(Dispatcher):
|
||||||
'''pipe_context'''
|
'''pipe_context'''
|
||||||
|
|
||||||
# Internal methods variable should be prefixed with '_'
|
# Internal methods variable should be prefixed with '_'
|
||||||
|
|
||||||
def __init__(self, interpreter):
|
def __init__(self, interpreter):
|
||||||
Dispatcher.__init__(self, interpreter)
|
Dispatcher.__init__(self, interpreter)
|
||||||
|
|
||||||
|
|
@ -236,28 +245,39 @@ class Context(Dispatcher):
|
||||||
self._state.vertex_buffers = []
|
self._state.vertex_buffers = []
|
||||||
self._state.vertex_elements = []
|
self._state.vertex_elements = []
|
||||||
self._state.vs = Struct()
|
self._state.vs = Struct()
|
||||||
|
self._state.tcs = Struct()
|
||||||
|
self._state.tes = Struct()
|
||||||
self._state.gs = Struct()
|
self._state.gs = Struct()
|
||||||
self._state.fs = Struct()
|
self._state.fs = Struct()
|
||||||
self._state.vs.shader = None
|
self._state.vs.shader = None
|
||||||
|
self._state.tcs.shader = None
|
||||||
|
self._state.tes.shader = None
|
||||||
self._state.gs.shader = None
|
self._state.gs.shader = None
|
||||||
self._state.fs.shader = None
|
self._state.fs.shader = None
|
||||||
self._state.vs.sampler = []
|
self._state.vs.sampler = []
|
||||||
|
self._state.tcs.sampler = []
|
||||||
|
self._state.tes.sampler = []
|
||||||
self._state.gs.sampler = []
|
self._state.gs.sampler = []
|
||||||
self._state.fs.sampler = []
|
self._state.fs.sampler = []
|
||||||
self._state.vs.sampler_views = []
|
self._state.vs.sampler_views = []
|
||||||
|
self._state.tcs.sampler_views = []
|
||||||
|
self._state.tes.sampler_views = []
|
||||||
self._state.gs.sampler_views = []
|
self._state.gs.sampler_views = []
|
||||||
self._state.fs.sampler_views = []
|
self._state.fs.sampler_views = []
|
||||||
self._state.vs.constant_buffer = []
|
self._state.vs.constant_buffer = []
|
||||||
|
self._state.tcs.constant_buffer = []
|
||||||
|
self._state.tes.constant_buffer = []
|
||||||
self._state.gs.constant_buffer = []
|
self._state.gs.constant_buffer = []
|
||||||
self._state.fs.constant_buffer = []
|
self._state.fs.constant_buffer = []
|
||||||
self._state.render_condition_condition = 0
|
self._state.render_condition_condition = 0
|
||||||
self._state.render_condition_mode = 0
|
self._state.render_condition_mode = 0
|
||||||
|
self._state.sample_mask = 0xffffffff
|
||||||
|
|
||||||
self._draw_no = 0
|
self._draw_no = 0
|
||||||
|
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def create_blend_state(self, state):
|
def create_blend_state(self, state):
|
||||||
# Normalize state to avoid spurious differences
|
# Normalize state to avoid spurious differences
|
||||||
if not state.logicop_enable:
|
if not state.logicop_enable:
|
||||||
|
|
@ -277,7 +297,7 @@ class Context(Dispatcher):
|
||||||
|
|
||||||
def delete_blend_state(self, state):
|
def delete_blend_state(self, state):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def create_sampler_state(self, state):
|
def create_sampler_state(self, state):
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
@ -300,21 +320,21 @@ class Context(Dispatcher):
|
||||||
def bind_fragment_sampler_states(self, num_states, states):
|
def bind_fragment_sampler_states(self, num_states, states):
|
||||||
# XXX: deprecated method
|
# XXX: deprecated method
|
||||||
self._state.fs.sampler = states
|
self._state.fs.sampler = states
|
||||||
|
|
||||||
def create_rasterizer_state(self, state):
|
def create_rasterizer_state(self, state):
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def bind_rasterizer_state(self, state):
|
def bind_rasterizer_state(self, state):
|
||||||
self._state.rasterizer = state
|
self._state.rasterizer = state
|
||||||
|
|
||||||
def delete_rasterizer_state(self, state):
|
def delete_rasterizer_state(self, state):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def create_depth_stencil_alpha_state(self, state):
|
def create_depth_stencil_alpha_state(self, state):
|
||||||
# Normalize state to avoid spurious differences
|
# Normalize state to avoid spurious differences
|
||||||
if not state.alpha.enabled:
|
if not state.alpha_enabled:
|
||||||
del state.alpha.func
|
del state.alpha_func
|
||||||
del state.alpha.ref_value
|
del state.alpha_ref_value
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
if not state.stencil[i].enabled:
|
if not state.stencil[i].enabled:
|
||||||
del state.stencil[i].func
|
del state.stencil[i].func
|
||||||
|
|
@ -322,7 +342,7 @@ class Context(Dispatcher):
|
||||||
|
|
||||||
def bind_depth_stencil_alpha_state(self, state):
|
def bind_depth_stencil_alpha_state(self, state):
|
||||||
self._state.depth_stencil_alpha = state
|
self._state.depth_stencil_alpha = state
|
||||||
|
|
||||||
def delete_depth_stencil_alpha_state(self, state):
|
def delete_depth_stencil_alpha_state(self, state):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -335,22 +355,35 @@ class Context(Dispatcher):
|
||||||
return state
|
return state
|
||||||
|
|
||||||
create_vs_state = _create_shader_state
|
create_vs_state = _create_shader_state
|
||||||
|
create_tcs_state = _create_shader_state
|
||||||
|
create_tes_state = _create_shader_state
|
||||||
create_gs_state = _create_shader_state
|
create_gs_state = _create_shader_state
|
||||||
create_fs_state = _create_shader_state
|
create_fs_state = _create_shader_state
|
||||||
|
|
||||||
def bind_vs_state(self, state):
|
def bind_vs_state(self, state):
|
||||||
self._state.vs.shader = state
|
self._state.vs.shader = state
|
||||||
|
|
||||||
|
def bind_tcs_state(self, state):
|
||||||
|
self._state.tcs.shader = state
|
||||||
|
|
||||||
|
def bind_tes_state(self, state):
|
||||||
|
self._state.tes.shader = state
|
||||||
|
|
||||||
def bind_gs_state(self, state):
|
def bind_gs_state(self, state):
|
||||||
self._state.gs.shader = state
|
self._state.gs.shader = state
|
||||||
|
|
||||||
def bind_fs_state(self, state):
|
def bind_fs_state(self, state):
|
||||||
self._state.fs.shader = state
|
self._state.fs.shader = state
|
||||||
|
|
||||||
|
def bind_tcz_state(self, state):
|
||||||
|
self._state.tcs.shader = state
|
||||||
|
|
||||||
def _delete_shader_state(self, state):
|
def _delete_shader_state(self, state):
|
||||||
return state
|
return state
|
||||||
|
|
||||||
delete_vs_state = _delete_shader_state
|
delete_vs_state = _delete_shader_state
|
||||||
|
delete_tcs_state = _delete_shader_state
|
||||||
|
delete_tes_state = _delete_shader_state
|
||||||
delete_gs_state = _delete_shader_state
|
delete_gs_state = _delete_shader_state
|
||||||
delete_fs_state = _delete_shader_state
|
delete_fs_state = _delete_shader_state
|
||||||
|
|
||||||
|
|
@ -377,15 +410,19 @@ class Context(Dispatcher):
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
def _get_stage_state(self, shader):
|
def _get_stage_state(self, shader):
|
||||||
if shader == PIPE_SHADER_VERTEX:
|
if shader == 'PIPE_SHADER_VERTEX':
|
||||||
return self._state.vs
|
return self._state.vs
|
||||||
if shader == PIPE_SHADER_GEOMETRY:
|
if shader == 'PIPE_SHADER_TESS_CTRL':
|
||||||
|
return self._state.tcs
|
||||||
|
if shader == 'PIPE_SHADER_TESS_EVAL':
|
||||||
|
return self._state.tes
|
||||||
|
if shader == 'PIPE_SHADER_GEOMETRY':
|
||||||
return self._state.gs
|
return self._state.gs
|
||||||
if shader == PIPE_SHADER_FRAGMENT:
|
if shader == 'PIPE_SHADER_FRAGMENT':
|
||||||
return self._state.fs
|
return self._state.fs
|
||||||
assert False
|
assert False
|
||||||
|
|
||||||
def set_constant_buffer(self, shader, index, constant_buffer):
|
def set_constant_buffer(self, shader, index, take_ownership, constant_buffer):
|
||||||
self._update(self._get_stage_state(shader).constant_buffer, index, 1, [constant_buffer])
|
self._update(self._get_stage_state(shader).constant_buffer, index, 1, [constant_buffer])
|
||||||
|
|
||||||
def set_framebuffer_state(self, state):
|
def set_framebuffer_state(self, state):
|
||||||
|
|
@ -417,7 +454,7 @@ class Context(Dispatcher):
|
||||||
def sampler_view_destroy(self, view):
|
def sampler_view_destroy(self, view):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def set_sampler_views(self, shader, start, num, views):
|
def set_sampler_views(self, shader, start, num, unbind_num_trailing_slots, take_ownership, views):
|
||||||
# FIXME: Handle non-zero start
|
# FIXME: Handle non-zero start
|
||||||
assert start == 0
|
assert start == 0
|
||||||
self._get_stage_state(shader).sampler_views = views
|
self._get_stage_state(shader).sampler_views = views
|
||||||
|
|
@ -434,9 +471,9 @@ class Context(Dispatcher):
|
||||||
# XXX: deprecated
|
# XXX: deprecated
|
||||||
self._state.vs.sampler_views = views
|
self._state.vs.sampler_views = views
|
||||||
|
|
||||||
def set_vertex_buffers(self, start_slot, num_buffers, buffers):
|
def set_vertex_buffers(self, start_slot, num_buffers, unbind_num_trailing_slots, take_ownership, buffers):
|
||||||
self._update(self._state.vertex_buffers, start_slot, num_buffers, buffers)
|
self._update(self._state.vertex_buffers, start_slot, num_buffers, buffers)
|
||||||
|
|
||||||
def create_vertex_elements_state(self, num_elements, elements):
|
def create_vertex_elements_state(self, num_elements, elements):
|
||||||
return elements[0:num_elements]
|
return elements[0:num_elements]
|
||||||
|
|
||||||
|
|
@ -449,6 +486,9 @@ class Context(Dispatcher):
|
||||||
def set_index_buffer(self, ib):
|
def set_index_buffer(self, ib):
|
||||||
self._state.index_buffer = ib
|
self._state.index_buffer = ib
|
||||||
|
|
||||||
|
def set_patch_vertices(self, patch_vertices):
|
||||||
|
pass
|
||||||
|
|
||||||
# Don't dump more than this number of indices/vertices
|
# Don't dump more than this number of indices/vertices
|
||||||
MAX_ELEMENTS = 16
|
MAX_ELEMENTS = 16
|
||||||
|
|
||||||
|
|
@ -456,7 +496,7 @@ class Context(Dispatcher):
|
||||||
'''Merge the vertices into our state.'''
|
'''Merge the vertices into our state.'''
|
||||||
|
|
||||||
index_size = self._state.index_buffer.index_size
|
index_size = self._state.index_buffer.index_size
|
||||||
|
|
||||||
format = {
|
format = {
|
||||||
1: 'B',
|
1: 'B',
|
||||||
2: 'H',
|
2: 'H',
|
||||||
|
|
@ -543,7 +583,13 @@ class Context(Dispatcher):
|
||||||
self._state.so_targets = tgs
|
self._state.so_targets = tgs
|
||||||
self._state.offsets = offsets
|
self._state.offsets = offsets
|
||||||
|
|
||||||
def draw_vbo(self, info):
|
def set_sample_mask(self, sample_mask):
|
||||||
|
self._state.sample_mask = sample_mask
|
||||||
|
|
||||||
|
def set_min_samples(self, min_samples):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def draw_vbo(self, info, drawid_offset, indirect, draws, num_draws):
|
||||||
self._draw_no += 1
|
self._draw_no += 1
|
||||||
|
|
||||||
if self.interpreter.call_no < self.interpreter.options.call and \
|
if self.interpreter.call_no < self.interpreter.options.call and \
|
||||||
|
|
@ -557,8 +603,8 @@ class Context(Dispatcher):
|
||||||
if info.index_size != 0:
|
if info.index_size != 0:
|
||||||
min_index, max_index = self._merge_indices(info)
|
min_index, max_index = self._merge_indices(info)
|
||||||
else:
|
else:
|
||||||
min_index = info.start
|
min_index = draws[0].start
|
||||||
max_index = info.start + info.count - 1
|
max_index = draws[0].start + draws[0].count - 1
|
||||||
self._merge_vertices(min_index, max_index - min_index + 1)
|
self._merge_vertices(min_index, max_index - min_index + 1)
|
||||||
|
|
||||||
self._dump_state()
|
self._dump_state()
|
||||||
|
|
@ -566,33 +612,32 @@ class Context(Dispatcher):
|
||||||
_dclRE = re.compile('^DCL\s+(IN|OUT|SAMP|SVIEW)\[([0-9]+)\].*$', re.MULTILINE)
|
_dclRE = re.compile('^DCL\s+(IN|OUT|SAMP|SVIEW)\[([0-9]+)\].*$', re.MULTILINE)
|
||||||
|
|
||||||
def _normalize_stage_state(self, stage):
|
def _normalize_stage_state(self, stage):
|
||||||
|
|
||||||
registers = {}
|
|
||||||
|
|
||||||
if stage.shader is not None and stage.shader.tokens is not None:
|
if stage.shader is not None and stage.shader.tokens is not None:
|
||||||
|
registers = {}
|
||||||
|
|
||||||
for mo in self._dclRE.finditer(stage.shader.tokens):
|
for mo in self._dclRE.finditer(stage.shader.tokens):
|
||||||
file_ = mo.group(1)
|
file_ = mo.group(1)
|
||||||
index = mo.group(2)
|
index = mo.group(2)
|
||||||
register = registers.setdefault(file_, set())
|
register = registers.setdefault(file_, set())
|
||||||
register.add(int(index))
|
register.add(int(index))
|
||||||
|
|
||||||
if 'SAMP' in registers and 'SVIEW' not in registers:
|
if 'SAMP' in registers and 'SVIEW' not in registers:
|
||||||
registers['SVIEW'] = registers['SAMP']
|
registers['SVIEW'] = registers['SAMP']
|
||||||
|
|
||||||
mapping = [
|
mapping = [
|
||||||
#("CONST", "constant_buffer"),
|
#("CONST", "constant_buffer"),
|
||||||
("SAMP", "sampler"),
|
("SAMP", "sampler"),
|
||||||
("SVIEW", "sampler_views"),
|
("SVIEW", "sampler_views"),
|
||||||
]
|
]
|
||||||
|
|
||||||
for fileName, attrName in mapping:
|
for fileName, attrName in mapping:
|
||||||
register = registers.setdefault(fileName, set())
|
register = registers.setdefault(fileName, set())
|
||||||
attr = getattr(stage, attrName)
|
attr = getattr(stage, attrName)
|
||||||
for index in range(len(attr)):
|
for index in range(len(attr)):
|
||||||
if index not in register:
|
if index not in register:
|
||||||
attr[index] = None
|
attr[index] = None
|
||||||
while attr and attr[-1] is None:
|
while attr and attr[-1] is None:
|
||||||
attr.pop()
|
attr.pop()
|
||||||
|
|
||||||
def _dump_state(self):
|
def _dump_state(self):
|
||||||
'''Dump our state to JSON and terminate.'''
|
'''Dump our state to JSON and terminate.'''
|
||||||
|
|
@ -600,6 +645,8 @@ class Context(Dispatcher):
|
||||||
state = copy.deepcopy(self._state)
|
state = copy.deepcopy(self._state)
|
||||||
|
|
||||||
self._normalize_stage_state(state.vs)
|
self._normalize_stage_state(state.vs)
|
||||||
|
self._normalize_stage_state(state.tcs)
|
||||||
|
self._normalize_stage_state(state.tes)
|
||||||
self._normalize_stage_state(state.gs)
|
self._normalize_stage_state(state.gs)
|
||||||
self._normalize_stage_state(state.fs)
|
self._normalize_stage_state(state.fs)
|
||||||
|
|
||||||
|
|
@ -630,13 +677,13 @@ class Context(Dispatcher):
|
||||||
|
|
||||||
def is_resource_referenced(self, texture, face, level):
|
def is_resource_referenced(self, texture, face, level):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_transfer(self, texture, sr, usage, box):
|
def get_transfer(self, texture, sr, usage, box):
|
||||||
if texture is None:
|
if texture is None:
|
||||||
return None
|
return None
|
||||||
transfer = Transfer(texture, sr, usage, box)
|
transfer = Transfer(texture, sr, usage, box)
|
||||||
return transfer
|
return transfer
|
||||||
|
|
||||||
def tex_transfer_destroy(self, transfer):
|
def tex_transfer_destroy(self, transfer):
|
||||||
self.interpreter.unregister_object(transfer)
|
self.interpreter.unregister_object(transfer)
|
||||||
|
|
||||||
|
|
@ -672,11 +719,14 @@ class Context(Dispatcher):
|
||||||
|
|
||||||
def clear(self, buffers, color, depth, stencil, scissor_state=None):
|
def clear(self, buffers, color, depth, stencil, scissor_state=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def clear_render_target(self, dst, rgba, dstx, dsty, width, height):
|
def clear_render_target(self, dst, rgba, dstx, dsty, width, height, render_condition_enabled):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def clear_depth_stencil(self, dst, clear_flags, depth, stencil, dstx, dsty, width, height):
|
def clear_depth_stencil(self, dst, clear_flags, depth, stencil, dstx, dsty, width, height, render_condition_enabled):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def clear_texture(self, res, level, box, **color):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def create_surface(self, resource, surf_tmpl):
|
def create_surface(self, resource, surf_tmpl):
|
||||||
|
|
@ -689,7 +739,7 @@ class Context(Dispatcher):
|
||||||
|
|
||||||
def create_query(self, query_type, index):
|
def create_query(self, query_type, index):
|
||||||
return query_type
|
return query_type
|
||||||
|
|
||||||
def destroy_query(self, query):
|
def destroy_query(self, query):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -710,17 +760,24 @@ class Context(Dispatcher):
|
||||||
class Interpreter(parser.SimpleTraceDumper):
|
class Interpreter(parser.SimpleTraceDumper):
|
||||||
'''Specialization of a trace parser that interprets the calls as it goes
|
'''Specialization of a trace parser that interprets the calls as it goes
|
||||||
along.'''
|
along.'''
|
||||||
|
|
||||||
ignoredCalls = set((
|
ignoredCalls = set((
|
||||||
('pipe_screen', 'is_format_supported'),
|
('pipe_screen', 'is_format_supported'),
|
||||||
('pipe_screen', 'get_name'),
|
('pipe_screen', 'get_name'),
|
||||||
('pipe_screen', 'get_vendor'),
|
('pipe_screen', 'get_vendor'),
|
||||||
|
('pipe_screen', 'get_device_uuid'),
|
||||||
|
('pipe_screen', 'get_driver_uuid'),
|
||||||
|
('pipe_screen', 'get_compiler_options'),
|
||||||
('pipe_screen', 'get_param'),
|
('pipe_screen', 'get_param'),
|
||||||
('pipe_screen', 'get_paramf'),
|
('pipe_screen', 'get_paramf'),
|
||||||
('pipe_screen', 'get_shader_param'),
|
('pipe_screen', 'get_shader_param'),
|
||||||
|
('pipe_screen', 'get_compute_param'),
|
||||||
('pipe_screen', 'get_disk_shader_cache'),
|
('pipe_screen', 'get_disk_shader_cache'),
|
||||||
('pipe_context', 'clear_render_target'), # XXX workaround trace bugs
|
('pipe_context', 'clear_render_target'), # XXX workaround trace bugs
|
||||||
('pipe_context', 'flush_resource'),
|
('pipe_context', 'flush_resource'),
|
||||||
|
('pipe_context', 'buffer_map'),
|
||||||
|
('pipe_context', 'texture_map'),
|
||||||
|
('pipe_context', 'transfer_unmap'),
|
||||||
))
|
))
|
||||||
|
|
||||||
def __init__(self, stream, options, formatter):
|
def __init__(self, stream, options, formatter):
|
||||||
|
|
@ -732,7 +789,7 @@ class Interpreter(parser.SimpleTraceDumper):
|
||||||
|
|
||||||
def register_object(self, address, object):
|
def register_object(self, address, object):
|
||||||
self.objects[address] = object
|
self.objects[address] = object
|
||||||
|
|
||||||
def unregister_object(self, object):
|
def unregister_object(self, object):
|
||||||
# TODO
|
# TODO
|
||||||
pass
|
pass
|
||||||
|
|
@ -743,7 +800,7 @@ class Interpreter(parser.SimpleTraceDumper):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# Could happen, e.g., with user memory pointers
|
# Could happen, e.g., with user memory pointers
|
||||||
return address
|
return address
|
||||||
|
|
||||||
def interpret(self, trace):
|
def interpret(self, trace):
|
||||||
for call in trace.calls:
|
for call in trace.calls:
|
||||||
self.interpret_call(call)
|
self.interpret_call(call)
|
||||||
|
|
@ -761,9 +818,9 @@ class Interpreter(parser.SimpleTraceDumper):
|
||||||
parser.TraceDumper.handle_call(self, call)
|
parser.TraceDumper.handle_call(self, call)
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
args = [(str(name), 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:
|
if call.klass:
|
||||||
name, obj = args[0]
|
name, obj = args[0]
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
|
|
@ -772,7 +829,7 @@ class Interpreter(parser.SimpleTraceDumper):
|
||||||
|
|
||||||
method = getattr(obj, call.method)
|
method = getattr(obj, call.method)
|
||||||
ret = method(**dict(args))
|
ret = method(**dict(args))
|
||||||
|
|
||||||
# Keep track of created pointer objects.
|
# Keep track of created pointer objects.
|
||||||
if call.ret and isinstance(call.ret, model.Pointer):
|
if call.ret and isinstance(call.ret, model.Pointer):
|
||||||
if ret is None:
|
if ret is None:
|
||||||
|
|
@ -787,7 +844,7 @@ class Interpreter(parser.SimpleTraceDumper):
|
||||||
|
|
||||||
def verbosity(self, level):
|
def verbosity(self, level):
|
||||||
return self.options.verbosity >= level
|
return self.options.verbosity >= level
|
||||||
|
|
||||||
|
|
||||||
class DumpStateOptions(parser.ParseOptions):
|
class DumpStateOptions(parser.ParseOptions):
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue