2 #############################################################################
4 # Copyright 2008 Tungsten Graphics, Inc.
6 # This program is free software: you can redistribute it and/or modify it
7 # under the terms of the GNU Lesser General Public License as published
8 # by the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #############################################################################
28 def make_image(surface
):
29 pixels
= gallium
.FloatArray(surface
.height
*surface
.width
*4)
30 surface
.get_tile_rgba(0, 0, surface
.width
, surface
.height
, pixels
)
35 size
=(surface
.width
, surface
.height
),
37 outpixels
= outimage
.load()
38 for y
in range(0, surface
.height
):
39 for x
in range(0, surface
.width
):
40 offset
= (y
*surface
.width
+ x
)*4
41 r
, g
, b
, a
= [int(pixels
[offset
+ ch
]*255) for ch
in range(4)]
42 outpixels
[x
, y
] = r
, g
, b
45 def save_image(filename
, surface
):
46 outimage
= make_image(surface
)
47 outimage
.save(filename
, "PNG")
49 def show_image(surface
):
50 outimage
= make_image(surface
)
53 from PIL
import Image
, ImageTk
56 root
.title('background image')
58 image1
= ImageTk
.PhotoImage(outimage
)
63 root
.geometry("%dx%d+%d+%d" % (w
, h
, x
, y
))
64 panel1
= tk
.Label(root
, image
=image1
)
65 panel1
.pack(side
='top', fill
='both', expand
='yes')
75 # A basic Python class can pass as a C-like structure
80 "pipe_blend_color": gallium
.BlendColor
,
81 "pipe_blend_state": gallium
.Blend
,
82 #"pipe_clip_state": gallium.Clip,
83 #"pipe_constant_buffer": gallium.ConstantBuffer,
84 "pipe_depth_state": gallium
.Depth
,
85 "pipe_stencil_state": gallium
.Stencil
,
86 "pipe_alpha_state": gallium
.Alpha
,
87 "pipe_depth_stencil_alpha_state": gallium
.DepthStencilAlpha
,
88 "pipe_format_block": gallium
.FormatBlock
,
89 #"pipe_framebuffer_state": gallium.Framebuffer,
90 "pipe_poly_stipple": gallium
.PolyStipple
,
91 "pipe_rasterizer_state": gallium
.Rasterizer
,
92 "pipe_sampler_state": gallium
.Sampler
,
93 "pipe_scissor_state": gallium
.Scissor
,
94 #"pipe_shader_state": gallium.Shader,
95 #"pipe_vertex_buffer": gallium.VertexBuffer,
96 "pipe_vertex_element": gallium
.VertexElement
,
97 "pipe_viewport_state": gallium
.Viewport
,
98 #"pipe_texture": gallium.Texture,
102 member_array_factories
= {
103 "pipe_rasterizer_state": {"sprite_coord_mode": gallium
.ByteArray
},
104 "pipe_poly_stipple": {"stipple": gallium
.UnsignedArray
},
105 "pipe_viewport_state": {"scale": gallium
.FloatArray
, "translate": gallium
.FloatArray
},
106 #"pipe_clip_state": {"ucp": gallium.FloatArray},
107 "pipe_depth_stencil_alpha_state": {"stencil": gallium
.StencilArray
},
108 "pipe_blend_color": {"color": gallium
.FloatArray
},
109 "pipe_sampler_state": {"border_color": gallium
.FloatArray
},
113 class Translator(model
.Visitor
):
114 """Translate model arguments into regular Python objects"""
116 def __init__(self
, interpreter
):
117 self
.interpreter
= interpreter
120 def visit(self
, node
):
125 def visit_literal(self
, node
):
126 self
.result
= node
.value
128 def visit_named_constant(self
, node
):
129 # lookup the named constant in the gallium module
130 self
.result
= getattr(gallium
, node
.name
)
132 def visit_array(self
, node
):
134 for element
in node
.elements
:
135 array
.append(self
.visit(element
))
138 def visit_struct(self
, node
):
139 struct_factory
= struct_factories
.get(node
.name
, Struct
)
140 struct
= struct_factory()
141 for member_name
, member_node
in node
.members
:
142 member_value
= self
.visit(member_node
)
144 array_factory
= member_array_factories
[node
.name
][member_name
]
148 assert isinstance(member_value
, list)
149 array
= array_factory(len(member_value
))
150 for i
in range(len(member_value
)):
151 array
[i
] = member_value
[i
]
153 #print node.name, member_name, member_value
154 assert isinstance(struct
, Struct
) or hasattr(struct
, member_name
)
155 setattr(struct
, member_name
, member_value
)
158 def visit_pointer(self
, node
):
159 self
.result
= self
.interpreter
.lookup_object(node
.address
)
164 def __init__(self
, interpreter
, real
):
165 self
.interpreter
= interpreter
169 class Global(Object
):
171 def __init__(self
, interpreter
, real
):
172 self
.interpreter
= interpreter
175 def pipe_winsys_create(self
):
176 return Winsys(self
.interpreter
, gallium
.Device())
178 def pipe_screen_create(self
, winsys
):
179 return Screen(self
.interpreter
, winsys
.real
)
181 def pipe_context_create(self
, screen
):
182 context
= screen
.real
.context_create()
183 return Context(self
.interpreter
, context
)
186 class Winsys(Object
):
188 def __init__(self
, interpreter
, real
):
189 self
.interpreter
= interpreter
195 def user_buffer_create(self
, data
, size
):
196 # We don't really care to distinguish between user and regular buffers
197 buffer = self
.real
.buffer_create(size
,
199 gallium
.PIPE_BUFFER_USAGE_CPU_READ |
200 gallium
.PIPE_BUFFER_USAGE_CPU_WRITE
)
201 buffer.write(data
, size
)
204 def buffer_create(self
, alignment
, usage
, size
):
205 return self
.real
.buffer_create(size
, alignment
, usage
)
207 def buffer_destroy(self
, buffer):
210 def buffer_write(self
, buffer, data
, size
):
211 buffer.write(data
, size
)
213 def fence_finish(self
, fence
, flags
):
216 def fence_reference(self
, dst
, src
):
219 def flush_frontbuffer(self
, surface
):
222 def surface_alloc(self
):
225 def surface_release(self
, surface
):
229 class Screen(Object
):
234 def get_vendor(self
):
237 def get_param(self
, param
):
240 def get_paramf(self
, param
):
243 def is_format_supported(self
, format
, target
, tex_usage
, geom_flags
):
244 return self
.real
.is_format_supported(format
, target
, tex_usage
, geom_flags
)
246 def texture_create(self
, template
):
247 return self
.real
.texture_create(
248 format
= template
.format
,
249 width
= template
.width
[0],
250 height
= template
.height
[0],
251 depth
= template
.depth
[0],
252 last_level
= template
.last_level
,
253 target
= template
.target
,
254 tex_usage
= template
.tex_usage
,
257 def texture_destroy(self
, texture
):
258 self
.interpreter
.unregister_object(texture
)
260 def texture_release(self
, surface
):
263 def get_tex_surface(self
, texture
, face
, level
, zslice
, usage
):
264 return texture
.get_surface(face
, level
, zslice
, usage
)
266 def tex_surface_destroy(self
, surface
):
267 self
.interpreter
.unregister_object(surface
)
269 def tex_surface_release(self
, surface
):
272 def surface_write(self
, surface
, data
, stride
, size
):
273 assert surface
.nblocksy
* stride
== size
274 surface
.put_tile_raw(0, 0, surface
.width
, surface
.height
, data
, stride
)
277 class Context(Object
):
279 def __init__(self
, interpreter
, real
):
280 Object
.__init
__(self
, interpreter
, real
)
287 def create_blend_state(self
, state
):
290 def bind_blend_state(self
, state
):
291 if state
is not None:
292 self
.real
.set_blend(state
)
294 def delete_blend_state(self
, state
):
297 def create_sampler_state(self
, state
):
300 def delete_sampler_state(self
, state
):
303 def bind_sampler_states(self
, n
, states
):
305 self
.real
.set_sampler(i
, states
[i
])
307 def create_rasterizer_state(self
, state
):
310 def bind_rasterizer_state(self
, state
):
311 if state
is not None:
312 self
.real
.set_rasterizer(state
)
314 def delete_rasterizer_state(self
, state
):
317 def create_depth_stencil_alpha_state(self
, state
):
320 def bind_depth_stencil_alpha_state(self
, state
):
321 if state
is not None:
322 self
.real
.set_depth_stencil_alpha(state
)
324 def delete_depth_stencil_alpha_state(self
, state
):
327 def create_fs_state(self
, state
):
328 tokens
= str(state
.tokens
)
329 shader
= gallium
.Shader(tokens
)
332 create_vs_state
= create_fs_state
334 def bind_fs_state(self
, state
):
335 self
.real
.set_fragment_shader(state
)
337 def bind_vs_state(self
, state
):
338 self
.real
.set_vertex_shader(state
)
340 def delete_fs_state(self
, state
):
343 delete_vs_state
= delete_fs_state
345 def set_blend_color(self
, state
):
346 self
.real
.set_blend_color(state
)
348 def set_clip_state(self
, state
):
349 _state
= gallium
.Clip()
353 ucp
= gallium
.FloatArray(gallium
.PIPE_MAX_CLIP_PLANES
*4)
354 for i
in range(len(state
.ucp
)):
355 for j
in range(len(state
.ucp
[i
])):
356 ucp
[i
*4 + j
] = state
.ucp
[i
][j
]
358 self
.real
.set_clip(_state
)
360 def set_constant_buffer(self
, shader
, index
, state
):
361 if state
is not None:
362 self
.real
.set_constant_buffer(shader
, index
, state
.buffer)
364 def set_framebuffer_state(self
, state
):
365 _state
= gallium
.Framebuffer()
366 _state
.width
= state
.width
367 _state
.height
= state
.height
368 _state
.num_cbufs
= state
.num_cbufs
369 for i
in range(len(state
.cbufs
)):
370 _state
.set_cbuf(i
, state
.cbufs
[i
])
371 _state
.set_zsbuf(state
.zsbuf
)
372 self
.real
.set_framebuffer(_state
)
374 self
.cbufs
= state
.cbufs
375 self
.zsbuf
= state
.zsbuf
377 def set_polygon_stipple(self
, state
):
378 self
.real
.set_polygon_stipple(state
)
380 def set_scissor_state(self
, state
):
381 self
.real
.set_scissor(state
)
383 def set_viewport_state(self
, state
):
384 self
.real
.set_viewport(state
)
386 def set_sampler_textures(self
, n
, textures
):
388 self
.real
.set_sampler_texture(i
, textures
[i
])
390 def set_vertex_buffers(self
, n
, vbufs
):
393 self
.real
.set_vertex_buffer(
396 max_index
= vbuf
.max_index
,
397 buffer_offset
= vbuf
.buffer_offset
,
398 buffer = vbuf
.buffer,
401 def set_vertex_elements(self
, n
, elements
):
403 self
.real
.set_vertex_element(i
, elements
[i
])
404 self
.real
.set_vertex_elements(n
)
406 def set_edgeflags(self
, bitfield
):
410 def draw_arrays(self
, mode
, start
, count
):
411 self
.real
.draw_arrays(mode
, start
, count
)
413 def draw_elements(self
, indexBuffer
, indexSize
, mode
, start
, count
):
414 self
.real
.draw_elements(indexBuffer
, indexSize
, mode
, start
, count
)
416 def draw_range_elements(self
, indexBuffer
, indexSize
, minIndex
, maxIndex
, mode
, start
, count
):
417 self
.real
.draw_range_elements(indexBuffer
, indexSize
, minIndex
, maxIndex
, mode
, start
, count
)
419 def flush(self
, flags
):
420 self
.real
.flush(flags
)
421 if flags
& gallium
.PIPE_FLUSH_FRAME
:
425 def clear(self
, surface
, value
):
426 self
.real
.surface_clear(surface
, value
)
431 if self
.cbufs
and self
.cbufs
[0]:
432 show_image(self
.cbufs
[0])
435 class Interpreter(parser
.TraceParser
):
437 def __init__(self
, stream
):
438 parser
.TraceParser
.__init
__(self
, stream
)
441 self
.globl
= Global(self
, None)
443 def register_object(self
, address
, object):
444 self
.objects
[address
] = object
446 def unregister_object(self
, object):
450 def lookup_object(self
, address
):
451 return self
.objects
[address
]
453 def interpret(self
, trace
):
454 for call
in trace
.calls
:
455 self
.interpret_call(call
)
457 def handle_call(self
, call
):
458 sys
.stderr
.write("%s\n" % call
)
460 args
= [self
.interpret_arg(arg
) for name
, arg
in call
.args
]
468 method
= getattr(obj
, call
.method
)
471 if call
.ret
and isinstance(call
.ret
, model
.Pointer
):
472 self
.register_object(call
.ret
.address
, ret
)
474 def interpret_arg(self
, node
):
475 translator
= Translator(self
)
476 return translator
.visit(node
)
479 if __name__
== '__main__':
480 parser
.main(Interpreter
)