aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2015-04-20 21:25:25 +0200
committermarha <marha@users.sourceforge.net>2015-04-20 21:25:25 +0200
commit4ba9be2882d9f1567809edb0a31fcdf11320d41f (patch)
treef796ab7a5044f9dd99aac7cb9a7c836857987635
parent82c8df11062f72a7d467e26cedbbd8b322ff7a70 (diff)
downloadvcxsrv-4ba9be2882d9f1567809edb0a31fcdf11320d41f.tar.gz
vcxsrv-4ba9be2882d9f1567809edb0a31fcdf11320d41f.tar.bz2
vcxsrv-4ba9be2882d9f1567809edb0a31fcdf11320d41f.zip
randrproto xkeyboard-config fontconfig libX11 libXdmcp libXmu pixman xkbcomp xserver mesa git update 20 Apr 2015
xserver commit b1029716e41e252f149b82124a149da180607c96 xkeyboard-config commit 7d00bcc2d9c3944bbdfcbe472ee3299729dc7687 libX11 commit 748d47e69f5c12d8557d56a8a8ec166588da7b93 libXdmcp commit b10f382e3aa2e86cd5a2bc27d6758da55f0ab1f6 xkbcomp commit 1ae525b3d236b59e6437b2b5433d460e18370973 pixman commit 58e21d3e45c5227c2ca9ac00cf044f22a7975180 randrproto commit 98da0d6e48b7d124d6788ea568e9f9e3dc204322 libXmu commit 4459e6940fe3fdf26a8d5d4c71989498bc400a62 fontconfig commit 07be485a0a84995ce69bf60e3b1bb22cb35f6b0e mesa commit c1485f4b7d044724b3dbc1011f3c3a8a53132010
-rw-r--r--X11/extensions/randr.h10
-rw-r--r--X11/extensions/randrproto.h59
-rw-r--r--X11/extensions/randrproto.txt215
-rw-r--r--fontconfig/doc/fontconfig-user.sgml2
-rw-r--r--fontconfig/src/fccfg.c6
-rw-r--r--fontconfig/src/fcdir.c4
-rw-r--r--fontconfig/src/fcrange.c2
-rw-r--r--fontconfig/src/fcxml.c23
-rw-r--r--fontconfig/test/Makefile.am7
-rw-r--r--fontconfig/test/test-bz89617.c38
-rw-r--r--libX11/nls/compose.dir.pre4
-rw-r--r--libX11/nls/en_US.UTF-8/Compose.pre3
-rw-r--r--libX11/nls/locale.alias.pre10
-rw-r--r--libX11/nls/locale.dir.pre6
-rw-r--r--libXdmcp/configure.ac8
-rw-r--r--libXmu/src/RdBitF.c1
-rw-r--r--libXmu/src/StrToCurs.c4
-rw-r--r--mesalib/.gitignore1
-rw-r--r--mesalib/Makefile.am15
-rw-r--r--mesalib/configure.ac78
-rw-r--r--mesalib/docs/GL3.txt21
-rw-r--r--mesalib/docs/README.WIN324
-rw-r--r--mesalib/docs/faq.html13
-rw-r--r--mesalib/docs/index.html12
-rw-r--r--mesalib/docs/llvmpipe.html32
-rw-r--r--mesalib/docs/relnotes.html2
-rw-r--r--mesalib/docs/relnotes/10.5.2.html130
-rw-r--r--mesalib/docs/relnotes/10.5.3.html125
-rw-r--r--mesalib/docs/relnotes/10.6.0.html8
-rw-r--r--mesalib/docs/specs/MESA_image_dma_buf_export.txt142
-rw-r--r--mesalib/docs/viewperf.html94
-rw-r--r--mesalib/include/EGL/eglmesaext.h8
-rw-r--r--mesalib/include/GL/internal/dri_interface.h4
-rw-r--r--mesalib/include/GL/osmesa.h6
-rw-r--r--mesalib/include/c99_math.h8
-rw-r--r--mesalib/m4/ax_check_python_mako_module.m42
-rw-r--r--mesalib/scons/gallium.py1
-rw-r--r--mesalib/src/Makefile.am8
-rw-r--r--mesalib/src/SConscript5
-rw-r--r--mesalib/src/gallium/auxiliary/Makefile.am2
-rw-r--r--mesalib/src/gallium/auxiliary/Makefile.sources6
-rw-r--r--mesalib/src/gallium/auxiliary/hud/hud_driver_query.c3
-rw-r--r--mesalib/src/gallium/auxiliary/nir/tgsi_to_nir.c1750
-rw-r--r--mesalib/src/gallium/auxiliary/nir/tgsi_to_nir.h30
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_debug_symbol.c12
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_linkage.c149
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_linkage.h67
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_math.h18
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_tile.c12
-rw-r--r--mesalib/src/glsl/Makefile.am11
-rw-r--r--mesalib/src/glsl/Makefile.sources10
-rw-r--r--mesalib/src/glsl/ast_function.cpp112
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp68
-rw-r--r--mesalib/src/glsl/builtin_functions.cpp4
-rw-r--r--mesalib/src/glsl/glsl_lexer.ll20
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp11
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h5
-rw-r--r--mesalib/src/glsl/glsl_types.cpp76
-rw-r--r--mesalib/src/glsl/glsl_types.h6
-rw-r--r--mesalib/src/glsl/ir.cpp14
-rw-r--r--mesalib/src/glsl/ir.h102
-rw-r--r--mesalib/src/glsl/ir_constant_expression.cpp2
-rw-r--r--mesalib/src/glsl/ir_equals.cpp20
-rw-r--r--mesalib/src/glsl/ir_validate.cpp8
-rw-r--r--mesalib/src/glsl/link_uniforms.cpp4
-rw-r--r--mesalib/src/glsl/link_varyings.cpp13
-rw-r--r--mesalib/src/glsl/linker.cpp236
-rw-r--r--mesalib/src/glsl/loop_controls.cpp2
-rw-r--r--mesalib/src/glsl/lower_const_arrays_to_uniforms.cpp4
-rw-r--r--mesalib/src/glsl/nir/glsl_to_nir.cpp92
-rw-r--r--mesalib/src/glsl/nir/nir.c64
-rw-r--r--mesalib/src/glsl/nir/nir.h51
-rw-r--r--mesalib/src/glsl/nir/nir_algebraic.py17
-rw-r--r--mesalib/src/glsl/nir/nir_builder.h135
-rw-r--r--mesalib/src/glsl/nir/nir_from_ssa.c9
-rw-r--r--mesalib/src/glsl/nir/nir_lower_idiv.c155
-rw-r--r--mesalib/src/glsl/nir/nir_lower_phis_to_scalar.c2
-rw-r--r--mesalib/src/glsl/nir/nir_lower_samplers.cpp45
-rw-r--r--mesalib/src/glsl/nir/nir_lower_tex_projector.c143
-rw-r--r--mesalib/src/glsl/nir/nir_lower_var_copies.c8
-rw-r--r--mesalib/src/glsl/nir/nir_lower_vars_to_ssa.c2
-rw-r--r--mesalib/src/glsl/nir/nir_normalize_cubemap_coords.c110
-rw-r--r--mesalib/src/glsl/nir/nir_opcodes.py8
-rw-r--r--mesalib/src/glsl/nir/nir_opt_algebraic.py63
-rw-r--r--mesalib/src/glsl/nir/nir_opt_cse.c32
-rw-r--r--mesalib/src/glsl/nir/nir_opt_peephole_ffma.c261
-rw-r--r--mesalib/src/glsl/nir/nir_opt_peephole_select.c4
-rw-r--r--mesalib/src/glsl/nir/nir_print.c36
-rw-r--r--mesalib/src/glsl/nir/nir_remove_dead_variables.c22
-rw-r--r--mesalib/src/glsl/nir/nir_search.c4
-rw-r--r--mesalib/src/glsl/nir/nir_split_var_copies.c4
-rw-r--r--mesalib/src/glsl/nir/nir_sweep.c172
-rw-r--r--mesalib/src/glsl/nir/nir_to_ssa.c2
-rw-r--r--mesalib/src/glsl/nir/nir_types.cpp6
-rw-r--r--mesalib/src/glsl/nir/nir_types.h1
-rw-r--r--mesalib/src/glsl/nir/nir_validate.c16
-rw-r--r--mesalib/src/glsl/opt_algebraic.cpp32
-rw-r--r--mesalib/src/glsl/opt_cse.cpp63
-rw-r--r--mesalib/src/glsl/s_expression.cpp4
-rw-r--r--mesalib/src/glsl/shader_enums.h187
-rw-r--r--mesalib/src/loader/Makefile.am1
-rw-r--r--mesalib/src/mapi/glapi/gen/ARB_direct_state_access.xml118
-rw-r--r--mesalib/src/mapi/glapi/gen/ARB_program_interface_query.xml109
-rw-r--r--mesalib/src/mapi/glapi/gen/gl_API.xml4
-rw-r--r--mesalib/src/mapi/glapi/gen/gl_genexec.py1
-rw-r--r--mesalib/src/mapi/stub.c2
-rw-r--r--mesalib/src/mesa/Makefile.am2
-rw-r--r--mesalib/src/mesa/Makefile.sources7
-rw-r--r--mesalib/src/mesa/SConscript7
-rw-r--r--mesalib/src/mesa/drivers/SConscript2
-rw-r--r--mesalib/src/mesa/drivers/dri/common/utils.c2
-rw-r--r--mesalib/src/mesa/drivers/dri/common/xmlconfig.c2
-rw-r--r--mesalib/src/mesa/drivers/dri/common/xmlpool/Makefile.am19
-rw-r--r--mesalib/src/mesa/drivers/dri/swrast/swrast.c2
-rw-r--r--mesalib/src/mesa/drivers/dri/swrast/swrast_priv.h4
-rw-r--r--mesalib/src/mesa/main/.gitignore1
-rw-r--r--mesalib/src/mesa/main/atifragshader.c4
-rw-r--r--mesalib/src/mesa/main/attrib.c1
-rw-r--r--mesalib/src/mesa/main/bufferobj.c11
-rw-r--r--mesalib/src/mesa/main/colormac.h45
-rw-r--r--mesalib/src/mesa/main/context.c12
-rw-r--r--mesalib/src/mesa/main/debug.c2
-rw-r--r--mesalib/src/mesa/main/dlopen.h6
-rw-r--r--mesalib/src/mesa/main/errors.c43
-rw-r--r--mesalib/src/mesa/main/errors.h7
-rw-r--r--mesalib/src/mesa/main/extensions.c1
-rw-r--r--mesalib/src/mesa/main/fbobject.c439
-rw-r--r--mesalib/src/mesa/main/fbobject.h16
-rw-r--r--mesalib/src/mesa/main/ffvertex_prog.c6
-rw-r--r--mesalib/src/mesa/main/format_pack.py1
-rw-r--r--mesalib/src/mesa/main/format_unpack.h2
-rw-r--r--mesalib/src/mesa/main/format_unpack.py5
-rw-r--r--mesalib/src/mesa/main/glformats.c2
-rw-r--r--mesalib/src/mesa/main/imports.h24
-rw-r--r--mesalib/src/mesa/main/macros.h7
-rw-r--r--mesalib/src/mesa/main/mtypes.h184
-rw-r--r--mesalib/src/mesa/main/multisample.c9
-rw-r--r--mesalib/src/mesa/main/pipelineobj.c35
-rw-r--r--mesalib/src/mesa/main/pipelineobj.h3
-rw-r--r--mesalib/src/mesa/main/pixel.c1
-rw-r--r--mesalib/src/mesa/main/pixeltransfer.c2
-rw-r--r--mesalib/src/mesa/main/program_resource.c417
-rw-r--r--mesalib/src/mesa/main/program_resource.h58
-rw-r--r--mesalib/src/mesa/main/queryobj.c131
-rw-r--r--mesalib/src/mesa/main/queryobj.h14
-rw-r--r--mesalib/src/mesa/main/samplerobj.c25
-rw-r--r--mesalib/src/mesa/main/samplerobj.h5
-rw-r--r--mesalib/src/mesa/main/shader_query.cpp764
-rw-r--r--mesalib/src/mesa/main/shaderapi.c25
-rw-r--r--mesalib/src/mesa/main/shaderapi.h45
-rw-r--r--mesalib/src/mesa/main/shaderobj.c6
-rw-r--r--mesalib/src/mesa/main/state.c27
-rw-r--r--mesalib/src/mesa/main/texcompress.c1
-rw-r--r--mesalib/src/mesa/main/texcompress_fxt1.c1
-rw-r--r--mesalib/src/mesa/main/texcompress_rgtc.c1
-rw-r--r--mesalib/src/mesa/main/texcompress_s3tc.c9
-rw-r--r--mesalib/src/mesa/main/texparam.c1
-rw-r--r--mesalib/src/mesa/main/texstate.c2
-rw-r--r--mesalib/src/mesa/main/texstore.c1
-rw-r--r--mesalib/src/mesa/main/transformfeedback.c386
-rw-r--r--mesalib/src/mesa/main/transformfeedback.h30
-rw-r--r--mesalib/src/mesa/main/uniform_query.cpp138
-rw-r--r--mesalib/src/mesa/main/uniforms.c294
-rw-r--r--mesalib/src/mesa/main/uniforms.h5
-rw-r--r--mesalib/src/mesa/main/version.c1
-rw-r--r--mesalib/src/mesa/main/viewport.c48
-rw-r--r--mesalib/src/mesa/main/viewport.h3
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp104
-rw-r--r--mesalib/src/mesa/program/prog_execute.c1
-rw-r--r--mesalib/src/mesa/program/prog_instruction.h2
-rw-r--r--mesalib/src/mesa/program/prog_parameter.c72
-rw-r--r--mesalib/src/mesa/program/prog_parameter.h9
-rw-r--r--mesalib/src/mesa/program/prog_to_nir.c1096
-rw-r--r--mesalib/src/mesa/program/prog_to_nir.h37
-rw-r--r--mesalib/src/mesa/program/program.c5
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_array.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_constbuf.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_shader.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_clear.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_program.c4
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c23
-rw-r--r--mesalib/src/mesa/state_tracker/st_debug.c1
-rw-r--r--mesalib/src/mesa/state_tracker/st_debug.h1
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp237
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h7
-rw-r--r--mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_program.c49
-rw-r--r--mesalib/src/mesa/state_tracker/st_program.h3
-rw-r--r--mesalib/src/mesa/state_tracker/st_texture.c8
-rw-r--r--mesalib/src/mesa/swrast/s_aatriangle.c1
-rw-r--r--mesalib/src/mesa/swrast/s_alpha.c1
-rw-r--r--mesalib/src/mesa/swrast/s_atifragshader.c1
-rw-r--r--mesalib/src/mesa/swrast/s_context.c1
-rw-r--r--mesalib/src/mesa/swrast/s_copypix.c1
-rw-r--r--mesalib/src/mesa/swrast/s_feedback.c1
-rw-r--r--mesalib/src/mesa/swrast/s_fog.c1
-rw-r--r--mesalib/src/mesa/swrast/s_fragprog.c2
-rw-r--r--mesalib/src/mesa/swrast/s_lines.c1
-rw-r--r--mesalib/src/mesa/swrast/s_linetemp.h4
-rw-r--r--mesalib/src/mesa/swrast/s_points.c1
-rw-r--r--mesalib/src/mesa/swrast/s_span.c3
-rw-r--r--mesalib/src/mesa/swrast/s_texcombine.c2
-rw-r--r--mesalib/src/mesa/swrast/s_texfetch.c1
-rw-r--r--mesalib/src/mesa/swrast/s_texfilter.c2
-rw-r--r--mesalib/src/mesa/swrast/s_texrender.c1
-rw-r--r--mesalib/src/mesa/swrast/s_triangle.c1
-rw-r--r--mesalib/src/mesa/swrast/s_tritemp.h4
-rw-r--r--mesalib/src/mesa/swrast/s_zoom.c1
-rw-r--r--mesalib/src/mesa/swrast_setup/ss_context.c7
-rw-r--r--mesalib/src/mesa/swrast_setup/ss_triangle.c1
-rw-r--r--mesalib/src/mesa/tnl/t_context.c12
-rw-r--r--mesalib/src/mesa/tnl/t_context.h1
-rw-r--r--mesalib/src/mesa/tnl/t_draw.c2
-rw-r--r--mesalib/src/mesa/tnl/t_rasterpos.c14
-rw-r--r--mesalib/src/mesa/tnl/t_vb_fog.c1
-rw-r--r--mesalib/src/mesa/tnl/t_vb_light.c1
-rw-r--r--mesalib/src/mesa/tnl/t_vb_lighttmp.h8
-rw-r--r--mesalib/src/mesa/tnl/t_vb_normals.c1
-rw-r--r--mesalib/src/mesa/tnl/t_vb_program.c1
-rw-r--r--mesalib/src/mesa/tnl/t_vb_texgen.c1
-rw-r--r--mesalib/src/mesa/tnl/t_vb_texmat.c1
-rw-r--r--mesalib/src/mesa/tnl/t_vb_vertex.c1
-rw-r--r--mesalib/src/mesa/tnl/t_vertex.c1
-rw-r--r--mesalib/src/mesa/tnl/t_vertex_generic.c4
-rw-r--r--mesalib/src/mesa/tnl/t_vertex_sse.c1
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_api.c2
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_draw.c4
-rw-r--r--mesalib/src/mesa/vbo/vbo_primitive_restart.c6
-rw-r--r--mesalib/src/mesa/vbo/vbo_rebase.c2
-rw-r--r--mesalib/src/mesa/vbo/vbo_save_api.c2
-rw-r--r--mesalib/src/mesa/x86/common_x86.c2
-rw-r--r--mesalib/src/util/ralloc.c26
-rw-r--r--mesalib/src/util/ralloc.h15
-rw-r--r--mesalib/src/util/u_atomic_test.c5
-rw-r--r--pixman/pixman/pixman-arm-simd-asm.h4
-rw-r--r--pixman/pixman/pixman.c18
-rw-r--r--pixman/test/check-formats.c192
-rw-r--r--pixman/test/lowlevel-blt-bench.c299
-rw-r--r--pixman/test/utils.c463
-rw-r--r--pixman/test/utils.h12
-rw-r--r--xkbcomp/listing.c1
-rw-r--r--xorg-server/configure.ac2
-rw-r--r--xorg-server/glamor/glamor.c224
-rw-r--r--xorg-server/glamor/glamor.h173
-rw-r--r--xorg-server/glamor/glamor_addtraps.c29
-rw-r--r--xorg-server/glamor/glamor_compositerects.c4
-rw-r--r--xorg-server/glamor/glamor_copy.c75
-rw-r--r--xorg-server/glamor/glamor_core.c30
-rw-r--r--xorg-server/glamor/glamor_dash.c15
-rw-r--r--xorg-server/glamor/glamor_egl.c24
-rw-r--r--xorg-server/glamor/glamor_fbo.c162
-rw-r--r--xorg-server/glamor/glamor_font.c1
-rw-r--r--xorg-server/glamor/glamor_glyphblt.c54
-rw-r--r--xorg-server/glamor/glamor_glyphs.c14
-rw-r--r--xorg-server/glamor/glamor_gradient.c12
-rw-r--r--xorg-server/glamor/glamor_image.c27
-rw-r--r--xorg-server/glamor/glamor_largepixmap.c185
-rw-r--r--xorg-server/glamor/glamor_lines.c23
-rw-r--r--xorg-server/glamor/glamor_picture.c20
-rw-r--r--xorg-server/glamor/glamor_pixmap.c144
-rw-r--r--xorg-server/glamor/glamor_points.c24
-rw-r--r--xorg-server/glamor/glamor_prepare.c40
-rw-r--r--xorg-server/glamor/glamor_priv.h243
-rw-r--r--xorg-server/glamor/glamor_program.c19
-rw-r--r--xorg-server/glamor/glamor_program.h2
-rw-r--r--xorg-server/glamor/glamor_rects.c28
-rw-r--r--xorg-server/glamor/glamor_render.c309
-rw-r--r--xorg-server/glamor/glamor_segs.c20
-rw-r--r--xorg-server/glamor/glamor_spans.c61
-rw-r--r--xorg-server/glamor/glamor_sync.c2
-rw-r--r--xorg-server/glamor/glamor_text.c47
-rw-r--r--xorg-server/glamor/glamor_transfer.c57
-rw-r--r--xorg-server/glamor/glamor_transform.c16
-rw-r--r--xorg-server/glamor/glamor_trapezoid.c16
-rw-r--r--xorg-server/glamor/glamor_triangles.c42
-rw-r--r--xorg-server/glamor/glamor_utils.h215
-rw-r--r--xorg-server/glamor/glamor_window.c12
-rw-r--r--xorg-server/glamor/glamor_xv.c15
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c2
-rw-r--r--xorg-server/hw/kdrive/ephyr/hostx.c9
-rw-r--r--xorg-server/hw/xfree86/common/xf86Events.c7
-rw-r--r--xorg-server/hw/xfree86/common/xf86platformBus.c20
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/driver.c5
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Crtc.c53
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Crtc.h26
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/systemd-logind.c17
-rw-r--r--xorg-server/hw/xquartz/quartz.c1
-rw-r--r--xorg-server/hw/xquartz/xpr/xprScreen.c2
-rw-r--r--xorg-server/hw/xwayland/Makefile.am1
-rw-r--r--xorg-server/hw/xwayland/xwayland-glamor.c6
-rw-r--r--xorg-server/hw/xwin/InitOutput.c61
-rw-r--r--xorg-server/hw/xwin/Makefile.am2
-rw-r--r--xorg-server/hw/xwin/XWin.exe.manifest16
-rw-r--r--xorg-server/hw/xwin/glx/gen_gl_wrappers.py96
-rw-r--r--xorg-server/hw/xwin/man/XWin.man11
-rw-r--r--xorg-server/hw/xwin/win.h35
-rw-r--r--xorg-server/hw/xwin/winengine.c26
-rw-r--r--xorg-server/hw/xwin/winglobals.c2
-rw-r--r--xorg-server/hw/xwin/winos.c72
-rw-r--r--xorg-server/hw/xwin/winprocarg.c20
-rw-r--r--xorg-server/hw/xwin/winscrinit.c23
-rw-r--r--xorg-server/hw/xwin/winshaddd.c1221
-rw-r--r--xorg-server/hw/xwin/winwndproc.c6
-rw-r--r--xorg-server/include/Makefile.am1
-rw-r--r--xorg-server/include/extinit.h5
-rw-r--r--xorg-server/include/nonsdk_extinit.h35
-rw-r--r--xorg-server/include/protocol-versions.h2
-rw-r--r--xorg-server/mi/mifillarc.c5
-rw-r--r--xorg-server/mi/miinitext.c3
-rw-r--r--xorg-server/os/log.c28
-rw-r--r--xorg-server/os/xdmcp.c17
-rw-r--r--xorg-server/pseudoramiX/pseudoramiX.c6
-rw-r--r--xorg-server/pseudoramiX/pseudoramiX.h2
-rw-r--r--xorg-server/randr/Makefile.am1
-rw-r--r--xorg-server/randr/randr.c4
-rw-r--r--xorg-server/randr/randrstr.h44
-rw-r--r--xorg-server/randr/rrdispatch.c3
-rw-r--r--xorg-server/randr/rrmonitor.c748
-rw-r--r--xorg-server/randr/rrsdispatch.c38
-rw-r--r--xorg-server/randr/rrxinerama.c123
-rw-r--r--xorg-server/xkeyboard-config/rules/base.xml.in6
-rw-r--r--xorg-server/xkeyboard-config/symbols/de1
-rw-r--r--xorg-server/xkeyboard-config/symbols/latam61
-rw-r--r--xorg-server/xkeyboard-config/symbols/typo107
325 files changed, 11685 insertions, 5731 deletions
diff --git a/X11/extensions/randr.h b/X11/extensions/randr.h
index 3c6721bc5..6fcda8748 100644
--- a/X11/extensions/randr.h
+++ b/X11/extensions/randr.h
@@ -40,11 +40,11 @@ typedef unsigned long XRandrModeFlags;
#define RANDR_NAME "RANDR"
#define RANDR_MAJOR 1
-#define RANDR_MINOR 4
+#define RANDR_MINOR 5
#define RRNumberErrors 4
#define RRNumberEvents 2
-#define RRNumberRequests 42
+#define RRNumberRequests 45
#define X_RRQueryVersion 0
/* we skip 1 to make old clients fail pretty immediately */
@@ -104,6 +104,11 @@ typedef unsigned long XRandrModeFlags;
#define X_RRDeleteProviderProperty 40
#define X_RRGetProviderProperty 41
+/* v1.5 */
+#define X_RRGetMonitors 42
+#define X_RRSetMonitor 43
+#define X_RRDeleteMonitor 44
+
/* Event selection bits */
#define RRScreenChangeNotifyMask (1L << 0)
/* V1.2 additions */
@@ -181,6 +186,7 @@ typedef unsigned long XRandrModeFlags;
#define RR_PROPERTY_BORDER "Border"
#define RR_PROPERTY_BORDER_DIMENSIONS "BorderDimensions"
#define RR_PROPERTY_GUID "GUID"
+#define RR_PROPERTY_RANDR_TILE "TILE"
/* roles this device can carry out */
#define RR_Capability_None 0
diff --git a/X11/extensions/randrproto.h b/X11/extensions/randrproto.h
index 30691e7ea..114a6248e 100644
--- a/X11/extensions/randrproto.h
+++ b/X11/extensions/randrproto.h
@@ -50,6 +50,7 @@
#define RRCrtc CARD32
#define RRProvider CARD32
#define RRModeFlags CARD32
+#define Atom CARD32
#define Rotation CARD16
#define SizeID CARD16
@@ -1012,6 +1013,63 @@ typedef struct {
} xRRSetPanningReply;
#define sz_xRRSetPanningReply 32
+typedef struct {
+ Atom name B32;
+ BOOL primary;
+ BOOL automatic;
+ CARD16 noutput B16;
+ INT16 x B16;
+ INT16 y B16;
+ CARD16 width B16;
+ CARD16 height B16;
+ CARD32 widthInMillimeters B32;
+ CARD32 heightInMillimeters B32;
+} xRRMonitorInfo;
+#define sz_xRRMonitorInfo 24
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ Window window B32;
+ BOOL get_active;
+ CARD8 pad;
+ CARD16 pad2;
+} xRRGetMonitorsReq;
+#define sz_xRRGetMonitorsReq 12
+
+typedef struct {
+ BYTE type;
+ CARD8 status;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ Time timestamp B32;
+ CARD32 nmonitors B32;
+ CARD32 noutputs B32;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+} xRRGetMonitorsReply;
+#define sz_xRRGetMonitorsReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ Window window B32;
+ xRRMonitorInfo monitor;
+} xRRSetMonitorReq;
+#define sz_xRRSetMonitorReq 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ Window window B32;
+ Atom name B32;
+} xRRDeleteMonitorReq;
+#define sz_xRRDeleteMonitorReq 12
+
#undef RRModeFlags
#undef RRCrtc
#undef RRMode
@@ -1033,5 +1091,6 @@ typedef struct {
#undef Rotation
#undef SizeID
#undef SubpixelOrder
+#undef Atom
#endif /* _XRANDRP_H_ */
diff --git a/X11/extensions/randrproto.txt b/X11/extensions/randrproto.txt
index 190048299..74b7c366d 100644
--- a/X11/extensions/randrproto.txt
+++ b/X11/extensions/randrproto.txt
@@ -1,5 +1,5 @@
The X Resize, Rotate and Reflect Extension
- Version 1.4.1
+ Version 1.5.0
2015-03-14
Jim Gettys
@@ -149,7 +149,44 @@ be dynamically configured to provide support for:
4) multiple GPU rendering - This replaces Xinerama.
-1.99 Acknowledgements
+1.5. Introduction to version 1.5 of the extension
+
+Version 1.5 adds an optional TILE property to outputs.
+
+ • An optional TILE property.
+ This property is used to denote individual tiles in a tiled monitor
+ configuration, as exposed via DisplayID v1.3.
+
+Version 1.5 adds monitors
+
+ • A 'Monitor' is a rectangular subset of the screen which represents
+ a coherent collection of pixels presented to the user.
+
+ • Each Monitor is be associated with a list of outputs (which may be
+ empty).
+
+ • When clients define monitors, the associated outputs are removed from
+ existing Monitors. If removing the output causes the list for that
+ monitor to become empty, that monitor will be deleted.
+
+ • For active CRTCs that have no output associated with any
+ client-defined Monitor, one server-defined monitor will
+ automatically be defined of the first Output associated with them.
+
+ • When defining a monitor, setting the geometry to all zeros will
+ cause that monitor to dynamically track the bounding box of the
+ active outputs associated with them
+
+This new object separates the physical configuration of the hardware
+from the logical subsets the screen that applications should
+consider as single viewable areas.
+
+1.5.1. Relationship between Monitors and Xinerama
+
+Xinerama's information now comes from the Monitors instead of directly
+from the CRTCs. The Monitor marked as Primary will be listed first.
+
+1.99 Acknowledgments
Our thanks to the contributors to the design found on the xpert mailing
list, in particular:
@@ -162,7 +199,9 @@ David Dawes for XFree86 DDX integration work
Thomas Winischhofer for the hardware-accelerated SiS rotation implementation
Matthew Tippett and Kevin Martin for splitting outputs and CRTCs to more
fully expose what video hardware can do
-Dave Airlie for the 1.4.0 protocol changes.
+Dave Airlie for the 1.4.0 protocol changes and for working through the
+implications of MST monitors and encouraging the introduction of the
+'Monitor' concept.
❧❧❧❧❧❧❧❧❧❧❧
@@ -262,7 +301,7 @@ RRCONFIGSTATUS { Success
configuration is unsupported by the hardware. The goal is to make
these limitations expressed by the protocol, but when that isn't
possible it is correct to return this error value. If, as a
- implementor, you find this error code required, please submit the
+ implementer, you find this error code required, please submit the
hardware constraints that exist so that a future version of the
extension can correctly capture the configuration constraints in
your system.
@@ -365,6 +404,21 @@ PROVIDER_CAPS { SourceOutput, SinkOutput, SourceOffload, SinkOffload }
❧❧❧❧❧❧❧❧❧❧❧
+5.6. Protocol Types added in version 1.5 of the extension
+
+MONITORINFO { name: ATOM
+ primary: BOOL
+ automatic: BOOL
+ x: INT16
+ y: INT16
+ width: CARD16
+ height: CARD16
+ width-in-millimeters: CARD32
+ height-in-millimeters: CARD32
+ outputs: LISTofOUTPUT }
+
+ ❧❧❧❧❧❧❧❧❧❧❧
+
6. Extension Initialization
The name of this extension is "RANDR".
@@ -1539,6 +1593,79 @@ dynamic changes in the display environment.
❧❧❧❧❧❧❧❧❧❧❧
+
+7.5. Extension Requests added in version 1.5 of the extension.
+
+┌───
+ RRGetMonitors
+ window : WINDOW
+ get_active : BOOL
+ ▶
+ timestamp: TIMESTAMP
+ monitors: LISTofMONITORINFO
+└───
+ Errors: Window
+
+ Returns the list of Monitors for the screen containing
+ 'window'. If 'get_active' is set it returns only active
+ monitors (non-0x0 monitors). 'get_active' should always
+ be set by toolkits, and not by configuration clients.
+
+ 'timestamp' indicates the server time when the list of
+ monitors last changed.
+
+┌───
+ RRSetMonitor
+ window : WINDOW
+ info: MONITORINFO
+└───
+ Errors: Window, Output, Atom, Value
+
+ Create a new monitor. Any existing Monitor of the same name is deleted.
+
+ 'name' must be a valid atom or an Atom error results.
+
+ 'name' must not match the name of any Output on the screen, or
+ a Value error results.
+
+ If 'info.outputs' is non-empty, and if x, y, width, height are all
+ zero, then the Monitor geometry will be dynamically defined to
+ be the bounding box of the geometry of the active CRTCs
+ associated with them.
+
+ If 'name' matches an existing Monitor on the screen, the
+ existing one will be deleted as if RRDeleteMonitor were called.
+
+ For each output in 'info.outputs, each one is removed from all
+ pre-existing Monitors. If removing the output causes the list of
+ outputs for that Monitor to become empty, then that Monitor will
+ be deleted as if RRDeleteMonitor were called.
+
+ Only one monitor per screen may be primary. If 'info.primary'
+ is true, then the primary value will be set to false on all
+ other monitors on the screen.
+
+ RRSetMonitor generates a ConfigureNotify event on the root
+ window of the screen.
+
+┌───
+ RRDeleteMonitor
+ window : WINDOW
+ name: ATOM
+└───
+ Errors: Window, Atom, Value
+
+ Deletes the named Monitor.
+
+ 'name' must be a valid atom or an Atom error results.
+
+ 'name' must match the name of a Monitor on the screen, or a
+ Value error results.
+
+ RRDeleteMonitor generates a ConfigureNotify event on the root
+ window of the screen.
+
+ ❧❧❧❧❧❧❧❧❧❧❧
8. Extension Events
Clients MAY select for ConfigureNotify on the root window to be
@@ -1968,6 +2095,26 @@ doesn't handle a mandatory property correctly.
unique identifiers. When such an identifier is available, this property
contains its raw bytes.
+ "TILE" aka RR_PROPERTY_RANDR_TILE
+ Type: INTEGER
+ Format: 32
+ Num items: 8
+ Flags: Immutable
+ Range/List: -
+
+ Tile monitors have an array of values describing the tiling,
+ based on DisplayID v1.3
+
+ The 8 elements are:
+ 0: group id - The tile group identifier
+ 1: flags - flags for tile group
+ 0x1 = single monitor enclosure
+ 2: number of horizontal tiles in tile group
+ 3: number of vertical tiles in tile group
+ 4: horizontal tile location for this tile
+ 5: vertical tile location for this tile
+ 6: horizontal tile size for this tile
+ 7: vertical tile size for this tile
9.2 Properties introduced with version 1.2 of the RandR extension
@@ -2008,6 +2155,11 @@ Property Immutable Mandatory since
──────── ───────── ───────────────
GUID yes not mandatory
+9.7 Properties introduced with version 1.5 of the RandR extension
+
+Property Immutable Mandatory since
+──────── ───────── ───────────────
+TILE yes not mandatory
❧❧❧❧❧❧❧❧❧❧❧
10. Extension Versioning
@@ -2044,6 +2196,8 @@ list of what each version provided:
1.4: Added provider objects for handling multi-GPU systems.
+ 1.5: Added Monitors
+
Compatibility between 0.0 and 1.0 was *NOT* preserved, and 0.0 clients
will fail against 1.0 servers. The wire encoding op-codes were
changed for GetScreenInfo to ensure this failure in a relatively
@@ -2194,6 +2348,23 @@ A.1 Common Types
0x00000008 SinkOffload
└───
+A.1.1 Common Types added in version 1.5 of the protocol
+
+┌───
+ MONITORINFO (16 + 4*n)
+ 4 ATOM name
+ 1 BOOL primary
+ 1 BOOL automatic
+ 2 CARD16 ncrtcs
+ 2 INT16 x
+ 2 INT16 y
+ 2 CARD16 width in pixels
+ 2 CARD16 height in pixels
+ 4 CARD32 width in millimeters
+ 4 CARD32 height in millimeters
+ 4*n CRTC crtcs
+└───
+
A.2 Protocol Requests
Opcodes 1 and 3 were used in the 0.0 protocols, and will return
@@ -2932,6 +3103,42 @@ A.2.3 Protocol Requests added with version 1.4
p unused, p=pad(n)
└───
+A.2.4 Protocol Requests added with version 1.5
+
+┌───
+ RRGetMonitors
+ 1 CARD8 major opcode
+ 1 42 RandR opcode
+ 2 2 request length
+ 4 WINDOW window
+ ▶
+ 1 1 Reply
+ 1 unused
+ 2 CARD16 sequence number
+ 4 6*n + o reply length
+ 4 TIMESTAMP timestamp
+ 4 n nmonitors
+ 4 o noutputs
+ 12 unused
+ n*24+o*4 LISTofMONITORINFO monitors
+└───
+┌───
+ RRSetMonitor
+ 1 CARD8 major opcode
+ 1 43 RandR opcode
+ 2 6 + o request length
+ 4 WINDOW window
+ 24+o MONITORINFO monitorinfo
+└───
+┌───
+ RRDeleteMonitor
+ 1 CARD8 major opcode
+ 1 44 RandR opcode
+ 2 3 request length
+ 4 WINDOW window
+ 4 ATOM name
+└───
+
A.3 Protocol Events
┌───
diff --git a/fontconfig/doc/fontconfig-user.sgml b/fontconfig/doc/fontconfig-user.sgml
index ac9d8079e..7b4ad7408 100644
--- a/fontconfig/doc/fontconfig-user.sgml
+++ b/fontconfig/doc/fontconfig-user.sgml
@@ -323,7 +323,7 @@ a directory in the users home directory. If 'prefix' is set to "xdg", the value
The default directory is ``$XDG_CACHE_HOME/fontconfig'' and it contains the cache files
named ``<literal>&lt;hash value&gt;</literal>-<literal>&lt;architecture&gt;</literal>.cache-<literal>&lt;version&gt;</literal>'',
where <literal>&lt;version&gt;</literal> is the font configureation file
-version number (currently 3).
+version number (currently 5).
</para></refsect2>
<refsect2><title><literal>&lt;include ignore_missing="no" prefix="default"&gt;</literal></title><para>
This element contains the name of an additional configuration file or
diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c
index b92270b64..cc2d9ee63 100644
--- a/fontconfig/src/fccfg.c
+++ b/fontconfig/src/fccfg.c
@@ -1843,6 +1843,7 @@ FcConfigSubstitute (FcConfig *config,
#if defined (_WIN32)
static FcChar8 fontconfig_path[1000] = ""; /* MT-dontcare */
+FcChar8 fontconfig_instprefix[1000] = ""; /* MT-dontcare */
# if (defined (PIC) || defined (DLL_EXPORT))
@@ -1877,6 +1878,7 @@ DllMain (HINSTANCE hinstDLL,
if (p && (FcStrCmpIgnoreCase (p + 1, (const FcChar8 *) "bin") == 0 ||
FcStrCmpIgnoreCase (p + 1, (const FcChar8 *) "lib") == 0))
*p = '\0';
+ strcat ((char *) fontconfig_instprefix, (char *) fontconfig_path);
strcat ((char *) fontconfig_path, "\\etc\\fonts");
}
else
@@ -2227,7 +2229,9 @@ FcConfigAppFontAddFile (FcConfig *config,
FcStrSetDestroy (subdirs);
return FcFalse;
}
- if ((sublist = FcStrListCreate (subdirs)))
+ if (subdirs->num == 0)
+ ret = FcTrue;
+ else if ((sublist = FcStrListCreate (subdirs)))
{
while ((subdir = FcStrListNext (sublist)))
{
diff --git a/fontconfig/src/fcdir.c b/fontconfig/src/fcdir.c
index 593382f43..2e7f0dc7c 100644
--- a/fontconfig/src/fcdir.c
+++ b/fontconfig/src/fcdir.c
@@ -136,8 +136,8 @@ FcFileScanFontConfig (FcFontSet *set,
ret = FcFalse;
}
}
- else if (font)
- FcPatternDestroy (font);
+ else
+ ret = FcFalse;
id++;
} while (font && ret && id < count);
return ret;
diff --git a/fontconfig/src/fcrange.c b/fontconfig/src/fcrange.c
index 37cf06755..9b1b67b82 100644
--- a/fontconfig/src/fcrange.c
+++ b/fontconfig/src/fcrange.c
@@ -204,7 +204,7 @@ FcRangeHash (const FcRange *r)
{
FcRange c = FcRangeCanonicalize (r);
int b = (int) (c.u.d.begin * 100);
- int e = (int) (c.u.d.end * 100);
+ int e = FcDoubleCmpEQ (c.u.d.end, DBL_MAX) ? INT_MAX : (int) (c.u.d.end * 100);
return b ^ (b << 1) ^ (e << 9);
}
diff --git a/fontconfig/src/fcxml.c b/fontconfig/src/fcxml.c
index cdb14b67c..9a6f08d27 100644
--- a/fontconfig/src/fcxml.c
+++ b/fontconfig/src/fcxml.c
@@ -54,6 +54,7 @@
#ifdef _WIN32
#include <mbstring.h>
+extern FcChar8 fontconfig_instprefix[];
#endif
static void
@@ -2187,7 +2188,25 @@ FcParseCacheDir (FcConfigParse *parse)
data = prefix;
}
#ifdef _WIN32
- if (strcmp ((const char *) data, "WINDOWSTEMPDIR_FONTCONFIG_CACHE") == 0)
+ else if (data[0] == '/' && fontconfig_instprefix[0] != '\0')
+ {
+ size_t plen = strlen ((const char *)fontconfig_instprefix);
+ size_t dlen = strlen ((const char *)data);
+
+ prefix = malloc (plen + 1 + dlen + 1);
+ if (!prefix)
+ {
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ goto bail;
+ }
+ strcpy ((char *) prefix, (char *) fontconfig_instprefix);
+ prefix[plen] = FC_DIR_SEPARATOR;
+ memcpy (&prefix[plen + 1], data, dlen);
+ prefix[plen + 1 + dlen] = 0;
+ FcStrFree (data);
+ data = prefix;
+ }
+ else if (strcmp ((const char *) data, "WINDOWSTEMPDIR_FONTCONFIG_CACHE") == 0)
{
int rc;
FcStrFree (data);
@@ -2265,8 +2284,8 @@ FcParseInclude (FcConfigParse *parse)
attr = FcConfigGetAttribute (parse, "ignore_missing");
if (attr && FcConfigLexBool (parse, (FcChar8 *) attr) == FcTrue)
ignore_missing = FcTrue;
-#ifndef _WIN32
attr = FcConfigGetAttribute (parse, "deprecated");
+#ifndef _WIN32
if (attr && FcConfigLexBool (parse, (FcChar8 *) attr) == FcTrue)
deprecated = FcTrue;
#endif
diff --git a/fontconfig/test/Makefile.am b/fontconfig/test/Makefile.am
index f270b5071..bf1ec24a2 100644
--- a/fontconfig/test/Makefile.am
+++ b/fontconfig/test/Makefile.am
@@ -24,6 +24,13 @@ test_pthread_LDADD = $(top_builddir)/src/libfontconfig.la
# to meaningfully test anything, and we are not installed yet.
#TESTS += test-pthread
endif
+check_PROGRAMS += test-bz89617
+test_bz89617_CFLAGS = \
+ -DSRCDIR="\"$(abs_srcdir)\""
+
+test_bz89617_LDADD = $(top_builddir)/src/libfontconfig.la
+TESTS += test-bz89617
+
noinst_PROGRAMS = $(check_PROGRAMS)
if !OS_WIN32
diff --git a/fontconfig/test/test-bz89617.c b/fontconfig/test/test-bz89617.c
new file mode 100644
index 000000000..389f47094
--- /dev/null
+++ b/fontconfig/test/test-bz89617.c
@@ -0,0 +1,38 @@
+/*
+ * fontconfig/test/test-bz89617.c
+ *
+ * Copyright © 2000 Keith Packard
+ * Copyright © 2015 Akira TAGOH
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <stdio.h>
+#include <fontconfig/fontconfig.h>
+
+int
+main (void)
+{
+ FcConfig *config = FcConfigGetCurrent ();
+
+ if (!FcConfigAppFontAddFile (config, SRCDIR "/4x6.pcf") ||
+ FcConfigAppFontAddFile (config, "/dev/null"))
+ return 1;
+
+ return 0;
+}
diff --git a/libX11/nls/compose.dir.pre b/libX11/nls/compose.dir.pre
index e52a5c568..268c90a48 100644
--- a/libX11/nls/compose.dir.pre
+++ b/libX11/nls/compose.dir.pre
@@ -389,7 +389,7 @@ km_KH.UTF-8/Compose: km_KH.UTF-8
en_US.UTF-8/Compose: kn_IN.UTF-8
ko_KR.UTF-8/Compose: ko_KR.UTF-8
en_US.UTF-8/Compose: ks_IN.UTF-8
-en_US.UTF-8/Compose: ks_IN@devanagari.UTF-8
+en_US.UTF-8/Compose: ks_IN.UTF-8@devanagari
en_US.UTF-8/Compose: ku_TR.UTF-8
en_US.UTF-8/Compose: kw_GB.UTF-8
en_US.UTF-8/Compose: ky_KG.UTF-8
@@ -429,7 +429,7 @@ en_US.UTF-8/Compose: ru_UA.UTF-8
en_US.UTF-8/Compose: rw_RW.UTF-8
en_US.UTF-8/Compose: sa_IN.UTF-8
en_US.UTF-8/Compose: sd_IN.UTF-8
-en_US.UTF-8/Compose: sd_IN@devanagari.UTF-8
+en_US.UTF-8/Compose: sd_IN.UTF-8@devanagari
en_US.UTF-8/Compose: se_NO.UTF-8
en_US.UTF-8/Compose: sh_BA.UTF-8
en_US.UTF-8/Compose: sh_YU.UTF-8
diff --git a/libX11/nls/en_US.UTF-8/Compose.pre b/libX11/nls/en_US.UTF-8/Compose.pre
index 972e111b9..2041757c9 100644
--- a/libX11/nls/en_US.UTF-8/Compose.pre
+++ b/libX11/nls/en_US.UTF-8/Compose.pre
@@ -276,6 +276,7 @@ XCOMM Other symbols
<Multi_key> <colon> <parenright> : "☺" U263A # WHITE SMILING FACE
<Multi_key> <colon> <parenleft> : "☹" U2639 # WHITE FROWNING FACE
+<Multi_key> <backslash> <o> <slash> : "🙌" # PERSON RAISING BOTH HANDS IN CELEBRATION
<Multi_key> <F> <U> : "🖕" U1F595 # REVERSED HAND WITH MIDDLE FINGER EXTENDED
<Multi_key> <L> <L> <A> <P> : "🖖" U1F596 # RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS
@@ -5840,8 +5841,6 @@ XCOMM
<dead_circumflex> <Cyrillic_ER> : "Р̂" # CYRILLIC CAPITAL LETTER ER WITH COMBINING CIRCUMFLEX ACCENT
<Multi_key> <asciicircum> <Cyrillic_ER> : "Р̂" # CYRILLIC CAPITAL LETTER ER WITH COMBINING CIRCUMFLEX ACCENT
-<Multi_key> <backslash> <o> <slash> : "🙌" # PERSON RAISING BOTH HANDS IN CELEBRATION
-
XCOMM APL support Geoff Streeter 2012-01-04
XCOMM APL was initially an overstruck language. The original APL terminal was an IBM golfball
diff --git a/libX11/nls/locale.alias.pre b/libX11/nls/locale.alias.pre
index 1319492fb..63d224612 100644
--- a/libX11/nls/locale.alias.pre
+++ b/libX11/nls/locale.alias.pre
@@ -750,8 +750,8 @@ KO_KR.UTF-8: ko_KR.UTF-8
ks: ks_IN.UTF-8
ks_IN: ks_IN.UTF-8
ks_IN.utf8: ks_IN.UTF-8
-ks_IN@devanagari: ks_IN@devanagari.UTF-8
-ks_IN@devanagari.utf8: ks_IN@devanagari.UTF-8
+ks_IN@devanagari: ks_IN.UTF-8@devanagari
+ks_IN.utf8@devanagari: ks_IN.UTF-8@devanagari
kw: kw_GB.ISO8859-1
kw_GB: kw_GB.ISO8859-1
kw_GB.iso88591: kw_GB.ISO8859-1
@@ -982,9 +982,9 @@ rw_RW.ISO-8859-1: rw_RW.ISO8859-1
rw_RW.utf8: rw_RW.UTF-8
sd: sd_IN.UTF-8
sd_IN.utf8: sd_IN.UTF-8
-sd@devanagari: sd_IN@devanagari.UTF-8
-sd_IN@devanagari: sd_IN@devanagari.UTF-8
-sd_IN@devanagari.utf8: sd_IN@devanagari.UTF-8
+sd@devanagari: sd_INUTF-8@devanagari
+sd_IN@devanagari: sd_INUTF-8@devanagari
+sd_IN.utf8@devanagari: sd_INUTF-8@devanagari
se_NO: se_NO.UTF-8
se_NO.utf8: se_NO.UTF-8
XCOMM sh was the old ISO code for Serbo-Croatian (now individual sr and hr).
diff --git a/libX11/nls/locale.dir.pre b/libX11/nls/locale.dir.pre
index ab1bacec6..8570ba336 100644
--- a/libX11/nls/locale.dir.pre
+++ b/libX11/nls/locale.dir.pre
@@ -292,6 +292,7 @@ en_US.UTF-8/XLC_LOCALE: ar_YE.UTF-8
en_US.UTF-8/XLC_LOCALE: as_IN.UTF-8
en_US.UTF-8/XLC_LOCALE: az_AZ.UTF-8
en_US.UTF-8/XLC_LOCALE: be_BY.UTF-8
+en_US.UTF-8/XLC_LOCALE: be_BY.UTF-8@latin
en_US.UTF-8/XLC_LOCALE: bg_BG.UTF-8
en_US.UTF-8/XLC_LOCALE: bn_BD.UTF-8
en_US.UTF-8/XLC_LOCALE: bn_IN.UTF-8
@@ -389,7 +390,7 @@ en_US.UTF-8/XLC_LOCALE: kl_GL.UTF-8
en_US.UTF-8/XLC_LOCALE: km_KH.UTF-8
en_US.UTF-8/XLC_LOCALE: kn_IN.UTF-8
en_US.UTF-8/XLC_LOCALE: ks_IN.UTF-8
-en_US.UTF-8/XLC_LOCALE: ks_IN@devanagari.UTF-8
+en_US.UTF-8/XLC_LOCALE: ks_IN.UTF-8@devanagari
ko_KR.UTF-8/XLC_LOCALE: ko_KR.UTF-8
en_US.UTF-8/XLC_LOCALE: ku_TR.UTF-8
en_US.UTF-8/XLC_LOCALE: kw_GB.UTF-8
@@ -429,7 +430,7 @@ en_US.UTF-8/XLC_LOCALE: ru_UA.UTF-8
en_US.UTF-8/XLC_LOCALE: rw_RW.UTF-8
en_US.UTF-8/XLC_LOCALE: sa_IN.UTF-8
en_US.UTF-8/XLC_LOCALE: sd_IN.UTF-8
-en_US.UTF-8/XLC_LOCALE: sd_IN@devanagari.UTF-8
+en_US.UTF-8/XLC_LOCALE: sd_IN.UTF-8@devanagari
en_US.UTF-8/XLC_LOCALE: se_NO.UTF-8
en_US.UTF-8/XLC_LOCALE: sh_BA.UTF-8
en_US.UTF-8/XLC_LOCALE: sh_YU.UTF-8
@@ -440,6 +441,7 @@ en_US.UTF-8/XLC_LOCALE: sq_AL.UTF-8
en_US.UTF-8/XLC_LOCALE: sr_CS.UTF-8
en_US.UTF-8/XLC_LOCALE: sr_ME.UTF-8
en_US.UTF-8/XLC_LOCALE: sr_RS.UTF-8
+en_US.UTF-8/XLC_LOCALE: sr_RS.UTF-8@latin
en_US.UTF-8/XLC_LOCALE: sr_YU.UTF-8
en_US.UTF-8/XLC_LOCALE: ss_ZA.UTF-8
en_US.UTF-8/XLC_LOCALE: st_ZA.UTF-8
diff --git a/libXdmcp/configure.ac b/libXdmcp/configure.ac
index 608bab99e..2288502ec 100644
--- a/libXdmcp/configure.ac
+++ b/libXdmcp/configure.ac
@@ -55,6 +55,14 @@ AC_PROG_LN_S
# Checks for libraries.
AC_SEARCH_LIBS([recvfrom],[socket])
+case $host_os in
+ *mingw*)
+ AC_CHECK_LIB([ws2_32],[main])
+ ;;
+ *)
+ ;;
+esac
+
# Checks for library functions.
AC_CHECK_LIB([bsd], [arc4random_buf])
AC_CHECK_FUNCS([srand48 lrand48 arc4random_buf])
diff --git a/libXmu/src/RdBitF.c b/libXmu/src/RdBitF.c
index 02159c651..240c4c808 100644
--- a/libXmu/src/RdBitF.c
+++ b/libXmu/src/RdBitF.c
@@ -56,6 +56,7 @@ in this Software without prior written authorization from The Open Group.
#include <X11/Xmu/Drawing.h>
#ifdef WIN32
#include <X11/Xwindows.h>
+#include <direct.h> /* for _getdrives() */
#endif
#define MAX_SIZE 255
diff --git a/libXmu/src/StrToCurs.c b/libXmu/src/StrToCurs.c
index 7bb1da1cc..fc064c66e 100644
--- a/libXmu/src/StrToCurs.c
+++ b/libXmu/src/StrToCurs.c
@@ -58,8 +58,8 @@ SOFTWARE.
#include <X11/Xmu/CurUtil.h>
#include <X11/Xmu/CharSet.h>
-#ifndef X_NOT_POSIX
#include <stdlib.h>
+
#ifdef _POSIX_SOURCE
#include <limits.h>
#else
@@ -67,7 +67,7 @@ SOFTWARE.
#include <limits.h>
#undef _POSIX_SOURCE
#endif
-#endif /* X_NOT_POSIX */
+
#ifndef PATH_MAX
#ifdef WIN32
#define PATH_MAX 512
diff --git a/mesalib/.gitignore b/mesalib/.gitignore
index 00e3ce3da..21aa35cd3 100644
--- a/mesalib/.gitignore
+++ b/mesalib/.gitignore
@@ -45,3 +45,4 @@ manifest.txt
.libs/
Makefile
Makefile.in
+.install-mesa-links
diff --git a/mesalib/Makefile.am b/mesalib/Makefile.am
index f4f0912fa..9f49ce653 100644
--- a/mesalib/Makefile.am
+++ b/mesalib/Makefile.am
@@ -44,12 +44,15 @@ EXTRA_DIST = \
scons \
SConstruct
-noinst_HEADERS = \
- include/c99_compat.h \
- include/c99 \
- include/c11 \
- include/D3D9 \
- include/HaikuGL \
+noinst_HEADERS = \
+ include/c99_alloca.h \
+ include/c99_compat.h \
+ include/c99_math.h \
+ include/c99 \
+ include/c11 \
+ include/D3D9 \
+ include/HaikuGL \
+ include/no_extern_c.h \
include/pci_ids
# We list some directories in EXTRA_DIST, but don't actually want to include
diff --git a/mesalib/configure.ac b/mesalib/configure.ac
index 08378f570..095e23e69 100644
--- a/mesalib/configure.ac
+++ b/mesalib/configure.ac
@@ -123,10 +123,17 @@ if test "x$INDENT" != "xcat"; then
fi
AX_CHECK_PYTHON_MAKO_MODULE($PYTHON_MAKO_REQUIRED)
-if test -n "$PYTHON2" -a "x$acv_mako_found" = "xyes"; then
- AC_MSG_RESULT(yes)
+
+if test -z "$PYTHON2"; then
+ if test ! -f "$srcdir/src/util/format_srgb.c"; then
+ AC_MSG_ERROR([Python not found - unable to generate sources])
+ fi
else
- AC_MSG_ERROR([Python mako module v$PYTHON_MAKO_REQUIRED or higher not found])
+ if test "x$acv_mako_found" = xno; then
+ if test ! -f "$srcdir/src/mesa/main/format_unpack.c"; then
+ AC_MSG_ERROR([Python mako module v$PYTHON_MAKO_REQUIRED or higher not found])
+ fi
+ fi
fi
AC_PROG_INSTALL
@@ -223,7 +230,7 @@ _SAVE_LDFLAGS="$LDFLAGS"
_SAVE_CPPFLAGS="$CPPFLAGS"
dnl Compiler macros
-DEFINES="-DUSE_EXTERNAL_DXTN_LIB=1"
+DEFINES=""
AC_SUBST([DEFINES])
case "$host_os" in
linux*|*-gnu*|gnu*)
@@ -1634,7 +1641,7 @@ if test "x$enable_nine" = xyes; then
if ! echo "$with_gallium_drivers" | grep -q 'swrast'; then
AC_MSG_ERROR([nine requires the gallium swrast driver])
fi
- if test "x$with_gallium_drivers" == xswrast; then
+ if test "x$with_gallium_drivers" = xswrast; then
AC_MSG_ERROR([nine requires at least one non-swrast gallium driver])
fi
if test "x$enable_dri3" = xno; then
@@ -1649,19 +1656,6 @@ dnl
dnl OpenCL configuration
dnl
-AC_ARG_WITH([libclc-path],
- [AS_HELP_STRING([--with-libclc-path],
- [DEPRECATED: See http://dri.freedesktop.org/wiki/GalliumCompute#How_to_Install])],
- [LIBCLC_PATH="$withval"],
- [LIBCLC_PATH=''])
-
-if test -n "$LIBCLC_PATH"; then
- AC_MSG_ERROR([The --with-libclc-path option has been deprecated.
- Please review the updated build instructions for clover:
- http://dri.freedesktop.org/wiki/GalliumCompute])
-fi
-
-
AC_ARG_WITH([clang-libdir],
[AS_HELP_STRING([--with-clang-libdir],
[Path to Clang libraries @<:@default=llvm-config --libdir@:>@])],
@@ -1825,21 +1819,6 @@ if ! echo "$egl_platforms" | grep -q 'x11'; then
GL_PC_CFLAGS="$GL_PC_CFLAGS -DMESA_EGL_NO_X11_HEADERS"
fi
-AC_ARG_WITH([max-width],
- [AS_HELP_STRING([--with-max-width=N],
- [Maximum framebuffer width (4096)])],
- [DEFINES="${DEFINES} -DMAX_WIDTH=${withval}";
- AS_IF([test "${withval}" -gt "4096"],
- [AC_MSG_WARN([Large framebuffer: see s_tritemp.h comments.])])]
-)
-AC_ARG_WITH([max-height],
- [AS_HELP_STRING([--with-max-height=N],
- [Maximum framebuffer height (4096)])],
- [DEFINES="${DEFINES} -DMAX_HEIGHT=${withval}";
- AS_IF([test "${withval}" -gt "4096"],
- [AC_MSG_WARN([Large framebuffer: see s_tritemp.h comments.])])]
-)
-
dnl
dnl Gallium LLVM
dnl
@@ -1886,6 +1865,13 @@ strip_unwanted_llvm_flags() {
-e 's/-fstack-protector-strong\>//g'
}
+llvm_check_version_for() {
+ if test "${LLVM_VERSION_INT}${LLVM_VERSION_PATCH}" -lt "${1}0${2}${3}"; then
+ AC_MSG_ERROR([LLVM $1.$2.$3 or newer is required for $4])
+ fi
+}
+
+
if test -z "$with_gallium_drivers"; then
enable_gallium_llvm=no
@@ -1940,22 +1926,10 @@ if test "x$enable_gallium_llvm" = xyes; then
fi
if test "x$enable_opencl" = xyes; then
+ llvm_check_version_for "3" "5" "0" "opencl"
+
LLVM_COMPONENTS="${LLVM_COMPONENTS} all-targets ipo linker instrumentation"
- # LLVM 3.3 >= 177971 requires IRReader
- if $LLVM_CONFIG --components | grep -qw 'irreader'; then
- LLVM_COMPONENTS="${LLVM_COMPONENTS} irreader"
- fi
- # LLVM 3.4 requires Option
- if $LLVM_CONFIG --components | grep -qw 'option'; then
- LLVM_COMPONENTS="${LLVM_COMPONENTS} option"
- fi
- # Current OpenCL/Clover and LLVM 3.5 require ObjCARCOpts and ProfileData
- if $LLVM_CONFIG --components | grep -qw 'objcarcopts'; then
- LLVM_COMPONENTS="${LLVM_COMPONENTS} objcarcopts"
- fi
- if $LLVM_CONFIG --components | grep -qw 'profiledata'; then
- LLVM_COMPONENTS="${LLVM_COMPONENTS} profiledata"
- fi
+ LLVM_COMPONENTS="${LLVM_COMPONENTS} irreader option objcarcopts profiledata"
fi
DEFINES="${DEFINES} -DHAVE_LLVM=0x0$LLVM_VERSION_INT -DLLVM_VERSION_PATCH=$LLVM_VERSION_PATCH"
MESA_LLVM=1
@@ -2079,12 +2053,7 @@ radeon_llvm_check() {
if test "x$enable_gallium_llvm" != "xyes"; then
AC_MSG_ERROR([--enable-gallium-llvm is required when building $1])
fi
- LLVM_REQUIRED_VERSION_MAJOR="3"
- LLVM_REQUIRED_VERSION_MINOR="4"
- LLVM_REQUIRED_VERSION_PATCH="2"
- if test "${LLVM_VERSION_INT}${LLVM_VERSION_PATCH}" -lt "${LLVM_REQUIRED_VERSION_MAJOR}0${LLVM_REQUIRED_VERSION_MINOR}${LLVM_REQUIRED_VERSION_PATCH}"; then
- AC_MSG_ERROR([LLVM $LLVM_REQUIRED_VERSION_MAJOR.$LLVM_REQUIRED_VERSION_MINOR.$LLVM_REQUIRED_VERSION_PATCH or newer is required for $1])
- fi
+ llvm_check_version_for "3" "4" "2" $1
if test true && $LLVM_CONFIG --targets-built | grep -qvw 'R600' ; then
AC_MSG_ERROR([LLVM R600 Target not enabled. You can enable it when building the LLVM
sources with the --enable-experimental-targets=R600
@@ -2564,6 +2533,7 @@ if test "x$MESA_LLVM" = x1; then
echo " LLVM_CFLAGS: $LLVM_CFLAGS"
echo " LLVM_CXXFLAGS: $LLVM_CXXFLAGS"
echo " LLVM_CPPFLAGS: $LLVM_CPPFLAGS"
+ echo " LLVM_LDFLAGS: $LLVM_LDFLAGS"
echo ""
fi
echo " PYTHON2: $PYTHON2"
diff --git a/mesalib/docs/GL3.txt b/mesalib/docs/GL3.txt
index 93fa60d25..2dbd987de 100644
--- a/mesalib/docs/GL3.txt
+++ b/mesalib/docs/GL3.txt
@@ -111,11 +111,11 @@ GL 4.0, GLSL 4.00:
- New overload resolution rules DONE
GL_ARB_gpu_shader_fp64 DONE (nvc0, softpipe)
GL_ARB_sample_shading DONE (i965, nv50, nvc0, r600, radeonsi)
- GL_ARB_shader_subroutine not started
+ GL_ARB_shader_subroutine started (Dave)
GL_ARB_tessellation_shader started (Chris, Ilia)
GL_ARB_texture_buffer_object_rgb32 DONE (i965, nvc0, r600, radeonsi, llvmpipe, softpipe)
GL_ARB_texture_cube_map_array DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
- GL_ARB_texture_gather DONE (i965, nv50, nvc0, r600, radeonsi)
+ GL_ARB_texture_gather DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe)
GL_ARB_texture_query_lod DONE (i965, nv50, nvc0, r600, radeonsi)
GL_ARB_transform_feedback2 DONE (i965, nv50, nvc0, r600, radeonsi)
GL_ARB_transform_feedback3 DONE (i965, nv50, nvc0, r600, radeonsi)
@@ -161,7 +161,7 @@ GL 4.3, GLSL 4.30:
GL_ARB_internalformat_query2 not started
GL_ARB_invalidate_subdata DONE (all drivers)
GL_ARB_multi_draw_indirect DONE (i965, nvc0, r600, radeonsi, llvmpipe, softpipe)
- GL_ARB_program_interface_query not started
+ GL_ARB_program_interface_query DONE (all drivers)
GL_ARB_robust_buffer_access_behavior not started
GL_ARB_shader_image_size not started
GL_ARB_shader_storage_buffer_object not started
@@ -188,20 +188,20 @@ GL 4.4, GLSL 4.40:
GL 4.5, GLSL 4.50:
GL_ARB_ES3_1_compatibility not started
- GL_ARB_clip_control DONE (nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
+ GL_ARB_clip_control DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
GL_ARB_conditional_render_inverted DONE (i965, nv50, nvc0, llvmpipe, softpipe)
GL_ARB_cull_distance not started
GL_ARB_derivative_control DONE (i965, nv50, nvc0, r600)
GL_ARB_direct_state_access started
- - Transform Feedback object started (Martin Peres)
+ - Transform Feedback object DONE
- Buffer object DONE
- Framebuffer object started (Laura Ekstrand)
- - Renderbuffer object started (Martin Peres)
+ - Renderbuffer object DONE
- Texture object DONE
- Vertex array object started (Fredrik Höglund)
- - Sampler object started (Martin Peres)
- - Program Pipeline object started (Martin Peres)
- - Query object started (Martin Peres)
+ - Sampler object DONE
+ - Program Pipeline object DONE
+ - Query object DONE (will require changes when GL_ARB_query_buffer_object lands)
GL_ARB_get_texture_sub_image started (Brian Paul)
GL_ARB_shader_texture_image_samples not started
GL_ARB_texture_barrier DONE (nv50, nvc0, r600, radeonsi)
@@ -217,9 +217,10 @@ GLES3.1, GLSL ES 3.1
GL_ARB_draw_indirect DONE (i965, nvc0, r600, radeonsi, llvmpipe, softpipe)
GL_ARB_explicit_uniform_location DONE (all drivers that support GLSL)
GL_ARB_framebuffer_no_attachments not started
- GL_ARB_program_interface_query not started
+ GL_ARB_program_interface_query DONE (all drivers)
GL_ARB_shader_atomic_counters DONE (i965)
GL_ARB_shader_image_load_store in progress (curro)
+ GL_ARB_shader_image_size not started
GL_ARB_shader_storage_buffer_object not started
GL_ARB_shading_language_packing DONE (all drivers)
GL_ARB_separate_shader_objects DONE (all drivers)
diff --git a/mesalib/docs/README.WIN32 b/mesalib/docs/README.WIN32
index e0e5b9b2d..94e1d6fd8 100644
--- a/mesalib/docs/README.WIN32
+++ b/mesalib/docs/README.WIN32
@@ -11,10 +11,6 @@ no longer shipped or supported.
Run
- scons osmesa
-
-to build classic osmesa driver; or
-
scons libgl-gdi
to build gallium based GDI driver.
diff --git a/mesalib/docs/faq.html b/mesalib/docs/faq.html
index d4037e83c..b7c6fbf8a 100644
--- a/mesalib/docs/faq.html
+++ b/mesalib/docs/faq.html
@@ -327,19 +327,6 @@ Basically, applying a translation of (0.375, 0.375, 0.0) to your coordinates
will fix the problem.
</p>
-<h2>3.6 How can I change the maximum framebuffer size in Mesa's
-<tt>swrast</tt> backend?</h2>
-<p>
-These can be overridden by using the <tt>--with-max-width</tt> and
-<tt>--with-max-height</tt> options. The two need not be equal.
-</p><p>
-Do note that Mesa uses these values to size some internal buffers,
-so increasing these sizes will cause Mesa to require additional
-memory. Furthermore, increasing these limits beyond <tt>4096</tt>
-may introduce rasterization artifacts; see the leading comments in
-<tt>src/mesa/swrast/s_tritemp.h</tt>.
-</p>
-
<br>
<br>
diff --git a/mesalib/docs/index.html b/mesalib/docs/index.html
index 9bc5843ff..9e4644caa 100644
--- a/mesalib/docs/index.html
+++ b/mesalib/docs/index.html
@@ -16,6 +16,18 @@
<h1>News</h1>
+<h2>April 12, 2015</h2>
+<p>
+<a href="relnotes/10.5.3.html">Mesa 10.5.3</a> is released.
+This is a bug-fix release.
+</p>
+
+<h2>March 28, 2015</h2>
+<p>
+<a href="relnotes/10.5.2.html">Mesa 10.5.2</a> is released.
+This is a bug-fix release.
+</p>
+
<h2>March 20, 2015</h2>
<p>
<a href="relnotes/10.4.7.html">Mesa 10.4.7</a> is released.
diff --git a/mesalib/docs/llvmpipe.html b/mesalib/docs/llvmpipe.html
index 72db93aaf..f603bd646 100644
--- a/mesalib/docs/llvmpipe.html
+++ b/mesalib/docs/llvmpipe.html
@@ -58,15 +58,37 @@ It's the fastest software rasterizer for Mesa.
</pre>
<p>
- For Windows you will need to build LLVM from source with MSVC or MINGW
- (either natively or through cross compilers) and CMake, and set the LLVM
- environment variable to the directory you installed it to.
+ For Windows you will need to build LLVM from source with MSVC or MINGW
+ (either natively or through cross compilers) and CMake, and set the LLVM
+ environment variable to the directory you installed it to.
LLVM will be statically linked, so when building on MSVC it needs to be
built with a matching CRT as Mesa, and you'll need to pass
- -DLLVM_USE_CRT_RELEASE=MTd for debug and checked builds,
- -DLLVM_USE_CRT_RELEASE=MTd for profile and release builds.
+ <code>-DLLVM_USE_CRT_xxx=yyy</code> as described below.
+ </p>
+
+ <table border="1">
+ <tr>
+ <th rowspan="2">LLVM build-type</th>
+ <th colspan="2" align="center">Mesa build-type</th>
+ </tr>
+ <tr>
+ <th>debug,checked</th>
+ <th>release,profile</th>
+ </tr>
+ <tr>
+ <th>Debug</th>
+ <td><code>-DLLVM_USE_CRT_DEBUG=MTd</code></td>
+ <td><code>-DLLVM_USE_CRT_DEBUG=MT</code></td>
+ </tr>
+ <tr>
+ <th>Release</th>
+ <td><code>-DLLVM_USE_CRT_RELEASE=MTd</code></td>
+ <td><code>-DLLVM_USE_CRT_RELEASE=MT</code></td>
+ </tr>
+ </table>
+ <p>
You can build only the x86 target by passing -DLLVM_TARGETS_TO_BUILD=X86
to cmake.
</p>
diff --git a/mesalib/docs/relnotes.html b/mesalib/docs/relnotes.html
index 023f7dd8f..6ec35d11f 100644
--- a/mesalib/docs/relnotes.html
+++ b/mesalib/docs/relnotes.html
@@ -21,6 +21,8 @@ The release notes summarize what's new or changed in each Mesa release.
</p>
<ul>
+<li><a href="relnotes/10.5.3.html">10.5.3 release notes</a>
+<li><a href="relnotes/10.5.2.html">10.5.2 release notes</a>
<li><a href="relnotes/10.4.7.html">10.4.7 release notes</a>
<li><a href="relnotes/10.5.1.html">10.5.1 release notes</a>
<li><a href="relnotes/10.5.0.html">10.5.0 release notes</a>
diff --git a/mesalib/docs/relnotes/10.5.2.html b/mesalib/docs/relnotes/10.5.2.html
new file mode 100644
index 000000000..9114199c9
--- /dev/null
+++ b/mesalib/docs/relnotes/10.5.2.html
@@ -0,0 +1,130 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>Mesa Release Notes</title>
+ <link rel="stylesheet" type="text/css" href="../mesa.css">
+</head>
+<body>
+
+<div class="header">
+ <h1>The Mesa 3D Graphics Library</h1>
+</div>
+
+<iframe src="../contents.html"></iframe>
+<div class="content">
+
+<h1>Mesa 10.5.2 Release Notes / March 28, 2015</h1>
+
+<p>
+Mesa 10.5.2 is a bug fix release which fixes bugs found since the 10.5.1 release.
+</p>
+<p>
+Mesa 10.5.2 implements the OpenGL 3.3 API, but the version reported by
+glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
+glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 3.3. OpenGL
+3.3 is <strong>only</strong> available if requested at context creation
+because compatibility contexts are not supported.
+</p>
+
+
+<h2>SHA256 checksums</h2>
+<pre>
+755220e160a9f22fda0dffd47746f997b6e196d03f8edc390df7793aecaaa541 mesa-10.5.2.tar.gz
+2f4b6fb77c3e7d6f861558d0884a3073f575e1e673dad8d1b0624e78e9c4dd44 mesa-10.5.2.tar.xz
+</pre>
+
+
+<h2>New features</h2>
+<p>None</p>
+
+<h2>Bug fixes</h2>
+
+<p>This list is likely incomplete.</p>
+
+<ul>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=88534">Bug 88534</a> - include/c11/threads_posix.h PTHREAD_MUTEX_RECURSIVE_NP not defined</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89328">Bug 89328</a> - python required to build Mesa release tarballs</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89530">Bug 89530</a> - FTBFS in loader: missing fstat</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89590">Bug 89590</a> - Crash in glLinkProgram with shaders with multiple constant arrays</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89680">Bug 89680</a> - Hard link exist in Mesa 10.5.1 sources</li>
+
+</ul>
+
+
+<h2>Changes</h2>
+
+<p>Anuj Phogat (1):</p>
+<ul>
+ <li>glsl: Generate link error for non-matching gl_FragCoord redeclarations</li>
+</ul>
+
+<p>Emil Velikov (7):</p>
+<ul>
+ <li>docs: Add sha256 sums for the 10.5.1 release</li>
+ <li>automake: add missing egl files to the tarball</li>
+ <li>st/egl: don't ship the dri2.c link at the tarball</li>
+ <li>loader: include &lt;sys/stat.h&gt; for non-sysfs builds</li>
+ <li>auxiliary/os: fix the android build - s/drm_munmap/os_munmap/</li>
+ <li>cherry-ignore: add commit non applicable for 10.5</li>
+ <li>Update version to 10.5.2</li>
+</ul>
+
+<p>Felix Janda (1):</p>
+<ul>
+ <li>c11/threads: Use PTHREAD_MUTEX_RECURSIVE by default</li>
+</ul>
+
+<p>Francisco Jerez (1):</p>
+<ul>
+ <li>i965: Set nr_params to the number of uniform components in the VS/GS path.</li>
+</ul>
+
+<p>Ilia Mirkin (2):</p>
+<ul>
+ <li>freedreno/a3xx: use the same layer size for all slices</li>
+ <li>freedreno: fix slice pitch calculations</li>
+</ul>
+
+<p>Marek Olšák (1):</p>
+<ul>
+ <li>radeonsi: increase coords array size for radeon_llvm_emit_prepare_cube_coords</li>
+</ul>
+
+<p>Mario Kleiner (2):</p>
+<ul>
+ <li>glx: Handle out-of-sequence swap completion events correctly. (v2)</li>
+ <li>mapi: Make private copies of name strings provided by client.</li>
+</ul>
+
+<p>Rob Clark (1):</p>
+<ul>
+ <li>freedreno: update generated headers</li>
+</ul>
+
+<p>Samuel Iglesias Gonsalvez (2):</p>
+<ul>
+ <li>glsl: optimize (0 cmp x + y) into (-x cmp y).</li>
+ <li>configure: Introduce new output variable to ax_check_python_mako_module.m4</li>
+</ul>
+
+<p>Tapani Pälli (1):</p>
+<ul>
+ <li>glsl: fix names in lower_constant_arrays_to_uniforms</li>
+</ul>
+
+<p>Tom Stellard (1):</p>
+<ul>
+ <li>clover: Return 0 as storage size for local kernel args that are not set v2</li>
+</ul>
+
+
+</div>
+</body>
+</html>
diff --git a/mesalib/docs/relnotes/10.5.3.html b/mesalib/docs/relnotes/10.5.3.html
new file mode 100644
index 000000000..e5e0d3063
--- /dev/null
+++ b/mesalib/docs/relnotes/10.5.3.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>Mesa Release Notes</title>
+ <link rel="stylesheet" type="text/css" href="../mesa.css">
+</head>
+<body>
+
+<div class="header">
+ <h1>The Mesa 3D Graphics Library</h1>
+</div>
+
+<iframe src="../contents.html"></iframe>
+<div class="content">
+
+<h1>Mesa 10.5.3 Release Notes / April 12, 2015</h1>
+
+<p>
+Mesa 10.5.3 is a bug fix release which fixes bugs found since the 10.5.2 release.
+</p>
+<p>
+Mesa 10.5.3 implements the OpenGL 3.3 API, but the version reported by
+glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
+glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 3.3. OpenGL
+3.3 is <strong>only</strong> available if requested at context creation
+because compatibility contexts are not supported.
+</p>
+
+
+<h2>SHA256 checksums</h2>
+<pre>
+2371b8e210ccd19f61dd94b6664d612e5a479ba7d431a074512d87633bd6aeb4 mesa-10.5.3.tar.gz
+8701ee1be4f5c03238f5e63c1a9bd4cc03a2f6c0155ed42a1ae7d58f18912ba2 mesa-10.5.3.tar.xz
+</pre>
+
+
+<h2>New features</h2>
+<p>None</p>
+
+<h2>Bug fixes</h2>
+
+<p>This list is likely incomplete.</p>
+
+<ul>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83962">Bug 83962</a> - [HSW/BYT]Piglit spec_ARB_gpu_shader5_arb_gpu_shader5-emitstreamvertex_nodraw fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89679">Bug 89679</a> - [NV50] Portal/Half-Life 2 will not start (native Steam)</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89746">Bug 89746</a> - Mesa and LLVM 3.6+ break opengl for genymotion</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89754">Bug 89754</a> - vertexAttrib fails WebGL Conformance test with mesa drivers</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89758">Bug 89758</a> - pow WebGL Conformance test with mesa drivers</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89759">Bug 89759</a> - WebGL OGL ES GLSL conformance test with mesa drivers fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89905">Bug 89905</a> - scons build broken on 10.5.2 due to activated vega st</li>
+
+</ul>
+
+<h2>Changes</h2>
+
+<p>Dave Airlie (1):</p>
+<ul>
+ <li>st_glsl_to_tgsi: only do mov copy propagation on temps (v2)</li>
+</ul>
+
+<p>Emil Velikov (5):</p>
+<ul>
+ <li>docs: Add sha256 sums for the 10.5.2 release</li>
+ <li>xmlpool: don't forget to ship the MOS</li>
+ <li>configure.ac: error out if python/mako is not found when required</li>
+ <li>dist: add the VG depedencies into the tarball</li>
+ <li>Update version to 10.5.3</li>
+</ul>
+
+<p>Iago Toral Quiroga (1):</p>
+<ul>
+ <li>i965: Do not render primitives in non-zero streams then TF is disabled</li>
+</ul>
+
+<p>Ilia Mirkin (7):</p>
+<ul>
+ <li>st/mesa: update arrays when the current attrib has been updated</li>
+ <li>nv50/ir: take postFactor into account when doing peephole optimizations</li>
+ <li>nv50/ir/gk110: fix offset flag position for TXD opcode</li>
+ <li>freedreno/a3xx: fix 3d texture layout</li>
+ <li>freedreno/a3xx: point size should not be divided by 2</li>
+ <li>nv50: allocate more offset space for occlusion queries</li>
+ <li>nv50,nvc0: limit the y-tiling of 3d textures to the first level's tiling</li>
+</ul>
+
+<p>Kenneth Graunke (2):</p>
+<ul>
+ <li>i965: Fix instanced geometry shaders on Gen8+.</li>
+ <li>i965: Add forgotten multi-stream code to Gen8 SOL state.</li>
+</ul>
+
+<p>Marcin Ślusarz (1):</p>
+<ul>
+ <li>nouveau: synchronize "scratch runout" destruction with the command stream</li>
+</ul>
+
+<p>Michel Dänzer (1):</p>
+<ul>
+ <li>radeonsi: Cache LLVMTargetMachineRef in context instead of in screen</li>
+</ul>
+
+<p>Tom Stellard (1):</p>
+<ul>
+ <li>clover: Return CL_BUILD_ERROR for CL_PROGRAM_BUILD_STATUS when compilation fails v2</li>
+</ul>
+
+<p>Ville Syrjälä (1):</p>
+<ul>
+ <li>i965: Fix URB size for CHV</li>
+</ul>
+
+
+</div>
+</body>
+</html>
diff --git a/mesalib/docs/relnotes/10.6.0.html b/mesalib/docs/relnotes/10.6.0.html
index 00aaaa5fc..82aea5cf9 100644
--- a/mesalib/docs/relnotes/10.6.0.html
+++ b/mesalib/docs/relnotes/10.6.0.html
@@ -45,11 +45,15 @@ Note: some of the new features are only available with certain drivers.
<ul>
<li>GL_AMD_pinned_memory on r600, radeonsi</li>
+<li>GL_ARB_draw_indirect, GL_ARB_multi_draw_indirect on r600</li>
<li>GL_ARB_draw_instanced on freedreno</li>
<li>GL_ARB_gpu_shader_fp64 on nvc0, softpipe</li>
<li>GL_ARB_instanced_arrays on freedreno</li>
<li>GL_ARB_pipeline_statistics_query on i965, nv50, nvc0, r600, radeonsi, softpipe</li>
-<li>GL_ARB_draw_indirect, GL_ARB_multi_draw_indirect on r600</li>
+<li>GL_ARB_uniform_buffer_object on freedreno</li>
+<li>GL_EXT_draw_buffers2 on freedreno</li>
+<li>GL_ARB_clip_control on i965</li>
+<li>GL_ARB_program_interface_query (all drivers)</li>
</ul>
<h2>Bug fixes</h2>
@@ -65,6 +69,8 @@ TBD.
<li>Removed OpenVG support.</li>
<li>Removed the galahad gallium driver.</li>
<li>Removed the identity gallium driver.</li>
+<li>Removed the EGL loader from the Windows SCons build.</li>
+<li>Removed the classic osmesa from the Windows SCons build.</li>
</ul>
</div>
diff --git a/mesalib/docs/specs/MESA_image_dma_buf_export.txt b/mesalib/docs/specs/MESA_image_dma_buf_export.txt
new file mode 100644
index 000000000..c3794ee36
--- /dev/null
+++ b/mesalib/docs/specs/MESA_image_dma_buf_export.txt
@@ -0,0 +1,142 @@
+Name
+
+ MESA_image_dma_buf_export
+
+Name Strings
+
+ EGL_MESA_image_dma_buf_export
+
+Contributors
+
+ Dave Airlie
+
+Contact
+
+ Dave Airlie (airlied 'at' redhat 'dot' com)
+
+Status
+
+ Proposal
+
+Version
+
+ Version 2, Mar 30, 2015
+
+Number
+
+ EGL Extension #not assigned
+
+Dependencies
+
+ Reguires EGL 1.4 or later. This extension is written against the
+ wording of the EGL 1.4 specification.
+
+ EGL_KHR_base_image is required.
+
+ The EGL implementation must be running on a Linux kernel supporting the
+ dma_buf buffer sharing mechanism.
+
+Overview
+
+ This extension provides entry points for integrating EGLImage with the
+ dma-buf infrastructure. The extension allows creating a Linux dma_buf
+ file descriptor or multiple file descriptors, in the case of multi-plane
+ YUV image, from an EGLImage.
+
+ It is designed to provide the complementary functionality to EGL_EXT_image_dma_buf_import.
+
+IP Status
+
+ Open-source; freely implementable.
+
+New Types
+
+ This is a 64 bit unsigned integer.
+
+ typedef khronos_uint64_t EGLuint64MESA;
+
+
+New Procedures and Functions
+
+ EGLBoolean eglExportDMABUFImageQueryMESA(EGLDisplay dpy,
+ EGLImageKHR image,
+ int *fourcc,
+ int *num_planes,
+ EGLuint64MESA *modifiers);
+
+ EGLBoolean eglExportDMABUFImageMESA(EGLDisplay dpy,
+ EGLImageKHR image,
+ int *fds,
+ EGLint *strides,
+ EGLint *offsets);
+
+New Tokens
+
+ None
+
+
+Additions to the EGL 1.4 Specification:
+
+ To mirror the import extension, this extension attempts to return
+ enough information to enable an exported dma-buf to be imported
+ via eglCreateImageKHR and EGL_LINUX_DMA_BUF_EXT token.
+
+ Retrieving the information is a two step process, so two APIs
+ are required.
+
+ The first entrypoint
+ EGLBoolean eglExportDMABUFImageQueryMESA(EGLDisplay dpy,
+ EGLImageKHR image,
+ int *fourcc,
+ int *num_planes,
+ EGLuint64MESA *modifiers);
+
+ is used to retrieve the pixel format of the buffer, as specified by
+ drm_fourcc.h, the number of planes in the image and the Linux
+ drm modifiers. <fourcc>, <num_planes> and <modifiers> may be NULL,
+ in which case no value is retrieved.
+
+ The second entrypoint retrieves the dma_buf file descriptors,
+ strides and offsets for the image. The caller should pass
+ arrays sized according to the num_planes values retrieved previously.
+ Passing arrays of the wrong size will have undefined results.
+ If the number of fds is less than the number of planes, then
+ subsequent fd slots should contain -1.
+
+ EGLBoolean eglExportDMABUFImageMESA(EGLDisplay dpy,
+ EGLImageKHR image,
+ int *fds,
+ EGLint *strides,
+ EGLint *offsets);
+
+ <fds>, <strides>, <offsets> can be NULL if the infomatation isn't
+ required by the caller.
+
+Issues
+
+1. Should the API look more like an attribute getting API?
+
+ANSWER: No, from a user interface pov, having to iterate across calling
+the API up to 12 times using attribs seems like the wrong solution.
+
+2. Should the API take a plane and just get the fd/stride/offset for that
+ plane?
+
+ANSWER: UNKNOWN,this might be just as valid an API.
+
+3. Does ownership of the file descriptor remain with the app?
+
+ANSWER: Yes, the app is responsible for closing any fds retrieved.
+
+4. If number of planes and number of fds differ what should we do?
+
+ANSWER: Return -1 for the secondary slots, as this avoids having
+to dup the fd extra times to make the interface sane.
+
+Revision History
+
+ Version 2, March, 2015
+ Add a query interface (Dave Airlie)
+ Version 1, June 3, 2014
+ Initial draft (Dave Airlie)
+
diff --git a/mesalib/docs/viewperf.html b/mesalib/docs/viewperf.html
index 23c6028d2..6b63b94d8 100644
--- a/mesalib/docs/viewperf.html
+++ b/mesalib/docs/viewperf.html
@@ -19,6 +19,7 @@
<p>
This page lists known issues with
<a href="http://www.spec.org/gwpg/gpc.static/vp11info.html" target="_main">SPEC Viewperf 11</a>
+and <a href="https://www.spec.org/gwpg/gpc.static/vp12info.html" target="_main">SPEC Viewperf 12</a>
when running on Mesa-based drivers.
</p>
@@ -40,13 +41,15 @@ These issues have been reported to the SPEC organization in the hope that
they'll be fixed in the future.
</p>
+<h2><u>Viewperf 11</u></h2>
+
<p>
-Some of the Viewperf tests use a lot of memory.
+Some of the Viewperf 11 tests use a lot of memory.
At least 2GB of RAM is recommended.
</p>
-<h2>Catia-03 test 2</h2>
+<h3>Catia-03 test 2</h3>
<p>
This test creates over 38000 vertex buffer objects. On some systems
@@ -59,7 +62,7 @@ either in Viewperf or the Mesa driver.
-<h2>Catia-03 tests 3, 4, 8</h2>
+<h3>Catia-03 tests 3, 4, 8</h3>
<p>
These tests use features of the
@@ -79,7 +82,7 @@ Subsequent drawing calls become no-ops and the rendering is incorrect.
-<h2>sw-02 tests 1, 2, 4, 6</h2>
+<h3>sw-02 tests 1, 2, 4, 6</h3>
<p>
These tests depend on the
@@ -99,7 +102,7 @@ color. This is probably due to some uninitialized state somewhere.
-<h2>sw-02 test 6</h2>
+<h3>sw-02 test 6</h3>
<p>
The lines drawn in this test appear in a random color.
@@ -111,7 +114,7 @@ situation, we get a random color.
-<h2>Lightwave-01 test 3</h2>
+<h3>Lightwave-01 test 3</h3>
<p>
This test uses a number of mipmapped textures, but the textures are
@@ -172,7 +175,7 @@ However, we have no plans to implement this work-around in Mesa.
</p>
-<h2>Maya-03 test 2</h2>
+<h3>Maya-03 test 2</h3>
<p>
This test makes some unusual calls to glRotate. For example:
@@ -204,7 +207,7 @@ and with a semi-random color (between white and black) since GL_FOG is enabled.
</p>
-<h2>Proe-05 test 1</h2>
+<h3>Proe-05 test 1</h3>
<p>
This uses depth testing but there's two problems:
@@ -232,7 +235,7 @@ glClear is called so clearing the depth buffer would be a no-op anyway.
</p>
-<h2>Proe-05 test 6</h2>
+<h3>Proe-05 test 6</h3>
<p>
This test draws an engine model with a two-pass algorithm.
@@ -261,6 +264,79 @@ blending with appropriate patterns/modes to ensure the same fragments
are produced in both passes.
</p>
+<h2><u>Viewperf 12</u></h2>
+
+<p>
+Note that Viewperf 12 only runs on 64-bit Windows 7 or later.
+</p>
+
+<h3>catia-04</h3>
+
+<p>
+One of the catia tests calls wglGetProcAddress() to get some
+GL_EXT_direct_state_access functions (such as glBindMultiTextureEXT) and some
+GL_NV_half_float functions (such as glMultiTexCoord3hNV).
+If the extension/function is not supported, wglGetProcAddress() can return NULL.
+Unfortunately, Viewperf doesn't check for null pointers and crashes when it
+later tries to use the pointer.
+</p>
+
+<p>
+Another catia test uses OpenGL 3.1's primitive restart feature.
+But when Viewperf creates an OpenGL context, it doesn't request version 3.1
+If the driver returns version 3.0 or earlier all the calls related to primitive
+restart generate an OpenGL error.
+Some of the rendering is then incorrect.
+</p>
+
+
+<h3>energy-01</h3>
+
+<p>
+This test creates a 3D luminance texture of size 1K x 1K x 1K.
+If the OpenGL driver/device doesn't support a texture of this size
+the glTexImage3D() call will fail with GL_INVALID_VALUE or GL_OUT_OF_MEMORY
+and all that's rendered is plain white polygons.
+Ideally, the test would use a proxy texture to determine the max 3D
+texture size. But it does not do that.
+</p>
+
+<h3>maya-04</h3>
+
+<p>
+This test generates many GL_INVALID_OPERATION errors in its calls to
+glUniform().
+Causes include:
+<ul>
+<li> Trying to set float uniforms with glUniformi()
+<li> Trying to set float uniforms with glUniform3f()
+<li> Trying to set matrix uniforms with glUniform() instead of glUniformMatrix().
+</ul>
+<p>
+Apparently, the indexes returned by glGetUniformLocation() were hard-coded
+into the application trace when it was created.
+Since different implementations of glGetUniformLocation() may return different
+values for any given uniform name, subsequent calls to glUniform() will be
+invalid since they refer to the wrong uniform variables.
+This causes many OpenGL errors and leads to incorrect rendering.
+</p>
+
+<h3>medical-01</h3>
+
+<p>
+This test uses a single GLSL fragment shader which contains a GLSL 1.20
+array initializer statement, but it neglects to specify
+<code>#version 120</code> at the top of the shader code.
+So, the shader does not compile and all that's rendered is plain white polygons.
+</p>
+
+<h3>showcase-01</h3>
+
+<p>
+This is actually a DX11 test based on Autodesk's Showcase product.
+As such, it won't run with Mesa.
+</p>
+
</div>
</body>
diff --git a/mesalib/include/EGL/eglmesaext.h b/mesalib/include/EGL/eglmesaext.h
index 5fcc527d6..595babd54 100644
--- a/mesalib/include/EGL/eglmesaext.h
+++ b/mesalib/include/EGL/eglmesaext.h
@@ -170,6 +170,14 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG
#define EGL_NO_CONFIG_MESA ((EGLConfig)0)
#endif
+#if KHRONOS_SUPPORT_INT64
+#ifndef EGL_MESA_image_dma_buf_export
+#define EGL_MESA_image_dma_buf_export 1
+typedef khronos_uint64_t EGLuint64MESA;
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *fourcc, EGLint *nplanes, EGLuint64MESA *modifiers);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets);
+#endif
+#endif
#ifdef __cplusplus
}
#endif
diff --git a/mesalib/include/GL/internal/dri_interface.h b/mesalib/include/GL/internal/dri_interface.h
index 1d670b1e0..eb7da23f7 100644
--- a/mesalib/include/GL/internal/dri_interface.h
+++ b/mesalib/include/GL/internal/dri_interface.h
@@ -1006,7 +1006,7 @@ struct __DRIdri2ExtensionRec {
* extensions.
*/
#define __DRI_IMAGE "DRI_IMAGE"
-#define __DRI_IMAGE_VERSION 10
+#define __DRI_IMAGE_VERSION 11
/**
* These formats correspond to the similarly named MESA_FORMAT_*
@@ -1097,6 +1097,8 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_ATTRIB_FD 0x2007 /* available in versions
* 7+. Each query will return a
* new fd. */
+#define __DRI_IMAGE_ATTRIB_FOURCC 0x2008 /* available in versions 11 */
+#define __DRI_IMAGE_ATTRIB_NUM_PLANES 0x2009 /* available in versions 11 */
enum __DRIYUVColorSpace {
__DRI_YUV_COLOR_SPACE_UNDEFINED = 0,
diff --git a/mesalib/include/GL/osmesa.h b/mesalib/include/GL/osmesa.h
index 16ee89ae4..ca0d1675a 100644
--- a/mesalib/include/GL/osmesa.h
+++ b/mesalib/include/GL/osmesa.h
@@ -41,10 +41,8 @@
* OSMesaGetIntegerv - return OSMesa state parameters
*
*
- * The limits on the width and height of an image buffer are MAX_WIDTH and
- * MAX_HEIGHT as defined in Mesa/src/config.h. Defaults are 1280 and 1024.
- * You can increase them as needed but beware that many temporary arrays in
- * Mesa are dimensioned by MAX_WIDTH or MAX_HEIGHT.
+ * The limits on the width and height of an image buffer can be retrieved
+ * via OSMesaGetIntegerv(OSMESA_MAX_WIDTH/OSMESA_MAX_HEIGHT).
*/
diff --git a/mesalib/include/c99_math.h b/mesalib/include/c99_math.h
index 5b01d53a8..7ed7cc221 100644
--- a/mesalib/include/c99_math.h
+++ b/mesalib/include/c99_math.h
@@ -82,7 +82,12 @@ roundf(float x)
#endif /* _MSC_VER */
-#if __STDC_VERSION__ < 199901L && (!defined(__cplusplus) || defined(_MSC_VER))
+#if (defined(_MSC_VER) && _MSC_VER < 1800) || \
+ (!defined(_MSC_VER) && \
+ __STDC_VERSION__ < 199901L && \
+ (!defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600) && \
+ !defined(__cplusplus))
+
static inline long int
lrint(double d)
{
@@ -134,6 +139,7 @@ llrintf(float f)
return rounded;
}
+
#endif /* C99 */
diff --git a/mesalib/m4/ax_check_python_mako_module.m4 b/mesalib/m4/ax_check_python_mako_module.m4
index ee68a7cdb..7d9bb511c 100644
--- a/mesalib/m4/ax_check_python_mako_module.m4
+++ b/mesalib/m4/ax_check_python_mako_module.m4
@@ -54,8 +54,10 @@ else:
" | $PYTHON2 -
if test $? -ne 0 ; then
+ AC_MSG_RESULT(no)
AC_SUBST(acv_mako_found, 'no')
else
+ AC_MSG_RESULT(yes)
AC_SUBST(acv_mako_found, 'yes')
fi
])
diff --git a/mesalib/scons/gallium.py b/mesalib/scons/gallium.py
index efc65e718..51b84d765 100644
--- a/mesalib/scons/gallium.py
+++ b/mesalib/scons/gallium.py
@@ -549,6 +549,7 @@ def generate(env):
env.Append(CCFLAGS = [
'/analyze',
#'/analyze:log', '${TARGET.base}.xml',
+ '/wd28251', # Inconsistent annotation for function
])
if env['clang']:
# scan-build will produce more comprehensive output
diff --git a/mesalib/src/Makefile.am b/mesalib/src/Makefile.am
index 8edf33373..18cb4ce76 100644
--- a/mesalib/src/Makefile.am
+++ b/mesalib/src/Makefile.am
@@ -53,7 +53,13 @@ if HAVE_GALLIUM
SUBDIRS += gallium
endif
-EXTRA_DIST = egl/docs getopt hgl SConscript
+EXTRA_DIST = \
+ egl/drivers/haiku \
+ egl/docs \
+ getopt hgl SConscript
+
+AM_CFLAGS = $(VISIBILITY_CFLAGS)
+AM_CXXFLAGS = $(VISIBILITY_CXXFLAGS)
AM_CPPFLAGS = \
-I$(top_srcdir)/include/ \
diff --git a/mesalib/src/SConscript b/mesalib/src/SConscript
index 188ab08b6..b0578e892 100644
--- a/mesalib/src/SConscript
+++ b/mesalib/src/SConscript
@@ -12,7 +12,8 @@ if env['hostonly']:
# compilation
Return()
-SConscript('loader/SConscript')
+if env['platform'] != 'windows':
+ SConscript('loader/SConscript')
# When env['gles'] is set, the targets defined in mapi/glapi/SConscript are not
# used. libgl-xlib and libgl-gdi adapt themselves to use the targets defined
@@ -30,7 +31,7 @@ SConscript('mesa/SConscript')
if not env['embedded']:
if env['platform'] not in ('cygwin', 'darwin', 'freebsd', 'haiku', 'windows'):
SConscript('glx/SConscript')
- if env['platform'] not in ['darwin', 'haiku', 'sunos']:
+ if env['platform'] not in ['darwin', 'haiku', 'sunos', 'windows']:
if env['dri']:
SConscript('egl/drivers/dri2/SConscript')
SConscript('egl/main/SConscript')
diff --git a/mesalib/src/gallium/auxiliary/Makefile.am b/mesalib/src/gallium/auxiliary/Makefile.am
index 27a8b3fe4..89c7a13e9 100644
--- a/mesalib/src/gallium/auxiliary/Makefile.am
+++ b/mesalib/src/gallium/auxiliary/Makefile.am
@@ -10,6 +10,7 @@ include $(top_srcdir)/src/gallium/Automake.inc
noinst_LTLIBRARIES = libgallium.la
AM_CFLAGS = \
+ -I$(top_builddir)/src/glsl/nir \
-I$(top_srcdir)/src/gallium/auxiliary/util \
$(GALLIUM_CFLAGS) \
$(VISIBILITY_CFLAGS) \
@@ -21,6 +22,7 @@ AM_CXXFLAGS = \
libgallium_la_SOURCES = \
$(C_SOURCES) \
+ $(NIR_SOURCES) \
$(GENERATED_SOURCES)
if HAVE_MESA_LLVM
diff --git a/mesalib/src/gallium/auxiliary/Makefile.sources b/mesalib/src/gallium/auxiliary/Makefile.sources
index b7174d6e7..ec7547cad 100644
--- a/mesalib/src/gallium/auxiliary/Makefile.sources
+++ b/mesalib/src/gallium/auxiliary/Makefile.sources
@@ -251,8 +251,6 @@ C_SOURCES := \
util/u_keymap.h \
util/u_linear.c \
util/u_linear.h \
- util/u_linkage.c \
- util/u_linkage.h \
util/u_math.c \
util/u_math.h \
util/u_memory.h \
@@ -304,6 +302,10 @@ C_SOURCES := \
util/u_vbuf.h \
util/u_video.h
+NIR_SOURCES := \
+ nir/tgsi_to_nir.c \
+ nir/tgsi_to_nir.h
+
VL_SOURCES := \
vl/vl_compositor.c \
vl/vl_compositor.h \
diff --git a/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c b/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c
index b48708c2f..53771fcae 100644
--- a/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c
+++ b/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c
@@ -157,7 +157,8 @@ hud_pipe_query_install(struct hud_pane *pane, struct pipe_context *pipe,
if (!gr)
return;
- strcpy(gr->name, name);
+ strncpy(gr->name, name, sizeof(gr->name));
+ gr->name[sizeof(gr->name) - 1] = '\0';
gr->query_data = CALLOC_STRUCT(query_info);
if (!gr->query_data) {
FREE(gr);
diff --git a/mesalib/src/gallium/auxiliary/nir/tgsi_to_nir.c b/mesalib/src/gallium/auxiliary/nir/tgsi_to_nir.c
new file mode 100644
index 000000000..59aaf6778
--- /dev/null
+++ b/mesalib/src/gallium/auxiliary/nir/tgsi_to_nir.c
@@ -0,0 +1,1750 @@
+/*
+ * Copyright © 2014-2015 Broadcom
+ * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "util/ralloc.h"
+#include "glsl/nir/nir.h"
+#include "glsl/nir/nir_builder.h"
+#include "glsl/list.h"
+#include "glsl/shader_enums.h"
+
+#include "nir/tgsi_to_nir.h"
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_info.h"
+#include "tgsi/tgsi_scan.h"
+
+#define SWIZ(X, Y, Z, W) (unsigned[4]){ \
+ TGSI_SWIZZLE_##X, \
+ TGSI_SWIZZLE_##Y, \
+ TGSI_SWIZZLE_##Z, \
+ TGSI_SWIZZLE_##W, \
+ }
+
+struct ttn_reg_info {
+ /** nir register containing this TGSI index. */
+ nir_register *reg;
+ nir_variable *var;
+ /** Offset (in vec4s) from the start of var for this TGSI index. */
+ int offset;
+};
+
+struct ttn_compile {
+ union tgsi_full_token *token;
+ nir_builder build;
+ struct tgsi_shader_info *scan;
+
+ struct ttn_reg_info *output_regs;
+ struct ttn_reg_info *temp_regs;
+ nir_ssa_def **imm_defs;
+
+ nir_register *addr_reg;
+
+ /**
+ * Stack of cf_node_lists where instructions should be pushed as we pop
+ * back out of the control flow stack.
+ *
+ * For each IF/ELSE/ENDIF block, if_stack[if_stack_pos] has where the else
+ * instructions should be placed, and if_stack[if_stack_pos - 1] has where
+ * the next instructions outside of the if/then/else block go.
+ */
+ struct exec_list **if_stack;
+ unsigned if_stack_pos;
+
+ /**
+ * Stack of cf_node_lists where instructions should be pushed as we pop
+ * back out of the control flow stack.
+ *
+ * loop_stack[loop_stack_pos - 1] contains the cf_node_list for the outside
+ * of the loop.
+ */
+ struct exec_list **loop_stack;
+ unsigned loop_stack_pos;
+
+ /* How many TGSI_FILE_IMMEDIATE vec4s have been parsed so far. */
+ unsigned next_imm;
+};
+
+#define ttn_swizzle(b, src, x, y, z, w) \
+ nir_swizzle(b, src, SWIZ(x, y, z, w), 4, false)
+#define ttn_channel(b, src, swiz) \
+ nir_swizzle(b, src, SWIZ(swiz, swiz, swiz, swiz), 1, false)
+
+static nir_ssa_def *
+ttn_src_for_dest(nir_builder *b, nir_alu_dest *dest)
+{
+ nir_alu_src src;
+ memset(&src, 0, sizeof(src));
+
+ if (dest->dest.is_ssa)
+ src.src = nir_src_for_ssa(&dest->dest.ssa);
+ else {
+ assert(!dest->dest.reg.indirect);
+ src.src = nir_src_for_reg(dest->dest.reg.reg);
+ src.src.reg.base_offset = dest->dest.reg.base_offset;
+ }
+
+ for (int i = 0; i < 4; i++)
+ src.swizzle[i] = i;
+
+ return nir_fmov_alu(b, src, 4);
+}
+
+static void
+ttn_emit_declaration(struct ttn_compile *c)
+{
+ nir_builder *b = &c->build;
+ struct tgsi_full_declaration *decl = &c->token->FullDeclaration;
+ unsigned array_size = decl->Range.Last - decl->Range.First + 1;
+ unsigned file = decl->Declaration.File;
+ unsigned i;
+
+ if (file == TGSI_FILE_TEMPORARY) {
+ if (decl->Declaration.Array) {
+ /* for arrays, we create variables instead of registers: */
+ nir_variable *var = rzalloc(b->shader, nir_variable);
+
+ var->type = glsl_array_type(glsl_vec4_type(), array_size);
+ var->data.mode = nir_var_global;
+ var->name = ralloc_asprintf(var, "arr_%d", decl->Array.ArrayID);
+
+ exec_list_push_tail(&b->shader->globals, &var->node);
+
+ for (i = 0; i < array_size; i++) {
+ /* point all the matching slots to the same var,
+ * with appropriate offset set, mostly just so
+ * we know what to do when tgsi does a non-indirect
+ * access
+ */
+ c->temp_regs[decl->Range.First + i].reg = NULL;
+ c->temp_regs[decl->Range.First + i].var = var;
+ c->temp_regs[decl->Range.First + i].offset = i;
+ }
+ } else {
+ for (i = 0; i < array_size; i++) {
+ nir_register *reg = nir_local_reg_create(b->impl);
+ reg->num_components = 4;
+ c->temp_regs[decl->Range.First + i].reg = reg;
+ c->temp_regs[decl->Range.First + i].var = NULL;
+ c->temp_regs[decl->Range.First + i].offset = 0;
+ }
+ }
+ } else if (file == TGSI_FILE_ADDRESS) {
+ c->addr_reg = nir_local_reg_create(b->impl);
+ c->addr_reg->num_components = 4;
+ } else if (file == TGSI_FILE_SYSTEM_VALUE) {
+ /* Nothing to record for system values. */
+ } else if (file == TGSI_FILE_SAMPLER) {
+ /* Nothing to record for samplers. */
+ } else {
+ nir_variable *var;
+ assert(file == TGSI_FILE_INPUT ||
+ file == TGSI_FILE_OUTPUT ||
+ file == TGSI_FILE_CONSTANT);
+
+ /* nothing to do for UBOs: */
+ if ((file == TGSI_FILE_CONSTANT) && decl->Declaration.Dimension)
+ return;
+
+ var = rzalloc(b->shader, nir_variable);
+ var->data.driver_location = decl->Range.First;
+
+ var->type = glsl_vec4_type();
+ if (array_size > 1)
+ var->type = glsl_array_type(var->type, array_size);
+
+ switch (file) {
+ case TGSI_FILE_INPUT:
+ var->data.read_only = true;
+ var->data.mode = nir_var_shader_in;
+ var->name = ralloc_asprintf(var, "in_%d", decl->Range.First);
+
+ /* We should probably translate to a VERT_ATTRIB_* or VARYING_SLOT_*
+ * instead, but nothing in NIR core is looking at the value
+ * currently, and this is less change to drivers.
+ */
+ var->data.location = decl->Semantic.Name;
+ var->data.index = decl->Semantic.Index;
+
+ /* We definitely need to translate the interpolation field, because
+ * nir_print will decode it.
+ */
+ switch (decl->Interp.Interpolate) {
+ case TGSI_INTERPOLATE_CONSTANT:
+ var->data.interpolation = INTERP_QUALIFIER_FLAT;
+ break;
+ case TGSI_INTERPOLATE_LINEAR:
+ var->data.interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
+ break;
+ case TGSI_INTERPOLATE_PERSPECTIVE:
+ var->data.interpolation = INTERP_QUALIFIER_SMOOTH;
+ break;
+ }
+
+ exec_list_push_tail(&b->shader->inputs, &var->node);
+ break;
+ case TGSI_FILE_OUTPUT: {
+ /* Since we can't load from outputs in the IR, we make temporaries
+ * for the outputs and emit stores to the real outputs at the end of
+ * the shader.
+ */
+ nir_register *reg = nir_local_reg_create(b->impl);
+ reg->num_components = 4;
+ if (array_size > 1)
+ reg->num_array_elems = array_size;
+
+ var->data.mode = nir_var_shader_out;
+ var->name = ralloc_asprintf(var, "out_%d", decl->Range.First);
+
+ var->data.location = decl->Semantic.Name;
+ var->data.index = decl->Semantic.Index;
+
+ for (i = 0; i < array_size; i++) {
+ c->output_regs[decl->Range.First + i].offset = i;
+ c->output_regs[decl->Range.First + i].reg = reg;
+ }
+
+ exec_list_push_tail(&b->shader->outputs, &var->node);
+ }
+ break;
+ case TGSI_FILE_CONSTANT:
+ var->data.mode = nir_var_uniform;
+ var->name = ralloc_asprintf(var, "uniform_%d", decl->Range.First);
+
+ exec_list_push_tail(&b->shader->uniforms, &var->node);
+ break;
+ default:
+ unreachable("bad declaration file");
+ return;
+ }
+
+ }
+}
+
+static void
+ttn_emit_immediate(struct ttn_compile *c)
+{
+ nir_builder *b = &c->build;
+ struct tgsi_full_immediate *tgsi_imm = &c->token->FullImmediate;
+ nir_load_const_instr *load_const;
+ int i;
+
+ load_const = nir_load_const_instr_create(b->shader, 4);
+ c->imm_defs[c->next_imm] = &load_const->def;
+ c->next_imm++;
+
+ for (i = 0; i < 4; i++)
+ load_const->value.u[i] = tgsi_imm->u[i].Uint;
+
+ nir_instr_insert_after_cf_list(b->cf_node_list, &load_const->instr);
+}
+
+static nir_src
+ttn_src_for_indirect(struct ttn_compile *c, struct tgsi_ind_register *indirect);
+
+/* generate either a constant or indirect deref chain for accessing an
+ * array variable.
+ */
+static nir_deref_var *
+ttn_array_deref(struct ttn_compile *c, nir_intrinsic_instr *instr,
+ nir_variable *var, unsigned offset,
+ struct tgsi_ind_register *indirect)
+{
+ nir_deref_var *deref = nir_deref_var_create(instr, var);
+ nir_deref_array *arr = nir_deref_array_create(deref);
+
+ arr->base_offset = offset;
+ arr->deref.type = glsl_get_array_element(var->type);
+
+ if (indirect) {
+ arr->deref_array_type = nir_deref_array_type_indirect;
+ arr->indirect = ttn_src_for_indirect(c, indirect);
+ } else {
+ arr->deref_array_type = nir_deref_array_type_direct;
+ }
+
+ deref->deref.child = &arr->deref;
+
+ return deref;
+}
+
+static nir_src
+ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index,
+ struct tgsi_ind_register *indirect,
+ struct tgsi_dimension *dim,
+ struct tgsi_ind_register *dimind)
+{
+ nir_builder *b = &c->build;
+ nir_src src;
+
+ memset(&src, 0, sizeof(src));
+
+ switch (file) {
+ case TGSI_FILE_TEMPORARY:
+ if (c->temp_regs[index].var) {
+ unsigned offset = c->temp_regs[index].offset;
+ nir_variable *var = c->temp_regs[index].var;
+ nir_intrinsic_instr *load;
+
+ load = nir_intrinsic_instr_create(b->shader,
+ nir_intrinsic_load_var);
+ load->num_components = 4;
+ load->variables[0] = ttn_array_deref(c, load, var, offset, indirect);
+
+ nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
+
+ src = nir_src_for_ssa(&load->dest.ssa);
+
+ } else {
+ assert(!indirect);
+ src.reg.reg = c->temp_regs[index].reg;
+ }
+ assert(!dim);
+ break;
+
+ case TGSI_FILE_ADDRESS:
+ src.reg.reg = c->addr_reg;
+ assert(!dim);
+ break;
+
+ case TGSI_FILE_IMMEDIATE:
+ src = nir_src_for_ssa(c->imm_defs[index]);
+ assert(!indirect);
+ assert(!dim);
+ break;
+
+ case TGSI_FILE_SYSTEM_VALUE: {
+ nir_intrinsic_instr *load;
+ nir_intrinsic_op op;
+ unsigned ncomp = 1;
+
+ assert(!indirect);
+ assert(!dim);
+
+ switch (c->scan->system_value_semantic_name[index]) {
+ case TGSI_SEMANTIC_VERTEXID_NOBASE:
+ op = nir_intrinsic_load_vertex_id_zero_base;
+ break;
+ case TGSI_SEMANTIC_VERTEXID:
+ op = nir_intrinsic_load_vertex_id;
+ break;
+ case TGSI_SEMANTIC_BASEVERTEX:
+ op = nir_intrinsic_load_base_vertex;
+ break;
+ case TGSI_SEMANTIC_INSTANCEID:
+ op = nir_intrinsic_load_instance_id;
+ break;
+ default:
+ unreachable("bad system value");
+ }
+
+ load = nir_intrinsic_instr_create(b->shader, op);
+ load->num_components = ncomp;
+
+ nir_ssa_dest_init(&load->instr, &load->dest, ncomp, NULL);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
+
+ src = nir_src_for_ssa(&load->dest.ssa);
+ break;
+ }
+
+ case TGSI_FILE_INPUT:
+ case TGSI_FILE_CONSTANT: {
+ nir_intrinsic_instr *load;
+ nir_intrinsic_op op;
+ unsigned srcn = 0;
+
+ switch (file) {
+ case TGSI_FILE_INPUT:
+ op = indirect ? nir_intrinsic_load_input_indirect :
+ nir_intrinsic_load_input;
+ assert(!dim);
+ break;
+ case TGSI_FILE_CONSTANT:
+ if (dim) {
+ op = indirect ? nir_intrinsic_load_ubo_indirect :
+ nir_intrinsic_load_ubo;
+ /* convert index from vec4 to byte: */
+ index *= 16;
+ } else {
+ op = indirect ? nir_intrinsic_load_uniform_indirect :
+ nir_intrinsic_load_uniform;
+ }
+ break;
+ default:
+ unreachable("No other load files supported");
+ break;
+ }
+
+ load = nir_intrinsic_instr_create(b->shader, op);
+
+ load->num_components = 4;
+ load->const_index[0] = index;
+ load->const_index[1] = 1;
+ if (dim) {
+ if (dimind) {
+ load->src[srcn] =
+ ttn_src_for_file_and_index(c, dimind->File, dimind->Index,
+ NULL, NULL, NULL);
+ } else {
+ /* UBOs start at index 1 in TGSI: */
+ load->src[srcn] =
+ nir_src_for_ssa(nir_imm_int(b, dim->Index - 1));
+ }
+ srcn++;
+ }
+ if (indirect) {
+ load->src[srcn] = ttn_src_for_indirect(c, indirect);
+ if (dim) {
+ assert(load->src[srcn].is_ssa);
+ /* we also need to covert vec4 to byte here too: */
+ load->src[srcn] =
+ nir_src_for_ssa(nir_ishl(b, load->src[srcn].ssa,
+ nir_imm_int(b, 4)));
+ }
+ srcn++;
+ }
+ nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
+
+ src = nir_src_for_ssa(&load->dest.ssa);
+ break;
+ }
+
+ default:
+ unreachable("bad src file");
+ }
+
+
+ return src;
+}
+
+static nir_src
+ttn_src_for_indirect(struct ttn_compile *c, struct tgsi_ind_register *indirect)
+{
+ nir_builder *b = &c->build;
+ nir_alu_src src;
+ memset(&src, 0, sizeof(src));
+ for (int i = 0; i < 4; i++)
+ src.swizzle[i] = indirect->Swizzle;
+ src.src = ttn_src_for_file_and_index(c,
+ indirect->File,
+ indirect->Index,
+ NULL, NULL, NULL);
+ return nir_src_for_ssa(nir_imov_alu(b, src, 1));
+}
+
+static nir_alu_dest
+ttn_get_dest(struct ttn_compile *c, struct tgsi_full_dst_register *tgsi_fdst)
+{
+ struct tgsi_dst_register *tgsi_dst = &tgsi_fdst->Register;
+ nir_alu_dest dest;
+ unsigned index = tgsi_dst->Index;
+
+ memset(&dest, 0, sizeof(dest));
+
+ if (tgsi_dst->File == TGSI_FILE_TEMPORARY) {
+ if (c->temp_regs[index].var) {
+ nir_builder *b = &c->build;
+ nir_intrinsic_instr *load;
+ struct tgsi_ind_register *indirect =
+ tgsi_dst->Indirect ? &tgsi_fdst->Indirect : NULL;
+ nir_register *reg;
+
+ /* this works, because TGSI will give us a base offset
+ * (in case of indirect index) that points back into
+ * the array. Access can be direct or indirect, we
+ * don't really care. Just create a one-shot dst reg
+ * that will get store_var'd back into the array var
+ * at the end of ttn_emit_instruction()
+ */
+ reg = nir_local_reg_create(c->build.impl);
+ reg->num_components = 4;
+ dest.dest.reg.reg = reg;
+ dest.dest.reg.base_offset = 0;
+
+ /* since the alu op might not write to all components
+ * of the temporary, we must first do a load_var to
+ * get the previous array elements into the register.
+ * This is one area that NIR could use a bit of
+ * improvement (or opt pass to clean up the mess
+ * once things are scalarized)
+ */
+
+ load = nir_intrinsic_instr_create(c->build.shader,
+ nir_intrinsic_load_var);
+ load->num_components = 4;
+ load->variables[0] =
+ ttn_array_deref(c, load, c->temp_regs[index].var,
+ c->temp_regs[index].offset,
+ indirect);
+
+ load->dest = nir_dest_for_reg(reg);
+
+ nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
+ } else {
+ assert(!tgsi_dst->Indirect);
+ dest.dest.reg.reg = c->temp_regs[index].reg;
+ dest.dest.reg.base_offset = c->temp_regs[index].offset;
+ }
+ } else if (tgsi_dst->File == TGSI_FILE_OUTPUT) {
+ dest.dest.reg.reg = c->output_regs[index].reg;
+ dest.dest.reg.base_offset = c->output_regs[index].offset;
+ } else if (tgsi_dst->File == TGSI_FILE_ADDRESS) {
+ assert(index == 0);
+ dest.dest.reg.reg = c->addr_reg;
+ }
+
+ dest.write_mask = tgsi_dst->WriteMask;
+ dest.saturate = false;
+
+ if (tgsi_dst->Indirect && (tgsi_dst->File != TGSI_FILE_TEMPORARY)) {
+ nir_src *indirect = ralloc(c->build.shader, nir_src);
+ *indirect = ttn_src_for_indirect(c, &tgsi_fdst->Indirect);
+ dest.dest.reg.indirect = indirect;
+ }
+
+ return dest;
+}
+
+static nir_variable *
+ttn_get_var(struct ttn_compile *c, struct tgsi_full_dst_register *tgsi_fdst)
+{
+ struct tgsi_dst_register *tgsi_dst = &tgsi_fdst->Register;
+ unsigned index = tgsi_dst->Index;
+
+ if (tgsi_dst->File == TGSI_FILE_TEMPORARY) {
+ /* we should not have an indirect when there is no var! */
+ if (!c->temp_regs[index].var)
+ assert(!tgsi_dst->Indirect);
+ return c->temp_regs[index].var;
+ }
+
+ return NULL;
+}
+
+static nir_ssa_def *
+ttn_get_src(struct ttn_compile *c, struct tgsi_full_src_register *tgsi_fsrc)
+{
+ nir_builder *b = &c->build;
+ struct tgsi_src_register *tgsi_src = &tgsi_fsrc->Register;
+ unsigned tgsi_opcode = c->token->FullInstruction.Instruction.Opcode;
+ unsigned tgsi_src_type = tgsi_opcode_infer_src_type(tgsi_opcode);
+ bool src_is_float = !(tgsi_src_type == TGSI_TYPE_SIGNED ||
+ tgsi_src_type == TGSI_TYPE_UNSIGNED);
+ nir_alu_src src;
+
+ memset(&src, 0, sizeof(src));
+
+ if (tgsi_src->File == TGSI_FILE_NULL) {
+ return nir_imm_float(b, 0.0);
+ } else if (tgsi_src->File == TGSI_FILE_SAMPLER) {
+ /* Only the index of the sampler gets used in texturing, and it will
+ * handle looking that up on its own instead of using the nir_alu_src.
+ */
+ assert(!tgsi_src->Indirect);
+ return NULL;
+ } else {
+ struct tgsi_ind_register *ind = NULL;
+ struct tgsi_dimension *dim = NULL;
+ struct tgsi_ind_register *dimind = NULL;
+ if (tgsi_src->Indirect)
+ ind = &tgsi_fsrc->Indirect;
+ if (tgsi_src->Dimension) {
+ dim = &tgsi_fsrc->Dimension;
+ if (dim->Indirect)
+ dimind = &tgsi_fsrc->DimIndirect;
+ }
+ src.src = ttn_src_for_file_and_index(c,
+ tgsi_src->File,
+ tgsi_src->Index,
+ ind, dim, dimind);
+ }
+
+ src.swizzle[0] = tgsi_src->SwizzleX;
+ src.swizzle[1] = tgsi_src->SwizzleY;
+ src.swizzle[2] = tgsi_src->SwizzleZ;
+ src.swizzle[3] = tgsi_src->SwizzleW;
+
+ nir_ssa_def *def = nir_fmov_alu(b, src, 4);
+
+ if (tgsi_src->Absolute) {
+ if (src_is_float)
+ def = nir_fabs(b, def);
+ else
+ def = nir_iabs(b, def);
+ }
+
+ if (tgsi_src->Negate) {
+ if (src_is_float)
+ def = nir_fneg(b, def);
+ else
+ def = nir_ineg(b, def);
+ }
+
+ return def;
+}
+
+static void
+ttn_alu(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ unsigned num_srcs = nir_op_infos[op].num_inputs;
+ nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
+ unsigned i;
+
+ for (i = 0; i < num_srcs; i++)
+ instr->src[i].src = nir_src_for_ssa(src[i]);
+
+ instr->dest = dest;
+ nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr);
+}
+
+static void
+ttn_move_dest_masked(nir_builder *b, nir_alu_dest dest,
+ nir_ssa_def *def, unsigned write_mask)
+{
+ if (!(dest.write_mask & write_mask))
+ return;
+
+ nir_alu_instr *mov = nir_alu_instr_create(b->shader, nir_op_imov);
+ mov->dest = dest;
+ mov->dest.write_mask &= write_mask;
+ mov->src[0].src = nir_src_for_ssa(def);
+ for (unsigned i = def->num_components; i < 4; i++)
+ mov->src[0].swizzle[i] = def->num_components - 1;
+ nir_instr_insert_after_cf_list(b->cf_node_list, &mov->instr);
+}
+
+static void
+ttn_move_dest(nir_builder *b, nir_alu_dest dest, nir_ssa_def *def)
+{
+ ttn_move_dest_masked(b, dest, def, TGSI_WRITEMASK_XYZW);
+}
+
+static void
+ttn_arl(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest, nir_f2i(b, nir_ffloor(b, src[0])));
+}
+
+/* EXP - Approximate Exponential Base 2
+ * dst.x = 2^{\lfloor src.x\rfloor}
+ * dst.y = src.x - \lfloor src.x\rfloor
+ * dst.z = 2^{src.x}
+ * dst.w = 1.0
+ */
+static void
+ttn_exp(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_ssa_def *srcx = ttn_channel(b, src[0], X);
+
+ ttn_move_dest_masked(b, dest, nir_fexp2(b, nir_ffloor(b, srcx)),
+ TGSI_WRITEMASK_X);
+ ttn_move_dest_masked(b, dest, nir_fsub(b, srcx, nir_ffloor(b, srcx)),
+ TGSI_WRITEMASK_Y);
+ ttn_move_dest_masked(b, dest, nir_fexp2(b, srcx), TGSI_WRITEMASK_Z);
+ ttn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), TGSI_WRITEMASK_W);
+}
+
+/* LOG - Approximate Logarithm Base 2
+ * dst.x = \lfloor\log_2{|src.x|}\rfloor
+ * dst.y = \frac{|src.x|}{2^{\lfloor\log_2{|src.x|}\rfloor}}
+ * dst.z = \log_2{|src.x|}
+ * dst.w = 1.0
+ */
+static void
+ttn_log(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_ssa_def *abs_srcx = nir_fabs(b, ttn_channel(b, src[0], X));
+ nir_ssa_def *log2 = nir_flog2(b, abs_srcx);
+
+ ttn_move_dest_masked(b, dest, nir_ffloor(b, log2), TGSI_WRITEMASK_X);
+ ttn_move_dest_masked(b, dest,
+ nir_fdiv(b, abs_srcx, nir_fexp2(b, nir_ffloor(b, log2))),
+ TGSI_WRITEMASK_Y);
+ ttn_move_dest_masked(b, dest, nir_flog2(b, abs_srcx), TGSI_WRITEMASK_Z);
+ ttn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), TGSI_WRITEMASK_W);
+}
+
+/* DST - Distance Vector
+ * dst.x = 1.0
+ * dst.y = src0.y \times src1.y
+ * dst.z = src0.z
+ * dst.w = src1.w
+ */
+static void
+ttn_dst(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), TGSI_WRITEMASK_X);
+ ttn_move_dest_masked(b, dest, nir_fmul(b, src[0], src[1]), TGSI_WRITEMASK_Y);
+ ttn_move_dest_masked(b, dest, nir_fmov(b, src[0]), TGSI_WRITEMASK_Z);
+ ttn_move_dest_masked(b, dest, nir_fmov(b, src[1]), TGSI_WRITEMASK_W);
+}
+
+/* LIT - Light Coefficients
+ * dst.x = 1.0
+ * dst.y = max(src.x, 0.0)
+ * dst.z = (src.x > 0.0) ? max(src.y, 0.0)^{clamp(src.w, -128.0, 128.0))} : 0
+ * dst.w = 1.0
+ */
+static void
+ttn_lit(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), TGSI_WRITEMASK_XW);
+
+ ttn_move_dest_masked(b, dest, nir_fmax(b, ttn_channel(b, src[0], X),
+ nir_imm_float(b, 0.0)), TGSI_WRITEMASK_Y);
+
+ if (dest.write_mask & TGSI_WRITEMASK_Z) {
+ nir_ssa_def *src0_y = ttn_channel(b, src[0], Y);
+ nir_ssa_def *wclamp = nir_fmax(b, nir_fmin(b, ttn_channel(b, src[0], W),
+ nir_imm_float(b, 128.0)),
+ nir_imm_float(b, -128.0));
+ nir_ssa_def *pow = nir_fpow(b, nir_fmax(b, src0_y, nir_imm_float(b, 0.0)),
+ wclamp);
+
+ ttn_move_dest_masked(b, dest,
+ nir_bcsel(b,
+ nir_fge(b,
+ nir_imm_float(b, 0.0),
+ ttn_channel(b, src[0], X)),
+ nir_imm_float(b, 0.0),
+ pow),
+ TGSI_WRITEMASK_Z);
+ }
+}
+
+/* SCS - Sine Cosine
+ * dst.x = \cos{src.x}
+ * dst.y = \sin{src.x}
+ * dst.z = 0.0
+ * dst.w = 1.0
+ */
+static void
+ttn_scs(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest_masked(b, dest, nir_fcos(b, ttn_channel(b, src[0], X)),
+ TGSI_WRITEMASK_X);
+ ttn_move_dest_masked(b, dest, nir_fsin(b, ttn_channel(b, src[0], X)),
+ TGSI_WRITEMASK_Y);
+ ttn_move_dest_masked(b, dest, nir_imm_float(b, 0.0), TGSI_WRITEMASK_Z);
+ ttn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), TGSI_WRITEMASK_W);
+}
+
+static void
+ttn_sle(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest, nir_sge(b, src[1], src[0]));
+}
+
+static void
+ttn_sgt(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest, nir_slt(b, src[1], src[0]));
+}
+
+static void
+ttn_clamp(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest, nir_fmin(b, nir_fmax(b, src[0], src[1]), src[2]));
+}
+
+static void
+ttn_xpd(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest_masked(b, dest,
+ nir_fsub(b,
+ nir_fmul(b,
+ ttn_swizzle(b, src[0], Y, Z, X, X),
+ ttn_swizzle(b, src[1], Z, X, Y, X)),
+ nir_fmul(b,
+ ttn_swizzle(b, src[1], Y, Z, X, X),
+ ttn_swizzle(b, src[0], Z, X, Y, X))),
+ TGSI_WRITEMASK_XYZ);
+ ttn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), TGSI_WRITEMASK_W);
+}
+
+static void
+ttn_dp2a(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest,
+ ttn_channel(b, nir_fadd(b, nir_fdot2(b, src[0], src[1]),
+ src[2]),
+ X));
+}
+
+static void
+ttn_dp2(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest, nir_fdot2(b, src[0], src[1]));
+}
+
+static void
+ttn_dp3(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest, nir_fdot3(b, src[0], src[1]));
+}
+
+static void
+ttn_dp4(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest, nir_fdot4(b, src[0], src[1]));
+}
+
+static void
+ttn_dph(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest, nir_fadd(b, nir_fdot3(b, src[0], src[1]),
+ ttn_channel(b, src[1], W)));
+}
+
+static void
+ttn_umad(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest, nir_iadd(b, nir_imul(b, src[0], src[1]), src[2]));
+}
+
+static void
+ttn_arr(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest, nir_ffloor(b, nir_fadd(b, src[0], nir_imm_float(b, 0.5))));
+}
+
+static void
+ttn_cmp(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest, nir_bcsel(b,
+ nir_flt(b, src[0], nir_imm_float(b, 0.0)),
+ src[1], src[2]));
+}
+
+static void
+ttn_ucmp(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ttn_move_dest(b, dest, nir_bcsel(b,
+ nir_ine(b, src[0], nir_imm_int(b, 0)),
+ src[1], src[2]));
+}
+
+static void
+ttn_kill(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_intrinsic_instr *discard =
+ nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &discard->instr);
+}
+
+static void
+ttn_kill_if(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_ssa_def *cmp = nir_bany4(b, nir_flt(b, src[0], nir_imm_float(b, 0.0)));
+ nir_intrinsic_instr *discard =
+ nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard_if);
+ discard->src[0] = nir_src_for_ssa(cmp);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &discard->instr);
+}
+
+static void
+ttn_if(struct ttn_compile *c, nir_ssa_def *src, bool is_uint)
+{
+ nir_builder *b = &c->build;
+
+ /* Save the outside-of-the-if-statement node list. */
+ c->if_stack[c->if_stack_pos] = b->cf_node_list;
+ c->if_stack_pos++;
+
+ src = ttn_channel(b, src, X);
+
+ nir_if *if_stmt = nir_if_create(b->shader);
+ if (is_uint) {
+ if_stmt->condition = nir_src_for_ssa(nir_ine(b, src, nir_imm_int(b, 0)));
+ } else {
+ if_stmt->condition = nir_src_for_ssa(nir_fne(b, src, nir_imm_int(b, 0)));
+ }
+ nir_cf_node_insert_end(b->cf_node_list, &if_stmt->cf_node);
+
+ nir_builder_insert_after_cf_list(b, &if_stmt->then_list);
+
+ c->if_stack[c->if_stack_pos] = &if_stmt->else_list;
+ c->if_stack_pos++;
+}
+
+static void
+ttn_else(struct ttn_compile *c)
+{
+ nir_builder *b = &c->build;
+
+ nir_builder_insert_after_cf_list(b, c->if_stack[c->if_stack_pos - 1]);
+}
+
+static void
+ttn_endif(struct ttn_compile *c)
+{
+ nir_builder *b = &c->build;
+
+ c->if_stack_pos -= 2;
+ nir_builder_insert_after_cf_list(b, c->if_stack[c->if_stack_pos]);
+}
+
+static void
+ttn_bgnloop(struct ttn_compile *c)
+{
+ nir_builder *b = &c->build;
+
+ /* Save the outside-of-the-loop node list. */
+ c->loop_stack[c->loop_stack_pos] = b->cf_node_list;
+ c->loop_stack_pos++;
+
+ nir_loop *loop = nir_loop_create(b->shader);
+ nir_cf_node_insert_end(b->cf_node_list, &loop->cf_node);
+
+ nir_builder_insert_after_cf_list(b, &loop->body);
+}
+
+static void
+ttn_cont(nir_builder *b)
+{
+ nir_jump_instr *instr = nir_jump_instr_create(b->shader, nir_jump_continue);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr);
+}
+
+static void
+ttn_brk(nir_builder *b)
+{
+ nir_jump_instr *instr = nir_jump_instr_create(b->shader, nir_jump_break);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr);
+}
+
+static void
+ttn_endloop(struct ttn_compile *c)
+{
+ nir_builder *b = &c->build;
+
+ c->loop_stack_pos--;
+ nir_builder_insert_after_cf_list(b, c->loop_stack[c->loop_stack_pos]);
+}
+
+static void
+setup_texture_info(nir_tex_instr *instr, unsigned texture)
+{
+ switch (texture) {
+ case TGSI_TEXTURE_1D:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_1D;
+ break;
+ case TGSI_TEXTURE_1D_ARRAY:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_1D;
+ instr->is_array = true;
+ break;
+ case TGSI_TEXTURE_SHADOW1D:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_1D;
+ instr->is_shadow = true;
+ break;
+ case TGSI_TEXTURE_SHADOW1D_ARRAY:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_1D;
+ instr->is_shadow = true;
+ instr->is_array = true;
+ break;
+ case TGSI_TEXTURE_2D:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_2D;
+ break;
+ case TGSI_TEXTURE_2D_ARRAY:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_2D;
+ instr->is_array = true;
+ break;
+ case TGSI_TEXTURE_2D_MSAA:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_MS;
+ break;
+ case TGSI_TEXTURE_2D_ARRAY_MSAA:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_MS;
+ instr->is_array = true;
+ break;
+ case TGSI_TEXTURE_SHADOW2D:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_2D;
+ instr->is_shadow = true;
+ break;
+ case TGSI_TEXTURE_SHADOW2D_ARRAY:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_2D;
+ instr->is_shadow = true;
+ instr->is_array = true;
+ break;
+ case TGSI_TEXTURE_3D:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_3D;
+ break;
+ case TGSI_TEXTURE_CUBE:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_CUBE;
+ break;
+ case TGSI_TEXTURE_CUBE_ARRAY:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_CUBE;
+ instr->is_array = true;
+ break;
+ case TGSI_TEXTURE_SHADOWCUBE:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_CUBE;
+ instr->is_shadow = true;
+ break;
+ case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_CUBE;
+ instr->is_shadow = true;
+ instr->is_array = true;
+ break;
+ case TGSI_TEXTURE_RECT:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_RECT;
+ break;
+ case TGSI_TEXTURE_SHADOWRECT:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_RECT;
+ instr->is_shadow = true;
+ break;
+ default:
+ fprintf(stderr, "Unknown TGSI texture target %d\n", texture);
+ abort();
+ }
+}
+
+static void
+ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_builder *b = &c->build;
+ struct tgsi_full_instruction *tgsi_inst = &c->token->FullInstruction;
+ nir_tex_instr *instr;
+ nir_texop op;
+ unsigned num_srcs, samp = 1, i;
+
+ switch (tgsi_inst->Instruction.Opcode) {
+ case TGSI_OPCODE_TEX:
+ op = nir_texop_tex;
+ num_srcs = 1;
+ break;
+ case TGSI_OPCODE_TXP:
+ op = nir_texop_tex;
+ num_srcs = 2;
+ break;
+ case TGSI_OPCODE_TXB:
+ op = nir_texop_txb;
+ num_srcs = 2;
+ break;
+ case TGSI_OPCODE_TXL:
+ op = nir_texop_txl;
+ num_srcs = 2;
+ break;
+ case TGSI_OPCODE_TXL2:
+ op = nir_texop_txl;
+ num_srcs = 2;
+ samp = 2;
+ break;
+ case TGSI_OPCODE_TXF:
+ op = nir_texop_txf;
+ num_srcs = 2;
+ break;
+ case TGSI_OPCODE_TXD:
+ op = nir_texop_txd;
+ num_srcs = 3;
+ samp = 3;
+ break;
+
+ default:
+ fprintf(stderr, "unknown TGSI tex op %d\n", tgsi_inst->Instruction.Opcode);
+ abort();
+ }
+
+ if (tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D ||
+ tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D_ARRAY ||
+ tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D ||
+ tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY ||
+ tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOWRECT ||
+ tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE ||
+ tgsi_inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY) {
+ num_srcs++;
+ }
+
+ num_srcs += tgsi_inst->Texture.NumOffsets;
+
+ instr = nir_tex_instr_create(b->shader, num_srcs);
+ instr->op = op;
+
+ setup_texture_info(instr, tgsi_inst->Texture.Texture);
+
+ switch (instr->sampler_dim) {
+ case GLSL_SAMPLER_DIM_1D:
+ case GLSL_SAMPLER_DIM_BUF:
+ instr->coord_components = 1;
+ break;
+ case GLSL_SAMPLER_DIM_2D:
+ case GLSL_SAMPLER_DIM_RECT:
+ case GLSL_SAMPLER_DIM_EXTERNAL:
+ case GLSL_SAMPLER_DIM_MS:
+ instr->coord_components = 2;
+ break;
+ case GLSL_SAMPLER_DIM_3D:
+ case GLSL_SAMPLER_DIM_CUBE:
+ instr->coord_components = 3;
+ break;
+ }
+
+ if (instr->is_array)
+ instr->coord_components++;
+
+ assert(tgsi_inst->Src[samp].Register.File == TGSI_FILE_SAMPLER);
+ instr->sampler_index = tgsi_inst->Src[samp].Register.Index;
+
+ unsigned src_number = 0;
+
+ instr->src[src_number].src =
+ nir_src_for_ssa(nir_swizzle(b, src[0], SWIZ(X, Y, Z, W),
+ instr->coord_components, false));
+ instr->src[src_number].src_type = nir_tex_src_coord;
+ src_number++;
+
+ if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXP) {
+ instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
+ instr->src[src_number].src_type = nir_tex_src_projector;
+ src_number++;
+ }
+
+ if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXB) {
+ instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
+ instr->src[src_number].src_type = nir_tex_src_bias;
+ src_number++;
+ }
+
+ if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXL) {
+ instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
+ instr->src[src_number].src_type = nir_tex_src_lod;
+ src_number++;
+ }
+
+ if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXL2) {
+ instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[1], X));
+ instr->src[src_number].src_type = nir_tex_src_lod;
+ src_number++;
+ }
+
+ if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXF) {
+ instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
+ instr->src[src_number].src_type = nir_tex_src_lod;
+ src_number++;
+ }
+
+ if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXD) {
+ instr->src[src_number].src =
+ nir_src_for_ssa(nir_swizzle(b, src[1], SWIZ(X, Y, Z, W),
+ instr->coord_components, false));
+ instr->src[src_number].src_type = nir_tex_src_ddx;
+ src_number++;
+ instr->src[src_number].src =
+ nir_src_for_ssa(nir_swizzle(b, src[2], SWIZ(X, Y, Z, W),
+ instr->coord_components, false));
+ instr->src[src_number].src_type = nir_tex_src_ddy;
+ src_number++;
+ }
+
+ if (instr->is_shadow) {
+ if (instr->coord_components < 3)
+ instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], Z));
+ else
+ instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
+
+ instr->src[src_number].src_type = nir_tex_src_comparitor;
+ src_number++;
+ }
+
+ for (i = 0; i < tgsi_inst->Texture.NumOffsets; i++) {
+ struct tgsi_texture_offset *tex_offset = &tgsi_inst->TexOffsets[i];
+ /* since TexOffset ins't using tgsi_full_src_register we get to
+ * do some extra gymnastics:
+ */
+ nir_alu_src src;
+
+ memset(&src, 0, sizeof(src));
+
+ src.src = ttn_src_for_file_and_index(c,
+ tex_offset->File,
+ tex_offset->Index,
+ NULL, NULL, NULL);
+
+ src.swizzle[0] = tex_offset->SwizzleX;
+ src.swizzle[1] = tex_offset->SwizzleY;
+ src.swizzle[2] = tex_offset->SwizzleZ;
+ src.swizzle[3] = TGSI_SWIZZLE_W;
+
+ instr->src[src_number].src_type = nir_tex_src_offset;
+ instr->src[src_number].src = nir_src_for_ssa(
+ nir_fmov_alu(b, src, nir_tex_instr_src_size(instr, src_number)));
+ src_number++;
+ }
+
+ assert(src_number == num_srcs);
+
+ nir_ssa_dest_init(&instr->instr, &instr->dest, 4, NULL);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr);
+
+ /* Resolve the writemask on the texture op. */
+ ttn_move_dest(b, dest, &instr->dest.ssa);
+}
+
+/* TGSI_OPCODE_TXQ is actually two distinct operations:
+ *
+ * dst.x = texture\_width(unit, lod)
+ * dst.y = texture\_height(unit, lod)
+ * dst.z = texture\_depth(unit, lod)
+ * dst.w = texture\_levels(unit)
+ *
+ * dst.xyz map to NIR txs opcode, and dst.w maps to query_levels
+ */
+static void
+ttn_txq(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_builder *b = &c->build;
+ struct tgsi_full_instruction *tgsi_inst = &c->token->FullInstruction;
+ nir_tex_instr *txs, *qlv;
+
+ txs = nir_tex_instr_create(b->shader, 1);
+ txs->op = nir_texop_txs;
+ setup_texture_info(txs, tgsi_inst->Texture.Texture);
+
+ qlv = nir_tex_instr_create(b->shader, 0);
+ qlv->op = nir_texop_query_levels;
+ setup_texture_info(qlv, tgsi_inst->Texture.Texture);
+
+ assert(tgsi_inst->Src[1].Register.File == TGSI_FILE_SAMPLER);
+ txs->sampler_index = tgsi_inst->Src[1].Register.Index;
+ qlv->sampler_index = tgsi_inst->Src[1].Register.Index;
+
+ /* only single src, the lod: */
+ txs->src[0].src = nir_src_for_ssa(ttn_channel(b, src[0], X));
+ txs->src[0].src_type = nir_tex_src_lod;
+
+ nir_ssa_dest_init(&txs->instr, &txs->dest, 3, NULL);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &txs->instr);
+
+ nir_ssa_dest_init(&qlv->instr, &qlv->dest, 1, NULL);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &qlv->instr);
+
+ ttn_move_dest_masked(b, dest, &txs->dest.ssa, TGSI_WRITEMASK_XYZ);
+ ttn_move_dest_masked(b, dest, &qlv->dest.ssa, TGSI_WRITEMASK_W);
+}
+
+static const nir_op op_trans[TGSI_OPCODE_LAST] = {
+ [TGSI_OPCODE_ARL] = 0,
+ [TGSI_OPCODE_MOV] = nir_op_fmov,
+ [TGSI_OPCODE_LIT] = 0,
+ [TGSI_OPCODE_RCP] = nir_op_frcp,
+ [TGSI_OPCODE_RSQ] = nir_op_frsq,
+ [TGSI_OPCODE_EXP] = 0,
+ [TGSI_OPCODE_LOG] = 0,
+ [TGSI_OPCODE_MUL] = nir_op_fmul,
+ [TGSI_OPCODE_ADD] = nir_op_fadd,
+ [TGSI_OPCODE_DP3] = 0,
+ [TGSI_OPCODE_DP4] = 0,
+ [TGSI_OPCODE_DST] = 0,
+ [TGSI_OPCODE_MIN] = nir_op_fmin,
+ [TGSI_OPCODE_MAX] = nir_op_fmax,
+ [TGSI_OPCODE_SLT] = nir_op_slt,
+ [TGSI_OPCODE_SGE] = nir_op_sge,
+ [TGSI_OPCODE_MAD] = nir_op_ffma,
+ [TGSI_OPCODE_SUB] = nir_op_fsub,
+ [TGSI_OPCODE_LRP] = 0,
+ [TGSI_OPCODE_SQRT] = nir_op_fsqrt,
+ [TGSI_OPCODE_DP2A] = 0,
+ [TGSI_OPCODE_FRC] = nir_op_ffract,
+ [TGSI_OPCODE_CLAMP] = 0,
+ [TGSI_OPCODE_FLR] = nir_op_ffloor,
+ [TGSI_OPCODE_ROUND] = nir_op_fround_even,
+ [TGSI_OPCODE_EX2] = nir_op_fexp2,
+ [TGSI_OPCODE_LG2] = nir_op_flog2,
+ [TGSI_OPCODE_POW] = nir_op_fpow,
+ [TGSI_OPCODE_XPD] = 0,
+ [TGSI_OPCODE_ABS] = nir_op_fabs,
+ [TGSI_OPCODE_DPH] = 0,
+ [TGSI_OPCODE_COS] = nir_op_fcos,
+ [TGSI_OPCODE_DDX] = nir_op_fddx,
+ [TGSI_OPCODE_DDY] = nir_op_fddy,
+ [TGSI_OPCODE_KILL] = 0,
+ [TGSI_OPCODE_PK2H] = 0, /* XXX */
+ [TGSI_OPCODE_PK2US] = 0, /* XXX */
+ [TGSI_OPCODE_PK4B] = 0, /* XXX */
+ [TGSI_OPCODE_PK4UB] = 0, /* XXX */
+ [TGSI_OPCODE_SEQ] = nir_op_seq,
+ [TGSI_OPCODE_SGT] = 0,
+ [TGSI_OPCODE_SIN] = nir_op_fsin,
+ [TGSI_OPCODE_SLE] = 0,
+ [TGSI_OPCODE_TEX] = 0,
+ [TGSI_OPCODE_TXD] = 0,
+ [TGSI_OPCODE_TXP] = 0,
+ [TGSI_OPCODE_UP2H] = 0, /* XXX */
+ [TGSI_OPCODE_UP2US] = 0, /* XXX */
+ [TGSI_OPCODE_UP4B] = 0, /* XXX */
+ [TGSI_OPCODE_UP4UB] = 0, /* XXX */
+ [TGSI_OPCODE_ARR] = 0,
+
+ /* No function calls, yet. */
+ [TGSI_OPCODE_CAL] = 0, /* XXX */
+ [TGSI_OPCODE_RET] = 0, /* XXX */
+
+ [TGSI_OPCODE_SSG] = nir_op_fsign,
+ [TGSI_OPCODE_CMP] = 0,
+ [TGSI_OPCODE_SCS] = 0,
+ [TGSI_OPCODE_TXB] = 0,
+ [TGSI_OPCODE_DIV] = nir_op_fdiv,
+ [TGSI_OPCODE_DP2] = 0,
+ [TGSI_OPCODE_DP2A] = 0,
+ [TGSI_OPCODE_TXL] = 0,
+
+ [TGSI_OPCODE_BRK] = 0,
+ [TGSI_OPCODE_IF] = 0,
+ [TGSI_OPCODE_UIF] = 0,
+ [TGSI_OPCODE_ELSE] = 0,
+ [TGSI_OPCODE_ENDIF] = 0,
+
+ [TGSI_OPCODE_DDX_FINE] = nir_op_fddx_fine,
+ [TGSI_OPCODE_DDY_FINE] = nir_op_fddy_fine,
+
+ [TGSI_OPCODE_PUSHA] = 0, /* XXX */
+ [TGSI_OPCODE_POPA] = 0, /* XXX */
+
+ [TGSI_OPCODE_CEIL] = nir_op_fceil,
+ [TGSI_OPCODE_I2F] = nir_op_i2f,
+ [TGSI_OPCODE_NOT] = nir_op_inot,
+ [TGSI_OPCODE_TRUNC] = nir_op_ftrunc,
+ [TGSI_OPCODE_SHL] = nir_op_ishl,
+ [TGSI_OPCODE_AND] = nir_op_iand,
+ [TGSI_OPCODE_OR] = nir_op_ior,
+ [TGSI_OPCODE_MOD] = nir_op_umod,
+ [TGSI_OPCODE_XOR] = nir_op_ixor,
+ [TGSI_OPCODE_SAD] = 0, /* XXX */
+ [TGSI_OPCODE_TXF] = 0,
+ [TGSI_OPCODE_TXQ] = 0,
+
+ [TGSI_OPCODE_CONT] = 0,
+
+ [TGSI_OPCODE_EMIT] = 0, /* XXX */
+ [TGSI_OPCODE_ENDPRIM] = 0, /* XXX */
+
+ [TGSI_OPCODE_BGNLOOP] = 0,
+ [TGSI_OPCODE_BGNSUB] = 0, /* XXX: no function calls */
+ [TGSI_OPCODE_ENDLOOP] = 0,
+ [TGSI_OPCODE_ENDSUB] = 0, /* XXX: no function calls */
+
+ [TGSI_OPCODE_TXQ_LZ] = 0,
+ [TGSI_OPCODE_NOP] = 0,
+ [TGSI_OPCODE_FSEQ] = nir_op_feq,
+ [TGSI_OPCODE_FSGE] = nir_op_fge,
+ [TGSI_OPCODE_FSLT] = nir_op_flt,
+ [TGSI_OPCODE_FSNE] = nir_op_fne,
+
+ /* No control flow yet */
+ [TGSI_OPCODE_CALLNZ] = 0, /* XXX */
+ [TGSI_OPCODE_BREAKC] = 0, /* not emitted by glsl_to_tgsi.cpp */
+
+ [TGSI_OPCODE_KILL_IF] = 0,
+
+ [TGSI_OPCODE_END] = 0,
+
+ [TGSI_OPCODE_F2I] = nir_op_f2i,
+ [TGSI_OPCODE_IDIV] = nir_op_idiv,
+ [TGSI_OPCODE_IMAX] = nir_op_imax,
+ [TGSI_OPCODE_IMIN] = nir_op_imin,
+ [TGSI_OPCODE_INEG] = nir_op_ineg,
+ [TGSI_OPCODE_ISGE] = nir_op_ige,
+ [TGSI_OPCODE_ISHR] = nir_op_ishr,
+ [TGSI_OPCODE_ISLT] = nir_op_ilt,
+ [TGSI_OPCODE_F2U] = nir_op_f2u,
+ [TGSI_OPCODE_U2F] = nir_op_u2f,
+ [TGSI_OPCODE_UADD] = nir_op_iadd,
+ [TGSI_OPCODE_UDIV] = nir_op_udiv,
+ [TGSI_OPCODE_UMAD] = 0,
+ [TGSI_OPCODE_UMAX] = nir_op_umax,
+ [TGSI_OPCODE_UMIN] = nir_op_umin,
+ [TGSI_OPCODE_UMOD] = nir_op_umod,
+ [TGSI_OPCODE_UMUL] = nir_op_imul,
+ [TGSI_OPCODE_USEQ] = nir_op_ieq,
+ [TGSI_OPCODE_USGE] = nir_op_uge,
+ [TGSI_OPCODE_USHR] = nir_op_ushr,
+ [TGSI_OPCODE_USLT] = nir_op_ult,
+ [TGSI_OPCODE_USNE] = nir_op_ine,
+
+ [TGSI_OPCODE_SWITCH] = 0, /* not emitted by glsl_to_tgsi.cpp */
+ [TGSI_OPCODE_CASE] = 0, /* not emitted by glsl_to_tgsi.cpp */
+ [TGSI_OPCODE_DEFAULT] = 0, /* not emitted by glsl_to_tgsi.cpp */
+ [TGSI_OPCODE_ENDSWITCH] = 0, /* not emitted by glsl_to_tgsi.cpp */
+
+ /* XXX: SAMPLE opcodes */
+
+ [TGSI_OPCODE_UARL] = nir_op_imov,
+ [TGSI_OPCODE_UCMP] = 0,
+ [TGSI_OPCODE_IABS] = nir_op_iabs,
+ [TGSI_OPCODE_ISSG] = nir_op_isign,
+
+ /* XXX: atomics */
+
+ [TGSI_OPCODE_TEX2] = 0,
+ [TGSI_OPCODE_TXB2] = 0,
+ [TGSI_OPCODE_TXL2] = 0,
+
+ [TGSI_OPCODE_IMUL_HI] = nir_op_imul_high,
+ [TGSI_OPCODE_UMUL_HI] = nir_op_umul_high,
+
+ [TGSI_OPCODE_TG4] = 0,
+ [TGSI_OPCODE_LODQ] = 0, /* XXX */
+
+ [TGSI_OPCODE_IBFE] = nir_op_ibitfield_extract,
+ [TGSI_OPCODE_UBFE] = nir_op_ubitfield_extract,
+ [TGSI_OPCODE_BFI] = nir_op_bitfield_insert,
+ [TGSI_OPCODE_BREV] = nir_op_bitfield_reverse,
+ [TGSI_OPCODE_POPC] = nir_op_bit_count,
+ [TGSI_OPCODE_LSB] = nir_op_find_lsb,
+ [TGSI_OPCODE_IMSB] = nir_op_ifind_msb,
+ [TGSI_OPCODE_UMSB] = nir_op_ifind_msb, /* XXX: signed vs unsigned */
+
+ [TGSI_OPCODE_INTERP_CENTROID] = 0, /* XXX */
+ [TGSI_OPCODE_INTERP_SAMPLE] = 0, /* XXX */
+ [TGSI_OPCODE_INTERP_OFFSET] = 0, /* XXX */
+};
+
+static void
+ttn_emit_instruction(struct ttn_compile *c)
+{
+ nir_builder *b = &c->build;
+ struct tgsi_full_instruction *tgsi_inst = &c->token->FullInstruction;
+ unsigned i;
+ unsigned tgsi_op = tgsi_inst->Instruction.Opcode;
+ struct tgsi_full_dst_register *tgsi_dst = &tgsi_inst->Dst[0];
+
+ if (tgsi_op == TGSI_OPCODE_END)
+ return;
+
+ nir_ssa_def *src[TGSI_FULL_MAX_SRC_REGISTERS];
+ for (i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++) {
+ src[i] = ttn_get_src(c, &tgsi_inst->Src[i]);
+ }
+ nir_alu_dest dest = ttn_get_dest(c, tgsi_dst);
+
+ switch (tgsi_op) {
+ case TGSI_OPCODE_RSQ:
+ ttn_move_dest(b, dest, nir_frsq(b, ttn_channel(b, src[0], X)));
+ break;
+
+ case TGSI_OPCODE_SQRT:
+ ttn_move_dest(b, dest, nir_fsqrt(b, ttn_channel(b, src[0], X)));
+ break;
+
+ case TGSI_OPCODE_RCP:
+ ttn_move_dest(b, dest, nir_frcp(b, ttn_channel(b, src[0], X)));
+ break;
+
+ case TGSI_OPCODE_EX2:
+ ttn_move_dest(b, dest, nir_fexp2(b, ttn_channel(b, src[0], X)));
+ break;
+
+ case TGSI_OPCODE_LG2:
+ ttn_move_dest(b, dest, nir_flog2(b, ttn_channel(b, src[0], X)));
+ break;
+
+ case TGSI_OPCODE_POW:
+ ttn_move_dest(b, dest, nir_fpow(b,
+ ttn_channel(b, src[0], X),
+ ttn_channel(b, src[1], X)));
+ break;
+
+ case TGSI_OPCODE_COS:
+ ttn_move_dest(b, dest, nir_fcos(b, ttn_channel(b, src[0], X)));
+ break;
+
+ case TGSI_OPCODE_SIN:
+ ttn_move_dest(b, dest, nir_fsin(b, ttn_channel(b, src[0], X)));
+ break;
+
+ case TGSI_OPCODE_ARL:
+ ttn_arl(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_EXP:
+ ttn_exp(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_LOG:
+ ttn_log(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_DST:
+ ttn_dst(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_LIT:
+ ttn_lit(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_CLAMP:
+ ttn_clamp(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_XPD:
+ ttn_xpd(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_DP2:
+ ttn_dp2(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_DP3:
+ ttn_dp3(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_DP4:
+ ttn_dp4(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_DP2A:
+ ttn_dp2a(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_DPH:
+ ttn_dph(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_UMAD:
+ ttn_umad(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_LRP:
+ ttn_move_dest(b, dest, nir_flrp(b, src[2], src[1], src[0]));
+ break;
+
+ case TGSI_OPCODE_KILL:
+ ttn_kill(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_ARR:
+ ttn_arr(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_CMP:
+ ttn_cmp(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_UCMP:
+ ttn_ucmp(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_SCS:
+ ttn_scs(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_SGT:
+ ttn_sgt(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_SLE:
+ ttn_sle(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_KILL_IF:
+ ttn_kill_if(b, op_trans[tgsi_op], dest, src);
+ break;
+
+ case TGSI_OPCODE_TEX:
+ case TGSI_OPCODE_TXP:
+ case TGSI_OPCODE_TXL:
+ case TGSI_OPCODE_TXB:
+ case TGSI_OPCODE_TXD:
+ case TGSI_OPCODE_TXL2:
+ case TGSI_OPCODE_TXB2:
+ case TGSI_OPCODE_TXQ_LZ:
+ case TGSI_OPCODE_TXF:
+ case TGSI_OPCODE_TG4:
+ ttn_tex(c, dest, src);
+ break;
+
+ case TGSI_OPCODE_TXQ:
+ ttn_txq(c, dest, src);
+ break;
+
+ case TGSI_OPCODE_NOP:
+ break;
+
+ case TGSI_OPCODE_IF:
+ ttn_if(c, src[0], false);
+ break;
+
+ case TGSI_OPCODE_UIF:
+ ttn_if(c, src[0], true);
+ break;
+
+ case TGSI_OPCODE_ELSE:
+ ttn_else(c);
+ break;
+
+ case TGSI_OPCODE_ENDIF:
+ ttn_endif(c);
+ break;
+
+ case TGSI_OPCODE_BGNLOOP:
+ ttn_bgnloop(c);
+ break;
+
+ case TGSI_OPCODE_BRK:
+ ttn_brk(b);
+ break;
+
+ case TGSI_OPCODE_CONT:
+ ttn_cont(b);
+ break;
+
+ case TGSI_OPCODE_ENDLOOP:
+ ttn_endloop(c);
+ break;
+
+ default:
+ if (op_trans[tgsi_op] != 0 || tgsi_op == TGSI_OPCODE_MOV) {
+ ttn_alu(b, op_trans[tgsi_op], dest, src);
+ } else {
+ fprintf(stderr, "unknown TGSI opcode: %s\n",
+ tgsi_get_opcode_name(tgsi_op));
+ abort();
+ }
+ break;
+ }
+
+ if (tgsi_inst->Instruction.Saturate) {
+ assert(tgsi_inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE);
+ assert(!dest.dest.is_ssa);
+ ttn_move_dest(b, dest, nir_fsat(b, ttn_src_for_dest(b, &dest)));
+ }
+
+ /* if the dst has a matching var, append store_global to move
+ * output from reg to var
+ */
+ nir_variable *var = ttn_get_var(c, tgsi_dst);
+ if (var) {
+ unsigned index = tgsi_dst->Register.Index;
+ unsigned offset = c->temp_regs[index].offset;
+ nir_intrinsic_instr *store =
+ nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
+ struct tgsi_ind_register *indirect = tgsi_dst->Register.Indirect ?
+ &tgsi_dst->Indirect : NULL;
+
+ store->num_components = 4;
+ store->variables[0] = ttn_array_deref(c, store, var, offset, indirect);
+ store->src[0] = nir_src_for_reg(dest.dest.reg.reg);
+
+ nir_instr_insert_after_cf_list(b->cf_node_list, &store->instr);
+ }
+}
+
+/**
+ * Puts a NIR intrinsic to store of each TGSI_FILE_OUTPUT value to the output
+ * variables at the end of the shader.
+ *
+ * We don't generate these incrementally as the TGSI_FILE_OUTPUT values are
+ * written, because there's no output load intrinsic, which means we couldn't
+ * handle writemasks.
+ */
+static void
+ttn_add_output_stores(struct ttn_compile *c)
+{
+ nir_builder *b = &c->build;
+
+ foreach_list_typed(nir_variable, var, node, &b->shader->outputs) {
+ unsigned array_len = MAX2(glsl_get_length(var->type), 1);
+ unsigned i;
+
+ for (i = 0; i < array_len; i++) {
+ nir_intrinsic_instr *store =
+ nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_output);
+ store->num_components = 4;
+ store->const_index[0] = var->data.driver_location + i;
+ store->const_index[1] = 1;
+ store->src[0].reg.reg = c->output_regs[var->data.driver_location].reg;
+ nir_instr_insert_after_cf_list(b->cf_node_list, &store->instr);
+ }
+ }
+}
+
+struct nir_shader *
+tgsi_to_nir(const void *tgsi_tokens,
+ const nir_shader_compiler_options *options)
+{
+ struct tgsi_parse_context parser;
+ struct tgsi_shader_info scan;
+ struct ttn_compile *c;
+ struct nir_shader *s;
+ int ret;
+
+ c = rzalloc(NULL, struct ttn_compile);
+ s = nir_shader_create(NULL, options);
+
+ nir_function *func = nir_function_create(s, "main");
+ nir_function_overload *overload = nir_function_overload_create(func);
+ nir_function_impl *impl = nir_function_impl_create(overload);
+
+ nir_builder_init(&c->build, impl);
+ nir_builder_insert_after_cf_list(&c->build, &impl->body);
+
+ tgsi_scan_shader(tgsi_tokens, &scan);
+ c->scan = &scan;
+
+ s->num_inputs = scan.file_max[TGSI_FILE_INPUT] + 1;
+ s->num_uniforms = scan.const_file_max[0] + 1;
+ s->num_outputs = scan.file_max[TGSI_FILE_OUTPUT] + 1;
+
+ c->output_regs = rzalloc_array(c, struct ttn_reg_info,
+ scan.file_max[TGSI_FILE_OUTPUT] + 1);
+ c->temp_regs = rzalloc_array(c, struct ttn_reg_info,
+ scan.file_max[TGSI_FILE_TEMPORARY] + 1);
+ c->imm_defs = rzalloc_array(c, nir_ssa_def *,
+ scan.file_max[TGSI_FILE_IMMEDIATE] + 1);
+
+ c->if_stack = rzalloc_array(c, struct exec_list *,
+ (scan.opcode_count[TGSI_OPCODE_IF] +
+ scan.opcode_count[TGSI_OPCODE_UIF]) * 2);
+ c->loop_stack = rzalloc_array(c, struct exec_list *,
+ scan.opcode_count[TGSI_OPCODE_BGNLOOP]);
+
+ ret = tgsi_parse_init(&parser, tgsi_tokens);
+ assert(ret == TGSI_PARSE_OK);
+
+ while (!tgsi_parse_end_of_tokens(&parser)) {
+ tgsi_parse_token(&parser);
+ c->token = &parser.FullToken;
+
+ switch (parser.FullToken.Token.Type) {
+ case TGSI_TOKEN_TYPE_DECLARATION:
+ ttn_emit_declaration(c);
+ break;
+
+ case TGSI_TOKEN_TYPE_INSTRUCTION:
+ ttn_emit_instruction(c);
+ break;
+
+ case TGSI_TOKEN_TYPE_IMMEDIATE:
+ ttn_emit_immediate(c);
+ break;
+ }
+ }
+
+ tgsi_parse_free(&parser);
+
+ ttn_add_output_stores(c);
+
+ ralloc_free(c);
+ return s;
+}
diff --git a/mesalib/src/gallium/auxiliary/nir/tgsi_to_nir.h b/mesalib/src/gallium/auxiliary/nir/tgsi_to_nir.h
new file mode 100644
index 000000000..687348a80
--- /dev/null
+++ b/mesalib/src/gallium/auxiliary/nir/tgsi_to_nir.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright © 2014 Broadcom
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "glsl/nir/nir.h"
+
+struct nir_shader_compiler_options *options;
+
+struct nir_shader *
+tgsi_to_nir(const void *tgsi_tokens,
+ const struct nir_shader_compiler_options *options);
diff --git a/mesalib/src/gallium/auxiliary/util/u_debug_symbol.c b/mesalib/src/gallium/auxiliary/util/u_debug_symbol.c
index bba9122e7..542493252 100644
--- a/mesalib/src/gallium/auxiliary/util/u_debug_symbol.c
+++ b/mesalib/src/gallium/auxiliary/util/u_debug_symbol.c
@@ -82,18 +82,10 @@ getDbgHelpProcAddress(LPCSTR lpProcName)
hModule = LoadLibraryA("mgwhelp.dll");
if (!hModule) {
_debug_printf("warning: mgwhelp.dll not found: symbol names will not be resolved\n"
- "warning: download it from http://code.google.com/p/jrfonseca/wiki/DrMingw#MgwHelp\n");
+ "warning: download it from https://github.com/jrfonseca/drmingw/#mgwhelp\n");
}
}
-
- /*
- * bfdhelp.dll was the predecessor of mgwhelp.dll. It is available from
- * http://people.freedesktop.org/~jrfonseca/bfdhelp/ for now.
- */
- if (!hModule) {
- hModule = LoadLibraryA("bfdhelp.dll");
- }
- #endif
+#endif
/*
* Fallback to the real DbgHelp.
diff --git a/mesalib/src/gallium/auxiliary/util/u_linkage.c b/mesalib/src/gallium/auxiliary/util/u_linkage.c
deleted file mode 100644
index 245d941dc..000000000
--- a/mesalib/src/gallium/auxiliary/util/u_linkage.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2010 Luca Barbieri
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "util/u_debug.h"
-#include "pipe/p_shader_tokens.h"
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_scan.h"
-#include "util/u_linkage.h"
-
-/* we must only record the registers that are actually used, not just declared */
-static INLINE boolean
-util_semantic_set_test_and_set(struct util_semantic_set *set, unsigned value)
-{
- unsigned mask = 1 << (value % (sizeof(long) * 8));
- unsigned long *p = &set->masks[value / (sizeof(long) * 8)];
- unsigned long v = *p & mask;
- *p |= mask;
- return !!v;
-}
-
-unsigned
-util_semantic_set_from_program_file(struct util_semantic_set *set, const struct tgsi_token *tokens, enum tgsi_file_type file)
-{
- struct tgsi_shader_info info;
- struct tgsi_parse_context parse;
- unsigned count = 0;
- ubyte *semantic_name;
- ubyte *semantic_index;
-
- tgsi_scan_shader(tokens, &info);
-
- if(file == TGSI_FILE_INPUT)
- {
- semantic_name = info.input_semantic_name;
- semantic_index = info.input_semantic_index;
- }
- else if(file == TGSI_FILE_OUTPUT)
- {
- semantic_name = info.output_semantic_name;
- semantic_index = info.output_semantic_index;
- }
- else
- {
- assert(0);
- semantic_name = NULL;
- semantic_index = NULL;
- }
-
- tgsi_parse_init(&parse, tokens);
-
- memset(set->masks, 0, sizeof(set->masks));
- while(!tgsi_parse_end_of_tokens(&parse))
- {
- tgsi_parse_token(&parse);
-
- if(parse.FullToken.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION)
- {
- const struct tgsi_full_instruction *finst = &parse.FullToken.FullInstruction;
- unsigned i;
- for(i = 0; i < finst->Instruction.NumDstRegs; ++i)
- {
- if(finst->Dst[i].Register.File == file)
- {
- unsigned idx = finst->Dst[i].Register.Index;
- if(semantic_name[idx] == TGSI_SEMANTIC_GENERIC)
- {
- if(!util_semantic_set_test_and_set(set, semantic_index[idx]))
- ++count;
- }
- }
- }
-
- for(i = 0; i < finst->Instruction.NumSrcRegs; ++i)
- {
- if(finst->Src[i].Register.File == file)
- {
- unsigned idx = finst->Src[i].Register.Index;
- if(semantic_name[idx] == TGSI_SEMANTIC_GENERIC)
- {
- if(!util_semantic_set_test_and_set(set, semantic_index[idx]))
- ++count;
- }
- }
- }
- }
- }
- tgsi_parse_free(&parse);
-
- return count;
-}
-
-#define UTIL_SEMANTIC_SET_FOR_EACH(i, set) for(i = 0; i < 256; ++i) if(set->masks[i / (sizeof(long) * 8)] & (1 << (i % (sizeof(long) * 8))))
-
-void
-util_semantic_layout_from_set(unsigned char *layout, const struct util_semantic_set *set, unsigned efficient_slots, unsigned num_slots)
-{
- int first = -1;
- int last = -1;
- unsigned i;
-
- memset(layout, 0xff, num_slots);
-
- UTIL_SEMANTIC_SET_FOR_EACH(i, set)
- {
- if(first < 0)
- first = i;
- last = i;
- }
-
- if (last < (int) efficient_slots)
- {
- UTIL_SEMANTIC_SET_FOR_EACH(i, set)
- layout[i] = i;
- }
- else if ((last - first) < (int) efficient_slots)
- {
- UTIL_SEMANTIC_SET_FOR_EACH(i, set)
- layout[i - first] = i;
- }
- else
- {
- unsigned idx = 0;
- UTIL_SEMANTIC_SET_FOR_EACH(i, set)
- layout[idx++] = i;
- }
-}
diff --git a/mesalib/src/gallium/auxiliary/util/u_linkage.h b/mesalib/src/gallium/auxiliary/util/u_linkage.h
deleted file mode 100644
index 7b23123d3..000000000
--- a/mesalib/src/gallium/auxiliary/util/u_linkage.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2010 Luca Barbieri
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#ifndef U_LINKAGE_H_
-#define U_LINKAGE_H_
-
-#include "pipe/p_compiler.h"
-#include "pipe/p_shader_tokens.h"
-
-struct util_semantic_set
-{
- unsigned long masks[256 / 8 / sizeof(unsigned long)];
-};
-
-static INLINE boolean
-util_semantic_set_contains(struct util_semantic_set *set, unsigned char value)
-{
- return !!(set->masks[value / (sizeof(long) * 8)] & (1 << (value / (sizeof(long) * 8))));
-}
-
-unsigned util_semantic_set_from_program_file(struct util_semantic_set *set, const struct tgsi_token *tokens, enum tgsi_file_type file);
-
-/* efficient_slots is the number of slots such that hardware performance is
- * the same for using that amount, with holes, or less slots but with less
- * holes.
- *
- * num_slots is the size of the layout array and hardware limit instead.
- *
- * efficient_slots == 0 or efficient_slots == num_slots are typical settings.
- */
-void util_semantic_layout_from_set(unsigned char *layout, const struct util_semantic_set *set, unsigned efficient_slots, unsigned num_slots);
-
-static INLINE void
-util_semantic_table_from_layout(unsigned char *table, size_t table_size, unsigned char *layout,
- unsigned char first_slot_value, unsigned char num_slots)
-{
- unsigned char i;
- memset(table, 0xff, table_size);
-
- for(i = 0; i < num_slots; ++i)
- table[layout[i]] = first_slot_value + i;
-}
-
-#endif /* U_LINKAGE_H_ */
diff --git a/mesalib/src/gallium/auxiliary/util/u_math.h b/mesalib/src/gallium/auxiliary/util/u_math.h
index 8f62cac66..3d27a59e8 100644
--- a/mesalib/src/gallium/auxiliary/util/u_math.h
+++ b/mesalib/src/gallium/auxiliary/util/u_math.h
@@ -383,14 +383,28 @@ unsigned ffs( unsigned u )
return i;
}
-#elif defined(__MINGW32__) || defined(PIPE_OS_ANDROID)
+#elif defined(__MINGW32__) || defined(PIPE_OS_ANDROID) || \
+ defined(HAVE___BUILTIN_FFS)
#define ffs __builtin_ffs
-#define ffsll __builtin_ffsll
#endif
#endif /* FFS_DEFINED */
/**
+ * Find first bit set in long long. Least significant bit is 1.
+ * Return 0 if no bits set.
+ */
+#ifndef FFSLL_DEFINED
+#define FFSLL_DEFINED 1
+
+#if defined(__MINGW32__) || defined(PIPE_OS_ANDROID) || \
+ defined(HAVE___BUILTIN_FFSLL)
+#define ffsll __builtin_ffsll
+#endif
+
+#endif /* FFSLL_DEFINED */
+
+/**
* Find last bit set in a word. The least significant bit is 1.
* Return 0 if no bits are set.
*/
diff --git a/mesalib/src/gallium/auxiliary/util/u_tile.c b/mesalib/src/gallium/auxiliary/util/u_tile.c
index 6252e5dcf..8e199200f 100644
--- a/mesalib/src/gallium/auxiliary/util/u_tile.c
+++ b/mesalib/src/gallium/auxiliary/util/u_tile.c
@@ -214,13 +214,13 @@ s8x24_get_tile_rgba(const unsigned *src,
unsigned i, j;
for (i = 0; i < h; i++) {
- float *pRow = p;
+ uint32_t *pRow = (uint32_t *)p;
for (j = 0; j < w; j++, pRow += 4) {
pRow[0] =
pRow[1] =
pRow[2] =
- pRow[3] = (float)((*src++ >> 24) & 0xff);
+ pRow[3] = ((*src++ >> 24) & 0xff);
}
p += dst_stride;
@@ -241,12 +241,12 @@ x24s8_get_tile_rgba(const unsigned *src,
unsigned i, j;
for (i = 0; i < h; i++) {
- float *pRow = p;
+ uint32_t *pRow = (uint32_t *)p;
for (j = 0; j < w; j++, pRow += 4) {
pRow[0] =
pRow[1] =
pRow[2] =
- pRow[3] = (float)(*src++ & 0xff);
+ pRow[3] = (*src++ & 0xff);
}
p += dst_stride;
}
@@ -265,12 +265,12 @@ s8_get_tile_rgba(const unsigned char *src,
unsigned i, j;
for (i = 0; i < h; i++) {
- float *pRow = p;
+ uint32_t *pRow = (uint32_t *)p;
for (j = 0; j < w; j++, pRow += 4) {
pRow[0] =
pRow[1] =
pRow[2] =
- pRow[3] = (float)(*src++ & 0xff);
+ pRow[3] = (*src++ & 0xff);
}
p += dst_stride;
}
diff --git a/mesalib/src/glsl/Makefile.am b/mesalib/src/glsl/Makefile.am
index b466a3b5c..23c6fe8bb 100644
--- a/mesalib/src/glsl/Makefile.am
+++ b/mesalib/src/glsl/Makefile.am
@@ -46,6 +46,7 @@ EXTRA_DIST = tests glcpp/tests README TODO glcpp/README \
glcpp/glcpp-lex.l \
glcpp/glcpp-parse.y \
nir/nir_algebraic.py \
+ nir/nir_builder_opcodes_h.py \
nir/nir_constant_expressions.py \
nir/nir_opcodes.py \
nir/nir_opcodes_c.py \
@@ -67,7 +68,7 @@ TESTS_ENVIRONMENT= \
export PYTHON2=$(PYTHON2); \
export PYTHON_FLAGS=$(PYTHON_FLAGS);
-noinst_LTLIBRARIES = libglsl.la libglcpp.la
+noinst_LTLIBRARIES = libnir.la libglsl.la libglcpp.la
check_PROGRAMS = \
glcpp/glcpp \
glsl_test \
@@ -147,6 +148,12 @@ libglsl_la_SOURCES = \
$(LIBGLSL_FILES) \
$(NIR_FILES)
+libnir_la_SOURCES = \
+ glsl_types.cpp \
+ builtin_types.cpp \
+ glsl_symbol_table.cpp \
+ $(NIR_FILES)
+
glsl_compiler_SOURCES = \
$(GLSL_COMPILER_CXX_FILES)
@@ -251,8 +258,6 @@ nir/nir_opcodes.h: nir/nir_opcodes.py nir/nir_opcodes_h.py
$(MKDIR_P) nir; \
$(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opcodes_h.py > $@
-nir/nir.h: nir/nir_opcodes.h
-
nir/nir_opcodes.c: nir/nir_opcodes.py nir/nir_opcodes_c.py
$(MKDIR_P) nir; \
$(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/nir/nir_opcodes_c.py > $@
diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources
index b876642e8..c471eca23 100644
--- a/mesalib/src/glsl/Makefile.sources
+++ b/mesalib/src/glsl/Makefile.sources
@@ -22,6 +22,7 @@ NIR_FILES = \
nir/glsl_to_nir.h \
nir/nir.c \
nir/nir.h \
+ nir/nir_builder.h \
nir/nir_constant_expressions.h \
nir/nir_dominance.c \
nir/nir_from_ssa.c \
@@ -32,21 +33,25 @@ NIR_FILES = \
nir/nir_lower_atomics.c \
nir/nir_lower_global_vars_to_local.c \
nir/nir_lower_locals_to_regs.c \
+ nir/nir_lower_idiv.c \
nir/nir_lower_io.c \
nir/nir_lower_phis_to_scalar.c \
nir/nir_lower_samplers.cpp \
nir/nir_lower_system_values.c \
+ nir/nir_lower_tex_projector.c \
nir/nir_lower_to_source_mods.c \
nir/nir_lower_vars_to_ssa.c \
nir/nir_lower_var_copies.c \
nir/nir_lower_vec_to_movs.c \
nir/nir_metadata.c \
+ nir/nir_normalize_cubemap_coords.c \
nir/nir_opt_constant_folding.c \
nir/nir_opt_copy_propagate.c \
nir/nir_opt_cse.c \
nir/nir_opt_dce.c \
nir/nir_opt_gcm.c \
nir/nir_opt_global_to_local.c \
+ nir/nir_opt_peephole_ffma.c \
nir/nir_opt_peephole_select.c \
nir/nir_opt_remove_phis.c \
nir/nir_print.c \
@@ -54,9 +59,11 @@ NIR_FILES = \
nir/nir_search.c \
nir/nir_search.h \
nir/nir_split_var_copies.c \
+ nir/nir_sweep.c \
nir/nir_to_ssa.c \
nir/nir_types.h \
nir/nir_validate.c \
+ nir/nir_vla.h \
nir/nir_worklist.c \
nir/nir_worklist.h \
nir/nir_types.cpp \
@@ -183,7 +190,8 @@ LIBGLSL_FILES = \
opt_vectorize.cpp \
program.h \
s_expression.cpp \
- s_expression.h
+ s_expression.h \
+ shader_enums.h
# glsl_compiler
diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp
index 918be6966..87df93e68 100644
--- a/mesalib/src/glsl/ast_function.cpp
+++ b/mesalib/src/glsl/ast_function.cpp
@@ -1370,71 +1370,59 @@ emit_inline_matrix_constructor(const glsl_type *type,
} else {
const unsigned cols = type->matrix_columns;
const unsigned rows = type->vector_elements;
+ unsigned remaining_slots = rows * cols;
unsigned col_idx = 0;
unsigned row_idx = 0;
foreach_in_list(ir_rvalue, rhs, parameters) {
- const unsigned components_remaining_this_column = rows - row_idx;
- unsigned rhs_components = rhs->type->components();
- unsigned rhs_base = 0;
-
- /* Since the parameter might be used in the RHS of two assignments,
- * generate a temporary and copy the paramter there.
- */
- ir_variable *rhs_var =
- new(ctx) ir_variable(rhs->type, "mat_ctor_vec", ir_var_temporary);
- instructions->push_tail(rhs_var);
-
- ir_dereference *rhs_var_ref =
- new(ctx) ir_dereference_variable(rhs_var);
- ir_instruction *inst = new(ctx) ir_assignment(rhs_var_ref, rhs, NULL);
- instructions->push_tail(inst);
-
- /* Assign the current parameter to as many components of the matrix
- * as it will fill.
- *
- * NOTE: A single vector parameter can span two matrix columns. A
- * single vec4, for example, can completely fill a mat2.
- */
- if (rhs_components >= components_remaining_this_column) {
- const unsigned count = MIN2(rhs_components,
- components_remaining_this_column);
-
- rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var);
-
- ir_instruction *inst = assign_to_matrix_column(var, col_idx,
- row_idx,
- rhs_var_ref, 0,
- count, ctx);
- instructions->push_tail(inst);
-
- rhs_base = count;
-
- col_idx++;
- row_idx = 0;
- }
-
- /* If there is data left in the parameter and components left to be
- * set in the destination, emit another assignment. It is possible
- * that the assignment could be of a vec4 to the last element of the
- * matrix. In this case col_idx==cols, but there is still data
- * left in the source parameter. Obviously, don't emit an assignment
- * to data outside the destination matrix.
- */
- if ((col_idx < cols) && (rhs_base < rhs_components)) {
- const unsigned count = rhs_components - rhs_base;
-
- rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var);
-
- ir_instruction *inst = assign_to_matrix_column(var, col_idx,
- row_idx,
- rhs_var_ref,
- rhs_base,
- count, ctx);
- instructions->push_tail(inst);
-
- row_idx += count;
- }
+ unsigned rhs_components = rhs->type->components();
+ unsigned rhs_base = 0;
+
+ if (remaining_slots == 0)
+ break;
+
+ /* Since the parameter might be used in the RHS of two assignments,
+ * generate a temporary and copy the paramter there.
+ */
+ ir_variable *rhs_var =
+ new(ctx) ir_variable(rhs->type, "mat_ctor_vec", ir_var_temporary);
+ instructions->push_tail(rhs_var);
+
+ ir_dereference *rhs_var_ref =
+ new(ctx) ir_dereference_variable(rhs_var);
+ ir_instruction *inst = new(ctx) ir_assignment(rhs_var_ref, rhs, NULL);
+ instructions->push_tail(inst);
+
+ do {
+ /* Assign the current parameter to as many components of the matrix
+ * as it will fill.
+ *
+ * NOTE: A single vector parameter can span two matrix columns. A
+ * single vec4, for example, can completely fill a mat2.
+ */
+ unsigned count = MIN2(rows - row_idx,
+ rhs_components - rhs_base);
+
+ rhs_var_ref = new(ctx) ir_dereference_variable(rhs_var);
+ ir_instruction *inst = assign_to_matrix_column(var, col_idx,
+ row_idx,
+ rhs_var_ref,
+ rhs_base,
+ count, ctx);
+ instructions->push_tail(inst);
+ rhs_base += count;
+ row_idx += count;
+ remaining_slots -= count;
+
+ /* Sometimes, there is still data left in the parameters and
+ * components left to be set in the destination but in other
+ * column.
+ */
+ if (row_idx >= rows) {
+ row_idx = 0;
+ col_idx++;
+ }
+ } while(remaining_slots > 0 && rhs_base < rhs_components);
}
}
@@ -1791,7 +1779,7 @@ ast_function_expression::hir(exec_list *instructions,
return value;
}
- return ir_rvalue::error_value(ctx);
+ unreachable("not reached");
}
ir_rvalue *
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index d387b2e35..78369360f 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -375,66 +375,14 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b,
if (type_a == type_b)
return type_a;
} else {
- if (type_a->is_matrix() && type_b->is_matrix()) {
- /* Matrix multiply. The columns of A must match the rows of B. Given
- * the other previously tested constraints, this means the vector type
- * of a row from A must be the same as the vector type of a column from
- * B.
- */
- if (type_a->row_type() == type_b->column_type()) {
- /* The resulting matrix has the number of columns of matrix B and
- * the number of rows of matrix A. We get the row count of A by
- * looking at the size of a vector that makes up a column. The
- * transpose (size of a row) is done for B.
- */
- const glsl_type *const type =
- glsl_type::get_instance(type_a->base_type,
- type_a->column_type()->vector_elements,
- type_b->row_type()->vector_elements);
- assert(type != glsl_type::error_type);
-
- return type;
- }
- } else if (type_a->is_matrix()) {
- /* A is a matrix and B is a column vector. Columns of A must match
- * rows of B. Given the other previously tested constraints, this
- * means the vector type of a row from A must be the same as the
- * vector the type of B.
- */
- if (type_a->row_type() == type_b) {
- /* The resulting vector has a number of elements equal to
- * the number of rows of matrix A. */
- const glsl_type *const type =
- glsl_type::get_instance(type_a->base_type,
- type_a->column_type()->vector_elements,
- 1);
- assert(type != glsl_type::error_type);
-
- return type;
- }
- } else {
- assert(type_b->is_matrix());
+ const glsl_type *type = glsl_type::get_mul_type(type_a, type_b);
- /* A is a row vector and B is a matrix. Columns of A must match rows
- * of B. Given the other previously tested constraints, this means
- * the type of A must be the same as the vector type of a column from
- * B.
- */
- if (type_a == type_b->column_type()) {
- /* The resulting vector has a number of elements equal to
- * the number of columns of matrix B. */
- const glsl_type *const type =
- glsl_type::get_instance(type_a->base_type,
- type_b->row_type()->vector_elements,
- 1);
- assert(type != glsl_type::error_type);
-
- return type;
- }
+ if (type == glsl_type::error_type) {
+ _mesa_glsl_error(loc, state,
+ "size mismatch for matrix multiplication");
}
- _mesa_glsl_error(loc, state, "size mismatch for matrix multiplication");
- return glsl_type::error_type;
+ return type;
}
@@ -5776,6 +5724,9 @@ ast_interface_block::hir(exec_list *instructions,
var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED
? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout;
+ if (var_mode == ir_var_shader_in || var_mode == ir_var_uniform)
+ var->data.read_only = true;
+
if (state->stage == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in)
handle_geometry_shader_input_decl(state, loc, var);
@@ -5816,6 +5767,9 @@ ast_interface_block::hir(exec_list *instructions,
var->data.sample = fields[i].sample;
var->init_interface_type(block_type);
+ if (var_mode == ir_var_shader_in || var_mode == ir_var_uniform)
+ var->data.read_only = true;
+
if (fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED) {
var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED
? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout;
diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp
index c6075722c..524b8d6e8 100644
--- a/mesalib/src/glsl/builtin_functions.cpp
+++ b/mesalib/src/glsl/builtin_functions.cpp
@@ -60,7 +60,7 @@
#include "ir_builder.h"
#include "glsl_parser_extras.h"
#include "program/prog_instruction.h"
-#include <limits>
+#include <math.h>
#define M_PIf ((float) M_PI)
#define M_PI_2f ((float) M_PI_2)
@@ -3215,7 +3215,7 @@ builtin_builder::_isinf(builtin_available_predicate avail, const glsl_type *type
ir_constant_data infinities;
for (int i = 0; i < type->vector_elements; i++) {
- infinities.f[i] = std::numeric_limits<float>::infinity();
+ infinities.f[i] = INFINITY;
}
body.emit(ret(equal(abs(x), imm(type, infinities))));
diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll
index 8dc3d106b..2785ed168 100644
--- a/mesalib/src/glsl/glsl_lexer.ll
+++ b/mesalib/src/glsl/glsl_lexer.ll
@@ -36,14 +36,13 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
#define YY_USER_ACTION \
do { \
- yylloc->source = 0; \
yylloc->first_column = yycolumn + 1; \
yylloc->first_line = yylloc->last_line = yylineno + 1; \
yycolumn += yyleng; \
yylloc->last_column = yycolumn + 1; \
} while(0);
-#define YY_USER_INIT yylineno = 0; yycolumn = 0;
+#define YY_USER_INIT yylineno = 0; yycolumn = 0; yylloc->source = 0;
/* A macro for handling reserved words and keywords across language versions.
*
@@ -188,6 +187,15 @@ HASH ^{SPC}#{SPC}
* one-based.
*/
yylineno = strtol(ptr, &ptr, 0) - 1;
+
+ /* From GLSL 3.30 and GLSL ES on, after processing the
+ * line directive (including its new-line), the implementation
+ * will behave as if it is compiling at the line number passed
+ * as argument. It was line number + 1 in older specifications.
+ */
+ if (yyextra->is_version(330, 100))
+ yylineno--;
+
yylloc->source = strtol(ptr, NULL, 0);
}
{HASH}line{SPCP}{INT}{SPC}$ {
@@ -203,6 +211,14 @@ HASH ^{SPC}#{SPC}
* one-based.
*/
yylineno = strtol(ptr, &ptr, 0) - 1;
+
+ /* From GLSL 3.30 and GLSL ES on, after processing the
+ * line directive (including its new-line), the implementation
+ * will behave as if it is compiling at the line number passed
+ * as argument. It was line number + 1 in older specifications.
+ */
+ if (yyextra->is_version(330, 100))
+ yylineno--;
}
^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}on{SPC}\) {
BEGIN PP;
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index 79624bc26..0aa3c54fc 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -73,8 +73,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
this->uses_builtin_functions = false;
/* Set default language version and extensions */
- this->language_version = ctx->Const.ForceGLSLVersion ?
- ctx->Const.ForceGLSLVersion : 110;
+ this->language_version = 110;
+ this->forced_language_version = ctx->Const.ForceGLSLVersion;
this->es_shader = false;
this->ARB_texture_rectangle_enable = true;
@@ -320,11 +320,14 @@ _mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version,
this->ARB_texture_rectangle_enable = false;
}
- this->language_version = version;
+ if (this->forced_language_version)
+ this->language_version = this->forced_language_version;
+ else
+ this->language_version = version;
bool supported = false;
for (unsigned i = 0; i < this->num_supported_versions; i++) {
- if (this->supported_versions[i].ver == (unsigned) version
+ if (this->supported_versions[i].ver == this->language_version
&& this->supported_versions[i].es == this->es_shader) {
supported = true;
break;
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index 0975c86ed..dae7864fd 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -105,8 +105,10 @@ struct _mesa_glsl_parse_state {
{
unsigned required_version = this->es_shader ?
required_glsl_es_version : required_glsl_version;
+ unsigned this_version = this->forced_language_version
+ ? this->forced_language_version : this->language_version;
return required_version != 0
- && this->language_version >= required_version;
+ && this_version >= required_version;
}
bool check_version(unsigned required_glsl_version,
@@ -226,6 +228,7 @@ struct _mesa_glsl_parse_state {
bool es_shader;
unsigned language_version;
+ unsigned forced_language_version;
gl_shader_stage stage;
/**
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index 38b37a6a9..4aa36a794 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -825,6 +825,73 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
const glsl_type *
+glsl_type::get_mul_type(const glsl_type *type_a, const glsl_type *type_b)
+{
+ if (type_a == type_b) {
+ return type_a;
+ } else if (type_a->is_matrix() && type_b->is_matrix()) {
+ /* Matrix multiply. The columns of A must match the rows of B. Given
+ * the other previously tested constraints, this means the vector type
+ * of a row from A must be the same as the vector type of a column from
+ * B.
+ */
+ if (type_a->row_type() == type_b->column_type()) {
+ /* The resulting matrix has the number of columns of matrix B and
+ * the number of rows of matrix A. We get the row count of A by
+ * looking at the size of a vector that makes up a column. The
+ * transpose (size of a row) is done for B.
+ */
+ const glsl_type *const type =
+ get_instance(type_a->base_type,
+ type_a->column_type()->vector_elements,
+ type_b->row_type()->vector_elements);
+ assert(type != error_type);
+
+ return type;
+ }
+ } else if (type_a->is_matrix()) {
+ /* A is a matrix and B is a column vector. Columns of A must match
+ * rows of B. Given the other previously tested constraints, this
+ * means the vector type of a row from A must be the same as the
+ * vector the type of B.
+ */
+ if (type_a->row_type() == type_b) {
+ /* The resulting vector has a number of elements equal to
+ * the number of rows of matrix A. */
+ const glsl_type *const type =
+ get_instance(type_a->base_type,
+ type_a->column_type()->vector_elements,
+ 1);
+ assert(type != error_type);
+
+ return type;
+ }
+ } else {
+ assert(type_b->is_matrix());
+
+ /* A is a row vector and B is a matrix. Columns of A must match rows
+ * of B. Given the other previously tested constraints, this means
+ * the type of A must be the same as the vector type of a column from
+ * B.
+ */
+ if (type_a == type_b->column_type()) {
+ /* The resulting vector has a number of elements equal to
+ * the number of columns of matrix B. */
+ const glsl_type *const type =
+ get_instance(type_a->base_type,
+ type_b->row_type()->vector_elements,
+ 1);
+ assert(type != error_type);
+
+ return type;
+ }
+ }
+
+ return error_type;
+}
+
+
+const glsl_type *
glsl_type::field_type(const char *name) const
{
if (this->base_type != GLSL_TYPE_STRUCT
@@ -1077,15 +1144,6 @@ glsl_type::std140_base_alignment(bool row_major) const
return base_alignment;
}
- /* A sampler may never occur in a UBO (without bindless of some sort),
- * however it is convenient to use this alignment function even with
- * regular uniforms. This allows use of this function on uniform structs
- * that contain samplers.
- */
- if (this->is_sampler()) {
- return 0;
- }
-
assert(!"not reached");
return -1;
}
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h
index 7359e9476..d383dd5be 100644
--- a/mesalib/src/glsl/glsl_types.h
+++ b/mesalib/src/glsl/glsl_types.h
@@ -276,6 +276,12 @@ struct glsl_type {
const char *block_name);
/**
+ * Get the type resulting from a multiplication of \p type_a * \p type_b
+ */
+ static const glsl_type *get_mul_type(const glsl_type *type_a,
+ const glsl_type *type_b);
+
+ /**
* Query the total number of scalars that make up a scalar, vector or matrix
*/
unsigned components() const
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index 54656f899..9e3238552 100644
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -240,8 +240,6 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
case ir_unop_round_even:
case ir_unop_sin:
case ir_unop_cos:
- case ir_unop_sin_reduced:
- case ir_unop_cos_reduced:
case ir_unop_dFdx:
case ir_unop_dFdx_coarse:
case ir_unop_dFdx_fine:
@@ -380,10 +378,12 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
} else if (op1->type->is_scalar()) {
this->type = op0->type;
} else {
- /* FINISHME: matrix types */
- assert(!op0->type->is_matrix() && !op1->type->is_matrix());
- assert(op0->type == op1->type);
- this->type = op0->type;
+ if (this->operation == ir_binop_mul) {
+ this->type = glsl_type::get_mul_type(op0->type, op1->type);
+ } else {
+ assert(op0->type == op1->type);
+ this->type = op0->type;
+ }
}
break;
@@ -540,8 +540,6 @@ static const char *const operator_strs[] = {
"round_even",
"sin",
"cos",
- "sin_reduced",
- "cos_reduced",
"dFdx",
"dFdxCoarse",
"dFdxFine",
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index fdc22edf1..fab1cd2d2 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -109,6 +109,31 @@ public:
virtual ir_instruction *clone(void *mem_ctx,
struct hash_table *ht) const = 0;
+ bool is_rvalue() const
+ {
+ return ir_type == ir_type_dereference_array ||
+ ir_type == ir_type_dereference_record ||
+ ir_type == ir_type_dereference_variable ||
+ ir_type == ir_type_constant ||
+ ir_type == ir_type_expression ||
+ ir_type == ir_type_swizzle ||
+ ir_type == ir_type_texture;
+ }
+
+ bool is_dereference() const
+ {
+ return ir_type == ir_type_dereference_array ||
+ ir_type == ir_type_dereference_record ||
+ ir_type == ir_type_dereference_variable;
+ }
+
+ bool is_jump() const
+ {
+ return ir_type == ir_type_loop_jump ||
+ ir_type == ir_type_return ||
+ ir_type == ir_type_discard;
+ }
+
/**
* \name IR instruction downcast functions
*
@@ -117,45 +142,33 @@ public:
* Additional downcast functions will be added as needed.
*/
/*@{*/
- class ir_rvalue *as_rvalue()
- {
- assume(this != NULL);
- if (ir_type == ir_type_dereference_array ||
- ir_type == ir_type_dereference_record ||
- ir_type == ir_type_dereference_variable ||
- ir_type == ir_type_constant ||
- ir_type == ir_type_expression ||
- ir_type == ir_type_swizzle ||
- ir_type == ir_type_texture)
- return (class ir_rvalue *) this;
- return NULL;
- }
-
- class ir_dereference *as_dereference()
- {
- assume(this != NULL);
- if (ir_type == ir_type_dereference_array ||
- ir_type == ir_type_dereference_record ||
- ir_type == ir_type_dereference_variable)
- return (class ir_dereference *) this;
- return NULL;
- }
-
- class ir_jump *as_jump()
- {
- assume(this != NULL);
- if (ir_type == ir_type_loop_jump ||
- ir_type == ir_type_return ||
- ir_type == ir_type_discard)
- return (class ir_jump *) this;
- return NULL;
- }
+ #define AS_BASE(TYPE) \
+ class ir_##TYPE *as_##TYPE() \
+ { \
+ assume(this != NULL); \
+ return is_##TYPE() ? (ir_##TYPE *) this : NULL; \
+ } \
+ const class ir_##TYPE *as_##TYPE() const \
+ { \
+ assume(this != NULL); \
+ return is_##TYPE() ? (ir_##TYPE *) this : NULL; \
+ }
+
+ AS_BASE(rvalue)
+ AS_BASE(dereference)
+ AS_BASE(jump)
+ #undef AS_BASE
#define AS_CHILD(TYPE) \
class ir_##TYPE * as_##TYPE() \
{ \
assume(this != NULL); \
return ir_type == ir_type_##TYPE ? (ir_##TYPE *) this : NULL; \
+ } \
+ const class ir_##TYPE * as_##TYPE() const \
+ { \
+ assume(this != NULL); \
+ return ir_type == ir_type_##TYPE ? (const ir_##TYPE *) this : NULL; \
}
AS_CHILD(variable)
AS_CHILD(function)
@@ -183,7 +196,8 @@ public:
* in particular. No support for other instruction types (assignments,
* jumps, calls, etc.) is planned.
*/
- virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+ virtual bool equals(const ir_instruction *ir,
+ enum ir_node_type ignore = ir_type_unset) const;
protected:
ir_instruction(enum ir_node_type t)
@@ -1300,8 +1314,6 @@ enum ir_expression_operation {
/*@{*/
ir_unop_sin,
ir_unop_cos,
- ir_unop_sin_reduced, /**< Reduced range sin. [-pi, pi] */
- ir_unop_cos_reduced, /**< Reduced range cos. [-pi, pi] */
/*@}*/
/**
@@ -1598,7 +1610,8 @@ public:
*/
ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2);
- virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+ virtual bool equals(const ir_instruction *ir,
+ enum ir_node_type ignore = ir_type_unset) const;
virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const;
@@ -1909,7 +1922,8 @@ public:
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
- virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+ virtual bool equals(const ir_instruction *ir,
+ enum ir_node_type ignore = ir_type_unset) const;
/**
* Return a string representing the ir_texture_opcode.
@@ -2010,7 +2024,8 @@ public:
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
- virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+ virtual bool equals(const ir_instruction *ir,
+ enum ir_node_type ignore = ir_type_unset) const;
bool is_lvalue() const
{
@@ -2063,7 +2078,8 @@ public:
virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
- virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+ virtual bool equals(const ir_instruction *ir,
+ enum ir_node_type ignore = ir_type_unset) const;
/**
* Get the variable that is ultimately referenced by an r-value
@@ -2109,7 +2125,8 @@ public:
virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
- virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+ virtual bool equals(const ir_instruction *ir,
+ enum ir_node_type ignore = ir_type_unset) const;
/**
* Get the variable that is ultimately referenced by an r-value
@@ -2219,7 +2236,8 @@ public:
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
- virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset);
+ virtual bool equals(const ir_instruction *ir,
+ enum ir_node_type ignore = ir_type_unset) const;
/**
* Get a particular component of a constant as a specific type
diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp
index ecebc3cdc..171b8e954 100644
--- a/mesalib/src/glsl/ir_constant_expression.cpp
+++ b/mesalib/src/glsl/ir_constant_expression.cpp
@@ -781,7 +781,6 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
break;
case ir_unop_sin:
- case ir_unop_sin_reduced:
assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
for (unsigned c = 0; c < op[0]->type->components(); c++) {
data.f[c] = sinf(op[0]->value.f[c]);
@@ -789,7 +788,6 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
break;
case ir_unop_cos:
- case ir_unop_cos_reduced:
assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
for (unsigned c = 0; c < op[0]->type->components(); c++) {
data.f[c] = cosf(op[0]->value.f[c]);
diff --git a/mesalib/src/glsl/ir_equals.cpp b/mesalib/src/glsl/ir_equals.cpp
index 65376cd94..cc1964eef 100644
--- a/mesalib/src/glsl/ir_equals.cpp
+++ b/mesalib/src/glsl/ir_equals.cpp
@@ -28,7 +28,8 @@
* can't access a's vtable in that case.
*/
static bool
-possibly_null_equals(ir_instruction *a, ir_instruction *b, enum ir_node_type ignore)
+possibly_null_equals(const ir_instruction *a, const ir_instruction *b,
+ enum ir_node_type ignore)
{
if (!a || !b)
return !a && !b;
@@ -41,13 +42,13 @@ possibly_null_equals(ir_instruction *a, ir_instruction *b, enum ir_node_type ign
* about.
*/
bool
-ir_instruction::equals(ir_instruction *, enum ir_node_type)
+ir_instruction::equals(const ir_instruction *, enum ir_node_type) const
{
return false;
}
bool
-ir_constant::equals(ir_instruction *ir, enum ir_node_type)
+ir_constant::equals(const ir_instruction *ir, enum ir_node_type) const
{
const ir_constant *other = ir->as_constant();
if (!other)
@@ -65,7 +66,8 @@ ir_constant::equals(ir_instruction *ir, enum ir_node_type)
}
bool
-ir_dereference_variable::equals(ir_instruction *ir, enum ir_node_type)
+ir_dereference_variable::equals(const ir_instruction *ir,
+ enum ir_node_type) const
{
const ir_dereference_variable *other = ir->as_dereference_variable();
if (!other)
@@ -75,7 +77,8 @@ ir_dereference_variable::equals(ir_instruction *ir, enum ir_node_type)
}
bool
-ir_dereference_array::equals(ir_instruction *ir, enum ir_node_type ignore)
+ir_dereference_array::equals(const ir_instruction *ir,
+ enum ir_node_type ignore) const
{
const ir_dereference_array *other = ir->as_dereference_array();
if (!other)
@@ -94,7 +97,8 @@ ir_dereference_array::equals(ir_instruction *ir, enum ir_node_type ignore)
}
bool
-ir_swizzle::equals(ir_instruction *ir, enum ir_node_type ignore)
+ir_swizzle::equals(const ir_instruction *ir,
+ enum ir_node_type ignore) const
{
const ir_swizzle *other = ir->as_swizzle();
if (!other)
@@ -116,7 +120,7 @@ ir_swizzle::equals(ir_instruction *ir, enum ir_node_type ignore)
}
bool
-ir_texture::equals(ir_instruction *ir, enum ir_node_type ignore)
+ir_texture::equals(const ir_instruction *ir, enum ir_node_type ignore) const
{
const ir_texture *other = ir->as_texture();
if (!other)
@@ -179,7 +183,7 @@ ir_texture::equals(ir_instruction *ir, enum ir_node_type ignore)
}
bool
-ir_expression::equals(ir_instruction *ir, enum ir_node_type ignore)
+ir_expression::equals(const ir_instruction *ir, enum ir_node_type ignore) const
{
const ir_expression *other = ir->as_expression();
if (!other)
diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp
index 7a7688cb2..cfe0df3dc 100644
--- a/mesalib/src/glsl/ir_validate.cpp
+++ b/mesalib/src/glsl/ir_validate.cpp
@@ -334,8 +334,6 @@ ir_validate::visit_leave(ir_expression *ir)
break;
case ir_unop_sin:
case ir_unop_cos:
- case ir_unop_sin_reduced:
- case ir_unop_cos_reduced:
case ir_unop_dFdx:
case ir_unop_dFdx_coarse:
case ir_unop_dFdx_fine:
@@ -543,9 +541,9 @@ ir_validate::visit_leave(ir_expression *ir)
case ir_binop_logic_and:
case ir_binop_logic_xor:
case ir_binop_logic_or:
- assert(ir->type == glsl_type::bool_type);
- assert(ir->operands[0]->type == glsl_type::bool_type);
- assert(ir->operands[1]->type == glsl_type::bool_type);
+ assert(ir->type->base_type == GLSL_TYPE_BOOL);
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
+ assert(ir->operands[1]->type->base_type == GLSL_TYPE_BOOL);
break;
case ir_binop_dot:
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
index 799c74bb9..59adc298b 100644
--- a/mesalib/src/glsl/link_uniforms.cpp
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -547,6 +547,8 @@ private:
virtual void enter_record(const glsl_type *type, const char *name,
bool row_major) {
assert(type->is_record());
+ if (this->ubo_block_index == -1)
+ return;
this->ubo_byte_offset = glsl_align(
this->ubo_byte_offset, type->std140_base_alignment(row_major));
}
@@ -554,6 +556,8 @@ private:
virtual void leave_record(const glsl_type *type, const char *name,
bool row_major) {
assert(type->is_record());
+ if (this->ubo_block_index == -1)
+ return;
this->ubo_byte_offset = glsl_align(
this->ubo_byte_offset, type->std140_base_alignment(row_major));
}
diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp
index 22617990f..605748a9c 100644
--- a/mesalib/src/glsl/link_varyings.cpp
+++ b/mesalib/src/glsl/link_varyings.cpp
@@ -263,6 +263,19 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
if (output != NULL) {
cross_validate_types_and_qualifiers(prog, input, output,
consumer->Stage, producer->Stage);
+ } else {
+ /* Check for input vars with unmatched output vars in prev stage
+ * taking into account that interface blocks could have a matching
+ * output but with different name, so we ignore them.
+ */
+ assert(!input->data.assigned);
+ if (input->data.used && !input->get_interface_type() &&
+ !input->data.explicit_location && !prog->SeparateShader)
+ linker_error(prog,
+ "%s shader input `%s' "
+ "has no matching output in the previous stage\n",
+ _mesa_shader_stage_to_string(consumer->Stage),
+ input->name);
}
}
}
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 4349f0973..b6baa5d36 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -1377,24 +1377,13 @@ link_fs_input_layout_qualifiers(struct gl_shader_program *prog,
* "If gl_FragCoord is redeclared in any fragment shader in a program,
* it must be redeclared in all the fragment shaders in that program
* that have a static use gl_FragCoord."
- *
- * Exclude the case when one of the 'linked_shader' or 'shader' redeclares
- * gl_FragCoord with no layout qualifiers but the other one doesn't
- * redeclare it. If we strictly follow GLSL 1.50 spec's language, it
- * should be a link error. But, generating link error for this case will
- * be a wrong behaviour which spec didn't intend to do and it could also
- * break some applications.
*/
if ((linked_shader->redeclares_gl_fragcoord
&& !shader->redeclares_gl_fragcoord
- && shader->uses_gl_fragcoord
- && (linked_shader->origin_upper_left
- || linked_shader->pixel_center_integer))
+ && shader->uses_gl_fragcoord)
|| (shader->redeclares_gl_fragcoord
&& !linked_shader->redeclares_gl_fragcoord
- && linked_shader->uses_gl_fragcoord
- && (shader->origin_upper_left
- || shader->pixel_center_integer))) {
+ && linked_shader->uses_gl_fragcoord)) {
linker_error(prog, "fragment shader defined with conflicting "
"layout qualifiers for gl_FragCoord\n");
}
@@ -2503,6 +2492,194 @@ check_explicit_uniform_locations(struct gl_context *ctx,
delete uniform_map;
}
+static bool
+add_program_resource(struct gl_shader_program *prog, GLenum type,
+ const void *data, uint8_t stages)
+{
+ assert(data);
+
+ /* If resource already exists, do not add it again. */
+ for (unsigned i = 0; i < prog->NumProgramResourceList; i++)
+ if (prog->ProgramResourceList[i].Data == data)
+ return true;
+
+ prog->ProgramResourceList =
+ reralloc(prog,
+ prog->ProgramResourceList,
+ gl_program_resource,
+ prog->NumProgramResourceList + 1);
+
+ if (!prog->ProgramResourceList) {
+ linker_error(prog, "Out of memory during linking.\n");
+ return false;
+ }
+
+ struct gl_program_resource *res =
+ &prog->ProgramResourceList[prog->NumProgramResourceList];
+
+ res->Type = type;
+ res->Data = data;
+ res->StageReferences = stages;
+
+ prog->NumProgramResourceList++;
+
+ return true;
+}
+
+/**
+ * Function builds a stage reference bitmask from variable name.
+ */
+static uint8_t
+build_stageref(struct gl_shader_program *shProg, const char *name)
+{
+ uint8_t stages = 0;
+
+ /* Note, that we assume MAX 8 stages, if there will be more stages, type
+ * used for reference mask in gl_program_resource will need to be changed.
+ */
+ assert(MESA_SHADER_STAGES < 8);
+
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ struct gl_shader *sh = shProg->_LinkedShaders[i];
+ if (!sh)
+ continue;
+ ir_variable *var = sh->symbols->get_variable(name);
+ if (var)
+ stages |= (1 << i);
+ }
+ return stages;
+}
+
+static bool
+add_interface_variables(struct gl_shader_program *shProg,
+ struct gl_shader *sh, GLenum programInterface)
+{
+ foreach_in_list(ir_instruction, node, sh->ir) {
+ ir_variable *var = node->as_variable();
+
+ if (!var)
+ continue;
+
+ switch (var->data.mode) {
+ /* From GL 4.3 core spec, section 11.1.1 (Vertex Attributes):
+ * "For GetActiveAttrib, all active vertex shader input variables
+ * are enumerated, including the special built-in inputs gl_VertexID
+ * and gl_InstanceID."
+ */
+ case ir_var_system_value:
+ if (var->data.location != SYSTEM_VALUE_VERTEX_ID &&
+ var->data.location != SYSTEM_VALUE_VERTEX_ID_ZERO_BASE &&
+ var->data.location != SYSTEM_VALUE_INSTANCE_ID)
+ continue;
+ case ir_var_shader_in:
+ if (programInterface != GL_PROGRAM_INPUT)
+ continue;
+ break;
+ case ir_var_shader_out:
+ if (programInterface != GL_PROGRAM_OUTPUT)
+ continue;
+ break;
+ default:
+ continue;
+ };
+
+ if (!add_program_resource(shProg, programInterface, var,
+ build_stageref(shProg, var->name)))
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Builds up a list of program resources that point to existing
+ * resource data.
+ */
+static void
+build_program_resource_list(struct gl_context *ctx,
+ struct gl_shader_program *shProg)
+{
+ /* Rebuild resource list. */
+ if (shProg->ProgramResourceList) {
+ ralloc_free(shProg->ProgramResourceList);
+ shProg->ProgramResourceList = NULL;
+ shProg->NumProgramResourceList = 0;
+ }
+
+ int input_stage = MESA_SHADER_STAGES, output_stage = 0;
+
+ /* Determine first input and final output stage. These are used to
+ * detect which variables should be enumerated in the resource list
+ * for GL_PROGRAM_INPUT and GL_PROGRAM_OUTPUT.
+ */
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (!shProg->_LinkedShaders[i])
+ continue;
+ if (input_stage == MESA_SHADER_STAGES)
+ input_stage = i;
+ output_stage = i;
+ }
+
+ /* Empty shader, no resources. */
+ if (input_stage == MESA_SHADER_STAGES && output_stage == 0)
+ return;
+
+ /* Add inputs and outputs to the resource list. */
+ if (!add_interface_variables(shProg, shProg->_LinkedShaders[input_stage],
+ GL_PROGRAM_INPUT))
+ return;
+
+ if (!add_interface_variables(shProg, shProg->_LinkedShaders[output_stage],
+ GL_PROGRAM_OUTPUT))
+ return;
+
+ /* Add transform feedback varyings. */
+ if (shProg->LinkedTransformFeedback.NumVarying > 0) {
+ for (int i = 0; i < shProg->LinkedTransformFeedback.NumVarying; i++) {
+ uint8_t stageref =
+ build_stageref(shProg,
+ shProg->LinkedTransformFeedback.Varyings[i].Name);
+ if (!add_program_resource(shProg, GL_TRANSFORM_FEEDBACK_VARYING,
+ &shProg->LinkedTransformFeedback.Varyings[i],
+ stageref))
+ return;
+ }
+ }
+
+ /* Add uniforms from uniform storage. */
+ for (unsigned i = 0; i < shProg->NumUserUniformStorage; i++) {
+ /* Do not add uniforms internally used by Mesa. */
+ if (shProg->UniformStorage[i].hidden)
+ continue;
+
+ uint8_t stageref =
+ build_stageref(shProg, shProg->UniformStorage[i].name);
+ if (!add_program_resource(shProg, GL_UNIFORM,
+ &shProg->UniformStorage[i], stageref))
+ return;
+ }
+
+ /* Add program uniform blocks. */
+ for (unsigned i = 0; i < shProg->NumUniformBlocks; i++) {
+ if (!add_program_resource(shProg, GL_UNIFORM_BLOCK,
+ &shProg->UniformBlocks[i], 0))
+ return;
+ }
+
+ /* Add atomic counter buffers. */
+ for (unsigned i = 0; i < shProg->NumAtomicBuffers; i++) {
+ if (!add_program_resource(shProg, GL_ATOMIC_COUNTER_BUFFER,
+ &shProg->AtomicBuffers[i], 0))
+ return;
+ }
+
+ /* TODO - following extensions will require more resource types:
+ *
+ * GL_ARB_shader_storage_buffer_object
+ * GL_ARB_shader_subroutine
+ */
+}
+
+
void
link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
{
@@ -2737,10 +2914,18 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
goto done;
}
- unsigned first;
- for (first = 0; first <= MESA_SHADER_FRAGMENT; first++) {
- if (prog->_LinkedShaders[first] != NULL)
- break;
+ unsigned first, last;
+
+ first = MESA_SHADER_STAGES;
+ last = 0;
+
+ /* Determine first and last stage. */
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (!prog->_LinkedShaders[i])
+ continue;
+ if (first == MESA_SHADER_STAGES)
+ first = i;
+ last = i;
}
if (num_tfeedback_decls != 0) {
@@ -2769,13 +2954,9 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
* ensures that inter-shader outputs written to in an earlier stage are
* eliminated if they are (transitively) not used in a later stage.
*/
- int last, next;
- for (last = MESA_SHADER_FRAGMENT; last >= 0; last--) {
- if (prog->_LinkedShaders[last] != NULL)
- break;
- }
+ int next;
- if (last >= 0 && last < MESA_SHADER_FRAGMENT) {
+ if (first < MESA_SHADER_FRAGMENT) {
gl_shader *const sh = prog->_LinkedShaders[last];
if (first == MESA_SHADER_GEOMETRY) {
@@ -2787,13 +2968,14 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
* MESA_SHADER_GEOMETRY.
*/
if (!assign_varying_locations(ctx, mem_ctx, prog,
- NULL, sh,
+ NULL, prog->_LinkedShaders[first],
num_tfeedback_decls, tfeedback_decls,
prog->Geom.VerticesIn))
goto done;
}
- if (num_tfeedback_decls != 0 || prog->SeparateShader) {
+ if (last != MESA_SHADER_FRAGMENT &&
+ (num_tfeedback_decls != 0 || prog->SeparateShader)) {
/* There was no fragment shader, but we still have to assign varying
* locations for use by transform feedback.
*/
@@ -2905,6 +3087,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
}
}
+ build_program_resource_list(ctx, prog);
+ if (!prog->LinkStatus)
+ goto done;
+
/* FINISHME: Assign fragment shader output locations. */
done:
diff --git a/mesalib/src/glsl/loop_controls.cpp b/mesalib/src/glsl/loop_controls.cpp
index d7f0b2809..51804bb5f 100644
--- a/mesalib/src/glsl/loop_controls.cpp
+++ b/mesalib/src/glsl/loop_controls.cpp
@@ -139,7 +139,7 @@ calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
iter = new(mem_ctx) ir_constant(double(iter_value + bias[i]));
break;
default:
- unreachable(!"Unsupported type for loop iterator.");
+ unreachable("Unsupported type for loop iterator.");
}
ir_expression *const mul =
diff --git a/mesalib/src/glsl/lower_const_arrays_to_uniforms.cpp b/mesalib/src/glsl/lower_const_arrays_to_uniforms.cpp
index 2243f479a..44967dcdb 100644
--- a/mesalib/src/glsl/lower_const_arrays_to_uniforms.cpp
+++ b/mesalib/src/glsl/lower_const_arrays_to_uniforms.cpp
@@ -49,7 +49,6 @@ public:
{
instructions = insts;
progress = false;
- index = 0;
}
bool run()
@@ -63,7 +62,6 @@ public:
private:
exec_list *instructions;
bool progress;
- unsigned index;
};
void
@@ -82,7 +80,7 @@ lower_const_array_visitor::handle_rvalue(ir_rvalue **rvalue)
void *mem_ctx = ralloc_parent(con);
- char *uniform_name = ralloc_asprintf(mem_ctx, "constarray__%d", index++);
+ char *uniform_name = ralloc_asprintf(mem_ctx, "constarray__%p", dra);
ir_variable *uni =
new(mem_ctx) ir_variable(con->type, uniform_name, ir_var_uniform);
diff --git a/mesalib/src/glsl/nir/glsl_to_nir.cpp b/mesalib/src/glsl/nir/glsl_to_nir.cpp
index 357944da6..f6b8331d4 100644
--- a/mesalib/src/glsl/nir/glsl_to_nir.cpp
+++ b/mesalib/src/glsl/nir/glsl_to_nir.cpp
@@ -88,6 +88,8 @@ private:
exec_list *cf_node_list;
nir_instr *result; /* result of the expression tree last visited */
+ nir_deref_var *evaluate_deref(nir_instr *mem_ctx, ir_instruction *ir);
+
/* the head of the dereference chain we're creating */
nir_deref_var *deref_head;
/* the tail of the dereference chain we're creating */
@@ -156,6 +158,14 @@ nir_visitor::~nir_visitor()
_mesa_hash_table_destroy(this->overload_table, NULL);
}
+nir_deref_var *
+nir_visitor::evaluate_deref(nir_instr *mem_ctx, ir_instruction *ir)
+{
+ ir->accept(this);
+ ralloc_steal(mem_ctx, this->deref_head);
+ return this->deref_head;
+}
+
static nir_constant *
constant_copy(ir_constant *ir, void *mem_ctx)
{
@@ -582,13 +592,11 @@ void
nir_visitor::visit(ir_return *ir)
{
if (ir->value != NULL) {
- ir->value->accept(this);
nir_intrinsic_instr *copy =
nir_intrinsic_instr_create(this->shader, nir_intrinsic_copy_var);
- copy->variables[0] = nir_deref_var_create(this->shader,
- this->impl->return_var);
- copy->variables[1] = this->deref_head;
+ copy->variables[0] = nir_deref_var_create(copy, this->impl->return_var);
+ copy->variables[1] = evaluate_deref(&copy->instr, ir->value);
}
nir_jump_instr *instr = nir_jump_instr_create(this->shader, nir_jump_return);
@@ -613,8 +621,7 @@ nir_visitor::visit(ir_call *ir)
nir_intrinsic_instr *instr = nir_intrinsic_instr_create(shader, op);
ir_dereference *param =
(ir_dereference *) ir->actual_parameters.get_head();
- param->accept(this);
- instr->variables[0] = this->deref_head;
+ instr->variables[0] = evaluate_deref(&instr->instr, param);
nir_ssa_dest_init(&instr->instr, &instr->dest, 1, NULL);
nir_instr_insert_after_cf_list(this->cf_node_list, &instr->instr);
@@ -623,8 +630,7 @@ nir_visitor::visit(ir_call *ir)
nir_intrinsic_instr_create(shader, nir_intrinsic_store_var);
store_instr->num_components = 1;
- ir->return_deref->accept(this);
- store_instr->variables[0] = this->deref_head;
+ store_instr->variables[0] = evaluate_deref(&store_instr->instr, ir->return_deref);
store_instr->src[0].is_ssa = true;
store_instr->src[0].ssa = &instr->dest.ssa;
@@ -642,13 +648,11 @@ nir_visitor::visit(ir_call *ir)
unsigned i = 0;
foreach_in_list(ir_dereference, param, &ir->actual_parameters) {
- param->accept(this);
- instr->params[i] = this->deref_head;
+ instr->params[i] = evaluate_deref(&instr->instr, param);
i++;
}
- ir->return_deref->accept(this);
- instr->return_deref = this->deref_head;
+ instr->return_deref = evaluate_deref(&instr->instr, ir->return_deref);
nir_instr_insert_after_cf_list(this->cf_node_list, &instr->instr);
}
@@ -663,12 +667,8 @@ nir_visitor::visit(ir_assignment *ir)
nir_intrinsic_instr *copy =
nir_intrinsic_instr_create(this->shader, nir_intrinsic_copy_var);
- ir->lhs->accept(this);
- copy->variables[0] = this->deref_head;
-
- ir->rhs->accept(this);
- copy->variables[1] = this->deref_head;
-
+ copy->variables[0] = evaluate_deref(&copy->instr, ir->lhs);
+ copy->variables[1] = evaluate_deref(&copy->instr, ir->rhs);
if (ir->condition) {
nir_if *if_stmt = nir_if_create(this->shader);
@@ -700,6 +700,7 @@ nir_visitor::visit(ir_assignment *ir)
load->num_components = ir->lhs->type->vector_elements;
nir_ssa_dest_init(&load->instr, &load->dest, num_components, NULL);
load->variables[0] = lhs_deref;
+ ralloc_steal(load, load->variables[0]);
nir_instr_insert_after_cf_list(this->cf_node_list, &load->instr);
nir_op vec_op;
@@ -741,7 +742,7 @@ nir_visitor::visit(ir_assignment *ir)
nir_intrinsic_instr *store =
nir_intrinsic_instr_create(this->shader, nir_intrinsic_store_var);
store->num_components = ir->lhs->type->vector_elements;
- nir_deref *store_deref = nir_copy_deref(this->shader, &lhs_deref->deref);
+ nir_deref *store_deref = nir_copy_deref(store, &lhs_deref->deref);
store->variables[0] = nir_deref_as_var(store_deref);
store->src[0] = src;
@@ -816,6 +817,7 @@ nir_visitor::evaluate_rvalue(ir_rvalue* ir)
nir_intrinsic_instr_create(this->shader, nir_intrinsic_load_var);
load_instr->num_components = ir->type->vector_elements;
load_instr->variables[0] = this->deref_head;
+ ralloc_steal(load_instr, load_instr->variables[0]);
add_instr(&load_instr->instr, ir->type->vector_elements);
}
@@ -959,6 +961,7 @@ nir_visitor::visit(ir_expression *ir)
nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(shader, op);
intrin->num_components = deref->type->vector_elements;
intrin->variables[0] = this->deref_head;
+ ralloc_steal(intrin, intrin->variables[0]);
if (intrin->intrinsic == nir_intrinsic_interp_var_at_offset ||
intrin->intrinsic == nir_intrinsic_interp_var_at_sample)
@@ -1087,12 +1090,6 @@ nir_visitor::visit(ir_expression *ir)
case ir_unop_round_even: emit(nir_op_fround_even, dest_size, srcs); break;
case ir_unop_sin: emit(nir_op_fsin, dest_size, srcs); break;
case ir_unop_cos: emit(nir_op_fcos, dest_size, srcs); break;
- case ir_unop_sin_reduced:
- emit(nir_op_fsin_reduced, dest_size, srcs);
- break;
- case ir_unop_cos_reduced:
- emit(nir_op_fcos_reduced, dest_size, srcs);
- break;
case ir_unop_dFdx: emit(nir_op_fddx, dest_size, srcs); break;
case ir_unop_dFdy: emit(nir_op_fddy, dest_size, srcs); break;
case ir_unop_dFdx_fine: emit(nir_op_fddx_fine, dest_size, srcs); break;
@@ -1210,6 +1207,9 @@ nir_visitor::visit(ir_expression *ir)
case ir_binop_bit_and:
case ir_binop_bit_or:
case ir_binop_bit_xor:
+ case ir_binop_logic_and:
+ case ir_binop_logic_or:
+ case ir_binop_logic_xor:
case ir_binop_lshift:
case ir_binop_rshift:
switch (ir->operation) {
@@ -1270,6 +1270,24 @@ nir_visitor::visit(ir_expression *ir)
case ir_binop_bit_xor:
op = nir_op_ixor;
break;
+ case ir_binop_logic_and:
+ if (supports_ints)
+ op = nir_op_iand;
+ else
+ op = nir_op_fand;
+ break;
+ case ir_binop_logic_or:
+ if (supports_ints)
+ op = nir_op_ior;
+ else
+ op = nir_op_for;
+ break;
+ case ir_binop_logic_xor:
+ if (supports_ints)
+ op = nir_op_ixor;
+ else
+ op = nir_op_fxor;
+ break;
case ir_binop_lshift:
op = nir_op_ishl;
break;
@@ -1444,24 +1462,6 @@ nir_visitor::visit(ir_expression *ir)
}
}
break;
- case ir_binop_logic_and:
- if (supports_ints)
- emit(nir_op_iand, dest_size, srcs);
- else
- emit(nir_op_fand, dest_size, srcs);
- break;
- case ir_binop_logic_or:
- if (supports_ints)
- emit(nir_op_ior, dest_size, srcs);
- else
- emit(nir_op_for, dest_size, srcs);
- break;
- case ir_binop_logic_xor:
- if (supports_ints)
- emit(nir_op_ixor, dest_size, srcs);
- else
- emit(nir_op_fxor, dest_size, srcs);
- break;
case ir_binop_dot:
switch (ir->operands[0]->type->vector_elements) {
case 2: emit(nir_op_fdot2, dest_size, srcs); break;
@@ -1633,8 +1633,7 @@ nir_visitor::visit(ir_texture *ir)
unreachable("not reached");
}
- ir->sampler->accept(this);
- instr->sampler = this->deref_head;
+ instr->sampler = evaluate_deref(&instr->instr, ir->sampler);
unsigned src_number = 0;
@@ -1759,7 +1758,7 @@ nir_visitor::visit(ir_dereference_record *ir)
int field_index = this->deref_tail->type->field_index(ir->field);
assert(field_index >= 0);
- nir_deref_struct *deref = nir_deref_struct_create(this->shader, field_index);
+ nir_deref_struct *deref = nir_deref_struct_create(this->deref_tail, field_index);
deref->deref.type = ir->type;
this->deref_tail->child = &deref->deref;
this->deref_tail = &deref->deref;
@@ -1783,5 +1782,6 @@ nir_visitor::visit(ir_dereference_array *ir)
ir->array->accept(this);
this->deref_tail->child = &deref->deref;
+ ralloc_steal(this->deref_tail, deref);
this->deref_tail = &deref->deref;
}
diff --git a/mesalib/src/glsl/nir/nir.c b/mesalib/src/glsl/nir/nir.c
index 6459d5108..c6e53612b 100644
--- a/mesalib/src/glsl/nir/nir.c
+++ b/mesalib/src/glsl/nir/nir.c
@@ -58,11 +58,11 @@ reg_create(void *mem_ctx, struct exec_list *list)
nir_register *reg = ralloc(mem_ctx, nir_register);
reg->parent_instr = NULL;
- reg->uses = _mesa_set_create(mem_ctx, _mesa_hash_pointer,
+ reg->uses = _mesa_set_create(reg, _mesa_hash_pointer,
_mesa_key_pointer_equal);
- reg->defs = _mesa_set_create(mem_ctx, _mesa_hash_pointer,
+ reg->defs = _mesa_set_create(reg, _mesa_hash_pointer,
_mesa_key_pointer_equal);
- reg->if_uses = _mesa_set_create(mem_ctx, _mesa_hash_pointer,
+ reg->if_uses = _mesa_set_create(reg, _mesa_hash_pointer,
_mesa_key_pointer_equal);
reg->num_components = 0;
@@ -108,7 +108,7 @@ nir_function_create(nir_shader *shader, const char *name)
exec_list_push_tail(&shader->functions, &func->node);
exec_list_make_empty(&func->overload_list);
- func->name = name;
+ func->name = ralloc_strdup(func, name);
func->shader = shader;
return func;
@@ -285,10 +285,10 @@ nir_block_create(void *mem_ctx)
cf_init(&block->cf_node, nir_cf_node_block);
block->successors[0] = block->successors[1] = NULL;
- block->predecessors = _mesa_set_create(mem_ctx, _mesa_hash_pointer,
+ block->predecessors = _mesa_set_create(block, _mesa_hash_pointer,
_mesa_key_pointer_equal);
block->imm_dom = NULL;
- block->dom_frontier = _mesa_set_create(mem_ctx, _mesa_hash_pointer,
+ block->dom_frontier = _mesa_set_create(block, _mesa_hash_pointer,
_mesa_key_pointer_equal);
exec_list_make_empty(&block->instr_list);
@@ -381,11 +381,11 @@ alu_src_init(nir_alu_src *src)
}
nir_alu_instr *
-nir_alu_instr_create(void *mem_ctx, nir_op op)
+nir_alu_instr_create(nir_shader *shader, nir_op op)
{
unsigned num_srcs = nir_op_infos[op].num_inputs;
nir_alu_instr *instr =
- ralloc_size(mem_ctx,
+ ralloc_size(shader,
sizeof(nir_alu_instr) + num_srcs * sizeof(nir_alu_src));
instr_init(&instr->instr, nir_instr_type_alu);
@@ -398,18 +398,18 @@ nir_alu_instr_create(void *mem_ctx, nir_op op)
}
nir_jump_instr *
-nir_jump_instr_create(void *mem_ctx, nir_jump_type type)
+nir_jump_instr_create(nir_shader *shader, nir_jump_type type)
{
- nir_jump_instr *instr = ralloc(mem_ctx, nir_jump_instr);
+ nir_jump_instr *instr = ralloc(shader, nir_jump_instr);
instr_init(&instr->instr, nir_instr_type_jump);
instr->type = type;
return instr;
}
nir_load_const_instr *
-nir_load_const_instr_create(void *mem_ctx, unsigned num_components)
+nir_load_const_instr_create(nir_shader *shader, unsigned num_components)
{
- nir_load_const_instr *instr = ralloc(mem_ctx, nir_load_const_instr);
+ nir_load_const_instr *instr = ralloc(shader, nir_load_const_instr);
instr_init(&instr->instr, nir_instr_type_load_const);
nir_ssa_def_init(&instr->instr, &instr->def, num_components, NULL);
@@ -418,11 +418,11 @@ nir_load_const_instr_create(void *mem_ctx, unsigned num_components)
}
nir_intrinsic_instr *
-nir_intrinsic_instr_create(void *mem_ctx, nir_intrinsic_op op)
+nir_intrinsic_instr_create(nir_shader *shader, nir_intrinsic_op op)
{
unsigned num_srcs = nir_intrinsic_infos[op].num_srcs;
nir_intrinsic_instr *instr =
- ralloc_size(mem_ctx,
+ ralloc_size(shader,
sizeof(nir_intrinsic_instr) + num_srcs * sizeof(nir_src));
instr_init(&instr->instr, nir_instr_type_intrinsic);
@@ -438,29 +438,29 @@ nir_intrinsic_instr_create(void *mem_ctx, nir_intrinsic_op op)
}
nir_call_instr *
-nir_call_instr_create(void *mem_ctx, nir_function_overload *callee)
+nir_call_instr_create(nir_shader *shader, nir_function_overload *callee)
{
- nir_call_instr *instr = ralloc(mem_ctx, nir_call_instr);
+ nir_call_instr *instr = ralloc(shader, nir_call_instr);
instr_init(&instr->instr, nir_instr_type_call);
instr->callee = callee;
instr->num_params = callee->num_params;
- instr->params = ralloc_array(mem_ctx, nir_deref_var *, instr->num_params);
+ instr->params = ralloc_array(instr, nir_deref_var *, instr->num_params);
instr->return_deref = NULL;
return instr;
}
nir_tex_instr *
-nir_tex_instr_create(void *mem_ctx, unsigned num_srcs)
+nir_tex_instr_create(nir_shader *shader, unsigned num_srcs)
{
- nir_tex_instr *instr = ralloc(mem_ctx, nir_tex_instr);
+ nir_tex_instr *instr = ralloc(shader, nir_tex_instr);
instr_init(&instr->instr, nir_instr_type_tex);
dest_init(&instr->dest);
instr->num_srcs = num_srcs;
- instr->src = ralloc_array(mem_ctx, nir_tex_src, num_srcs);
+ instr->src = ralloc_array(instr, nir_tex_src, num_srcs);
for (unsigned i = 0; i < num_srcs; i++)
src_init(&instr->src[i].src);
@@ -472,9 +472,9 @@ nir_tex_instr_create(void *mem_ctx, unsigned num_srcs)
}
nir_phi_instr *
-nir_phi_instr_create(void *mem_ctx)
+nir_phi_instr_create(nir_shader *shader)
{
- nir_phi_instr *instr = ralloc(mem_ctx, nir_phi_instr);
+ nir_phi_instr *instr = ralloc(shader, nir_phi_instr);
instr_init(&instr->instr, nir_instr_type_phi);
dest_init(&instr->dest);
@@ -483,9 +483,9 @@ nir_phi_instr_create(void *mem_ctx)
}
nir_parallel_copy_instr *
-nir_parallel_copy_instr_create(void *mem_ctx)
+nir_parallel_copy_instr_create(nir_shader *shader)
{
- nir_parallel_copy_instr *instr = ralloc(mem_ctx, nir_parallel_copy_instr);
+ nir_parallel_copy_instr *instr = ralloc(shader, nir_parallel_copy_instr);
instr_init(&instr->instr, nir_instr_type_parallel_copy);
exec_list_make_empty(&instr->entries);
@@ -494,9 +494,9 @@ nir_parallel_copy_instr_create(void *mem_ctx)
}
nir_ssa_undef_instr *
-nir_ssa_undef_instr_create(void *mem_ctx, unsigned num_components)
+nir_ssa_undef_instr_create(nir_shader *shader, unsigned num_components)
{
- nir_ssa_undef_instr *instr = ralloc(mem_ctx, nir_ssa_undef_instr);
+ nir_ssa_undef_instr *instr = ralloc(shader, nir_ssa_undef_instr);
instr_init(&instr->instr, nir_instr_type_ssa_undef);
nir_ssa_def_init(&instr->instr, &instr->def, num_components, NULL);
@@ -543,7 +543,7 @@ copy_deref_var(void *mem_ctx, nir_deref_var *deref)
nir_deref_var *ret = nir_deref_var_create(mem_ctx, deref->var);
ret->deref.type = deref->deref.type;
if (deref->deref.child)
- ret->deref.child = nir_copy_deref(mem_ctx, deref->deref.child);
+ ret->deref.child = nir_copy_deref(ret, deref->deref.child);
return ret;
}
@@ -558,7 +558,7 @@ copy_deref_array(void *mem_ctx, nir_deref_array *deref)
}
ret->deref.type = deref->deref.type;
if (deref->deref.child)
- ret->deref.child = nir_copy_deref(mem_ctx, deref->deref.child);
+ ret->deref.child = nir_copy_deref(ret, deref->deref.child);
return ret;
}
@@ -568,7 +568,7 @@ copy_deref_struct(void *mem_ctx, nir_deref_struct *deref)
nir_deref_struct *ret = nir_deref_struct_create(mem_ctx, deref->index);
ret->deref.type = deref->deref.type;
if (deref->deref.child)
- ret->deref.child = nir_copy_deref(mem_ctx, deref->deref.child);
+ ret->deref.child = nir_copy_deref(ret, deref->deref.child);
return ret;
}
@@ -1834,13 +1834,11 @@ void
nir_ssa_def_init(nir_instr *instr, nir_ssa_def *def,
unsigned num_components, const char *name)
{
- void *mem_ctx = ralloc_parent(instr);
-
def->name = name;
def->parent_instr = instr;
- def->uses = _mesa_set_create(mem_ctx, _mesa_hash_pointer,
+ def->uses = _mesa_set_create(instr, _mesa_hash_pointer,
_mesa_key_pointer_equal);
- def->if_uses = _mesa_set_create(mem_ctx, _mesa_hash_pointer,
+ def->if_uses = _mesa_set_create(instr, _mesa_hash_pointer,
_mesa_key_pointer_equal);
def->num_components = num_components;
diff --git a/mesalib/src/glsl/nir/nir.h b/mesalib/src/glsl/nir/nir.h
index 29fe94243..74772c798 100644
--- a/mesalib/src/glsl/nir/nir.h
+++ b/mesalib/src/glsl/nir/nir.h
@@ -34,6 +34,7 @@
#include "util/set.h"
#include "util/bitset.h"
#include "nir_types.h"
+#include "glsl/shader_enums.h"
#include <stdio.h>
#include "nir_opcodes.h"
@@ -529,6 +530,16 @@ nir_src_for_reg(nir_register *reg)
return src;
}
+static inline nir_instr *
+nir_src_get_parent_instr(const nir_src *src)
+{
+ if (src->is_ssa) {
+ return src->ssa->parent_instr;
+ } else {
+ return src->reg.reg->parent_instr;
+ }
+}
+
static inline nir_dest
nir_dest_for_reg(nir_register *reg)
{
@@ -1365,11 +1376,17 @@ typedef struct nir_function {
typedef struct nir_shader_compiler_options {
bool lower_ffma;
+ bool lower_flrp;
bool lower_fpow;
bool lower_fsat;
bool lower_fsqrt;
/** lowers fneg and ineg to fsub and isub. */
bool lower_negate;
+ /** lowers fsub and isub to fadd+fneg and iadd+ineg. */
+ bool lower_sub;
+
+ /* lower {slt,sge,seq,sne} to {flt,fge,feq,fne} + b2f: */
+ bool lower_scmp;
/**
* Does the driver support real 32-bit integers? (Otherwise, integers
@@ -1414,6 +1431,9 @@ typedef struct nir_shader {
* access plus one
*/
unsigned num_inputs, num_uniforms, num_outputs;
+
+ /** the number of uniforms that are only accessed directly */
+ unsigned num_direct_uniforms;
} nir_shader;
#define nir_foreach_overload(shader, overload) \
@@ -1466,26 +1486,26 @@ void nir_metadata_require(nir_function_impl *impl, nir_metadata required);
void nir_metadata_preserve(nir_function_impl *impl, nir_metadata preserved);
/** creates an instruction with default swizzle/writemask/etc. with NULL registers */
-nir_alu_instr *nir_alu_instr_create(void *mem_ctx, nir_op op);
+nir_alu_instr *nir_alu_instr_create(nir_shader *shader, nir_op op);
-nir_jump_instr *nir_jump_instr_create(void *mem_ctx, nir_jump_type type);
+nir_jump_instr *nir_jump_instr_create(nir_shader *shader, nir_jump_type type);
-nir_load_const_instr *nir_load_const_instr_create(void *mem_ctx,
+nir_load_const_instr *nir_load_const_instr_create(nir_shader *shader,
unsigned num_components);
-nir_intrinsic_instr *nir_intrinsic_instr_create(void *mem_ctx,
+nir_intrinsic_instr *nir_intrinsic_instr_create(nir_shader *shader,
nir_intrinsic_op op);
-nir_call_instr *nir_call_instr_create(void *mem_ctx,
+nir_call_instr *nir_call_instr_create(nir_shader *shader,
nir_function_overload *callee);
-nir_tex_instr *nir_tex_instr_create(void *mem_ctx, unsigned num_srcs);
+nir_tex_instr *nir_tex_instr_create(nir_shader *shader, unsigned num_srcs);
-nir_phi_instr *nir_phi_instr_create(void *mem_ctx);
+nir_phi_instr *nir_phi_instr_create(nir_shader *shader);
-nir_parallel_copy_instr *nir_parallel_copy_instr_create(void *mem_ctx);
+nir_parallel_copy_instr *nir_parallel_copy_instr_create(nir_shader *shader);
-nir_ssa_undef_instr *nir_ssa_undef_instr_create(void *mem_ctx,
+nir_ssa_undef_instr *nir_ssa_undef_instr_create(nir_shader *shader,
unsigned num_components);
nir_deref_var *nir_deref_var_create(void *mem_ctx, nir_variable *var);
@@ -1550,7 +1570,7 @@ void nir_print_instr(const nir_instr *instr, FILE *fp);
#ifdef DEBUG
void nir_validate_shader(nir_shader *shader);
#else
-static inline void nir_validate_shader(nir_shader *shader) { }
+static inline void nir_validate_shader(nir_shader *shader) { (void) shader; }
#endif /* DEBUG */
void nir_calc_dominance_impl(nir_function_impl *impl);
@@ -1596,14 +1616,18 @@ void nir_lower_alu_to_scalar(nir_shader *shader);
void nir_lower_phis_to_scalar(nir_shader *shader);
void nir_lower_samplers(nir_shader *shader,
- struct gl_shader_program *shader_program,
- struct gl_program *prog);
+ const struct gl_shader_program *shader_program,
+ gl_shader_stage stage);
void nir_lower_system_values(nir_shader *shader);
+void nir_lower_tex_projector(nir_shader *shader);
+void nir_lower_idiv(nir_shader *shader);
void nir_lower_atomics(nir_shader *shader);
void nir_lower_to_source_mods(nir_shader *shader);
+void nir_normalize_cubemap_coords(nir_shader *shader);
+
void nir_live_variables_impl(nir_function_impl *impl);
bool nir_ssa_defs_interfere(nir_ssa_def *a, nir_ssa_def *b);
@@ -1612,6 +1636,7 @@ void nir_convert_to_ssa(nir_shader *shader);
void nir_convert_from_ssa(nir_shader *shader);
bool nir_opt_algebraic(nir_shader *shader);
+bool nir_opt_algebraic_late(nir_shader *shader);
bool nir_opt_constant_folding(nir_shader *shader);
bool nir_opt_global_to_local(nir_shader *shader);
@@ -1631,6 +1656,8 @@ bool nir_opt_peephole_ffma(nir_shader *shader);
bool nir_opt_remove_phis(nir_shader *shader);
+void nir_sweep(nir_shader *shader);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/mesalib/src/glsl/nir/nir_algebraic.py b/mesalib/src/glsl/nir/nir_algebraic.py
index afab1a008..bbf4f08ef 100644
--- a/mesalib/src/glsl/nir/nir_algebraic.py
+++ b/mesalib/src/glsl/nir/nir_algebraic.py
@@ -181,12 +181,23 @@ _algebraic_pass_template = mako.template.Template("""
#include "nir.h"
#include "nir_search.h"
+#ifndef NIR_OPT_ALGEBRAIC_STRUCT_DEFS
+#define NIR_OPT_ALGEBRAIC_STRUCT_DEFS
+
struct transform {
const nir_search_expression *search;
const nir_search_value *replace;
unsigned condition_offset;
};
+struct opt_state {
+ void *mem_ctx;
+ bool progress;
+ const bool *condition_flags;
+};
+
+#endif
+
% for (opcode, xform_list) in xform_dict.iteritems():
% for xform in xform_list:
${xform.search.render()}
@@ -200,12 +211,6 @@ static const struct transform ${pass_name}_${opcode}_xforms[] = {
};
% endfor
-struct opt_state {
- void *mem_ctx;
- bool progress;
- const bool *condition_flags;
-};
-
static bool
${pass_name}_block(nir_block *block, void *void_state)
{
diff --git a/mesalib/src/glsl/nir/nir_builder.h b/mesalib/src/glsl/nir/nir_builder.h
index 7c4f7fd96..d1419ee21 100644
--- a/mesalib/src/glsl/nir/nir_builder.h
+++ b/mesalib/src/glsl/nir/nir_builder.h
@@ -28,6 +28,9 @@ struct exec_list;
typedef struct nir_builder {
struct exec_list *cf_node_list;
+ nir_instr *before_instr;
+ nir_instr *after_instr;
+
nir_shader *shader;
nir_function_impl *impl;
} nir_builder;
@@ -45,8 +48,75 @@ nir_builder_insert_after_cf_list(nir_builder *build,
struct exec_list *cf_node_list)
{
build->cf_node_list = cf_node_list;
+ build->before_instr = NULL;
+ build->after_instr = NULL;
+}
+
+static inline void
+nir_builder_insert_before_instr(nir_builder *build, nir_instr *before_instr)
+{
+ build->cf_node_list = NULL;
+ build->before_instr = before_instr;
+ build->after_instr = NULL;
}
+static inline void
+nir_builder_insert_after_instr(nir_builder *build, nir_instr *after_instr)
+{
+ build->cf_node_list = NULL;
+ build->before_instr = NULL;
+ build->after_instr = after_instr;
+}
+
+static inline void
+nir_builder_instr_insert(nir_builder *build, nir_instr *instr)
+{
+ if (build->cf_node_list) {
+ nir_instr_insert_after_cf_list(build->cf_node_list, instr);
+ } else if (build->before_instr) {
+ nir_instr_insert_before(build->before_instr, instr);
+ } else {
+ assert(build->after_instr);
+ nir_instr_insert_after(build->after_instr, instr);
+ build->after_instr = instr;
+ }
+}
+
+static inline nir_ssa_def *
+nir_build_imm(nir_builder *build, unsigned num_components, nir_const_value value)
+{
+ nir_load_const_instr *load_const =
+ nir_load_const_instr_create(build->shader, num_components);
+ if (!load_const)
+ return NULL;
+
+ load_const->value = value;
+
+ nir_builder_instr_insert(build, &load_const->instr);
+
+ return &load_const->def;
+}
+
+static inline nir_ssa_def *
+nir_imm_float(nir_builder *build, float x)
+{
+ nir_const_value v = { { .f = {x, 0, 0, 0} } };
+ return nir_build_imm(build, 1, v);
+}
+
+static inline nir_ssa_def *
+nir_imm_vec4(nir_builder *build, float x, float y, float z, float w)
+{
+ nir_const_value v = { { .f = {x, y, z, w} } };
+ return nir_build_imm(build, 4, v);
+}
+
+static inline nir_ssa_def *
+nir_imm_int(nir_builder *build, int x)
+{
+ nir_const_value v = { { .i = {x, 0, 0, 0} } };
+ return nir_build_imm(build, 1, v);
+}
static inline nir_ssa_def *
nir_build_alu(nir_builder *build, nir_op op, nir_ssa_def *src0,
@@ -90,7 +160,7 @@ nir_build_alu(nir_builder *build, nir_op op, nir_ssa_def *src0,
nir_ssa_dest_init(&instr->instr, &instr->dest.dest, num_components, NULL);
instr->dest.write_mask = (1 << num_components) - 1;
- nir_instr_insert_after_cf_list(build->cf_node_list, &instr->instr);
+ nir_builder_instr_insert(build, &instr->instr);
return &instr->dest.dest.ssa;
}
@@ -127,4 +197,67 @@ nir_##op(nir_builder *build, nir_ssa_def *src0, \
#include "nir_builder_opcodes.h"
+/**
+ * Similar to nir_fmov, but takes a nir_alu_src instead of a nir_ssa_def.
+ */
+static inline nir_ssa_def *
+nir_fmov_alu(nir_builder *build, nir_alu_src src, unsigned num_components)
+{
+ nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_fmov);
+ nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components, NULL);
+ mov->dest.write_mask = (1 << num_components) - 1;
+ mov->src[0] = src;
+ nir_builder_instr_insert(build, &mov->instr);
+
+ return &mov->dest.dest.ssa;
+}
+
+static inline nir_ssa_def *
+nir_imov_alu(nir_builder *build, nir_alu_src src, unsigned num_components)
+{
+ nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_imov);
+ nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components, NULL);
+ mov->dest.write_mask = (1 << num_components) - 1;
+ mov->src[0] = src;
+ nir_builder_instr_insert(build, &mov->instr);
+
+ return &mov->dest.dest.ssa;
+}
+
+/**
+ * Construct an fmov or imov that reswizzles the source's components.
+ */
+static inline nir_ssa_def *
+nir_swizzle(nir_builder *build, nir_ssa_def *src, unsigned swiz[4],
+ unsigned num_components, bool use_fmov)
+{
+ nir_alu_src alu_src;
+ memset(&alu_src, 0, sizeof(alu_src));
+ alu_src.src = nir_src_for_ssa(src);
+ for (int i = 0; i < 4; i++)
+ alu_src.swizzle[i] = swiz[i];
+
+ return use_fmov ? nir_fmov_alu(build, alu_src, num_components) :
+ nir_imov_alu(build, alu_src, num_components);
+}
+
+/**
+ * Turns a nir_src into a nir_ssa_def * so it can be passed to
+ * nir_build_alu()-based builder calls.
+ */
+static inline nir_ssa_def *
+nir_ssa_for_src(nir_builder *build, nir_src src, int num_components)
+{
+ if (src.is_ssa && src.ssa->num_components == num_components)
+ return src.ssa;
+
+ nir_alu_src alu;
+ memset(&alu, 0, sizeof(alu));
+ alu.src = src;
+ for (int j = 0; j < 4; j++)
+ alu.swizzle[j] = j;
+
+ return nir_imov_alu(build, alu, num_components);
+}
+
#endif /* NIR_BUILDER_H */
diff --git a/mesalib/src/glsl/nir/nir_from_ssa.c b/mesalib/src/glsl/nir/nir_from_ssa.c
index c3090fb06..184698abd 100644
--- a/mesalib/src/glsl/nir/nir_from_ssa.c
+++ b/mesalib/src/glsl/nir/nir_from_ssa.c
@@ -509,12 +509,13 @@ get_register_for_ssa_def(nir_ssa_def *def, struct from_ssa_state *state)
reg->num_components = def->num_components;
reg->num_array_elems = 0;
- /* This register comes from an SSA definition that was not part of a
- * phi-web. Therefore, we know it has a single unique definition
- * that dominates all of its uses. Therefore, we can copy the
+ /* This register comes from an SSA definition that is defined and not
+ * part of a phi-web. Therefore, we know it has a single unique
+ * definition that dominates all of its uses; we can copy the
* parent_instr from the SSA def safely.
*/
- reg->parent_instr = def->parent_instr;
+ if (def->parent_instr->type != nir_instr_type_ssa_undef)
+ reg->parent_instr = def->parent_instr;
_mesa_hash_table_insert(state->ssa_table, def, reg);
return reg;
diff --git a/mesalib/src/glsl/nir/nir_lower_idiv.c b/mesalib/src/glsl/nir/nir_lower_idiv.c
new file mode 100644
index 000000000..7b6803207
--- /dev/null
+++ b/mesalib/src/glsl/nir/nir_lower_idiv.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright © 2015 Red Hat
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <robclark@freedesktop.org>
+ */
+
+#include "nir.h"
+#include "nir_builder.h"
+
+/* Lowers idiv/udiv/umod
+ * Based on NV50LegalizeSSA::handleDIV()
+ *
+ * Note that this is probably not enough precision for compute shaders.
+ * Perhaps we want a second higher precision (looping) version of this?
+ * Or perhaps we assume if you can do compute shaders you can also
+ * branch out to a pre-optimized shader library routine..
+ */
+
+static void
+convert_instr(nir_builder *bld, nir_alu_instr *alu)
+{
+ nir_ssa_def *numer, *denom, *af, *bf, *a, *b, *q, *r;
+ nir_op op = alu->op;
+ bool is_signed;
+
+ if ((op != nir_op_idiv) &&
+ (op != nir_op_udiv) &&
+ (op != nir_op_umod))
+ return;
+
+ is_signed = (op == nir_op_idiv);
+
+ nir_builder_insert_before_instr(bld, &alu->instr);
+
+ numer = nir_ssa_for_src(bld, alu->src[0].src,
+ nir_ssa_alu_instr_src_components(alu, 0));
+ denom = nir_ssa_for_src(bld, alu->src[1].src,
+ nir_ssa_alu_instr_src_components(alu, 1));
+
+ if (is_signed) {
+ af = nir_i2f(bld, numer);
+ bf = nir_i2f(bld, denom);
+ af = nir_fabs(bld, af);
+ bf = nir_fabs(bld, bf);
+ a = nir_iabs(bld, numer);
+ b = nir_iabs(bld, denom);
+ } else {
+ af = nir_u2f(bld, numer);
+ bf = nir_u2f(bld, denom);
+ a = numer;
+ b = denom;
+ }
+
+ /* get first result: */
+ bf = nir_frcp(bld, bf);
+ bf = nir_isub(bld, bf, nir_imm_int(bld, 2)); /* yes, really */
+ q = nir_fmul(bld, af, bf);
+
+ if (is_signed) {
+ q = nir_f2i(bld, q);
+ } else {
+ q = nir_f2u(bld, q);
+ }
+
+ /* get error of first result: */
+ r = nir_imul(bld, q, b);
+ r = nir_isub(bld, a, r);
+ r = nir_u2f(bld, r);
+ r = nir_fmul(bld, r, bf);
+ r = nir_f2u(bld, r);
+
+ /* add quotients: */
+ q = nir_iadd(bld, q, r);
+
+ /* correction: if modulus >= divisor, add 1 */
+ r = nir_imul(bld, q, b);
+ r = nir_isub(bld, a, r);
+
+ r = nir_ige(bld, r, b);
+ r = nir_b2i(bld, r);
+
+ q = nir_iadd(bld, q, r);
+ if (is_signed) {
+ /* fix the sign: */
+ r = nir_ixor(bld, numer, denom);
+ r = nir_ushr(bld, r, nir_imm_int(bld, 31));
+ r = nir_i2b(bld, r);
+ b = nir_ineg(bld, q);
+ q = nir_bcsel(bld, r, b, q);
+ }
+
+ if (op == nir_op_umod) {
+ /* division result in q */
+ r = nir_imul(bld, q, b);
+ q = nir_isub(bld, a, r);
+ }
+
+ assert(alu->dest.dest.is_ssa);
+ nir_ssa_def_rewrite_uses(&alu->dest.dest.ssa,
+ nir_src_for_ssa(q),
+ ralloc_parent(alu));
+}
+
+static bool
+convert_block(nir_block *block, void *state)
+{
+ nir_builder *b = state;
+
+ nir_foreach_instr_safe(block, instr) {
+ if (instr->type == nir_instr_type_alu)
+ convert_instr(b, nir_instr_as_alu(instr));
+ }
+
+ return true;
+}
+
+static void
+convert_impl(nir_function_impl *impl)
+{
+ nir_builder b;
+ nir_builder_init(&b, impl);
+
+ nir_foreach_block(impl, convert_block, &b);
+ nir_metadata_preserve(impl, nir_metadata_block_index |
+ nir_metadata_dominance);
+}
+
+void
+nir_lower_idiv(nir_shader *shader)
+{
+ nir_foreach_overload(shader, overload) {
+ if (overload->impl)
+ convert_impl(overload->impl);
+ }
+}
diff --git a/mesalib/src/glsl/nir/nir_lower_phis_to_scalar.c b/mesalib/src/glsl/nir/nir_lower_phis_to_scalar.c
index 7cd93ea0a..4bdb80072 100644
--- a/mesalib/src/glsl/nir/nir_lower_phis_to_scalar.c
+++ b/mesalib/src/glsl/nir/nir_lower_phis_to_scalar.c
@@ -223,7 +223,7 @@ lower_phis_to_scalar_block(nir_block *block, void *void_state)
else
nir_instr_insert_after_block(src->pred, &mov->instr);
- nir_phi_src *new_src = ralloc(state->mem_ctx, nir_phi_src);
+ nir_phi_src *new_src = ralloc(new_phi, nir_phi_src);
new_src->pred = src->pred;
new_src->src = nir_src_for_ssa(&mov->dest.dest.ssa);
diff --git a/mesalib/src/glsl/nir/nir_lower_samplers.cpp b/mesalib/src/glsl/nir/nir_lower_samplers.cpp
index 3015dbd09..cf8ab8325 100644
--- a/mesalib/src/glsl/nir/nir_lower_samplers.cpp
+++ b/mesalib/src/glsl/nir/nir_lower_samplers.cpp
@@ -36,33 +36,26 @@ extern "C" {
}
static unsigned
-get_sampler_index(struct gl_shader_program *shader_program, const char *name,
- const struct gl_program *prog)
+get_sampler_index(const struct gl_shader_program *shader_program,
+ gl_shader_stage stage, const char *name)
{
- GLuint shader = _mesa_program_enum_to_shader_stage(prog->Target);
-
unsigned location;
if (!shader_program->UniformHash->get(location, name)) {
- linker_error(shader_program,
- "failed to find sampler named %s.\n", name);
+ assert(!"failed to find sampler");
return 0;
}
- if (!shader_program->UniformStorage[location].sampler[shader].active) {
- assert(0 && "cannot return a sampler");
- linker_error(shader_program,
- "cannot return a sampler named %s, because it is not "
- "used in this shader stage. This is a driver bug.\n",
- name);
+ if (!shader_program->UniformStorage[location].sampler[stage].active) {
+ assert(!"cannot return a sampler");
return 0;
}
- return shader_program->UniformStorage[location].sampler[shader].index;
+ return shader_program->UniformStorage[location].sampler[stage].index;
}
static void
-lower_sampler(nir_tex_instr *instr, struct gl_shader_program *shader_program,
- const struct gl_program *prog, void *mem_ctx)
+lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_program,
+ gl_shader_stage stage, void *mem_ctx)
{
if (instr->sampler == NULL)
return;
@@ -90,7 +83,7 @@ lower_sampler(nir_tex_instr *instr, struct gl_shader_program *shader_program,
ralloc_asprintf_append(&name, "[%u]", deref_array->base_offset);
break;
case nir_deref_array_type_indirect: {
- instr->src = reralloc(mem_ctx, instr->src, nir_tex_src,
+ instr->src = reralloc(instr, instr->src, nir_tex_src,
instr->num_srcs + 1);
memset(&instr->src[instr->num_srcs], 0, sizeof *instr->src);
instr->src[instr->num_srcs].src_type = nir_tex_src_sampler_offset;
@@ -133,15 +126,15 @@ lower_sampler(nir_tex_instr *instr, struct gl_shader_program *shader_program,
}
}
- instr->sampler_index += get_sampler_index(shader_program, name, prog);
+ instr->sampler_index += get_sampler_index(shader_program, stage, name);
instr->sampler = NULL;
}
typedef struct {
void *mem_ctx;
- struct gl_shader_program *shader_program;
- struct gl_program *prog;
+ const struct gl_shader_program *shader_program;
+ gl_shader_stage stage;
} lower_state;
static bool
@@ -152,7 +145,7 @@ lower_block_cb(nir_block *block, void *_state)
nir_foreach_instr(block, instr) {
if (instr->type == nir_instr_type_tex) {
nir_tex_instr *tex_instr = nir_instr_as_tex(instr);
- lower_sampler(tex_instr, state->shader_program, state->prog,
+ lower_sampler(tex_instr, state->shader_program, state->stage,
state->mem_ctx);
}
}
@@ -161,24 +154,24 @@ lower_block_cb(nir_block *block, void *_state)
}
static void
-lower_impl(nir_function_impl *impl, struct gl_shader_program *shader_program,
- struct gl_program *prog)
+lower_impl(nir_function_impl *impl, const struct gl_shader_program *shader_program,
+ gl_shader_stage stage)
{
lower_state state;
state.mem_ctx = ralloc_parent(impl);
state.shader_program = shader_program;
- state.prog = prog;
+ state.stage = stage;
nir_foreach_block(impl, lower_block_cb, &state);
}
extern "C" void
-nir_lower_samplers(nir_shader *shader, struct gl_shader_program *shader_program,
- struct gl_program *prog)
+nir_lower_samplers(nir_shader *shader, const struct gl_shader_program *shader_program,
+ gl_shader_stage stage)
{
nir_foreach_overload(shader, overload) {
if (overload->impl)
- lower_impl(overload->impl, shader_program, prog);
+ lower_impl(overload->impl, shader_program, stage);
}
}
diff --git a/mesalib/src/glsl/nir/nir_lower_tex_projector.c b/mesalib/src/glsl/nir/nir_lower_tex_projector.c
new file mode 100644
index 000000000..6b0e9c340
--- /dev/null
+++ b/mesalib/src/glsl/nir/nir_lower_tex_projector.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright © 2015 Broadcom
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*
+ * This lowering pass converts the coordinate division for texture projection
+ * to be done in ALU instructions instead of asking the texture operation to
+ * do so.
+ */
+
+#include "nir.h"
+#include "nir_builder.h"
+
+static nir_ssa_def *
+channel(nir_builder *b, nir_ssa_def *def, int c)
+{
+ return nir_swizzle(b, def, (unsigned[4]){c, c, c, c}, 1, false);
+}
+
+static bool
+nir_lower_tex_projector_block(nir_block *block, void *void_state)
+{
+ nir_builder *b = void_state;
+
+ nir_foreach_instr_safe(block, instr) {
+ if (instr->type != nir_instr_type_tex)
+ continue;
+
+ nir_tex_instr *tex = nir_instr_as_tex(instr);
+ nir_builder_insert_before_instr(b, &tex->instr);
+
+ /* Find the projector in the srcs list, if present. */
+ int proj_index;
+ for (proj_index = 0; proj_index < tex->num_srcs; proj_index++) {
+ if (tex->src[proj_index].src_type == nir_tex_src_projector)
+ break;
+ }
+ if (proj_index == tex->num_srcs)
+ continue;
+ nir_ssa_def *inv_proj =
+ nir_frcp(b, nir_ssa_for_src(b, tex->src[proj_index].src, 1));
+
+ /* Walk through the sources projecting the arguments. */
+ for (int i = 0; i < tex->num_srcs; i++) {
+ switch (tex->src[i].src_type) {
+ case nir_tex_src_coord:
+ case nir_tex_src_comparitor:
+ break;
+ default:
+ continue;
+ }
+ nir_ssa_def *unprojected =
+ nir_ssa_for_src(b, tex->src[i].src, nir_tex_instr_src_size(tex, i));
+ nir_ssa_def *projected = nir_fmul(b, unprojected, inv_proj);
+
+ /* Array indices don't get projected, so make an new vector with the
+ * coordinate's array index untouched.
+ */
+ if (tex->is_array && tex->src[i].src_type == nir_tex_src_coord) {
+ switch (tex->coord_components) {
+ case 4:
+ projected = nir_vec4(b,
+ channel(b, projected, 0),
+ channel(b, projected, 1),
+ channel(b, projected, 2),
+ channel(b, unprojected, 3));
+ break;
+ case 3:
+ projected = nir_vec3(b,
+ channel(b, projected, 0),
+ channel(b, projected, 1),
+ channel(b, unprojected, 2));
+ break;
+ case 2:
+ projected = nir_vec2(b,
+ channel(b, projected, 0),
+ channel(b, unprojected, 1));
+ break;
+ default:
+ unreachable("bad texture coord count for array");
+ break;
+ }
+ }
+
+ nir_instr_rewrite_src(&tex->instr,
+ &tex->src[i].src,
+ nir_src_for_ssa(projected));
+ }
+
+ /* Now move the later tex sources down the array so that the projector
+ * disappears.
+ */
+ nir_src dead;
+ memset(&dead, 0, sizeof dead);
+ nir_instr_rewrite_src(&tex->instr, &tex->src[proj_index].src, dead);
+ memmove(&tex->src[proj_index],
+ &tex->src[proj_index + 1],
+ (tex->num_srcs - proj_index) * sizeof(*tex->src));
+ tex->num_srcs--;
+ }
+
+ return true;
+}
+
+static void
+nir_lower_tex_projector_impl(nir_function_impl *impl)
+{
+ nir_builder b;
+ nir_builder_init(&b, impl);
+
+ nir_foreach_block(impl, nir_lower_tex_projector_block, &b);
+
+ nir_metadata_preserve(impl, nir_metadata_block_index |
+ nir_metadata_dominance);
+}
+
+void
+nir_lower_tex_projector(nir_shader *shader)
+{
+ nir_foreach_overload(shader, overload) {
+ if (overload->impl)
+ nir_lower_tex_projector_impl(overload->impl);
+ }
+}
diff --git a/mesalib/src/glsl/nir/nir_lower_var_copies.c b/mesalib/src/glsl/nir/nir_lower_var_copies.c
index 85ebb281c..58389a7c7 100644
--- a/mesalib/src/glsl/nir/nir_lower_var_copies.c
+++ b/mesalib/src/glsl/nir/nir_lower_var_copies.c
@@ -148,13 +148,10 @@ emit_copy_load_store(nir_intrinsic_instr *copy_instr,
unsigned num_components = glsl_get_vector_elements(src_tail->type);
- nir_deref *src_deref = nir_copy_deref(mem_ctx, &src_head->deref);
- nir_deref *dest_deref = nir_copy_deref(mem_ctx, &dest_head->deref);
-
nir_intrinsic_instr *load =
nir_intrinsic_instr_create(mem_ctx, nir_intrinsic_load_var);
load->num_components = num_components;
- load->variables[0] = nir_deref_as_var(src_deref);
+ load->variables[0] = nir_deref_as_var(nir_copy_deref(load, &src_head->deref));
nir_ssa_dest_init(&load->instr, &load->dest, num_components, NULL);
nir_instr_insert_before(&copy_instr->instr, &load->instr);
@@ -162,7 +159,8 @@ emit_copy_load_store(nir_intrinsic_instr *copy_instr,
nir_intrinsic_instr *store =
nir_intrinsic_instr_create(mem_ctx, nir_intrinsic_store_var);
store->num_components = num_components;
- store->variables[0] = nir_deref_as_var(dest_deref);
+ store->variables[0] = nir_deref_as_var(nir_copy_deref(store, &dest_head->deref));
+
store->src[0].is_ssa = true;
store->src[0].ssa = &load->dest.ssa;
diff --git a/mesalib/src/glsl/nir/nir_lower_vars_to_ssa.c b/mesalib/src/glsl/nir/nir_lower_vars_to_ssa.c
index 86e6ab416..2ca74d71b 100644
--- a/mesalib/src/glsl/nir/nir_lower_vars_to_ssa.c
+++ b/mesalib/src/glsl/nir/nir_lower_vars_to_ssa.c
@@ -642,7 +642,7 @@ add_phi_sources(nir_block *block, nir_block *pred,
struct deref_node *node = entry->data;
- nir_phi_src *src = ralloc(state->mem_ctx, nir_phi_src);
+ nir_phi_src *src = ralloc(phi, nir_phi_src);
src->pred = pred;
src->src.is_ssa = true;
src->src.ssa = get_ssa_def_for_block(node, pred, state);
diff --git a/mesalib/src/glsl/nir/nir_normalize_cubemap_coords.c b/mesalib/src/glsl/nir/nir_normalize_cubemap_coords.c
new file mode 100644
index 000000000..0da8447ac
--- /dev/null
+++ b/mesalib/src/glsl/nir/nir_normalize_cubemap_coords.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jason Ekstrand <jason@jlekstrand.net>
+ */
+
+#include "nir.h"
+#include "nir_builder.h"
+
+/**
+ * This file implements a NIR lowering pass to perform the normalization of
+ * the cubemap coordinates to have the largest magnitude component be -1.0
+ * or 1.0. This is based on the old GLSL IR based pass by Eric.
+ */
+
+static nir_ssa_def *
+channel(nir_builder *b, nir_ssa_def *def, int c)
+{
+ return nir_swizzle(b, def, (unsigned[4]){c, c, c, c}, 1, false);
+}
+
+static bool
+normalize_cubemap_coords_block(nir_block *block, void *void_state)
+{
+ nir_builder *b = void_state;
+
+ nir_foreach_instr(block, instr) {
+ if (instr->type != nir_instr_type_tex)
+ continue;
+
+ nir_tex_instr *tex = nir_instr_as_tex(instr);
+ if (tex->sampler_dim != GLSL_SAMPLER_DIM_CUBE)
+ continue;
+
+ nir_builder_insert_before_instr(b, &tex->instr);
+
+ for (unsigned i = 0; i < tex->num_srcs; i++) {
+ if (tex->src[i].src_type != nir_tex_src_coord)
+ continue;
+
+ nir_ssa_def *orig_coord =
+ nir_ssa_for_src(b, tex->src[i].src, nir_tex_instr_src_size(tex, i));
+ assert(orig_coord->num_components >= 3);
+
+ nir_ssa_def *abs = nir_fabs(b, orig_coord);
+ nir_ssa_def *norm = nir_fmax(b, channel(b, abs, 0),
+ nir_fmax(b, channel(b, abs, 1),
+ channel(b, abs, 2)));
+
+ nir_ssa_def *normalized = nir_fmul(b, orig_coord, nir_frcp(b, norm));
+
+ /* Array indices don't have to be normalized, so make a new vector
+ * with the coordinate's array index untouched.
+ */
+ if (tex->coord_components == 4) {
+ normalized = nir_vec4(b,
+ channel(b, normalized, 0),
+ channel(b, normalized, 1),
+ channel(b, normalized, 2),
+ channel(b, orig_coord, 3));
+ }
+
+ nir_instr_rewrite_src(&tex->instr,
+ &tex->src[i].src,
+ nir_src_for_ssa(normalized));
+ }
+ }
+
+ return true;
+}
+
+static void
+normalize_cubemap_coords_impl(nir_function_impl *impl)
+{
+ nir_builder b;
+ nir_builder_init(&b, impl);
+
+ nir_foreach_block(impl, normalize_cubemap_coords_block, &b);
+
+ nir_metadata_preserve(impl, nir_metadata_block_index |
+ nir_metadata_dominance);
+}
+
+void
+nir_normalize_cubemap_coords(nir_shader *shader)
+{
+ nir_foreach_overload(shader, overload)
+ if (overload->impl)
+ normalize_cubemap_coords_impl(overload->impl);
+}
diff --git a/mesalib/src/glsl/nir/nir_opcodes.py b/mesalib/src/glsl/nir/nir_opcodes.py
index 062cd628b..264806f5d 100644
--- a/mesalib/src/glsl/nir/nir_opcodes.py
+++ b/mesalib/src/glsl/nir/nir_opcodes.py
@@ -161,12 +161,12 @@ unop_convert("f2i", tfloat, tint, "src0") # Float-to-integer conversion.
unop_convert("f2u", tfloat, tunsigned, "src0") # Float-to-unsigned conversion
unop_convert("i2f", tint, tfloat, "src0") # Integer-to-float conversion.
# Float-to-boolean conversion
-unop_convert("f2b", tfloat, tbool, "src0 == 0.0f")
+unop_convert("f2b", tfloat, tbool, "src0 != 0.0f")
# Boolean-to-float conversion
unop_convert("b2f", tbool, tfloat, "src0 ? 1.0f : 0.0f")
# Int-to-boolean conversion
-unop_convert("i2b", tint, tbool, "src0 == 0")
-unop_convert("b2i", tbool, tint, "src0 ? 0 : -1") # Boolean-to-int conversion
+unop_convert("i2b", tint, tbool, "src0 != 0")
+unop_convert("b2i", tbool, tint, "src0 ? 1 : 0") # Boolean-to-int conversion
unop_convert("u2f", tunsigned, tfloat, "src0") #Unsigned-to-float conversion.
unop_reduce("bany", 1, tbool, tbool, "{src}", "{src0} || {src1}", "{src}")
@@ -191,8 +191,6 @@ unop("fround_even", tfloat, "_mesa_roundevenf(src0)")
unop("fsin", tfloat, "sinf(src0)")
unop("fcos", tfloat, "cosf(src0)")
-unop("fsin_reduced", tfloat, "sinf(src0)")
-unop("fcos_reduced", tfloat, "cosf(src0)")
# Partial derivatives.
diff --git a/mesalib/src/glsl/nir/nir_opt_algebraic.py b/mesalib/src/glsl/nir/nir_opt_algebraic.py
index ef855aa77..cdb19241c 100644
--- a/mesalib/src/glsl/nir/nir_opt_algebraic.py
+++ b/mesalib/src/glsl/nir/nir_opt_algebraic.py
@@ -75,6 +75,9 @@ optimizations = [
(('flrp', a, b, 1.0), b),
(('flrp', a, a, b), a),
(('flrp', 0.0, a, b), ('fmul', a, b)),
+ (('flrp', a, b, c), ('fadd', ('fmul', c, ('fsub', b, a)), a), 'options->lower_flrp'),
+ (('fadd', ('fmul', a, ('fadd', 1.0, ('fneg', c))), ('fmul', b, c)), ('flrp', a, b, c), '!options->lower_flrp'),
+ (('fadd', a, ('fmul', c, ('fadd', b, ('fneg', a)))), ('flrp', a, b, c), '!options->lower_flrp'),
(('ffma', a, b, c), ('fadd', ('fmul', a, b), c), 'options->lower_ffma'),
(('fadd', ('fmul', a, b), c), ('ffma', a, b, c), '!options->lower_ffma'),
# Comparison simplifications
@@ -82,10 +85,6 @@ optimizations = [
(('inot', ('fge', a, b)), ('flt', a, b)),
(('inot', ('ilt', a, b)), ('ige', a, b)),
(('inot', ('ige', a, b)), ('ilt', a, b)),
- (('flt', ('fadd', a, b), 0.0), ('flt', a, ('fneg', b))),
- (('fge', ('fadd', a, b), 0.0), ('fge', a, ('fneg', b))),
- (('feq', ('fadd', a, b), 0.0), ('feq', a, ('fneg', b))),
- (('fne', ('fadd', a, b), 0.0), ('fne', a, ('fneg', b))),
(('fge', ('fneg', ('fabs', a)), 0.0), ('feq', a, 0.0)),
(('bcsel', ('flt', a, b), a, b), ('fmin', a, b)),
(('bcsel', ('flt', a, b), b, a), ('fmax', a, b)),
@@ -95,6 +94,18 @@ optimizations = [
(('fsat', a), ('fmin', ('fmax', a, 0.0), 1.0), 'options->lower_fsat'),
(('fsat', ('fsat', a)), ('fsat', a)),
(('fmin', ('fmax', ('fmin', ('fmax', a, 0.0), 1.0), 0.0), 1.0), ('fmin', ('fmax', a, 0.0), 1.0)),
+ (('ior', ('flt', a, b), ('flt', a, c)), ('flt', a, ('fmax', b, c))),
+ (('ior', ('fge', a, b), ('fge', a, c)), ('fge', a, ('fmin', b, c))),
+ (('slt', a, b), ('b2f', ('flt', a, b)), 'options->lower_scmp'),
+ (('sge', a, b), ('b2f', ('fge', a, b)), 'options->lower_scmp'),
+ (('seq', a, b), ('b2f', ('feq', a, b)), 'options->lower_scmp'),
+ (('sne', a, b), ('b2f', ('fne', a, b)), 'options->lower_scmp'),
+ # Emulating booleans
+ (('fmul', ('b2f', a), ('b2f', b)), ('b2f', ('iand', a, b))),
+ (('fsat', ('fadd', ('b2f', a), ('b2f', b))), ('b2f', ('ior', a, b))),
+ (('iand', 'a@bool', 1.0), ('b2f', a)),
+ (('flt', ('fneg', ('b2f', a)), 0), a), # Generated by TGSI KILL_IF.
+ (('flt', ('fsub', 0.0, ('b2f', a)), 0), a), # Generated by TGSI KILL_IF.
# Comparison with the same args. Note that these are not done for
# the float versions because NaN always returns false on float
# inequalities.
@@ -122,7 +133,7 @@ optimizations = [
(('ishr', 0, a), 0),
(('ishr', a, 0), a),
(('ushr', 0, a), 0),
- (('ushr', a, 0), 0),
+ (('ushr', a, 0), a),
# Exponential/logarithmic identities
(('fexp2', ('flog2', a)), a), # 2^lg2(a) = a
(('fexp', ('flog', a)), a), # e^ln(a) = a
@@ -134,6 +145,26 @@ optimizations = [
(('fpow', a, 1.0), a),
(('fpow', a, 2.0), ('fmul', a, a)),
(('fpow', 2.0, a), ('fexp2', a)),
+ (('fsqrt', ('fexp2', a)), ('fexp2', ('fmul', 0.5, a))),
+ (('fsqrt', ('fexp', a)), ('fexp', ('fmul', 0.5, a))),
+ (('frcp', ('fexp2', a)), ('fexp2', ('fneg', a))),
+ (('frcp', ('fexp', a)), ('fexp', ('fneg', a))),
+ (('frsq', ('fexp2', a)), ('fexp2', ('fmul', -0.5, a))),
+ (('frsq', ('fexp', a)), ('fexp', ('fmul', -0.5, a))),
+ (('flog2', ('fsqrt', a)), ('fmul', 0.5, ('flog2', a))),
+ (('flog', ('fsqrt', a)), ('fmul', 0.5, ('flog', a))),
+ (('flog2', ('frcp', a)), ('fneg', ('flog2', a))),
+ (('flog', ('frcp', a)), ('fneg', ('flog', a))),
+ (('flog2', ('frsq', a)), ('fmul', -0.5, ('flog2', a))),
+ (('flog', ('frsq', a)), ('fmul', -0.5, ('flog', a))),
+ (('flog2', ('fpow', a, b)), ('fmul', b, ('flog2', a))),
+ (('flog', ('fpow', a, b)), ('fmul', b, ('flog', a))),
+ (('fadd', ('flog2', a), ('flog2', b)), ('flog2', ('fmul', a, b))),
+ (('fadd', ('flog', a), ('flog', b)), ('flog', ('fmul', a, b))),
+ (('fadd', ('flog2', a), ('fneg', ('flog2', b))), ('flog2', ('fdiv', a, b))),
+ (('fadd', ('flog', a), ('fneg', ('flog', b))), ('flog', ('fdiv', a, b))),
+ (('fmul', ('fexp2', a), ('fexp2', b)), ('fexp2', ('fadd', a, b))),
+ (('fmul', ('fexp', a), ('fexp', b)), ('fexp', ('fadd', a, b))),
# Division and reciprocal
(('fdiv', 1.0, a), ('frcp', a)),
(('frcp', ('frcp', a)), a),
@@ -154,18 +185,21 @@ optimizations = [
(('bcsel', a, b, b), b),
(('fcsel', a, b, b), b),
+ # Conversions
+ (('f2i', ('ftrunc', a)), ('f2i', a)),
+ (('f2u', ('ftrunc', a)), ('f2u', a)),
+
# Subtracts
(('fsub', a, ('fsub', 0.0, b)), ('fadd', a, b)),
(('isub', a, ('isub', 0, b)), ('iadd', a, b)),
+ (('fsub', a, b), ('fadd', a, ('fneg', b)), 'options->lower_sub'),
+ (('isub', a, b), ('iadd', a, ('ineg', b)), 'options->lower_sub'),
(('fneg', a), ('fsub', 0.0, a), 'options->lower_negate'),
(('ineg', a), ('isub', 0, a), 'options->lower_negate'),
(('fadd', a, ('fsub', 0.0, b)), ('fsub', a, b)),
(('iadd', a, ('isub', 0, b)), ('isub', a, b)),
(('fabs', ('fsub', 0.0, a)), ('fabs', a)),
(('iabs', ('isub', 0, a)), ('iabs', a)),
-
-# This one may not be exact
- (('feq', ('fadd', a, b), 0.0), ('feq', a, ('fneg', b))),
]
# Add optimizations to handle the case where the result of a ternary is
@@ -189,4 +223,17 @@ for op in ['flt', 'fge', 'feq', 'fne',
('bcsel', 'a', (op, 'd', 'b'), (op, 'd', 'c'))),
]
+# This section contains "late" optimizations that should be run after the
+# regular optimizations have finished. Optimizations should go here if
+# they help code generation but do not necessarily produce code that is
+# more easily optimizable.
+late_optimizations = [
+ (('flt', ('fadd', a, b), 0.0), ('flt', a, ('fneg', b))),
+ (('fge', ('fadd', a, b), 0.0), ('fge', a, ('fneg', b))),
+ (('feq', ('fadd', a, b), 0.0), ('feq', a, ('fneg', b))),
+ (('fne', ('fadd', a, b), 0.0), ('fne', a, ('fneg', b))),
+]
+
print nir_algebraic.AlgebraicPass("nir_opt_algebraic", optimizations).render()
+print nir_algebraic.AlgebraicPass("nir_opt_algebraic_late",
+ late_optimizations).render()
diff --git a/mesalib/src/glsl/nir/nir_opt_cse.c b/mesalib/src/glsl/nir/nir_opt_cse.c
index 9b383202d..553906e12 100644
--- a/mesalib/src/glsl/nir/nir_opt_cse.c
+++ b/mesalib/src/glsl/nir/nir_opt_cse.c
@@ -37,20 +37,19 @@ struct cse_state {
};
static bool
-nir_alu_srcs_equal(nir_alu_src src1, nir_alu_src src2, uint8_t read_mask)
+nir_alu_srcs_equal(nir_alu_instr *alu1, nir_alu_instr *alu2, unsigned src1,
+ unsigned src2)
{
- if (src1.abs != src2.abs || src1.negate != src2.negate)
+ if (alu1->src[src1].abs != alu2->src[src2].abs ||
+ alu1->src[src1].negate != alu2->src[src2].negate)
return false;
- for (int i = 0; i < 4; ++i) {
- if (!(read_mask & (1 << i)))
- continue;
-
- if (src1.swizzle[i] != src2.swizzle[i])
+ for (unsigned i = 0; i < nir_ssa_alu_instr_src_components(alu1, src1); i++) {
+ if (alu1->src[src1].swizzle[i] != alu2->src[src2].swizzle[i])
return false;
}
- return nir_srcs_equal(src1.src, src2.src);
+ return nir_srcs_equal(alu1->src[src1].src, alu2->src[src2].src);
}
static bool
@@ -73,10 +72,17 @@ nir_instrs_equal(nir_instr *instr1, nir_instr *instr2)
if (alu1->dest.dest.ssa.num_components != alu2->dest.dest.ssa.num_components)
return false;
- for (unsigned i = 0; i < nir_op_infos[alu1->op].num_inputs; i++) {
- if (!nir_alu_srcs_equal(alu1->src[i], alu2->src[i],
- (1 << alu1->dest.dest.ssa.num_components) - 1))
- return false;
+ if (nir_op_infos[alu1->op].algebraic_properties & NIR_OP_IS_COMMUTATIVE) {
+ assert(nir_op_infos[alu1->op].num_inputs == 2);
+ return (nir_alu_srcs_equal(alu1, alu2, 0, 0) &&
+ nir_alu_srcs_equal(alu1, alu2, 1, 1)) ||
+ (nir_alu_srcs_equal(alu1, alu2, 0, 1) &&
+ nir_alu_srcs_equal(alu1, alu2, 1, 0));
+ } else {
+ for (unsigned i = 0; i < nir_op_infos[alu1->op].num_inputs; i++) {
+ if (!nir_alu_srcs_equal(alu1, alu2, i, i))
+ return false;
+ }
}
return true;
}
@@ -154,12 +160,14 @@ nir_instrs_equal(nir_instr *instr1, nir_instr *instr2)
static bool
src_is_ssa(nir_src *src, void *data)
{
+ (void) data;
return src->is_ssa;
}
static bool
dest_is_ssa(nir_dest *dest, void *data)
{
+ (void) data;
return dest->is_ssa;
}
diff --git a/mesalib/src/glsl/nir/nir_opt_peephole_ffma.c b/mesalib/src/glsl/nir/nir_opt_peephole_ffma.c
new file mode 100644
index 000000000..9d5646fe6
--- /dev/null
+++ b/mesalib/src/glsl/nir/nir_opt_peephole_ffma.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jason Ekstrand (jason@jlekstrand.net)
+ *
+ */
+
+#include "nir.h"
+
+/*
+ * Implements a small peephole optimization that looks for a multiply that
+ * is only ever used in an add and replaces both with an fma.
+ */
+
+struct peephole_ffma_state {
+ void *mem_ctx;
+ nir_function_impl *impl;
+ bool progress;
+};
+
+static inline bool
+are_all_uses_fadd(nir_ssa_def *def)
+{
+ if (def->if_uses->entries > 0)
+ return false;
+
+ struct set_entry *use_iter;
+ set_foreach(def->uses, use_iter) {
+ nir_instr *use_instr = (nir_instr *)use_iter->key;
+
+ if (use_instr->type != nir_instr_type_alu)
+ return false;
+
+ nir_alu_instr *use_alu = nir_instr_as_alu(use_instr);
+ switch (use_alu->op) {
+ case nir_op_fadd:
+ break; /* This one's ok */
+
+ case nir_op_imov:
+ case nir_op_fmov:
+ case nir_op_fneg:
+ case nir_op_fabs:
+ assert(use_alu->dest.dest.is_ssa);
+ if (!are_all_uses_fadd(&use_alu->dest.dest.ssa))
+ return false;
+ break;
+
+ default:
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static nir_alu_instr *
+get_mul_for_src(nir_alu_src *src, uint8_t swizzle[4], bool *negate, bool *abs)
+{
+ assert(src->src.is_ssa && !src->abs && !src->negate);
+
+ nir_instr *instr = src->src.ssa->parent_instr;
+ if (instr->type != nir_instr_type_alu)
+ return NULL;
+
+ nir_alu_instr *alu = nir_instr_as_alu(instr);
+ switch (alu->op) {
+ case nir_op_imov:
+ case nir_op_fmov:
+ alu = get_mul_for_src(&alu->src[0], swizzle, negate, abs);
+ break;
+
+ case nir_op_fneg:
+ alu = get_mul_for_src(&alu->src[0], swizzle, negate, abs);
+ *negate = !*negate;
+ break;
+
+ case nir_op_fabs:
+ alu = get_mul_for_src(&alu->src[0], swizzle, negate, abs);
+ *negate = false;
+ *abs = true;
+ break;
+
+ case nir_op_fmul:
+ /* Only absorb a fmul into a ffma if the fmul is is only used in fadd
+ * operations. This prevents us from being too aggressive with our
+ * fusing which can actually lead to more instructions.
+ */
+ if (!are_all_uses_fadd(&alu->dest.dest.ssa))
+ return NULL;
+ break;
+
+ default:
+ return NULL;
+ }
+
+ if (!alu)
+ return NULL;
+
+ for (unsigned i = 0; i < 4; i++) {
+ if (!(alu->dest.write_mask & (1 << i)))
+ break;
+
+ swizzle[i] = swizzle[src->swizzle[i]];
+ }
+
+ return alu;
+}
+
+static bool
+nir_opt_peephole_ffma_block(nir_block *block, void *void_state)
+{
+ struct peephole_ffma_state *state = void_state;
+
+ nir_foreach_instr_safe(block, instr) {
+ if (instr->type != nir_instr_type_alu)
+ continue;
+
+ nir_alu_instr *add = nir_instr_as_alu(instr);
+ if (add->op != nir_op_fadd)
+ continue;
+
+ /* TODO: Maybe bail if this expression is considered "precise"? */
+
+ assert(add->src[0].src.is_ssa && add->src[1].src.is_ssa);
+
+ /* This, is the case a + a. We would rather handle this with an
+ * algebraic reduction than fuse it. Also, we want to only fuse
+ * things where the multiply is used only once and, in this case,
+ * it would be used twice by the same instruction.
+ */
+ if (add->src[0].src.ssa == add->src[1].src.ssa)
+ continue;
+
+ nir_alu_instr *mul;
+ uint8_t add_mul_src, swizzle[4];
+ bool negate, abs;
+ for (add_mul_src = 0; add_mul_src < 2; add_mul_src++) {
+ for (unsigned i = 0; i < 4; i++)
+ swizzle[i] = i;
+
+ negate = false;
+ abs = false;
+
+ mul = get_mul_for_src(&add->src[add_mul_src], swizzle, &negate, &abs);
+
+ if (mul != NULL)
+ break;
+ }
+
+ if (mul == NULL)
+ continue;
+
+ nir_ssa_def *mul_src[2];
+ mul_src[0] = mul->src[0].src.ssa;
+ mul_src[1] = mul->src[1].src.ssa;
+
+ if (abs) {
+ for (unsigned i = 0; i < 2; i++) {
+ nir_alu_instr *abs = nir_alu_instr_create(state->mem_ctx,
+ nir_op_fabs);
+ abs->src[0].src = nir_src_for_ssa(mul_src[i]);
+ nir_ssa_dest_init(&abs->instr, &abs->dest.dest,
+ mul_src[i]->num_components, NULL);
+ abs->dest.write_mask = (1 << mul_src[i]->num_components) - 1;
+ nir_instr_insert_before(&add->instr, &abs->instr);
+ mul_src[i] = &abs->dest.dest.ssa;
+ }
+ }
+
+ if (negate) {
+ nir_alu_instr *neg = nir_alu_instr_create(state->mem_ctx,
+ nir_op_fneg);
+ neg->src[0].src = nir_src_for_ssa(mul_src[0]);
+ nir_ssa_dest_init(&neg->instr, &neg->dest.dest,
+ mul_src[0]->num_components, NULL);
+ neg->dest.write_mask = (1 << mul_src[0]->num_components) - 1;
+ nir_instr_insert_before(&add->instr, &neg->instr);
+ mul_src[0] = &neg->dest.dest.ssa;
+ }
+
+ nir_alu_instr *ffma = nir_alu_instr_create(state->mem_ctx, nir_op_ffma);
+ ffma->dest.saturate = add->dest.saturate;
+ ffma->dest.write_mask = add->dest.write_mask;
+
+ for (unsigned i = 0; i < 2; i++) {
+ ffma->src[i].src = nir_src_for_ssa(mul_src[i]);
+ for (unsigned j = 0; j < add->dest.dest.ssa.num_components; j++)
+ ffma->src[i].swizzle[j] = mul->src[i].swizzle[swizzle[j]];
+ }
+ nir_alu_src_copy(&ffma->src[2], &add->src[1 - add_mul_src],
+ state->mem_ctx);
+
+ assert(add->dest.dest.is_ssa);
+
+ nir_ssa_dest_init(&ffma->instr, &ffma->dest.dest,
+ add->dest.dest.ssa.num_components,
+ add->dest.dest.ssa.name);
+ nir_ssa_def_rewrite_uses(&add->dest.dest.ssa,
+ nir_src_for_ssa(&ffma->dest.dest.ssa),
+ state->mem_ctx);
+
+ nir_instr_insert_before(&add->instr, &ffma->instr);
+ assert(add->dest.dest.ssa.uses->entries == 0);
+ nir_instr_remove(&add->instr);
+
+ state->progress = true;
+ }
+
+ return true;
+}
+
+static bool
+nir_opt_peephole_ffma_impl(nir_function_impl *impl)
+{
+ struct peephole_ffma_state state;
+
+ state.mem_ctx = ralloc_parent(impl);
+ state.impl = impl;
+ state.progress = false;
+
+ nir_foreach_block(impl, nir_opt_peephole_ffma_block, &state);
+
+ if (state.progress)
+ nir_metadata_preserve(impl, nir_metadata_block_index |
+ nir_metadata_dominance);
+
+ return state.progress;
+}
+
+bool
+nir_opt_peephole_ffma(nir_shader *shader)
+{
+ bool progress = false;
+
+ nir_foreach_overload(shader, overload) {
+ if (overload->impl)
+ progress |= nir_opt_peephole_ffma_impl(overload->impl);
+ }
+
+ return progress;
+}
diff --git a/mesalib/src/glsl/nir/nir_opt_peephole_select.c b/mesalib/src/glsl/nir/nir_opt_peephole_select.c
index b89451b09..f400cfd66 100644
--- a/mesalib/src/glsl/nir/nir_opt_peephole_select.c
+++ b/mesalib/src/glsl/nir/nir_opt_peephole_select.c
@@ -84,7 +84,9 @@ block_check_for_allowed_instrs(nir_block *block)
case nir_instr_type_alu: {
/* It must be a move operation */
nir_alu_instr *mov = nir_instr_as_alu(instr);
- if (mov->op != nir_op_fmov && mov->op != nir_op_imov)
+ if (mov->op != nir_op_fmov && mov->op != nir_op_imov &&
+ mov->op != nir_op_fneg && mov->op != nir_op_ineg &&
+ mov->op != nir_op_fabs && mov->op != nir_op_iabs)
return false;
/* Can't handle saturate */
diff --git a/mesalib/src/glsl/nir/nir_print.c b/mesalib/src/glsl/nir/nir_print.c
index fa11a312e..fb8c9344c 100644
--- a/mesalib/src/glsl/nir/nir_print.c
+++ b/mesalib/src/glsl/nir/nir_print.c
@@ -137,25 +137,37 @@ print_dest(nir_dest *dest, FILE *fp)
}
static void
-print_alu_src(nir_alu_src *src, FILE *fp)
+print_alu_src(nir_alu_instr *instr, unsigned src, FILE *fp)
{
- if (src->negate)
+ if (instr->src[src].negate)
fprintf(fp, "-");
- if (src->abs)
+ if (instr->src[src].abs)
fprintf(fp, "abs(");
- print_src(&src->src, fp);
+ print_src(&instr->src[src].src, fp);
- if (src->swizzle[0] != 0 ||
- src->swizzle[1] != 1 ||
- src->swizzle[2] != 2 ||
- src->swizzle[3] != 3) {
+ bool print_swizzle = false;
+ for (unsigned i = 0; i < 4; i++) {
+ if (!nir_alu_instr_channel_used(instr, src, i))
+ continue;
+
+ if (instr->src[src].swizzle[i] != i) {
+ print_swizzle = true;
+ break;
+ }
+ }
+
+ if (print_swizzle) {
fprintf(fp, ".");
- for (unsigned i = 0; i < 4; i++)
- fprintf(fp, "%c", "xyzw"[src->swizzle[i]]);
+ for (unsigned i = 0; i < 4; i++) {
+ if (!nir_alu_instr_channel_used(instr, src, i))
+ continue;
+
+ fprintf(fp, "%c", "xyzw"[instr->src[src].swizzle[i]]);
+ }
}
- if (src->abs)
+ if (instr->src[src].abs)
fprintf(fp, ")");
}
@@ -189,7 +201,7 @@ print_alu_instr(nir_alu_instr *instr, FILE *fp)
if (i != 0)
fprintf(fp, ", ");
- print_alu_src(&instr->src[i], fp);
+ print_alu_src(instr, i, fp);
}
}
diff --git a/mesalib/src/glsl/nir/nir_remove_dead_variables.c b/mesalib/src/glsl/nir/nir_remove_dead_variables.c
index e7f8aeacb..4417e2a48 100644
--- a/mesalib/src/glsl/nir/nir_remove_dead_variables.c
+++ b/mesalib/src/glsl/nir/nir_remove_dead_variables.c
@@ -98,22 +98,14 @@ add_var_use_shader(nir_shader *shader, struct set *live)
}
static void
-remove_dead_local_vars(nir_function_impl *impl, struct set *live)
+remove_dead_vars(struct exec_list *var_list, struct set *live)
{
- foreach_list_typed_safe(nir_variable, var, node, &impl->locals) {
+ foreach_list_typed_safe(nir_variable, var, node, var_list) {
struct set_entry *entry = _mesa_set_search(live, var);
- if (entry == NULL)
- exec_node_remove(&var->node);
- }
-}
-
-static void
-remove_dead_global_vars(nir_shader *shader, struct set *live)
-{
- foreach_list_typed_safe(nir_variable, var, node, &shader->globals) {
- struct set_entry *entry = _mesa_set_search(live, var);
- if (entry == NULL)
+ if (entry == NULL) {
exec_node_remove(&var->node);
+ ralloc_free(var);
+ }
}
}
@@ -125,11 +117,11 @@ nir_remove_dead_variables(nir_shader *shader)
add_var_use_shader(shader, live);
- remove_dead_global_vars(shader, live);
+ remove_dead_vars(&shader->globals, live);
nir_foreach_overload(shader, overload) {
if (overload->impl)
- remove_dead_local_vars(overload->impl, live);
+ remove_dead_vars(&overload->impl->locals, live);
}
_mesa_set_destroy(live, NULL);
diff --git a/mesalib/src/glsl/nir/nir_search.c b/mesalib/src/glsl/nir/nir_search.c
index 73a802be7..5ba016085 100644
--- a/mesalib/src/glsl/nir/nir_search.c
+++ b/mesalib/src/glsl/nir/nir_search.c
@@ -218,8 +218,8 @@ match_expression(const nir_search_expression *expr, nir_alu_instr *instr,
if (matched)
return true;
- if (nir_op_infos[instr->op].num_inputs == 2 &&
- (nir_op_infos[instr->op].algebraic_properties & NIR_OP_IS_COMMUTATIVE)) {
+ if (nir_op_infos[instr->op].algebraic_properties & NIR_OP_IS_COMMUTATIVE) {
+ assert(nir_op_infos[instr->op].num_inputs == 2);
if (!match_value(expr->srcs[0], instr, 1, num_components,
swizzle, state))
return false;
diff --git a/mesalib/src/glsl/nir/nir_split_var_copies.c b/mesalib/src/glsl/nir/nir_split_var_copies.c
index 4d663b51b..fc72c078c 100644
--- a/mesalib/src/glsl/nir/nir_split_var_copies.c
+++ b/mesalib/src/glsl/nir/nir_split_var_copies.c
@@ -188,8 +188,8 @@ split_var_copy_instr(nir_intrinsic_instr *old_copy,
* belongs to the copy instruction and b) the deref chains may
* have some of the same links due to the way we constructed them
*/
- nir_deref *src = nir_copy_deref(state->mem_ctx, src_head);
- nir_deref *dest = nir_copy_deref(state->mem_ctx, dest_head);
+ nir_deref *src = nir_copy_deref(new_copy, src_head);
+ nir_deref *dest = nir_copy_deref(new_copy, dest_head);
new_copy->variables[0] = nir_deref_as_var(dest);
new_copy->variables[1] = nir_deref_as_var(src);
diff --git a/mesalib/src/glsl/nir/nir_sweep.c b/mesalib/src/glsl/nir/nir_sweep.c
new file mode 100644
index 000000000..d3549756a
--- /dev/null
+++ b/mesalib/src/glsl/nir/nir_sweep.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "nir.h"
+
+/**
+ * \file nir_sweep.c
+ *
+ * The nir_sweep() pass performs a mark and sweep pass over a nir_shader's associated
+ * memory - anything still connected to the program will be kept, and any dead memory
+ * we dropped on the floor will be freed.
+ *
+ * The expectation is that drivers should call this when finished compiling the shader
+ * (after any optimization, lowering, and so on). However, it's also fine to call it
+ * earlier, and even many times, trading CPU cycles for memory savings.
+ */
+
+#define steal_list(mem_ctx, type, list) \
+ foreach_list_typed(type, obj, node, list) { ralloc_steal(mem_ctx, obj); }
+
+static void sweep_cf_node(nir_shader *nir, nir_cf_node *cf_node);
+
+static bool
+sweep_src_indirect(nir_src *src, void *nir)
+{
+ if (!src->is_ssa && src->reg.indirect)
+ ralloc_steal(nir, src->reg.indirect);
+
+ return true;
+}
+
+static bool
+sweep_dest_indirect(nir_dest *dest, void *nir)
+{
+ if (!dest->is_ssa && dest->reg.indirect)
+ ralloc_steal(nir, dest->reg.indirect);
+
+ return true;
+}
+
+static void
+sweep_block(nir_shader *nir, nir_block *block)
+{
+ ralloc_steal(nir, block);
+
+ nir_foreach_instr(block, instr) {
+ ralloc_steal(nir, instr);
+
+ nir_foreach_src(instr, sweep_src_indirect, nir);
+ nir_foreach_dest(instr, sweep_dest_indirect, nir);
+ }
+}
+
+static void
+sweep_if(nir_shader *nir, nir_if *iff)
+{
+ ralloc_steal(nir, iff);
+
+ foreach_list_typed(nir_cf_node, cf_node, node, &iff->then_list) {
+ sweep_cf_node(nir, cf_node);
+ }
+
+ foreach_list_typed(nir_cf_node, cf_node, node, &iff->else_list) {
+ sweep_cf_node(nir, cf_node);
+ }
+}
+
+static void
+sweep_loop(nir_shader *nir, nir_loop *loop)
+{
+ ralloc_steal(nir, loop);
+
+ foreach_list_typed(nir_cf_node, cf_node, node, &loop->body) {
+ sweep_cf_node(nir, cf_node);
+ }
+}
+
+static void
+sweep_cf_node(nir_shader *nir, nir_cf_node *cf_node)
+{
+ switch (cf_node->type) {
+ case nir_cf_node_block:
+ sweep_block(nir, nir_cf_node_as_block(cf_node));
+ break;
+ case nir_cf_node_if:
+ sweep_if(nir, nir_cf_node_as_if(cf_node));
+ break;
+ case nir_cf_node_loop:
+ sweep_loop(nir, nir_cf_node_as_loop(cf_node));
+ break;
+ default:
+ unreachable("Invalid CF node type");
+ }
+}
+
+static void
+sweep_impl(nir_shader *nir, nir_function_impl *impl)
+{
+ ralloc_steal(nir, impl);
+
+ ralloc_steal(nir, impl->params);
+ ralloc_steal(nir, impl->return_var);
+ steal_list(nir, nir_variable, &impl->locals);
+ steal_list(nir, nir_register, &impl->registers);
+
+ foreach_list_typed(nir_cf_node, cf_node, node, &impl->body) {
+ sweep_cf_node(nir, cf_node);
+ }
+
+ sweep_block(nir, impl->end_block);
+
+ /* Wipe out all the metadata, if any. */
+ nir_metadata_preserve(impl, nir_metadata_none);
+}
+
+static void
+sweep_function(nir_shader *nir, nir_function *f)
+{
+ ralloc_steal(nir, f);
+
+ foreach_list_typed(nir_function_overload, overload, node, &f->overload_list) {
+ ralloc_steal(nir, overload);
+ ralloc_steal(nir, overload->params);
+ if (overload->impl)
+ sweep_impl(nir, overload->impl);
+ }
+}
+
+void
+nir_sweep(nir_shader *nir)
+{
+ void *rubbish = ralloc_context(NULL);
+
+ /* First, move ownership of all the memory to a temporary context; assume dead. */
+ ralloc_adopt(rubbish, nir);
+
+ /* Variables and registers are not dead. Steal them back. */
+ steal_list(nir, nir_variable, &nir->uniforms);
+ steal_list(nir, nir_variable, &nir->inputs);
+ steal_list(nir, nir_variable, &nir->outputs);
+ steal_list(nir, nir_variable, &nir->globals);
+ steal_list(nir, nir_variable, &nir->system_values);
+ steal_list(nir, nir_register, &nir->registers);
+
+ /* Recurse into functions, stealing their contents back. */
+ foreach_list_typed(nir_function, func, node, &nir->functions) {
+ sweep_function(nir, func);
+ }
+
+ /* Free everything we didn't steal back. */
+ ralloc_free(rubbish);
+}
diff --git a/mesalib/src/glsl/nir/nir_to_ssa.c b/mesalib/src/glsl/nir/nir_to_ssa.c
index 47cf45393..53ff54766 100644
--- a/mesalib/src/glsl/nir/nir_to_ssa.c
+++ b/mesalib/src/glsl/nir/nir_to_ssa.c
@@ -47,7 +47,7 @@ insert_trivial_phi(nir_register *reg, nir_block *block, void *mem_ctx)
set_foreach(block->predecessors, entry) {
nir_block *pred = (nir_block *) entry->key;
- nir_phi_src *src = ralloc(mem_ctx, nir_phi_src);
+ nir_phi_src *src = ralloc(instr, nir_phi_src);
src->pred = pred;
src->src.is_ssa = false;
src->src.reg.base_offset = 0;
diff --git a/mesalib/src/glsl/nir/nir_types.cpp b/mesalib/src/glsl/nir/nir_types.cpp
index a13c3e12a..f0d0b46d2 100644
--- a/mesalib/src/glsl/nir/nir_types.cpp
+++ b/mesalib/src/glsl/nir/nir_types.cpp
@@ -143,6 +143,12 @@ glsl_void_type(void)
}
const glsl_type *
+glsl_float_type(void)
+{
+ return glsl_type::float_type;
+}
+
+const glsl_type *
glsl_vec4_type(void)
{
return glsl_type::vec4_type;
diff --git a/mesalib/src/glsl/nir/nir_types.h b/mesalib/src/glsl/nir/nir_types.h
index 494051a67..276d4ad62 100644
--- a/mesalib/src/glsl/nir/nir_types.h
+++ b/mesalib/src/glsl/nir/nir_types.h
@@ -69,6 +69,7 @@ bool glsl_type_is_scalar(const struct glsl_type *type);
bool glsl_type_is_matrix(const struct glsl_type *type);
const struct glsl_type *glsl_void_type(void);
+const struct glsl_type *glsl_float_type(void);
const struct glsl_type *glsl_vec4_type(void);
const struct glsl_type *glsl_array_type(const struct glsl_type *base,
unsigned elements);
diff --git a/mesalib/src/glsl/nir/nir_validate.c b/mesalib/src/glsl/nir/nir_validate.c
index f247ae069..a7aa79837 100644
--- a/mesalib/src/glsl/nir/nir_validate.c
+++ b/mesalib/src/glsl/nir/nir_validate.c
@@ -295,6 +295,8 @@ validate_alu_instr(nir_alu_instr *instr, validate_state *state)
static void
validate_deref_chain(nir_deref *deref, validate_state *state)
{
+ assert(deref->child == NULL || ralloc_parent(deref->child) == deref);
+
nir_deref *parent = NULL;
while (deref != NULL) {
switch (deref->deref_type) {
@@ -336,9 +338,10 @@ validate_var_use(nir_variable *var, validate_state *state)
}
static void
-validate_deref_var(nir_deref_var *deref, validate_state *state)
+validate_deref_var(void *parent_mem_ctx, nir_deref_var *deref, validate_state *state)
{
assert(deref != NULL);
+ assert(ralloc_parent(deref) == parent_mem_ctx);
assert(deref->deref.type == deref->var->type);
validate_var_use(deref->var, state);
@@ -386,7 +389,7 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state)
unsigned num_vars = nir_intrinsic_infos[instr->intrinsic].num_variables;
for (unsigned i = 0; i < num_vars; i++) {
- validate_deref_var(instr->variables[i], state);
+ validate_deref_var(instr, instr->variables[i], state);
}
switch (instr->intrinsic) {
@@ -423,7 +426,7 @@ validate_tex_instr(nir_tex_instr *instr, validate_state *state)
}
if (instr->sampler != NULL)
- validate_deref_var(instr->sampler, state);
+ validate_deref_var(instr, instr->sampler, state);
}
static void
@@ -438,10 +441,10 @@ validate_call_instr(nir_call_instr *instr, validate_state *state)
for (unsigned i = 0; i < instr->num_params; i++) {
assert(instr->callee->params[i].type == instr->params[i]->deref.type);
- validate_deref_var(instr->params[i], state);
+ validate_deref_var(instr, instr->params[i], state);
}
- validate_deref_var(instr->return_deref, state);
+ validate_deref_var(instr, instr->return_deref, state);
}
static void
@@ -680,8 +683,7 @@ validate_cf_node(nir_cf_node *node, validate_state *state)
break;
default:
- assert(!"Invalid ALU instruction type");
- break;
+ unreachable("Invalid CF node type");
}
}
diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp
index 69c03ea8b..3d2f2ca0b 100644
--- a/mesalib/src/glsl/opt_algebraic.cpp
+++ b/mesalib/src/glsl/opt_algebraic.cpp
@@ -290,6 +290,20 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
ir_expression *op_expr[4] = {NULL, NULL, NULL, NULL};
unsigned int i;
+ if (ir->operation == ir_binop_mul &&
+ ir->operands[0]->type->is_matrix() &&
+ ir->operands[1]->type->is_vector()) {
+ ir_expression *matrix_mul = ir->operands[0]->as_expression();
+
+ if (matrix_mul && matrix_mul->operation == ir_binop_mul &&
+ matrix_mul->operands[0]->type->is_matrix() &&
+ matrix_mul->operands[1]->type->is_matrix()) {
+
+ return mul(matrix_mul->operands[0],
+ mul(matrix_mul->operands[1], ir->operands[1]));
+ }
+ }
+
assert(ir->get_num_operands() <= 4);
for (i = 0; i < ir->get_num_operands(); i++) {
if (ir->operands[i]->type->is_matrix())
@@ -421,6 +435,18 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
break;
}
+ case ir_unop_saturate:
+ if (op_expr[0] && op_expr[0]->operation == ir_binop_add) {
+ ir_expression *b2f_0 = op_expr[0]->operands[0]->as_expression();
+ ir_expression *b2f_1 = op_expr[0]->operands[1]->as_expression();
+
+ if (b2f_0 && b2f_0->operation == ir_unop_b2f &&
+ b2f_1 && b2f_1->operation == ir_unop_b2f) {
+ return b2f(logic_or(b2f_0->operands[0], b2f_1->operands[0]));
+ }
+ }
+ break;
+
case ir_binop_add:
if (is_vec_zero(op_const[0]))
return ir->operands[1];
@@ -518,6 +544,10 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
if (is_vec_negative_one(op_const[1]))
return neg(ir->operands[0]);
+ if (op_expr[0] && op_expr[0]->operation == ir_unop_b2f &&
+ op_expr[1] && op_expr[1]->operation == ir_unop_b2f) {
+ return b2f(logic_and(op_expr[0]->operands[0], op_expr[1]->operands[0]));
+ }
/* Reassociate multiplication of constants so that we can do
* constant folding.
@@ -544,6 +574,8 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
continue;
ir_expression *add_expr = floor_expr->operands[0]->as_expression();
+ if (!add_expr)
+ continue;
for (int j = 0; j < 2; j++) {
ir_expression *abs_expr = add_expr->operands[j]->as_expression();
diff --git a/mesalib/src/glsl/opt_cse.cpp b/mesalib/src/glsl/opt_cse.cpp
index b0b67f496..4b8e9a07b 100644
--- a/mesalib/src/glsl/opt_cse.cpp
+++ b/mesalib/src/glsl/opt_cse.cpp
@@ -63,6 +63,17 @@ public:
var = NULL;
}
+ void init(ir_instruction *base_ir, ir_rvalue **val)
+ {
+ this->val = val;
+ this->base_ir = base_ir;
+ this->var = NULL;
+
+ assert(val);
+ assert(*val);
+ assert(base_ir);
+ }
+
/**
* The pointer to the expression that we might be able to reuse
*
@@ -116,6 +127,18 @@ private:
ir_rvalue *try_cse(ir_rvalue *rvalue);
void add_to_ae(ir_rvalue **rvalue);
+ /**
+ * Move all nodes from the ae list to the free list
+ */
+ void empty_ae_list();
+
+ /**
+ * Get and initialize a new ae_entry
+ *
+ * This will either come from the free list or be freshly allocated.
+ */
+ ae_entry *get_ae_entry(ir_rvalue **rvalue);
+
/** List of ae_entry: The available expressions to reuse */
exec_list *ae;
@@ -126,6 +149,11 @@ private:
* right.
*/
exec_list *validate_instructions;
+
+ /**
+ * List of available-for-use ae_entry objects.
+ */
+ exec_list free_ae_entries;
};
/**
@@ -322,6 +350,25 @@ cse_visitor::try_cse(ir_rvalue *rvalue)
return NULL;
}
+void
+cse_visitor::empty_ae_list()
+{
+ free_ae_entries.append_list(ae);
+}
+
+ae_entry *
+cse_visitor::get_ae_entry(ir_rvalue **rvalue)
+{
+ ae_entry *entry = (ae_entry *) free_ae_entries.pop_head();
+ if (entry) {
+ entry->init(base_ir, rvalue);
+ } else {
+ entry = new(mem_ctx) ae_entry(base_ir, rvalue);
+ }
+
+ return entry;
+}
+
/** Add the rvalue to the list of available expressions for CSE. */
void
cse_visitor::add_to_ae(ir_rvalue **rvalue)
@@ -332,7 +379,7 @@ cse_visitor::add_to_ae(ir_rvalue **rvalue)
printf("\n");
}
- ae->push_tail(new(mem_ctx) ae_entry(base_ir, rvalue));
+ ae->push_tail(get_ae_entry(rvalue));
if (debug)
dump_ae(ae);
@@ -370,33 +417,33 @@ cse_visitor::visit_enter(ir_if *ir)
{
handle_rvalue(&ir->condition);
- ae->make_empty();
+ empty_ae_list();
visit_list_elements(this, &ir->then_instructions);
- ae->make_empty();
+ empty_ae_list();
visit_list_elements(this, &ir->else_instructions);
- ae->make_empty();
+ empty_ae_list();
return visit_continue_with_parent;
}
ir_visitor_status
cse_visitor::visit_enter(ir_function_signature *ir)
{
- ae->make_empty();
+ empty_ae_list();
visit_list_elements(this, &ir->body);
- ae->make_empty();
+ empty_ae_list();
return visit_continue_with_parent;
}
ir_visitor_status
cse_visitor::visit_enter(ir_loop *ir)
{
- ae->make_empty();
+ empty_ae_list();
visit_list_elements(this, &ir->body_instructions);
- ae->make_empty();
+ empty_ae_list();
return visit_continue_with_parent;
}
diff --git a/mesalib/src/glsl/s_expression.cpp b/mesalib/src/glsl/s_expression.cpp
index 7eaa491e2..f82e155a6 100644
--- a/mesalib/src/glsl/s_expression.cpp
+++ b/mesalib/src/glsl/s_expression.cpp
@@ -23,8 +23,8 @@
*/
#include <assert.h>
-#include <limits>
#include <stdio.h>
+#include <math.h>
#include "s_expression.h"
s_symbol::s_symbol(const char *str, size_t n)
@@ -70,7 +70,7 @@ read_atom(void *ctx, const char *&src, char *&symbol_buffer)
// requires strtof to parse '+INF' as +Infinity, but we still support some
// non-C99-compliant compilers (e.g. MSVC).
if (n == 4 && strncmp(src, "+INF", 4) == 0) {
- expr = new(ctx) s_float(std::numeric_limits<float>::infinity());
+ expr = new(ctx) s_float(INFINITY);
} else {
// Check if the atom is a number.
char *float_end = NULL;
diff --git a/mesalib/src/glsl/shader_enums.h b/mesalib/src/glsl/shader_enums.h
new file mode 100644
index 000000000..79e0f6b5f
--- /dev/null
+++ b/mesalib/src/glsl/shader_enums.h
@@ -0,0 +1,187 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef SHADER_ENUMS_H
+#define SHADER_ENUMS_H
+
+/**
+ * Shader stages. Note that these will become 5 with tessellation.
+ *
+ * The order must match how shaders are ordered in the pipeline.
+ * The GLSL linker assumes that if i<j, then the j-th shader is
+ * executed later than the i-th shader.
+ */
+typedef enum
+{
+ MESA_SHADER_VERTEX = 0,
+ MESA_SHADER_GEOMETRY = 1,
+ MESA_SHADER_FRAGMENT = 2,
+ MESA_SHADER_COMPUTE = 3,
+} gl_shader_stage;
+
+#define MESA_SHADER_STAGES (MESA_SHADER_COMPUTE + 1)
+
+/**
+ * Bitflags for system values.
+ */
+#define SYSTEM_BIT_SAMPLE_ID ((uint64_t)1 << SYSTEM_VALUE_SAMPLE_ID)
+#define SYSTEM_BIT_SAMPLE_POS ((uint64_t)1 << SYSTEM_VALUE_SAMPLE_POS)
+#define SYSTEM_BIT_SAMPLE_MASK_IN ((uint64_t)1 << SYSTEM_VALUE_SAMPLE_MASK_IN)
+/**
+ * If the gl_register_file is PROGRAM_SYSTEM_VALUE, the register index will be
+ * one of these values. If a NIR variable's mode is nir_var_system_value, it
+ * will be one of these values.
+ */
+typedef enum
+{
+ /**
+ * \name Vertex shader system values
+ */
+ /*@{*/
+ /**
+ * OpenGL-style vertex ID.
+ *
+ * Section 2.11.7 (Shader Execution), subsection Shader Inputs, of the
+ * OpenGL 3.3 core profile spec says:
+ *
+ * "gl_VertexID holds the integer index i implicitly passed by
+ * DrawArrays or one of the other drawing commands defined in section
+ * 2.8.3."
+ *
+ * Section 2.8.3 (Drawing Commands) of the same spec says:
+ *
+ * "The commands....are equivalent to the commands with the same base
+ * name (without the BaseVertex suffix), except that the ith element
+ * transferred by the corresponding draw call will be taken from
+ * element indices[i] + basevertex of each enabled array."
+ *
+ * Additionally, the overview in the GL_ARB_shader_draw_parameters spec
+ * says:
+ *
+ * "In unextended GL, vertex shaders have inputs named gl_VertexID and
+ * gl_InstanceID, which contain, respectively the index of the vertex
+ * and instance. The value of gl_VertexID is the implicitly passed
+ * index of the vertex being processed, which includes the value of
+ * baseVertex, for those commands that accept it."
+ *
+ * gl_VertexID gets basevertex added in. This differs from DirectX where
+ * SV_VertexID does \b not get basevertex added in.
+ *
+ * \note
+ * If all system values are available, \c SYSTEM_VALUE_VERTEX_ID will be
+ * equal to \c SYSTEM_VALUE_VERTEX_ID_ZERO_BASE plus
+ * \c SYSTEM_VALUE_BASE_VERTEX.
+ *
+ * \sa SYSTEM_VALUE_VERTEX_ID_ZERO_BASE, SYSTEM_VALUE_BASE_VERTEX
+ */
+ SYSTEM_VALUE_VERTEX_ID,
+
+ /**
+ * Instanced ID as supplied to gl_InstanceID
+ *
+ * Values assigned to gl_InstanceID always begin with zero, regardless of
+ * the value of baseinstance.
+ *
+ * Section 11.1.3.9 (Shader Inputs) of the OpenGL 4.4 core profile spec
+ * says:
+ *
+ * "gl_InstanceID holds the integer instance number of the current
+ * primitive in an instanced draw call (see section 10.5)."
+ *
+ * Through a big chain of pseudocode, section 10.5 describes that
+ * baseinstance is not counted by gl_InstanceID. In that section, notice
+ *
+ * "If an enabled vertex attribute array is instanced (it has a
+ * non-zero divisor as specified by VertexAttribDivisor), the element
+ * index that is transferred to the GL, for all vertices, is given by
+ *
+ * floor(instance/divisor) + baseinstance
+ *
+ * If an array corresponding to an attribute required by a vertex
+ * shader is not enabled, then the corresponding element is taken from
+ * the current attribute state (see section 10.2)."
+ *
+ * Note that baseinstance is \b not included in the value of instance.
+ */
+ SYSTEM_VALUE_INSTANCE_ID,
+
+ /**
+ * DirectX-style vertex ID.
+ *
+ * Unlike \c SYSTEM_VALUE_VERTEX_ID, this system value does \b not include
+ * the value of basevertex.
+ *
+ * \sa SYSTEM_VALUE_VERTEX_ID, SYSTEM_VALUE_BASE_VERTEX
+ */
+ SYSTEM_VALUE_VERTEX_ID_ZERO_BASE,
+
+ /**
+ * Value of \c basevertex passed to \c glDrawElementsBaseVertex and similar
+ * functions.
+ *
+ * \sa SYSTEM_VALUE_VERTEX_ID, SYSTEM_VALUE_VERTEX_ID_ZERO_BASE
+ */
+ SYSTEM_VALUE_BASE_VERTEX,
+ /*@}*/
+
+ /**
+ * \name Geometry shader system values
+ */
+ /*@{*/
+ SYSTEM_VALUE_INVOCATION_ID,
+ /*@}*/
+
+ /**
+ * \name Fragment shader system values
+ */
+ /*@{*/
+ SYSTEM_VALUE_FRONT_FACE, /**< (not done yet) */
+ SYSTEM_VALUE_SAMPLE_ID,
+ SYSTEM_VALUE_SAMPLE_POS,
+ SYSTEM_VALUE_SAMPLE_MASK_IN,
+ /*@}*/
+
+ SYSTEM_VALUE_MAX /**< Number of values */
+} gl_system_value;
+
+
+/**
+ * The possible interpolation qualifiers that can be applied to a fragment
+ * shader input in GLSL.
+ *
+ * Note: INTERP_QUALIFIER_NONE must be 0 so that memsetting the
+ * gl_fragment_program data structure to 0 causes the default behavior.
+ */
+enum glsl_interp_qualifier
+{
+ INTERP_QUALIFIER_NONE = 0,
+ INTERP_QUALIFIER_SMOOTH,
+ INTERP_QUALIFIER_FLAT,
+ INTERP_QUALIFIER_NOPERSPECTIVE,
+ INTERP_QUALIFIER_COUNT /**< Number of interpolation qualifiers */
+};
+
+
+#endif /* SHADER_ENUMS_H */
diff --git a/mesalib/src/loader/Makefile.am b/mesalib/src/loader/Makefile.am
index 3d32279ea..36ddba82b 100644
--- a/mesalib/src/loader/Makefile.am
+++ b/mesalib/src/loader/Makefile.am
@@ -30,7 +30,6 @@ libloader_la_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src \
$(VISIBILITY_CFLAGS) \
- $(MSVC2013_COMPAT_CFLAGS) \
$(LIBUDEV_CFLAGS)
libloader_la_SOURCES = $(LOADER_C_FILES)
diff --git a/mesalib/src/mapi/glapi/gen/ARB_direct_state_access.xml b/mesalib/src/mapi/glapi/gen/ARB_direct_state_access.xml
index 641e68f71..8a092d697 100644
--- a/mesalib/src/mapi/glapi/gen/ARB_direct_state_access.xml
+++ b/mesalib/src/mapi/glapi/gen/ARB_direct_state_access.xml
@@ -7,6 +7,47 @@
<enum name="QUERY_TARGET" value="0x82EA"/>
<enum name="TEXTURE_BINDING" value="0x82EB"/>
+ <!-- Transform Feedback object functions -->
+
+ <function name="CreateTransformFeedbacks" offset="assign">
+ <param name="n" type="GLsizei" />
+ <param name="ids" type="GLuint *" />
+ </function>
+
+ <function name="TransformFeedbackBufferBase" offset="assign">
+ <param name="xfb" type="GLuint" />
+ <param name="index" type="GLuint" />
+ <param name="buffer" type="GLuint" />
+ </function>
+
+ <function name="TransformFeedbackBufferRange" offset="assign">
+ <param name="xfb" type="GLuint" />
+ <param name="index" type="GLuint" />
+ <param name="buffer" type="GLuint" />
+ <param name="offset" type="GLintptr" />
+ <param name="size" type="GLsizeiptr" />
+ </function>
+
+ <function name="GetTransformFeedbackiv" offset="assign">
+ <param name="xfb" type="GLuint" />
+ <param name="pname" type="GLenum" />
+ <param name="param" type="GLint *" />
+ </function>
+
+ <function name="GetTransformFeedbacki_v" offset="assign">
+ <param name="xfb" type="GLuint" />
+ <param name="pname" type="GLenum" />
+ <param name="index" type="GLuint" />
+ <param name="param" type="GLint *" />
+ </function>
+
+ <function name="GetTransformFeedbacki64_v" offset="assign">
+ <param name="xfb" type="GLuint" />
+ <param name="pname" type="GLenum" />
+ <param name="index" type="GLuint" />
+ <param name="param" type="GLint64 *" />
+ </function>
+
<!-- Buffer object functions -->
<function name="CreateBuffers" offset="assign">
@@ -111,6 +152,34 @@
<param name="data" type="GLvoid *" />
</function>
+ <!-- Renderbuffer object functions -->
+
+ <function name="CreateRenderbuffers" offset="assign">
+ <param name="n" type="GLsizei" />
+ <param name="renderbuffers" type="GLuint *" />
+ </function>
+
+ <function name="NamedRenderbufferStorage" offset="assign">
+ <param name="renderbuffer" type="GLuint" />
+ <param name="internalformat" type="GLenum" />
+ <param name="width" type="GLsizei" />
+ <param name="height" type="GLsizei" />
+ </function>
+
+ <function name="NamedRenderbufferStorageMultisample" offset="assign">
+ <param name="renderbuffer" type="GLuint" />
+ <param name="samples" type="GLsizei" />
+ <param name="internalformat" type="GLenum" />
+ <param name="width" type="GLsizei" />
+ <param name="height" type="GLsizei" />
+ </function>
+
+ <function name="GetNamedRenderbufferParameteriv" offset="assign">
+ <param name="renderbuffer" type="GLuint" />
+ <param name="pname" type="GLenum" />
+ <param name="params" type="GLint *" />
+ </function>
+
<!-- Texture object functions -->
<function name="CreateTextures" offset="assign">
@@ -379,5 +448,54 @@
<param name="params" type="GLint *" />
</function>
+ <!-- Sampler object functions -->
+
+ <function name="CreateSamplers" offset="assign">
+ <param name="n" type="GLsizei" />
+ <param name="samplers" type="GLuint *" />
+ </function>
+
+ <!-- Program Pipeline object functions -->
+
+ <function name="CreateProgramPipelines" offset="assign">
+ <param name="n" type="GLsizei" />
+ <param name="pipelines" type="GLuint *" />
+ </function>
+
+ <!-- Query object functions -->
+
+ <function name="CreateQueries" offset="assign">
+ <param name="target" type="GLenum" />
+ <param name="n" type="GLsizei" />
+ <param name="ids" type="GLuint *" />
+ </function>
+
+ <function name="GetQueryBufferObjectiv" offset="assign">
+ <param name="id" type="GLuint" />
+ <param name="buffer" type="GLuint" />
+ <param name="pname" type="GLenum" />
+ <param name="offset" type="GLintptr" />
+ </function>
+
+ <function name="GetQueryBufferObjectuiv" offset="assign">
+ <param name="id" type="GLuint" />
+ <param name="buffer" type="GLuint" />
+ <param name="pname" type="GLenum" />
+ <param name="offset" type="GLintptr" />
+ </function>
+
+ <function name="GetQueryBufferObjecti64v" offset="assign">
+ <param name="id" type="GLuint" />
+ <param name="buffer" type="GLuint" />
+ <param name="pname" type="GLenum" />
+ <param name="offset" type="GLintptr" />
+ </function>
+
+ <function name="GetQueryBufferObjectui64v" offset="assign">
+ <param name="id" type="GLuint" />
+ <param name="buffer" type="GLuint" />
+ <param name="pname" type="GLenum" />
+ <param name="offset" type="GLintptr" />
+ </function>
</category>
</OpenGLAPI>
diff --git a/mesalib/src/mapi/glapi/gen/ARB_program_interface_query.xml b/mesalib/src/mapi/glapi/gen/ARB_program_interface_query.xml
new file mode 100644
index 000000000..59eb59c64
--- /dev/null
+++ b/mesalib/src/mapi/glapi/gen/ARB_program_interface_query.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_ARB_program_interface_query" number="134">
+
+ <enum name="UNIFORM" value="0x92E1"/>
+ <enum name="UNIFORM_BLOCK" value="0x92E2"/>
+ <enum name="PROGRAM_INPUT" value="0x92E3"/>
+ <enum name="PROGRAM_OUTPUT" value="0x92E4"/>
+ <enum name="BUFFER_VARIABLE" value="0x92E5"/>
+ <enum name="SHADER_STORAGE_BLOCK" value="0x92E6"/>
+ <enum name="ATOMIC_COUNTER_BUFFER" value="0x92C0"/>
+ <enum name="VERTEX_SUBROUTINE" value="0x92E8"/>
+ <enum name="TESS_CONTROL_SUBROUTINE" value="0x92E9"/>
+ <enum name="TESS_EVALUATION_SUBROUTINE" value="0x92EA"/>
+ <enum name="GEOMETRY_SUBROUTINE" value="0x92EB"/>
+ <enum name="FRAGMENT_SUBROUTINE" value="0x92EC"/>
+ <enum name="COMPUTE_SUBROUTINE" value="0x92ED"/>
+ <enum name="VERTEX_SUBROUTINE_UNIFORM" value="0x92EE"/>
+ <enum name="TESS_CONTROL_SUBROUTINE_UNIFORM" value="0x92EF"/>
+ <enum name="TESS_EVALUATION_SUBROUTINE_UNIFORM" value="0x92F0"/>
+ <enum name="GEOMETRY_SUBROUTINE_UNIFORM" value="0x92F1"/>
+ <enum name="FRAGMENT_SUBROUTINE_UNIFORM" value="0x92F2"/>
+ <enum name="COMPUTE_SUBROUTINE_UNIFORM" value="0x92F3"/>
+ <enum name="TRANSFORM_FEEDBACK_VARYING" value="0x92F4"/>
+ <enum name="ACTIVE_RESOURCES" value="0x92F5"/>
+ <enum name="MAX_NAME_LENGTH" value="0x92F6"/>
+ <enum name="MAX_NUM_ACTIVE_VARIABLES" value="0x92F7"/>
+ <enum name="MAX_NUM_COMPATIBLE_SUBROUTINES" value="0x92F8"/>
+ <enum name="NAME_LENGTH" value="0x92F9"/>
+ <enum name="TYPE" value="0x92FA"/>
+ <enum name="ARRAY_SIZE" value="0x92FB"/>
+ <enum name="OFFSET" value="0x92FC"/>
+ <enum name="BLOCK_INDEX" value="0x92FD"/>
+ <enum name="ARRAY_STRIDE" value="0x92FE"/>
+ <enum name="MATRIX_STRIDE" value="0x92FF"/>
+ <enum name="IS_ROW_MAJOR" value="0x9300"/>
+ <enum name="ATOMIC_COUNTER_BUFFER_INDEX" value="0x9301"/>
+ <enum name="BUFFER_BINDING" value="0x9302"/>
+ <enum name="BUFFER_DATA_SIZE" value="0x9303"/>
+ <enum name="NUM_ACTIVE_VARIABLES" value="0x9304"/>
+ <enum name="ACTIVE_VARIABLES" value="0x9305"/>
+ <enum name="REFERENCED_BY_VERTEX_SHADER" value="0x9306"/>
+ <enum name="REFERENCED_BY_TESS_CONTROL_SHADER" value="0x9307"/>
+ <enum name="REFERENCED_BY_TESS_EVALUATION_SHADER" value="0x9308"/>
+ <enum name="REFERENCED_BY_GEOMETRY_SHADER" value="0x9309"/>
+ <enum name="REFERENCED_BY_FRAGMENT_SHADER" value="0x930A"/>
+ <enum name="REFERENCED_BY_COMPUTE_SHADER" value="0x930B"/>
+ <enum name="TOP_LEVEL_ARRAY_SIZE" value="0x930C"/>
+ <enum name="TOP_LEVEL_ARRAY_STRIDE" value="0x930D"/>
+ <enum name="LOCATION" value="0x930E"/>
+ <enum name="LOCATION_INDEX" value="0x930F"/>
+ <enum name="IS_PER_PATCH" value="0x92E7"/>
+ <enum name="NUM_COMPATIBLE_SUBROUTINES" value="0x8E4A"/>
+ <enum name="COMPATIBLE_SUBROUTINES" value="0x8E4B"/>
+
+ <function name="GetProgramInterfaceiv" offset="assign">
+ <param name="program" type="GLuint"/>
+ <param name="programInterface" type="GLenum"/>
+ <param name="pname" type="GLenum"/>
+ <param name="params" type="GLint *" output="true"/>
+ </function>
+
+ <function name="GetProgramResourceIndex" offset="assign">
+ <param name="program" type="GLuint"/>
+ <param name="programInterface" type="GLenum"/>
+ <param name="name" type="const GLchar *"/>
+ <return type="GLuint"/>
+ </function>
+
+ <function name="GetProgramResourceName" offset="assign">
+ <param name="program" type="GLuint"/>
+ <param name="programInterface" type="GLenum"/>
+ <param name="index" type="GLuint"/>
+ <param name="bufSize" type="GLsizei "/>
+ <param name="length" type="GLsizei *" output="true"/>
+ <param name="name" type="GLchar *" output="true"/>
+ </function>
+
+ <function name="GetProgramResourceiv" offset="assign">
+ <param name="program" type="GLuint"/>
+ <param name="programInterface" type="GLenum"/>
+ <param name="index" type="GLuint"/>
+ <param name="propCount" type="GLsizei "/>
+ <param name="props" type="const GLenum *" output="true"/>
+ <param name="bufSize" type="GLsizei "/>
+ <param name="length" type="GLsizei *" output="true"/>
+ <param name="params" type="GLint *" output="true"/>
+ </function>
+
+ <function name="GetProgramResourceLocation" offset="assign">
+ <param name="program" type="GLuint"/>
+ <param name="programInterface" type="GLenum"/>
+ <param name="name" type="const GLchar *"/>
+ <return type="GLint"/>
+ </function>
+
+ <function name="GetProgramResourceLocationIndex" offset="assign">
+ <param name="program" type="GLuint"/>
+ <param name="programInterface" type="GLenum"/>
+ <param name="name" type="const GLchar *"/>
+ <return type="GLint"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml
index 1ceb60a0f..a8a6db683 100644
--- a/mesalib/src/mapi/glapi/gen/gl_API.xml
+++ b/mesalib/src/mapi/glapi/gen/gl_API.xml
@@ -8337,7 +8337,9 @@
<!-- ARB extension #133 is ARB_multi_draw_indirect, defined in the same
file as ARB_draw_indirect -->
-<!-- ARB extensions #134...#138 -->
+<xi:include href="ARB_program_interface_query.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+<!-- ARB extensions #135...#138 -->
<xi:include href="ARB_texture_buffer_range.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
diff --git a/mesalib/src/mapi/glapi/gen/gl_genexec.py b/mesalib/src/mapi/glapi/gen/gl_genexec.py
index d479e66da..7151f0de1 100644
--- a/mesalib/src/mapi/glapi/gen/gl_genexec.py
+++ b/mesalib/src/mapi/glapi/gen/gl_genexec.py
@@ -92,6 +92,7 @@ header = """/**
#include "main/pixelstore.h"
#include "main/points.h"
#include "main/polygon.h"
+#include "main/program_resource.h"
#include "main/querymatrix.h"
#include "main/queryobj.h"
#include "main/readpix.h"
diff --git a/mesalib/src/mapi/stub.c b/mesalib/src/mapi/stub.c
index 05436bab6..45e4f7dc6 100644
--- a/mesalib/src/mapi/stub.c
+++ b/mesalib/src/mapi/stub.c
@@ -102,7 +102,7 @@ stub_add_dynamic(const char *name)
if (!stub->addr)
return NULL;
- stub->name = (const void *) name;
+ stub->name = (const void *) strdup(name);
/* to be fixed later */
stub->slot = -1;
diff --git a/mesalib/src/mesa/Makefile.am b/mesalib/src/mesa/Makefile.am
index 3dab8f03f..60114e4f6 100644
--- a/mesalib/src/mesa/Makefile.am
+++ b/mesalib/src/mesa/Makefile.am
@@ -174,6 +174,7 @@ endif
libmesa_la_SOURCES = \
$(MESA_FILES) \
$(PROGRAM_FILES) \
+ $(PROGRAM_NIR_FILES) \
$(MESA_ASM_FILES_FOR_ARCH)
libmesa_la_LIBADD = \
@@ -183,6 +184,7 @@ libmesa_la_LIBADD = \
libmesagallium_la_SOURCES = \
$(MESA_GALLIUM_FILES) \
$(PROGRAM_FILES) \
+ $(PROGRAM_NIR_FILES) \
$(MESA_ASM_FILES_FOR_ARCH)
libmesagallium_la_LIBADD = \
diff --git a/mesalib/src/mesa/Makefile.sources b/mesalib/src/mesa/Makefile.sources
index 217be9ab3..1293d4135 100644
--- a/mesalib/src/mesa/Makefile.sources
+++ b/mesalib/src/mesa/Makefile.sources
@@ -152,6 +152,8 @@ MAIN_FILES = \
main/points.h \
main/polygon.c \
main/polygon.h \
+ main/program_resource.c \
+ main/program_resource.h \
main/querymatrix.c \
main/querymatrix.h \
main/queryobj.c \
@@ -520,6 +522,10 @@ PROGRAM_FILES = \
program/symbol_table.c \
program/symbol_table.h
+PROGRAM_NIR_FILES = \
+ program/prog_to_nir.c \
+ program/prog_to_nir.h
+
ASM_C_FILES = \
x86/common_x86.c \
x86/x86_xform.c \
@@ -608,6 +614,7 @@ INCLUDE_DIRS = \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/glsl \
-I$(top_builddir)/src/glsl \
+ -I$(top_builddir)/src/glsl/nir \
-I$(top_srcdir)/src/glsl/glcpp \
-I$(top_srcdir)/src/mesa \
-I$(top_builddir)/src/mesa \
diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript
index a563fd2ff..5b80a216f 100644
--- a/mesalib/src/mesa/SConscript
+++ b/mesalib/src/mesa/SConscript
@@ -130,9 +130,10 @@ def write_git_sha1_h_file(filename):
(commit, foo) = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()
except:
# git log command didn't work
- dirname = os.path.dirname(filename)
- if not os.path.exists(dirname):
- os.makedirs(dirname)
+ if not os.path.exists(filename):
+ dirname = os.path.dirname(filename)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
# create an empty file if none already exists
f = open(filename, "w")
f.close()
diff --git a/mesalib/src/mesa/drivers/SConscript b/mesalib/src/mesa/drivers/SConscript
index 17813da96..db656780c 100644
--- a/mesalib/src/mesa/drivers/SConscript
+++ b/mesalib/src/mesa/drivers/SConscript
@@ -1,7 +1,5 @@
Import('*')
-SConscript('osmesa/SConscript')
-
if env['x11']:
SConscript('x11/SConscript')
diff --git a/mesalib/src/mesa/drivers/dri/common/utils.c b/mesalib/src/mesa/drivers/dri/common/utils.c
index bb22107e9..70d34e8ce 100644
--- a/mesalib/src/mesa/drivers/dri/common/utils.c
+++ b/mesalib/src/mesa/drivers/dri/common/utils.c
@@ -227,7 +227,7 @@ driCreateConfigs(mesa_format format,
break;
default:
fprintf(stderr, "[%s:%u] Unknown framebuffer type %s (%d).\n",
- __FUNCTION__, __LINE__,
+ __func__, __LINE__,
_mesa_get_format_name(format), format);
return NULL;
}
diff --git a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c
index 2b284ccf2..f17693e73 100644
--- a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c
+++ b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c
@@ -56,7 +56,7 @@ extern char *program_invocation_name, *program_invocation_short_name;
# include <stdlib.h>
# define GET_PROGRAM_NAME() getprogname()
# endif
-#elif defined(__NetBSD__) && defined(__NetBSD_Version) && (__NetBSD_Version >= 106000100)
+#elif defined(__NetBSD__) && defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 106000100)
# include <stdlib.h>
# define GET_PROGRAM_NAME() getprogname()
#elif defined(__APPLE__)
diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/Makefile.am b/mesalib/src/mesa/drivers/dri/common/xmlpool/Makefile.am
index 555771685..a6f1652d1 100644
--- a/mesalib/src/mesa/drivers/dri/common/xmlpool/Makefile.am
+++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/Makefile.am
@@ -52,14 +52,19 @@ POT=xmlpool.pot
.PHONY: all clean pot po mo
-EXTRA_DIST = gen_xmlpool.py options.h t_options.h $(POS) SConscript
-BUILT_SOURCES = options.h
-CLEANFILES = $(MOS) options.h
+EXTRA_DIST = \
+ gen_xmlpool.py \
+ options.h \
+ t_options.h \
+ $(POS) \
+ $(MOS) \
+ SConscript
-# All generated files are cleaned up.
-clean:
- -rm -f $(POT) options.h *~
- -rm -rf $(LANGS)
+BUILT_SOURCES = options.h
+CLEANFILES = \
+ options.h
+ $(POS) \
+ $(MOS)
# Default target options.h
options.h: LOCALEDIR := .
diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
index fb29078b6..d1bb72139 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c
+++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
@@ -326,7 +326,7 @@ choose_pixel_format(const struct gl_config *v)
&& v->blueMask == 0xc0)
return PF_R3G3B2;
- _mesa_problem( NULL, "unexpected format in %s", __FUNCTION__ );
+ _mesa_problem( NULL, "unexpected format in %s", __func__ );
return 0;
}
diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast_priv.h b/mesalib/src/mesa/drivers/dri/swrast/swrast_priv.h
index 1f3a48f38..a6ab53529 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/swrast_priv.h
+++ b/mesalib/src/mesa/drivers/dri/swrast/swrast_priv.h
@@ -41,13 +41,13 @@
#define DEBUG_SPAN 0
#if DEBUG_CORE
-#define TRACE printf("--> %s\n", __FUNCTION__)
+#define TRACE printf("--> %s\n", __func__)
#else
#define TRACE
#endif
#if DEBUG_SPAN
-#define TRACE_SPAN printf("--> %s\n", __FUNCTION__)
+#define TRACE_SPAN printf("--> %s\n", __func__)
#else
#define TRACE_SPAN
#endif
diff --git a/mesalib/src/mesa/main/.gitignore b/mesalib/src/mesa/main/.gitignore
index 8256ad792..355b426e2 100644
--- a/mesalib/src/mesa/main/.gitignore
+++ b/mesalib/src/mesa/main/.gitignore
@@ -7,5 +7,6 @@ remap_helper.h
get_hash.h
get_hash.h.tmp
format_info.h
+format_info.c
format_pack.c
format_unpack.c
diff --git a/mesalib/src/mesa/main/atifragshader.c b/mesalib/src/mesa/main/atifragshader.c
index 9d967b9e6..9fc35520a 100644
--- a/mesalib/src/mesa/main/atifragshader.c
+++ b/mesalib/src/mesa/main/atifragshader.c
@@ -476,7 +476,7 @@ _mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle)
curI->swizzle = swizzle;
#if MESA_DEBUG_ATI_FS
- _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__,
+ _mesa_debug(ctx, "%s(%s, %s, %s)\n", __func__,
_mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(coord),
_mesa_lookup_enum_by_nr(swizzle));
#endif
@@ -549,7 +549,7 @@ _mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle)
curI->swizzle = swizzle;
#if MESA_DEBUG_ATI_FS
- _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__,
+ _mesa_debug(ctx, "%s(%s, %s, %s)\n", __func__,
_mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(interp),
_mesa_lookup_enum_by_nr(swizzle));
#endif
diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c
index 20216a87d..b163c0aa6 100644
--- a/mesalib/src/mesa/main/attrib.c
+++ b/mesalib/src/mesa/main/attrib.c
@@ -32,7 +32,6 @@
#include "buffers.h"
#include "bufferobj.h"
#include "clear.h"
-#include "colormac.h"
#include "context.h"
#include "depth.h"
#include "enable.h"
diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c
index 965877084..66dee6802 100644
--- a/mesalib/src/mesa/main/bufferobj.c
+++ b/mesalib/src/mesa/main/bufferobj.c
@@ -1333,6 +1333,7 @@ create_buffers(GLsizei n, GLuint *buffers, bool dsa)
buf = ctx->Driver.NewBufferObject(ctx, buffers[i]);
if (!buf) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
+ mtx_unlock(&ctx->Shared->Mutex);
return;
}
}
@@ -3885,8 +3886,10 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
switch (target) {
case GL_TRANSFORM_FEEDBACK_BUFFER:
- _mesa_bind_buffer_range_transform_feedback(ctx, index, bufObj,
- offset, size);
+ _mesa_bind_buffer_range_transform_feedback(ctx,
+ ctx->TransformFeedback.CurrentObject,
+ index, bufObj, offset, size,
+ false);
return;
case GL_UNIFORM_BUFFER:
bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size);
@@ -3950,7 +3953,9 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
switch (target) {
case GL_TRANSFORM_FEEDBACK_BUFFER:
- _mesa_bind_buffer_base_transform_feedback(ctx, index, bufObj);
+ _mesa_bind_buffer_base_transform_feedback(ctx,
+ ctx->TransformFeedback.CurrentObject,
+ index, bufObj, false);
return;
case GL_UNIFORM_BUFFER:
bind_buffer_base_uniform_buffer(ctx, index, bufObj);
diff --git a/mesalib/src/mesa/main/colormac.h b/mesalib/src/mesa/main/colormac.h
index bc69f4673..33ca5af07 100644
--- a/mesalib/src/mesa/main/colormac.h
+++ b/mesalib/src/mesa/main/colormac.h
@@ -52,70 +52,25 @@ _mesa_unclamped_float_rgba_to_ubyte(GLubyte dst[4], const GLfloat src[4])
/**
* \name Generic color packing macros. All inputs should be GLubytes.
- *
- * \todo We may move these into texstore.h at some point.
*/
/*@{*/
#define PACK_COLOR_8888( X, Y, Z, W ) \
(((X) << 24) | ((Y) << 16) | ((Z) << 8) | (W))
-#define PACK_COLOR_8888_REV( X, Y, Z, W ) \
- (((W) << 24) | ((Z) << 16) | ((Y) << 8) | (X))
-
-#define PACK_COLOR_888( X, Y, Z ) \
- (((X) << 16) | ((Y) << 8) | (Z))
-
#define PACK_COLOR_565( X, Y, Z ) \
((((X) & 0xf8) << 8) | (((Y) & 0xfc) << 3) | (((Z) & 0xf8) >> 3))
-#define PACK_COLOR_5551( R, G, B, A ) \
- ((((R) & 0xf8) << 8) | (((G) & 0xf8) << 3) | (((B) & 0xf8) >> 2) | \
- ((A) >> 7))
-
#define PACK_COLOR_1555( A, B, G, R ) \
((((B) & 0xf8) << 7) | (((G) & 0xf8) << 2) | (((R) & 0xf8) >> 3) | \
(((A) & 0x80) << 8))
-#define PACK_COLOR_1555_REV( A, B, G, R ) \
- ((((B) & 0xf8) >> 1) | (((G) & 0xc0) >> 6) | (((G) & 0x38) << 10) | (((R) & 0xf8) << 5) | \
- ((A) ? 0x80 : 0))
-
-#define PACK_COLOR_2101010_UB( A, B, G, R ) \
- (((B) << 22) | ((G) << 12) | ((R) << 2) | \
- (((A) & 0xc0) << 24))
-
-#define PACK_COLOR_2101010_US( A, B, G, R ) \
- ((((B) >> 6) << 20) | (((G) >> 6) << 10) | ((R) >> 6) | \
- (((A) >> 14) << 30))
-
#define PACK_COLOR_4444( R, G, B, A ) \
((((R) & 0xf0) << 8) | (((G) & 0xf0) << 4) | ((B) & 0xf0) | ((A) >> 4))
-#define PACK_COLOR_4444_REV( R, G, B, A ) \
- ((((B) & 0xf0) << 8) | (((A) & 0xf0) << 4) | ((R) & 0xf0) | ((G) >> 4))
-
-#define PACK_COLOR_44( L, A ) \
- (((L) & 0xf0) | (((A) & 0xf0) >> 4))
-
#define PACK_COLOR_88( L, A ) \
(((L) << 8) | (A))
-#define PACK_COLOR_88_REV( L, A ) \
- (((A) << 8) | (L))
-
-#define PACK_COLOR_1616( L, A ) \
- (((L) << 16) | (A))
-
-#define PACK_COLOR_1616_REV( L, A ) \
- (((A) << 16) | (L))
-
-#define PACK_COLOR_332( R, G, B ) \
- (((R) & 0xe0) | (((G) & 0xe0) >> 3) | (((B) & 0xc0) >> 6))
-
-#define PACK_COLOR_233( B, G, R ) \
- (((B) & 0xc0) | (((G) & 0xe0) >> 2) | (((R) & 0xe0) >> 5))
-
/*@}*/
diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c
index c1acda980..adf64976e 100644
--- a/mesalib/src/mesa/main/context.c
+++ b/mesalib/src/mesa/main/context.c
@@ -1288,7 +1288,6 @@ _mesa_free_context_data( struct gl_context *ctx )
_mesa_free_eval_data( ctx );
_mesa_free_texture_data( ctx );
_mesa_free_matrix_data( ctx );
- _mesa_free_viewport_data( ctx );
_mesa_free_pipeline_data(ctx);
_mesa_free_program_data(ctx);
_mesa_free_shader_state(ctx);
@@ -1449,17 +1448,10 @@ _mesa_copy_context( const struct gl_context *src, struct gl_context *dst,
dst->Transform = src->Transform;
}
if (mask & GL_VIEWPORT_BIT) {
- /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
unsigned i;
for (i = 0; i < src->Const.MaxViewports; i++) {
- dst->ViewportArray[i].X = src->ViewportArray[i].X;
- dst->ViewportArray[i].Y = src->ViewportArray[i].Y;
- dst->ViewportArray[i].Width = src->ViewportArray[i].Width;
- dst->ViewportArray[i].Height = src->ViewportArray[i].Height;
- dst->ViewportArray[i].Near = src->ViewportArray[i].Near;
- dst->ViewportArray[i].Far = src->ViewportArray[i].Far;
- _math_matrix_copy(&dst->ViewportArray[i]._WindowMap,
- &src->ViewportArray[i]._WindowMap);
+ /* OK to memcpy */
+ dst->ViewportArray[i] = src->ViewportArray[i];
}
}
diff --git a/mesalib/src/mesa/main/debug.c b/mesalib/src/mesa/main/debug.c
index b50d79e0c..c93e84a04 100644
--- a/mesalib/src/mesa/main/debug.c
+++ b/mesalib/src/mesa/main/debug.c
@@ -26,11 +26,11 @@
#include <stdio.h>
#include "mtypes.h"
#include "attrib.h"
-#include "colormac.h"
#include "enums.h"
#include "formats.h"
#include "hash.h"
#include "imports.h"
+#include "macros.h"
#include "debug.h"
#include "get.h"
#include "pixelstore.h"
diff --git a/mesalib/src/mesa/main/dlopen.h b/mesalib/src/mesa/main/dlopen.h
index 1e7784914..4d20ff2c7 100644
--- a/mesalib/src/mesa/main/dlopen.h
+++ b/mesalib/src/mesa/main/dlopen.h
@@ -50,7 +50,7 @@ _mesa_dlopen(const char *libname, int flags)
#if defined(HAVE_DLOPEN)
flags = RTLD_LAZY | RTLD_GLOBAL; /* Overriding flags at this time */
return dlopen(libname, flags);
-#elif defined(__MINGW32__)
+#elif defined(_WIN32)
return LoadLibraryA(libname);
#else
return NULL;
@@ -71,7 +71,7 @@ _mesa_dlsym(void *handle, const char *fname)
} u;
#if defined(HAVE_DLOPEN)
u.v = dlsym(handle, fname);
-#elif defined(__MINGW32__)
+#elif defined(_WIN32)
u.v = (void *) GetProcAddress(handle, fname);
#else
u.v = NULL;
@@ -87,7 +87,7 @@ _mesa_dlclose(void *handle)
{
#if defined(HAVE_DLOPEN)
dlclose(handle);
-#elif defined(__MINGW32__)
+#elif defined(_WIN32)
FreeLibrary(handle);
#else
(void) handle;
diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c
index 8ffbf413c..2aa1deb63 100644
--- a/mesalib/src/mesa/main/errors.c
+++ b/mesalib/src/mesa/main/errors.c
@@ -1232,12 +1232,14 @@ _mesa_free_errors_data(struct gl_context *ctx)
/** \name Diagnostics */
/*@{*/
+static FILE *LogFile = NULL;
+
+
static void
output_if_debug(const char *prefixString, const char *outputString,
GLboolean newline)
{
static int debug = -1;
- static FILE *fout = NULL;
/* Init the local 'debug' var once.
* Note: the _mesa_init_debug() function should have been called
@@ -1249,9 +1251,9 @@ output_if_debug(const char *prefixString, const char *outputString,
*/
const char *logFile = getenv("MESA_LOG_FILE");
if (logFile)
- fout = fopen(logFile, "w");
- if (!fout)
- fout = stderr;
+ LogFile = fopen(logFile, "w");
+ if (!LogFile)
+ LogFile = stderr;
#ifdef DEBUG
/* in debug builds, print messages unless MESA_DEBUG="silent" */
if (MESA_DEBUG_FLAGS & DEBUG_SILENT)
@@ -1266,10 +1268,13 @@ output_if_debug(const char *prefixString, const char *outputString,
/* Now only print the string if we're required to do so. */
if (debug) {
- fprintf(fout, "%s: %s", prefixString, outputString);
+ if (prefixString)
+ fprintf(LogFile, "%s: %s", prefixString, outputString);
+ else
+ fprintf(LogFile, "%s", outputString);
if (newline)
- fprintf(fout, "\n");
- fflush(fout);
+ fprintf(LogFile, "\n");
+ fflush(LogFile);
#if defined(_WIN32)
/* stderr from windows applications without console is not usually
@@ -1285,6 +1290,18 @@ output_if_debug(const char *prefixString, const char *outputString,
/**
+ * Return the file handle to use for debug/logging. Defaults to stderr
+ * unless MESA_LOG_FILE is defined.
+ */
+FILE *
+_mesa_get_log_file(void)
+{
+ assert(LogFile);
+ return LogFile;
+}
+
+
+/**
* When a new type of error is recorded, print a message describing
* previous errors which were accumulated.
*/
@@ -1525,6 +1542,18 @@ _mesa_debug( const struct gl_context *ctx, const char *fmtString, ... )
}
+void
+_mesa_log(const char *fmtString, ...)
+{
+ char s[MAX_DEBUG_MESSAGE_LENGTH];
+ va_list args;
+ va_start(args, fmtString);
+ _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
+ va_end(args);
+ output_if_debug("", s, GL_FALSE);
+}
+
+
/**
* Report debug information from the shader compiler via GL_ARB_debug_output.
*
diff --git a/mesalib/src/mesa/main/errors.h b/mesalib/src/mesa/main/errors.h
index 0c521c0d0..e6dc9b5f1 100644
--- a/mesalib/src/mesa/main/errors.h
+++ b/mesalib/src/mesa/main/errors.h
@@ -36,6 +36,7 @@
#define ERRORS_H
+#include <stdio.h>
#include "compiler.h"
#include "glheader.h"
#include "mtypes.h"
@@ -69,6 +70,12 @@ extern void
_mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) PRINTFLIKE(2, 3);
extern void
+_mesa_log(const char *fmtString, ...) PRINTFLIKE(1, 2);
+
+extern FILE *
+_mesa_get_log_file(void);
+
+extern void
_mesa_gl_debug(struct gl_context *ctx,
GLuint *id,
enum mesa_debug_source source,
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index f21201538..861b15006 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -139,6 +139,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_pixel_buffer_object", o(EXT_pixel_buffer_object), GL, 2004 },
{ "GL_ARB_point_parameters", o(EXT_point_parameters), GLL, 1997 },
{ "GL_ARB_point_sprite", o(ARB_point_sprite), GL, 2003 },
+ { "GL_ARB_program_interface_query", o(dummy_true), GL, 2012 },
{ "GL_ARB_provoking_vertex", o(EXT_provoking_vertex), GL, 2009 },
{ "GL_ARB_robustness", o(dummy_true), GL, 2010 },
{ "GL_ARB_sample_shading", o(ARB_sample_shading), GL, 2009 },
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index f8d0d92bf..8032585ab 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -212,13 +212,13 @@ get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
*/
i = attachment - GL_COLOR_ATTACHMENT0_EXT;
if (i >= ctx->Const.MaxColorAttachments
- || (i > 0 && ctx->API == API_OPENGLES)) {
- return NULL;
+ || (i > 0 && ctx->API == API_OPENGLES)) {
+ return NULL;
}
return &fb->Attachment[BUFFER_COLOR0 + i];
case GL_DEPTH_STENCIL_ATTACHMENT:
if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
- return NULL;
+ return NULL;
/* fall-through */
case GL_DEPTH_ATTACHMENT_EXT:
return &fb->Attachment[BUFFER_DEPTH];
@@ -1122,28 +1122,28 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
if (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_ES2_compatibility) {
/* Check that all DrawBuffers are present */
for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) {
- if (fb->ColorDrawBuffer[j] != GL_NONE) {
- const struct gl_renderbuffer_attachment *att
- = get_attachment(ctx, fb, fb->ColorDrawBuffer[j]);
- assert(att);
- if (att->Type == GL_NONE) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT;
- fbo_incomplete(ctx, "missing drawbuffer", j);
- return;
- }
- }
+ if (fb->ColorDrawBuffer[j] != GL_NONE) {
+ const struct gl_renderbuffer_attachment *att
+ = get_attachment(ctx, fb, fb->ColorDrawBuffer[j]);
+ assert(att);
+ if (att->Type == GL_NONE) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT;
+ fbo_incomplete(ctx, "missing drawbuffer", j);
+ return;
+ }
+ }
}
/* Check that the ReadBuffer is present */
if (fb->ColorReadBuffer != GL_NONE) {
- const struct gl_renderbuffer_attachment *att
- = get_attachment(ctx, fb, fb->ColorReadBuffer);
- assert(att);
- if (att->Type == GL_NONE) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT;
+ const struct gl_renderbuffer_attachment *att
+ = get_attachment(ctx, fb, fb->ColorReadBuffer);
+ assert(att);
+ if (att->Type == GL_NONE) {
+ fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT;
fbo_incomplete(ctx, "missing readbuffer", -1);
- return;
- }
+ return;
+ }
}
}
@@ -1205,6 +1205,28 @@ _mesa_IsRenderbuffer(GLuint renderbuffer)
}
+static struct gl_renderbuffer *
+allocate_renderbuffer(struct gl_context *ctx, GLuint renderbuffer,
+ const char *func)
+{
+ struct gl_renderbuffer *newRb;
+
+ /* create new renderbuffer object */
+ newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer);
+ if (!newRb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
+ return NULL;
+ }
+ assert(newRb->AllocStorage);
+ mtx_lock(&ctx->Shared->Mutex);
+ _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb);
+ newRb->RefCount = 1; /* referenced by hash table */
+ mtx_unlock(&ctx->Shared->Mutex);
+
+ return newRb;
+}
+
+
static void
bind_renderbuffer(GLenum target, GLuint renderbuffer, bool allow_user_names)
{
@@ -1233,15 +1255,7 @@ bind_renderbuffer(GLenum target, GLuint renderbuffer, bool allow_user_names)
}
if (!newRb) {
- /* create new renderbuffer object */
- newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer);
- if (!newRb) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindRenderbufferEXT");
- return;
- }
- assert(newRb->AllocStorage);
- _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb);
- newRb->RefCount = 1; /* referenced by hash table */
+ newRb = allocate_renderbuffer(ctx, renderbuffer, "glBindRenderbufferEXT");
}
}
else {
@@ -1333,9 +1347,9 @@ _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
for (i = 0; i < n; i++) {
if (renderbuffers[i] > 0) {
- struct gl_renderbuffer *rb;
- rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]);
- if (rb) {
+ struct gl_renderbuffer *rb;
+ rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]);
+ if (rb) {
/* check if deleting currently bound renderbuffer object */
if (rb == ctx->CurrentRenderbuffer) {
/* bind default */
@@ -1368,31 +1382,31 @@ _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
_mesa_detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
}
- /* Remove from hash table immediately, to free the ID.
+ /* Remove from hash table immediately, to free the ID.
* But the object will not be freed until it's no longer
* referenced anywhere else.
*/
- _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
+ _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
if (rb != &DummyRenderbuffer) {
/* no longer referenced by hash table */
_mesa_reference_renderbuffer(&rb, NULL);
- }
- }
+ }
+ }
}
}
}
-
-void GLAPIENTRY
-_mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers)
+static void
+create_render_buffers(struct gl_context *ctx, GLsizei n, GLuint *renderbuffers,
+ bool dsa)
{
- GET_CURRENT_CONTEXT(ctx);
+ const char *func = dsa ? "glCreateRenderbuffers" : "glGenRenderbuffers";
GLuint first;
GLint i;
if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenRenderbuffersEXT(n)");
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(n<0)", func);
return;
}
@@ -1404,14 +1418,35 @@ _mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers)
for (i = 0; i < n; i++) {
GLuint name = first + i;
renderbuffers[i] = name;
- /* insert dummy placeholder into hash table */
- mtx_lock(&ctx->Shared->Mutex);
- _mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer);
- mtx_unlock(&ctx->Shared->Mutex);
+
+ if (dsa) {
+ allocate_renderbuffer(ctx, name, func);
+ } else {
+ /* insert a dummy renderbuffer into the hash table */
+ mtx_lock(&ctx->Shared->Mutex);
+ _mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer);
+ mtx_unlock(&ctx->Shared->Mutex);
+ }
}
}
+void GLAPIENTRY
+_mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ create_render_buffers(ctx, n, renderbuffers, false);
+}
+
+
+void GLAPIENTRY
+_mesa_CreateRenderbuffers(GLsizei n, GLuint *renderbuffers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ create_render_buffers(ctx, n, renderbuffers, true);
+}
+
+
/**
* Given an internal format token for a render buffer, return the
* corresponding base format (one of GL_RGB, GL_RGBA, GL_STENCIL_INDEX,
@@ -1749,40 +1784,17 @@ invalidate_rb(GLuint key, void *data, void *userData)
/**
- * Helper function used by _mesa_RenderbufferStorage() and
- * _mesa_RenderbufferStorageMultisample().
- * samples will be NO_SAMPLES if called by _mesa_RenderbufferStorage().
+ * Helper function used by renderbuffer_storage_direct() and
+ * renderbuffer_storage_target().
+ * samples will be NO_SAMPLES if called by a non-multisample function.
*/
static void
-renderbuffer_storage(GLenum target, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei samples)
+renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei samples, const char *func)
{
- const char *func = samples == NO_SAMPLES ?
- "glRenderbufferStorage" : "glRenderbufferStorageMultisample";
- struct gl_renderbuffer *rb;
GLenum baseFormat;
GLenum sample_count_error;
- GET_CURRENT_CONTEXT(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API) {
- if (samples == NO_SAMPLES)
- _mesa_debug(ctx, "%s(%s, %s, %d, %d)\n",
- func,
- _mesa_lookup_enum_by_nr(target),
- _mesa_lookup_enum_by_nr(internalFormat),
- width, height);
- else
- _mesa_debug(ctx, "%s(%s, %s, %d, %d, %d)\n",
- func,
- _mesa_lookup_enum_by_nr(target),
- _mesa_lookup_enum_by_nr(internalFormat),
- width, height, samples);
- }
-
- if (target != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
- return;
- }
baseFormat = _mesa_base_fbo_format(ctx, internalFormat);
if (baseFormat == 0) {
@@ -1792,12 +1804,14 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
}
if (width < 0 || width > (GLsizei) ctx->Const.MaxRenderbufferSize) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(width)", func);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid width %d)", func,
+ width);
return;
}
if (height < 0 || height > (GLsizei) ctx->Const.MaxRenderbufferSize) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(height)", func);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid height %d)", func,
+ height);
return;
}
@@ -1809,7 +1823,7 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
/* check the sample count;
* note: driver may choose to use more samples than what's requested
*/
- sample_count_error = _mesa_check_sample_count(ctx, target,
+ sample_count_error = _mesa_check_sample_count(ctx, GL_RENDERBUFFER,
internalFormat, samples);
if (sample_count_error != GL_NO_ERROR) {
_mesa_error(ctx, sample_count_error, "%s(samples)", func);
@@ -1817,12 +1831,6 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
}
}
- rb = ctx->CurrentRenderbuffer;
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", func);
- return;
- }
-
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
if (rb->InternalFormat == internalFormat &&
@@ -1864,6 +1872,83 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
}
}
+/**
+ * Helper function used by _mesa_NamedRenderbufferStorage*().
+ * samples will be NO_SAMPLES if called by a non-multisample function.
+ */
+static void
+renderbuffer_storage_named(GLuint renderbuffer, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei samples,
+ const char *func)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API) {
+ if (samples == NO_SAMPLES)
+ _mesa_debug(ctx, "%s(%u, %s, %d, %d)\n",
+ func, renderbuffer,
+ _mesa_lookup_enum_by_nr(internalFormat),
+ width, height);
+ else
+ _mesa_debug(ctx, "%s(%u, %s, %d, %d, %d)\n",
+ func, renderbuffer,
+ _mesa_lookup_enum_by_nr(internalFormat),
+ width, height, samples);
+ }
+
+ struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
+ if (!rb || rb == &DummyRenderbuffer) {
+ /* ID was reserved, but no real renderbuffer object made yet */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid renderbuffer %u)",
+ func, renderbuffer);
+ return;
+ }
+
+ renderbuffer_storage(ctx, rb, internalFormat, width, height, samples, func);
+}
+
+/**
+ * Helper function used by _mesa_RenderbufferStorage() and
+ * _mesa_RenderbufferStorageMultisample().
+ * samples will be NO_SAMPLES if called by _mesa_RenderbufferStorage().
+ */
+static void
+renderbuffer_storage_target(GLenum target, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei samples,
+ const char *func)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API) {
+ if (samples == NO_SAMPLES)
+ _mesa_debug(ctx, "%s(%s, %s, %d, %d)\n",
+ func,
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(internalFormat),
+ width, height);
+ else
+ _mesa_debug(ctx, "%s(%s, %s, %d, %d, %d)\n",
+ func,
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(internalFormat),
+ width, height, samples);
+ }
+
+ if (target != GL_RENDERBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
+ return;
+ }
+
+ if (!ctx->CurrentRenderbuffer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no renderbuffer bound)",
+ func);
+ return;
+ }
+
+ renderbuffer_storage(ctx, ctx->CurrentRenderbuffer, internalFormat, width,
+ height, samples, func);
+}
+
void GLAPIENTRY
_mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
@@ -1923,7 +2008,8 @@ _mesa_RenderbufferStorage(GLenum target, GLenum internalFormat,
* glRenderbufferStorageMultisample() with samples=0. We pass in
* a token value here just for error reporting purposes.
*/
- renderbuffer_storage(target, internalFormat, width, height, NO_SAMPLES);
+ renderbuffer_storage_target(target, internalFormat, width, height,
+ NO_SAMPLES, "glRenderbufferStorage");
}
@@ -1932,7 +2018,8 @@ _mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
GLenum internalFormat,
GLsizei width, GLsizei height)
{
- renderbuffer_storage(target, internalFormat, width, height, samples);
+ renderbuffer_storage_target(target, internalFormat, width, height,
+ samples, "glRenderbufferStorageMultisample");
}
@@ -1941,7 +2028,7 @@ _mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
*/
void GLAPIENTRY
_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
- GLsizei width, GLsizei height)
+ GLsizei width, GLsizei height)
{
switch (internalFormat) {
case GL_RGB565:
@@ -1953,29 +2040,38 @@ _es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
break;
}
- renderbuffer_storage(target, internalFormat, width, height, 0);
+ renderbuffer_storage_target(target, internalFormat, width, height, 0,
+ "glRenderbufferStorageEXT");
}
-
void GLAPIENTRY
-_mesa_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
+_mesa_NamedRenderbufferStorage(GLuint renderbuffer, GLenum internalformat,
+ GLsizei width, GLsizei height)
{
- struct gl_renderbuffer *rb;
- GET_CURRENT_CONTEXT(ctx);
+ /* GL_ARB_fbo says calling this function is equivalent to calling
+ * glRenderbufferStorageMultisample() with samples=0. We pass in
+ * a token value here just for error reporting purposes.
+ */
+ renderbuffer_storage_named(renderbuffer, internalformat, width, height,
+ NO_SAMPLES, "glNamedRenderbufferStorage");
+}
- if (target != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetRenderbufferParameterivEXT(target)");
- return;
- }
+void GLAPIENTRY
+_mesa_NamedRenderbufferStorageMultisample(GLuint renderbuffer, GLsizei samples,
+ GLenum internalformat,
+ GLsizei width, GLsizei height)
+{
+ renderbuffer_storage_named(renderbuffer, internalformat, width, height,
+ samples,
+ "glNamedRenderbufferStorageMultisample");
+}
- rb = ctx->CurrentRenderbuffer;
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetRenderbufferParameterivEXT");
- return;
- }
+static void
+get_render_buffer_parameteriv(struct gl_context *ctx,
+ struct gl_renderbuffer *rb, GLenum pname,
+ GLint *params, const char *func)
+{
/* No need to flush here since we're just quering state which is
* not effected by rendering.
*/
@@ -2006,10 +2102,51 @@ _mesa_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
}
/* fallthrough */
default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname=%s)", func,
+ _mesa_lookup_enum_by_nr(pname));
+ return;
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (target != GL_RENDERBUFFER_EXT) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetRenderbufferParameterivEXT(target)");
return;
}
+
+ if (!ctx->CurrentRenderbuffer) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetRenderbufferParameterivEXT"
+ "(no renderbuffer bound)");
+ return;
+ }
+
+ get_render_buffer_parameteriv(ctx, ctx->CurrentRenderbuffer, pname,
+ params, "glGetRenderbufferParameteriv");
+}
+
+
+void GLAPIENTRY
+_mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname,
+ GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
+ if (!rb || rb == &DummyRenderbuffer) {
+ /* ID was reserved, but no real renderbuffer object made yet */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetNamedRenderbufferParameteriv"
+ "(invalid renderbuffer %i)", renderbuffer);
+ return;
+ }
+
+ get_render_buffer_parameteriv(ctx, rb, pname, params,
+ "glGetNamedRenderbufferParameteriv");
}
@@ -2116,12 +2253,12 @@ bind_framebuffer(GLenum target, GLuint framebuffer, bool allow_user_names)
}
if (!newDrawFb) {
- /* create new framebuffer object */
- newDrawFb = ctx->Driver.NewFramebuffer(ctx, framebuffer);
- if (!newDrawFb) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
- return;
- }
+ /* create new framebuffer object */
+ newDrawFb = ctx->Driver.NewFramebuffer(ctx, framebuffer);
+ if (!newDrawFb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
+ return;
+ }
_mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newDrawFb);
}
newReadFb = newDrawFb;
@@ -2224,9 +2361,9 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
for (i = 0; i < n; i++) {
if (framebuffers[i] > 0) {
- struct gl_framebuffer *fb;
- fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]);
- if (fb) {
+ struct gl_framebuffer *fb;
+ fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]);
+ if (fb) {
assert(fb == &DummyFramebuffer || fb->Name == framebuffers[i]);
/* check if deleting currently bound framebuffer object */
@@ -2241,16 +2378,16 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
_mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
- /* remove from hash table immediately, to free the ID */
- _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);
+ /* remove from hash table immediately, to free the ID */
+ _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);
if (fb != &DummyFramebuffer) {
/* But the object will not be freed until it's no longer
* bound in any context.
*/
_mesa_reference_framebuffer(&fb, NULL);
- }
- }
+ }
+ }
}
}
}
@@ -2498,34 +2635,34 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
_mesa_tex_target_to_face(textarget) ==
fb->Attachment[BUFFER_STENCIL].CubeMapFace &&
zoffset == fb->Attachment[BUFFER_STENCIL].Zoffset) {
- /* The texture object is already attached to the stencil attachment
- * point. Don't create a new renderbuffer; just reuse the stencil
- * attachment's. This is required to prevent a GL error in
- * glGetFramebufferAttachmentParameteriv(GL_DEPTH_STENCIL).
- */
- reuse_framebuffer_texture_attachment(fb, BUFFER_DEPTH,
- BUFFER_STENCIL);
+ /* The texture object is already attached to the stencil attachment
+ * point. Don't create a new renderbuffer; just reuse the stencil
+ * attachment's. This is required to prevent a GL error in
+ * glGetFramebufferAttachmentParameteriv(GL_DEPTH_STENCIL).
+ */
+ reuse_framebuffer_texture_attachment(fb, BUFFER_DEPTH,
+ BUFFER_STENCIL);
} else if (attachment == GL_STENCIL_ATTACHMENT &&
- texObj == fb->Attachment[BUFFER_DEPTH].Texture &&
+ texObj == fb->Attachment[BUFFER_DEPTH].Texture &&
level == fb->Attachment[BUFFER_DEPTH].TextureLevel &&
_mesa_tex_target_to_face(textarget) ==
fb->Attachment[BUFFER_DEPTH].CubeMapFace &&
zoffset == fb->Attachment[BUFFER_DEPTH].Zoffset) {
- /* As above, but with depth and stencil transposed. */
- reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL,
- BUFFER_DEPTH);
+ /* As above, but with depth and stencil transposed. */
+ reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL,
+ BUFFER_DEPTH);
} else {
- set_texture_attachment(ctx, fb, att, texObj, textarget,
- level, zoffset, layered);
- if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
- /* Above we created a new renderbuffer and attached it to the
- * depth attachment point. Now attach it to the stencil attachment
- * point too.
- */
- assert(att == &fb->Attachment[BUFFER_DEPTH]);
- reuse_framebuffer_texture_attachment(fb,BUFFER_STENCIL,
- BUFFER_DEPTH);
- }
+ set_texture_attachment(ctx, fb, att, texObj, textarget,
+ level, zoffset, layered);
+ if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
+ /* Above we created a new renderbuffer and attached it to the
+ * depth attachment point. Now attach it to the stencil attachment
+ * point too.
+ */
+ assert(att == &fb->Attachment[BUFFER_DEPTH]);
+ reuse_framebuffer_texture_attachment(fb,BUFFER_STENCIL,
+ BUFFER_DEPTH);
+ }
}
/* Set the render-to-texture flag. We'll check this flag in
@@ -2541,8 +2678,8 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
else {
remove_attachment(ctx, att);
if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
- assert(att == &fb->Attachment[BUFFER_DEPTH]);
- remove_attachment(ctx, &fb->Attachment[BUFFER_STENCIL]);
+ assert(att == &fb->Attachment[BUFFER_DEPTH]);
+ remove_attachment(ctx, &fb->Attachment[BUFFER_STENCIL]);
}
}
@@ -2721,16 +2858,16 @@ _mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
if (renderbuffer) {
rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferRenderbuffer(non-existant"
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferRenderbuffer(non-existant"
" renderbuffer %u)", renderbuffer);
- return;
+ return;
}
else if (rb == &DummyRenderbuffer) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferRenderbuffer(renderbuffer %u)",
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferRenderbuffer(renderbuffer %u)",
renderbuffer);
- return;
+ return;
}
}
else {
@@ -2795,9 +2932,9 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
if ((!_mesa_is_desktop_gl(ctx) ||
!ctx->Extensions.ARB_framebuffer_object)
&& !_mesa_is_gles3(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameteriv(bound FBO = 0)");
- return;
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferAttachmentParameteriv(bound FBO = 0)");
+ return;
}
if (_mesa_is_gles3(ctx) && attachment != GL_BACK &&
@@ -2855,10 +2992,10 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
return;
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
if (att->Type == GL_RENDERBUFFER_EXT) {
- *params = att->Renderbuffer->Name;
+ *params = att->Renderbuffer->Name;
}
else if (att->Type == GL_TEXTURE) {
- *params = att->Texture->Name;
+ *params = att->Texture->Name;
}
else {
assert(att->Type == GL_NONE);
@@ -2871,7 +3008,7 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
return;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
if (att->Type == GL_TEXTURE) {
- *params = att->TextureLevel;
+ *params = att->TextureLevel;
}
else if (att->Type == GL_NONE) {
_mesa_error(ctx, err,
diff --git a/mesalib/src/mesa/main/fbobject.h b/mesalib/src/mesa/main/fbobject.h
index 77fdef415..61aa1f503 100644
--- a/mesalib/src/mesa/main/fbobject.h
+++ b/mesalib/src/mesa/main/fbobject.h
@@ -115,6 +115,9 @@ extern void GLAPIENTRY
_mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers);
extern void GLAPIENTRY
+_mesa_CreateRenderbuffers(GLsizei n, GLuint *renderbuffers);
+
+extern void GLAPIENTRY
_mesa_RenderbufferStorage(GLenum target, GLenum internalformat,
GLsizei width, GLsizei height);
@@ -128,12 +131,25 @@ _es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height);
extern void GLAPIENTRY
+_mesa_NamedRenderbufferStorage(GLuint renderbuffer, GLenum internalformat,
+ GLsizei width, GLsizei height);
+
+extern void GLAPIENTRY
+_mesa_NamedRenderbufferStorageMultisample(GLuint renderbuffer, GLsizei samples,
+ GLenum internalformat,
+ GLsizei width, GLsizei height);
+
+extern void GLAPIENTRY
_mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
extern void GLAPIENTRY
_mesa_GetRenderbufferParameteriv(GLenum target, GLenum pname,
GLint *params);
+void GLAPIENTRY
+_mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname,
+ GLint *params);
+
extern GLboolean GLAPIENTRY
_mesa_IsFramebuffer(GLuint framebuffer);
diff --git a/mesalib/src/mesa/main/ffvertex_prog.c b/mesalib/src/mesa/main/ffvertex_prog.c
index 395b00e15..edf7e3390 100644
--- a/mesalib/src/mesa/main/ffvertex_prog.c
+++ b/mesalib/src/mesa/main/ffvertex_prog.c
@@ -619,13 +619,13 @@ static void emit_op3fn(struct tnl_program *p,
#define emit_op3(p, op, dst, mask, src0, src1, src2) \
- emit_op3fn(p, op, dst, mask, src0, src1, src2, __FUNCTION__, __LINE__)
+ emit_op3fn(p, op, dst, mask, src0, src1, src2, __func__, __LINE__)
#define emit_op2(p, op, dst, mask, src0, src1) \
- emit_op3fn(p, op, dst, mask, src0, src1, undef, __FUNCTION__, __LINE__)
+ emit_op3fn(p, op, dst, mask, src0, src1, undef, __func__, __LINE__)
#define emit_op1(p, op, dst, mask, src0) \
- emit_op3fn(p, op, dst, mask, src0, undef, undef, __FUNCTION__, __LINE__)
+ emit_op3fn(p, op, dst, mask, src0, undef, undef, __func__, __LINE__)
static struct ureg make_temp( struct tnl_program *p, struct ureg reg )
diff --git a/mesalib/src/mesa/main/format_pack.py b/mesalib/src/mesa/main/format_pack.py
index f141da83c..2f43a30dd 100644
--- a/mesalib/src/mesa/main/format_pack.py
+++ b/mesalib/src/mesa/main/format_pack.py
@@ -43,7 +43,6 @@ string = """/*
#include <stdint.h>
-#include "colormac.h"
#include "format_pack.h"
#include "format_utils.h"
#include "macros.h"
diff --git a/mesalib/src/mesa/main/format_unpack.h b/mesalib/src/mesa/main/format_unpack.h
index eba3c6650..964c6077a 100644
--- a/mesalib/src/mesa/main/format_unpack.h
+++ b/mesalib/src/mesa/main/format_unpack.h
@@ -25,6 +25,8 @@
#ifndef FORMAT_UNPACK_H
#define FORMAT_UNPACK_H
+#include "formats.h"
+
extern void
_mesa_unpack_rgba_row(mesa_format format, GLuint n,
const void *src, GLfloat dst[][4]);
diff --git a/mesalib/src/mesa/main/format_unpack.py b/mesalib/src/mesa/main/format_unpack.py
index 53bdf641d..0ae73b897 100644
--- a/mesalib/src/mesa/main/format_unpack.py
+++ b/mesalib/src/mesa/main/format_unpack.py
@@ -43,7 +43,6 @@ string = """/*
#include <stdint.h>
-#include "colormac.h"
#include "format_unpack.h"
#include "format_utils.h"
#include "macros.h"
@@ -333,7 +332,7 @@ _mesa_unpack_rgba_row(mesa_format format, GLuint n,
unpack_float_ycbcr_rev(src, dst, n);
break;
default:
- _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__,
+ _mesa_problem(NULL, "%s: bad format %s", __func__,
_mesa_get_format_name(format));
return;
}
@@ -402,7 +401,7 @@ _mesa_unpack_uint_rgba_row(mesa_format format, GLuint n,
break;
%endfor
default:
- _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__,
+ _mesa_problem(NULL, "%s: bad format %s", __func__,
_mesa_get_format_name(format));
return;
}
diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c
index 4e05229cf..8ced57949 100644
--- a/mesalib/src/mesa/main/glformats.c
+++ b/mesalib/src/mesa/main/glformats.c
@@ -1393,7 +1393,7 @@ _mesa_base_format_has_channel(GLenum base_format, GLenum pname)
return GL_FALSE;
default:
_mesa_warning(NULL, "%s: Unexpected channel token 0x%x\n",
- __FUNCTION__, pname);
+ __func__, pname);
return GL_FALSE;
}
diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h
index 29f249980..c4d917ebb 100644
--- a/mesalib/src/mesa/main/imports.h
+++ b/mesalib/src/mesa/main/imports.h
@@ -433,6 +433,30 @@ _mesa_fls(unsigned int n)
#endif
}
+/**
+ * Find the last (most significant) bit set in a uint64_t value.
+ *
+ * Essentially ffsll() in the reverse direction.
+ */
+static inline unsigned int
+_mesa_flsll(uint64_t n)
+{
+#ifdef HAVE___BUILTIN_CLZLL
+ return n == 0 ? 0 : 64 - __builtin_clzll(n);
+#else
+ unsigned int v = 1;
+
+ if (n == 0)
+ return 0;
+
+ while (n >>= 1)
+ v++;
+
+ return v;
+#endif
+}
+
+
extern GLhalfARB
_mesa_float_to_half(float f);
diff --git a/mesalib/src/mesa/main/macros.h b/mesalib/src/mesa/main/macros.h
index 2d7a6a107..3344ec841 100644
--- a/mesalib/src/mesa/main/macros.h
+++ b/mesalib/src/mesa/main/macros.h
@@ -789,7 +789,14 @@ NORMALIZE_3FV(GLfloat v[3])
static inline GLboolean
DIFFERENT_SIGNS(GLfloat x, GLfloat y)
{
+#ifdef _MSC_VER
+#pragma warning( push )
+#pragma warning( disable : 6334 ) /* sizeof operator applied to an expression with an operator may yield unexpected results */
+#endif
return signbit(x) != signbit(y);
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif
}
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 8e1dba6f0..1c751cfff 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -42,6 +42,7 @@
#include "main/config.h"
#include "glapi/glapi.h"
#include "math/m_matrix.h" /* GLmatrix */
+#include "glsl/shader_enums.h"
#include "util/simple_list.h" /* struct simple_node */
#include "main/formats.h" /* MESA_FORMAT_COUNT */
@@ -280,13 +281,6 @@ typedef enum
/*@}*/
/**
- * Bitflags for system values.
- */
-#define SYSTEM_BIT_SAMPLE_ID BITFIELD64_BIT(SYSTEM_VALUE_SAMPLE_ID)
-#define SYSTEM_BIT_SAMPLE_POS BITFIELD64_BIT(SYSTEM_VALUE_SAMPLE_POS)
-#define SYSTEM_BIT_SAMPLE_MASK_IN BITFIELD64_BIT(SYSTEM_VALUE_SAMPLE_MASK_IN)
-
-/**
* Determine if the given gl_varying_slot appears in the fragment shader.
*/
static inline GLboolean
@@ -395,25 +389,6 @@ typedef enum
BUFFER_BIT_COLOR6 | \
BUFFER_BIT_COLOR7)
-
-/**
- * Shader stages. Note that these will become 5 with tessellation.
- *
- * The order must match how shaders are ordered in the pipeline.
- * The GLSL linker assumes that if i<j, then the j-th shader is
- * executed later than the i-th shader.
- */
-typedef enum
-{
- MESA_SHADER_VERTEX = 0,
- MESA_SHADER_GEOMETRY = 1,
- MESA_SHADER_FRAGMENT = 2,
- MESA_SHADER_COMPUTE = 3,
-} gl_shader_stage;
-
-#define MESA_SHADER_STAGES (MESA_SHADER_COMPUTE + 1)
-
-
/**
* Framebuffer configuration (aka visual / pixelformat)
* Note: some of these fields should be boolean, but it appears that
@@ -1456,7 +1431,6 @@ struct gl_viewport_attrib
GLfloat X, Y; /**< position */
GLfloat Width, Height; /**< size */
GLdouble Near, Far; /**< Depth buffer range */
- GLmatrix _WindowMap; /**< Mapping transformation as a matrix. */
};
@@ -2082,140 +2056,6 @@ typedef enum
/**
- * If the register file is PROGRAM_SYSTEM_VALUE, the register index will be
- * one of these values.
- */
-typedef enum
-{
- /**
- * \name Vertex shader system values
- */
- /*@{*/
- /**
- * OpenGL-style vertex ID.
- *
- * Section 2.11.7 (Shader Execution), subsection Shader Inputs, of the
- * OpenGL 3.3 core profile spec says:
- *
- * "gl_VertexID holds the integer index i implicitly passed by
- * DrawArrays or one of the other drawing commands defined in section
- * 2.8.3."
- *
- * Section 2.8.3 (Drawing Commands) of the same spec says:
- *
- * "The commands....are equivalent to the commands with the same base
- * name (without the BaseVertex suffix), except that the ith element
- * transferred by the corresponding draw call will be taken from
- * element indices[i] + basevertex of each enabled array."
- *
- * Additionally, the overview in the GL_ARB_shader_draw_parameters spec
- * says:
- *
- * "In unextended GL, vertex shaders have inputs named gl_VertexID and
- * gl_InstanceID, which contain, respectively the index of the vertex
- * and instance. The value of gl_VertexID is the implicitly passed
- * index of the vertex being processed, which includes the value of
- * baseVertex, for those commands that accept it."
- *
- * gl_VertexID gets basevertex added in. This differs from DirectX where
- * SV_VertexID does \b not get basevertex added in.
- *
- * \note
- * If all system values are available, \c SYSTEM_VALUE_VERTEX_ID will be
- * equal to \c SYSTEM_VALUE_VERTEX_ID_ZERO_BASE plus
- * \c SYSTEM_VALUE_BASE_VERTEX.
- *
- * \sa SYSTEM_VALUE_VERTEX_ID_ZERO_BASE, SYSTEM_VALUE_BASE_VERTEX
- */
- SYSTEM_VALUE_VERTEX_ID,
-
- /**
- * Instanced ID as supplied to gl_InstanceID
- *
- * Values assigned to gl_InstanceID always begin with zero, regardless of
- * the value of baseinstance.
- *
- * Section 11.1.3.9 (Shader Inputs) of the OpenGL 4.4 core profile spec
- * says:
- *
- * "gl_InstanceID holds the integer instance number of the current
- * primitive in an instanced draw call (see section 10.5)."
- *
- * Through a big chain of pseudocode, section 10.5 describes that
- * baseinstance is not counted by gl_InstanceID. In that section, notice
- *
- * "If an enabled vertex attribute array is instanced (it has a
- * non-zero divisor as specified by VertexAttribDivisor), the element
- * index that is transferred to the GL, for all vertices, is given by
- *
- * floor(instance/divisor) + baseinstance
- *
- * If an array corresponding to an attribute required by a vertex
- * shader is not enabled, then the corresponding element is taken from
- * the current attribute state (see section 10.2)."
- *
- * Note that baseinstance is \b not included in the value of instance.
- */
- SYSTEM_VALUE_INSTANCE_ID,
-
- /**
- * DirectX-style vertex ID.
- *
- * Unlike \c SYSTEM_VALUE_VERTEX_ID, this system value does \b not include
- * the value of basevertex.
- *
- * \sa SYSTEM_VALUE_VERTEX_ID, SYSTEM_VALUE_BASE_VERTEX
- */
- SYSTEM_VALUE_VERTEX_ID_ZERO_BASE,
-
- /**
- * Value of \c basevertex passed to \c glDrawElementsBaseVertex and similar
- * functions.
- *
- * \sa SYSTEM_VALUE_VERTEX_ID, SYSTEM_VALUE_VERTEX_ID_ZERO_BASE
- */
- SYSTEM_VALUE_BASE_VERTEX,
- /*@}*/
-
- /**
- * \name Geometry shader system values
- */
- /*@{*/
- SYSTEM_VALUE_INVOCATION_ID,
- /*@}*/
-
- /**
- * \name Fragment shader system values
- */
- /*@{*/
- SYSTEM_VALUE_FRONT_FACE, /**< (not done yet) */
- SYSTEM_VALUE_SAMPLE_ID,
- SYSTEM_VALUE_SAMPLE_POS,
- SYSTEM_VALUE_SAMPLE_MASK_IN,
- /*@}*/
-
- SYSTEM_VALUE_MAX /**< Number of values */
-} gl_system_value;
-
-
-/**
- * The possible interpolation qualifiers that can be applied to a fragment
- * shader input in GLSL.
- *
- * Note: INTERP_QUALIFIER_NONE must be 0 so that memsetting the
- * gl_fragment_program data structure to 0 causes the default behavior.
- */
-enum glsl_interp_qualifier
-{
- INTERP_QUALIFIER_NONE = 0,
- INTERP_QUALIFIER_SMOOTH,
- INTERP_QUALIFIER_FLAT,
- INTERP_QUALIFIER_NOPERSPECTIVE,
- INTERP_QUALIFIER_COUNT /**< Number of interpolation qualifiers */
-};
-
-
-/**
* \brief Layout qualifiers for gl_FragDepth.
*
* Extension AMD_conservative_depth allows gl_FragDepth to be redeclared with
@@ -2247,6 +2087,8 @@ struct gl_program
struct prog_instruction *Instructions;
+ struct nir_shader *nir;
+
GLbitfield64 InputsRead; /**< Bitmask of which input regs are read */
GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */
GLbitfield SystemValuesRead; /**< Bitmask of SYSTEM_VALUE_x inputs used */
@@ -2762,6 +2604,16 @@ struct gl_active_atomic_buffer
};
/**
+ * Active resource in a gl_shader_program
+ */
+struct gl_program_resource
+{
+ GLenum Type; /** Program interface type. */
+ const void *Data; /** Pointer to resource associated data structure. */
+ uint8_t StageReferences; /** Bitmask of shader stage references. */
+};
+
+/**
* A GLSL program object.
* Basically a linked collection of vertex and fragment shaders.
*/
@@ -2935,6 +2787,10 @@ struct gl_shader_program
*/
struct gl_shader *_LinkedShaders[MESA_SHADER_STAGES];
+ /** List of all active resources after linking. */
+ struct gl_program_resource *ProgramResourceList;
+ unsigned NumProgramResourceList;
+
/* True if any of the fragment shaders attached to this program use:
* #extension ARB_fragment_coord_conventions: enable
*/
@@ -3527,8 +3383,8 @@ struct gl_constants
GLboolean ForceGLSLExtensionsWarn;
/**
- * If non-zero, forces GLSL shaders without the #version directive to behave
- * as if they began with "#version ForceGLSLVersion".
+ * If non-zero, forces GLSL shaders to behave as if they began
+ * with "#version ForceGLSLVersion".
*/
GLuint ForceGLSLVersion;
@@ -4523,7 +4379,7 @@ struct gl_context
#ifdef DEBUG
extern int MESA_VERBOSE;
extern int MESA_DEBUG_FLAGS;
-# define MESA_FUNCTION __FUNCTION__
+# define MESA_FUNCTION __func__
#else
# define MESA_VERBOSE 0
# define MESA_DEBUG_FLAGS 0
diff --git a/mesalib/src/mesa/main/multisample.c b/mesalib/src/mesa/main/multisample.c
index 0e9207bc1..816837b95 100644
--- a/mesalib/src/mesa/main/multisample.c
+++ b/mesalib/src/mesa/main/multisample.c
@@ -150,6 +150,15 @@ GLenum
_mesa_check_sample_count(struct gl_context *ctx, GLenum target,
GLenum internalFormat, GLsizei samples)
{
+ /* Section 2.5 (GL Errors) of OpenGL 3.0 specification, page 16:
+ *
+ * "If a negative number is provided where an argument of type sizei or
+ * sizeiptr is specified, the error INVALID VALUE is generated."
+ */
+ if (samples < 0) {
+ return GL_INVALID_VALUE;
+ }
+
/* Section 4.4 (Framebuffer objects), page 198 of the OpenGL ES 3.0.0
* specification says:
*
diff --git a/mesalib/src/mesa/main/pipelineobj.c b/mesalib/src/mesa/main/pipelineobj.c
index fb241af1e..0fefa7d56 100644
--- a/mesalib/src/mesa/main/pipelineobj.c
+++ b/mesalib/src/mesa/main/pipelineobj.c
@@ -498,16 +498,18 @@ _mesa_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
* \param n Number of IDs to generate.
* \param pipelines pipeline of \c n locations to store the IDs.
*/
-void GLAPIENTRY
-_mesa_GenProgramPipelines(GLsizei n, GLuint *pipelines)
+static void
+create_program_pipelines(struct gl_context *ctx, GLsizei n, GLuint *pipelines,
+ bool dsa)
{
- GET_CURRENT_CONTEXT(ctx);
-
+ const char *func;
GLuint first;
GLint i;
+ func = dsa ? "glCreateProgramPipelines" : "glGenProgramPipelines";
+
if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenProgramPipelines(n<0)");
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s (n < 0)", func);
return;
}
@@ -523,16 +525,37 @@ _mesa_GenProgramPipelines(GLsizei n, GLuint *pipelines)
obj = _mesa_new_pipeline_object(ctx, name);
if (!obj) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenProgramPipelines");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
return;
}
+ if (dsa) {
+ /* make dsa-allocated objects behave like program objects */
+ obj->EverBound = GL_TRUE;
+ }
+
save_pipeline_object(ctx, obj);
pipelines[i] = first + i;
}
}
+void GLAPIENTRY
+_mesa_GenProgramPipelines(GLsizei n, GLuint *pipelines)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ create_program_pipelines(ctx, n, pipelines, false);
+}
+
+void GLAPIENTRY
+_mesa_CreateProgramPipelines(GLsizei n, GLuint *pipelines)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ create_program_pipelines(ctx, n, pipelines, true);
+}
+
/**
* Determine if ID is the name of an pipeline object.
*
diff --git a/mesalib/src/mesa/main/pipelineobj.h b/mesalib/src/mesa/main/pipelineobj.h
index 7285a78f1..b57bcb99e 100644
--- a/mesalib/src/mesa/main/pipelineobj.h
+++ b/mesalib/src/mesa/main/pipelineobj.h
@@ -82,6 +82,9 @@ _mesa_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines);
extern void GLAPIENTRY
_mesa_GenProgramPipelines(GLsizei n, GLuint *pipelines);
+void GLAPIENTRY
+_mesa_CreateProgramPipelines(GLsizei n, GLuint *pipelines);
+
extern GLboolean GLAPIENTRY
_mesa_IsProgramPipeline(GLuint pipeline);
diff --git a/mesalib/src/mesa/main/pixel.c b/mesalib/src/mesa/main/pixel.c
index 7162c6fef..ecda2694f 100644
--- a/mesalib/src/mesa/main/pixel.c
+++ b/mesalib/src/mesa/main/pixel.c
@@ -30,7 +30,6 @@
#include "glheader.h"
#include "bufferobj.h"
-#include "colormac.h"
#include "context.h"
#include "macros.h"
#include "pixel.h"
diff --git a/mesalib/src/mesa/main/pixeltransfer.c b/mesalib/src/mesa/main/pixeltransfer.c
index 8bbeeb853..94464ea67 100644
--- a/mesalib/src/mesa/main/pixeltransfer.c
+++ b/mesalib/src/mesa/main/pixeltransfer.c
@@ -31,7 +31,7 @@
#include "glheader.h"
-#include "colormac.h"
+#include "macros.h"
#include "pixeltransfer.h"
#include "imports.h"
#include "mtypes.h"
diff --git a/mesalib/src/mesa/main/program_resource.c b/mesalib/src/mesa/main/program_resource.c
new file mode 100644
index 000000000..b15a13210
--- /dev/null
+++ b/mesalib/src/mesa/main/program_resource.c
@@ -0,0 +1,417 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "main/enums.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
+#include "program_resource.h"
+
+static bool
+supported_interface_enum(GLenum iface)
+{
+ switch (iface) {
+ case GL_UNIFORM:
+ case GL_UNIFORM_BLOCK:
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ case GL_ATOMIC_COUNTER_BUFFER:
+ return true;
+ case GL_VERTEX_SUBROUTINE:
+ case GL_TESS_CONTROL_SUBROUTINE:
+ case GL_TESS_EVALUATION_SUBROUTINE:
+ case GL_GEOMETRY_SUBROUTINE:
+ case GL_FRAGMENT_SUBROUTINE:
+ case GL_COMPUTE_SUBROUTINE:
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_BUFFER_VARIABLE:
+ case GL_SHADER_STORAGE_BLOCK:
+ default:
+ return false;
+ }
+}
+
+void GLAPIENTRY
+_mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface,
+ GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ unsigned i;
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glGetProgramInterfaceiv");
+ if (!shProg)
+ return;
+
+ if (!params) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetProgramInterfaceiv(params NULL)");
+ return;
+ }
+
+ /* Validate interface. */
+ if (!supported_interface_enum(programInterface)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramInterfaceiv(%s)",
+ _mesa_lookup_enum_by_nr(programInterface));
+ return;
+ }
+
+ /* Validate pname against interface. */
+ switch(pname) {
+ case GL_ACTIVE_RESOURCES:
+ for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++)
+ if (shProg->ProgramResourceList[i].Type == programInterface)
+ (*params)++;
+ break;
+ case GL_MAX_NAME_LENGTH:
+ if (programInterface == GL_ATOMIC_COUNTER_BUFFER) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetProgramInterfaceiv(%s pname %s)",
+ _mesa_lookup_enum_by_nr(programInterface),
+ _mesa_lookup_enum_by_nr(pname));
+ return;
+ }
+ /* Name length consists of base name, 3 additional chars '[0]' if
+ * resource is an array and finally 1 char for string terminator.
+ */
+ for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) {
+ if (shProg->ProgramResourceList[i].Type != programInterface)
+ continue;
+ const char *name =
+ _mesa_program_resource_name(&shProg->ProgramResourceList[i]);
+ unsigned array_size =
+ _mesa_program_resource_array_size(&shProg->ProgramResourceList[i]);
+ *params = MAX2(*params, strlen(name) + (array_size ? 3 : 0) + 1);
+ }
+ break;
+ case GL_MAX_NUM_ACTIVE_VARIABLES:
+ switch (programInterface) {
+ case GL_UNIFORM_BLOCK:
+ for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) {
+ if (shProg->ProgramResourceList[i].Type == programInterface) {
+ struct gl_uniform_block *block =
+ (struct gl_uniform_block *)
+ shProg->ProgramResourceList[i].Data;
+ *params = MAX2(*params, block->NumUniforms);
+ }
+ }
+ break;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) {
+ if (shProg->ProgramResourceList[i].Type == programInterface) {
+ struct gl_active_atomic_buffer *buffer =
+ (struct gl_active_atomic_buffer *)
+ shProg->ProgramResourceList[i].Data;
+ *params = MAX2(*params, buffer->NumUniforms);
+ }
+ }
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetProgramInterfaceiv(%s pname %s)",
+ _mesa_lookup_enum_by_nr(programInterface),
+ _mesa_lookup_enum_by_nr(pname));
+ };
+ break;
+ case GL_MAX_NUM_COMPATIBLE_SUBROUTINES:
+ default:
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetProgramInterfaceiv(pname %s)",
+ _mesa_lookup_enum_by_nr(pname));
+ }
+}
+
+static bool
+is_xfb_marker(const char *str)
+{
+ static const char *markers[] = {
+ "gl_NextBuffer",
+ "gl_SkipComponents1",
+ "gl_SkipComponents2",
+ "gl_SkipComponents3",
+ "gl_SkipComponents4",
+ NULL
+ };
+ const char **m = markers;
+
+ if (strncmp(str, "gl_", 3) != 0)
+ return false;
+
+ for (; *m; m++)
+ if (strcmp(*m, str) == 0)
+ return true;
+
+ return false;
+}
+
+/**
+ * Checks if given name index is legal for GetProgramResourceIndex,
+ * check is written to be compatible with GL_ARB_array_of_arrays.
+ */
+static bool
+valid_program_resource_index_name(const GLchar *name)
+{
+ const char *array = strstr(name, "[");
+ const char *close = strrchr(name, ']');
+
+ /* Not array, no need for the check. */
+ if (!array)
+ return true;
+
+ /* Last array index has to be zero. */
+ if (!close || *--close != '0')
+ return false;
+
+ return true;
+}
+
+GLuint GLAPIENTRY
+_mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface,
+ const GLchar *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_program_resource *res;
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glGetProgramResourceIndex");
+ if (!shProg || !name)
+ return GL_INVALID_INDEX;
+
+ /*
+ * For the interface TRANSFORM_FEEDBACK_VARYING, the value INVALID_INDEX
+ * should be returned when querying the index assigned to the special names
+ * "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2",
+ * "gl_SkipComponents3", and "gl_SkipComponents4".
+ */
+ if (programInterface == GL_TRANSFORM_FEEDBACK_VARYING &&
+ is_xfb_marker(name))
+ return GL_INVALID_INDEX;
+
+ switch (programInterface) {
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ case GL_UNIFORM:
+ case GL_UNIFORM_BLOCK:
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ /* Validate name syntax for arrays. */
+ if (!valid_program_resource_index_name(name))
+ return GL_INVALID_INDEX;
+
+ res = _mesa_program_resource_find_name(shProg, programInterface, name);
+ if (!res)
+ return GL_INVALID_INDEX;
+
+ return _mesa_program_resource_index(shProg, res);
+ case GL_ATOMIC_COUNTER_BUFFER:
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)",
+ _mesa_lookup_enum_by_nr(programInterface));
+ }
+
+ return GL_INVALID_INDEX;
+}
+
+void GLAPIENTRY
+_mesa_GetProgramResourceName(GLuint program, GLenum programInterface,
+ GLuint index, GLsizei bufSize, GLsizei *length,
+ GLchar *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glGetProgramResourceName");
+
+ /* Set user friendly return values in case of errors. */
+ if (name)
+ *name = '\0';
+ if (length)
+ *length = 0;
+
+ if (!shProg || !name)
+ return;
+
+ if (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
+ !supported_interface_enum(programInterface)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceName(%s)",
+ _mesa_lookup_enum_by_nr(programInterface));
+ return;
+ }
+
+ _mesa_get_program_resource_name(shProg, programInterface, index, bufSize,
+ length, name, "glGetProgramResourceName");
+}
+
+void GLAPIENTRY
+_mesa_GetProgramResourceiv(GLuint program, GLenum programInterface,
+ GLuint index, GLsizei propCount,
+ const GLenum *props, GLsizei bufSize,
+ GLsizei *length, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program, "glGetProgramResourceiv");
+
+ if (!shProg || !params)
+ return;
+
+ /* The error INVALID_VALUE is generated if <propCount> is zero.
+ * Note that we check < 0 here because it makes sense to bail early.
+ */
+ if (propCount <= 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetProgramResourceiv(propCount <= 0)");
+ return;
+ }
+
+ /* No need to write any properties, user requested none. */
+ if (bufSize == 0)
+ return;
+
+ _mesa_get_program_resourceiv(shProg, programInterface, index,
+ propCount, props, bufSize, length, params);
+}
+
+/**
+ * Function verifies syntax of given name for GetProgramResourceLocation
+ * and GetProgramResourceLocationIndex for the following cases:
+ *
+ * "array element portion of a string passed to GetProgramResourceLocation
+ * or GetProgramResourceLocationIndex must not have, a "+" sign, extra
+ * leading zeroes, or whitespace".
+ *
+ * Check is written to be compatible with GL_ARB_array_of_arrays.
+ */
+static bool
+invalid_array_element_syntax(const GLchar *name)
+{
+ char *first = strchr(name, '[');
+ char *last = strrchr(name, '[');
+
+ if (!first)
+ return false;
+
+ /* No '+' or ' ' allowed anywhere. */
+ if (strchr(first, '+') || strchr(first, ' '))
+ return true;
+
+ /* Check that last array index is 0. */
+ if (last[1] == '0' && last[2] != ']')
+ return true;
+
+ return false;
+}
+
+static struct gl_shader_program *
+lookup_linked_program(GLuint program, const char *caller)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *prog =
+ _mesa_lookup_shader_program_err(ctx, program, caller);
+
+ if (!prog)
+ return NULL;
+
+ if (prog->LinkStatus == GL_FALSE) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
+ caller);
+ return NULL;
+ }
+ return prog;
+}
+
+GLint GLAPIENTRY
+_mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface,
+ const GLchar *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ lookup_linked_program(program, "glGetProgramResourceLocation");
+
+ if (!shProg || !name || invalid_array_element_syntax(name))
+ return -1;
+
+ /* Validate programInterface. */
+ switch (programInterface) {
+ case GL_UNIFORM:
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ break;
+
+ /* For reference valid cases requiring additional extension support:
+ * GL_ARB_shader_subroutine
+ * GL_ARB_tessellation_shader
+ * GL_ARB_compute_shader
+ */
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceLocation(%s %s)",
+ _mesa_lookup_enum_by_nr(programInterface), name);
+ }
+
+ return _mesa_program_resource_location(shProg, programInterface, name);
+}
+
+/**
+ * Returns output index for dual source blending.
+ */
+GLint GLAPIENTRY
+_mesa_GetProgramResourceLocationIndex(GLuint program, GLenum programInterface,
+ const GLchar *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ lookup_linked_program(program, "glGetProgramResourceLocationIndex");
+
+ if (!shProg || !name || invalid_array_element_syntax(name))
+ return -1;
+
+ /* From the GL_ARB_program_interface_query spec:
+ *
+ * "For GetProgramResourceLocationIndex, <programInterface> must be
+ * PROGRAM_OUTPUT."
+ */
+ if (programInterface != GL_PROGRAM_OUTPUT) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetProgramResourceLocationIndex(%s)",
+ _mesa_lookup_enum_by_nr(programInterface));
+ return -1;
+ }
+
+ return _mesa_program_resource_location_index(shProg, GL_PROGRAM_OUTPUT,
+ name);
+}
diff --git a/mesalib/src/mesa/main/program_resource.h b/mesalib/src/mesa/main/program_resource.h
new file mode 100644
index 000000000..326ae1f93
--- /dev/null
+++ b/mesalib/src/mesa/main/program_resource.h
@@ -0,0 +1,58 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2015 Intel Corporation. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef PROGRAM_RESOURCE_H
+#define PROGRAM_RESOURCE_H
+
+#include "glheader.h"
+
+extern void GLAPIENTRY
+_mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface,
+ GLenum pname, GLint *params);
+
+extern GLuint GLAPIENTRY
+_mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface,
+ const GLchar *name);
+
+extern void GLAPIENTRY
+_mesa_GetProgramResourceName(GLuint program, GLenum programInterface,
+ GLuint index, GLsizei bufSize, GLsizei *length,
+ GLchar *name);
+
+extern void GLAPIENTRY
+_mesa_GetProgramResourceiv(GLuint program, GLenum programInterface,
+ GLuint index, GLsizei propCount,
+ const GLenum *props, GLsizei bufSize,
+ GLsizei *length, GLint *params);
+
+extern GLint GLAPIENTRY
+_mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface,
+ const GLchar *name);
+
+extern GLint GLAPIENTRY
+_mesa_GetProgramResourceLocationIndex(GLuint program, GLenum programInterface,
+ const GLchar *name);
+
+#endif
diff --git a/mesalib/src/mesa/main/queryobj.c b/mesalib/src/mesa/main/queryobj.c
index 0842b540d..fbccf3fe6 100644
--- a/mesalib/src/mesa/main/queryobj.c
+++ b/mesalib/src/mesa/main/queryobj.c
@@ -233,18 +233,22 @@ get_query_binding_point(struct gl_context *ctx, GLenum target, GLuint index)
}
}
-
-void GLAPIENTRY
-_mesa_GenQueries(GLsizei n, GLuint *ids)
+/**
+ * Create $n query objects and store them in *ids. Make them of type $target
+ * if dsa is set. Called from _mesa_GenQueries() and _mesa_CreateQueries().
+ */
+static void
+create_queries(struct gl_context *ctx, GLenum target, GLsizei n, GLuint *ids,
+ bool dsa)
{
+ const char *func = dsa ? "glGenQueries" : "glCreateQueries";
GLuint first;
- GET_CURRENT_CONTEXT(ctx);
if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glGenQueries(%d)\n", n);
+ _mesa_debug(ctx, "%s(%d)\n", func, n);
if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)");
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
return;
}
@@ -255,8 +259,12 @@ _mesa_GenQueries(GLsizei n, GLuint *ids)
struct gl_query_object *q
= ctx->Driver.NewQueryObject(ctx, first + i);
if (!q) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenQueriesARB");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
return;
+ } else if (dsa) {
+ /* Do the equivalent of binding the buffer with a target */
+ q->Target = target;
+ q->EverBound = GL_TRUE;
}
ids[i] = first + i;
_mesa_HashInsert(ctx->Query.QueryObjects, first + i, q);
@@ -264,6 +272,36 @@ _mesa_GenQueries(GLsizei n, GLuint *ids)
}
}
+void GLAPIENTRY
+_mesa_GenQueries(GLsizei n, GLuint *ids)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ create_queries(ctx, 0, n, ids, false);
+}
+
+void GLAPIENTRY
+_mesa_CreateQueries(GLenum target, GLsizei n, GLuint *ids)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ switch (target) {
+ case GL_SAMPLES_PASSED:
+ case GL_ANY_SAMPLES_PASSED:
+ case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
+ case GL_TIME_ELAPSED:
+ case GL_TIMESTAMP:
+ case GL_PRIMITIVES_GENERATED:
+ case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCreateQueries(invalid target = %s)",
+ _mesa_lookup_enum_by_nr(target));
+ return;
+ }
+
+ create_queries(ctx, target, n, ids, true);
+}
+
void GLAPIENTRY
_mesa_DeleteQueries(GLsizei n, const GLuint *ids)
@@ -424,6 +462,18 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id)
}
}
+ /* This possibly changes the target of a buffer allocated by
+ * CreateQueries. Issue 39) in the ARB_direct_state_access extension states
+ * the following:
+ *
+ * "CreateQueries adds a <target>, so strictly speaking the <target>
+ * command isn't needed for BeginQuery/EndQuery, but in the end, this also
+ * isn't a selector, so we decided not to change it."
+ *
+ * Updating the target of the query object should be acceptable, so let's
+ * do that.
+ */
+
q->Target = target;
q->Active = GL_TRUE;
q->Result = 0;
@@ -541,6 +591,18 @@ _mesa_QueryCounter(GLuint id, GLenum target)
return;
}
+ /* This possibly changes the target of a buffer allocated by
+ * CreateQueries. Issue 39) in the ARB_direct_state_access extension states
+ * the following:
+ *
+ * "CreateQueries adds a <target>, so strictly speaking the <target>
+ * command isn't needed for BeginQuery/EndQuery, but in the end, this also
+ * isn't a selector, so we decided not to change it."
+ *
+ * Updating the target of the query object should be acceptable, so let's
+ * do that.
+ */
+
q->Target = target;
q->Result = 0;
q->Ready = GL_FALSE;
@@ -710,8 +772,8 @@ _mesa_GetQueryObjectiv(GLuint id, GLenum pname, GLint *params)
}
break;
case GL_QUERY_RESULT_AVAILABLE_ARB:
- if (!q->Ready)
- ctx->Driver.CheckQuery( ctx, q );
+ if (!q->Ready)
+ ctx->Driver.CheckQuery( ctx, q );
*params = q->Ready;
break;
default:
@@ -761,8 +823,8 @@ _mesa_GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
}
break;
case GL_QUERY_RESULT_AVAILABLE_ARB:
- if (!q->Ready)
- ctx->Driver.CheckQuery( ctx, q );
+ if (!q->Ready)
+ ctx->Driver.CheckQuery( ctx, q );
*params = q->Ready;
break;
default:
@@ -801,8 +863,8 @@ _mesa_GetQueryObjecti64v(GLuint id, GLenum pname, GLint64EXT *params)
*params = q->Result;
break;
case GL_QUERY_RESULT_AVAILABLE_ARB:
- if (!q->Ready)
- ctx->Driver.CheckQuery( ctx, q );
+ if (!q->Ready)
+ ctx->Driver.CheckQuery( ctx, q );
*params = q->Ready;
break;
default:
@@ -841,8 +903,8 @@ _mesa_GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params)
*params = q->Result;
break;
case GL_QUERY_RESULT_AVAILABLE_ARB:
- if (!q->Ready)
- ctx->Driver.CheckQuery( ctx, q );
+ if (!q->Ready)
+ ctx->Driver.CheckQuery( ctx, q );
*params = q->Ready;
break;
default:
@@ -852,6 +914,45 @@ _mesa_GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params)
}
/**
+ * New with GL_ARB_query_buffer_object
+ */
+void GLAPIENTRY
+_mesa_GetQueryBufferObjectiv(GLuint id, GLuint buffer, GLenum pname,
+ GLintptr offset)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryBufferObjectiv");
+}
+
+
+void GLAPIENTRY
+_mesa_GetQueryBufferObjectuiv(GLuint id, GLuint buffer, GLenum pname,
+ GLintptr offset)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryBufferObjectuiv");
+}
+
+
+void GLAPIENTRY
+_mesa_GetQueryBufferObjecti64v(GLuint id, GLuint buffer, GLenum pname,
+ GLintptr offset)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryBufferObjecti64v");
+}
+
+
+void GLAPIENTRY
+_mesa_GetQueryBufferObjectui64v(GLuint id, GLuint buffer, GLenum pname,
+ GLintptr offset)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryBufferObjectui64v");
+}
+
+
+/**
* Allocate/init the context state related to query objects.
*/
void
diff --git a/mesalib/src/mesa/main/queryobj.h b/mesalib/src/mesa/main/queryobj.h
index 6cbcabd46..d1036fcce 100644
--- a/mesalib/src/mesa/main/queryobj.h
+++ b/mesalib/src/mesa/main/queryobj.h
@@ -51,6 +51,8 @@ _mesa_free_queryobj_data(struct gl_context *ctx);
void GLAPIENTRY
_mesa_GenQueries(GLsizei n, GLuint *ids);
void GLAPIENTRY
+_mesa_CreateQueries(GLenum target, GLsizei n, GLuint *ids);
+void GLAPIENTRY
_mesa_DeleteQueries(GLsizei n, const GLuint *ids);
GLboolean GLAPIENTRY
_mesa_IsQuery(GLuint id);
@@ -77,5 +79,17 @@ void GLAPIENTRY
_mesa_GetQueryObjecti64v(GLuint id, GLenum pname, GLint64EXT *params);
void GLAPIENTRY
_mesa_GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params);
+void GLAPIENTRY
+_mesa_GetQueryBufferObjectiv(GLuint id, GLuint buffer, GLenum pname,
+ GLintptr offset);
+void GLAPIENTRY
+_mesa_GetQueryBufferObjectuiv(GLuint id, GLuint buffer, GLenum pname,
+ GLintptr offset);
+void GLAPIENTRY
+_mesa_GetQueryBufferObjecti64v(GLuint id, GLuint buffer, GLenum pname,
+ GLintptr offset);
+void GLAPIENTRY
+_mesa_GetQueryBufferObjectui64v(GLuint id, GLuint buffer, GLenum pname,
+ GLintptr offset);
#endif /* QUERYOBJ_H */
diff --git a/mesalib/src/mesa/main/samplerobj.c b/mesalib/src/mesa/main/samplerobj.c
index d66b0b5e8..a3aacc66a 100644
--- a/mesalib/src/mesa/main/samplerobj.c
+++ b/mesalib/src/mesa/main/samplerobj.c
@@ -181,19 +181,18 @@ _mesa_delete_sampler_object(struct gl_context *ctx,
free(sampObj);
}
-
-void GLAPIENTRY
-_mesa_GenSamplers(GLsizei count, GLuint *samplers)
+static void
+create_samplers(struct gl_context *ctx, GLsizei count, GLuint *samplers,
+ const char *caller)
{
- GET_CURRENT_CONTEXT(ctx);
GLuint first;
GLint i;
if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glGenSamplers(%d)\n", count);
+ _mesa_debug(ctx, "%s(%d)\n", caller, count);
if (count < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenSamplers");
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(n<0)", caller);
return;
}
@@ -211,6 +210,20 @@ _mesa_GenSamplers(GLsizei count, GLuint *samplers)
}
}
+void GLAPIENTRY
+_mesa_GenSamplers(GLsizei count, GLuint *samplers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ create_samplers(ctx, count, samplers, "glGenSamplers");
+}
+
+void GLAPIENTRY
+_mesa_CreateSamplers(GLsizei count, GLuint *samplers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ create_samplers(ctx, count, samplers, "glCreateSamplers");
+}
+
void GLAPIENTRY
_mesa_DeleteSamplers(GLsizei count, const GLuint *samplers)
diff --git a/mesalib/src/mesa/main/samplerobj.h b/mesalib/src/mesa/main/samplerobj.h
index 1bb3193e4..7bea91114 100644
--- a/mesalib/src/mesa/main/samplerobj.h
+++ b/mesalib/src/mesa/main/samplerobj.h
@@ -32,6 +32,9 @@ extern "C" {
#endif
+#include "mtypes.h"
+
+
struct dd_function_table;
static inline struct gl_sampler_object *
@@ -80,6 +83,8 @@ _mesa_init_sampler_object_functions(struct dd_function_table *driver);
void GLAPIENTRY
_mesa_GenSamplers(GLsizei count, GLuint *samplers);
void GLAPIENTRY
+_mesa_CreateSamplers(GLsizei count, GLuint *samplers);
+void GLAPIENTRY
_mesa_DeleteSamplers(GLsizei count, const GLuint *samplers);
GLboolean GLAPIENTRY
_mesa_IsSampler(GLuint sampler);
diff --git a/mesalib/src/mesa/main/shader_query.cpp b/mesalib/src/mesa/main/shader_query.cpp
index df9081b73..b5f1d082c 100644
--- a/mesalib/src/mesa/main/shader_query.cpp
+++ b/mesalib/src/mesa/main/shader_query.cpp
@@ -34,11 +34,33 @@
#include "shaderobj.h"
#include "program/hash_table.h"
#include "../glsl/program.h"
+#include "uniforms.h"
+#include "main/enums.h"
extern "C" {
#include "shaderapi.h"
}
+static GLint
+program_resource_location(struct gl_shader_program *shProg,
+ struct gl_program_resource *res, const char *name);
+
+/**
+ * Declare convenience functions to return resource data in a given type.
+ * Warning! this is not type safe so be *very* careful when using these.
+ */
+#define DECL_RESOURCE_FUNC(name, type) \
+const type * RESOURCE_ ## name (gl_program_resource *res) { \
+ assert(res->Data); \
+ return (type *) res->Data; \
+}
+
+DECL_RESOURCE_FUNC(VAR, ir_variable);
+DECL_RESOURCE_FUNC(UBO, gl_uniform_block);
+DECL_RESOURCE_FUNC(UNI, gl_uniform_storage);
+DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer);
+DECL_RESOURCE_FUNC(XFB, gl_transform_feedback_varying_info);
+
void GLAPIENTRY
_mesa_BindAttribLocation(GLhandleARB program, GLuint index,
const GLcharARB *name)
@@ -129,45 +151,41 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index,
return;
}
- exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir;
- unsigned current_index = 0;
-
- foreach_in_list(ir_instruction, node, ir) {
- const ir_variable *const var = node->as_variable();
-
- if (!is_active_attrib(var))
- continue;
+ struct gl_program_resource *res =
+ _mesa_program_resource_find_index(shProg, GL_PROGRAM_INPUT,
+ desired_index);
- if (current_index == desired_index) {
- const char *var_name = var->name;
+ /* User asked for index that does not exist. */
+ if (!res) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
+ return;
+ }
- /* Since gl_VertexID may be lowered to gl_VertexIDMESA, we need to
- * consider gl_VertexIDMESA as gl_VertexID for purposes of checking
- * active attributes.
- */
- if (var->data.mode == ir_var_system_value &&
- var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {
- var_name = "gl_VertexID";
- }
+ const ir_variable *const var = RESOURCE_VAR(res);
- _mesa_copy_string(name, maxLength, length, var_name);
+ if (!is_active_attrib(var))
+ return;
- if (size)
- *size = (var->type->is_array()) ? var->type->length : 1;
+ const char *var_name = var->name;
- if (type)
- *type = var->type->gl_type;
+ /* Since gl_VertexID may be lowered to gl_VertexIDMESA, we need to
+ * consider gl_VertexIDMESA as gl_VertexID for purposes of checking
+ * active attributes.
+ */
+ if (var->data.mode == ir_var_system_value &&
+ var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {
+ var_name = "gl_VertexID";
+ }
- return;
- }
+ _mesa_copy_string(name, maxLength, length, var_name);
- current_index++;
- }
+ if (size)
+ _mesa_program_resource_prop(shProg, res, desired_index, GL_ARRAY_SIZE,
+ size, "glGetActiveAttrib");
- /* If the loop did not return early, the caller must have asked for
- * an index that did not exit. Set an error.
- */
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
+ if (type)
+ _mesa_program_resource_prop(shProg, res, desired_index, GL_TYPE,
+ (GLint *) type, "glGetActiveAttrib");
}
/* Locations associated with shader variables (array or non-array) can be
@@ -252,31 +270,25 @@ _mesa_GetAttribLocation(GLhandleARB program, const GLcharARB * name)
if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)
return -1;
- exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir;
- foreach_in_list(ir_instruction, node, ir) {
- const ir_variable *const var = node->as_variable();
-
- /* The extra check against VERT_ATTRIB_GENERIC0 is because
- * glGetAttribLocation cannot be used on "conventional" attributes.
- *
- * From page 95 of the OpenGL 3.0 spec:
- *
- * "If name is not an active attribute, if name is a conventional
- * attribute, or if an error occurs, -1 will be returned."
- */
- if (var == NULL
- || var->data.mode != ir_var_shader_in
- || var->data.location == -1
- || var->data.location < VERT_ATTRIB_GENERIC0)
- continue;
-
- int index = get_matching_index(var, (const char *) name);
+ struct gl_program_resource *res =
+ _mesa_program_resource_find_name(shProg, GL_PROGRAM_INPUT, name);
- if (index >= 0)
- return var->data.location + index - VERT_ATTRIB_GENERIC0;
- }
+ if (!res)
+ return -1;
- return -1;
+ GLint loc = program_resource_location(shProg, res, name);
+
+ /* The extra check against against 0 is made because of builtin-attribute
+ * locations that have offset applied. Function program_resource_location
+ * can return built-in attribute locations < 0 and glGetAttribLocation
+ * cannot be used on "conventional" attributes.
+ *
+ * From page 95 of the OpenGL 3.0 spec:
+ *
+ * "If name is not an active attribute, if name is a conventional
+ * attribute, or if an error occurs, -1 will be returned."
+ */
+ return (loc >= 0) ? loc : -1;
}
@@ -416,29 +428,8 @@ _mesa_GetFragDataIndex(GLuint program, const GLchar *name)
if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)
return -1;
- exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir;
- foreach_in_list(ir_instruction, node, ir) {
- const ir_variable *const var = node->as_variable();
-
- /* The extra check against FRAG_RESULT_DATA0 is because
- * glGetFragDataLocation cannot be used on "conventional" attributes.
- *
- * From page 95 of the OpenGL 3.0 spec:
- *
- * "If name is not an active attribute, if name is a conventional
- * attribute, or if an error occurs, -1 will be returned."
- */
- if (var == NULL
- || var->data.mode != ir_var_shader_out
- || var->data.location == -1
- || var->data.location < FRAG_RESULT_DATA0)
- continue;
-
- if (get_matching_index(var, (const char *) name) >= 0)
- return var->data.index;
- }
-
- return -1;
+ return _mesa_program_resource_location_index(shProg, GL_PROGRAM_OUTPUT,
+ name);
}
GLint GLAPIENTRY
@@ -472,29 +463,612 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name)
if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)
return -1;
- exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir;
- foreach_in_list(ir_instruction, node, ir) {
- const ir_variable *const var = node->as_variable();
+ struct gl_program_resource *res =
+ _mesa_program_resource_find_name(shProg, GL_PROGRAM_OUTPUT, name);
- /* The extra check against FRAG_RESULT_DATA0 is because
- * glGetFragDataLocation cannot be used on "conventional" attributes.
- *
- * From page 95 of the OpenGL 3.0 spec:
+ if (!res)
+ return -1;
+
+ GLint loc = program_resource_location(shProg, res, name);
+
+ /* The extra check against against 0 is made because of builtin-attribute
+ * locations that have offset applied. Function program_resource_location
+ * can return built-in attribute locations < 0 and glGetFragDataLocation
+ * cannot be used on "conventional" attributes.
+ *
+ * From page 95 of the OpenGL 3.0 spec:
+ *
+ * "If name is not an active attribute, if name is a conventional
+ * attribute, or if an error occurs, -1 will be returned."
+ */
+ return (loc >= 0) ? loc : -1;
+}
+
+const char*
+_mesa_program_resource_name(struct gl_program_resource *res)
+{
+ switch (res->Type) {
+ case GL_UNIFORM_BLOCK:
+ return RESOURCE_UBO(res)->Name;
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ return RESOURCE_XFB(res)->Name;
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ return RESOURCE_VAR(res)->name;
+ case GL_UNIFORM:
+ return RESOURCE_UNI(res)->name;
+ default:
+ assert(!"support for resource type not implemented");
+ }
+ return NULL;
+}
+
+
+unsigned
+_mesa_program_resource_array_size(struct gl_program_resource *res)
+{
+ switch (res->Type) {
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ return RESOURCE_XFB(res)->Size > 1 ?
+ RESOURCE_XFB(res)->Size : 0;
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ return RESOURCE_VAR(res)->data.max_array_access;
+ case GL_UNIFORM:
+ return RESOURCE_UNI(res)->array_elements;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ case GL_UNIFORM_BLOCK:
+ return 0;
+ default:
+ assert(!"support for resource type not implemented");
+ }
+ return 0;
+}
+
+static int
+array_index_of_resource(struct gl_program_resource *res,
+ const char *name)
+{
+ assert(res->Data);
+
+ switch (res->Type) {
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ return get_matching_index(RESOURCE_VAR(res), name);
+ default:
+ assert(!"support for resource type not implemented");
+ }
+}
+
+/* Find a program resource with specific name in given interface.
+ */
+struct gl_program_resource *
+_mesa_program_resource_find_name(struct gl_shader_program *shProg,
+ GLenum programInterface, const char *name)
+{
+ struct gl_program_resource *res = shProg->ProgramResourceList;
+ for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, res++) {
+ if (res->Type != programInterface)
+ continue;
+
+ /* Resource basename. */
+ const char *rname = _mesa_program_resource_name(res);
+ unsigned baselen = strlen(rname);
+
+ switch (programInterface) {
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ case GL_UNIFORM_BLOCK:
+ case GL_UNIFORM:
+ if (strncmp(rname, name, baselen) == 0) {
+ /* Basename match, check if array or struct. */
+ if (name[baselen] == '\0' ||
+ name[baselen] == '[' ||
+ name[baselen] == '.') {
+ return res;
+ }
+ }
+ break;
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ if (array_index_of_resource(res, name) >= 0)
+ return res;
+ break;
+ default:
+ assert(!"not implemented for given interface");
+ }
+ }
+ return NULL;
+}
+
+static GLuint
+calc_resource_index(struct gl_shader_program *shProg,
+ struct gl_program_resource *res)
+{
+ unsigned i;
+ GLuint index = 0;
+ for (i = 0; i < shProg->NumProgramResourceList; i++) {
+ if (&shProg->ProgramResourceList[i] == res)
+ return index;
+ if (shProg->ProgramResourceList[i].Type == res->Type)
+ index++;
+ }
+ return GL_INVALID_INDEX;
+}
+
+/**
+ * Calculate index for the given resource.
+ */
+GLuint
+_mesa_program_resource_index(struct gl_shader_program *shProg,
+ struct gl_program_resource *res)
+{
+ if (!res)
+ return GL_INVALID_INDEX;
+
+ switch (res->Type) {
+ case GL_UNIFORM_BLOCK:
+ return RESOURCE_UBO(res)- shProg->UniformBlocks;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ return RESOURCE_ATC(res) - shProg->AtomicBuffers;
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ default:
+ return calc_resource_index(shProg, res);
+ }
+}
+
+/* Find a program resource with specific index in given interface.
+ */
+struct gl_program_resource *
+_mesa_program_resource_find_index(struct gl_shader_program *shProg,
+ GLenum programInterface, GLuint index)
+{
+ struct gl_program_resource *res = shProg->ProgramResourceList;
+ int idx = -1;
+
+ for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, res++) {
+ if (res->Type != programInterface)
+ continue;
+
+ switch (res->Type) {
+ case GL_UNIFORM_BLOCK:
+ case GL_ATOMIC_COUNTER_BUFFER:
+ if (_mesa_program_resource_index(shProg, res) == index)
+ return res;
+
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ case GL_UNIFORM:
+ if (++idx == (int) index)
+ return res;
+ break;
+ default:
+ assert(!"not implemented for given interface");
+ }
+ }
+ return NULL;
+}
+
+/* Get full name of a program resource.
+ */
+bool
+_mesa_get_program_resource_name(struct gl_shader_program *shProg,
+ GLenum programInterface, GLuint index,
+ GLsizei bufSize, GLsizei *length,
+ GLchar *name, const char *caller)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ /* Find resource with given interface and index. */
+ struct gl_program_resource *res =
+ _mesa_program_resource_find_index(shProg, programInterface, index);
+
+ /* The error INVALID_VALUE is generated if <index> is greater than
+ * or equal to the number of entries in the active resource list for
+ * <programInterface>.
+ */
+ if (!res) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(index %u)", caller, index);
+ return false;
+ }
+
+ if (bufSize < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize %d)", caller, bufSize);
+ return false;
+ }
+
+ GLsizei localLength;
+
+ if (length == NULL)
+ length = &localLength;
+
+ _mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res));
+
+ /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0
+ * spec says:
+ *
+ * "If the active uniform is an array, the uniform name returned in
+ * name will always be the name of the uniform array appended with
+ * "[0]"."
+ *
+ * The same text also appears in the OpenGL 4.2 spec. It does not,
+ * however, appear in any previous spec. Previous specifications are
+ * ambiguous in this regard. However, either name can later be passed
+ * to glGetUniformLocation (and related APIs), so there shouldn't be any
+ * harm in always appending "[0]" to uniform array names.
+ *
+ * Geometry shader stage has different naming convention where the 'normal'
+ * condition is an array, therefore for variables referenced in geometry
+ * stage we do not add '[0]'.
+ *
+ * Note, that TCS outputs and TES inputs should not have index appended
+ * either.
+ */
+ bool add_index = !(((programInterface == GL_PROGRAM_INPUT) &&
+ res->StageReferences & (1 << MESA_SHADER_GEOMETRY)));
+
+ if (add_index && _mesa_program_resource_array_size(res)) {
+ int i;
+
+ /* The comparison is strange because *length does *NOT* include the
+ * terminating NUL, but maxLength does.
+ */
+ for (i = 0; i < 3 && (*length + i + 1) < bufSize; i++)
+ name[*length + i] = "[0]"[i];
+
+ name[*length + i] = '\0';
+ *length += i;
+ }
+ return true;
+}
+
+static GLint
+program_resource_location(struct gl_shader_program *shProg,
+ struct gl_program_resource *res, const char *name)
+{
+ unsigned index, offset;
+ int array_index = -1;
+
+ if (res->Type == GL_PROGRAM_INPUT || res->Type == GL_PROGRAM_OUTPUT) {
+ array_index = array_index_of_resource(res, name);
+ if (array_index < 0)
+ return -1;
+ }
+
+ /* VERT_ATTRIB_GENERIC0 and FRAG_RESULT_DATA0 are decremented as these
+ * offsets are used internally to differentiate between built-in attributes
+ * and user-defined attributes.
+ */
+ switch (res->Type) {
+ case GL_PROGRAM_INPUT:
+ return RESOURCE_VAR(res)->data.location + array_index - VERT_ATTRIB_GENERIC0;
+ case GL_PROGRAM_OUTPUT:
+ return RESOURCE_VAR(res)->data.location + array_index - FRAG_RESULT_DATA0;
+ case GL_UNIFORM:
+ index = _mesa_get_uniform_location(shProg, name, &offset);
+
+ if (index == GL_INVALID_INDEX)
+ return -1;
+
+ /* From the GL_ARB_uniform_buffer_object spec:
*
- * "If name is not an active attribute, if name is a conventional
- * attribute, or if an error occurs, -1 will be returned."
+ * "The value -1 will be returned if <name> does not correspond to an
+ * active uniform variable name in <program>, if <name> is associated
+ * with a named uniform block, or if <name> starts with the reserved
+ * prefix "gl_"."
*/
- if (var == NULL
- || var->data.mode != ir_var_shader_out
- || var->data.location == -1
- || var->data.location < FRAG_RESULT_DATA0)
- continue;
+ if (RESOURCE_UNI(res)->block_index != -1 ||
+ RESOURCE_UNI(res)->atomic_buffer_index != -1)
+ return -1;
- int index = get_matching_index(var, (const char *) name);
+ /* location in remap table + array element offset */
+ return RESOURCE_UNI(res)->remap_location + offset;
- if (index >= 0)
- return var->data.location + index - FRAG_RESULT_DATA0;
+ default:
+ return -1;
}
+}
- return -1;
+/**
+ * Function implements following location queries:
+ * glGetAttribLocation
+ * glGetFragDataLocation
+ * glGetUniformLocation
+ */
+GLint
+_mesa_program_resource_location(struct gl_shader_program *shProg,
+ GLenum programInterface, const char *name)
+{
+ struct gl_program_resource *res =
+ _mesa_program_resource_find_name(shProg, programInterface, name);
+
+ /* Resource not found. */
+ if (!res)
+ return -1;
+
+ return program_resource_location(shProg, res, name);
+}
+
+/**
+ * Function implements following index queries:
+ * glGetFragDataIndex
+ */
+GLint
+_mesa_program_resource_location_index(struct gl_shader_program *shProg,
+ GLenum programInterface, const char *name)
+{
+ struct gl_program_resource *res =
+ _mesa_program_resource_find_name(shProg, programInterface, name);
+
+ /* Non-existent variable or resource is not referenced by fragment stage. */
+ if (!res || !(res->StageReferences & (1 << MESA_SHADER_FRAGMENT)))
+ return -1;
+
+ return RESOURCE_VAR(res)->data.index;
+}
+
+static uint8_t
+stage_from_enum(GLenum ref)
+{
+ switch (ref) {
+ case GL_REFERENCED_BY_VERTEX_SHADER:
+ return MESA_SHADER_VERTEX;
+ case GL_REFERENCED_BY_GEOMETRY_SHADER:
+ return MESA_SHADER_GEOMETRY;
+ case GL_REFERENCED_BY_FRAGMENT_SHADER:
+ return MESA_SHADER_FRAGMENT;
+ default:
+ assert(!"shader stage not supported");
+ return MESA_SHADER_STAGES;
+ }
+}
+
+/**
+ * Check if resource is referenced by given 'referenced by' stage enum.
+ * ATC and UBO resources hold stage references of their own.
+ */
+static bool
+is_resource_referenced(struct gl_shader_program *shProg,
+ struct gl_program_resource *res,
+ GLuint index, uint8_t stage)
+{
+ if (res->Type == GL_ATOMIC_COUNTER_BUFFER)
+ return RESOURCE_ATC(res)->StageReferences[stage];
+
+ if (res->Type == GL_UNIFORM_BLOCK)
+ return shProg->UniformBlockStageIndex[stage][index] != -1;
+
+ return res->StageReferences & (1 << stage);
+}
+
+static unsigned
+get_buffer_property(struct gl_shader_program *shProg,
+ struct gl_program_resource *res, const GLenum prop,
+ GLint *val, const char *caller)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (res->Type != GL_UNIFORM_BLOCK &&
+ res->Type != GL_ATOMIC_COUNTER_BUFFER)
+ goto invalid_operation;
+
+ if (res->Type == GL_UNIFORM_BLOCK) {
+ switch (prop) {
+ case GL_BUFFER_BINDING:
+ *val = RESOURCE_UBO(res)->Binding;
+ return 1;
+ case GL_BUFFER_DATA_SIZE:
+ *val = RESOURCE_UBO(res)->UniformBufferSize;
+ return 1;
+ case GL_NUM_ACTIVE_VARIABLES:
+ *val = RESOURCE_UBO(res)->NumUniforms;
+ return 1;
+ case GL_ACTIVE_VARIABLES:
+ for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
+ const char *iname = RESOURCE_UBO(res)->Uniforms[i].IndexName;
+ struct gl_program_resource *uni =
+ _mesa_program_resource_find_name(shProg, GL_UNIFORM, iname);
+ *val++ =
+ _mesa_program_resource_index(shProg, uni);
+ }
+ return RESOURCE_UBO(res)->NumUniforms;
+ }
+ } else if (res->Type == GL_ATOMIC_COUNTER_BUFFER) {
+ switch (prop) {
+ case GL_BUFFER_BINDING:
+ *val = RESOURCE_ATC(res)->Binding;
+ return 1;
+ case GL_BUFFER_DATA_SIZE:
+ *val = RESOURCE_ATC(res)->MinimumSize;
+ return 1;
+ case GL_NUM_ACTIVE_VARIABLES:
+ *val = RESOURCE_ATC(res)->NumUniforms;
+ return 1;
+ case GL_ACTIVE_VARIABLES:
+ for (unsigned i = 0; i < RESOURCE_ATC(res)->NumUniforms; i++)
+ *val++ = RESOURCE_ATC(res)->Uniforms[i];
+ return RESOURCE_ATC(res)->NumUniforms;
+ }
+ }
+ assert(!"support for property type not implemented");
+
+invalid_operation:
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s prop %s)", caller,
+ _mesa_lookup_enum_by_nr(res->Type),
+ _mesa_lookup_enum_by_nr(prop));
+
+ return 0;
+}
+
+unsigned
+_mesa_program_resource_prop(struct gl_shader_program *shProg,
+ struct gl_program_resource *res, GLuint index,
+ const GLenum prop, GLint *val, const char *caller)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+#define VALIDATE_TYPE(type)\
+ if (res->Type != type)\
+ goto invalid_operation;
+
+ switch(prop) {
+ case GL_NAME_LENGTH:
+ if (res->Type == GL_ATOMIC_COUNTER_BUFFER)
+ goto invalid_operation;
+ /* Base name +3 if array '[0]' + terminator. */
+ *val = strlen(_mesa_program_resource_name(res)) +
+ (_mesa_program_resource_array_size(res) > 0 ? 3 : 0) + 1;
+ return 1;
+ case GL_TYPE:
+ switch (res->Type) {
+ case GL_UNIFORM:
+ *val = RESOURCE_UNI(res)->type->gl_type;
+ return 1;
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ *val = RESOURCE_VAR(res)->type->gl_type;
+ return 1;
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ *val = RESOURCE_XFB(res)->Type;
+ return 1;
+ default:
+ goto invalid_operation;
+ }
+ case GL_ARRAY_SIZE:
+ switch (res->Type) {
+ case GL_UNIFORM:
+ *val = MAX2(RESOURCE_UNI(res)->array_elements, 1);
+ return 1;
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ *val = MAX2(RESOURCE_VAR(res)->type->length, 1);
+ return 1;
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ *val = MAX2(RESOURCE_XFB(res)->Size, 1);
+ return 1;
+ default:
+ goto invalid_operation;
+ }
+ case GL_OFFSET:
+ VALIDATE_TYPE(GL_UNIFORM);
+ *val = RESOURCE_UNI(res)->offset;
+ return 1;
+ case GL_BLOCK_INDEX:
+ VALIDATE_TYPE(GL_UNIFORM);
+ *val = RESOURCE_UNI(res)->block_index;
+ return 1;
+ case GL_ARRAY_STRIDE:
+ VALIDATE_TYPE(GL_UNIFORM);
+ *val = RESOURCE_UNI(res)->array_stride;
+ return 1;
+ case GL_MATRIX_STRIDE:
+ VALIDATE_TYPE(GL_UNIFORM);
+ *val = RESOURCE_UNI(res)->matrix_stride;
+ return 1;
+ case GL_IS_ROW_MAJOR:
+ VALIDATE_TYPE(GL_UNIFORM);
+ *val = RESOURCE_UNI(res)->row_major;
+ return 1;
+ case GL_ATOMIC_COUNTER_BUFFER_INDEX:
+ VALIDATE_TYPE(GL_UNIFORM);
+ *val = RESOURCE_UNI(res)->atomic_buffer_index;
+ return 1;
+ case GL_BUFFER_BINDING:
+ case GL_BUFFER_DATA_SIZE:
+ case GL_NUM_ACTIVE_VARIABLES:
+ case GL_ACTIVE_VARIABLES:
+ return get_buffer_property(shProg, res, prop, val, caller);
+ case GL_REFERENCED_BY_VERTEX_SHADER:
+ case GL_REFERENCED_BY_GEOMETRY_SHADER:
+ case GL_REFERENCED_BY_FRAGMENT_SHADER:
+ switch (res->Type) {
+ case GL_UNIFORM:
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ case GL_UNIFORM_BLOCK:
+ case GL_ATOMIC_COUNTER_BUFFER:
+ *val = is_resource_referenced(shProg, res, index,
+ stage_from_enum(prop));
+ return 1;
+ default:
+ goto invalid_operation;
+ }
+ case GL_LOCATION:
+ switch (res->Type) {
+ case GL_UNIFORM:
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ *val = program_resource_location(shProg, res,
+ _mesa_program_resource_name(res));
+ return 1;
+ default:
+ goto invalid_operation;
+ }
+ case GL_LOCATION_INDEX:
+ if (res->Type != GL_PROGRAM_OUTPUT)
+ goto invalid_operation;
+ *val = RESOURCE_VAR(res)->data.index;
+ return 1;
+
+ /* GL_ARB_tessellation_shader */
+ case GL_IS_PER_PATCH:
+ case GL_REFERENCED_BY_TESS_CONTROL_SHADER:
+ case GL_REFERENCED_BY_TESS_EVALUATION_SHADER:
+ /* GL_ARB_compute_shader */
+ case GL_REFERENCED_BY_COMPUTE_SHADER:
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(%s prop %s)", caller,
+ _mesa_lookup_enum_by_nr(res->Type),
+ _mesa_lookup_enum_by_nr(prop));
+ return 0;
+ }
+
+#undef VALIDATE_TYPE
+
+invalid_operation:
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s prop %s)", caller,
+ _mesa_lookup_enum_by_nr(res->Type),
+ _mesa_lookup_enum_by_nr(prop));
+ return 0;
+}
+
+extern void
+_mesa_get_program_resourceiv(struct gl_shader_program *shProg,
+ GLenum programInterface, GLuint index, GLsizei propCount,
+ const GLenum *props, GLsizei bufSize,
+ GLsizei *length, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint *val = (GLint *) params;
+ const GLenum *prop = props;
+ GLsizei amount = 0;
+
+ struct gl_program_resource *res =
+ _mesa_program_resource_find_index(shProg, programInterface, index);
+
+ /* No such resource found or bufSize negative. */
+ if (!res || bufSize < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetProgramResourceiv(%s index %d bufSize %d)",
+ _mesa_lookup_enum_by_nr(programInterface), index, bufSize);
+ return;
+ }
+
+ /* Write propCount values until error occurs or bufSize reached. */
+ for (int i = 0; i < propCount && i < bufSize; i++, val++, prop++) {
+ int props_written =
+ _mesa_program_resource_prop(shProg, res, index, *prop, val,
+ "glGetProgramResourceiv");
+
+ /* Error happened. */
+ if (props_written == 0)
+ return;
+
+ amount += props_written;
+ }
+
+ /* If <length> is not NULL, the actual number of integer values
+ * written to <params> will be written to <length>.
+ */
+ if (length)
+ *length = amount;
}
diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c
index 30716f5e3..77e2b8745 100644
--- a/mesalib/src/mesa/main/shaderapi.c
+++ b/mesalib/src/mesa/main/shaderapi.c
@@ -882,10 +882,9 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj)
sh->CompileStatus = GL_FALSE;
} else {
if (ctx->_Shader->Flags & GLSL_DUMP) {
- fprintf(stderr, "GLSL source for %s shader %d:\n",
+ _mesa_log("GLSL source for %s shader %d:\n",
_mesa_shader_stage_to_string(sh->Stage), sh->Name);
- fprintf(stderr, "%s\n", sh->Source);
- fflush(stderr);
+ _mesa_log("%s\n", sh->Source);
}
/* this call will set the shader->CompileStatus field to indicate if
@@ -899,27 +898,25 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj)
if (ctx->_Shader->Flags & GLSL_DUMP) {
if (sh->CompileStatus) {
- fprintf(stderr, "GLSL IR for shader %d:\n", sh->Name);
- _mesa_print_ir(stderr, sh->ir, NULL);
- fprintf(stderr, "\n\n");
+ _mesa_log("GLSL IR for shader %d:\n", sh->Name);
+ _mesa_print_ir(_mesa_get_log_file(), sh->ir, NULL);
+ _mesa_log("\n\n");
} else {
- fprintf(stderr, "GLSL shader %d failed to compile.\n", sh->Name);
+ _mesa_log("GLSL shader %d failed to compile.\n", sh->Name);
}
if (sh->InfoLog && sh->InfoLog[0] != 0) {
- fprintf(stderr, "GLSL shader %d info log:\n", sh->Name);
- fprintf(stderr, "%s\n", sh->InfoLog);
+ _mesa_log("GLSL shader %d info log:\n", sh->Name);
+ _mesa_log("%s\n", sh->InfoLog);
}
- fflush(stderr);
}
}
if (!sh->CompileStatus) {
if (ctx->_Shader->Flags & GLSL_DUMP_ON_ERROR) {
- fprintf(stderr, "GLSL source for %s shader %d:\n",
+ _mesa_log("GLSL source for %s shader %d:\n",
_mesa_shader_stage_to_string(sh->Stage), sh->Name);
- fprintf(stderr, "%s\n", sh->Source);
- fprintf(stderr, "Info Log:\n%s\n", sh->InfoLog);
- fflush(stderr);
+ _mesa_log("%s\n", sh->Source);
+ _mesa_log("Info Log:\n%s\n", sh->InfoLog);
}
if (ctx->_Shader->Flags & GLSL_REPORT_ERRORS) {
diff --git a/mesalib/src/mesa/main/shaderapi.h b/mesalib/src/mesa/main/shaderapi.h
index 047d2562d..aba6d5d83 100644
--- a/mesalib/src/mesa/main/shaderapi.h
+++ b/mesalib/src/mesa/main/shaderapi.h
@@ -219,6 +219,51 @@ extern GLuint GLAPIENTRY
_mesa_CreateShaderProgramv(GLenum type, GLsizei count,
const GLchar* const *strings);
+/* GL_ARB_program_resource_query */
+extern const char*
+_mesa_program_resource_name(struct gl_program_resource *res);
+
+extern unsigned
+_mesa_program_resource_array_size(struct gl_program_resource *res);
+
+extern GLuint
+_mesa_program_resource_index(struct gl_shader_program *shProg,
+ struct gl_program_resource *res);
+
+extern struct gl_program_resource *
+_mesa_program_resource_find_name(struct gl_shader_program *shProg,
+ GLenum programInterface, const char *name);
+
+extern struct gl_program_resource *
+_mesa_program_resource_find_index(struct gl_shader_program *shProg,
+ GLenum programInterface, GLuint index);
+
+extern bool
+_mesa_get_program_resource_name(struct gl_shader_program *shProg,
+ GLenum programInterface, GLuint index,
+ GLsizei bufSize, GLsizei *length,
+ GLchar *name, const char *caller);
+
+extern GLint
+_mesa_program_resource_location(struct gl_shader_program *shProg,
+ GLenum programInterface, const char *name);
+
+extern GLint
+_mesa_program_resource_location_index(struct gl_shader_program *shProg,
+ GLenum programInterface, const char *name);
+
+extern unsigned
+_mesa_program_resource_prop(struct gl_shader_program *shProg,
+ struct gl_program_resource *res, GLuint index,
+ const GLenum prop, GLint *val, const char *caller);
+
+extern void
+_mesa_get_program_resourceiv(struct gl_shader_program *shProg,
+ GLenum programInterface, GLuint index,
+ GLsizei propCount, const GLenum *props,
+ GLsizei bufSize, GLsizei *length,
+ GLint *params);
+
#ifdef __cplusplus
}
#endif
diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c
index d7620c8ef..e42896036 100644
--- a/mesalib/src/mesa/main/shaderobj.c
+++ b/mesalib/src/mesa/main/shaderobj.c
@@ -315,6 +315,12 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
ralloc_free(shProg->AtomicBuffers);
shProg->AtomicBuffers = NULL;
shProg->NumAtomicBuffers = 0;
+
+ if (shProg->ProgramResourceList) {
+ ralloc_free(shProg->ProgramResourceList);
+ shProg->ProgramResourceList = NULL;
+ shProg->NumProgramResourceList = 0;
+ }
}
diff --git a/mesalib/src/mesa/main/state.c b/mesalib/src/mesa/main/state.c
index dadfb3c8c..cc84c6148 100644
--- a/mesalib/src/mesa/main/state.c
+++ b/mesalib/src/mesa/main/state.c
@@ -269,28 +269,6 @@ update_program_constants(struct gl_context *ctx)
-static void
-update_viewport_matrix(struct gl_context *ctx)
-{
- const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
- unsigned i;
-
- assert(depthMax > 0);
-
- /* Compute scale and bias values. This is really driver-specific
- * and should be maintained elsewhere if at all.
- * NOTE: RasterPos uses this.
- */
- for (i = 0; i < ctx->Const.MaxViewports; i++) {
- double scale[3], translate[3];
-
- _mesa_get_viewport_xform(ctx, i, scale, translate);
- _math_matrix_viewport(&ctx->ViewportArray[i]._WindowMap,
- scale, translate, depthMax);
- }
-}
-
-
/**
* Update the ctx->Polygon._FrontBit flag.
*/
@@ -407,9 +385,6 @@ _mesa_update_state_locked( struct gl_context *ctx )
if (new_state & _NEW_PIXEL)
_mesa_update_pixel( ctx, new_state );
- if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT))
- update_viewport_matrix(ctx);
-
if (new_state & (_NEW_MULTISAMPLE | _NEW_BUFFERS))
update_multisample( ctx );
@@ -507,7 +482,7 @@ _mesa_set_varying_vp_inputs( struct gl_context *ctx,
ctx->FragmentProgram._TexEnvProgram) {
ctx->NewState |= _NEW_VARYING_VP_INPUTS;
}
- /*printf("%s %x\n", __FUNCTION__, varying_inputs);*/
+ /*printf("%s %x\n", __func__, varying_inputs);*/
}
}
diff --git a/mesalib/src/mesa/main/texcompress.c b/mesalib/src/mesa/main/texcompress.c
index 00234d4cc..0fd1a3683 100644
--- a/mesalib/src/mesa/main/texcompress.c
+++ b/mesalib/src/mesa/main/texcompress.c
@@ -32,7 +32,6 @@
#include "glheader.h"
#include "imports.h"
-#include "colormac.h"
#include "context.h"
#include "formats.h"
#include "mtypes.h"
diff --git a/mesalib/src/mesa/main/texcompress_fxt1.c b/mesalib/src/mesa/main/texcompress_fxt1.c
index 562359410..f06f04882 100644
--- a/mesalib/src/mesa/main/texcompress_fxt1.c
+++ b/mesalib/src/mesa/main/texcompress_fxt1.c
@@ -31,7 +31,6 @@
#include "glheader.h"
#include "imports.h"
-#include "colormac.h"
#include "image.h"
#include "macros.h"
#include "mipmap.h"
diff --git a/mesalib/src/mesa/main/texcompress_rgtc.c b/mesalib/src/mesa/main/texcompress_rgtc.c
index f40e4e6c0..66de1f17d 100644
--- a/mesalib/src/mesa/main/texcompress_rgtc.c
+++ b/mesalib/src/mesa/main/texcompress_rgtc.c
@@ -35,7 +35,6 @@
#include "glheader.h"
#include "imports.h"
-#include "colormac.h"
#include "image.h"
#include "macros.h"
#include "mipmap.h"
diff --git a/mesalib/src/mesa/main/texcompress_s3tc.c b/mesalib/src/mesa/main/texcompress_s3tc.c
index 41d00d4e9..7ce3cb88e 100644
--- a/mesalib/src/mesa/main/texcompress_s3tc.c
+++ b/mesalib/src/mesa/main/texcompress_s3tc.c
@@ -29,13 +29,8 @@
* GL_EXT_texture_compression_s3tc support.
*/
-#ifndef USE_EXTERNAL_DXTN_LIB
-#define USE_EXTERNAL_DXTN_LIB 1
-#endif
-
#include "glheader.h"
#include "imports.h"
-#include "colormac.h"
#include "dlopen.h"
#include "image.h"
#include "macros.h"
@@ -77,7 +72,6 @@ _mesa_init_texture_s3tc( struct gl_context *ctx )
{
/* called during context initialization */
ctx->Mesa_DXTn = GL_FALSE;
-#if USE_EXTERNAL_DXTN_LIB
if (!dxtlibhandle) {
dxtlibhandle = _mesa_dlopen(DXTN_LIBNAME, 0);
if (!dxtlibhandle) {
@@ -118,9 +112,6 @@ _mesa_init_texture_s3tc( struct gl_context *ctx )
if (dxtlibhandle) {
ctx->Mesa_DXTn = GL_TRUE;
}
-#else
- (void) ctx;
-#endif
}
/**
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index 1ef728660..b5d42d304 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -32,7 +32,6 @@
#include <stdbool.h>
#include "main/glheader.h"
#include "main/blend.h"
-#include "main/colormac.h"
#include "main/context.h"
#include "main/enums.h"
#include "main/formats.h"
diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c
index 0a7f983fb..1af9d47f0 100644
--- a/mesalib/src/mesa/main/texstate.c
+++ b/mesalib/src/mesa/main/texstate.c
@@ -31,8 +31,6 @@
#include <stdio.h>
#include "glheader.h"
#include "bufferobj.h"
-#include "colormac.h"
-#include "colortab.h"
#include "context.h"
#include "enums.h"
#include "macros.h"
diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c
index 7ad9d2b68..152520598 100644
--- a/mesalib/src/mesa/main/texstore.c
+++ b/mesalib/src/mesa/main/texstore.c
@@ -53,7 +53,6 @@
#include "glheader.h"
#include "bufferobj.h"
-#include "colormac.h"
#include "format_pack.h"
#include "format_utils.h"
#include "image.h"
diff --git a/mesalib/src/mesa/main/transformfeedback.c b/mesalib/src/mesa/main/transformfeedback.c
index ce678c864..103011ce5 100644
--- a/mesalib/src/mesa/main/transformfeedback.c
+++ b/mesalib/src/mesa/main/transformfeedback.c
@@ -514,22 +514,24 @@ _mesa_EndTransformFeedback(void)
* Helper used by BindBufferRange() and BindBufferBase().
*/
static void
-bind_buffer_range(struct gl_context *ctx, GLuint index,
+bind_buffer_range(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj,
+ GLuint index,
struct gl_buffer_object *bufObj,
- GLintptr offset, GLsizeiptr size)
+ GLintptr offset, GLsizeiptr size,
+ bool dsa)
{
- struct gl_transform_feedback_object *obj =
- ctx->TransformFeedback.CurrentObject;
-
/* Note: no need to FLUSH_VERTICES or flag NewTransformFeedback, because
* transform feedback buffers can't be changed while transform feedback is
* active.
*/
- /* The general binding point */
- _mesa_reference_buffer_object(ctx,
- &ctx->TransformFeedback.CurrentBuffer,
- bufObj);
+ if (!dsa) {
+ /* The general binding point */
+ _mesa_reference_buffer_object(ctx,
+ &ctx->TransformFeedback.CurrentBuffer,
+ bufObj);
+ }
/* The per-attribute binding point */
_mesa_set_transform_feedback_binding(ctx, obj, index, bufObj, offset, size);
@@ -539,75 +541,209 @@ bind_buffer_range(struct gl_context *ctx, GLuint index,
/**
* Specify a buffer object to receive transform feedback results. Plus,
* specify the starting offset to place the results, and max size.
- * Called from the glBindBufferRange() function.
+ * Called from the glBindBufferRange() and glTransformFeedbackBufferRange
+ * functions.
*/
void
_mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
- GLuint index,
- struct gl_buffer_object *bufObj,
- GLintptr offset,
- GLsizeiptr size)
+ struct gl_transform_feedback_object *obj,
+ GLuint index,
+ struct gl_buffer_object *bufObj,
+ GLintptr offset,
+ GLsizeiptr size,
+ bool dsa)
{
- struct gl_transform_feedback_object *obj;
+ const char *gl_methd_name;
+ if (dsa)
+ gl_methd_name = "glTransformFeedbackBufferRange";
+ else
+ gl_methd_name = "glBindBufferRange";
- obj = ctx->TransformFeedback.CurrentObject;
if (obj->Active) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBindBufferRange(transform feedback active)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(transform feedback active)",
+ gl_methd_name);
return;
}
if (index >= ctx->Const.MaxTransformFeedbackBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index);
+ /* OpenGL 4.5 core profile, 6.1, pdf page 82: "An INVALID_VALUE error is
+ * generated if index is greater than or equal to the number of binding
+ * points for transform feedback, as described in section 6.7.1."
+ */
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d out of bounds)",
+ gl_methd_name, index);
return;
}
if (size & 0x3) {
- /* must a multiple of four */
- _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)", (int) size);
+ /* OpenGL 4.5 core profile, 6.7, pdf page 103: multiple of 4 */
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d must be a multiple of "
+ "four)", gl_methd_name, (int) size);
return;
}
if (offset & 0x3) {
- /* must be multiple of four */
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glBindBufferRange(offset=%d)", (int) offset);
+ /* OpenGL 4.5 core profile, 6.7, pdf page 103: multiple of 4 */
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d must be a multiple "
+ "of four)", gl_methd_name, (int) offset);
return;
- }
+ }
+
+ if (offset < 0) {
+ /* OpenGL 4.5 core profile, 6.1, pdf page 82: "An INVALID_VALUE error is
+ * generated by BindBufferRange if offset is negative."
+ *
+ * OpenGL 4.5 core profile, 13.2, pdf page 445: "An INVALID_VALUE error
+ * is generated by TransformFeedbackBufferRange if offset is negative."
+ */
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d must be >= 0)",
+ gl_methd_name,
+ (int) offset);
+ return;
+ }
- bind_buffer_range(ctx, index, bufObj, offset, size);
+ if (size <= 0 && (dsa || bufObj != ctx->Shared->NullBufferObj)) {
+ /* OpenGL 4.5 core profile, 6.1, pdf page 82: "An INVALID_VALUE error is
+ * generated by BindBufferRange if buffer is non-zero and size is less
+ * than or equal to zero."
+ *
+ * OpenGL 4.5 core profile, 13.2, pdf page 445: "An INVALID_VALUE error
+ * is generated by TransformFeedbackBufferRange if size is less than or
+ * equal to zero."
+ */
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d must be > 0)",
+ gl_methd_name, (int) size);
+ return;
+ }
+
+ bind_buffer_range(ctx, obj, index, bufObj, offset, size, dsa);
}
/**
* Specify a buffer object to receive transform feedback results.
* As above, but start at offset = 0.
- * Called from the glBindBufferBase() function.
+ * Called from the glBindBufferBase() and glTransformFeedbackBufferBase()
+ * functions.
*/
void
_mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx,
- GLuint index,
- struct gl_buffer_object *bufObj)
+ struct gl_transform_feedback_object *obj,
+ GLuint index,
+ struct gl_buffer_object *bufObj,
+ bool dsa)
{
- struct gl_transform_feedback_object *obj;
-
- obj = ctx->TransformFeedback.CurrentObject;
-
if (obj->Active) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glBindBufferBase(transform feedback active)");
+ "%s(transform feedback active)",
+ dsa ? "glTransformFeedbackBufferBase" : "glBindBufferBase");
return;
}
if (index >= ctx->Const.MaxTransformFeedbackBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d out of bounds)",
+ dsa ? "glTransformFeedbackBufferBase" : "glBindBufferBase",
+ index);
+ return;
+ }
+
+ bind_buffer_range(ctx, obj, index, bufObj, 0, 0, dsa);
+}
+
+/**
+ * Wrapper around lookup_transform_feedback_object that throws
+ * GL_INVALID_OPERATION if id is not in the hash table. After calling
+ * _mesa_error, it returns NULL.
+ */
+static struct gl_transform_feedback_object *
+lookup_transform_feedback_object_err(struct gl_context *ctx,
+ GLuint xfb, const char* func)
+{
+ struct gl_transform_feedback_object *obj;
+
+ obj = _mesa_lookup_transform_feedback_object(ctx, xfb);
+ if (!obj) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(xfb=%u: non-generated object name)", func, xfb);
+ }
+
+ return obj;
+}
+
+/**
+ * Wrapper around _mesa_lookup_bufferobj that throws GL_INVALID_VALUE if id
+ * is not in the hash table. Specialised version for the
+ * transform-feedback-related functions. After calling _mesa_error, it
+ * returns NULL.
+ */
+static struct gl_buffer_object *
+lookup_transform_feedback_bufferobj_err(struct gl_context *ctx,
+ GLuint buffer, const char* func)
+{
+ struct gl_buffer_object *bufObj;
+
+ /* OpenGL 4.5 core profile, 13.2, pdf page 444: buffer must be zero or the
+ * name of an existing buffer object.
+ */
+ if (buffer == 0) {
+ bufObj = ctx->Shared->NullBufferObj;
+ } else {
+ bufObj = _mesa_lookup_bufferobj(ctx, buffer);
+ if (!bufObj) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid buffer=%u)", func,
+ buffer);
+ }
+ }
+
+ return bufObj;
+}
+
+void GLAPIENTRY
+_mesa_TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_transform_feedback_object *obj;
+ struct gl_buffer_object *bufObj;
+
+ obj = lookup_transform_feedback_object_err(ctx, xfb,
+ "glTransformFeedbackBufferBase");
+ if(!obj) {
+ return;
+ }
+
+ bufObj = lookup_transform_feedback_bufferobj_err(ctx, buffer,
+ "glTransformFeedbackBufferBase");
+ if(!bufObj) {
return;
}
- bind_buffer_range(ctx, index, bufObj, 0, 0);
+ _mesa_bind_buffer_base_transform_feedback(ctx, obj, index, bufObj, true);
}
+void GLAPIENTRY
+_mesa_TransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer,
+ GLintptr offset, GLsizeiptr size)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_transform_feedback_object *obj;
+ struct gl_buffer_object *bufObj;
+
+ obj = lookup_transform_feedback_object_err(ctx, xfb,
+ "glTransformFeedbackBufferRange");
+ if(!obj) {
+ return;
+ }
+
+ bufObj = lookup_transform_feedback_bufferobj_err(ctx, buffer,
+ "glTransformFeedbackBufferRange");
+ if(!bufObj) {
+ return;
+ }
+
+ _mesa_bind_buffer_range_transform_feedback(ctx, obj, index, bufObj, offset,
+ size, true);
+}
/**
* Specify a buffer object to receive transform feedback results, plus the
@@ -660,7 +796,7 @@ _mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer,
return;
}
- bind_buffer_range(ctx, index, bufObj, offset, 0);
+ bind_buffer_range(ctx, obj, index, bufObj, offset, 0, false);
}
@@ -784,7 +920,7 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index,
GLsizei *size, GLenum *type, GLchar *name)
{
const struct gl_shader_program *shProg;
- const struct gl_transform_feedback_info *linked_xfb_info;
+ struct gl_program_resource *res;
GET_CURRENT_CONTEXT(ctx);
shProg = _mesa_lookup_shader_program(ctx, program);
@@ -794,22 +930,27 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index,
return;
}
- linked_xfb_info = &shProg->LinkedTransformFeedback;
- if (index >= (GLuint) linked_xfb_info->NumVarying) {
+ res = _mesa_program_resource_find_index((struct gl_shader_program *) shProg,
+ GL_TRANSFORM_FEEDBACK_VARYING,
+ index);
+ if (!res) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetTransformFeedbackVarying(index=%u)", index);
return;
}
/* return the varying's name and length */
- _mesa_copy_string(name, bufSize, length,
- linked_xfb_info->Varyings[index].Name);
+ _mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res));
/* return the datatype and value's size (in datatype units) */
if (type)
- *type = linked_xfb_info->Varyings[index].Type;
+ _mesa_program_resource_prop((struct gl_shader_program *) shProg,
+ res, index, GL_TYPE, (GLint*) type,
+ "glGetTransformFeedbackVarying");
if (size)
- *size = linked_xfb_info->Varyings[index].Size;
+ _mesa_program_resource_prop((struct gl_shader_program *) shProg,
+ res, index, GL_ARRAY_SIZE, (GLint*) size,
+ "glGetTransformFeedbackVarying");
}
@@ -817,6 +958,10 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index,
struct gl_transform_feedback_object *
_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name)
{
+ /* OpenGL 4.5 core profile, 13.2 pdf page 444: "xfb must be zero, indicating
+ * the default transform feedback object, or the name of an existing
+ * transform feedback object."
+ */
if (name == 0) {
return ctx->TransformFeedback.DefaultObject;
}
@@ -825,25 +970,24 @@ _mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name)
_mesa_HashLookup(ctx->TransformFeedback.Objects, name);
}
-
-/**
- * Create new transform feedback objects. Transform feedback objects
- * encapsulate the state related to transform feedback to allow quickly
- * switching state (and drawing the results, below).
- * Part of GL_ARB_transform_feedback2.
- */
-void GLAPIENTRY
-_mesa_GenTransformFeedbacks(GLsizei n, GLuint *names)
+static void
+create_transform_feedbacks(struct gl_context *ctx, GLsizei n, GLuint *ids,
+ bool dsa)
{
GLuint first;
- GET_CURRENT_CONTEXT(ctx);
+ const char* func;
+
+ if (dsa)
+ func = "glCreateTransformFeedbacks";
+ else
+ func = "glGenTransformFeedbacks";
if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenTransformFeedbacks(n < 0)");
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
return;
}
- if (!names)
+ if (!ids)
return;
/* we don't need contiguous IDs, but this might be faster */
@@ -854,18 +998,56 @@ _mesa_GenTransformFeedbacks(GLsizei n, GLuint *names)
struct gl_transform_feedback_object *obj
= ctx->Driver.NewTransformFeedback(ctx, first + i);
if (!obj) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTransformFeedbacks");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
return;
}
- names[i] = first + i;
+ ids[i] = first + i;
_mesa_HashInsert(ctx->TransformFeedback.Objects, first + i, obj);
+ if (dsa) {
+ /* this is normally done at bind time in the non-dsa case */
+ obj->EverBound = GL_TRUE;
+ }
}
}
else {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTransformFeedbacks");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
}
}
+/**
+ * Create new transform feedback objects. Transform feedback objects
+ * encapsulate the state related to transform feedback to allow quickly
+ * switching state (and drawing the results, below).
+ * Part of GL_ARB_transform_feedback2.
+ */
+void GLAPIENTRY
+_mesa_GenTransformFeedbacks(GLsizei n, GLuint *names)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ /* GenTransformFeedbacks should just reserve the object names that a
+ * subsequent call to BindTransformFeedback should actively create. For
+ * the sake of simplicity, we reserve the names and create the objects
+ * straight away.
+ */
+
+ create_transform_feedbacks(ctx, n, names, false);
+}
+
+/**
+ * Create new transform feedback objects. Transform feedback objects
+ * encapsulate the state related to transform feedback to allow quickly
+ * switching state (and drawing the results, below).
+ * Part of GL_ARB_direct_state_access.
+ */
+void GLAPIENTRY
+_mesa_CreateTransformFeedbacks(GLsizei n, GLuint *names)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ create_transform_feedbacks(ctx, n, names, true);
+}
+
/**
* Is the given ID a transform feedback object?
@@ -1026,3 +1208,89 @@ _mesa_ResumeTransformFeedback(void)
assert(ctx->Driver.ResumeTransformFeedback);
ctx->Driver.ResumeTransformFeedback(ctx, obj);
}
+
+extern void GLAPIENTRY
+_mesa_GetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param)
+{
+ struct gl_transform_feedback_object *obj;
+ GET_CURRENT_CONTEXT(ctx);
+
+ obj = lookup_transform_feedback_object_err(ctx, xfb,
+ "glGetTransformFeedbackiv");
+ if(!obj) {
+ return;
+ }
+
+ switch(pname) {
+ case GL_TRANSFORM_FEEDBACK_PAUSED:
+ *param = obj->Paused;
+ break;
+ case GL_TRANSFORM_FEEDBACK_ACTIVE:
+ *param = obj->Active;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTransformFeedbackiv(pname=%i)", pname);
+ }
+}
+
+extern void GLAPIENTRY
+_mesa_GetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index,
+ GLint *param)
+{
+ struct gl_transform_feedback_object *obj;
+ GET_CURRENT_CONTEXT(ctx);
+
+ obj = lookup_transform_feedback_object_err(ctx, xfb,
+ "glGetTransformFeedbacki_v");
+ if(!obj) {
+ return;
+ }
+
+ if (index >= ctx->Const.MaxTransformFeedbackBuffers) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetTransformFeedbacki_v(index=%i)", index);
+ return;
+ }
+
+ switch(pname) {
+ case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+ *param = obj->BufferNames[index];
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTransformFeedbacki_v(pname=%i)", pname);
+ }
+}
+
+extern void GLAPIENTRY
+_mesa_GetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index,
+ GLint64 *param)
+{
+ struct gl_transform_feedback_object *obj;
+ GET_CURRENT_CONTEXT(ctx);
+
+ obj = lookup_transform_feedback_object_err(ctx, xfb,
+ "glGetTransformFeedbacki64_v");
+ if(!obj) {
+ return;
+ }
+
+ if (index >= ctx->Const.MaxTransformFeedbackBuffers) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetTransformFeedbacki64_v(index=%i)", index);
+ return;
+ }
+
+ switch(pname) {
+ case GL_TRANSFORM_FEEDBACK_BUFFER_START:
+ *param = obj->Offset[index];
+ break;
+ case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
+ *param = obj->RequestedSize[index];
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTransformFeedbacki64_v(pname=%i)", pname);
+ }
+}
diff --git a/mesalib/src/mesa/main/transformfeedback.h b/mesalib/src/mesa/main/transformfeedback.h
index 87f4080e0..bb9729cdb 100644
--- a/mesalib/src/mesa/main/transformfeedback.h
+++ b/mesalib/src/mesa/main/transformfeedback.h
@@ -65,15 +65,18 @@ _mesa_EndTransformFeedback(void);
extern void
_mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj,
GLuint index,
struct gl_buffer_object *bufObj,
GLintptr offset,
- GLsizeiptr size);
+ GLsizeiptr size, bool dsa);
extern void
_mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj,
GLuint index,
- struct gl_buffer_object *bufObj);
+ struct gl_buffer_object *bufObj,
+ bool dsa);
extern void GLAPIENTRY
_mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer,
@@ -102,6 +105,9 @@ _mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name);
extern void GLAPIENTRY
_mesa_GenTransformFeedbacks(GLsizei n, GLuint *names);
+extern void GLAPIENTRY
+_mesa_CreateTransformFeedbacks(GLsizei n, GLuint *names);
+
extern GLboolean GLAPIENTRY
_mesa_IsTransformFeedback(GLuint name);
@@ -141,4 +147,24 @@ _mesa_set_transform_feedback_binding(struct gl_context *ctx,
tfObj->RequestedSize[index] = size;
}
+/*** GL_ARB_direct_state_access ***/
+
+extern void GLAPIENTRY
+_mesa_TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer);
+
+extern void GLAPIENTRY
+_mesa_TransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer,
+ GLintptr offset, GLsizeiptr size);
+
+extern void GLAPIENTRY
+_mesa_GetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param);
+
+extern void GLAPIENTRY
+_mesa_GetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index,
+ GLint *param);
+
+extern void GLAPIENTRY
+_mesa_GetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index,
+ GLint64 *param);
+
#endif /* TRANSFORM_FEEDBACK_H */
diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp
index 2ab5528c3..4e77b3284 100644
--- a/mesalib/src/mesa/main/uniform_query.cpp
+++ b/mesalib/src/mesa/main/uniform_query.cpp
@@ -46,6 +46,7 @@ _mesa_GetActiveUniform(GLuint program, GLuint index,
{
GET_CURRENT_CONTEXT(ctx);
struct gl_shader_program *shProg;
+ struct gl_program_resource *res;
if (maxLength < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(maxLength < 0)");
@@ -56,26 +57,51 @@ _mesa_GetActiveUniform(GLuint program, GLuint index,
if (!shProg)
return;
- if (index >= shProg->NumUserUniformStorage) {
+ res = _mesa_program_resource_find_index((struct gl_shader_program *) shProg,
+ GL_UNIFORM, index);
+
+ if (!res) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
return;
}
- const struct gl_uniform_storage *const uni = &shProg->UniformStorage[index];
-
- if (nameOut) {
- _mesa_get_uniform_name(uni, maxLength, length, nameOut);
- }
-
- if (size) {
- /* array_elements is zero for non-arrays, but the API requires that 1 be
- * returned.
- */
- *size = MAX2(1, uni->array_elements);
- }
+ if (nameOut)
+ _mesa_get_program_resource_name(shProg, GL_UNIFORM, index, maxLength,
+ length, nameOut, "glGetActiveUniform");
+ if (type)
+ _mesa_program_resource_prop((struct gl_shader_program *) shProg,
+ res, index, GL_TYPE, (GLint*) type,
+ "glGetActiveUniform");
+ if (size)
+ _mesa_program_resource_prop((struct gl_shader_program *) shProg,
+ res, index, GL_ARRAY_SIZE, (GLint*) size,
+ "glGetActiveUniform");
+}
- if (type) {
- *type = uni->type->gl_type;
+static GLenum
+resource_prop_from_uniform_prop(GLenum uni_prop)
+{
+ switch (uni_prop) {
+ case GL_UNIFORM_TYPE:
+ return GL_TYPE;
+ case GL_UNIFORM_SIZE:
+ return GL_ARRAY_SIZE;
+ case GL_UNIFORM_NAME_LENGTH:
+ return GL_NAME_LENGTH;
+ case GL_UNIFORM_BLOCK_INDEX:
+ return GL_BLOCK_INDEX;
+ case GL_UNIFORM_OFFSET:
+ return GL_OFFSET;
+ case GL_UNIFORM_ARRAY_STRIDE:
+ return GL_ARRAY_STRIDE;
+ case GL_UNIFORM_MATRIX_STRIDE:
+ return GL_MATRIX_STRIDE;
+ case GL_UNIFORM_IS_ROW_MAJOR:
+ return GL_IS_ROW_MAJOR;
+ case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX:
+ return GL_ATOMIC_COUNTER_BUFFER_INDEX;
+ default:
+ return 0;
}
}
@@ -88,7 +114,8 @@ _mesa_GetActiveUniformsiv(GLuint program,
{
GET_CURRENT_CONTEXT(ctx);
struct gl_shader_program *shProg;
- GLsizei i;
+ struct gl_program_resource *res;
+ GLenum res_prop;
if (uniformCount < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
@@ -100,80 +127,21 @@ _mesa_GetActiveUniformsiv(GLuint program,
if (!shProg)
return;
- for (i = 0; i < uniformCount; i++) {
- GLuint index = uniformIndices[i];
+ res_prop = resource_prop_from_uniform_prop(pname);
- if (index >= shProg->NumUserUniformStorage) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)");
- return;
+ for (int i = 0; i < uniformCount; i++) {
+ res = _mesa_program_resource_find_index(shProg, GL_UNIFORM,
+ uniformIndices[i]);
+ if (!res) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)");
+ break;
}
- }
-
- for (i = 0; i < uniformCount; i++) {
- GLuint index = uniformIndices[i];
- const struct gl_uniform_storage *uni = &shProg->UniformStorage[index];
-
- switch (pname) {
- case GL_UNIFORM_TYPE:
- params[i] = uni->type->gl_type;
- break;
-
- case GL_UNIFORM_SIZE:
- /* array_elements is zero for non-arrays, but the API requires that 1 be
- * returned.
- */
- params[i] = MAX2(1, uni->array_elements);
- break;
- case GL_UNIFORM_NAME_LENGTH:
- params[i] = strlen(uni->name) + 1;
-
- /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0
- * spec says:
- *
- * "If the active uniform is an array, the uniform name returned
- * in name will always be the name of the uniform array appended
- * with "[0]"."
- */
- if (uni->array_elements != 0)
- params[i] += 3;
- break;
-
- case GL_UNIFORM_BLOCK_INDEX:
- params[i] = uni->block_index;
- break;
-
- case GL_UNIFORM_OFFSET:
- params[i] = uni->offset;
- break;
-
- case GL_UNIFORM_ARRAY_STRIDE:
- params[i] = uni->array_stride;
- break;
-
- case GL_UNIFORM_MATRIX_STRIDE:
- params[i] = uni->matrix_stride;
- break;
-
- case GL_UNIFORM_IS_ROW_MAJOR:
- params[i] = uni->row_major;
- break;
-
- case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX:
- if (!ctx->Extensions.ARB_shader_atomic_counters)
- goto invalid_enum;
- params[i] = uni->atomic_buffer_index;
+ if (!_mesa_program_resource_prop(shProg, res, uniformIndices[i],
+ res_prop, &params[i],
+ "glGetActiveUniformsiv"))
break;
-
- default:
- goto invalid_enum;
- }
}
-
- return;
-
- invalid_enum:
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)");
}
static struct gl_uniform_storage *
diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c
index fb1482f9c..5548d1d02 100644
--- a/mesalib/src/mesa/main/uniforms.c
+++ b/mesalib/src/mesa/main/uniforms.c
@@ -911,7 +911,6 @@ GLint GLAPIENTRY
_mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name)
{
struct gl_shader_program *shProg;
- GLuint index, offset;
GET_CURRENT_CONTEXT(ctx);
@@ -931,23 +930,7 @@ _mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name)
return -1;
}
- index = _mesa_get_uniform_location(shProg, name, &offset);
- if (index == GL_INVALID_INDEX)
- return -1;
-
- /* From the GL_ARB_uniform_buffer_object spec:
- *
- * "The value -1 will be returned if <name> does not correspond to an
- * active uniform variable name in <program>, if <name> is associated
- * with a named uniform block, or if <name> starts with the reserved
- * prefix "gl_"."
- */
- if (shProg->UniformStorage[index].block_index != -1 ||
- shProg->UniformStorage[index].atomic_buffer_index != -1)
- return -1;
-
- /* location in remap table + array element offset */
- return shProg->UniformStorage[index].remap_location + offset;
+ return _mesa_program_resource_location(shProg, GL_UNIFORM, name);
}
GLuint GLAPIENTRY
@@ -955,7 +938,6 @@ _mesa_GetUniformBlockIndex(GLuint program,
const GLchar *uniformBlockName)
{
GET_CURRENT_CONTEXT(ctx);
- GLuint i;
struct gl_shader_program *shProg;
if (!ctx->Extensions.ARB_uniform_buffer_object) {
@@ -968,12 +950,13 @@ _mesa_GetUniformBlockIndex(GLuint program,
if (!shProg)
return GL_INVALID_INDEX;
- for (i = 0; i < shProg->NumUniformBlocks; i++) {
- if (!strcmp(shProg->UniformBlocks[i].Name, uniformBlockName))
- return i;
- }
+ struct gl_program_resource *res =
+ _mesa_program_resource_find_name(shProg, GL_UNIFORM_BLOCK,
+ uniformBlockName);
+ if (!res)
+ return GL_INVALID_INDEX;
- return GL_INVALID_INDEX;
+ return _mesa_program_resource_index(shProg, res);
}
void GLAPIENTRY
@@ -1003,9 +986,9 @@ _mesa_GetUniformIndices(GLuint program,
}
for (i = 0; i < uniformCount; i++) {
- unsigned offset;
- uniformIndices[i] = _mesa_get_uniform_location(shProg,
- uniformNames[i], &offset);
+ struct gl_program_resource *res =
+ _mesa_program_resource_find_name(shProg, GL_UNIFORM, uniformNames[i]);
+ uniformIndices[i] = _mesa_program_resource_index(shProg, res);
}
}
@@ -1061,104 +1044,104 @@ _mesa_UniformBlockBinding(GLuint program,
}
}
-void GLAPIENTRY
-_mesa_GetActiveUniformBlockiv(GLuint program,
- GLuint uniformBlockIndex,
- GLenum pname,
- GLint *params)
+
+/**
+ * Generic program resource property query.
+ */
+static void
+mesa_bufferiv(struct gl_shader_program *shProg, GLenum type,
+ GLuint index, GLenum pname, GLint *params, const char *caller)
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_shader_program *shProg;
- struct gl_uniform_block *block;
- unsigned i;
+ struct gl_program_resource *res =
+ _mesa_program_resource_find_index(shProg, type, index);
- if (!ctx->Extensions.ARB_uniform_buffer_object) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
+ if (!res) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufferindex %d)", caller, index);
return;
}
- shProg = _mesa_lookup_shader_program_err(ctx, program,
- "glGetActiveUniformBlockiv");
- if (!shProg)
- return;
-
- if (uniformBlockIndex >= shProg->NumUniformBlocks) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glGetActiveUniformBlockiv(block index %u >= %u)",
- uniformBlockIndex, shProg->NumUniformBlocks);
- return;
- }
-
- block = &shProg->UniformBlocks[uniformBlockIndex];
-
switch (pname) {
case GL_UNIFORM_BLOCK_BINDING:
- params[0] = block->Binding;
+ case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+ _mesa_program_resource_prop(shProg, res, index, GL_BUFFER_BINDING,
+ params, caller);
return;
-
case GL_UNIFORM_BLOCK_DATA_SIZE:
- params[0] = block->UniformBufferSize;
+ case GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE:
+ _mesa_program_resource_prop(shProg, res, index, GL_BUFFER_DATA_SIZE,
+ params, caller);
return;
-
case GL_UNIFORM_BLOCK_NAME_LENGTH:
- params[0] = strlen(block->Name) + 1;
+ _mesa_program_resource_prop(shProg, res, index, GL_NAME_LENGTH,
+ params, caller);
return;
-
- case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: {
- unsigned count = 0;
-
- for (i = 0; i < block->NumUniforms; i++) {
- unsigned offset;
- const int idx =
- _mesa_get_uniform_location(shProg,
- block->Uniforms[i].IndexName,
- &offset);
- if (idx != -1)
- count++;
- }
-
- params[0] = count;
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+ case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS:
+ _mesa_program_resource_prop(shProg, res, index, GL_NUM_ACTIVE_VARIABLES,
+ params, caller);
return;
- }
-
- case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: {
- unsigned count = 0;
-
- for (i = 0; i < block->NumUniforms; i++) {
- unsigned offset;
- const int idx =
- _mesa_get_uniform_location(shProg,
- block->Uniforms[i].IndexName,
- &offset);
-
- if (idx != -1)
- params[count++] = idx;
- }
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+ case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES:
+ _mesa_program_resource_prop(shProg, res, index, GL_ACTIVE_VARIABLES,
+ params, caller);
return;
- }
-
case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
- params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_VERTEX][uniformBlockIndex] != -1;
+ case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER:
+ _mesa_program_resource_prop(shProg, res, index,
+ GL_REFERENCED_BY_VERTEX_SHADER, params,
+ caller);
return;
-
case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
- if (!_mesa_has_geometry_shaders(ctx))
- break;
- params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_GEOMETRY][uniformBlockIndex] != -1;
+ case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER:
+ _mesa_program_resource_prop(shProg, res, index,
+ GL_REFERENCED_BY_GEOMETRY_SHADER, params,
+ caller);
return;
-
case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
- params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_FRAGMENT][uniformBlockIndex] != -1;
+ case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER:
+ _mesa_program_resource_prop(shProg, res, index,
+ GL_REFERENCED_BY_FRAGMENT_SHADER, params,
+ caller);
+ return;
+ case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER:
+ params[0] = GL_FALSE;
+ return;
+ case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER:
+ params[0] = GL_FALSE;
return;
-
default:
_mesa_error(ctx, GL_INVALID_ENUM,
- "glGetActiveUniformBlockiv(pname 0x%x (%s))",
- pname, _mesa_lookup_enum_by_nr(pname));
+ "%s(pname 0x%x (%s))", caller, pname,
+ _mesa_lookup_enum_by_nr(pname));
return;
}
}
+
+void GLAPIENTRY
+_mesa_GetActiveUniformBlockiv(GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg;
+
+ if (!ctx->Extensions.ARB_uniform_buffer_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
+ return;
+ }
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program,
+ "glGetActiveUniformBlockiv");
+ if (!shProg)
+ return;
+
+ mesa_bufferiv(shProg, GL_UNIFORM_BLOCK, uniformBlockIndex, pname, params,
+ "glGetActiveUniformBlockiv");
+}
+
void GLAPIENTRY
_mesa_GetActiveUniformBlockName(GLuint program,
GLuint uniformBlockIndex,
@@ -1168,7 +1151,6 @@ _mesa_GetActiveUniformBlockName(GLuint program,
{
GET_CURRENT_CONTEXT(ctx);
struct gl_shader_program *shProg;
- struct gl_uniform_block *block;
if (!ctx->Extensions.ARB_uniform_buffer_object) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
@@ -1187,18 +1169,11 @@ _mesa_GetActiveUniformBlockName(GLuint program,
if (!shProg)
return;
- if (uniformBlockIndex >= shProg->NumUniformBlocks) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glGetActiveUniformBlockiv(block index %u >= %u)",
- uniformBlockIndex, shProg->NumUniformBlocks);
- return;
- }
-
- block = &shProg->UniformBlocks[uniformBlockIndex];
-
- if (uniformBlockName) {
- _mesa_copy_string(uniformBlockName, bufSize, length, block->Name);
- }
+ if (uniformBlockName)
+ _mesa_get_program_resource_name(shProg, GL_UNIFORM_BLOCK,
+ uniformBlockIndex, bufSize, length,
+ uniformBlockName,
+ "glGetActiveUniformBlockName");
}
void GLAPIENTRY
@@ -1226,54 +1201,8 @@ _mesa_GetActiveUniformName(GLuint program, GLuint uniformIndex,
if (!shProg)
return;
- if (uniformIndex >= shProg->NumUserUniformStorage) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
- return;
- }
-
- if (uniformName) {
- _mesa_get_uniform_name(& shProg->UniformStorage[uniformIndex],
- bufSize, length, uniformName);
- }
-}
-
-void
-_mesa_get_uniform_name(const struct gl_uniform_storage *uni,
- GLsizei maxLength, GLsizei *length,
- GLchar *nameOut)
-{
- GLsizei localLength;
-
- if (length == NULL)
- length = &localLength;
-
- _mesa_copy_string(nameOut, maxLength, length, uni->name);
-
- /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0
- * spec says:
- *
- * "If the active uniform is an array, the uniform name returned in
- * name will always be the name of the uniform array appended with
- * "[0]"."
- *
- * The same text also appears in the OpenGL 4.2 spec. It does not,
- * however, appear in any previous spec. Previous specifications are
- * ambiguous in this regard. However, either name can later be passed
- * to glGetUniformLocation (and related APIs), so there shouldn't be any
- * harm in always appending "[0]" to uniform array names.
- */
- if (uni->array_elements != 0) {
- int i;
-
- /* The comparison is strange because *length does *NOT* include the
- * terminating NUL, but maxLength does.
- */
- for (i = 0; i < 3 && (*length + i + 1) < maxLength; i++)
- nameOut[*length + i] = "[0]"[i];
-
- nameOut[*length + i] = '\0';
- *length += i;
- }
+ _mesa_get_program_resource_name(shProg, GL_UNIFORM, uniformIndex, bufSize,
+ length, uniformName, "glGetActiveUniformName");
}
void GLAPIENTRY
@@ -1282,8 +1211,6 @@ _mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex,
{
GET_CURRENT_CONTEXT(ctx);
struct gl_shader_program *shProg;
- struct gl_active_atomic_buffer *ab;
- GLuint i;
if (!ctx->Extensions.ARB_shader_atomic_counters) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -1296,49 +1223,8 @@ _mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex,
if (!shProg)
return;
- if (bufferIndex >= shProg->NumAtomicBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glGetActiveAtomicCounterBufferiv(bufferIndex)");
- return;
- }
-
- ab = &shProg->AtomicBuffers[bufferIndex];
-
- switch (pname) {
- case GL_ATOMIC_COUNTER_BUFFER_BINDING:
- params[0] = ab->Binding;
- return;
- case GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE:
- params[0] = ab->MinimumSize;
- return;
- case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS:
- params[0] = ab->NumUniforms;
- return;
- case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES:
- for (i = 0; i < ab->NumUniforms; ++i)
- params[i] = ab->Uniforms[i];
- return;
- case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER:
- params[0] = ab->StageReferences[MESA_SHADER_VERTEX];
- return;
- case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER:
- params[0] = ab->StageReferences[MESA_SHADER_GEOMETRY];
- return;
- case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER:
- params[0] = ab->StageReferences[MESA_SHADER_FRAGMENT];
- return;
- case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER:
- params[0] = GL_FALSE;
- return;
- case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER:
- params[0] = GL_FALSE;
- return;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetActiveAtomicCounterBufferiv(pname 0x%x (%s))",
- pname, _mesa_lookup_enum_by_nr(pname));
- return;
- }
+ mesa_bufferiv(shProg, GL_ATOMIC_COUNTER_BUFFER, bufferIndex, pname, params,
+ "glGetActiveAtomicCounterBufferiv");
}
void GLAPIENTRY
diff --git a/mesalib/src/mesa/main/uniforms.h b/mesalib/src/mesa/main/uniforms.h
index 0e6113fe9..55fa2357e 100644
--- a/mesalib/src/mesa/main/uniforms.h
+++ b/mesalib/src/mesa/main/uniforms.h
@@ -398,11 +398,6 @@ _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *);
extern const struct gl_program_parameter *
get_uniform_parameter(struct gl_shader_program *shProg, GLint index);
-extern void
-_mesa_get_uniform_name(const struct gl_uniform_storage *uni,
- GLsizei maxLength, GLsizei *length,
- GLchar *nameOut);
-
struct gl_builtin_uniform_element {
const char *field;
int tokens[STATE_LENGTH];
diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c
index 8e0c3ef5b..7c6d99418 100644
--- a/mesalib/src/mesa/main/version.c
+++ b/mesalib/src/mesa/main/version.c
@@ -382,6 +382,7 @@ compute_version_es2(const struct gl_extensions *extensions)
extensions->ARB_shader_texture_lod &&
extensions->ARB_texture_float &&
extensions->ARB_texture_rg &&
+ extensions->ARB_depth_buffer_float &&
extensions->EXT_draw_buffers2 &&
/* extensions->ARB_framebuffer_object && */
extensions->EXT_framebuffer_sRGB &&
diff --git a/mesalib/src/mesa/main/viewport.c b/mesalib/src/mesa/main/viewport.c
index 0adce9c78..b27063031 100644
--- a/mesalib/src/mesa/main/viewport.c
+++ b/mesalib/src/mesa/main/viewport.c
@@ -40,8 +40,6 @@ set_viewport_no_notify(struct gl_context *ctx, unsigned idx,
GLfloat x, GLfloat y,
GLfloat width, GLfloat height)
{
- double scale[3], translate[3];
-
/* clamp width and height to the implementation dependent range */
width = MIN2(width, (GLfloat) ctx->Const.MaxViewportWidth);
height = MIN2(height, (GLfloat) ctx->Const.MaxViewportHeight);
@@ -72,16 +70,6 @@ set_viewport_no_notify(struct gl_context *ctx, unsigned idx,
ctx->ViewportArray[idx].Y = y;
ctx->ViewportArray[idx].Height = height;
ctx->NewState |= _NEW_VIEWPORT;
-
-#if 1
- /* XXX remove this someday. Currently the DRI drivers rely on
- * the WindowMap matrix being up to date in the driver's Viewport
- * and DepthRange functions.
- */
- _mesa_get_viewport_xform(ctx, idx, scale, translate);
- _math_matrix_viewport(&ctx->ViewportArray[idx]._WindowMap,
- scale, translate, ctx->DrawBuffer->_DepthMaxF);
-#endif
}
struct gl_viewport_inputs {
@@ -140,8 +128,8 @@ _mesa_Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
/**
- * Set new viewport parameters and update derived state (the _WindowMap
- * matrix). Usually called from _mesa_Viewport().
+ * Set new viewport parameters and update derived state.
+ * Usually called from _mesa_Viewport().
*
* \param ctx GL context.
* \param idx Index of the viewport to be updated.
@@ -246,8 +234,6 @@ static void
set_depth_range_no_notify(struct gl_context *ctx, unsigned idx,
GLclampd nearval, GLclampd farval)
{
- double scale[3], translate[3];
-
if (ctx->ViewportArray[idx].Near == nearval &&
ctx->ViewportArray[idx].Far == farval)
return;
@@ -255,16 +241,6 @@ set_depth_range_no_notify(struct gl_context *ctx, unsigned idx,
ctx->ViewportArray[idx].Near = CLAMP(nearval, 0.0, 1.0);
ctx->ViewportArray[idx].Far = CLAMP(farval, 0.0, 1.0);
ctx->NewState |= _NEW_VIEWPORT;
-
-#if 1
- /* XXX remove this someday. Currently the DRI drivers rely on
- * the WindowMap matrix being up to date in the driver's Viewport
- * and DepthRange functions.
- */
- _mesa_get_viewport_xform(ctx, idx, scale, translate);
- _math_matrix_viewport(&ctx->ViewportArray[idx]._WindowMap,
- scale, translate, ctx->DrawBuffer->_DepthMaxF);
-#endif
}
void
@@ -388,7 +364,6 @@ _mesa_DepthRangeIndexed(GLuint index, GLclampd nearval, GLclampd farval)
*/
void _mesa_init_viewport(struct gl_context *ctx)
{
- GLfloat depthMax = 65535.0F; /* sorf of arbitrary */
unsigned i;
ctx->Transform.ClipOrigin = GL_LOWER_LEFT;
@@ -398,8 +373,6 @@ void _mesa_init_viewport(struct gl_context *ctx)
* so just initialize all of them.
*/
for (i = 0; i < MAX_VIEWPORTS; i++) {
- double scale[3], translate[3];
-
/* Viewport group */
ctx->ViewportArray[i].X = 0;
ctx->ViewportArray[i].Y = 0;
@@ -407,27 +380,10 @@ void _mesa_init_viewport(struct gl_context *ctx)
ctx->ViewportArray[i].Height = 0;
ctx->ViewportArray[i].Near = 0.0;
ctx->ViewportArray[i].Far = 1.0;
- _math_matrix_ctr(&ctx->ViewportArray[i]._WindowMap);
-
- _mesa_get_viewport_xform(ctx, i, scale, translate);
- _math_matrix_viewport(&ctx->ViewportArray[i]._WindowMap,
- scale, translate, depthMax);
}
}
-/**
- * Free the context viewport attribute group data.
- * \param ctx the GL context.
- */
-void _mesa_free_viewport_data(struct gl_context *ctx)
-{
- unsigned i;
-
- for (i = 0; i < MAX_VIEWPORTS; i++)
- _math_matrix_dtr(&ctx->ViewportArray[i]._WindowMap);
-}
-
extern void GLAPIENTRY
_mesa_ClipControl(GLenum origin, GLenum depth)
{
diff --git a/mesalib/src/mesa/main/viewport.h b/mesalib/src/mesa/main/viewport.h
index 426e194bd..899dc2d0b 100644
--- a/mesalib/src/mesa/main/viewport.h
+++ b/mesalib/src/mesa/main/viewport.h
@@ -68,9 +68,6 @@ extern void
_mesa_init_viewport(struct gl_context *ctx);
-extern void
-_mesa_free_viewport_data(struct gl_context *ctx);
-
extern void GLAPIENTRY
_mesa_ClipControl(GLenum origin, GLenum depth);
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 39790ec8e..3dcb53702 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -303,9 +303,6 @@ public:
void emit_scalar(ir_instruction *ir, enum prog_opcode op,
dst_reg dst, src_reg src0, src_reg src1);
- void emit_scs(ir_instruction *ir, enum prog_opcode op,
- dst_reg dst, const src_reg &src);
-
bool try_emit_mad(ir_expression *ir,
int mul_operand);
bool try_emit_mad_for_and_not(ir_expression *ir,
@@ -479,101 +476,6 @@ ir_to_mesa_visitor::emit_scalar(ir_instruction *ir, enum prog_opcode op,
emit_scalar(ir, op, dst, src0, undef);
}
-/**
- * Emit an OPCODE_SCS instruction
- *
- * The \c SCS opcode functions a bit differently than the other Mesa (or
- * ARB_fragment_program) opcodes. Instead of splatting its result across all
- * four components of the destination, it writes one value to the \c x
- * component and another value to the \c y component.
- *
- * \param ir IR instruction being processed
- * \param op Either \c OPCODE_SIN or \c OPCODE_COS depending on which
- * value is desired.
- * \param dst Destination register
- * \param src Source register
- */
-void
-ir_to_mesa_visitor::emit_scs(ir_instruction *ir, enum prog_opcode op,
- dst_reg dst,
- const src_reg &src)
-{
- /* Vertex programs cannot use the SCS opcode.
- */
- if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) {
- emit_scalar(ir, op, dst, src);
- return;
- }
-
- const unsigned component = (op == OPCODE_SIN) ? 0 : 1;
- const unsigned scs_mask = (1U << component);
- int done_mask = ~dst.writemask;
- src_reg tmp;
-
- assert(op == OPCODE_SIN || op == OPCODE_COS);
-
- /* If there are compnents in the destination that differ from the component
- * that will be written by the SCS instrution, we'll need a temporary.
- */
- if (scs_mask != unsigned(dst.writemask)) {
- tmp = get_temp(glsl_type::vec4_type);
- }
-
- for (unsigned i = 0; i < 4; i++) {
- unsigned this_mask = (1U << i);
- src_reg src0 = src;
-
- if ((done_mask & this_mask) != 0)
- continue;
-
- /* The source swizzle specified which component of the source generates
- * sine / cosine for the current component in the destination. The SCS
- * instruction requires that this value be swizzle to the X component.
- * Replace the current swizzle with a swizzle that puts the source in
- * the X component.
- */
- unsigned src0_swiz = GET_SWZ(src.swizzle, i);
-
- src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
- src0_swiz, src0_swiz);
- for (unsigned j = i + 1; j < 4; j++) {
- /* If there is another enabled component in the destination that is
- * derived from the same inputs, generate its value on this pass as
- * well.
- */
- if (!(done_mask & (1 << j)) &&
- GET_SWZ(src0.swizzle, j) == src0_swiz) {
- this_mask |= (1 << j);
- }
- }
-
- if (this_mask != scs_mask) {
- ir_to_mesa_instruction *inst;
- dst_reg tmp_dst = dst_reg(tmp);
-
- /* Emit the SCS instruction.
- */
- inst = emit(ir, OPCODE_SCS, tmp_dst, src0);
- inst->dst.writemask = scs_mask;
-
- /* Move the result of the SCS instruction to the desired location in
- * the destination.
- */
- tmp.swizzle = MAKE_SWIZZLE4(component, component,
- component, component);
- inst = emit(ir, OPCODE_SCS, dst, tmp);
- inst->dst.writemask = this_mask;
- } else {
- /* Emit the SCS instruction to write directly to the destination.
- */
- ir_to_mesa_instruction *inst = emit(ir, OPCODE_SCS, dst, src0);
- inst->dst.writemask = scs_mask;
- }
-
- done_mask |= this_mask;
- }
-}
-
src_reg
ir_to_mesa_visitor::src_reg_for_float(float val)
{
@@ -1122,12 +1024,6 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
case ir_unop_cos:
emit_scalar(ir, OPCODE_COS, result_dst, op[0]);
break;
- case ir_unop_sin_reduced:
- emit_scs(ir, OPCODE_SIN, result_dst, op[0]);
- break;
- case ir_unop_cos_reduced:
- emit_scs(ir, OPCODE_COS, result_dst, op[0]);
- break;
case ir_unop_dFdx:
emit(ir, OPCODE_DDX, result_dst, op[0]);
diff --git a/mesalib/src/mesa/program/prog_execute.c b/mesalib/src/mesa/program/prog_execute.c
index dc4919ae8..16e8e340d 100644
--- a/mesalib/src/mesa/program/prog_execute.c
+++ b/mesalib/src/mesa/program/prog_execute.c
@@ -37,7 +37,6 @@
#include "c99_math.h"
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "prog_execute.h"
#include "prog_instruction.h"
diff --git a/mesalib/src/mesa/program/prog_instruction.h b/mesalib/src/mesa/program/prog_instruction.h
index ab3acbc02..96da198f8 100644
--- a/mesalib/src/mesa/program/prog_instruction.h
+++ b/mesalib/src/mesa/program/prog_instruction.h
@@ -59,6 +59,8 @@
#define SWIZZLE_NOOP MAKE_SWIZZLE4(0,1,2,3)
#define GET_SWZ(swz, idx) (((swz) >> ((idx)*3)) & 0x7)
#define GET_BIT(msk, idx) (((msk) >> (idx)) & 0x1)
+/** Determine if swz contains SWIZZLE_ZERO/ONE/NIL for any components. */
+#define HAS_EXTENDED_SWIZZLE(swz) (swz & 0x924)
#define SWIZZLE_XYZW MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W)
#define SWIZZLE_XXXX MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)
diff --git a/mesalib/src/mesa/program/prog_parameter.c b/mesalib/src/mesa/program/prog_parameter.c
index cdfe25145..53e9813e6 100644
--- a/mesalib/src/mesa/program/prog_parameter.c
+++ b/mesalib/src/mesa/program/prog_parameter.c
@@ -190,40 +190,6 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList,
/**
- * Add a new named constant to the parameter list.
- * This will be used when the program contains something like this:
- * PARAM myVals = { 0, 1, 2, 3 };
- *
- * \param paramList the parameter list
- * \param name the name for the constant
- * \param values four float values
- * \return index/position of the new parameter in the parameter list
- */
-GLint
-_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
- const char *name, const gl_constant_value values[4],
- GLuint size)
-{
- /* first check if this is a duplicate constant */
- GLint pos;
- for (pos = 0; pos < (GLint)paramList->NumParameters; pos++) {
- const gl_constant_value *pvals = paramList->ParameterValues[pos];
- if (pvals[0].u == values[0].u &&
- pvals[1].u == values[1].u &&
- pvals[2].u == values[2].u &&
- pvals[3].u == values[3].u &&
- strcmp(paramList->Parameters[pos].Name, name) == 0) {
- /* Same name and value is already in the param list - reuse it */
- return pos;
- }
- }
- /* not found, add new parameter */
- return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name,
- size, GL_NONE, values, NULL);
-}
-
-
-/**
* Add a new unnamed constant to the parameter list. This will be used
* when a fragment/vertex program contains something like this:
* MOV r, { 0, 1, 2, 3 };
@@ -303,28 +269,6 @@ _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
swizzleOut);
}
-#if 0 /* not used yet */
-/**
- * Returns the number of 4-component registers needed to store a piece
- * of GL state. For matrices this may be as many as 4 registers,
- * everything else needs
- * just 1 register.
- */
-static GLuint
-sizeof_state_reference(const GLint *stateTokens)
-{
- if (stateTokens[0] == STATE_MATRIX) {
- GLuint rows = stateTokens[4] - stateTokens[3] + 1;
- assert(rows >= 1);
- assert(rows <= 4);
- return rows;
- }
- else {
- return 1;
- }
-}
-#endif
-
/**
* Add a new state reference to the parameter list.
@@ -365,22 +309,6 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList,
/**
- * Lookup a parameter value by name in the given parameter list.
- * \return pointer to the float[4] values.
- */
-gl_constant_value *
-_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
- GLsizei nameLen, const char *name)
-{
- GLint i = _mesa_lookup_parameter_index(paramList, nameLen, name);
- if (i < 0)
- return NULL;
- else
- return paramList->ParameterValues[i];
-}
-
-
-/**
* Given a program parameter name, find its position in the list of parameters.
* \param paramList the parameter list to search
* \param nameLen length of name (in chars).
diff --git a/mesalib/src/mesa/program/prog_parameter.h b/mesalib/src/mesa/program/prog_parameter.h
index 6b3b3c262..74a5fd918 100644
--- a/mesalib/src/mesa/program/prog_parameter.h
+++ b/mesalib/src/mesa/program/prog_parameter.h
@@ -120,11 +120,6 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList,
const gl_state_index state[STATE_LENGTH]);
extern GLint
-_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
- const char *name, const gl_constant_value values[4],
- GLuint size);
-
-extern GLint
_mesa_add_typed_unnamed_constant(struct gl_program_parameter_list *paramList,
const gl_constant_value values[4], GLuint size,
GLenum datatype, GLuint *swizzleOut);
@@ -138,10 +133,6 @@ extern GLint
_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
const gl_state_index stateTokens[STATE_LENGTH]);
-extern gl_constant_value *
-_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
- GLsizei nameLen, const char *name);
-
extern GLint
_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
GLsizei nameLen, const char *name);
diff --git a/mesalib/src/mesa/program/prog_to_nir.c b/mesalib/src/mesa/program/prog_to_nir.c
new file mode 100644
index 000000000..c738f5073
--- /dev/null
+++ b/mesalib/src/mesa/program/prog_to_nir.c
@@ -0,0 +1,1096 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ * Copyright © 2014-2015 Broadcom
+ * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "nir/nir.h"
+#include "nir/nir_builder.h"
+#include "glsl/list.h"
+#include "main/imports.h"
+#include "util/ralloc.h"
+
+#include "prog_to_nir.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_print.h"
+
+/**
+ * \file prog_to_nir.c
+ *
+ * A translator from Mesa IR (prog_instruction.h) to NIR. This is primarily
+ * intended to support ARB_vertex_program, ARB_fragment_program, and fixed-function
+ * vertex processing. Full GLSL support should use glsl_to_nir instead.
+ */
+
+struct ptn_compile {
+ const struct gl_program *prog;
+ nir_builder build;
+ bool error;
+
+ nir_variable *input_vars[VARYING_SLOT_MAX];
+ nir_variable *output_vars[VARYING_SLOT_MAX];
+ nir_register **output_regs;
+ nir_register **temp_regs;
+
+ nir_register *addr_reg;
+};
+
+#define SWIZ(X, Y, Z, W) \
+ (unsigned[4]){ SWIZZLE_##X, SWIZZLE_##Y, SWIZZLE_##Z, SWIZZLE_##W }
+#define ptn_swizzle(b, src, x, y, z, w) nir_swizzle(b, src, SWIZ(x, y, z, w), 4, true)
+#define ptn_channel(b, src, ch) nir_swizzle(b, src, SWIZ(ch, ch, ch, ch), 1, true)
+
+static nir_ssa_def *
+ptn_src_for_dest(struct ptn_compile *c, nir_alu_dest *dest)
+{
+ nir_builder *b = &c->build;
+
+ nir_alu_src src;
+ memset(&src, 0, sizeof(src));
+
+ if (dest->dest.is_ssa)
+ src.src = nir_src_for_ssa(&dest->dest.ssa);
+ else {
+ assert(!dest->dest.reg.indirect);
+ src.src = nir_src_for_reg(dest->dest.reg.reg);
+ src.src.reg.base_offset = dest->dest.reg.base_offset;
+ }
+
+ for (int i = 0; i < 4; i++)
+ src.swizzle[i] = i;
+
+ return nir_fmov_alu(b, src, 4);
+}
+
+static nir_alu_dest
+ptn_get_dest(struct ptn_compile *c, const struct prog_dst_register *prog_dst)
+{
+ nir_alu_dest dest;
+
+ memset(&dest, 0, sizeof(dest));
+
+ switch (prog_dst->File) {
+ case PROGRAM_TEMPORARY:
+ dest.dest.reg.reg = c->temp_regs[prog_dst->Index];
+ break;
+ case PROGRAM_OUTPUT:
+ dest.dest.reg.reg = c->output_regs[prog_dst->Index];
+ break;
+ case PROGRAM_ADDRESS:
+ assert(prog_dst->Index == 0);
+ dest.dest.reg.reg = c->addr_reg;
+ break;
+ case PROGRAM_UNDEFINED:
+ break;
+ }
+
+ dest.write_mask = prog_dst->WriteMask;
+ dest.saturate = false;
+
+ assert(!prog_dst->RelAddr);
+
+ return dest;
+}
+
+/**
+ * Multiply the contents of the ADDR register by 4 to convert from the number
+ * of vec4s to the number of floating point components.
+ */
+static nir_ssa_def *
+ptn_addr_reg_value(struct ptn_compile *c)
+{
+ nir_builder *b = &c->build;
+ nir_alu_src src;
+ memset(&src, 0, sizeof(src));
+ src.src = nir_src_for_reg(c->addr_reg);
+
+ return nir_imul(b, nir_fmov_alu(b, src, 1), nir_imm_int(b, 4));
+}
+
+static nir_ssa_def *
+ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
+{
+ nir_builder *b = &c->build;
+ nir_alu_src src;
+
+ memset(&src, 0, sizeof(src));
+
+ switch (prog_src->File) {
+ case PROGRAM_UNDEFINED:
+ return nir_imm_float(b, 0.0);
+ case PROGRAM_TEMPORARY:
+ assert(!prog_src->RelAddr && prog_src->Index >= 0);
+ src.src.reg.reg = c->temp_regs[prog_src->Index];
+ break;
+ case PROGRAM_INPUT: {
+ /* ARB_vertex_program doesn't allow relative addressing on vertex
+ * attributes; ARB_fragment_program has no relative addressing at all.
+ */
+ assert(!prog_src->RelAddr);
+
+ assert(prog_src->Index >= 0 && prog_src->Index < VARYING_SLOT_MAX);
+
+ nir_intrinsic_instr *load =
+ nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
+ load->num_components = 4;
+ load->variables[0] = nir_deref_var_create(load, c->input_vars[prog_src->Index]);
+
+ nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
+
+ src.src = nir_src_for_ssa(&load->dest.ssa);
+ break;
+ }
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_CONSTANT: {
+ /* We actually want to look at the type in the Parameters list for this,
+ * because it lets us upload constant builtin uniforms as actual
+ * constants.
+ */
+ struct gl_program_parameter_list *plist = c->prog->Parameters;
+ gl_register_file file = prog_src->RelAddr ? prog_src->File :
+ plist->Parameters[prog_src->Index].Type;
+
+ switch (file) {
+ case PROGRAM_CONSTANT:
+ if ((c->prog->IndirectRegisterFiles & (1 << PROGRAM_CONSTANT)) == 0) {
+ float *v = (float *) plist->ParameterValues[prog_src->Index];
+ src.src = nir_src_for_ssa(nir_imm_vec4(b, v[0], v[1], v[2], v[3]));
+ break;
+ }
+ /* FALLTHROUGH */
+ case PROGRAM_STATE_VAR: {
+ nir_intrinsic_op load_op =
+ prog_src->RelAddr ? nir_intrinsic_load_uniform_indirect :
+ nir_intrinsic_load_uniform;
+ nir_intrinsic_instr *load = nir_intrinsic_instr_create(b->shader, load_op);
+ nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
+ load->num_components = 4;
+
+ /* Multiply src->Index by 4 to scale from # of vec4s to components. */
+ load->const_index[0] = 4 * prog_src->Index;
+ load->const_index[1] = 1;
+
+ if (prog_src->RelAddr) {
+ nir_ssa_def *reladdr = ptn_addr_reg_value(c);
+ if (prog_src->Index < 0) {
+ /* This is a negative offset which should be added to the address
+ * register's value.
+ */
+ reladdr = nir_iadd(b, reladdr, nir_imm_int(b, load->const_index[0]));
+ load->const_index[0] = 0;
+ }
+ load->src[0] = nir_src_for_ssa(reladdr);
+ }
+
+ nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
+
+ src.src = nir_src_for_ssa(&load->dest.ssa);
+ break;
+ }
+ default:
+ fprintf(stderr, "bad uniform src register file: %s (%d)\n",
+ _mesa_register_file_name(file), file);
+ abort();
+ }
+ break;
+ }
+ default:
+ fprintf(stderr, "unknown src register file: %s (%d)\n",
+ _mesa_register_file_name(prog_src->File), prog_src->File);
+ abort();
+ }
+
+ nir_ssa_def *def;
+ if (!HAS_EXTENDED_SWIZZLE(prog_src->Swizzle)) {
+ for (int i = 0; i < 4; i++)
+ src.swizzle[i] = GET_SWZ(prog_src->Swizzle, i);
+
+ def = nir_fmov_alu(b, src, 4);
+ } else {
+ nir_ssa_def *chans[4];
+ for (int i = 0; i < 4; i++) {
+ int swizzle = GET_SWZ(prog_src->Swizzle, i);
+ if (swizzle == SWIZZLE_ZERO) {
+ chans[i] = nir_imm_float(b, 0.0);
+ } else if (swizzle == SWIZZLE_ONE) {
+ chans[i] = nir_imm_float(b, 1.0);
+ } else {
+ assert(swizzle != SWIZZLE_NIL);
+ nir_alu_instr *mov = nir_alu_instr_create(b->shader, nir_op_fmov);
+ nir_ssa_dest_init(&mov->instr, &mov->dest.dest, 1, NULL);
+ mov->dest.write_mask = 0x1;
+ mov->src[0] = src;
+ mov->src[0].swizzle[0] = swizzle;
+ nir_instr_insert_after_cf_list(b->cf_node_list, &mov->instr);
+
+ chans[i] = &mov->dest.dest.ssa;
+ }
+ }
+ def = nir_vec4(b, chans[0], chans[1], chans[2], chans[3]);
+ }
+
+ if (prog_src->Abs)
+ def = nir_fabs(b, def);
+
+ if (prog_src->Negate)
+ def = nir_fneg(b, def);
+
+ return def;
+}
+
+static void
+ptn_alu(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
+{
+ unsigned num_srcs = nir_op_infos[op].num_inputs;
+ nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
+ unsigned i;
+
+ for (i = 0; i < num_srcs; i++)
+ instr->src[i].src = nir_src_for_ssa(src[i]);
+
+ instr->dest = dest;
+ nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr);
+}
+
+static void
+ptn_move_dest_masked(nir_builder *b, nir_alu_dest dest,
+ nir_ssa_def *def, unsigned write_mask)
+{
+ if (!(dest.write_mask & write_mask))
+ return;
+
+ nir_alu_instr *mov = nir_alu_instr_create(b->shader, nir_op_fmov);
+ if (!mov)
+ return;
+
+ mov->dest = dest;
+ mov->dest.write_mask &= write_mask;
+ mov->src[0].src = nir_src_for_ssa(def);
+ for (unsigned i = def->num_components; i < 4; i++)
+ mov->src[0].swizzle[i] = def->num_components - 1;
+ nir_instr_insert_after_cf_list(b->cf_node_list, &mov->instr);
+}
+
+static void
+ptn_move_dest(nir_builder *b, nir_alu_dest dest, nir_ssa_def *def)
+{
+ ptn_move_dest_masked(b, dest, def, WRITEMASK_XYZW);
+}
+
+static void
+ptn_arl(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ptn_move_dest(b, dest, nir_f2i(b, nir_ffloor(b, src[0])));
+}
+
+/* EXP - Approximate Exponential Base 2
+ * dst.x = 2^{\lfloor src.x\rfloor}
+ * dst.y = src.x - \lfloor src.x\rfloor
+ * dst.z = 2^{src.x}
+ * dst.w = 1.0
+ */
+static void
+ptn_exp(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_ssa_def *srcx = ptn_channel(b, src[0], X);
+
+ ptn_move_dest_masked(b, dest, nir_fexp2(b, nir_ffloor(b, srcx)), WRITEMASK_X);
+ ptn_move_dest_masked(b, dest, nir_fsub(b, srcx, nir_ffloor(b, srcx)), WRITEMASK_Y);
+ ptn_move_dest_masked(b, dest, nir_fexp2(b, srcx), WRITEMASK_Z);
+ ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_W);
+}
+
+/* LOG - Approximate Logarithm Base 2
+ * dst.x = \lfloor\log_2{|src.x|}\rfloor
+ * dst.y = |src.x| * 2^{-\lfloor\log_2{|src.x|}\rfloor}}
+ * dst.z = \log_2{|src.x|}
+ * dst.w = 1.0
+ */
+static void
+ptn_log(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_ssa_def *abs_srcx = nir_fabs(b, ptn_channel(b, src[0], X));
+ nir_ssa_def *log2 = nir_flog2(b, abs_srcx);
+ nir_ssa_def *floor_log2 = nir_ffloor(b, log2);
+
+ ptn_move_dest_masked(b, dest, floor_log2, WRITEMASK_X);
+ ptn_move_dest_masked(b, dest,
+ nir_fmul(b, abs_srcx,
+ nir_fexp2(b, nir_fneg(b, floor_log2))),
+ WRITEMASK_Y);
+ ptn_move_dest_masked(b, dest, log2, WRITEMASK_Z);
+ ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_W);
+}
+
+/* DST - Distance Vector
+ * dst.x = 1.0
+ * dst.y = src0.y \times src1.y
+ * dst.z = src0.z
+ * dst.w = src1.w
+ */
+static void
+ptn_dst(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_X);
+ ptn_move_dest_masked(b, dest, nir_fmul(b, src[0], src[1]), WRITEMASK_Y);
+ ptn_move_dest_masked(b, dest, nir_fmov(b, src[0]), WRITEMASK_Z);
+ ptn_move_dest_masked(b, dest, nir_fmov(b, src[1]), WRITEMASK_W);
+}
+
+/* LIT - Light Coefficients
+ * dst.x = 1.0
+ * dst.y = max(src.x, 0.0)
+ * dst.z = (src.x > 0.0) ? max(src.y, 0.0)^{clamp(src.w, -128.0, 128.0))} : 0
+ * dst.w = 1.0
+ */
+static void
+ptn_lit(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_XW);
+
+ ptn_move_dest_masked(b, dest, nir_fmax(b, ptn_channel(b, src[0], X),
+ nir_imm_float(b, 0.0)), WRITEMASK_Y);
+
+ if (dest.write_mask & WRITEMASK_Z) {
+ nir_ssa_def *src0_y = ptn_channel(b, src[0], Y);
+ nir_ssa_def *wclamp = nir_fmax(b, nir_fmin(b, ptn_channel(b, src[0], W),
+ nir_imm_float(b, 128.0)),
+ nir_imm_float(b, -128.0));
+ nir_ssa_def *pow = nir_fpow(b, nir_fmax(b, src0_y, nir_imm_float(b, 0.0)),
+ wclamp);
+
+ nir_ssa_def *z;
+ if (b->shader->options->native_integers) {
+ z = nir_bcsel(b,
+ nir_fge(b, nir_imm_float(b, 0.0), ptn_channel(b, src[0], X)),
+ nir_imm_float(b, 0.0),
+ pow);
+ } else {
+ z = nir_fcsel(b,
+ nir_sge(b, nir_imm_float(b, 0.0), ptn_channel(b, src[0], X)),
+ nir_imm_float(b, 0.0),
+ pow);
+ }
+
+ ptn_move_dest_masked(b, dest, z, WRITEMASK_Z);
+ }
+}
+
+/* SCS - Sine Cosine
+ * dst.x = \cos{src.x}
+ * dst.y = \sin{src.x}
+ * dst.z = 0.0
+ * dst.w = 1.0
+ */
+static void
+ptn_scs(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ptn_move_dest_masked(b, dest, nir_fcos(b, ptn_channel(b, src[0], X)),
+ WRITEMASK_X);
+ ptn_move_dest_masked(b, dest, nir_fsin(b, ptn_channel(b, src[0], X)),
+ WRITEMASK_Y);
+ ptn_move_dest_masked(b, dest, nir_imm_float(b, 0.0), WRITEMASK_Z);
+ ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_W);
+}
+
+/**
+ * Emit SLT. For platforms with integers, prefer b2f(flt(...)).
+ */
+static void
+ptn_slt(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ if (b->shader->options->native_integers) {
+ ptn_move_dest(b, dest, nir_b2f(b, nir_flt(b, src[0], src[1])));
+ } else {
+ ptn_move_dest(b, dest, nir_slt(b, src[0], src[1]));
+ }
+}
+
+/**
+ * Emit SGE. For platforms with integers, prefer b2f(fge(...)).
+ */
+static void
+ptn_sge(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ if (b->shader->options->native_integers) {
+ ptn_move_dest(b, dest, nir_b2f(b, nir_fge(b, src[0], src[1])));
+ } else {
+ ptn_move_dest(b, dest, nir_sge(b, src[0], src[1]));
+ }
+}
+
+static void
+ptn_sle(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_ssa_def *commuted[] = { src[1], src[0] };
+ ptn_sge(b, dest, commuted);
+}
+
+static void
+ptn_sgt(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_ssa_def *commuted[] = { src[1], src[0] };
+ ptn_slt(b, dest, commuted);
+}
+
+/**
+ * Emit SEQ. For platforms with integers, prefer b2f(feq(...)).
+ */
+static void
+ptn_seq(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ if (b->shader->options->native_integers) {
+ ptn_move_dest(b, dest, nir_b2f(b, nir_feq(b, src[0], src[1])));
+ } else {
+ ptn_move_dest(b, dest, nir_seq(b, src[0], src[1]));
+ }
+}
+
+/**
+ * Emit SNE. For platforms with integers, prefer b2f(fne(...)).
+ */
+static void
+ptn_sne(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ if (b->shader->options->native_integers) {
+ ptn_move_dest(b, dest, nir_b2f(b, nir_fne(b, src[0], src[1])));
+ } else {
+ ptn_move_dest(b, dest, nir_sne(b, src[0], src[1]));
+ }
+}
+
+static void
+ptn_xpd(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ptn_move_dest_masked(b, dest,
+ nir_fsub(b,
+ nir_fmul(b,
+ ptn_swizzle(b, src[0], Y, Z, X, X),
+ ptn_swizzle(b, src[1], Z, X, Y, X)),
+ nir_fmul(b,
+ ptn_swizzle(b, src[1], Y, Z, X, X),
+ ptn_swizzle(b, src[0], Z, X, Y, X))),
+ WRITEMASK_XYZ);
+ ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_W);
+}
+
+static void
+ptn_dp2(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ptn_move_dest(b, dest, nir_fdot2(b, src[0], src[1]));
+}
+
+static void
+ptn_dp3(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ptn_move_dest(b, dest, nir_fdot3(b, src[0], src[1]));
+}
+
+static void
+ptn_dp4(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ptn_move_dest(b, dest, nir_fdot4(b, src[0], src[1]));
+}
+
+static void
+ptn_dph(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_ssa_def *dp3 = nir_fdot3(b, src[0], src[1]);
+ ptn_move_dest(b, dest, nir_fadd(b, dp3, ptn_channel(b, src[1], W)));
+}
+
+static void
+ptn_cmp(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ if (b->shader->options->native_integers) {
+ ptn_move_dest(b, dest, nir_bcsel(b,
+ nir_flt(b, src[0], nir_imm_float(b, 0.0)),
+ src[1], src[2]));
+ } else {
+ ptn_move_dest(b, dest, nir_fcsel(b,
+ nir_slt(b, src[0], nir_imm_float(b, 0.0)),
+ src[1], src[2]));
+ }
+}
+
+static void
+ptn_lrp(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ ptn_move_dest(b, dest, nir_flrp(b, src[2], src[1], src[0]));
+}
+
+static void
+ptn_kil(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_ssa_def *cmp = b->shader->options->native_integers ?
+ nir_bany4(b, nir_flt(b, src[0], nir_imm_float(b, 0.0))) :
+ nir_fany4(b, nir_slt(b, src[0], nir_imm_float(b, 0.0)));
+
+ nir_intrinsic_instr *discard =
+ nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard_if);
+ discard->src[0] = nir_src_for_ssa(cmp);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &discard->instr);
+}
+
+static void
+ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src,
+ struct prog_instruction *prog_inst)
+{
+ nir_tex_instr *instr;
+ nir_texop op;
+ unsigned num_srcs;
+
+ switch (prog_inst->Opcode) {
+ case OPCODE_TEX:
+ op = nir_texop_tex;
+ num_srcs = 1;
+ break;
+ case OPCODE_TXB:
+ op = nir_texop_txb;
+ num_srcs = 2;
+ break;
+ case OPCODE_TXD:
+ op = nir_texop_txd;
+ num_srcs = 3;
+ break;
+ case OPCODE_TXL:
+ op = nir_texop_txl;
+ num_srcs = 2;
+ break;
+ case OPCODE_TXP:
+ op = nir_texop_tex;
+ num_srcs = 2;
+ break;
+ case OPCODE_TXP_NV:
+ assert(!"not handled");
+ op = nir_texop_tex;
+ num_srcs = 2;
+ break;
+ default:
+ fprintf(stderr, "unknown tex op %d\n", prog_inst->Opcode);
+ abort();
+ }
+
+ if (prog_inst->TexShadow)
+ num_srcs++;
+
+ instr = nir_tex_instr_create(b->shader, num_srcs);
+ instr->op = op;
+ instr->dest_type = nir_type_float;
+ instr->is_shadow = prog_inst->TexShadow;
+ instr->sampler_index = prog_inst->TexSrcUnit;
+
+ switch (prog_inst->TexSrcTarget) {
+ case TEXTURE_1D_INDEX:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_1D;
+ break;
+ case TEXTURE_2D_INDEX:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_2D;
+ break;
+ case TEXTURE_3D_INDEX:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_3D;
+ break;
+ case TEXTURE_CUBE_INDEX:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_CUBE;
+ break;
+ case TEXTURE_RECT_INDEX:
+ instr->sampler_dim = GLSL_SAMPLER_DIM_RECT;
+ break;
+ default:
+ fprintf(stderr, "Unknown texture target %d\n", prog_inst->TexSrcTarget);
+ abort();
+ }
+
+ switch (instr->sampler_dim) {
+ case GLSL_SAMPLER_DIM_1D:
+ case GLSL_SAMPLER_DIM_BUF:
+ instr->coord_components = 1;
+ break;
+ case GLSL_SAMPLER_DIM_2D:
+ case GLSL_SAMPLER_DIM_RECT:
+ case GLSL_SAMPLER_DIM_EXTERNAL:
+ case GLSL_SAMPLER_DIM_MS:
+ instr->coord_components = 2;
+ break;
+ case GLSL_SAMPLER_DIM_3D:
+ case GLSL_SAMPLER_DIM_CUBE:
+ instr->coord_components = 3;
+ break;
+ }
+
+ unsigned src_number = 0;
+
+ instr->src[src_number].src =
+ nir_src_for_ssa(ptn_swizzle(b, src[0], X, Y, Z, W));
+ instr->src[src_number].src_type = nir_tex_src_coord;
+ src_number++;
+
+ if (prog_inst->Opcode == OPCODE_TXP) {
+ instr->src[src_number].src = nir_src_for_ssa(ptn_channel(b, src[0], W));
+ instr->src[src_number].src_type = nir_tex_src_projector;
+ src_number++;
+ }
+
+ if (prog_inst->Opcode == OPCODE_TXB) {
+ instr->src[src_number].src = nir_src_for_ssa(ptn_channel(b, src[0], W));
+ instr->src[src_number].src_type = nir_tex_src_bias;
+ src_number++;
+ }
+
+ if (prog_inst->Opcode == OPCODE_TXL) {
+ instr->src[src_number].src = nir_src_for_ssa(ptn_channel(b, src[0], W));
+ instr->src[src_number].src_type = nir_tex_src_lod;
+ src_number++;
+ }
+
+ if (instr->is_shadow) {
+ if (instr->coord_components < 3)
+ instr->src[src_number].src = nir_src_for_ssa(ptn_channel(b, src[0], Z));
+ else
+ instr->src[src_number].src = nir_src_for_ssa(ptn_channel(b, src[0], W));
+
+ instr->src[src_number].src_type = nir_tex_src_comparitor;
+ src_number++;
+ }
+
+ assert(src_number == num_srcs);
+
+ nir_ssa_dest_init(&instr->instr, &instr->dest, 4, NULL);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr);
+
+ /* Resolve the writemask on the texture op. */
+ ptn_move_dest(b, dest, &instr->dest.ssa);
+}
+
+static const nir_op op_trans[MAX_OPCODE] = {
+ [OPCODE_NOP] = 0,
+ [OPCODE_ABS] = nir_op_fabs,
+ [OPCODE_ADD] = nir_op_fadd,
+ [OPCODE_ARL] = 0,
+ [OPCODE_CMP] = 0,
+ [OPCODE_COS] = nir_op_fcos,
+ [OPCODE_DDX] = nir_op_fddx,
+ [OPCODE_DDY] = nir_op_fddy,
+ [OPCODE_DP2] = 0,
+ [OPCODE_DP3] = 0,
+ [OPCODE_DP4] = 0,
+ [OPCODE_DPH] = 0,
+ [OPCODE_DST] = 0,
+ [OPCODE_END] = 0,
+ [OPCODE_EX2] = nir_op_fexp2,
+ [OPCODE_EXP] = nir_op_fexp,
+ [OPCODE_FLR] = nir_op_ffloor,
+ [OPCODE_FRC] = nir_op_ffract,
+ [OPCODE_LG2] = nir_op_flog2,
+ [OPCODE_LIT] = 0,
+ [OPCODE_LOG] = 0,
+ [OPCODE_LRP] = 0,
+ [OPCODE_MAD] = nir_op_ffma,
+ [OPCODE_MAX] = nir_op_fmax,
+ [OPCODE_MIN] = nir_op_fmin,
+ [OPCODE_MOV] = nir_op_fmov,
+ [OPCODE_MUL] = nir_op_fmul,
+ [OPCODE_POW] = nir_op_fpow,
+ [OPCODE_RCP] = nir_op_frcp,
+
+ [OPCODE_RSQ] = nir_op_frsq,
+ [OPCODE_SCS] = 0,
+ [OPCODE_SEQ] = 0,
+ [OPCODE_SGE] = 0,
+ [OPCODE_SGT] = 0,
+ [OPCODE_SIN] = nir_op_fsin,
+ [OPCODE_SLE] = 0,
+ [OPCODE_SLT] = 0,
+ [OPCODE_SNE] = 0,
+ [OPCODE_SSG] = nir_op_fsign,
+ [OPCODE_SUB] = nir_op_fsub,
+ [OPCODE_SWZ] = 0,
+ [OPCODE_TEX] = 0,
+ [OPCODE_TRUNC] = nir_op_ftrunc,
+ [OPCODE_TXB] = 0,
+ [OPCODE_TXD] = 0,
+ [OPCODE_TXL] = 0,
+ [OPCODE_TXP] = 0,
+ [OPCODE_TXP_NV] = 0,
+ [OPCODE_XPD] = 0,
+};
+
+static void
+ptn_emit_instruction(struct ptn_compile *c, struct prog_instruction *prog_inst)
+{
+ nir_builder *b = &c->build;
+ unsigned i;
+ const unsigned op = prog_inst->Opcode;
+
+ if (op == OPCODE_END)
+ return;
+
+ nir_ssa_def *src[3];
+ for (i = 0; i < 3; i++) {
+ src[i] = ptn_get_src(c, &prog_inst->SrcReg[i]);
+ }
+ nir_alu_dest dest = ptn_get_dest(c, &prog_inst->DstReg);
+ if (c->error)
+ return;
+
+ switch (op) {
+ case OPCODE_RSQ:
+ ptn_move_dest(b, dest, nir_frsq(b, ptn_channel(b, src[0], X)));
+ break;
+
+ case OPCODE_RCP:
+ ptn_move_dest(b, dest, nir_frcp(b, ptn_channel(b, src[0], X)));
+ break;
+
+ case OPCODE_EX2:
+ ptn_move_dest(b, dest, nir_fexp2(b, ptn_channel(b, src[0], X)));
+ break;
+
+ case OPCODE_LG2:
+ ptn_move_dest(b, dest, nir_flog2(b, ptn_channel(b, src[0], X)));
+ break;
+
+ case OPCODE_POW:
+ ptn_move_dest(b, dest, nir_fpow(b,
+ ptn_channel(b, src[0], X),
+ ptn_channel(b, src[1], X)));
+ break;
+
+ case OPCODE_COS:
+ ptn_move_dest(b, dest, nir_fcos(b, ptn_channel(b, src[0], X)));
+ break;
+
+ case OPCODE_SIN:
+ ptn_move_dest(b, dest, nir_fsin(b, ptn_channel(b, src[0], X)));
+ break;
+
+ case OPCODE_ARL:
+ ptn_arl(b, dest, src);
+ break;
+
+ case OPCODE_EXP:
+ ptn_exp(b, dest, src);
+ break;
+
+ case OPCODE_LOG:
+ ptn_log(b, dest, src);
+ break;
+
+ case OPCODE_LRP:
+ ptn_lrp(b, dest, src);
+ break;
+
+ case OPCODE_DST:
+ ptn_dst(b, dest, src);
+ break;
+
+ case OPCODE_LIT:
+ ptn_lit(b, dest, src);
+ break;
+
+ case OPCODE_XPD:
+ ptn_xpd(b, dest, src);
+ break;
+
+ case OPCODE_DP2:
+ ptn_dp2(b, dest, src);
+ break;
+
+ case OPCODE_DP3:
+ ptn_dp3(b, dest, src);
+ break;
+
+ case OPCODE_DP4:
+ ptn_dp4(b, dest, src);
+ break;
+
+ case OPCODE_DPH:
+ ptn_dph(b, dest, src);
+ break;
+
+ case OPCODE_KIL:
+ ptn_kil(b, dest, src);
+ break;
+
+ case OPCODE_CMP:
+ ptn_cmp(b, dest, src);
+ break;
+
+ case OPCODE_SCS:
+ ptn_scs(b, dest, src);
+ break;
+
+ case OPCODE_SLT:
+ ptn_slt(b, dest, src);
+ break;
+
+ case OPCODE_SGT:
+ ptn_sgt(b, dest, src);
+ break;
+
+ case OPCODE_SLE:
+ ptn_sle(b, dest, src);
+ break;
+
+ case OPCODE_SGE:
+ ptn_sge(b, dest, src);
+ break;
+
+ case OPCODE_SEQ:
+ ptn_seq(b, dest, src);
+ break;
+
+ case OPCODE_SNE:
+ ptn_sne(b, dest, src);
+ break;
+
+ case OPCODE_TEX:
+ case OPCODE_TXB:
+ case OPCODE_TXD:
+ case OPCODE_TXL:
+ case OPCODE_TXP:
+ case OPCODE_TXP_NV:
+ ptn_tex(b, dest, src, prog_inst);
+ break;
+
+ case OPCODE_SWZ:
+ /* Extended swizzles were already handled in ptn_get_src(). */
+ ptn_alu(b, nir_op_fmov, dest, src);
+ break;
+
+ case OPCODE_NOP:
+ break;
+
+ default:
+ if (op_trans[op] != 0 || op == OPCODE_MOV) {
+ ptn_alu(b, op_trans[op], dest, src);
+ } else {
+ fprintf(stderr, "unknown opcode: %s\n", _mesa_opcode_string(op));
+ abort();
+ }
+ break;
+ }
+
+ if (prog_inst->SaturateMode) {
+ assert(prog_inst->SaturateMode == SATURATE_ZERO_ONE);
+ assert(!dest.dest.is_ssa);
+ ptn_move_dest(b, dest, nir_fsat(b, ptn_src_for_dest(c, &dest)));
+ }
+}
+
+/**
+ * Puts a NIR intrinsic to store of each PROGRAM_OUTPUT value to the output
+ * variables at the end of the shader.
+ *
+ * We don't generate these incrementally as the PROGRAM_OUTPUT values are
+ * written, because there's no output load intrinsic, which means we couldn't
+ * handle writemasks.
+ */
+static void
+ptn_add_output_stores(struct ptn_compile *c)
+{
+ nir_builder *b = &c->build;
+
+ foreach_list_typed(nir_variable, var, node, &b->shader->outputs) {
+ nir_intrinsic_instr *store =
+ nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
+ store->num_components = 4;
+ store->variables[0] =
+ nir_deref_var_create(store, c->output_vars[var->data.location]);
+ store->src[0].reg.reg = c->output_regs[var->data.location];
+ nir_instr_insert_after_cf_list(c->build.cf_node_list, &store->instr);
+ }
+}
+
+static void
+setup_registers_and_variables(struct ptn_compile *c)
+{
+ nir_builder *b = &c->build;
+ struct nir_shader *shader = b->shader;
+
+ /* Create input variables. */
+ const int num_inputs = _mesa_flsll(c->prog->InputsRead);
+ for (int i = 0; i < num_inputs; i++) {
+ if (!(c->prog->InputsRead & BITFIELD64_BIT(i)))
+ continue;
+ nir_variable *var = rzalloc(shader, nir_variable);
+ var->type = glsl_vec4_type();
+ var->data.read_only = true;
+ var->data.mode = nir_var_shader_in;
+ var->name = ralloc_asprintf(var, "in_%d", i);
+ var->data.location = i;
+ var->data.index = 0;
+
+ if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
+ struct gl_fragment_program *fp =
+ (struct gl_fragment_program *) c->prog;
+
+ var->data.interpolation = fp->InterpQualifier[i];
+
+ if (i == VARYING_SLOT_POS) {
+ var->data.origin_upper_left = fp->OriginUpperLeft;
+ var->data.pixel_center_integer = fp->PixelCenterInteger;
+ } else if (i == VARYING_SLOT_FOGC) {
+ /* fogcoord is defined as <f, 0.0, 0.0, 1.0>. Make the actual
+ * input variable a float, and create a local containing the
+ * full vec4 value.
+ */
+ var->type = glsl_float_type();
+
+ nir_intrinsic_instr *load_x =
+ nir_intrinsic_instr_create(shader, nir_intrinsic_load_var);
+ load_x->num_components = 1;
+ load_x->variables[0] = nir_deref_var_create(load_x, var);
+ nir_ssa_dest_init(&load_x->instr, &load_x->dest, 1, NULL);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &load_x->instr);
+
+ nir_ssa_def *f001 = nir_vec4(b, &load_x->dest.ssa, nir_imm_float(b, 0.0),
+ nir_imm_float(b, 0.0), nir_imm_float(b, 1.0));
+
+ nir_variable *fullvar = rzalloc(shader, nir_variable);
+ fullvar->type = glsl_vec4_type();
+ fullvar->data.mode = nir_var_local;
+ fullvar->name = "fogcoord_tmp";
+ exec_list_push_tail(&b->impl->locals, &fullvar->node);
+
+ nir_intrinsic_instr *store =
+ nir_intrinsic_instr_create(shader, nir_intrinsic_store_var);
+ store->num_components = 4;
+ store->variables[0] = nir_deref_var_create(store, fullvar);
+ store->src[0] = nir_src_for_ssa(f001);
+ nir_instr_insert_after_cf_list(b->cf_node_list, &store->instr);
+
+ /* Insert the real input into the list so the driver has real
+ * inputs, but set c->input_vars[i] to the temporary so we use
+ * the splatted value.
+ */
+ exec_list_push_tail(&shader->inputs, &var->node);
+ c->input_vars[i] = fullvar;
+ continue;
+ }
+ }
+
+ exec_list_push_tail(&shader->inputs, &var->node);
+ c->input_vars[i] = var;
+ }
+
+ /* Create output registers and variables. */
+ int max_outputs = _mesa_fls(c->prog->OutputsWritten);
+ c->output_regs = rzalloc_array(c, nir_register *, max_outputs);
+
+ for (int i = 0; i < max_outputs; i++) {
+ if (!(c->prog->OutputsWritten & BITFIELD64_BIT(i)))
+ continue;
+
+ /* Since we can't load from outputs in the IR, we make temporaries
+ * for the outputs and emit stores to the real outputs at the end of
+ * the shader.
+ */
+ nir_register *reg = nir_local_reg_create(b->impl);
+ reg->num_components = 4;
+
+ nir_variable *var = rzalloc(shader, nir_variable);
+ var->type = glsl_vec4_type();
+ var->data.mode = nir_var_shader_out;
+ var->name = ralloc_asprintf(var, "out_%d", i);
+
+ var->data.location = i;
+ var->data.index = 0;
+
+ c->output_regs[i] = reg;
+
+ exec_list_push_tail(&shader->outputs, &var->node);
+ c->output_vars[i] = var;
+ }
+
+ /* Create temporary registers. */
+ c->temp_regs = rzalloc_array(c, nir_register *, c->prog->NumTemporaries);
+
+ nir_register *reg;
+ for (int i = 0; i < c->prog->NumTemporaries; i++) {
+ reg = nir_local_reg_create(b->impl);
+ if (!reg) {
+ c->error = true;
+ return;
+ }
+ reg->num_components = 4;
+ c->temp_regs[i] = reg;
+ }
+
+ /* Create the address register (for ARB_vertex_program). */
+ reg = nir_local_reg_create(b->impl);
+ if (!reg) {
+ c->error = true;
+ return;
+ }
+ reg->num_components = 1;
+ c->addr_reg = reg;
+
+ /* Set the number of uniforms */
+ shader->num_uniforms = 4 * c->prog->Parameters->NumParameters;
+}
+
+struct nir_shader *
+prog_to_nir(const struct gl_program *prog, const nir_shader_compiler_options *options)
+{
+ struct ptn_compile *c;
+ struct nir_shader *s;
+
+ c = rzalloc(NULL, struct ptn_compile);
+ if (!c)
+ return NULL;
+ s = nir_shader_create(NULL, options);
+ if (!s)
+ goto fail;
+ c->prog = prog;
+
+ nir_function *func = nir_function_create(s, "main");
+ nir_function_overload *overload = nir_function_overload_create(func);
+ nir_function_impl *impl = nir_function_impl_create(overload);
+
+ c->build.shader = s;
+ c->build.impl = impl;
+ c->build.cf_node_list = &impl->body;
+
+ setup_registers_and_variables(c);
+ if (unlikely(c->error))
+ goto fail;
+
+ for (unsigned int i = 0; i < prog->NumInstructions; i++) {
+ ptn_emit_instruction(c, &prog->Instructions[i]);
+
+ if (unlikely(c->error))
+ break;
+ }
+
+ ptn_add_output_stores(c);
+
+fail:
+ if (c->error) {
+ ralloc_free(s);
+ s = NULL;
+ }
+ ralloc_free(c);
+ return s;
+}
diff --git a/mesalib/src/mesa/program/prog_to_nir.h b/mesalib/src/mesa/program/prog_to_nir.h
new file mode 100644
index 000000000..34e4cd104
--- /dev/null
+++ b/mesalib/src/mesa/program/prog_to_nir.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#pragma once
+#ifndef PROG_TO_NIR_H
+#define PROG_TO_NIR_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct nir_shader *prog_to_nir(const struct gl_program *prog,
+ const nir_shader_compiler_options *options);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/mesalib/src/mesa/program/program.c b/mesalib/src/mesa/program/program.c
index 3c214d5e3..4f28e2a3b 100644
--- a/mesalib/src/mesa/program/program.c
+++ b/mesalib/src/mesa/program/program.c
@@ -37,6 +37,7 @@
#include "prog_cache.h"
#include "prog_parameter.h"
#include "prog_instruction.h"
+#include "util/ralloc.h"
/**
@@ -380,6 +381,10 @@ _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
_mesa_free_parameter_list(prog->Parameters);
}
+ if (prog->nir) {
+ ralloc_free(prog->nir);
+ }
+
free(prog);
}
diff --git a/mesalib/src/mesa/state_tracker/st_atom.c b/mesalib/src/mesa/state_tracker/st_atom.c
index f0fe11ffa..428f2d9d7 100644
--- a/mesalib/src/mesa/state_tracker/st_atom.c
+++ b/mesalib/src/mesa/state_tracker/st_atom.c
@@ -183,7 +183,7 @@ void st_validate_state( struct st_context *st )
if (state->st == 0)
return;
- /*printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st);*/
+ /*printf("%s %x/%x\n", __func__, state->mesa, state->st);*/
#ifdef DEBUG
if (1) {
diff --git a/mesalib/src/mesa/state_tracker/st_atom_array.c b/mesalib/src/mesa/state_tracker/st_atom_array.c
index 9b52f9779..d4fb8b862 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_array.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_array.c
@@ -598,7 +598,7 @@ static void update_array(struct st_context *st)
const struct st_tracked_state st_update_array = {
"st_update_array", /* name */
{ /* dirty */
- 0, /* mesa */
+ _NEW_CURRENT_ATTRIB, /* mesa */
ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM, /* st */
},
update_array /* update */
diff --git a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
index 7984bf742..a54e0d9db 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
@@ -92,7 +92,7 @@ void st_upload_constants( struct st_context *st,
if (ST_DEBUG & DEBUG_CONSTANTS) {
debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
- __FUNCTION__, shader_type, params->NumParameters,
+ __func__, shader_type, params->NumParameters,
params->StateFlags);
_mesa_print_parameter_list(params);
}
diff --git a/mesalib/src/mesa/state_tracker/st_atom_shader.c b/mesalib/src/mesa/state_tracker/st_atom_shader.c
index 73768ed12..629f54f25 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_shader.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_shader.c
@@ -40,9 +40,8 @@
#include "program/program.h"
#include "pipe/p_context.h"
-
+#include "pipe/p_shader_tokens.h"
#include "util/u_simple_shaders.h"
-
#include "cso_cache/cso_context.h"
#include "st_context.h"
diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c
index dd81a6273..f10e9063a 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_clear.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c
@@ -247,7 +247,7 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
util_framebuffer_get_num_layers(&st->state.framebuffer);
/*
- printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__,
+ printf("%s %s%s%s %f,%f %f,%f\n", __func__,
color ? "color, " : "",
depth ? "depth, " : "",
stencil ? "stencil" : "",
diff --git a/mesalib/src/mesa/state_tracker/st_cb_program.c b/mesalib/src/mesa/state_tracker/st_cb_program.c
index aa301d830..c382d7d2c 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_program.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_program.c
@@ -41,6 +41,7 @@
#include "draw/draw_context.h"
#include "st_context.h"
+#include "st_debug.h"
#include "st_program.h"
#include "st_mesa_to_tgsi.h"
#include "st_cb_program.h"
@@ -214,6 +215,9 @@ st_program_string_notify( struct gl_context *ctx,
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
}
+ if (ST_DEBUG & DEBUG_PRECOMPILE)
+ st_precompile_shader_variant(st, prog);
+
/* XXX check if program is legal, within limits */
return GL_TRUE;
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c
index 5c520b44f..bdf236e82 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c
@@ -123,7 +123,7 @@ gl_target_to_pipe(GLenum target)
static struct gl_texture_image *
st_NewTextureImage(struct gl_context * ctx)
{
- DBG("%s\n", __FUNCTION__);
+ DBG("%s\n", __func__);
(void) ctx;
return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image);
}
@@ -144,7 +144,7 @@ st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
{
struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object);
- DBG("%s\n", __FUNCTION__);
+ DBG("%s\n", __func__);
_mesa_initialize_texture_object(ctx, &obj->base, name, target);
return &obj->base;
@@ -172,7 +172,7 @@ st_FreeTextureImageBuffer(struct gl_context *ctx,
{
struct st_texture_image *stImage = st_texture_image(texImage);
- DBG("%s\n", __FUNCTION__);
+ DBG("%s\n", __func__);
if (stImage->pt) {
pipe_resource_reference(&stImage->pt, NULL);
@@ -405,7 +405,7 @@ guess_and_alloc_texture(struct st_context *st,
GLuint ptWidth, ptHeight, ptDepth, ptLayers;
enum pipe_format fmt;
- DBG("%s\n", __FUNCTION__);
+ DBG("%s\n", __func__);
assert(!stObj->pt);
@@ -473,7 +473,7 @@ guess_and_alloc_texture(struct st_context *st,
stObj->lastLevel = lastLevel;
- DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL));
+ DBG("%s returning %d\n", __func__, (stObj->pt != NULL));
return stObj->pt != NULL;
}
@@ -496,7 +496,7 @@ st_AllocTextureImageBuffer(struct gl_context *ctx,
GLuint height = texImage->Height;
GLuint depth = texImage->Depth;
- DBG("%s\n", __FUNCTION__);
+ DBG("%s\n", __func__);
assert(!stImage->pt); /* xxx this might be wrong */
@@ -738,6 +738,11 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims,
if (gl_target == GL_TEXTURE_CUBE_MAP) {
gl_target = GL_TEXTURE_2D;
}
+ /* TexSubImage can specify subsets of cube map array faces
+ * so we need to upload via 2D array instead */
+ if (gl_target == GL_TEXTURE_CUBE_MAP_ARRAY) {
+ gl_target = GL_TEXTURE_2D_ARRAY;
+ }
/* Initialize the source texture description. */
memset(&src_templ, 0, sizeof(src_templ));
@@ -1148,7 +1153,7 @@ st_GetTexImage(struct gl_context * ctx,
}
if (ST_DEBUG & DEBUG_FALLBACK)
- debug_printf("%s: fallback format translation\n", __FUNCTION__);
+ debug_printf("%s: fallback format translation\n", __func__);
dstMesaFormat = _mesa_format_from_format_and_type(format, type);
dstStride = _mesa_image_row_stride(&ctx->Pack, width, format, type);
@@ -1234,7 +1239,7 @@ fallback_copy_texsubimage(struct gl_context *ctx,
struct pipe_transfer *transfer;
if (ST_DEBUG & DEBUG_FALLBACK)
- debug_printf("%s: fallback processing\n", __FUNCTION__);
+ debug_printf("%s: fallback processing\n", __func__);
if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
srcY = strb->Base.Height - srcY - height;
@@ -1389,7 +1394,7 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
if (!strb || !strb->surface || !stImage->pt) {
- debug_printf("%s: null strb or stImage\n", __FUNCTION__);
+ debug_printf("%s: null strb or stImage\n", __func__);
return;
}
diff --git a/mesalib/src/mesa/state_tracker/st_debug.c b/mesalib/src/mesa/state_tracker/st_debug.c
index de3e3a9cd..50891c112 100644
--- a/mesalib/src/mesa/state_tracker/st_debug.c
+++ b/mesalib/src/mesa/state_tracker/st_debug.c
@@ -56,6 +56,7 @@ static const struct debug_named_value st_debug_flags[] = {
{ "draw", DEBUG_DRAW, NULL },
{ "buffer", DEBUG_BUFFER, NULL },
{ "wf", DEBUG_WIREFRAME, NULL },
+ { "precompile", DEBUG_PRECOMPILE, NULL },
DEBUG_NAMED_VALUE_END
};
diff --git a/mesalib/src/mesa/state_tracker/st_debug.h b/mesalib/src/mesa/state_tracker/st_debug.h
index cc8197836..288eccf9f 100644
--- a/mesalib/src/mesa/state_tracker/st_debug.h
+++ b/mesalib/src/mesa/state_tracker/st_debug.h
@@ -47,6 +47,7 @@ st_print_current(void);
#define DEBUG_DRAW 0x100
#define DEBUG_BUFFER 0x200
#define DEBUG_WIREFRAME 0x400
+#define DEBUG_PRECOMPILE 0x800
#ifdef DEBUG
extern int ST_DEBUG;
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index efee4b258..93671ba9c 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -30,40 +30,25 @@
* Translate GLSL IR to TGSI.
*/
-#include <stdio.h>
-#include "main/compiler.h"
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_expression_flattening.h"
-#include "glsl_types.h"
+#include "st_glsl_to_tgsi.h"
+
#include "glsl_parser_extras.h"
-#include "../glsl/program.h"
#include "ir_optimization.h"
-#include "ast.h"
-#include "main/mtypes.h"
+#include "main/errors.h"
#include "main/shaderobj.h"
#include "main/uniforms.h"
#include "main/shaderapi.h"
-#include "program/hash_table.h"
#include "program/prog_instruction.h"
-#include "program/prog_optimize.h"
-#include "program/prog_print.h"
-#include "program/program.h"
-#include "program/prog_parameter.h"
#include "program/sampler.h"
-#include "pipe/p_compiler.h"
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
-#include "pipe/p_shader_tokens.h"
-#include "pipe/p_state.h"
-#include "util/u_math.h"
#include "tgsi/tgsi_ureg.h"
#include "tgsi/tgsi_info.h"
-#include "st_context.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
#include "st_program.h"
-#include "st_glsl_to_tgsi.h"
#include "st_mesa_to_tgsi.h"
@@ -328,6 +313,7 @@ public:
int num_address_regs;
int samplers_used;
bool indirect_addr_consts;
+ int wpos_transform_const;
int glsl_version;
bool native_integers;
@@ -441,9 +427,6 @@ public:
void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0);
- void emit_scs(ir_instruction *ir, unsigned op,
- st_dst_reg dst, const st_src_reg &src);
-
bool try_emit_mad(ir_expression *ir,
int mul_operand);
bool try_emit_mad_for_and_not(ir_expression *ir,
@@ -966,101 +949,6 @@ glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
emit(NULL, op, dst, src0);
}
-/**
- * Emit an TGSI_OPCODE_SCS instruction
- *
- * The \c SCS opcode functions a bit differently than the other TGSI opcodes.
- * Instead of splatting its result across all four components of the
- * destination, it writes one value to the \c x component and another value to
- * the \c y component.
- *
- * \param ir IR instruction being processed
- * \param op Either \c TGSI_OPCODE_SIN or \c TGSI_OPCODE_COS depending
- * on which value is desired.
- * \param dst Destination register
- * \param src Source register
- */
-void
-glsl_to_tgsi_visitor::emit_scs(ir_instruction *ir, unsigned op,
- st_dst_reg dst,
- const st_src_reg &src)
-{
- /* Vertex programs cannot use the SCS opcode.
- */
- if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) {
- emit_scalar(ir, op, dst, src);
- return;
- }
-
- const unsigned component = (op == TGSI_OPCODE_SIN) ? 0 : 1;
- const unsigned scs_mask = (1U << component);
- int done_mask = ~dst.writemask;
- st_src_reg tmp;
-
- assert(op == TGSI_OPCODE_SIN || op == TGSI_OPCODE_COS);
-
- /* If there are compnents in the destination that differ from the component
- * that will be written by the SCS instrution, we'll need a temporary.
- */
- if (scs_mask != unsigned(dst.writemask)) {
- tmp = get_temp(glsl_type::vec4_type);
- }
-
- for (unsigned i = 0; i < 4; i++) {
- unsigned this_mask = (1U << i);
- st_src_reg src0 = src;
-
- if ((done_mask & this_mask) != 0)
- continue;
-
- /* The source swizzle specified which component of the source generates
- * sine / cosine for the current component in the destination. The SCS
- * instruction requires that this value be swizzle to the X component.
- * Replace the current swizzle with a swizzle that puts the source in
- * the X component.
- */
- unsigned src0_swiz = GET_SWZ(src.swizzle, i);
-
- src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
- src0_swiz, src0_swiz);
- for (unsigned j = i + 1; j < 4; j++) {
- /* If there is another enabled component in the destination that is
- * derived from the same inputs, generate its value on this pass as
- * well.
- */
- if (!(done_mask & (1 << j)) &&
- GET_SWZ(src0.swizzle, j) == src0_swiz) {
- this_mask |= (1 << j);
- }
- }
-
- if (this_mask != scs_mask) {
- glsl_to_tgsi_instruction *inst;
- st_dst_reg tmp_dst = st_dst_reg(tmp);
-
- /* Emit the SCS instruction.
- */
- inst = emit(ir, TGSI_OPCODE_SCS, tmp_dst, src0);
- inst->dst[0].writemask = scs_mask;
-
- /* Move the result of the SCS instruction to the desired location in
- * the destination.
- */
- tmp.swizzle = MAKE_SWIZZLE4(component, component,
- component, component);
- inst = emit(ir, TGSI_OPCODE_SCS, dst, tmp);
- inst->dst[0].writemask = this_mask;
- } else {
- /* Emit the SCS instruction to write directly to the destination.
- */
- glsl_to_tgsi_instruction *inst = emit(ir, TGSI_OPCODE_SCS, dst, src0);
- inst->dst[0].writemask = scs_mask;
- }
-
- done_mask |= this_mask;
- }
-}
-
int
glsl_to_tgsi_visitor::add_constant(gl_register_file file,
gl_constant_value values[8], int size, int datatype,
@@ -1611,12 +1499,6 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
case ir_unop_cos:
emit_scalar(ir, TGSI_OPCODE_COS, result_dst, op[0]);
break;
- case ir_unop_sin_reduced:
- emit_scs(ir, TGSI_OPCODE_SIN, result_dst, op[0]);
- break;
- case ir_unop_cos_reduced:
- emit_scs(ir, TGSI_OPCODE_COS, result_dst, op[0]);
- break;
case ir_unop_saturate: {
glsl_to_tgsi_instruction *inst;
inst = emit(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
@@ -3134,7 +3016,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
break;
case ir_query_levels:
opcode = TGSI_OPCODE_TXQ;
- lod_info = st_src_reg(PROGRAM_IMMEDIATE, 0, GLSL_TYPE_INT);
+ lod_info = undef_src;
levels_src = get_temp(ir->type);
break;
case ir_txf:
@@ -3456,6 +3338,7 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
num_address_regs = 0;
samplers_used = 0;
indirect_addr_consts = false;
+ wpos_transform_const = -1;
glsl_version = 0;
native_integers = false;
mem_ctx = ralloc_context(NULL);
@@ -3465,6 +3348,7 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
shader = NULL;
options = NULL;
have_sqrt = false;
+ have_fma = false;
}
glsl_to_tgsi_visitor::~glsl_to_tgsi_visitor()
@@ -3937,6 +3821,7 @@ glsl_to_tgsi_visitor::copy_propagate(void)
inst->dst[0].index == inst->src[0].index) &&
!inst->dst[0].reladdr &&
!inst->saturate &&
+ inst->src[0].file != PROGRAM_ARRAY &&
!inst->src[0].reladdr &&
!inst->src[0].reladdr2 &&
!inst->src[0].negate) {
@@ -4464,7 +4349,9 @@ struct st_translate {
struct ureg_dst arrays[MAX_ARRAYS];
struct ureg_src *constants;
+ int num_constants;
struct ureg_src *immediates;
+ int num_immediates;
struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS];
struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS];
struct ureg_dst address[3];
@@ -4666,7 +4553,7 @@ src_register(struct st_translate *t, const st_src_reg *reg)
{
switch(reg->file) {
case PROGRAM_UNDEFINED:
- return ureg_src_undef();
+ return ureg_imm4f(t->ureg, 0, 0, 0, 0);
case PROGRAM_TEMPORARY:
case PROGRAM_ARRAY:
@@ -4674,17 +4561,18 @@ src_register(struct st_translate *t, const st_src_reg *reg)
case PROGRAM_UNIFORM:
assert(reg->index >= 0);
- return t->constants[reg->index];
+ return reg->index < t->num_constants ?
+ t->constants[reg->index] : ureg_imm4f(t->ureg, 0, 0, 0, 0);
case PROGRAM_STATE_VAR:
case PROGRAM_CONSTANT: /* ie, immediate */
if (reg->has_index2)
return ureg_src_register(TGSI_FILE_CONSTANT, reg->index);
- else if (reg->index < 0)
- return ureg_DECL_constant(t->ureg, 0);
else
- return t->constants[reg->index];
+ return reg->index >= 0 && reg->index < t->num_constants ?
+ t->constants[reg->index] : ureg_imm4f(t->ureg, 0, 0, 0, 0);
case PROGRAM_IMMEDIATE:
+ assert(reg->index >= 0 && reg->index < t->num_immediates);
return t->immediates[reg->index];
case PROGRAM_INPUT:
@@ -4805,6 +4693,7 @@ translate_tex_offset(struct st_translate *t,
switch (in_offset->file) {
case PROGRAM_IMMEDIATE:
+ assert(in_offset->index >= 0 && in_offset->index < t->num_immediates);
imm_src = t->immediates[in_offset->index];
offset.File = imm_src.File;
@@ -4867,10 +4756,8 @@ compile_tgsi_instruction(struct st_translate *t,
inst->saturate,
clamp_dst_color_output);
- for (i = 0; i < num_src; i++) {
- assert(inst->src[i].file != PROGRAM_UNDEFINED);
+ for (i = 0; i < num_src; i++)
src[i] = translate_src(t, &inst->src[i]);
- }
switch(inst->op) {
case TGSI_OPCODE_BGNLOOP:
@@ -4939,28 +4826,19 @@ compile_tgsi_instruction(struct st_translate *t,
*/
static void
emit_wpos_adjustment( struct st_translate *t,
- const struct gl_program *program,
+ int wpos_transform_const,
boolean invert,
GLfloat adjX, GLfloat adjY[2])
{
struct ureg_program *ureg = t->ureg;
+ assert(wpos_transform_const >= 0);
+
/* Fragment program uses fragment position input.
* Need to replace instances of INPUT[WPOS] with temp T
- * where T = INPUT[WPOS] by y is inverted.
+ * where T = INPUT[WPOS] is inverted by Y.
*/
- static const gl_state_index wposTransformState[STATE_LENGTH]
- = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM,
- (gl_state_index)0, (gl_state_index)0, (gl_state_index)0 };
-
- /* XXX: note we are modifying the incoming shader here! Need to
- * do this before emitting the constant decls below, or this
- * will be missed:
- */
- unsigned wposTransConst = _mesa_add_state_reference(program->Parameters,
- wposTransformState);
-
- struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst );
+ struct ureg_src wpostrans = ureg_DECL_constant(ureg, wpos_transform_const);
struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg );
struct ureg_src wpos_input = t->inputs[t->inputMapping[VARYING_SLOT_POS]];
@@ -5024,7 +4902,8 @@ static void
emit_wpos(struct st_context *st,
struct st_translate *t,
const struct gl_program *program,
- struct ureg_program *ureg)
+ struct ureg_program *ureg,
+ int wpos_transform_const)
{
const struct gl_fragment_program *fp =
(const struct gl_fragment_program *) program;
@@ -5121,7 +5000,7 @@ emit_wpos(struct st_context *st,
/* we invert after adjustment so that we avoid the MOV to temporary,
* and reuse the adjustment ADD instead */
- emit_wpos_adjustment(t, program, invert, adjX, adjY);
+ emit_wpos_adjustment(t, wpos_transform_const, invert, adjX, adjY);
}
/**
@@ -5238,15 +5117,6 @@ st_translate_program(
t->outputMapping = outputMapping;
t->ureg = ureg;
- if (program->shader_program) {
- for (i = 0; i < program->shader_program->NumUserUniformStorage; i++) {
- struct gl_uniform_storage *const storage =
- &program->shader_program->UniformStorage[i];
-
- _mesa_uniform_detach_all_driver_storage(storage);
- }
- }
-
/*
* Declare input attributes.
*/
@@ -5260,10 +5130,9 @@ st_translate_program(
}
if (proginfo->InputsRead & VARYING_BIT_POS) {
- /* Must do this after setting up t->inputs, and before
- * emitting constant references, below:
- */
- emit_wpos(st_context(ctx), t, proginfo, ureg);
+ /* Must do this after setting up t->inputs. */
+ emit_wpos(st_context(ctx), t, proginfo, ureg,
+ program->wpos_transform_const);
}
if (proginfo->InputsRead & VARYING_BIT_FACE)
@@ -5400,6 +5269,7 @@ st_translate_program(
ret = PIPE_ERROR_OUT_OF_MEMORY;
goto out;
}
+ t->num_constants = proginfo->Parameters->NumParameters;
for (i = 0; i < proginfo->Parameters->NumParameters; i++) {
switch (proginfo->Parameters->Parameters[i].Type) {
@@ -5451,6 +5321,8 @@ st_translate_program(
ret = PIPE_ERROR_OUT_OF_MEMORY;
goto out;
}
+ t->num_immediates = program->num_immediates;
+
i = 0;
foreach_in_list(immediate_storage, imm, &program->immediates) {
assert(i < program->num_immediates);
@@ -5479,33 +5351,21 @@ st_translate_program(
t->insn[t->labels[i].branch_target]);
}
- if (program->shader_program) {
- /* This has to be done last. Any operation the can cause
- * prog->ParameterValues to get reallocated (e.g., anything that adds a
- * program constant) has to happen before creating this linkage.
- */
- for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
- if (program->shader_program->_LinkedShaders[i] == NULL)
- continue;
-
- _mesa_associate_uniform_storage(ctx, program->shader_program,
- program->shader_program->_LinkedShaders[i]->Program->Parameters);
- }
- }
-
out:
if (t) {
free(t->temps);
free(t->insn);
free(t->labels);
free(t->constants);
+ t->num_constants = 0;
free(t->immediates);
+ t->num_immediates = 0;
if (t->error) {
- debug_printf("%s: translate error flag set\n", __FUNCTION__);
+ debug_printf("%s: translate error flag set\n", __func__);
}
- free(t);
+ FREE(t);
}
return ret;
@@ -5634,14 +5494,12 @@ get_mesa_program(struct gl_context *ctx,
v->emit(NULL, TGSI_OPCODE_END);
if (ctx->_Shader->Flags & GLSL_DUMP) {
- printf("\n");
- printf("GLSL IR for linked %s program %d:\n",
+ _mesa_log("\n");
+ _mesa_log("GLSL IR for linked %s program %d:\n",
_mesa_shader_stage_to_string(shader->Stage),
shader_program->Name);
- _mesa_print_ir(stdout, shader->ir, NULL);
- printf("\n");
- printf("\n");
- fflush(stdout);
+ _mesa_print_ir(_mesa_get_log_file(), shader->ir, NULL);
+ _mesa_log("\n\n");
}
prog->Instructions = NULL;
@@ -5650,6 +5508,17 @@ get_mesa_program(struct gl_context *ctx,
do_set_program_inouts(shader->ir, prog, shader->Stage);
count_resources(v, prog);
+ /* This must be done before the uniform storage is associated. */
+ if (shader->Type == GL_FRAGMENT_SHADER &&
+ prog->InputsRead & VARYING_BIT_POS){
+ static const gl_state_index wposTransformState[STATE_LENGTH] = {
+ STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM
+ };
+
+ v->wpos_transform_const = _mesa_add_state_reference(prog->Parameters,
+ wposTransformState);
+ }
+
_mesa_reference_program(ctx, &shader->Program, prog);
/* This has to be done last. Any operation the can cause
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h
index 5ed640747..2cb80bcf9 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h
@@ -22,17 +22,18 @@
* DEALINGS IN THE SOFTWARE.
*/
+#include "pipe/p_defines.h"
+#include "main/mtypes.h"
+
#ifdef __cplusplus
extern "C" {
#endif
-#include "main/glheader.h"
-#include "tgsi/tgsi_ureg.h"
-
struct gl_context;
struct gl_shader;
struct gl_shader_program;
struct glsl_to_tgsi_visitor;
+struct ureg_program;
enum pipe_error st_translate_program(
struct gl_context *ctx,
diff --git a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 2f1016110..98d525c86 100644
--- a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -1249,7 +1249,7 @@ out:
free(t->constants);
if (t->error) {
- debug_printf("%s: translate error flag set\n", __FUNCTION__);
+ debug_printf("%s: translate error flag set\n", __func__);
}
return ret;
diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c
index 4cfd817ce..d93b3c7bc 100644
--- a/mesalib/src/mesa/state_tracker/st_program.c
+++ b/mesalib/src/mesa/state_tracker/st_program.c
@@ -185,9 +185,6 @@ st_prepare_vertex_program(struct gl_context *ctx,
if (stvp->Base.IsPositionInvariant)
_mesa_insert_mvp_code(ctx, &stvp->Base);
- if (!stvp->glsl_to_tgsi)
- assert(stvp->Base.Base.NumInstructions > 1);
-
/*
* Determine number of inputs, the mappings between VERT_ATTRIB_x
* and TGSI generic input indexes, plus input attrib semantic info.
@@ -403,7 +400,7 @@ st_translate_vertex_program(struct st_context *st,
return vpv;
fail:
- debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__);
+ debug_printf("%s: failed to translate Mesa program:\n", __func__);
_mesa_print_program(&stvp->Base.Base);
debug_assert(0);
@@ -1318,3 +1315,47 @@ st_print_current_vertex_program(void)
}
}
}
+
+
+/**
+ * Compile one shader variant.
+ */
+void
+st_precompile_shader_variant(struct st_context *st,
+ struct gl_program *prog)
+{
+ switch (prog->Target) {
+ case GL_VERTEX_PROGRAM_ARB: {
+ struct st_vertex_program *p = (struct st_vertex_program *)prog;
+ struct st_vp_variant_key key;
+
+ memset(&key, 0, sizeof(key));
+ key.st = st;
+ st_get_vp_variant(st, p, &key);
+ break;
+ }
+
+ case GL_GEOMETRY_PROGRAM_NV: {
+ struct st_geometry_program *p = (struct st_geometry_program *)prog;
+ struct st_gp_variant_key key;
+
+ memset(&key, 0, sizeof(key));
+ key.st = st;
+ st_get_gp_variant(st, p, &key);
+ break;
+ }
+
+ case GL_FRAGMENT_PROGRAM_ARB: {
+ struct st_fragment_program *p = (struct st_fragment_program *)prog;
+ struct st_fp_variant_key key;
+
+ memset(&key, 0, sizeof(key));
+ key.st = st;
+ st_get_fp_variant(st, p, &key);
+ break;
+ }
+
+ default:
+ assert(0);
+ }
+}
diff --git a/mesalib/src/mesa/state_tracker/st_program.h b/mesalib/src/mesa/state_tracker/st_program.h
index 451d7bb6a..b2c86faec 100644
--- a/mesalib/src/mesa/state_tracker/st_program.h
+++ b/mesalib/src/mesa/state_tracker/st_program.h
@@ -329,6 +329,9 @@ st_destroy_program_variants(struct st_context *st);
extern void
st_print_current_vertex_program(void);
+extern void
+st_precompile_shader_variant(struct st_context *st,
+ struct gl_program *prog);
#ifdef __cplusplus
}
diff --git a/mesalib/src/mesa/state_tracker/st_texture.c b/mesalib/src/mesa/state_tracker/st_texture.c
index ca7c83c21..6beb21e33 100644
--- a/mesalib/src/mesa/state_tracker/st_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_texture.c
@@ -74,7 +74,7 @@ st_texture_create(struct st_context *st,
if (target == PIPE_TEXTURE_CUBE)
assert(layers == 6);
- DBG("%s target %d format %s last_level %d\n", __FUNCTION__,
+ DBG("%s target %d format %s last_level %d\n", __func__,
(int) target, util_format_name(format), last_level);
assert(format);
@@ -177,7 +177,7 @@ st_gl_texture_dims_to_pipe_dims(GLenum texture,
*widthOut = widthIn;
*heightOut = heightIn;
*depthOut = 1;
- *layersOut = depthIn;
+ *layersOut = util_align_npot(depthIn, 6);
break;
default:
assert(0 && "Unexpected texture in st_gl_texture_dims_to_pipe_dims()");
@@ -250,7 +250,7 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
GLuint level;
void *map;
- DBG("%s \n", __FUNCTION__);
+ DBG("%s \n", __func__);
if (!stImage->pt)
return NULL;
@@ -304,7 +304,7 @@ st_texture_image_unmap(struct st_context *st,
slice += stObj->base.MinLayer;
transfer = &stImage->transfer[slice + stImage->base.Face].transfer;
- DBG("%s\n", __FUNCTION__);
+ DBG("%s\n", __func__);
pipe_transfer_unmap(pipe, *transfer);
*transfer = NULL;
diff --git a/mesalib/src/mesa/swrast/s_aatriangle.c b/mesalib/src/mesa/swrast/s_aatriangle.c
index 1d076cc7d..b51098704 100644
--- a/mesalib/src/mesa/swrast/s_aatriangle.c
+++ b/mesalib/src/mesa/swrast/s_aatriangle.c
@@ -30,7 +30,6 @@
#include "main/glheader.h"
#include "main/context.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/state.h"
diff --git a/mesalib/src/mesa/swrast/s_alpha.c b/mesalib/src/mesa/swrast/s_alpha.c
index b1a7ff132..841642fa9 100644
--- a/mesalib/src/mesa/swrast/s_alpha.c
+++ b/mesalib/src/mesa/swrast/s_alpha.c
@@ -29,7 +29,6 @@
#include "main/glheader.h"
#include "main/context.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "s_alpha.h"
diff --git a/mesalib/src/mesa/swrast/s_atifragshader.c b/mesalib/src/mesa/swrast/s_atifragshader.c
index 0bf03771f..9e029db25 100644
--- a/mesalib/src/mesa/swrast/s_atifragshader.c
+++ b/mesalib/src/mesa/swrast/s_atifragshader.c
@@ -20,7 +20,6 @@
*/
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "main/atifragshader.h"
#include "main/samplerobj.h"
diff --git a/mesalib/src/mesa/swrast/s_context.c b/mesalib/src/mesa/swrast/s_context.c
index ecde292e3..af24207e5 100644
--- a/mesalib/src/mesa/swrast/s_context.c
+++ b/mesalib/src/mesa/swrast/s_context.c
@@ -27,7 +27,6 @@
#include "main/imports.h"
#include "main/bufferobj.h"
-#include "main/colormac.h"
#include "main/mtypes.h"
#include "main/samplerobj.h"
#include "main/teximage.h"
diff --git a/mesalib/src/mesa/swrast/s_copypix.c b/mesalib/src/mesa/swrast/s_copypix.c
index 17140ad2d..68c83e44e 100644
--- a/mesalib/src/mesa/swrast/s_copypix.c
+++ b/mesalib/src/mesa/swrast/s_copypix.c
@@ -25,7 +25,6 @@
#include "main/glheader.h"
#include "main/context.h"
-#include "main/colormac.h"
#include "main/condrender.h"
#include "main/macros.h"
#include "main/pixeltransfer.h"
diff --git a/mesalib/src/mesa/swrast/s_feedback.c b/mesalib/src/mesa/swrast/s_feedback.c
index f25b89735..71f48ce92 100644
--- a/mesalib/src/mesa/swrast/s_feedback.c
+++ b/mesalib/src/mesa/swrast/s_feedback.c
@@ -23,7 +23,6 @@
*/
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/feedback.h"
#include "main/macros.h"
diff --git a/mesalib/src/mesa/swrast/s_fog.c b/mesalib/src/mesa/swrast/s_fog.c
index e270b7e24..8b0bdf8fa 100644
--- a/mesalib/src/mesa/swrast/s_fog.c
+++ b/mesalib/src/mesa/swrast/s_fog.c
@@ -25,7 +25,6 @@
#include "c99_math.h"
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "s_context.h"
diff --git a/mesalib/src/mesa/swrast/s_fragprog.c b/mesalib/src/mesa/swrast/s_fragprog.c
index 12bcda311..175915a5a 100644
--- a/mesalib/src/mesa/swrast/s_fragprog.c
+++ b/mesalib/src/mesa/swrast/s_fragprog.c
@@ -23,7 +23,7 @@
*/
#include "main/glheader.h"
-#include "main/colormac.h"
+#include "main/macros.h"
#include "main/samplerobj.h"
#include "main/teximage.h"
#include "program/prog_instruction.h"
diff --git a/mesalib/src/mesa/swrast/s_lines.c b/mesalib/src/mesa/swrast/s_lines.c
index 3e626b9e0..58bd2fc72 100644
--- a/mesalib/src/mesa/swrast/s_lines.c
+++ b/mesalib/src/mesa/swrast/s_lines.c
@@ -25,7 +25,6 @@
#include "main/glheader.h"
#include "main/context.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "s_aaline.h"
#include "s_context.h"
diff --git a/mesalib/src/mesa/swrast/s_linetemp.h b/mesalib/src/mesa/swrast/s_linetemp.h
index 352c88428..035a1e640 100644
--- a/mesalib/src/mesa/swrast/s_linetemp.h
+++ b/mesalib/src/mesa/swrast/s_linetemp.h
@@ -106,7 +106,7 @@ NAME( struct gl_context *ctx, const SWvertex *vert0, const SWvertex *vert1 )
}
/*
- printf("%s():\n", __FUNCTION__);
+ printf("%s():\n", __func__);
printf(" (%f, %f, %f) -> (%f, %f, %f)\n",
vert0->attrib[VARYING_SLOT_POS][0],
vert0->attrib[VARYING_SLOT_POS][1],
@@ -154,7 +154,7 @@ NAME( struct gl_context *ctx, const SWvertex *vert0, const SWvertex *vert1 )
return;
/*
- printf("%s %d,%d %g %g %g %g %g %g %g %g\n", __FUNCTION__, dx, dy,
+ printf("%s %d,%d %g %g %g %g %g %g %g %g\n", __func__, dx, dy,
vert0->attrib[VARYING_SLOT_COL1][0],
vert0->attrib[VARYING_SLOT_COL1][1],
vert0->attrib[VARYING_SLOT_COL1][2],
diff --git a/mesalib/src/mesa/swrast/s_points.c b/mesalib/src/mesa/swrast/s_points.c
index 8180483ba..2212c95fa 100644
--- a/mesalib/src/mesa/swrast/s_points.c
+++ b/mesalib/src/mesa/swrast/s_points.c
@@ -24,7 +24,6 @@
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "s_context.h"
#include "s_feedback.h"
diff --git a/mesalib/src/mesa/swrast/s_span.c b/mesalib/src/mesa/swrast/s_span.c
index e304b6b5a..3db10e163 100644
--- a/mesalib/src/mesa/swrast/s_span.c
+++ b/mesalib/src/mesa/swrast/s_span.c
@@ -33,7 +33,6 @@
#include "c99_math.h"
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/format_pack.h"
#include "main/format_unpack.h"
#include "main/macros.h"
@@ -1144,7 +1143,7 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
struct gl_framebuffer *fb = ctx->DrawBuffer;
/*
- printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__,
+ printf("%s() interp 0x%x array 0x%x\n", __func__,
span->interpMask, span->arrayMask);
*/
diff --git a/mesalib/src/mesa/swrast/s_texcombine.c b/mesalib/src/mesa/swrast/s_texcombine.c
index 58ff16465..0adb8e5ba 100644
--- a/mesalib/src/mesa/swrast/s_texcombine.c
+++ b/mesalib/src/mesa/swrast/s_texcombine.c
@@ -26,8 +26,8 @@
#include "main/glheader.h"
#include "main/context.h"
-#include "main/colormac.h"
#include "main/imports.h"
+#include "main/macros.h"
#include "main/pixeltransfer.h"
#include "main/samplerobj.h"
#include "program/prog_instruction.h"
diff --git a/mesalib/src/mesa/swrast/s_texfetch.c b/mesalib/src/mesa/swrast/s_texfetch.c
index 3c4ee15ba..1fe21c0b4 100644
--- a/mesalib/src/mesa/swrast/s_texfetch.c
+++ b/mesalib/src/mesa/swrast/s_texfetch.c
@@ -33,7 +33,6 @@
*/
-#include "main/colormac.h"
#include "main/macros.h"
#include "main/texcompress.h"
#include "main/texcompress_fxt1.h"
diff --git a/mesalib/src/mesa/swrast/s_texfilter.c b/mesalib/src/mesa/swrast/s_texfilter.c
index 3ade99519..abc1727cf 100644
--- a/mesalib/src/mesa/swrast/s_texfilter.c
+++ b/mesalib/src/mesa/swrast/s_texfilter.c
@@ -26,8 +26,8 @@
#include "c99_math.h"
#include "main/glheader.h"
#include "main/context.h"
-#include "main/colormac.h"
#include "main/imports.h"
+#include "main/macros.h"
#include "main/samplerobj.h"
#include "main/teximage.h"
#include "main/texobj.h"
diff --git a/mesalib/src/mesa/swrast/s_texrender.c b/mesalib/src/mesa/swrast/s_texrender.c
index 29bb270d6..fa853c919 100644
--- a/mesalib/src/mesa/swrast/s_texrender.c
+++ b/mesalib/src/mesa/swrast/s_texrender.c
@@ -1,6 +1,5 @@
#include "main/context.h"
-#include "main/colormac.h"
#include "main/fbobject.h"
#include "main/macros.h"
#include "main/teximage.h"
diff --git a/mesalib/src/mesa/swrast/s_triangle.c b/mesalib/src/mesa/swrast/s_triangle.c
index af039c359..876a74b08 100644
--- a/mesalib/src/mesa/swrast/s_triangle.c
+++ b/mesalib/src/mesa/swrast/s_triangle.c
@@ -31,7 +31,6 @@
#include "main/glheader.h"
#include "main/context.h"
-#include "main/colormac.h"
#include "main/imports.h"
#include "main/macros.h"
#include "main/mtypes.h"
diff --git a/mesalib/src/mesa/swrast/s_tritemp.h b/mesalib/src/mesa/swrast/s_tritemp.h
index fb73b2d59..fddbbfd99 100644
--- a/mesalib/src/mesa/swrast/s_tritemp.h
+++ b/mesalib/src/mesa/swrast/s_tritemp.h
@@ -92,7 +92,7 @@
#ifndef MAX_GLUINT
-#define MAX_GLUINT 0xffffffff
+#define MAX_GLUINT 0xffffffffu
#endif
@@ -156,7 +156,7 @@ static void NAME(struct gl_context *ctx, const SWvertex *v0,
#endif
/*
- printf("%s()\n", __FUNCTION__);
+ printf("%s()\n", __func__);
printf(" %g, %g, %g\n",
v0->attrib[VARYING_SLOT_POS][0],
v0->attrib[VARYING_SLOT_POS][1],
diff --git a/mesalib/src/mesa/swrast/s_zoom.c b/mesalib/src/mesa/swrast/s_zoom.c
index ab22652c7..9879e2a5f 100644
--- a/mesalib/src/mesa/swrast/s_zoom.c
+++ b/mesalib/src/mesa/swrast/s_zoom.c
@@ -26,7 +26,6 @@
#include "main/macros.h"
#include "main/imports.h"
#include "main/format_pack.h"
-#include "main/colormac.h"
#include "s_context.h"
#include "s_span.h"
diff --git a/mesalib/src/mesa/swrast_setup/ss_context.c b/mesalib/src/mesa/swrast_setup/ss_context.c
index 0b3b9e4df..74b1da342 100644
--- a/mesalib/src/mesa/swrast_setup/ss_context.c
+++ b/mesalib/src/mesa/swrast_setup/ss_context.c
@@ -27,7 +27,7 @@
#include "main/glheader.h"
#include "main/imports.h"
-#include "main/colormac.h"
+#include "main/macros.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
@@ -167,7 +167,7 @@ setup_vertex_format(struct gl_context *ctx)
EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, pointSize );
_tnl_install_attrs( ctx, map, e,
- ctx->ViewportArray[0]._WindowMap.m,
+ tnl->_WindowMap.m,
sizeof(SWvertex) );
swsetup->last_index_bitset = index_bitset;
@@ -265,7 +265,8 @@ _swsetup_Wakeup( struct gl_context *ctx )
void
_swsetup_Translate( struct gl_context *ctx, const void *vertex, SWvertex *dest )
{
- const GLfloat *m = ctx->ViewportArray[0]._WindowMap.m;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ const GLfloat *m = tnl->_WindowMap.m;
GLfloat tmp[4];
GLuint i;
diff --git a/mesalib/src/mesa/swrast_setup/ss_triangle.c b/mesalib/src/mesa/swrast_setup/ss_triangle.c
index 483c41592..b92c20be2 100644
--- a/mesalib/src/mesa/swrast_setup/ss_triangle.c
+++ b/mesalib/src/mesa/swrast_setup/ss_triangle.c
@@ -27,7 +27,6 @@
#include "c99_math.h"
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "main/mtypes.h"
diff --git a/mesalib/src/mesa/tnl/t_context.c b/mesalib/src/mesa/tnl/t_context.c
index bc705d7a3..5b9dd54d7 100644
--- a/mesalib/src/mesa/tnl/t_context.c
+++ b/mesalib/src/mesa/tnl/t_context.c
@@ -35,6 +35,7 @@
#include "math/m_translate.h"
#include "math/m_xform.h"
#include "main/state.h"
+#include "main/viewport.h"
#include "tnl.h"
#include "t_context.h"
@@ -69,6 +70,8 @@ _tnl_CreateContext( struct gl_context *ctx )
_tnl_install_pipeline( ctx, _tnl_default_pipeline );
}
+ _math_matrix_ctr(&tnl->_WindowMap);
+
tnl->NeedNdcCoords = GL_TRUE;
tnl->AllowVertexFog = GL_TRUE;
tnl->AllowPixelFog = GL_TRUE;
@@ -108,6 +111,8 @@ _tnl_DestroyContext( struct gl_context *ctx )
struct tnl_shine_tab *s, *tmps;
TNLcontext *tnl = TNL_CONTEXT(ctx);
+ _math_matrix_dtr(&tnl->_WindowMap);
+
/* Free lighting shininess exponentiation table */
foreach_s( s, tmps, tnl->_ShineTabList ) {
free( s );
@@ -182,6 +187,13 @@ _tnl_InvalidateState( struct gl_context *ctx, GLuint new_state )
}
}
}
+
+ if (new_state & (_NEW_VIEWPORT | _NEW_BUFFERS)) {
+ double scale[3], translate[3];
+ _mesa_get_viewport_xform(ctx, 0, scale, translate);
+ _math_matrix_viewport(&tnl->_WindowMap, scale, translate,
+ ctx->DrawBuffer->_DepthMaxF);
+ }
}
diff --git a/mesalib/src/mesa/tnl/t_context.h b/mesalib/src/mesa/tnl/t_context.h
index e89a7f836..e7adb5f53 100644
--- a/mesalib/src/mesa/tnl/t_context.h
+++ b/mesalib/src/mesa/tnl/t_context.h
@@ -514,6 +514,7 @@ typedef struct
/* Clipspace/ndc/window vertex managment:
*/
struct tnl_clipspace clipspace;
+ GLmatrix _WindowMap;
/* Probably need a better configuration mechanism:
*/
diff --git a/mesalib/src/mesa/tnl/t_draw.c b/mesalib/src/mesa/tnl/t_draw.c
index 60265d60b..6adf1dce6 100644
--- a/mesalib/src/mesa/tnl/t_draw.c
+++ b/mesalib/src/mesa/tnl/t_draw.c
@@ -448,7 +448,7 @@ void _tnl_draw_prims(struct gl_context *ctx,
if (0)
{
- printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
+ printf("%s %d..%d\n", __func__, min_index, max_index);
for (i = 0; i < nr_prims; i++)
printf("prim %d: %s start %d count %d\n", i,
_mesa_lookup_enum_by_nr(prim[i].mode),
diff --git a/mesalib/src/mesa/tnl/t_rasterpos.c b/mesalib/src/mesa/tnl/t_rasterpos.c
index 9ecf947df..d4b45bac9 100644
--- a/mesalib/src/mesa/tnl/t_rasterpos.c
+++ b/mesalib/src/mesa/tnl/t_rasterpos.c
@@ -25,12 +25,12 @@
#include "c99_math.h"
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/feedback.h"
#include "main/light.h"
#include "main/macros.h"
#include "util/simple_list.h"
#include "main/mtypes.h"
+#include "main/viewport.h"
#include "math/m_matrix.h"
#include "tnl/tnl.h"
@@ -378,6 +378,7 @@ _tnl_RasterPos(struct gl_context *ctx, const GLfloat vObj[4])
GLfloat eye[4], clip[4], ndc[3], d;
GLfloat *norm, eyenorm[3];
GLfloat *objnorm = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
+ double scale[3], translate[3];
/* apply modelview matrix: eye = MV * obj */
TRANSFORM_POINT( eye, ctx->ModelviewMatrixStack.Top->m, vObj );
@@ -410,13 +411,10 @@ _tnl_RasterPos(struct gl_context *ctx, const GLfloat vObj[4])
ndc[1] = clip[1] * d;
ndc[2] = clip[2] * d;
/* wincoord = viewport_mapping(ndc) */
- ctx->Current.RasterPos[0] = (ndc[0] * ctx->ViewportArray[0]._WindowMap.m[MAT_SX]
- + ctx->ViewportArray[0]._WindowMap.m[MAT_TX]);
- ctx->Current.RasterPos[1] = (ndc[1] * ctx->ViewportArray[0]._WindowMap.m[MAT_SY]
- + ctx->ViewportArray[0]._WindowMap.m[MAT_TY]);
- ctx->Current.RasterPos[2] = (ndc[2] * ctx->ViewportArray[0]._WindowMap.m[MAT_SZ]
- + ctx->ViewportArray[0]._WindowMap.m[MAT_TZ])
- / ctx->DrawBuffer->_DepthMaxF;
+ _mesa_get_viewport_xform(ctx, 0, scale, translate);
+ ctx->Current.RasterPos[0] = ndc[0] * scale[0] + translate[0];
+ ctx->Current.RasterPos[1] = ndc[1] * scale[1] + translate[1];
+ ctx->Current.RasterPos[2] = ndc[2] * scale[2] + translate[2];
ctx->Current.RasterPos[3] = clip[3];
if (ctx->Transform.DepthClamp) {
diff --git a/mesalib/src/mesa/tnl/t_vb_fog.c b/mesalib/src/mesa/tnl/t_vb_fog.c
index 3626f1da3..1ca72f866 100644
--- a/mesalib/src/mesa/tnl/t_vb_fog.c
+++ b/mesalib/src/mesa/tnl/t_vb_fog.c
@@ -28,7 +28,6 @@
#include "c99_math.h"
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/mtypes.h"
diff --git a/mesalib/src/mesa/tnl/t_vb_light.c b/mesalib/src/mesa/tnl/t_vb_light.c
index 7781b6a6c..dbd57fa6b 100644
--- a/mesalib/src/mesa/tnl/t_vb_light.c
+++ b/mesalib/src/mesa/tnl/t_vb_light.c
@@ -25,7 +25,6 @@
#include "c99_math.h"
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/light.h"
#include "main/macros.h"
#include "main/imports.h"
diff --git a/mesalib/src/mesa/tnl/t_vb_lighttmp.h b/mesalib/src/mesa/tnl/t_vb_lighttmp.h
index 57f569bd7..f8786accb 100644
--- a/mesalib/src/mesa/tnl/t_vb_lighttmp.h
+++ b/mesalib/src/mesa/tnl/t_vb_lighttmp.h
@@ -68,7 +68,7 @@ static void TAG(light_rgba_spec)( struct gl_context *ctx,
const GLuint nr = VB->Count;
#ifdef TRACE
- fprintf(stderr, "%s\n", __FUNCTION__ );
+ fprintf(stderr, "%s\n", __func__ );
#endif
VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
@@ -249,7 +249,7 @@ static void TAG(light_rgba)( struct gl_context *ctx,
const GLuint nr = VB->Count;
#ifdef TRACE
- fprintf(stderr, "%s\n", __FUNCTION__ );
+ fprintf(stderr, "%s\n", __func__ );
#endif
VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
@@ -429,7 +429,7 @@ static void TAG(light_fast_rgba_single)( struct gl_context *ctx,
#endif
#ifdef TRACE
- fprintf(stderr, "%s\n", __FUNCTION__ );
+ fprintf(stderr, "%s\n", __func__ );
#endif
(void) input; /* doesn't refer to Eye or Obj */
@@ -533,7 +533,7 @@ static void TAG(light_fast_rgba)( struct gl_context *ctx,
const struct gl_light *light;
#ifdef TRACE
- fprintf(stderr, "%s %d\n", __FUNCTION__, nr );
+ fprintf(stderr, "%s %d\n", __func__, nr );
#endif
(void) input;
diff --git a/mesalib/src/mesa/tnl/t_vb_normals.c b/mesalib/src/mesa/tnl/t_vb_normals.c
index b67789e42..9aee1a2fb 100644
--- a/mesalib/src/mesa/tnl/t_vb_normals.c
+++ b/mesalib/src/mesa/tnl/t_vb_normals.c
@@ -27,7 +27,6 @@
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/mtypes.h"
diff --git a/mesalib/src/mesa/tnl/t_vb_program.c b/mesalib/src/mesa/tnl/t_vb_program.c
index 464a4cddd..149434971 100644
--- a/mesalib/src/mesa/tnl/t_vb_program.c
+++ b/mesalib/src/mesa/tnl/t_vb_program.c
@@ -32,7 +32,6 @@
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/samplerobj.h"
diff --git a/mesalib/src/mesa/tnl/t_vb_texgen.c b/mesalib/src/mesa/tnl/t_vb_texgen.c
index 9a61ef2fe..94066f4f6 100644
--- a/mesalib/src/mesa/tnl/t_vb_texgen.c
+++ b/mesalib/src/mesa/tnl/t_vb_texgen.c
@@ -35,7 +35,6 @@
*/
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/mtypes.h"
diff --git a/mesalib/src/mesa/tnl/t_vb_texmat.c b/mesalib/src/mesa/tnl/t_vb_texmat.c
index 1cc2c8116..ef034d643 100644
--- a/mesalib/src/mesa/tnl/t_vb_texmat.c
+++ b/mesalib/src/mesa/tnl/t_vb_texmat.c
@@ -27,7 +27,6 @@
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/mtypes.h"
diff --git a/mesalib/src/mesa/tnl/t_vb_vertex.c b/mesalib/src/mesa/tnl/t_vb_vertex.c
index ea3a56cd1..b56d6803c 100644
--- a/mesalib/src/mesa/tnl/t_vb_vertex.c
+++ b/mesalib/src/mesa/tnl/t_vb_vertex.c
@@ -27,7 +27,6 @@
#include "main/glheader.h"
-#include "main/colormac.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/mtypes.h"
diff --git a/mesalib/src/mesa/tnl/t_vertex.c b/mesalib/src/mesa/tnl/t_vertex.c
index 369d6d945..c3294b007 100644
--- a/mesalib/src/mesa/tnl/t_vertex.c
+++ b/mesalib/src/mesa/tnl/t_vertex.c
@@ -28,7 +28,6 @@
#include <stdio.h>
#include "main/glheader.h"
#include "main/context.h"
-#include "main/colormac.h"
#include "swrast/s_chan.h"
#include "t_context.h"
#include "t_vertex.h"
diff --git a/mesalib/src/mesa/tnl/t_vertex_generic.c b/mesalib/src/mesa/tnl/t_vertex_generic.c
index 079d473fc..2a25a9692 100644
--- a/mesalib/src/mesa/tnl/t_vertex_generic.c
+++ b/mesalib/src/mesa/tnl/t_vertex_generic.c
@@ -28,7 +28,7 @@
#include "main/glheader.h"
#include "main/context.h"
-#include "main/colormac.h"
+#include "main/macros.h"
#include "util/simple_list.h"
#include "swrast/s_chan.h"
#include "t_context.h"
@@ -36,7 +36,7 @@
#if 0
-#define DEBUG_INSERT printf("%s\n", __FUNCTION__)
+#define DEBUG_INSERT printf("%s\n", __func__)
#else
#define DEBUG_INSERT
#endif
diff --git a/mesalib/src/mesa/tnl/t_vertex_sse.c b/mesalib/src/mesa/tnl/t_vertex_sse.c
index 963432c48..30dc1a720 100644
--- a/mesalib/src/mesa/tnl/t_vertex_sse.c
+++ b/mesalib/src/mesa/tnl/t_vertex_sse.c
@@ -29,7 +29,6 @@
#include "main/glheader.h"
#include "main/context.h"
-#include "main/colormac.h"
#include "util/simple_list.h"
#include "main/enums.h"
#include "swrast/s_chan.h"
diff --git a/mesalib/src/mesa/vbo/vbo_exec_api.c b/mesalib/src/mesa/vbo/vbo_exec_api.c
index 02741c2bc..859078f12 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_api.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_api.c
@@ -439,7 +439,7 @@ do { \
} while (0)
-#define ERROR(err) _mesa_error( ctx, err, __FUNCTION__ )
+#define ERROR(err) _mesa_error( ctx, err, __func__ )
#define TAG(x) vbo_##x
#include "vbo_attrib_tmp.h"
diff --git a/mesalib/src/mesa/vbo/vbo_exec_draw.c b/mesalib/src/mesa/vbo/vbo_exec_draw.c
index 91f2ca43a..37b53a830 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_draw.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_draw.c
@@ -45,7 +45,7 @@ vbo_exec_debug_verts( struct vbo_exec_context *exec )
GLuint i;
printf("%s: %u vertices %d primitives, %d vertsize\n",
- __FUNCTION__,
+ __func__,
count,
exec->vtx.prim_count,
exec->vtx.vertex_size);
@@ -402,7 +402,7 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped)
}
if (0)
- printf("%s %d %d\n", __FUNCTION__, exec->vtx.prim_count,
+ printf("%s %d %d\n", __func__, exec->vtx.prim_count,
exec->vtx.vert_count);
vbo_context(ctx)->draw_prims( ctx,
diff --git a/mesalib/src/mesa/vbo/vbo_primitive_restart.c b/mesalib/src/mesa/vbo/vbo_primitive_restart.c
index 562dedcd5..dafc4fd2a 100644
--- a/mesalib/src/mesa/vbo/vbo_primitive_restart.c
+++ b/mesalib/src/mesa/vbo/vbo_primitive_restart.c
@@ -167,6 +167,8 @@ vbo_sw_primitive_restart(struct gl_context *ctx,
struct gl_buffer_object *indirect)
{
GLuint prim_num;
+ struct _mesa_prim new_prim;
+ struct _mesa_index_buffer new_ib;
struct sub_primitive *sub_prims;
struct sub_primitive *sub_prim;
GLuint num_sub_prims;
@@ -182,8 +184,6 @@ vbo_sw_primitive_restart(struct gl_context *ctx,
/* If there is an indirect buffer, map it and extract the draw params */
if (indirect && prims[0].is_indirect) {
- struct _mesa_prim new_prim = *prims;
- struct _mesa_index_buffer new_ib = *ib;
const uint32_t *indirect_params;
if (!ctx->Driver.MapBufferRange(ctx, 0, indirect->Size, GL_MAP_READ_BIT,
indirect, MAP_INTERNAL)) {
@@ -195,6 +195,7 @@ vbo_sw_primitive_restart(struct gl_context *ctx,
}
assert(nr_prims == 1);
+ new_prim = prims[0];
indirect_params = (const uint32_t *)
ADD_POINTERS(indirect->Mappings[MAP_INTERNAL].Pointer,
new_prim.indirect_offset);
@@ -206,6 +207,7 @@ vbo_sw_primitive_restart(struct gl_context *ctx,
new_prim.basevertex = indirect_params[3];
new_prim.base_instance = indirect_params[4];
+ new_ib = *ib;
new_ib.count = new_prim.count;
prims = &new_prim;
diff --git a/mesalib/src/mesa/vbo/vbo_rebase.c b/mesalib/src/mesa/vbo/vbo_rebase.c
index b06df4ab2..c3c4b64e6 100644
--- a/mesalib/src/mesa/vbo/vbo_rebase.c
+++ b/mesalib/src/mesa/vbo/vbo_rebase.c
@@ -142,7 +142,7 @@ void vbo_rebase_prims( struct gl_context *ctx,
assert(min_index != 0);
if (0)
- printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
+ printf("%s %d..%d\n", __func__, min_index, max_index);
/* XXX this path is disabled for now.
diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c
index fd9a5de3d..5927beeb3 100644
--- a/mesalib/src/mesa/vbo/vbo_save_api.c
+++ b/mesalib/src/mesa/vbo/vbo_save_api.c
@@ -763,7 +763,7 @@ _save_reset_vertex(struct gl_context *ctx)
-#define ERROR(err) _mesa_compile_error(ctx, err, __FUNCTION__);
+#define ERROR(err) _mesa_compile_error(ctx, err, __func__);
/* Only one size for each attribute may be active at once. Eg. if
diff --git a/mesalib/src/mesa/x86/common_x86.c b/mesalib/src/mesa/x86/common_x86.c
index 86fbca91e..1c8640514 100644
--- a/mesalib/src/mesa/x86/common_x86.c
+++ b/mesalib/src/mesa/x86/common_x86.c
@@ -42,7 +42,7 @@
#include <sys/types.h>
#include <sys/sysctl.h>
#endif
-#if defined(USE_SSE_ASM) && defined(__OpenBSD__)
+#if defined(USE_SSE_ASM) && (defined(__OpenBSD__) || defined(__NetBSD__))
#include <sys/param.h>
#include <sys/sysctl.h>
#include <machine/cpu.h>
diff --git a/mesalib/src/util/ralloc.c b/mesalib/src/util/ralloc.c
index 36bc61fd0..01719c888 100644
--- a/mesalib/src/util/ralloc.c
+++ b/mesalib/src/util/ralloc.c
@@ -271,6 +271,32 @@ ralloc_steal(const void *new_ctx, void *ptr)
add_child(parent, info);
}
+void
+ralloc_adopt(const void *new_ctx, void *old_ctx)
+{
+ ralloc_header *new_info, *old_info, *child;
+
+ if (unlikely(old_ctx == NULL))
+ return;
+
+ old_info = get_header(old_ctx);
+ new_info = get_header(new_ctx);
+
+ /* If there are no children, bail. */
+ if (unlikely(old_info->child == NULL))
+ return;
+
+ /* Set all the children's parent to new_ctx; get a pointer to the last child. */
+ for (child = old_info->child; child->next != NULL; child = child->next) {
+ child->parent = new_info;
+ }
+
+ /* Connect the two lists together; parent them to new_ctx; make old_ctx empty. */
+ child->next = new_info->child;
+ new_info->child = old_info->child;
+ old_info->child = NULL;
+}
+
void *
ralloc_parent(const void *ptr)
{
diff --git a/mesalib/src/util/ralloc.h b/mesalib/src/util/ralloc.h
index f088a3627..7587e1190 100644
--- a/mesalib/src/util/ralloc.h
+++ b/mesalib/src/util/ralloc.h
@@ -46,16 +46,16 @@
#ifndef RALLOC_H
#define RALLOC_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include <stddef.h>
#include <stdarg.h>
#include <stdbool.h>
#include "macros.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* \def ralloc(ctx, type)
* Allocate a new object chained off of the given context.
@@ -235,6 +235,13 @@ void ralloc_free(void *ptr);
void ralloc_steal(const void *new_ctx, void *ptr);
/**
+ * Reparent all children from one context to another.
+ *
+ * This effectively calls ralloc_steal(new_ctx, child) for all children of \p old_ctx.
+ */
+void ralloc_adopt(const void *new_ctx, void *old_ctx);
+
+/**
* Return the given pointer's ralloc context.
*/
void *ralloc_parent(const void *ptr);
diff --git a/mesalib/src/util/u_atomic_test.c b/mesalib/src/util/u_atomic_test.c
index 939cfe445..7844f6162 100644
--- a/mesalib/src/util/u_atomic_test.c
+++ b/mesalib/src/util/u_atomic_test.c
@@ -36,6 +36,11 @@
#include "u_atomic.h"
+#ifdef _MSC_VER
+#pragma warning( disable : 28112 ) /* Accessing a local variable via an Interlocked function */
+#pragma warning( disable : 28113 ) /* A variable which is accessed via an Interlocked function must always be accessed via an Interlocked function */
+#endif
+
/* Test only assignment-like operations, which are supported on all types */
#define test_atomic_assign(type, ones) \
diff --git a/pixman/pixman/pixman-arm-simd-asm.h b/pixman/pixman/pixman-arm-simd-asm.h
index 8de060a6b..da153c3f5 100644
--- a/pixman/pixman/pixman-arm-simd-asm.h
+++ b/pixman/pixman/pixman-arm-simd-asm.h
@@ -211,8 +211,8 @@
PF add, SCRATCH, base, WK0, lsl #bpp_shift-dst_bpp_shift
PF and, SCRATCH, SCRATCH, #31
PF rsb, SCRATCH, SCRATCH, WK0, lsl #bpp_shift-dst_bpp_shift
- PF sub, SCRATCH, SCRATCH, #1 /* so now ranges are -16..-1 / 0..31 / 32..63 */
- PF movs, SCRATCH, SCRATCH, #32-6 /* so this sets NC / nc / Nc */
+ PF sub, SCRATCH, SCRATCH, #1 /* so now ranges are -16..-1 / 0..31 / 32..63 */
+ PF movs, SCRATCH, SCRATCH, lsl #32-6 /* so this sets NC / nc / Nc */
PF bcs, 61f
PF bpl, 60f
PF pld, [ptr, #32*(prefetch_distance+2)]
diff --git a/pixman/pixman/pixman.c b/pixman/pixman/pixman.c
index 9555ceaaf..a07c577ad 100644
--- a/pixman/pixman/pixman.c
+++ b/pixman/pixman/pixman.c
@@ -325,18 +325,20 @@ _pixman_compute_composite_region32 (pixman_region32_t * region,
return TRUE;
}
-typedef struct
+typedef struct box_48_16 box_48_16_t;
+
+struct box_48_16
{
- pixman_fixed_48_16_t x1;
- pixman_fixed_48_16_t y1;
- pixman_fixed_48_16_t x2;
- pixman_fixed_48_16_t y2;
-} box_48_16_t;
+ pixman_fixed_48_16_t x1;
+ pixman_fixed_48_16_t y1;
+ pixman_fixed_48_16_t x2;
+ pixman_fixed_48_16_t y2;
+};
static pixman_bool_t
-compute_transformed_extents (pixman_transform_t *transform,
+compute_transformed_extents (pixman_transform_t *transform,
const pixman_box32_t *extents,
- box_48_16_t *transformed)
+ box_48_16_t *transformed)
{
pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
pixman_fixed_t x1, y1, x2, y2;
diff --git a/pixman/test/check-formats.c b/pixman/test/check-formats.c
index 8eb263b77..4e2633c41 100644
--- a/pixman/test/check-formats.c
+++ b/pixman/test/check-formats.c
@@ -104,198 +104,6 @@ check_op (pixman_op_t op,
return retval;
}
-static const pixman_op_t op_list[] =
-{
- PIXMAN_OP_CLEAR,
- PIXMAN_OP_SRC,
- PIXMAN_OP_DST,
- PIXMAN_OP_OVER,
- PIXMAN_OP_OVER_REVERSE,
- PIXMAN_OP_IN,
- PIXMAN_OP_IN_REVERSE,
- PIXMAN_OP_OUT,
- PIXMAN_OP_OUT_REVERSE,
- PIXMAN_OP_ATOP,
- PIXMAN_OP_ATOP_REVERSE,
- PIXMAN_OP_XOR,
- PIXMAN_OP_ADD,
- PIXMAN_OP_SATURATE,
-
- PIXMAN_OP_DISJOINT_CLEAR,
- PIXMAN_OP_DISJOINT_SRC,
- PIXMAN_OP_DISJOINT_DST,
- PIXMAN_OP_DISJOINT_OVER,
- PIXMAN_OP_DISJOINT_OVER_REVERSE,
- PIXMAN_OP_DISJOINT_IN,
- PIXMAN_OP_DISJOINT_IN_REVERSE,
- PIXMAN_OP_DISJOINT_OUT,
- PIXMAN_OP_DISJOINT_OUT_REVERSE,
- PIXMAN_OP_DISJOINT_ATOP,
- PIXMAN_OP_DISJOINT_ATOP_REVERSE,
- PIXMAN_OP_DISJOINT_XOR,
-
- PIXMAN_OP_CONJOINT_CLEAR,
- PIXMAN_OP_CONJOINT_SRC,
- PIXMAN_OP_CONJOINT_DST,
- PIXMAN_OP_CONJOINT_OVER,
- PIXMAN_OP_CONJOINT_OVER_REVERSE,
- PIXMAN_OP_CONJOINT_IN,
- PIXMAN_OP_CONJOINT_IN_REVERSE,
- PIXMAN_OP_CONJOINT_OUT,
- PIXMAN_OP_CONJOINT_OUT_REVERSE,
- PIXMAN_OP_CONJOINT_ATOP,
- PIXMAN_OP_CONJOINT_ATOP_REVERSE,
- PIXMAN_OP_CONJOINT_XOR,
-
- PIXMAN_OP_MULTIPLY,
- PIXMAN_OP_SCREEN,
- PIXMAN_OP_OVERLAY,
- PIXMAN_OP_DARKEN,
- PIXMAN_OP_LIGHTEN,
- PIXMAN_OP_COLOR_DODGE,
- PIXMAN_OP_COLOR_BURN,
- PIXMAN_OP_HARD_LIGHT,
- PIXMAN_OP_SOFT_LIGHT,
- PIXMAN_OP_DIFFERENCE,
- PIXMAN_OP_EXCLUSION,
- PIXMAN_OP_HSL_HUE,
- PIXMAN_OP_HSL_SATURATION,
- PIXMAN_OP_HSL_COLOR,
- PIXMAN_OP_HSL_LUMINOSITY
-};
-
-static const pixman_format_code_t format_list[] =
-{
- PIXMAN_a8r8g8b8,
- PIXMAN_x8r8g8b8,
- PIXMAN_a8b8g8r8,
- PIXMAN_x8b8g8r8,
- PIXMAN_b8g8r8a8,
- PIXMAN_b8g8r8x8,
- PIXMAN_r8g8b8a8,
- PIXMAN_r8g8b8x8,
- PIXMAN_x14r6g6b6,
- PIXMAN_x2r10g10b10,
- PIXMAN_a2r10g10b10,
- PIXMAN_x2b10g10r10,
- PIXMAN_a2b10g10r10,
- PIXMAN_a8r8g8b8_sRGB,
- PIXMAN_r8g8b8,
- PIXMAN_b8g8r8,
- PIXMAN_r5g6b5,
- PIXMAN_b5g6r5,
- PIXMAN_a1r5g5b5,
- PIXMAN_x1r5g5b5,
- PIXMAN_a1b5g5r5,
- PIXMAN_x1b5g5r5,
- PIXMAN_a4r4g4b4,
- PIXMAN_x4r4g4b4,
- PIXMAN_a4b4g4r4,
- PIXMAN_x4b4g4r4,
- PIXMAN_a8,
- PIXMAN_r3g3b2,
- PIXMAN_b2g3r3,
- PIXMAN_a2r2g2b2,
- PIXMAN_a2b2g2r2,
- PIXMAN_x4a4,
- PIXMAN_a4,
- PIXMAN_r1g2b1,
- PIXMAN_b1g2r1,
- PIXMAN_a1r1g1b1,
- PIXMAN_a1b1g1r1,
- PIXMAN_a1,
-};
-
-static pixman_format_code_t
-format_from_string (const char *s)
-{
- int i;
-
- for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
- {
- if (strcasecmp (format_name (format_list[i]), s) == 0)
- return format_list[i];
- }
-
- return PIXMAN_null;
-}
-
-static void
-emit (const char *s, int *n_chars)
-{
- *n_chars += printf ("%s,", s);
- if (*n_chars > 60)
- {
- printf ("\n ");
- *n_chars = 0;
- }
- else
- {
- printf (" ");
- (*n_chars)++;
- }
-}
-
-static void
-list_formats (void)
-{
- int n_chars;
- int i;
-
- printf ("Formats:\n ");
-
- n_chars = 0;
- for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
- emit (format_name (format_list[i]), &n_chars);
-
- printf ("\n\n");
-}
-
-static void
-list_operators (void)
-{
- char short_name [128] = { 0 };
- int i, n_chars;
-
- printf ("Operators:\n ");
-
- n_chars = 0;
- for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
- {
- pixman_op_t op = op_list[i];
- int j;
-
- snprintf (short_name, sizeof (short_name) - 1, "%s",
- operator_name (op) + strlen ("PIXMAN_OP_"));
-
- for (j = 0; short_name[j] != '\0'; ++j)
- short_name[j] = tolower (short_name[j]);
-
- emit (short_name, &n_chars);
- }
-
- printf ("\n\n");
-}
-
-static pixman_op_t
-operator_from_string (const char *s)
-{
- char full_name[128] = { 0 };
- int i;
-
- snprintf (full_name, (sizeof full_name) - 1, "PIXMAN_OP_%s", s);
-
- for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
- {
- pixman_op_t op = op_list[i];
-
- if (strcasecmp (operator_name (op), full_name) == 0)
- return op;
- }
-
- return PIXMAN_OP_NONE;
-}
-
int
main (int argc, char **argv)
{
diff --git a/pixman/test/lowlevel-blt-bench.c b/pixman/test/lowlevel-blt-bench.c
index 3da094a2b..aff460874 100644
--- a/pixman/test/lowlevel-blt-bench.c
+++ b/pixman/test/lowlevel-blt-bench.c
@@ -367,14 +367,14 @@ bench_RT (pixman_op_t op,
}
void
-bench_composite (char * testname,
- int src_fmt,
- int src_flags,
- int op,
- int mask_fmt,
- int mask_flags,
- int dst_fmt,
- double npix)
+bench_composite (const char *testname,
+ int src_fmt,
+ int src_flags,
+ int op,
+ int mask_fmt,
+ int mask_flags,
+ int dst_fmt,
+ double npix)
{
pixman_image_t * src_img;
pixman_image_t * dst_img;
@@ -587,7 +587,7 @@ bench_composite (char * testname,
#define PIXMAN_OP_OUT_REV (PIXMAN_OP_OUT_REVERSE)
-struct
+struct test_entry
{
char *testname;
int src_fmt;
@@ -596,8 +596,11 @@ struct
int mask_fmt;
int mask_flags;
int dst_fmt;
-}
-tests_tbl[] =
+};
+
+typedef struct test_entry test_entry_t;
+
+static const test_entry_t tests_tbl[] =
{
{ "add_8_8_8", PIXMAN_a8, 0, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a8 },
{ "add_n_8_8", PIXMAN_a8r8g8b8, 1, PIXMAN_OP_ADD, PIXMAN_a8, 0, PIXMAN_a8 },
@@ -719,6 +722,260 @@ tests_tbl[] =
{ "rpixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8b8g8r8 },
};
+static const test_entry_t special_patterns[] =
+{
+ { "add_n_2x10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_x2r10g10b10 },
+ { "add_n_2a10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_ADD, PIXMAN_null, 0, PIXMAN_a2r10g10b10 },
+ { "src_n_2x10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_x2r10g10b10 },
+ { "src_n_2a10", PIXMAN_a2r10g10b10, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a2r10g10b10 },
+ { "src_0888_8888_rev", PIXMAN_b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_x8r8g8b8 },
+ { "src_0888_0565_rev", PIXMAN_b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_r5g6b5 },
+ { "src_n_8", PIXMAN_a8, 1, PIXMAN_OP_SRC, PIXMAN_null, 0, PIXMAN_a8 },
+ { "pixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8r8g8b8 },
+ { "rpixbuf", PIXMAN_x8b8g8r8, 0, PIXMAN_OP_SRC, PIXMAN_a8b8g8r8, 0, PIXMAN_a8b8g8r8 },
+};
+
+/* Returns the sub-string's end pointer in string. */
+static const char *
+copy_sub_string (char *buf,
+ const char *string,
+ const char *scan_from,
+ const char *end)
+{
+ const char *delim;
+ size_t n;
+
+ delim = strchr (scan_from, '_');
+ if (!delim)
+ delim = end;
+
+ n = delim - string;
+ strncpy(buf, string, n);
+ buf[n] = '\0';
+
+ return delim;
+}
+
+static pixman_op_t
+parse_longest_operator (char *buf, const char **strp, const char *end)
+{
+ const char *p = *strp;
+ const char *sub_end;
+ const char *best_end = p;
+ pixman_op_t best_op = PIXMAN_OP_NONE;
+ pixman_op_t op;
+
+ while (p < end)
+ {
+ sub_end = copy_sub_string (buf, *strp, p, end);
+ op = operator_from_string (buf);
+ p = sub_end + 1;
+
+ if (op != PIXMAN_OP_NONE)
+ {
+ best_end = p;
+ best_op = op;
+ }
+ }
+
+ *strp = best_end;
+ return best_op;
+}
+
+static pixman_format_code_t
+parse_format (char *buf, const char **p, const char *end)
+{
+ pixman_format_code_t format;
+ const char *delim;
+
+ if (*p >= end)
+ return PIXMAN_null;
+
+ delim = copy_sub_string (buf, *p, *p, end);
+ format = format_from_string (buf);
+
+ if (format != PIXMAN_null)
+ *p = delim + 1;
+
+ return format;
+}
+
+static int
+parse_test_pattern (test_entry_t *test, const char *pattern)
+{
+ const char *p = pattern;
+ const char *end = pattern + strlen (pattern);
+ char buf[1024];
+ pixman_format_code_t format[3];
+ int i;
+
+ if (strlen (pattern) > sizeof (buf) - 1)
+ return -1;
+
+ /* Special cases that the parser cannot produce. */
+ for (i = 0; i < ARRAY_LENGTH (special_patterns); i++)
+ {
+ if (strcmp (pattern, special_patterns[i].testname) == 0)
+ {
+ *test = special_patterns[i];
+ return 0;
+ }
+ }
+
+ /* Extract operator, may contain delimiters,
+ * so take the longest string that matches.
+ */
+ test->op = parse_longest_operator (buf, &p, end);
+ if (test->op == PIXMAN_OP_NONE)
+ return -1;
+
+ /* extract up to three pixel formats */
+ format[0] = parse_format (buf, &p, end);
+ format[1] = parse_format (buf, &p, end);
+ format[2] = parse_format (buf, &p, end);
+
+ if (format[0] == PIXMAN_null || format[1] == PIXMAN_null)
+ return -1;
+
+ /* recognize CA flag */
+ test->mask_flags = 0;
+ if (p < end)
+ {
+ if (strcmp (p, "ca") == 0)
+ test->mask_flags |= CA_FLAG;
+ else
+ return -1; /* trailing garbage */
+ }
+
+ test->src_fmt = format[0];
+ if (format[2] == PIXMAN_null)
+ {
+ test->mask_fmt = PIXMAN_null;
+ test->dst_fmt = format[1];
+ }
+ else
+ {
+ test->mask_fmt = format[1];
+ test->dst_fmt = format[2];
+ }
+
+ test->src_flags = 0;
+ if (test->src_fmt == PIXMAN_solid)
+ {
+ test->src_fmt = PIXMAN_a8r8g8b8;
+ test->src_flags |= SOLID_FLAG;
+ }
+
+ if (test->mask_fmt == PIXMAN_solid)
+ {
+ if (test->mask_flags & CA_FLAG)
+ test->mask_fmt = PIXMAN_a8r8g8b8;
+ else
+ test->mask_fmt = PIXMAN_a8;
+
+ test->mask_flags |= SOLID_FLAG;
+ }
+
+ return 0;
+}
+
+static int
+check_int (int got, int expected, const char *name, const char *field)
+{
+ if (got == expected)
+ return 0;
+
+ printf ("%s: %s failure: expected %d, got %d.\n",
+ name, field, expected, got);
+
+ return 1;
+}
+
+static int
+check_format (int got, int expected, const char *name, const char *field)
+{
+ if (got == expected)
+ return 0;
+
+ printf ("%s: %s failure: expected %s (%#x), got %s (%#x).\n",
+ name, field,
+ format_name (expected), expected,
+ format_name (got), got);
+
+ return 1;
+}
+
+static void
+parser_self_test (void)
+{
+ const test_entry_t *ent;
+ test_entry_t test;
+ int fails = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_LENGTH (tests_tbl); i++)
+ {
+ ent = &tests_tbl[i];
+
+ if (parse_test_pattern (&test, ent->testname) < 0)
+ {
+ printf ("parsing failed for '%s'\n", ent->testname);
+ fails++;
+ continue;
+ }
+
+ fails += check_format (test.src_fmt, ent->src_fmt,
+ ent->testname, "src_fmt");
+ fails += check_format (test.mask_fmt, ent->mask_fmt,
+ ent->testname, "mask_fmt");
+ fails += check_format (test.dst_fmt, ent->dst_fmt,
+ ent->testname, "dst_fmt");
+ fails += check_int (test.src_flags, ent->src_flags,
+ ent->testname, "src_flags");
+ fails += check_int (test.mask_flags, ent->mask_flags,
+ ent->testname, "mask_flags");
+ fails += check_int (test.op, ent->op, ent->testname, "op");
+ }
+
+ if (fails)
+ {
+ printf ("Parser self-test failed.\n");
+ exit (EXIT_FAILURE);
+ }
+
+ printf ("Parser self-test complete.\n");
+}
+
+static void
+run_one_test (const char *pattern, double bandwidth_)
+{
+ test_entry_t test;
+
+ if (parse_test_pattern (&test, pattern) < 0)
+ {
+ printf ("Error: Could not parse the test pattern '%s'.\n", pattern);
+ return;
+ }
+
+ bench_composite (pattern,
+ test.src_fmt,
+ test.src_flags,
+ test.op,
+ test.mask_fmt,
+ test.mask_flags,
+ test.dst_fmt,
+ bandwidth_ / 8);
+}
+
+static void
+run_default_tests (double bandwidth_)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_LENGTH (tests_tbl); i++)
+ run_one_test (tests_tbl[i].testname, bandwidth_);
+}
+
int
main (int argc, char *argv[])
{
@@ -754,6 +1011,8 @@ main (int argc, char *argv[])
return 1;
}
+ parser_self_test ();
+
src = aligned_malloc (4096, BUFSIZE * 3);
memset (src, 0xCC, BUFSIZE * 3);
dst = src + (BUFSIZE / 4);
@@ -801,19 +1060,13 @@ main (int argc, char *argv[])
}
printf ("---\n");
- for (i = 0; i < ARRAY_LENGTH (tests_tbl); i++)
+ if (strcmp (pattern, "all") == 0)
{
- if (strcmp (pattern, "all") == 0 || strcmp (tests_tbl[i].testname, pattern) == 0)
- {
- bench_composite (tests_tbl[i].testname,
- tests_tbl[i].src_fmt,
- tests_tbl[i].src_flags,
- tests_tbl[i].op,
- tests_tbl[i].mask_fmt,
- tests_tbl[i].mask_flags,
- tests_tbl[i].dst_fmt,
- bandwidth/8);
- }
+ run_default_tests (bandwidth);
+ }
+ else
+ {
+ run_one_test (pattern, bandwidth);
}
free (src);
diff --git a/pixman/test/utils.c b/pixman/test/utils.c
index ab3424f9e..5663aecbe 100644
--- a/pixman/test/utils.c
+++ b/pixman/test/utils.c
@@ -5,6 +5,7 @@
#include <signal.h>
#include <stdlib.h>
#include <float.h>
+#include <ctype.h>
#ifdef HAVE_GETTIMEOFDAY
#include <sys/time.h>
@@ -948,164 +949,348 @@ initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
}
}
-const char *
-operator_name (pixman_op_t op)
+struct operator_entry {
+ pixman_op_t op;
+ const char *name;
+ pixman_bool_t is_alias;
+};
+
+typedef struct operator_entry operator_entry_t;
+
+static const operator_entry_t op_list[] =
{
- switch (op)
- {
- case PIXMAN_OP_CLEAR: return "PIXMAN_OP_CLEAR";
- case PIXMAN_OP_SRC: return "PIXMAN_OP_SRC";
- case PIXMAN_OP_DST: return "PIXMAN_OP_DST";
- case PIXMAN_OP_OVER: return "PIXMAN_OP_OVER";
- case PIXMAN_OP_OVER_REVERSE: return "PIXMAN_OP_OVER_REVERSE";
- case PIXMAN_OP_IN: return "PIXMAN_OP_IN";
- case PIXMAN_OP_IN_REVERSE: return "PIXMAN_OP_IN_REVERSE";
- case PIXMAN_OP_OUT: return "PIXMAN_OP_OUT";
- case PIXMAN_OP_OUT_REVERSE: return "PIXMAN_OP_OUT_REVERSE";
- case PIXMAN_OP_ATOP: return "PIXMAN_OP_ATOP";
- case PIXMAN_OP_ATOP_REVERSE: return "PIXMAN_OP_ATOP_REVERSE";
- case PIXMAN_OP_XOR: return "PIXMAN_OP_XOR";
- case PIXMAN_OP_ADD: return "PIXMAN_OP_ADD";
- case PIXMAN_OP_SATURATE: return "PIXMAN_OP_SATURATE";
-
- case PIXMAN_OP_DISJOINT_CLEAR: return "PIXMAN_OP_DISJOINT_CLEAR";
- case PIXMAN_OP_DISJOINT_SRC: return "PIXMAN_OP_DISJOINT_SRC";
- case PIXMAN_OP_DISJOINT_DST: return "PIXMAN_OP_DISJOINT_DST";
- case PIXMAN_OP_DISJOINT_OVER: return "PIXMAN_OP_DISJOINT_OVER";
- case PIXMAN_OP_DISJOINT_OVER_REVERSE: return "PIXMAN_OP_DISJOINT_OVER_REVERSE";
- case PIXMAN_OP_DISJOINT_IN: return "PIXMAN_OP_DISJOINT_IN";
- case PIXMAN_OP_DISJOINT_IN_REVERSE: return "PIXMAN_OP_DISJOINT_IN_REVERSE";
- case PIXMAN_OP_DISJOINT_OUT: return "PIXMAN_OP_DISJOINT_OUT";
- case PIXMAN_OP_DISJOINT_OUT_REVERSE: return "PIXMAN_OP_DISJOINT_OUT_REVERSE";
- case PIXMAN_OP_DISJOINT_ATOP: return "PIXMAN_OP_DISJOINT_ATOP";
- case PIXMAN_OP_DISJOINT_ATOP_REVERSE: return "PIXMAN_OP_DISJOINT_ATOP_REVERSE";
- case PIXMAN_OP_DISJOINT_XOR: return "PIXMAN_OP_DISJOINT_XOR";
-
- case PIXMAN_OP_CONJOINT_CLEAR: return "PIXMAN_OP_CONJOINT_CLEAR";
- case PIXMAN_OP_CONJOINT_SRC: return "PIXMAN_OP_CONJOINT_SRC";
- case PIXMAN_OP_CONJOINT_DST: return "PIXMAN_OP_CONJOINT_DST";
- case PIXMAN_OP_CONJOINT_OVER: return "PIXMAN_OP_CONJOINT_OVER";
- case PIXMAN_OP_CONJOINT_OVER_REVERSE: return "PIXMAN_OP_CONJOINT_OVER_REVERSE";
- case PIXMAN_OP_CONJOINT_IN: return "PIXMAN_OP_CONJOINT_IN";
- case PIXMAN_OP_CONJOINT_IN_REVERSE: return "PIXMAN_OP_CONJOINT_IN_REVERSE";
- case PIXMAN_OP_CONJOINT_OUT: return "PIXMAN_OP_CONJOINT_OUT";
- case PIXMAN_OP_CONJOINT_OUT_REVERSE: return "PIXMAN_OP_CONJOINT_OUT_REVERSE";
- case PIXMAN_OP_CONJOINT_ATOP: return "PIXMAN_OP_CONJOINT_ATOP";
- case PIXMAN_OP_CONJOINT_ATOP_REVERSE: return "PIXMAN_OP_CONJOINT_ATOP_REVERSE";
- case PIXMAN_OP_CONJOINT_XOR: return "PIXMAN_OP_CONJOINT_XOR";
-
- case PIXMAN_OP_MULTIPLY: return "PIXMAN_OP_MULTIPLY";
- case PIXMAN_OP_SCREEN: return "PIXMAN_OP_SCREEN";
- case PIXMAN_OP_OVERLAY: return "PIXMAN_OP_OVERLAY";
- case PIXMAN_OP_DARKEN: return "PIXMAN_OP_DARKEN";
- case PIXMAN_OP_LIGHTEN: return "PIXMAN_OP_LIGHTEN";
- case PIXMAN_OP_COLOR_DODGE: return "PIXMAN_OP_COLOR_DODGE";
- case PIXMAN_OP_COLOR_BURN: return "PIXMAN_OP_COLOR_BURN";
- case PIXMAN_OP_HARD_LIGHT: return "PIXMAN_OP_HARD_LIGHT";
- case PIXMAN_OP_SOFT_LIGHT: return "PIXMAN_OP_SOFT_LIGHT";
- case PIXMAN_OP_DIFFERENCE: return "PIXMAN_OP_DIFFERENCE";
- case PIXMAN_OP_EXCLUSION: return "PIXMAN_OP_EXCLUSION";
- case PIXMAN_OP_HSL_HUE: return "PIXMAN_OP_HSL_HUE";
- case PIXMAN_OP_HSL_SATURATION: return "PIXMAN_OP_HSL_SATURATION";
- case PIXMAN_OP_HSL_COLOR: return "PIXMAN_OP_HSL_COLOR";
- case PIXMAN_OP_HSL_LUMINOSITY: return "PIXMAN_OP_HSL_LUMINOSITY";
-
- case PIXMAN_OP_NONE:
- return "<invalid operator 'none'>";
- };
+#define ENTRY(op) \
+ { PIXMAN_OP_##op, "PIXMAN_OP_" #op, FALSE }
+#define ALIAS(op, nam) \
+ { PIXMAN_OP_##op, nam, TRUE }
+
+ /* operator_name () will return the first hit in this table,
+ * so keep the list properly ordered between entries and aliases.
+ * Aliases are not listed by list_operators ().
+ */
- return "<unknown operator>";
-}
+ ENTRY (CLEAR),
+ ENTRY (SRC),
+ ENTRY (DST),
+ ENTRY (OVER),
+ ENTRY (OVER_REVERSE),
+ ALIAS (OVER_REVERSE, "overrev"),
+ ENTRY (IN),
+ ENTRY (IN_REVERSE),
+ ALIAS (IN_REVERSE, "inrev"),
+ ENTRY (OUT),
+ ENTRY (OUT_REVERSE),
+ ALIAS (OUT_REVERSE, "outrev"),
+ ENTRY (ATOP),
+ ENTRY (ATOP_REVERSE),
+ ALIAS (ATOP_REVERSE, "atoprev"),
+ ENTRY (XOR),
+ ENTRY (ADD),
+ ENTRY (SATURATE),
+
+ ENTRY (DISJOINT_CLEAR),
+ ENTRY (DISJOINT_SRC),
+ ENTRY (DISJOINT_DST),
+ ENTRY (DISJOINT_OVER),
+ ENTRY (DISJOINT_OVER_REVERSE),
+ ENTRY (DISJOINT_IN),
+ ENTRY (DISJOINT_IN_REVERSE),
+ ENTRY (DISJOINT_OUT),
+ ENTRY (DISJOINT_OUT_REVERSE),
+ ENTRY (DISJOINT_ATOP),
+ ENTRY (DISJOINT_ATOP_REVERSE),
+ ENTRY (DISJOINT_XOR),
+
+ ENTRY (CONJOINT_CLEAR),
+ ENTRY (CONJOINT_SRC),
+ ENTRY (CONJOINT_DST),
+ ENTRY (CONJOINT_OVER),
+ ENTRY (CONJOINT_OVER_REVERSE),
+ ENTRY (CONJOINT_IN),
+ ENTRY (CONJOINT_IN_REVERSE),
+ ENTRY (CONJOINT_OUT),
+ ENTRY (CONJOINT_OUT_REVERSE),
+ ENTRY (CONJOINT_ATOP),
+ ENTRY (CONJOINT_ATOP_REVERSE),
+ ENTRY (CONJOINT_XOR),
+
+ ENTRY (MULTIPLY),
+ ENTRY (SCREEN),
+ ENTRY (OVERLAY),
+ ENTRY (DARKEN),
+ ENTRY (LIGHTEN),
+ ENTRY (COLOR_DODGE),
+ ENTRY (COLOR_BURN),
+ ENTRY (HARD_LIGHT),
+ ENTRY (SOFT_LIGHT),
+ ENTRY (DIFFERENCE),
+ ENTRY (EXCLUSION),
+ ENTRY (HSL_HUE),
+ ENTRY (HSL_SATURATION),
+ ENTRY (HSL_COLOR),
+ ENTRY (HSL_LUMINOSITY),
+
+ ALIAS (NONE, "<invalid operator 'none'>")
+
+#undef ENTRY
+#undef ALIAS
+};
-const char *
-format_name (pixman_format_code_t format)
+struct format_entry
{
- switch (format)
- {
+ pixman_format_code_t format;
+ const char *name;
+ pixman_bool_t is_alias;
+};
+
+typedef struct format_entry format_entry_t;
+
+static const format_entry_t format_list[] =
+{
+#define ENTRY(f) \
+ { PIXMAN_##f, #f, FALSE }
+#define ALIAS(f, nam) \
+ { PIXMAN_##f, nam, TRUE }
+
+ /* format_name () will return the first hit in this table,
+ * so keep the list properly ordered between entries and aliases.
+ * Aliases are not listed by list_formats ().
+ */
+
/* 32bpp formats */
- case PIXMAN_a8r8g8b8: return "a8r8g8b8";
- case PIXMAN_x8r8g8b8: return "x8r8g8b8";
- case PIXMAN_a8b8g8r8: return "a8b8g8r8";
- case PIXMAN_x8b8g8r8: return "x8b8g8r8";
- case PIXMAN_b8g8r8a8: return "b8g8r8a8";
- case PIXMAN_b8g8r8x8: return "b8g8r8x8";
- case PIXMAN_r8g8b8a8: return "r8g8b8a8";
- case PIXMAN_r8g8b8x8: return "r8g8b8x8";
- case PIXMAN_x14r6g6b6: return "x14r6g6b6";
- case PIXMAN_x2r10g10b10: return "x2r10g10b10";
- case PIXMAN_a2r10g10b10: return "a2r10g10b10";
- case PIXMAN_x2b10g10r10: return "x2b10g10r10";
- case PIXMAN_a2b10g10r10: return "a2b10g10r10";
+ ENTRY (a8r8g8b8),
+ ALIAS (a8r8g8b8, "8888"),
+ ENTRY (x8r8g8b8),
+ ALIAS (x8r8g8b8, "x888"),
+ ENTRY (a8b8g8r8),
+ ENTRY (x8b8g8r8),
+ ENTRY (b8g8r8a8),
+ ENTRY (b8g8r8x8),
+ ENTRY (r8g8b8a8),
+ ENTRY (r8g8b8x8),
+ ENTRY (x14r6g6b6),
+ ENTRY (x2r10g10b10),
+ ALIAS (x2r10g10b10, "2x10"),
+ ENTRY (a2r10g10b10),
+ ALIAS (a2r10g10b10, "2a10"),
+ ENTRY (x2b10g10r10),
+ ENTRY (a2b10g10r10),
/* sRGB formats */
- case PIXMAN_a8r8g8b8_sRGB: return "a8r8g8b8_sRGB";
+ ENTRY (a8r8g8b8_sRGB),
/* 24bpp formats */
- case PIXMAN_r8g8b8: return "r8g8b8";
- case PIXMAN_b8g8r8: return "b8g8r8";
-
-/* 16bpp formats */
- case PIXMAN_r5g6b5: return "r5g6b5";
- case PIXMAN_b5g6r5: return "b5g6r5";
-
- case PIXMAN_a1r5g5b5: return "a1r5g5b5";
- case PIXMAN_x1r5g5b5: return "x1r5g5b5";
- case PIXMAN_a1b5g5r5: return "a1b5g5r5";
- case PIXMAN_x1b5g5r5: return "x1b5g5r5";
- case PIXMAN_a4r4g4b4: return "a4r4g4b4";
- case PIXMAN_x4r4g4b4: return "x4r4g4b4";
- case PIXMAN_a4b4g4r4: return "a4b4g4r4";
- case PIXMAN_x4b4g4r4: return "x4b4g4r4";
+ ENTRY (r8g8b8),
+ ALIAS (r8g8b8, "0888"),
+ ENTRY (b8g8r8),
+
+/* 16 bpp formats */
+ ENTRY (r5g6b5),
+ ALIAS (r5g6b5, "0565"),
+ ENTRY (b5g6r5),
+
+ ENTRY (a1r5g5b5),
+ ALIAS (a1r5g5b5, "1555"),
+ ENTRY (x1r5g5b5),
+ ENTRY (a1b5g5r5),
+ ENTRY (x1b5g5r5),
+ ENTRY (a4r4g4b4),
+ ALIAS (a4r4g4b4, "4444"),
+ ENTRY (x4r4g4b4),
+ ENTRY (a4b4g4r4),
+ ENTRY (x4b4g4r4),
/* 8bpp formats */
- case PIXMAN_a8: return "a8";
- case PIXMAN_r3g3b2: return "r3g3b2";
- case PIXMAN_b2g3r3: return "b2g3r3";
- case PIXMAN_a2r2g2b2: return "a2r2g2b2";
- case PIXMAN_a2b2g2r2: return "a2b2g2r2";
-
-#if 0
- case PIXMAN_x4c4: return "x4c4";
- case PIXMAN_g8: return "g8";
-#endif
- case PIXMAN_c8: return "x4c4 / c8";
- case PIXMAN_x4g4: return "x4g4 / g8";
+ ENTRY (a8),
+ ALIAS (a8, "8"),
+ ENTRY (r3g3b2),
+ ENTRY (b2g3r3),
+ ENTRY (a2r2g2b2),
+ ALIAS (a2r2g2b2, "2222"),
+ ENTRY (a2b2g2r2),
+
+ ALIAS (c8, "x4c4 / c8"),
+ /* ENTRY (c8), */
+ ALIAS (g8, "x4g4 / g8"),
+ /* ENTRY (g8), */
+
+ ENTRY (x4a4),
+
+ /* These format codes are identical to c8 and g8, respectively. */
+ /* ENTRY (x4c4), */
+ /* ENTRY (x4g4), */
+
+/* 4 bpp formats */
+ ENTRY (a4),
+ ENTRY (r1g2b1),
+ ENTRY (b1g2r1),
+ ENTRY (a1r1g1b1),
+ ENTRY (a1b1g1r1),
+
+ ALIAS (c4, "c4"),
+ /* ENTRY (c4), */
+ ALIAS (g4, "g4"),
+ /* ENTRY (g4), */
+
+/* 1bpp formats */
+ ENTRY (a1),
+
+ ALIAS (g1, "g1"),
+ /* ENTRY (g1), */
- case PIXMAN_x4a4: return "x4a4";
+/* YUV formats */
+ ALIAS (yuy2, "yuy2"),
+ /* ENTRY (yuy2), */
+ ALIAS (yv12, "yv12"),
+ /* ENTRY (yv12), */
+
+/* Fake formats, not in pixman_format_code_t enum */
+ ALIAS (null, "null"),
+ ALIAS (solid, "solid"),
+ ALIAS (solid, "n"),
+ ALIAS (pixbuf, "pixbuf"),
+ ALIAS (rpixbuf, "rpixbuf"),
+ ALIAS (unknown, "unknown"),
+
+#undef ENTRY
+#undef ALIAS
+};
-/* 4bpp formats */
- case PIXMAN_a4: return "a4";
- case PIXMAN_r1g2b1: return "r1g2b1";
- case PIXMAN_b1g2r1: return "b1g2r1";
- case PIXMAN_a1r1g1b1: return "a1r1g1b1";
- case PIXMAN_a1b1g1r1: return "a1b1g1r1";
+pixman_format_code_t
+format_from_string (const char *s)
+{
+ int i;
- case PIXMAN_c4: return "c4";
- case PIXMAN_g4: return "g4";
+ for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
+ {
+ const format_entry_t *ent = &format_list[i];
-/* 1bpp formats */
- case PIXMAN_a1: return "a1";
+ if (strcasecmp (ent->name, s) == 0)
+ return ent->format;
+ }
- case PIXMAN_g1: return "g1";
+ return PIXMAN_null;
+}
-/* YUV formats */
- case PIXMAN_yuy2: return "yuy2";
- case PIXMAN_yv12: return "yv12";
- };
+static void
+emit (const char *s, int *n_chars)
+{
+ *n_chars += printf ("%s,", s);
+ if (*n_chars > 60)
+ {
+ printf ("\n ");
+ *n_chars = 0;
+ }
+ else
+ {
+ printf (" ");
+ (*n_chars)++;
+ }
+}
- /* Fake formats.
- *
- * This is separate switch to prevent GCC from complaining
- * that the values are not in the pixman_format_code_t enum.
- */
- switch ((uint32_t)format)
+void
+list_formats (void)
+{
+ int n_chars;
+ int i;
+
+ printf ("Formats:\n ");
+
+ n_chars = 0;
+ for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
{
- case PIXMAN_null: return "null";
- case PIXMAN_solid: return "solid";
- case PIXMAN_pixbuf: return "pixbuf";
- case PIXMAN_rpixbuf: return "rpixbuf";
- case PIXMAN_unknown: return "unknown";
- };
+ const format_entry_t *ent = &format_list[i];
+
+ if (ent->is_alias)
+ continue;
+
+ emit (ent->name, &n_chars);
+ }
+
+ printf ("\n\n");
+}
+
+void
+list_operators (void)
+{
+ char short_name [128] = { 0 };
+ int i, n_chars;
+
+ printf ("Operators:\n ");
+
+ n_chars = 0;
+ for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
+ {
+ const operator_entry_t *ent = &op_list[i];
+ int j;
+
+ if (ent->is_alias)
+ continue;
+
+ snprintf (short_name, sizeof (short_name) - 1, "%s",
+ ent->name + strlen ("PIXMAN_OP_"));
+
+ for (j = 0; short_name[j] != '\0'; ++j)
+ short_name[j] = tolower (short_name[j]);
+
+ emit (short_name, &n_chars);
+ }
+
+ printf ("\n\n");
+}
+
+pixman_op_t
+operator_from_string (const char *s)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
+ {
+ const operator_entry_t *ent = &op_list[i];
+
+ if (ent->is_alias)
+ {
+ if (strcasecmp (ent->name, s) == 0)
+ return ent->op;
+ }
+ else
+ {
+ if (strcasecmp (ent->name + strlen ("PIXMAN_OP_"), s) == 0)
+ return ent->op;
+ }
+ }
+
+ return PIXMAN_OP_NONE;
+}
+
+const char *
+operator_name (pixman_op_t op)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
+ {
+ const operator_entry_t *ent = &op_list[i];
+
+ if (ent->op == op)
+ return ent->name;
+ }
+
+ return "<unknown operator>";
+}
+
+const char *
+format_name (pixman_format_code_t format)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_LENGTH (format_list); ++i)
+ {
+ const format_entry_t *ent = &format_list[i];
+
+ if (ent->format == format)
+ return ent->name;
+ }
return "<unknown format>";
};
diff --git a/pixman/test/utils.h b/pixman/test/utils.h
index 6804334bb..fc105243b 100644
--- a/pixman/test/utils.h
+++ b/pixman/test/utils.h
@@ -187,6 +187,18 @@ convert_linear_to_srgb (double component);
void
initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb);
+pixman_format_code_t
+format_from_string (const char *s);
+
+void
+list_formats (void);
+
+void
+list_operators (void);
+
+pixman_op_t
+operator_from_string (const char *s);
+
const char *
operator_name (pixman_op_t op);
diff --git a/xkbcomp/listing.c b/xkbcomp/listing.c
index 945f7f6ca..322cbf240 100644
--- a/xkbcomp/listing.c
+++ b/xkbcomp/listing.c
@@ -108,6 +108,7 @@ SOFTWARE.
#endif
#ifdef WIN32
+# define WIN32_LEAN_AND_MEAN
# include <X11/Xwindows.h>
# define FileName(file) file.cFileName
# undef TEXT
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac
index 280c3692a..606298bdc 100644
--- a/xorg-server/configure.ac
+++ b/xorg-server/configure.ac
@@ -782,7 +782,7 @@ LIBXSHMFENCE="xshmfence >= 1.1"
dnl Required modules
XPROTO="xproto >= 7.0.26"
-RANDRPROTO="randrproto >= 1.4.0"
+RANDRPROTO="randrproto >= 1.5.0"
RENDERPROTO="renderproto >= 0.11"
XEXTPROTO="xextproto >= 7.2.99.901"
INPUTPROTO="inputproto >= 2.3"
diff --git a/xorg-server/glamor/glamor.c b/xorg-server/glamor/glamor.c
index 017266a85..6f4f30927 100644
--- a/xorg-server/glamor/glamor.c
+++ b/xorg-server/glamor/glamor.c
@@ -34,6 +34,7 @@
#include <stdlib.h>
#include "glamor_priv.h"
+#include "mipict.h"
DevPrivateKeyRec glamor_screen_private_key;
DevPrivateKeyRec glamor_pixmap_private_key;
@@ -59,26 +60,34 @@ glamor_get_drawable_pixmap(DrawablePtr drawable)
return (PixmapPtr) drawable;
}
+static void
+glamor_init_pixmap_private_small(PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv)
+{
+ pixmap_priv->box.x1 = 0;
+ pixmap_priv->box.x2 = pixmap->drawable.width;
+ pixmap_priv->box.y1 = 0;
+ pixmap_priv->box.y2 = pixmap->drawable.height;
+ pixmap_priv->block_w = pixmap->drawable.width;
+ pixmap_priv->block_h = pixmap->drawable.height;
+ pixmap_priv->block_hcnt = 1;
+ pixmap_priv->block_wcnt = 1;
+ pixmap_priv->box_array = &pixmap_priv->box;
+ pixmap_priv->fbo_array = &pixmap_priv->fbo;
+}
+
_X_EXPORT void
glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
{
glamor_pixmap_private *pixmap_priv;
- glamor_screen_private *glamor_priv =
- glamor_get_screen_private(pixmap->drawable.pScreen);
pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
&glamor_pixmap_private_key);
if (pixmap_priv == NULL) {
pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
glamor_set_pixmap_private(pixmap, pixmap_priv);
- pixmap_priv->base.pixmap = pixmap;
- pixmap_priv->base.glamor_priv = glamor_priv;
}
pixmap_priv->type = type;
- pixmap_priv->base.box.x1 = 0;
- pixmap_priv->base.box.x2 = pixmap->drawable.width;
- pixmap_priv->base.box.y1 = 0;
- pixmap_priv->base.box.y2 = pixmap->drawable.height;
+ glamor_init_pixmap_private_small(pixmap, pixmap_priv);
}
_X_EXPORT void
@@ -93,9 +102,9 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
glamor_priv = glamor_get_screen_private(screen);
pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (pixmap_priv->base.fbo) {
+ if (pixmap_priv->fbo) {
fbo = glamor_pixmap_detach_fbo(pixmap_priv);
- glamor_destroy_fbo(fbo);
+ glamor_destroy_fbo(glamor_priv, fbo);
}
format = gl_iformat_for_pixmap(pixmap);
@@ -119,10 +128,10 @@ glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap)
glamor_priv = glamor_get_screen_private(screen_pixmap->drawable.pScreen);
pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
- glamor_priv->screen_fbo = pixmap_priv->base.fbo->fb;
+ glamor_priv->screen_fbo = pixmap_priv->fbo->fb;
- pixmap_priv->base.fbo->width = screen_pixmap->drawable.width;
- pixmap_priv->base.fbo->height = screen_pixmap->drawable.height;
+ pixmap_priv->fbo->width = screen_pixmap->drawable.width;
+ pixmap_priv->fbo->height = screen_pixmap->drawable.height;
}
uint32_t
@@ -133,7 +142,7 @@ glamor_get_pixmap_texture(PixmapPtr pixmap)
if (pixmap_priv->type != GLAMOR_TEXTURE_ONLY)
return 0;
- return pixmap_priv->base.fbo->tex;
+ return pixmap_priv->fbo->tex;
}
PixmapPtr
@@ -141,7 +150,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
unsigned int usage)
{
PixmapPtr pixmap;
- glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY;
glamor_pixmap_private *pixmap_priv;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_pixmap_fbo *fbo = NULL;
@@ -169,38 +177,26 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
}
glamor_set_pixmap_private(pixmap, pixmap_priv);
- if (usage == GLAMOR_CREATE_PIXMAP_MAP)
- type = GLAMOR_MEMORY_MAP;
-
- pixmap_priv->base.pixmap = pixmap;
- pixmap_priv->base.glamor_priv = glamor_priv;
-
format = gl_iformat_for_pixmap(pixmap);
pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
+ pixmap_priv->type = GLAMOR_TEXTURE_ONLY;
+
if (usage == GLAMOR_CREATE_PIXMAP_NO_TEXTURE) {
- pixmap_priv->type = GLAMOR_TEXTURE_ONLY;
- pixmap_priv->base.box.x1 = 0;
- pixmap_priv->base.box.y1 = 0;
- pixmap_priv->base.box.x2 = w;
- pixmap_priv->base.box.y2 = h;
+ glamor_init_pixmap_private_small(pixmap, pixmap_priv);
return pixmap;
}
- else if (type == GLAMOR_MEMORY_MAP || usage == GLAMOR_CREATE_NO_LARGE ||
+ else if (usage == GLAMOR_CREATE_NO_LARGE ||
glamor_check_fbo_size(glamor_priv, w, h))
{
- pixmap_priv->type = type;
- pixmap_priv->base.box.x1 = 0;
- pixmap_priv->base.box.y1 = 0;
- pixmap_priv->base.box.x2 = w;
- pixmap_priv->base.box.y2 = h;
+ glamor_init_pixmap_private_small(pixmap, pixmap_priv);
fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
} else {
int tile_size = glamor_priv->max_fbo_size;
- DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n", pixmap, w, h, tile_size);
- pixmap_priv->type = GLAMOR_TEXTURE_LARGE;
+ DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n",
+ pixmap, w, h, tile_size);
fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage,
tile_size, tile_size, pixmap_priv);
}
@@ -305,6 +301,35 @@ glamor_create_screen_resources(ScreenPtr screen)
return ret;
}
+static Bool
+glamor_check_instruction_count(int gl_version)
+{
+ GLint max_native_alu_instructions;
+
+ /* Avoid using glamor if the reported instructions limit is too low,
+ * as this would cause glamor to fallback on sw due to large shaders
+ * which ends up being unbearably slow.
+ */
+ if (gl_version < 30) {
+ if (!epoxy_has_gl_extension("GL_ARB_fragment_program")) {
+ ErrorF("GL_ARB_fragment_program required\n");
+ return FALSE;
+ }
+
+ glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB,
+ GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB,
+ &max_native_alu_instructions);
+ if (max_native_alu_instructions < GLAMOR_MIN_ALU_INSTRUCTIONS) {
+ LogMessage(X_WARNING,
+ "glamor requires at least %d instructions (%d reported)\n",
+ GLAMOR_MIN_ALU_INSTRUCTIONS, max_native_alu_instructions);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
/** Set up glamor for an already-configured GL context. */
Bool
glamor_init(ScreenPtr screen, unsigned int flags)
@@ -312,10 +337,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_screen_private *glamor_priv;
int gl_version;
int max_viewport_size[2];
-
-#ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(screen);
-#endif
+
if (flags & ~GLAMOR_VALID_FLAGS) {
ErrorF("glamor_init: Invalid flags %x\n", flags);
return FALSE;
@@ -384,6 +407,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
ErrorF("Require OpenGL version 2.1 or later.\n");
goto fail;
}
+
+ if (!glamor_check_instruction_count(gl_version))
+ goto fail;
} else {
if (gl_version < 20) {
ErrorF("Require Open GLES2.0 or later.\n");
@@ -411,6 +437,14 @@ glamor_init(ScreenPtr screen, unsigned int flags)
epoxy_has_gl_extension("GL_ARB_buffer_storage");
glamor_priv->has_nv_texture_barrier =
epoxy_has_gl_extension("GL_NV_texture_barrier");
+ glamor_priv->has_unpack_subimage =
+ glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP ||
+ epoxy_gl_version() >= 30 ||
+ epoxy_has_gl_extension("GL_EXT_unpack_subimage");
+ glamor_priv->has_pack_subimage =
+ glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP ||
+ epoxy_gl_version() >= 30 ||
+ epoxy_has_gl_extension("GL_NV_pack_subimage");
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size);
@@ -442,54 +476,48 @@ glamor_init(ScreenPtr screen, unsigned int flags)
if (!glamor_font_init(screen))
goto fail;
- if (flags & GLAMOR_USE_SCREEN) {
+ glamor_priv->saved_procs.block_handler = screen->BlockHandler;
+ screen->BlockHandler = _glamor_block_handler;
- glamor_priv->saved_procs.block_handler = screen->BlockHandler;
- screen->BlockHandler = _glamor_block_handler;
+ glamor_priv->saved_procs.create_gc = screen->CreateGC;
+ screen->CreateGC = glamor_create_gc;
- glamor_priv->saved_procs.create_gc = screen->CreateGC;
- screen->CreateGC = glamor_create_gc;
+ glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap;
+ screen->CreatePixmap = glamor_create_pixmap;
- glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap;
- screen->CreatePixmap = glamor_create_pixmap;
+ glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
+ screen->DestroyPixmap = glamor_destroy_pixmap;
- glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
- screen->DestroyPixmap = glamor_destroy_pixmap;
+ glamor_priv->saved_procs.get_spans = screen->GetSpans;
+ screen->GetSpans = glamor_get_spans;
- glamor_priv->saved_procs.get_spans = screen->GetSpans;
- screen->GetSpans = glamor_get_spans;
+ glamor_priv->saved_procs.get_image = screen->GetImage;
+ screen->GetImage = glamor_get_image;
- glamor_priv->saved_procs.get_image = screen->GetImage;
- screen->GetImage = glamor_get_image;
+ glamor_priv->saved_procs.change_window_attributes =
+ screen->ChangeWindowAttributes;
+ screen->ChangeWindowAttributes = glamor_change_window_attributes;
- glamor_priv->saved_procs.change_window_attributes =
- screen->ChangeWindowAttributes;
- screen->ChangeWindowAttributes = glamor_change_window_attributes;
+ glamor_priv->saved_procs.copy_window = screen->CopyWindow;
+ screen->CopyWindow = glamor_copy_window;
- glamor_priv->saved_procs.copy_window = screen->CopyWindow;
- screen->CopyWindow = glamor_copy_window;
+ glamor_priv->saved_procs.bitmap_to_region = screen->BitmapToRegion;
+ screen->BitmapToRegion = glamor_bitmap_to_region;
- glamor_priv->saved_procs.bitmap_to_region = screen->BitmapToRegion;
- screen->BitmapToRegion = glamor_bitmap_to_region;
- }
-#ifdef RENDER
- if (flags & GLAMOR_USE_PICTURE_SCREEN) {
- glamor_priv->saved_procs.composite = ps->Composite;
- ps->Composite = glamor_composite;
+ glamor_priv->saved_procs.composite = ps->Composite;
+ ps->Composite = glamor_composite;
- glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
- ps->Trapezoids = glamor_trapezoids;
+ glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
+ ps->Trapezoids = glamor_trapezoids;
- glamor_priv->saved_procs.triangles = ps->Triangles;
- ps->Triangles = glamor_triangles;
+ glamor_priv->saved_procs.triangles = ps->Triangles;
+ ps->Triangles = glamor_triangles;
- glamor_priv->saved_procs.addtraps = ps->AddTraps;
- ps->AddTraps = glamor_add_traps;
-
- }
+ glamor_priv->saved_procs.addtraps = ps->AddTraps;
+ ps->AddTraps = glamor_add_traps;
glamor_priv->saved_procs.composite_rects = ps->CompositeRects;
- ps->CompositeRects = glamor_composite_rectangles;
+ ps->CompositeRects = miCompositeRects;
glamor_priv->saved_procs.glyphs = ps->Glyphs;
ps->Glyphs = glamor_glyphs;
@@ -503,13 +531,14 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_priv->saved_procs.destroy_picture = ps->DestroyPicture;
ps->DestroyPicture = glamor_destroy_picture;
glamor_init_composite_shaders(screen);
-#endif
+
glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
screen->SetWindowPixmap = glamor_set_window_pixmap;
glamor_init_vbo(screen);
glamor_init_pixmap_fbo(screen);
glamor_init_finish_access_shaders(screen);
+
#ifdef GLAMOR_GRADIENT_SHADER
glamor_init_gradient_shader(screen);
#endif
@@ -532,9 +561,7 @@ glamor_release_screen_priv(ScreenPtr screen)
glamor_screen_private *glamor_priv;
glamor_priv = glamor_get_screen_private(screen);
-#ifdef RENDER
glamor_fini_composite_shaders(screen);
-#endif
glamor_fini_vbo(screen);
glamor_fini_pixmap_fbo(screen);
glamor_fini_finish_access_shaders(screen);
@@ -560,8 +587,8 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
else {
if (old_priv == NULL)
return;
-
- glamor_pixmap_destroy_fbo(old_priv);
+ glamor_pixmap_destroy_fbo(glamor_get_screen_private(pixmap->drawable.pScreen),
+ old_priv);
free(old_priv);
}
@@ -573,43 +600,34 @@ glamor_close_screen(ScreenPtr screen)
{
glamor_screen_private *glamor_priv;
PixmapPtr screen_pixmap;
- int flags;
-
-#ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(screen);
-#endif
+
glamor_priv = glamor_get_screen_private(screen);
- flags = glamor_priv->flags;
glamor_sync_close(screen);
glamor_glyphs_fini(screen);
screen->CloseScreen = glamor_priv->saved_procs.close_screen;
screen->CreateScreenResources =
glamor_priv->saved_procs.create_screen_resources;
- if (flags & GLAMOR_USE_SCREEN) {
-
- screen->CreateGC = glamor_priv->saved_procs.create_gc;
- screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
- screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
- screen->GetSpans = glamor_priv->saved_procs.get_spans;
- screen->ChangeWindowAttributes =
- glamor_priv->saved_procs.change_window_attributes;
- screen->CopyWindow = glamor_priv->saved_procs.copy_window;
- screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
- screen->BlockHandler = glamor_priv->saved_procs.block_handler;
- }
-#ifdef RENDER
- if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) {
- ps->Composite = glamor_priv->saved_procs.composite;
- ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
- ps->Triangles = glamor_priv->saved_procs.triangles;
- ps->CreatePicture = glamor_priv->saved_procs.create_picture;
- }
+ screen->CreateGC = glamor_priv->saved_procs.create_gc;
+ screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
+ screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
+ screen->GetSpans = glamor_priv->saved_procs.get_spans;
+ screen->ChangeWindowAttributes =
+ glamor_priv->saved_procs.change_window_attributes;
+ screen->CopyWindow = glamor_priv->saved_procs.copy_window;
+ screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
+ screen->BlockHandler = glamor_priv->saved_procs.block_handler;
+
+ ps->Composite = glamor_priv->saved_procs.composite;
+ ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
+ ps->Triangles = glamor_priv->saved_procs.triangles;
+ ps->CreatePicture = glamor_priv->saved_procs.create_picture;
ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
ps->Glyphs = glamor_priv->saved_procs.glyphs;
ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph;
screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
-#endif
+
screen_pixmap = screen->GetScreenPixmap(screen);
glamor_set_pixmap_private(screen_pixmap, NULL);
@@ -658,7 +676,7 @@ glamor_fd_from_pixmap(ScreenPtr screen,
return -1;
return glamor_egl_dri3_fd_name_from_tex(screen,
pixmap,
- pixmap_priv->base.fbo->tex,
+ pixmap_priv->fbo->tex,
FALSE, stride, size);
default:
break;
@@ -683,7 +701,7 @@ glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
return -1;
return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen,
pixmap,
- pixmap_priv->base.fbo->tex,
+ pixmap_priv->fbo->tex,
TRUE, stride, size);
default:
break;
diff --git a/xorg-server/glamor/glamor.h b/xorg-server/glamor/glamor.h
index 206158c02..d07182d9e 100644
--- a/xorg-server/glamor/glamor.h
+++ b/xorg-server/glamor/glamor.h
@@ -53,25 +53,15 @@ struct glamor_context;
*/
typedef enum glamor_pixmap_type {
GLAMOR_MEMORY,
- GLAMOR_MEMORY_MAP,
GLAMOR_TEXTURE_DRM,
- GLAMOR_SEPARATE_TEXTURE,
GLAMOR_DRM_ONLY,
GLAMOR_TEXTURE_ONLY,
- GLAMOR_TEXTURE_LARGE,
- GLAMOR_TEXTURE_PACK
} glamor_pixmap_type_t;
#define GLAMOR_EGL_EXTERNAL_BUFFER 3
-#define GLAMOR_INVERTED_Y_AXIS 1 /* compat stub */
-#define GLAMOR_USE_SCREEN (1 << 1)
-#define GLAMOR_USE_PICTURE_SCREEN (1 << 2)
-#define GLAMOR_USE_EGL_SCREEN (1 << 3)
-#define GLAMOR_NO_DRI3 (1 << 4)
-#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS \
- | GLAMOR_USE_SCREEN \
- | GLAMOR_USE_PICTURE_SCREEN \
- | GLAMOR_USE_EGL_SCREEN \
+#define GLAMOR_USE_EGL_SCREEN (1 << 0)
+#define GLAMOR_NO_DRI3 (1 << 1)
+#define GLAMOR_VALID_FLAGS (GLAMOR_USE_EGL_SCREEN \
| GLAMOR_NO_DRI3)
/* @glamor_init: Initialize glamor internal data structure.
@@ -79,23 +69,13 @@ typedef enum glamor_pixmap_type {
* @screen: Current screen pointer.
* @flags: Please refer the flags description above.
*
- * @GLAMOR_USE_SCREEN:
- * If running in an pre-existing X environment, and the
- * gl context is GLX, then you should set this bit and
- * let the glamor to handle all the screen related
- * functions such as GC ops and CreatePixmap/DestroyPixmap.
- *
- * @GLAMOR_USE_PICTURE_SCREEN:
- * If don't use any other underlying DDX driver to handle
- * the picture related rendering functions, please set this
- * bit on. Otherwise, clear this bit. And then it is the DDX
- * driver's responsibility to determine how/when to jump to
- * glamor's picture compositing path.
- *
* @GLAMOR_USE_EGL_SCREEN:
* If you are using EGL layer, then please set this bit
* on, otherwise, clear it.
*
+ * @GLAMOR_NO_DRI3
+ * Disable the built-in DRI3 support
+ *
* This function initializes necessary internal data structure
* for glamor. And before calling into this function, the OpenGL
* environment should be ready. Should be called before any real
@@ -142,7 +122,6 @@ extern _X_EXPORT Bool glamor_destroy_pixmap(PixmapPtr pixmap);
#define GLAMOR_CREATE_PIXMAP_CPU 0x100
#define GLAMOR_CREATE_PIXMAP_FIXUP 0x101
#define GLAMOR_CREATE_FBO_NO_FBO 0x103
-#define GLAMOR_CREATE_PIXMAP_MAP 0x104
#define GLAMOR_CREATE_NO_LARGE 0x105
#define GLAMOR_CREATE_PIXMAP_NO_TEXTURE 0x106
@@ -326,146 +305,6 @@ extern _X_EXPORT void glamor_destroy_gc(GCPtr gc);
extern Bool _X_EXPORT glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
extern void _X_EXPORT glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region);
-/* Glamor rendering/drawing functions with XXX_nf.
- * nf means no fallback within glamor internal if possible. If glamor
- * fail to accelerate the operation, glamor will return a false, and the
- * caller need to implement fallback method. Return a true means the
- * rendering request get done successfully. */
-extern _X_EXPORT Bool glamor_fill_spans_nf(DrawablePtr drawable,
- GCPtr gc,
- int n, DDXPointPtr points,
- int *widths, int sorted);
-
-extern _X_EXPORT Bool glamor_poly_fill_rect_nf(DrawablePtr drawable,
- GCPtr gc,
- int nrect, xRectangle *prect);
-
-extern _X_EXPORT Bool glamor_put_image_nf(DrawablePtr drawable,
- GCPtr gc, int depth, int x, int y,
- int w, int h, int left_pad,
- int image_format, char *bits);
-
-extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src,
- DrawablePtr dst,
- GCPtr gc,
- BoxPtr box,
- int nbox,
- int dx,
- int dy,
- Bool reverse,
- Bool upsidedown, Pixel bitplane,
- void *closure);
-
-extern _X_EXPORT Bool glamor_copy_nf(DrawablePtr src,
- DrawablePtr dst,
- GCPtr gc,
- BoxPtr box,
- int nbox,
- int dx,
- int dy,
- Bool reverse,
- Bool upsidedown, Pixel bitplane,
- void *closure);
-
-extern _X_EXPORT Bool glamor_composite_nf(CARD8 op,
- PicturePtr source,
- PicturePtr mask,
- PicturePtr dest,
- INT16 x_source,
- INT16 y_source,
- INT16 x_mask,
- INT16 y_mask,
- INT16 x_dest, INT16 y_dest,
- CARD16 width, CARD16 height);
-
-extern _X_EXPORT Bool glamor_trapezoids_nf(CARD8 op,
- PicturePtr src, PicturePtr dst,
- PictFormatPtr mask_format,
- INT16 x_src, INT16 y_src,
- int ntrap, xTrapezoid *traps);
-
-extern _X_EXPORT Bool glamor_glyphs_nf(CARD8 op,
- PicturePtr src,
- PicturePtr dst,
- PictFormatPtr mask_format,
- INT16 x_src,
- INT16 y_src, int nlist,
- GlyphListPtr list, GlyphPtr *glyphs);
-
-extern _X_EXPORT Bool glamor_triangles_nf(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc, INT16 ySrc,
- int ntris, xTriangle *tris);
-
-extern _X_EXPORT void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
-
-extern _X_EXPORT Bool glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc,
- char *src, DDXPointPtr points,
- int *widths, int n, int sorted);
-
-extern _X_EXPORT Bool glamor_get_spans_nf(DrawablePtr drawable, int wmax,
- DDXPointPtr points, int *widths,
- int count, char *dst);
-
-extern _X_EXPORT Bool glamor_composite_rects_nf(CARD8 op,
- PicturePtr pDst,
- xRenderColor *color,
- int nRect, xRectangle *rects);
-
-extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y,
- int w, int h, unsigned int format,
- unsigned long planeMask, char *d);
-
-extern _X_EXPORT Bool glamor_add_traps_nf(PicturePtr pPicture,
- INT16 x_off,
- INT16 y_off, int ntrap,
- xTrap *traps);
-
-extern _X_EXPORT Bool glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst,
- GCPtr pGC, int srcx, int srcy, int w,
- int h, int dstx, int dsty,
- unsigned long bitPlane,
- RegionPtr *pRegion);
-
-extern _X_EXPORT Bool glamor_image_glyph_blt_nf(DrawablePtr pDrawable,
- GCPtr pGC, int x, int y,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- void *pglyphBase);
-
-extern _X_EXPORT Bool glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- void *pglyphBase);
-
-extern _X_EXPORT Bool glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap,
- DrawablePtr pDrawable, int w, int h,
- int x, int y);
-
-extern _X_EXPORT Bool glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr ppt);
-
-extern _X_EXPORT Bool glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC,
- int nseg, xSegment *pSeg);
-
-extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc,
- int mode, int n, DDXPointPtr points);
-
-extern _X_EXPORT Bool glamor_poly_text8_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, char *chars, int *final_pos);
-
-extern _X_EXPORT Bool glamor_poly_text16_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, unsigned short *chars, int *final_pos);
-
-extern _X_EXPORT Bool glamor_image_text8_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, char *chars);
-
-extern _X_EXPORT Bool glamor_image_text16_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, unsigned short *chars);
-
#define HAS_GLAMOR_TEXT 1
#ifdef GLAMOR_FOR_XORG
diff --git a/xorg-server/glamor/glamor_addtraps.c b/xorg-server/glamor/glamor_addtraps.c
index fdc0f4232..7ad9f3000 100644
--- a/xorg-server/glamor/glamor_addtraps.c
+++ b/xorg-server/glamor/glamor_addtraps.c
@@ -28,34 +28,13 @@
#include "glamor_priv.h"
-static Bool
-_glamor_add_traps(PicturePtr pPicture,
- INT16 x_off,
- INT16 y_off, int ntrap, xTrap *traps, Bool fallback)
+void
+glamor_add_traps(PicturePtr pPicture,
+ INT16 x_off,
+ INT16 y_off, int ntrap, xTrap *traps)
{
- if (!fallback
- && (!pPicture->pDrawable
- || glamor_ddx_fallback_check_pixmap(pPicture->pDrawable)))
- return FALSE;
-
if (glamor_prepare_access_picture(pPicture, GLAMOR_ACCESS_RW)) {
fbAddTraps(pPicture, x_off, y_off, ntrap, traps);
}
glamor_finish_access_picture(pPicture);
-
- return TRUE;
-}
-
-void
-glamor_add_traps(PicturePtr pPicture,
- INT16 x_off, INT16 y_off, int ntrap, xTrap *traps)
-{
- _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, TRUE);
-}
-
-Bool
-glamor_add_traps_nf(PicturePtr pPicture,
- INT16 x_off, INT16 y_off, int ntrap, xTrap *traps)
-{
- return _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, FALSE);
}
diff --git a/xorg-server/glamor/glamor_compositerects.c b/xorg-server/glamor/glamor_compositerects.c
index 3b6b2ed07..e188d8a3f 100644
--- a/xorg-server/glamor/glamor_compositerects.c
+++ b/xorg-server/glamor/glamor_compositerects.c
@@ -246,7 +246,7 @@ glamor_composite_rectangles(CARD8 op,
goto done;
}
else {
- if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) {
+ if (_X_LIKELY(glamor_pixmap_priv_is_small(priv))) {
int error;
source = CreateSolidPicture(0, color, &error);
@@ -254,7 +254,7 @@ glamor_composite_rectangles(CARD8 op,
goto done;
if (glamor_composite_clipped_region(op, source,
NULL, dst,
- NULL, NULL, priv,
+ NULL, NULL, pixmap,
&region, 0, 0, 0, 0, 0, 0))
goto done;
}
diff --git a/xorg-server/glamor/glamor_copy.c b/xorg-server/glamor/glamor_copy.c
index 3320935f0..75fe8a700 100644
--- a/xorg-server/glamor/glamor_copy.c
+++ b/xorg-server/glamor/glamor_copy.c
@@ -42,7 +42,7 @@ use_copyarea(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
glBindTexture(GL_TEXTURE_2D, src->tex);
glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
- glUniform2f(prog->fill_size_uniform, src->width, src->height);
+ glUniform2f(prog->fill_size_inv_uniform, 1.0f/src->width, 1.0f/src->height);
return TRUE;
}
@@ -51,7 +51,7 @@ static const glamor_facet glamor_facet_copyarea = {
"copy_area",
.vs_vars = "attribute vec2 primitive;\n",
.vs_exec = (GLAMOR_POS(gl_Position, primitive.xy)
- " fill_pos = (fill_offset + primitive.xy) / fill_size;\n"),
+ " fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"),
.fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n",
.locations = glamor_program_location_fill,
.use = use_copyarea,
@@ -71,7 +71,7 @@ use_copyplane(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
glBindTexture(GL_TEXTURE_2D, src->tex);
glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
- glUniform2f(prog->fill_size_uniform, src->width, src->height);
+ glUniform2f(prog->fill_size_inv_uniform, 1.0f/src->width, 1.0f/src->height);
glamor_set_color(dst, gc->fgPixel, prog->fg_uniform);
glamor_set_color(dst, gc->bgPixel, prog->bg_uniform);
@@ -134,7 +134,7 @@ static const glamor_facet glamor_facet_copyplane = {
.version = 130,
.vs_vars = "attribute vec2 primitive;\n",
.vs_exec = (GLAMOR_POS(gl_Position, (primitive.xy))
- " fill_pos = (fill_offset + primitive.xy) / fill_size;\n"),
+ " fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"),
.fs_exec = (" uvec4 bits = uvec4(round(texture2D(sampler, fill_pos) * bitmul));\n"
" if ((bits & bitplane) != uvec4(0,0,0,0))\n"
" gl_FragColor = fg;\n"
@@ -315,7 +315,6 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
struct copy_args args;
glamor_program *prog;
const glamor_facet *copy_facet;
- Bool set_scissor;
int n;
glamor_make_current(glamor_priv);
@@ -367,9 +366,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y);
- set_scissor = src_priv->type == GLAMOR_TEXTURE_LARGE;
- if (set_scissor)
- glEnable(GL_SCISSOR_TEST);
+ glEnable(GL_SCISSOR_TEST);
glamor_pixmap_loop(src_priv, src_box_x, src_box_y) {
BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_x, src_box_y);
@@ -385,30 +382,20 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
glamor_set_destination_drawable(dst, dst_box_x, dst_box_y, FALSE, FALSE,
prog->matrix_uniform, &dst_off_x, &dst_off_y);
- if (set_scissor)
- glScissor(dst_off_x - args.dx,
- dst_off_y - args.dy,
- src_box->x2 - src_box->x1,
- src_box->y2 - src_box->y1);
-
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
- glDrawArrays(GL_QUADS, 0, nbox * 4);
- else {
- int i;
- for (i = 0; i < nbox; i++)
- glDrawArrays(GL_TRIANGLE_FAN, i*4, 4);
- }
+ glScissor(dst_off_x - args.dx,
+ dst_off_y - args.dy,
+ src_box->x2 - src_box->x1,
+ src_box->y2 - src_box->y1);
+
+ glamor_glDrawArrays_GL_QUADS(glamor_priv, nbox);
}
}
- if (set_scissor)
- glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_SCISSOR_TEST);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glDisable(GL_COLOR_LOGIC_OP);
return TRUE;
bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
return FALSE;
}
@@ -452,7 +439,6 @@ glamor_copy_fbo_fbo_temp(DrawablePtr src,
if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy))
goto bail_ctx;
- glDisable(GL_COLOR_LOGIC_OP);
/* Find the size of the area to copy
*/
@@ -521,7 +507,6 @@ bail:
return FALSE;
bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
return FALSE;
}
@@ -709,39 +694,3 @@ glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_regio
RegionUninit(&dst_region);
}
-
-Bool
-glamor_copy_n_to_n_nf(DrawablePtr src,
- DrawablePtr dst,
- GCPtr gc,
- BoxPtr box,
- int nbox,
- int dx,
- int dy,
- Bool reverse,
- Bool upsidedown, Pixel bitplane,
- void *closure)
-{
- if (glamor_copy_gl(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure))
- return TRUE;
- if (glamor_ddx_fallback_check_pixmap(src) && glamor_ddx_fallback_check_pixmap(dst))
- return FALSE;
- glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
- return TRUE;
-}
-
-Bool
-glamor_copy_plane_nf(DrawablePtr src, DrawablePtr dst, GCPtr gc,
- int srcx, int srcy, int w, int h, int dstx, int dsty,
- unsigned long bitplane, RegionPtr *region)
-{
- if (glamor_ddx_fallback_check_pixmap(src) &&
- glamor_ddx_fallback_check_pixmap(dst) &&
- glamor_ddx_fallback_check_gc(gc))
- return FALSE;
-
- *region = glamor_copy_plane(src, dst, gc,
- srcx, srcy, w, h, dstx, dsty,
- bitplane);
- return TRUE;
-}
diff --git a/xorg-server/glamor/glamor_core.c b/xorg-server/glamor/glamor_core.c
index 737b2744b..55174541f 100644
--- a/xorg-server/glamor/glamor_core.c
+++ b/xorg-server/glamor/glamor_core.c
@@ -43,9 +43,9 @@ glamor_get_drawable_location(const DrawablePtr drawable)
glamor_screen_private *glamor_priv =
glamor_get_screen_private(drawable->pScreen);
if (pixmap_priv == NULL ||
- pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED)
+ pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED)
return 'm';
- if (pixmap_priv->base.fbo->fb == glamor_priv->screen_fbo)
+ if (pixmap_priv->fbo->fb == glamor_priv->screen_fbo)
return 's';
else
return 'f';
@@ -173,46 +173,48 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
const char *fs_source =
"void main()\n"
"{\n"
+ " vec4 color = texture2D(sampler, source_texture);\n"
" if (revert == REVERT_NONE) \n"
" { \n"
" if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING)) \n"
- " gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
+ " gl_FragColor = color.bgra;\n"
" else \n"
- " gl_FragColor = texture2D(sampler, source_texture).rgba;\n"
+ " gl_FragColor = color.rgba;\n"
" } \n"
" else \n"
" { \n"
" if (swap_rb == SWAP_DOWNLOADING) \n"
- " gl_FragColor = texture2D(sampler, source_texture).argb;\n"
+ " gl_FragColor = color.argb;\n"
" else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
- " gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
+ " gl_FragColor = color.abgr;\n"
" else if (swap_rb == SWAP_UPLOADING)\n"
- " gl_FragColor = texture2D(sampler, source_texture).gbar;\n"
+ " gl_FragColor = color.gbar;\n"
" else if (swap_rb == SWAP_NONE_UPLOADING)\n"
- " gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
+ " gl_FragColor = color.abgr;\n"
" } \n"
"}\n";
const char *set_alpha_source =
"void main()\n"
"{\n"
+ " vec4 color = texture2D(sampler, source_texture);\n"
" if (revert == REVERT_NONE) \n"
" { \n"
" if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING)) \n"
- " gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
+ " gl_FragColor = vec4(color.bgr, 1);\n"
" else \n"
- " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
+ " gl_FragColor = vec4(color.rgb, 1);\n"
" } \n"
" else \n"
" { \n"
" if (swap_rb == SWAP_DOWNLOADING) \n"
- " gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n"
+ " gl_FragColor = vec4(1, color.rgb);\n"
" else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
- " gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
+ " gl_FragColor = vec4(1, color.bgr);\n"
" else if (swap_rb == SWAP_UPLOADING)\n"
- " gl_FragColor = vec4(texture2D(sampler, source_texture).gba, 1);\n"
+ " gl_FragColor = vec4(color.gba, 1);\n"
" else if (swap_rb == SWAP_NONE_UPLOADING)\n"
- " gl_FragColor = vec4(texture2D(sampler, source_texture).abg, 1);\n"
+ " gl_FragColor = vec4(color.abg, 1);\n"
" } \n"
"}\n";
GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
diff --git a/xorg-server/glamor/glamor_dash.c b/xorg-server/glamor/glamor_dash.c
index e8f60fa10..4281ff0a8 100644
--- a/xorg-server/glamor/glamor_dash.c
+++ b/xorg-server/glamor/glamor_dash.c
@@ -159,11 +159,11 @@ glamor_dash_setup(DrawablePtr drawable, GCPtr gc)
&glamor_priv->on_off_dash_line_progs,
&glamor_facet_on_off_dash_lines);
if (!prog)
- goto bail_ctx;
+ goto bail;
break;
case LineDoubleDash:
if (gc->fillStyle != FillSolid)
- goto bail_ctx;
+ goto bail;
prog = &glamor_priv->double_dash_line_prog;
@@ -171,32 +171,30 @@ glamor_dash_setup(DrawablePtr drawable, GCPtr gc)
if (!glamor_build_program(screen, prog,
&glamor_facet_double_dash_lines,
NULL))
- goto bail_ctx;
+ goto bail;
}
if (!glamor_use_program(pixmap, gc, prog, NULL))
- goto bail_ctx;
+ goto bail;
glamor_set_color(pixmap, gc->fgPixel, prog->fg_uniform);
glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform);
break;
default:
- goto bail_ctx;
+ goto bail;
}
/* Set the dash pattern as texture 1 */
glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, dash_priv->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, dash_priv->fbo->tex);
glUniform1i(prog->dash_uniform, 1);
glUniform1f(prog->dash_length_uniform, dash_pixmap->drawable.width);
return prog;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return NULL;
}
@@ -230,7 +228,6 @@ glamor_dash_loop(DrawablePtr drawable, GCPtr gc, glamor_program *prog,
}
glDisable(GL_SCISSOR_TEST);
- glDisable(GL_COLOR_LOGIC_OP);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
}
diff --git a/xorg-server/glamor/glamor_egl.c b/xorg-server/glamor/glamor_egl.c
index 113450c8d..6033780f8 100644
--- a/xorg-server/glamor/glamor_egl.c
+++ b/xorg-server/glamor/glamor_egl.c
@@ -239,7 +239,6 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
"Failed to create textured screen.");
return FALSE;
}
-
glamor_set_screen_pixmap(screen_pixmap, NULL);
return TRUE;
}
@@ -272,7 +271,7 @@ glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image)
glamor_get_pixmap_private(pixmap);
EGLImageKHR old;
- old = pixmap_priv->base.image;
+ old = pixmap_priv->image;
if (old) {
ScreenPtr screen = pixmap->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
@@ -280,7 +279,7 @@ glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image)
eglDestroyImageKHR(glamor_egl->display, old);
}
- pixmap_priv->base.image = image;
+ pixmap_priv->image = image;
}
Bool
@@ -420,7 +419,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
glamor_make_current(glamor_priv);
- image = pixmap_priv->base.image;
+ image = pixmap_priv->image;
if (!image) {
image = eglCreateImageKHR(glamor_egl->display,
glamor_egl->context,
@@ -536,7 +535,7 @@ glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
struct glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
- if (pixmap_priv && pixmap_priv->base.image) {
+ if (pixmap_priv && pixmap_priv->image) {
ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
struct glamor_egl_screen_private *glamor_egl =
glamor_egl_get_screen_private(scrn);
@@ -545,8 +544,8 @@ glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
* a texture. we must call glFlush to make sure the
* operation on that texture has been done.*/
glamor_block_handler(pixmap->drawable.pScreen);
- eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image);
- pixmap_priv->base.image = NULL;
+ eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
+ pixmap_priv->image = NULL;
}
}
@@ -561,13 +560,12 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
glamor_pixmap_exchange_fbos(front, back);
- temp = back_priv->base.image;
- back_priv->base.image = front_priv->base.image;
- front_priv->base.image = temp;
+ temp = back_priv->image;
+ back_priv->image = front_priv->image;
+ front_priv->image = temp;
glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
-
}
void
@@ -589,8 +587,8 @@ glamor_egl_close_screen(ScreenPtr screen)
screen_pixmap = screen->GetScreenPixmap(screen);
pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
- eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image);
- pixmap_priv->base.image = NULL;
+ eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
+ pixmap_priv->image = NULL;
screen->CloseScreen = glamor_egl->saved_close_screen;
diff --git a/xorg-server/glamor/glamor_fbo.c b/xorg-server/glamor/glamor_fbo.c
index 8d73e4765..ea0e80102 100644
--- a/xorg-server/glamor/glamor_fbo.c
+++ b/xorg-server/glamor/glamor_fbo.c
@@ -72,7 +72,7 @@ cache_hbucket(int size)
static glamor_pixmap_fbo *
glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
- int w, int h, GLenum format, int flag)
+ int w, int h, GLenum format)
{
struct xorg_list *cache;
glamor_pixmap_fbo *fbo_entry, *ret_fbo = NULL;
@@ -87,33 +87,18 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
cache = &glamor_priv->fbo_cache[n_format]
[cache_wbucket(w)]
[cache_hbucket(h)];
- if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) {
- xorg_list_for_each_entry(fbo_entry, cache, list) {
- if (fbo_entry->width >= w && fbo_entry->height >= h) {
-
- DEBUGF("Request w %d h %d format %x \n", w, h, format);
- DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
- fbo_entry, fbo_entry->width, fbo_entry->height,
- fbo_entry->fb, fbo_entry->tex);
- xorg_list_del(&fbo_entry->list);
- ret_fbo = fbo_entry;
- break;
- }
- }
- }
- else {
- xorg_list_for_each_entry(fbo_entry, cache, list) {
- if (fbo_entry->width == w && fbo_entry->height == h) {
-
- DEBUGF("Request w %d h %d format %x \n", w, h, format);
- DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
- fbo_entry, fbo_entry->width, fbo_entry->height,
- fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
- assert(format == fbo_entry->format);
- xorg_list_del(&fbo_entry->list);
- ret_fbo = fbo_entry;
- break;
- }
+
+ xorg_list_for_each_entry(fbo_entry, cache, list) {
+ if (fbo_entry->width == w && fbo_entry->height == h) {
+
+ DEBUGF("Request w %d h %d format %x \n", w, h, format);
+ DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
+ fbo_entry, fbo_entry->width, fbo_entry->height,
+ fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
+ assert(format == fbo_entry->format);
+ xorg_list_del(&fbo_entry->list);
+ ret_fbo = fbo_entry;
+ break;
}
}
@@ -127,9 +112,10 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
}
static void
-glamor_purge_fbo(glamor_pixmap_fbo *fbo)
+glamor_purge_fbo(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo)
{
- glamor_make_current(fbo->glamor_priv);
+ glamor_make_current(glamor_priv);
if (fbo->fb)
glDeleteFramebuffers(1, &fbo->fb);
@@ -142,7 +128,8 @@ glamor_purge_fbo(glamor_pixmap_fbo *fbo)
}
static void
-glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
+glamor_pixmap_fbo_cache_put(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo)
{
struct xorg_list *cache;
int n_format;
@@ -154,32 +141,33 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
n_format = cache_format(fbo->format);
if (fbo->fb == 0 || fbo->external || n_format == -1
- || fbo->glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
- fbo->glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX;
- glamor_fbo_expire(fbo->glamor_priv);
- glamor_purge_fbo(fbo);
+ || glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
+ glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX;
+ glamor_fbo_expire(glamor_priv);
+ glamor_purge_fbo(glamor_priv, fbo);
return;
}
- cache = &fbo->glamor_priv->fbo_cache[n_format]
+ cache = &glamor_priv->fbo_cache[n_format]
[cache_wbucket(fbo->width)]
[cache_hbucket(fbo->height)];
DEBUGF
("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n",
fbo, cache, fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
- fbo->glamor_priv->fbo_cache_watermark += fbo->width * fbo->height;
+ glamor_priv->fbo_cache_watermark += fbo->width * fbo->height;
xorg_list_add(&fbo->list, cache);
- fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
+ fbo->expire = glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
#endif
}
static int
-glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
+glamor_pixmap_ensure_fb(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo)
{
int status, err = 0;
- glamor_make_current(fbo->glamor_priv);
+ glamor_make_current(glamor_priv);
if (fbo->fb == 0)
glGenFramebuffers(1, &fbo->fb);
@@ -239,22 +227,14 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
fbo->height = h;
fbo->external = FALSE;
fbo->format = format;
- fbo->glamor_priv = glamor_priv;
-
- if (flag == GLAMOR_CREATE_PIXMAP_MAP) {
- glamor_make_current(glamor_priv);
- glGenBuffers(1, &fbo->pbo);
- goto done;
- }
if (flag != GLAMOR_CREATE_FBO_NO_FBO) {
- if (glamor_pixmap_ensure_fb(fbo) != 0) {
- glamor_purge_fbo(fbo);
+ if (glamor_pixmap_ensure_fb(glamor_priv, fbo) != 0) {
+ glamor_purge_fbo(glamor_priv, fbo);
fbo = NULL;
}
}
- done:
return fbo;
}
@@ -280,7 +260,7 @@ glamor_fbo_expire(glamor_screen_private *glamor_priv)
xorg_list_del(&fbo_entry->list);
DEBUGF("cache %p fbo %p expired %d current %d \n", cache,
fbo_entry, fbo_entry->expire, glamor_priv->tick);
- glamor_purge_fbo(fbo_entry);
+ glamor_purge_fbo(glamor_priv, fbo_entry);
}
}
@@ -317,16 +297,17 @@ glamor_fini_pixmap_fbo(ScreenPtr screen)
xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache,
list) {
xorg_list_del(&fbo_entry->list);
- glamor_purge_fbo(fbo_entry);
+ glamor_purge_fbo(glamor_priv, fbo_entry);
}
}
}
void
-glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
+glamor_destroy_fbo(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo)
{
xorg_list_del(&fbo->list);
- glamor_pixmap_fbo_cache_put(fbo);
+ glamor_pixmap_fbo_cache_put(glamor_priv, fbo);
}
@@ -348,7 +329,6 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
glamor_make_current(glamor_priv);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
@@ -363,26 +343,15 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
{
glamor_pixmap_fbo *fbo;
GLint tex = 0;
- int cache_flag;
if (flag == GLAMOR_CREATE_FBO_NO_FBO)
goto new_fbo;
- if (flag == GLAMOR_CREATE_PIXMAP_MAP)
- goto no_tex;
-
- /* Tiling from textures requires exact pixmap sizes. As we don't
- * know which pixmaps will be used as tiles, just allocate
- * everything at the requested size
- */
- cache_flag = GLAMOR_CACHE_EXACT_SIZE;
-
- fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h, format, cache_flag);
+ fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h, format);
if (fbo)
return fbo;
new_fbo:
tex = _glamor_create_tex(glamor_priv, w, h, format);
- no_tex:
fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
return fbo;
@@ -399,9 +368,9 @@ _glamor_create_fbo_array(glamor_screen_private *glamor_priv,
glamor_pixmap_fbo **fbo_array;
BoxPtr box_array;
int i, j;
- glamor_pixmap_private_large_t *priv;
+ glamor_pixmap_private *priv;
- priv = &pixmap_priv->large;
+ priv = pixmap_priv;
block_wcnt = (w + block_w - 1) / block_w;
block_hcnt = (h + block_h - 1) / block_h;
@@ -438,7 +407,7 @@ _glamor_create_fbo_array(glamor_screen_private *glamor_priv,
format,
GLAMOR_CREATE_PIXMAP_FIXUP);
else
- fbo_array[i * block_wcnt + j] = priv->base.fbo;
+ fbo_array[i * block_wcnt + j] = priv->fbo;
if (fbo_array[i * block_wcnt + j] == NULL)
goto cleanup;
}
@@ -454,7 +423,7 @@ _glamor_create_fbo_array(glamor_screen_private *glamor_priv,
cleanup:
for (i = 0; i < block_wcnt * block_hcnt; i++)
if ((fbo_array)[i])
- glamor_destroy_fbo((fbo_array)[i]);
+ glamor_destroy_fbo(glamor_priv, (fbo_array)[i]);
free(box_array);
free(fbo_array);
return NULL;
@@ -468,8 +437,8 @@ glamor_create_fbo_array(glamor_screen_private *glamor_priv,
int block_w, int block_h,
glamor_pixmap_private *pixmap_priv)
{
- pixmap_priv->large.block_w = block_w;
- pixmap_priv->large.block_h = block_h;
+ pixmap_priv->block_w = block_w;
+ pixmap_priv->block_h = block_h;
return _glamor_create_fbo_array(glamor_priv, w, h, format, flag,
block_w, block_h, pixmap_priv, 0);
}
@@ -482,11 +451,11 @@ glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
if (pixmap_priv == NULL)
return NULL;
- fbo = pixmap_priv->base.fbo;
+ fbo = pixmap_priv->fbo;
if (fbo == NULL)
return NULL;
- pixmap_priv->base.fbo = NULL;
+ pixmap_priv->fbo = NULL;
return fbo;
}
@@ -498,47 +467,44 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (pixmap_priv->base.fbo)
+ if (pixmap_priv->fbo)
return;
- pixmap_priv->base.fbo = fbo;
+ pixmap_priv->fbo = fbo;
switch (pixmap_priv->type) {
- case GLAMOR_TEXTURE_LARGE:
case GLAMOR_TEXTURE_ONLY:
case GLAMOR_TEXTURE_DRM:
- pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL;
+ pixmap_priv->gl_fbo = GLAMOR_FBO_NORMAL;
if (fbo->tex != 0)
- pixmap_priv->base.gl_tex = 1;
+ pixmap_priv->gl_tex = 1;
else {
/* XXX For the Xephyr only, may be broken now. */
- pixmap_priv->base.gl_tex = 0;
+ pixmap_priv->gl_tex = 0;
}
- case GLAMOR_MEMORY_MAP:
pixmap->devPrivate.ptr = NULL;
- break;
default:
break;
}
}
void
-glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv)
+glamor_pixmap_destroy_fbo(glamor_screen_private *glamor_priv,
+ glamor_pixmap_private *priv)
{
glamor_pixmap_fbo *fbo;
- if (priv->type == GLAMOR_TEXTURE_LARGE) {
+ if (glamor_pixmap_priv_is_large(priv)) {
int i;
- glamor_pixmap_private_large_t *large = &priv->large;
- for (i = 0; i < large->block_wcnt * large->block_hcnt; i++)
- glamor_destroy_fbo(large->fbo_array[i]);
- free(large->fbo_array);
+ for (i = 0; i < priv->block_wcnt * priv->block_hcnt; i++)
+ glamor_destroy_fbo(glamor_priv, priv->fbo_array[i]);
+ free(priv->fbo_array);
}
else {
fbo = glamor_pixmap_detach_fbo(priv);
if (fbo)
- glamor_destroy_fbo(fbo);
+ glamor_destroy_fbo(glamor_priv, fbo);
}
}
@@ -551,7 +517,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (pixmap_priv->base.fbo == NULL) {
+ if (pixmap_priv->fbo == NULL) {
fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
pixmap->drawable.height, format, flag);
@@ -562,13 +528,13 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
}
else {
/* We do have a fbo, but it may lack of fb or tex. */
- if (!pixmap_priv->base.fbo->tex)
- pixmap_priv->base.fbo->tex =
+ if (!pixmap_priv->fbo->tex)
+ pixmap_priv->fbo->tex =
_glamor_create_tex(glamor_priv, pixmap->drawable.width,
pixmap->drawable.height, format);
- if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->base.fbo->fb == 0)
- if (glamor_pixmap_ensure_fb(pixmap_priv->base.fbo) != 0)
+ if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0)
+ if (glamor_pixmap_ensure_fb(glamor_priv, pixmap_priv->fbo) != 0)
return FALSE;
}
@@ -583,7 +549,7 @@ glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back)
front_priv = glamor_get_pixmap_private(front);
back_priv = glamor_get_pixmap_private(back);
- temp_fbo = front_priv->base.fbo;
- front_priv->base.fbo = back_priv->base.fbo;
- back_priv->base.fbo = temp_fbo;
+ temp_fbo = front_priv->fbo;
+ front_priv->fbo = back_priv->fbo;
+ back_priv->fbo = temp_fbo;
}
diff --git a/xorg-server/glamor/glamor_font.c b/xorg-server/glamor/glamor_font.c
index 0ca91fa2e..cc0fecf7a 100644
--- a/xorg-server/glamor/glamor_font.c
+++ b/xorg-server/glamor/glamor_font.c
@@ -97,7 +97,6 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, glamor_font->texture_id);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
diff --git a/xorg-server/glamor/glamor_glyphblt.c b/xorg-server/glamor/glamor_glyphblt.c
index 73b1df51e..1791f6dca 100644
--- a/xorg-server/glamor/glamor_glyphblt.c
+++ b/xorg-server/glamor/glamor_glyphblt.c
@@ -60,7 +60,7 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
&glamor_priv->poly_glyph_blt_progs,
&glamor_facet_poly_glyph_blt);
if (!prog)
- goto bail_ctx;
+ goto bail;
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
@@ -138,12 +138,9 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
}
}
- glDisable(GL_COLOR_LOGIC_OP);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
@@ -160,32 +157,6 @@ glamor_poly_glyph_blt(DrawablePtr drawable, GCPtr gc,
ppci, pglyph_base);
}
-Bool
-glamor_poly_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
- int start_x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, void *pglyph_base)
-{
- if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci,
- pglyph_base))
- return TRUE;
- if (glamor_ddx_fallback_check_pixmap(drawable) &&
- glamor_ddx_fallback_check_gc(gc)) {
- return FALSE;
- }
- miPolyGlyphBlt(drawable, gc, start_x, y, nglyph,
- ppci, pglyph_base);
- return TRUE;
-}
-
-Bool
-glamor_image_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
- int start_x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, void *pglyph_base)
-{
- miImageGlyphBlt(drawable, gc, start_x, y, nglyph, ppci, pglyph_base);
- return TRUE;
-}
-
static Bool
glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
DrawablePtr drawable, int w, int h, int x, int y)
@@ -217,7 +188,7 @@ glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
&glamor_priv->poly_glyph_blt_progs,
&glamor_facet_poly_glyph_blt);
if (!prog)
- goto bail_ctx;
+ goto bail;
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
@@ -256,12 +227,9 @@ glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
glDrawArrays(GL_POINTS, 0, num_points);
}
- glDisable(GL_COLOR_LOGIC_OP);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
@@ -275,21 +243,3 @@ glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
}
-
-Bool
-glamor_push_pixels_nf(GCPtr gc, PixmapPtr bitmap,
- DrawablePtr drawable, int w, int h, int x, int y)
-{
- if (glamor_push_pixels_gl(gc, bitmap, drawable, w, h, x, y))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable) &&
- glamor_ddx_fallback_check_pixmap(&bitmap->drawable) &&
- glamor_ddx_fallback_check_gc(gc))
- {
- return FALSE;
- }
-
- miPushPixels(gc, bitmap, drawable, w, h, x, y);
- return TRUE;
-}
diff --git a/xorg-server/glamor/glamor_glyphs.c b/xorg-server/glamor/glamor_glyphs.c
index 1f1362487..2cf0c7d16 100644
--- a/xorg-server/glamor/glamor_glyphs.c
+++ b/xorg-server/glamor/glamor_glyphs.c
@@ -1166,11 +1166,9 @@ static void
glamor_glyphs_flush_mask(struct glyphs_flush_mask_arg *arg)
{
if (arg->buffer->count > 0) {
-#ifdef RENDER
glamor_composite_glyph_rects(PictOpAdd, arg->buffer->source,
NULL, arg->mask,
arg->buffer->count, arg->buffer->rects);
-#endif
}
arg->buffer->count = 0;
arg->buffer->source = NULL;
@@ -1769,15 +1767,3 @@ glamor_glyphs(CARD8 op,
_glamor_glyphs(op, src, dst, mask_format, x_src,
y_src, nlist, list, glyphs, TRUE);
}
-
-Bool
-glamor_glyphs_nf(CARD8 op,
- PicturePtr src,
- PicturePtr dst,
- PictFormatPtr mask_format,
- INT16 x_src,
- INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr *glyphs)
-{
- return _glamor_glyphs(op, src, dst, mask_format, x_src,
- y_src, nlist, list, glyphs, FALSE);
-}
diff --git a/xorg-server/glamor/glamor_gradient.c b/xorg-server/glamor/glamor_gradient.c
index 4ded89dcd..8ea645efc 100644
--- a/xorg-server/glamor/glamor_gradient.c
+++ b/xorg-server/glamor/glamor_gradient.c
@@ -32,8 +32,6 @@
#include "glamor_priv.h"
-#ifdef RENDER
-
#define LINEAR_SMALL_STOPS (6 + 2)
#define LINEAR_LARGE_STOPS (16 + 2)
@@ -684,9 +682,9 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
return 0;
}
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+ glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
- pixmap_priv_get_dest_scale(pixmap_priv, xscale, yscale);
+ pixmap_priv_get_dest_scale(pixmap, pixmap_priv, xscale, yscale);
DEBUGF("xscale = %f, yscale = %f,"
" x_source = %d, y_source = %d, width = %d, height = %d\n",
@@ -995,6 +993,8 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
vertices, tex_vertices, 0))
goto GRADIENT_FAIL;
+ glamor_set_alu(screen, GXcopy);
+
/* Set all the stops and colors to shader. */
if (stops_count > RADIAL_SMALL_STOPS) {
stop_colors = malloc(4 * stops_count * sizeof(float));
@@ -1311,6 +1311,8 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
vertices, tex_vertices, 1))
goto GRADIENT_FAIL;
+ glamor_set_alu(screen, GXcopy);
+
/* Normalize the PTs. */
glamor_set_normalize_pt(xscale, yscale,
pixman_fixed_to_double(src_picture->pSourcePict->
@@ -1473,5 +1475,3 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
}
#endif /* End of GLAMOR_GRADIENT_SHADER */
-
-#endif /* End of RENDER */
diff --git a/xorg-server/glamor/glamor_image.c b/xorg-server/glamor/glamor_image.c
index b38b41212..5633da647 100644
--- a/xorg-server/glamor/glamor_image.c
+++ b/xorg-server/glamor/glamor_image.c
@@ -102,19 +102,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
}
-Bool
-glamor_put_image_nf(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
- int w, int h, int leftPad, int format, char *bits)
-{
- if (glamor_put_image_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits))
- return TRUE;
- if (glamor_ddx_fallback_check_pixmap(drawable) &&
- glamor_ddx_fallback_check_gc(gc))
- return FALSE;
- glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
- return TRUE;
-}
-
static Bool
glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h,
unsigned int format, unsigned long plane_mask, char *d)
@@ -163,17 +150,3 @@ glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
return;
glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d);
}
-
-Bool
-glamor_get_image_nf(DrawablePtr drawable, int x, int y, int w, int h,
- unsigned int format, unsigned long plane_mask, char *d)
-{
- if (glamor_get_image_gl(drawable, x, y, w, h, format, plane_mask, d))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable))
- return FALSE;
-
- glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d);
- return TRUE;
-}
diff --git a/xorg-server/glamor/glamor_largepixmap.c b/xorg-server/glamor/glamor_largepixmap.c
index 9b2458453..391f376e9 100644
--- a/xorg-server/glamor/glamor_largepixmap.c
+++ b/xorg-server/glamor/glamor_largepixmap.c
@@ -2,10 +2,10 @@
#include "glamor_priv.h"
-static inline glamor_pixmap_private_large_t *
+static inline glamor_pixmap_private *
__glamor_large(glamor_pixmap_private *pixmap_priv) {
- assert(pixmap_priv->type == GLAMOR_TEXTURE_LARGE);
- return &pixmap_priv->large;
+ assert(glamor_pixmap_priv_is_large(pixmap_priv));
+ return pixmap_priv;
}
/**
@@ -150,12 +150,13 @@ __glamor_compute_clipped_regions(int block_w,
*/
glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
+glamor_compute_clipped_regions_ext(PixmapPtr pixmap,
RegionPtr region,
int *n_region,
int inner_block_w, int inner_block_h,
int reverse, int upsidedown)
{
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_pixmap_clipped_regions *clipped_regions, *inner_regions,
*result_regions;
int i, j, x, y, k, inner_n_regions;
@@ -166,7 +167,7 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
DEBUGF("ext called \n");
- if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
+ if (glamor_pixmap_priv_is_small(pixmap_priv)) {
clipped_regions = calloc(1, sizeof(*clipped_regions));
if (clipped_regions == NULL) {
*n_region = 0;
@@ -176,24 +177,22 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
clipped_regions[0].block_idx = 0;
RegionCopy(clipped_regions[0].region, region);
*n_region = 1;
- block_w = pixmap_priv->base.pixmap->drawable.width;
- block_h = pixmap_priv->base.pixmap->drawable.height;
+ block_w = pixmap->drawable.width;
+ block_h = pixmap->drawable.height;
box_array = &small_box;
small_box.x1 = small_box.y1 = 0;
small_box.x2 = block_w;
small_box.y2 = block_h;
}
else {
- glamor_pixmap_private_large_t *priv = __glamor_large(pixmap_priv);
+ glamor_pixmap_private *priv = __glamor_large(pixmap_priv);
clipped_regions = __glamor_compute_clipped_regions(priv->block_w,
priv->block_h,
priv->block_wcnt,
0, 0,
- priv->base.pixmap->
- drawable.width,
- priv->base.pixmap->
- drawable.height,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
region, n_region,
reverse, upsidedown);
@@ -336,7 +335,8 @@ _glamor_largepixmap_reflect_fixup(short *xy1, short *xy2, int wh)
*
*/
static glamor_pixmap_clipped_regions *
-_glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
+_glamor_compute_clipped_regions(PixmapPtr pixmap,
+ glamor_pixmap_private *pixmap_priv,
RegionPtr region, int *n_region,
int repeat_type, int is_transform,
int reverse, int upsidedown)
@@ -352,10 +352,10 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
int right_shift = 0;
int down_shift = 0;
int x_center_shift = 0, y_center_shift = 0;
- glamor_pixmap_private_large_t *priv;
+ glamor_pixmap_private *priv;
DEBUGRegionPrint(region);
- if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
+ if (glamor_pixmap_priv_is_small(pixmap_priv)) {
clipped_regions = calloc(1, sizeof(*clipped_regions));
clipped_regions[0].region = RegionCreate(NULL, 1);
clipped_regions[0].block_idx = 0;
@@ -366,8 +366,8 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
priv = __glamor_large(pixmap_priv);
- pixmap_width = priv->base.pixmap->drawable.width;
- pixmap_height = priv->base.pixmap->drawable.height;
+ pixmap_width = pixmap->drawable.width;
+ pixmap_height = pixmap->drawable.height;
if (repeat_type == 0 || repeat_type == RepeatPad) {
RegionPtr saved_region = NULL;
@@ -385,10 +385,8 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
priv->block_h,
priv->block_wcnt,
0, 0,
- priv->base.pixmap->
- drawable.width,
- priv->base.pixmap->
- drawable.height,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
region, n_region,
reverse, upsidedown);
if (saved_region)
@@ -670,11 +668,13 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
}
glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region,
+glamor_compute_clipped_regions(PixmapPtr pixmap,
+ RegionPtr region,
int *n_region, int repeat_type,
int reverse, int upsidedown)
{
- return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type,
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+ return _glamor_compute_clipped_regions(pixmap, priv, region, n_region, repeat_type,
0, reverse, upsidedown);
}
@@ -682,12 +682,13 @@ glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region,
* by default. Or just use region32 for repeat cases?
**/
glamor_pixmap_clipped_regions *
-glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
+glamor_compute_transform_clipped_regions(PixmapPtr pixmap,
struct pixman_transform *transform,
RegionPtr region, int *n_region,
int dx, int dy, int repeat_type,
int reverse, int upsidedown)
{
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
BoxPtr temp_extent;
struct pixman_box32 temp_box;
struct pixman_box16 short_box;
@@ -714,8 +715,8 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
temp_box.x1 = 0;
if (temp_box.y1 < 0)
temp_box.y1 = 0;
- temp_box.x2 = MIN(temp_box.x2, priv->base.pixmap->drawable.width);
- temp_box.y2 = MIN(temp_box.y2, priv->base.pixmap->drawable.height);
+ temp_box.x2 = MIN(temp_box.x2, pixmap->drawable.width);
+ temp_box.y2 = MIN(temp_box.y2, pixmap->drawable.height);
}
/* Now copy back the box32 to a box16 box. */
short_box.x1 = temp_box.x1;
@@ -725,7 +726,8 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
RegionInitBoxes(temp_region, &short_box, 1);
DEBUGF("copy to temp source region \n");
DEBUGRegionPrint(temp_region);
- ret = _glamor_compute_clipped_regions(priv,
+ ret = _glamor_compute_clipped_regions(pixmap,
+ priv,
temp_region,
n_region,
repeat_type, 1, reverse, upsidedown);
@@ -747,7 +749,8 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
* if the clipped result cross the region boundary.
*/
static void
-glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
+glamor_merge_clipped_regions(PixmapPtr pixmap,
+ glamor_pixmap_private *pixmap_priv,
int repeat_type,
glamor_pixmap_clipped_regions *clipped_regions,
int *n_regions, int *need_clean_fbo)
@@ -760,11 +763,11 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
int overlap;
int i;
int pixmap_width, pixmap_height;
- glamor_pixmap_private_large_t *priv;
+ glamor_pixmap_private *priv;
priv = __glamor_large(pixmap_priv);
- pixmap_width = priv->base.pixmap->drawable.width;
- pixmap_height = priv->base.pixmap->drawable.height;
+ pixmap_width = pixmap->drawable.width;
+ pixmap_height =pixmap->drawable.height;
temp_region = RegionCreate(NULL, 4);
for (i = 0; i < *n_regions; i++) {
@@ -784,10 +787,10 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
DEBUGF("%d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2,
temp_box.y2);
temp_pixmap =
- glamor_create_pixmap(priv->base.pixmap->drawable.pScreen,
+ glamor_create_pixmap(pixmap->drawable.pScreen,
temp_box.x2 - temp_box.x1,
temp_box.y2 - temp_box.y1,
- priv->base.pixmap->drawable.depth,
+ pixmap->drawable.depth,
GLAMOR_CREATE_PIXMAP_FIXUP);
if (temp_pixmap == NULL) {
assert(0);
@@ -795,7 +798,7 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
}
temp_priv = glamor_get_pixmap_private(temp_pixmap);
- assert(temp_priv->type != GLAMOR_TEXTURE_LARGE);
+ assert(glamor_pixmap_priv_is_small(temp_priv));
priv->box = temp_box;
if (temp_extent->x1 >= 0 && temp_extent->x2 <= pixmap_width
@@ -808,7 +811,7 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
copy_box.y2 = temp_extent->y2 - temp_extent->y1;
dx = temp_extent->x1;
dy = temp_extent->y1;
- glamor_copy(&priv->base.pixmap->drawable,
+ glamor_copy(&pixmap->drawable,
&temp_pixmap->drawable,
NULL, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
// glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
@@ -840,7 +843,7 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
copy_box.x1, copy_box.y1, copy_box.x2,
copy_box.y2, dx, dy);
- glamor_copy(&priv->base.pixmap->drawable,
+ glamor_copy(&pixmap->drawable,
&temp_pixmap->drawable,
NULL, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
@@ -855,7 +858,7 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
RegionDestroy(clipped_regions[i].region);
RegionDestroy(temp_region);
priv->box = temp_box;
- priv->base.fbo = glamor_pixmap_detach_fbo(temp_priv);
+ priv->fbo = glamor_pixmap_detach_fbo(temp_priv);
DEBUGF("priv box x1 %d y1 %d x2 %d y2 %d \n",
priv->box.x1, priv->box.y1, priv->box.x2, priv->box.y2);
glamor_destroy_pixmap(temp_pixmap);
@@ -920,10 +923,10 @@ glamor_get_transform_block_size(struct pixman_transform *transform,
return TRUE;
}
-#define VECTOR_FROM_POINT(p, x, y) \
+#define VECTOR_FROM_POINT(p, x, y) do {\
p.v[0] = x; \
p.v[1] = y; \
- p.v[2] = 1.0;
+ p.v[2] = 1.0; } while (0)
void
glamor_get_transform_extent_from_box(struct pixman_box32 *box,
struct pixman_transform *transform)
@@ -933,12 +936,12 @@ glamor_get_transform_extent_from_box(struct pixman_box32 *box,
struct pixman_f_transform ftransform;
- VECTOR_FROM_POINT(p0, box->x1, box->y1)
- VECTOR_FROM_POINT(p1, box->x2, box->y1)
- VECTOR_FROM_POINT(p2, box->x2, box->y2)
- VECTOR_FROM_POINT(p3, box->x1, box->y2)
+ VECTOR_FROM_POINT(p0, box->x1, box->y1);
+ VECTOR_FROM_POINT(p1, box->x2, box->y1);
+ VECTOR_FROM_POINT(p2, box->x2, box->y2);
+ VECTOR_FROM_POINT(p3, box->x1, box->y2);
- pixman_f_transform_from_pixman_transform(&ftransform, transform);
+ pixman_f_transform_from_pixman_transform(&ftransform, transform);
pixman_f_transform_point(&ftransform, &p0);
pixman_f_transform_point(&ftransform, &p1);
pixman_f_transform_point(&ftransform, &p2);
@@ -966,7 +969,8 @@ glamor_get_transform_extent_from_box(struct pixman_box32 *box,
}
static void
-_glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
+_glamor_process_transformed_clipped_region(PixmapPtr pixmap,
+ glamor_pixmap_private *priv,
int repeat_type,
glamor_pixmap_clipped_regions *
clipped_regions, int *n_regions,
@@ -976,7 +980,7 @@ _glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
if (*n_regions != 1) {
/* Merge all source regions into one region. */
- glamor_merge_clipped_regions(priv, repeat_type,
+ glamor_merge_clipped_regions(pixmap, priv, repeat_type,
clipped_regions, n_regions,
need_clean_fbo);
}
@@ -990,22 +994,22 @@ _glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
int rem;
temp_box = RegionExtents(clipped_regions[0].region);
- modulus(temp_box->x1, priv->base.pixmap->drawable.width, rem);
- shift_x = (temp_box->x1 - rem) / priv->base.pixmap->drawable.width;
- modulus(temp_box->y1, priv->base.pixmap->drawable.height, rem);
- shift_y = (temp_box->y1 - rem) / priv->base.pixmap->drawable.height;
+ modulus(temp_box->x1, pixmap->drawable.width, rem);
+ shift_x = (temp_box->x1 - rem) / pixmap->drawable.width;
+ modulus(temp_box->y1, pixmap->drawable.height, rem);
+ shift_y = (temp_box->y1 - rem) / pixmap->drawable.height;
if (shift_x != 0) {
__glamor_large(priv)->box.x1 +=
- shift_x * priv->base.pixmap->drawable.width;
+ shift_x * pixmap->drawable.width;
__glamor_large(priv)->box.x2 +=
- shift_x * priv->base.pixmap->drawable.width;
+ shift_x * pixmap->drawable.width;
}
if (shift_y != 0) {
__glamor_large(priv)->box.y1 +=
- shift_y * priv->base.pixmap->drawable.height;
+ shift_y * pixmap->drawable.height;
__glamor_large(priv)->box.y2 +=
- shift_y * priv->base.pixmap->drawable.height;
+ shift_y * pixmap->drawable.height;
}
}
}
@@ -1016,9 +1020,9 @@ glamor_composite_largepixmap_region(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
- glamor_pixmap_private *source_pixmap_priv,
- glamor_pixmap_private *mask_pixmap_priv,
- glamor_pixmap_private *dest_pixmap_priv,
+ PixmapPtr source_pixmap,
+ PixmapPtr mask_pixmap,
+ PixmapPtr dest_pixmap,
RegionPtr region, Bool force_clip,
INT16 x_source,
INT16 y_source,
@@ -1027,6 +1031,11 @@ glamor_composite_largepixmap_region(CARD8 op,
INT16 x_dest, INT16 y_dest,
CARD16 width, CARD16 height)
{
+ ScreenPtr screen = dest_pixmap->drawable.pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ glamor_pixmap_private *source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+ glamor_pixmap_private *mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+ glamor_pixmap_private *dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
glamor_pixmap_clipped_regions *clipped_dest_regions;
glamor_pixmap_clipped_regions *clipped_source_regions;
glamor_pixmap_clipped_regions *clipped_mask_regions;
@@ -1056,12 +1065,12 @@ glamor_composite_largepixmap_region(CARD8 op,
else
mask_repeat_type = RepeatNone;
- if (dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ if (glamor_pixmap_priv_is_large(dest_pixmap_priv)) {
dest_block_width = __glamor_large(dest_pixmap_priv)->block_w;
dest_block_height = __glamor_large(dest_pixmap_priv)->block_h;
} else {
- dest_block_width = dest_pixmap_priv->base.pixmap->drawable.width;
- dest_block_height = dest_pixmap_priv->base.pixmap->drawable.height;
+ dest_block_width = dest_pixmap->drawable.width;
+ dest_block_height = dest_pixmap->drawable.height;
}
fixed_block_width = dest_block_width;
fixed_block_height = dest_block_height;
@@ -1087,7 +1096,7 @@ glamor_composite_largepixmap_region(CARD8 op,
*/
if (source_pixmap_priv
&& source->transform
- && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ && glamor_pixmap_priv_is_large(source_pixmap_priv)) {
int source_transformed_block_width, source_transformed_block_height;
if (!glamor_get_transform_block_size(source->transform,
@@ -1109,7 +1118,7 @@ glamor_composite_largepixmap_region(CARD8 op,
}
if (mask_pixmap_priv
- && mask->transform && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ && mask->transform && glamor_pixmap_priv_is_large(mask_pixmap_priv)) {
int mask_transformed_block_width, mask_transformed_block_height;
if (!glamor_get_transform_block_size(mask->transform,
@@ -1134,12 +1143,12 @@ glamor_composite_largepixmap_region(CARD8 op,
if (force_clip || fixed_block_width < dest_block_width
|| fixed_block_height < dest_block_height)
clipped_dest_regions =
- glamor_compute_clipped_regions_ext(dest_pixmap_priv, region,
+ glamor_compute_clipped_regions_ext(dest_pixmap, region,
&n_dest_regions,
fixed_block_width,
fixed_block_height, 0, 0);
else
- clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap_priv,
+ clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap,
region,
&n_dest_regions,
0, 0, 0);
@@ -1147,7 +1156,7 @@ glamor_composite_largepixmap_region(CARD8 op,
if (source_pixmap_priv
&& (source_pixmap_priv == dest_pixmap_priv ||
source_pixmap_priv == mask_pixmap_priv)
- && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ && glamor_pixmap_priv_is_large(source_pixmap_priv)) {
/* XXX self-copy... */
need_free_source_pixmap_priv = source_pixmap_priv;
source_pixmap_priv = malloc(sizeof(*source_pixmap_priv));
@@ -1163,12 +1172,12 @@ glamor_composite_largepixmap_region(CARD8 op,
glamor_set_pixmap_fbo_current(dest_pixmap_priv,
clipped_dest_regions[i].block_idx);
if (source_pixmap_priv &&
- source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ glamor_pixmap_priv_is_large(source_pixmap_priv)) {
if (!source->transform && source_repeat_type != RepeatPad) {
RegionTranslate(clipped_dest_regions[i].region,
x_source - x_dest, y_source - y_dest);
clipped_source_regions =
- glamor_compute_clipped_regions(source_pixmap_priv,
+ glamor_compute_clipped_regions(source_pixmap,
clipped_dest_regions[i].
region, &n_source_regions,
source_repeat_type, 0, 0);
@@ -1176,7 +1185,7 @@ glamor_composite_largepixmap_region(CARD8 op,
}
else {
clipped_source_regions =
- glamor_compute_transform_clipped_regions(source_pixmap_priv,
+ glamor_compute_transform_clipped_regions(source_pixmap,
source->transform,
clipped_dest_regions
[i].region,
@@ -1193,7 +1202,7 @@ glamor_composite_largepixmap_region(CARD8 op,
}
else
_glamor_process_transformed_clipped_region
- (source_pixmap_priv, source_repeat_type,
+ (source_pixmap, source_pixmap_priv, source_repeat_type,
clipped_source_regions, &n_source_regions,
&need_clean_source_fbo);
}
@@ -1204,7 +1213,7 @@ glamor_composite_largepixmap_region(CARD8 op,
clipped_source_regions[j].block_idx);
if (mask_pixmap_priv &&
- mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ glamor_pixmap_priv_is_large(mask_pixmap_priv)) {
if (is_normal_mask_fbo && is_normal_source_fbo) {
/* both mask and source are normal fbo box without transform or repeatpad.
* The region is clipped against source and then we clip it against mask here.*/
@@ -1214,7 +1223,7 @@ glamor_composite_largepixmap_region(CARD8 op,
RegionTranslate(clipped_source_regions[j].region,
-x_source + x_mask, -y_source + y_mask);
clipped_mask_regions =
- glamor_compute_clipped_regions(mask_pixmap_priv,
+ glamor_compute_clipped_regions(mask_pixmap,
clipped_source_regions
[j].region,
&n_mask_regions,
@@ -1230,7 +1239,7 @@ glamor_composite_largepixmap_region(CARD8 op,
RegionTranslate(clipped_dest_regions[i].region,
-x_dest + x_mask, -y_dest + y_mask);
clipped_mask_regions =
- glamor_compute_clipped_regions(mask_pixmap_priv,
+ glamor_compute_clipped_regions(mask_pixmap,
clipped_dest_regions
[i].region,
&n_mask_regions,
@@ -1244,14 +1253,14 @@ glamor_composite_largepixmap_region(CARD8 op,
if (!is_normal_source_fbo)
clipped_mask_regions =
glamor_compute_transform_clipped_regions
- (mask_pixmap_priv, mask->transform,
+ (mask_pixmap, mask->transform,
clipped_dest_regions[i].region,
&n_mask_regions, x_mask - x_dest,
y_mask - y_dest, mask_repeat_type, 0, 0);
else
clipped_mask_regions =
glamor_compute_transform_clipped_regions
- (mask_pixmap_priv, mask->transform,
+ (mask_pixmap, mask->transform,
clipped_source_regions[j].region,
&n_mask_regions, x_mask - x_source,
y_mask - y_source, mask_repeat_type, 0, 0);
@@ -1263,7 +1272,7 @@ glamor_composite_largepixmap_region(CARD8 op,
}
else
_glamor_process_transformed_clipped_region
- (mask_pixmap_priv, mask_repeat_type,
+ (mask_pixmap, mask_pixmap_priv, mask_repeat_type,
clipped_mask_regions, &n_mask_regions,
&need_clean_mask_fbo);
}
@@ -1273,9 +1282,9 @@ glamor_composite_largepixmap_region(CARD8 op,
if (!glamor_composite_clipped_region(op, \
null_source ? NULL : source, \
null_mask ? NULL : mask, dest, \
- null_source ? NULL : source_pixmap_priv, \
- null_mask ? NULL : mask_pixmap_priv, \
- dest_pixmap_priv, region, \
+ null_source ? NULL : source_pixmap, \
+ null_mask ? NULL : mask_pixmap, \
+ dest_pixmap, region, \
x_source, y_source, x_mask, y_mask, \
x_dest, y_dest)) { \
assert(0); \
@@ -1326,8 +1335,8 @@ glamor_composite_largepixmap_region(CARD8 op,
null_mask = 0;
if (need_clean_mask_fbo) {
assert(is_normal_mask_fbo == 0);
- glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
- mask_pixmap_priv->base.fbo = NULL;
+ glamor_destroy_fbo(glamor_priv, mask_pixmap_priv->fbo);
+ mask_pixmap_priv->fbo = NULL;
need_clean_mask_fbo = 0;
}
}
@@ -1355,19 +1364,19 @@ glamor_composite_largepixmap_region(CARD8 op,
null_source = 0;
if (need_clean_source_fbo) {
assert(is_normal_source_fbo == 0);
- glamor_destroy_fbo(source_pixmap_priv->base.fbo);
- source_pixmap_priv->base.fbo = NULL;
+ glamor_destroy_fbo(glamor_priv, source_pixmap_priv->fbo);
+ source_pixmap_priv->fbo = NULL;
need_clean_source_fbo = 0;
}
}
else {
if (mask_pixmap_priv &&
- mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ glamor_pixmap_priv_is_large(mask_pixmap_priv)) {
if (!mask->transform && mask_repeat_type != RepeatPad) {
RegionTranslate(clipped_dest_regions[i].region,
x_mask - x_dest, y_mask - y_dest);
clipped_mask_regions =
- glamor_compute_clipped_regions(mask_pixmap_priv,
+ glamor_compute_clipped_regions(mask_pixmap,
clipped_dest_regions[i].
region, &n_mask_regions,
mask_repeat_type, 0, 0);
@@ -1376,7 +1385,7 @@ glamor_composite_largepixmap_region(CARD8 op,
else {
clipped_mask_regions =
glamor_compute_transform_clipped_regions
- (mask_pixmap_priv, mask->transform,
+ (mask_pixmap, mask->transform,
clipped_dest_regions[i].region, &n_mask_regions,
x_mask - x_dest, y_mask - y_dest, mask_repeat_type, 0,
0);
@@ -1388,7 +1397,7 @@ glamor_composite_largepixmap_region(CARD8 op,
}
else
_glamor_process_transformed_clipped_region
- (mask_pixmap_priv, mask_repeat_type,
+ (mask_pixmap, mask_pixmap_priv, mask_repeat_type,
clipped_mask_regions, &n_mask_regions,
&need_clean_mask_fbo);
}
@@ -1417,8 +1426,8 @@ glamor_composite_largepixmap_region(CARD8 op,
if (null_mask)
null_mask = 0;
if (need_clean_mask_fbo) {
- glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
- mask_pixmap_priv->base.fbo = NULL;
+ glamor_destroy_fbo(glamor_priv, mask_pixmap_priv->fbo);
+ mask_pixmap_priv->fbo = NULL;
need_clean_mask_fbo = 0;
}
}
diff --git a/xorg-server/glamor/glamor_lines.c b/xorg-server/glamor/glamor_lines.c
index e9a619505..2dd9c07db 100644
--- a/xorg-server/glamor/glamor_lines.c
+++ b/xorg-server/glamor/glamor_lines.c
@@ -65,7 +65,7 @@ glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
&glamor_facet_poly_lines);
if (!prog)
- goto bail_ctx;
+ goto bail;
/* Set up the vertex buffers for the points */
@@ -117,12 +117,9 @@ glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
}
glDisable(GL_SCISSOR_TEST);
- glDisable(GL_COLOR_LOGIC_OP);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
@@ -167,21 +164,3 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc,
return;
glamor_poly_lines_bail(drawable, gc, mode, n, points);
}
-
-Bool
-glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc,
- int mode, int n, DDXPointPtr points)
-{
- if (glamor_poly_lines_gl(drawable, gc, mode, n, points))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable) &&
- glamor_ddx_fallback_check_gc(gc))
- {
- return FALSE;
- }
-
- glamor_poly_lines_bail(drawable, gc, mode, n, points);
- return TRUE;
-}
-
diff --git a/xorg-server/glamor/glamor_picture.c b/xorg-server/glamor/glamor_picture.c
index bc658f801..53b032c89 100644
--- a/xorg-server/glamor/glamor_picture.c
+++ b/xorg-server/glamor/glamor_picture.c
@@ -69,19 +69,9 @@ glamor_create_picture(PicturePtr picture)
glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
pixmap_priv = glamor_get_pixmap_private(pixmap);
}
- else {
- if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
- /* If the picture format is not compatible with glamor fbo format,
- * we have to mark this pixmap as a separated texture, and don't
- * fallback to DDX layer. */
- if (pixmap_priv->type == GLAMOR_TEXTURE_DRM
- && !glamor_pict_format_is_compatible(picture))
- glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE);
- }
- }
- pixmap_priv->base.is_picture = 1;
- pixmap_priv->base.picture = picture;
+ pixmap_priv->is_picture = 1;
+ pixmap_priv->picture = picture;
return miCreatePicture(picture);
}
@@ -99,8 +89,8 @@ glamor_destroy_picture(PicturePtr picture)
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (pixmap_priv) {
- pixmap_priv->base.is_picture = 0;
- pixmap_priv->base.picture = NULL;
+ pixmap_priv->is_picture = 0;
+ pixmap_priv->picture = NULL;
}
miDestroyPicture(picture);
}
@@ -109,5 +99,5 @@ void
glamor_picture_format_fixup(PicturePtr picture,
glamor_pixmap_private *pixmap_priv)
{
- pixmap_priv->base.picture = picture;
+ pixmap_priv->picture = picture;
}
diff --git a/xorg-server/glamor/glamor_pixmap.c b/xorg-server/glamor/glamor_pixmap.c
index 947113ee9..89b4c366b 100644
--- a/xorg-server/glamor/glamor_pixmap.c
+++ b/xorg-server/glamor/glamor_pixmap.c
@@ -63,31 +63,36 @@ glamor_pixmap_fini(ScreenPtr screen)
}
void
-glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *fbo, int x0, int y0,
+glamor_set_destination_pixmap_fbo(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo, int x0, int y0,
int width, int height)
{
- glamor_make_current(fbo->glamor_priv);
+ glamor_make_current(glamor_priv);
glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
glViewport(x0, y0, width, height);
}
void
-glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
+glamor_set_destination_pixmap_priv_nc(glamor_screen_private *glamor_priv,
+ PixmapPtr pixmap,
+ glamor_pixmap_private *pixmap_priv)
{
int w, h;
- PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap_priv, w, h);
- glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0, w, h);
+ PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, pixmap_priv, w, h);
+ glamor_set_destination_pixmap_fbo(glamor_priv, pixmap_priv->fbo, 0, 0, w, h);
}
int
-glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv)
+glamor_set_destination_pixmap_priv(glamor_screen_private *glamor_priv,
+ PixmapPtr pixmap,
+ glamor_pixmap_private *pixmap_priv)
{
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
return -1;
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+ glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
return 0;
}
@@ -96,8 +101,10 @@ glamor_set_destination_pixmap(PixmapPtr pixmap)
{
int err;
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- err = glamor_set_destination_pixmap_priv(pixmap_priv);
+ err = glamor_set_destination_pixmap_priv(glamor_priv, pixmap, pixmap_priv);
return err;
}
@@ -471,7 +478,7 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
- pict_format = pixmap_priv->base.picture->format;
+ pict_format = pixmap_priv->picture->format;
else
pict_format = format_for_depth(pixmap->drawable.depth);
@@ -717,7 +724,6 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
}
glBindTexture(GL_TEXTURE_2D, *tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
@@ -742,6 +748,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
int swap_rb, int x, int y, int w, int h,
int stride, void *bits, int pbo)
{
+ ScreenPtr screen = pixmap->drawable.pScreen;
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
@@ -793,25 +800,25 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
if (no_alpha == 0
&& revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING
#ifdef WALKAROUND_LARGE_TEXTURE_MAP
- && pixmap_priv->type != GLAMOR_TEXTURE_LARGE
+ && glamor_pixmap_priv_is_small(pixmap_priv)
#endif
) {
int fbo_x_off, fbo_y_off;
- assert(pixmap_priv->base.fbo->tex);
+ assert(pixmap_priv->fbo->tex);
pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
- assert(x + fbo_x_off + w <= pixmap_priv->base.fbo->width);
- assert(y + fbo_y_off + h <= pixmap_priv->base.fbo->height);
- __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex,
+ assert(x + fbo_x_off + w <= pixmap_priv->fbo->width);
+ assert(y + fbo_y_off + h <= pixmap_priv->fbo->height);
+ __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
format, type,
x + fbo_x_off, y + fbo_y_off, w, h,
bits, pbo);
} else {
ptexcoords = texcoords_inv;
- pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
+ pixmap_priv_get_dest_scale(pixmap, pixmap_priv, &dst_xscale, &dst_yscale);
glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
dst_yscale,
x, y,
@@ -826,7 +833,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
GL_FALSE, 2 * sizeof(float), ptexcoords);
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+ glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
+ glamor_set_alu(screen, GXcopy);
__glamor_upload_pixmap_to_texture(pixmap, &tex,
format, type, 0, 0, w, h, bits, pbo);
glActiveTexture(GL_TEXTURE0);
@@ -868,17 +876,17 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
- if (pixmap_priv->base.gl_fbo != GLAMOR_FBO_UNATTACHED)
+ if (pixmap_priv->gl_fbo != GLAMOR_FBO_UNATTACHED)
return 0;
- if (pixmap_priv->base.fbo
- && (pixmap_priv->base.fbo->width < pixmap->drawable.width
- || pixmap_priv->base.fbo->height < pixmap->drawable.height)) {
+ if (pixmap_priv->fbo
+ && (pixmap_priv->fbo->width < pixmap->drawable.width
+ || pixmap_priv->fbo->height < pixmap->drawable.height)) {
fbo = glamor_pixmap_detach_fbo(pixmap_priv);
- glamor_destroy_fbo(fbo);
+ glamor_destroy_fbo(glamor_priv, fbo);
}
- if (pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb)
+ if (pixmap_priv->fbo && pixmap_priv->fbo->fb)
return 0;
if (!(no_alpha || (revert == REVERT_NORMAL)
@@ -889,8 +897,8 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
}
if ((flag == GLAMOR_CREATE_FBO_NO_FBO
- && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
- || (flag == 0 && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
+ && pixmap_priv->fbo && pixmap_priv->fbo->tex)
+ || (flag == 0 && pixmap_priv->fbo && pixmap_priv->fbo->fb))
return 0;
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
@@ -928,6 +936,8 @@ Bool
glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
int h, int stride, void *bits, int pbo)
{
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
GLenum format, type;
int no_alpha, revert, swap_rb;
glamor_pixmap_private *pixmap_priv;
@@ -945,10 +955,10 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
return FALSE;
pixmap_priv = glamor_get_pixmap_private(pixmap);
- force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
- && !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
+ force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
+ && !glamor_check_fbo_size(glamor_priv, w, h);
- if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
+ if (glamor_pixmap_priv_is_large(pixmap_priv) || force_clip) {
RegionRec region;
BoxRec box;
int n_region;
@@ -966,14 +976,14 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
RegionInitBoxes(&region, &box, 1);
if (!force_clip)
clipped_regions =
- glamor_compute_clipped_regions(pixmap_priv, &region, &n_region,
+ glamor_compute_clipped_regions(pixmap, &region, &n_region,
0, 0, 0);
else
clipped_regions =
- glamor_compute_clipped_regions_ext(pixmap_priv, &region,
+ glamor_compute_clipped_regions_ext(pixmap, &region,
&n_region,
- pixmap_priv->large.block_w,
- pixmap_priv->large.block_h,
+ pixmap_priv->block_w,
+ pixmap_priv->block_h,
0,
0);
DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
@@ -1044,10 +1054,10 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
pixmap_priv = glamor_get_pixmap_private(pixmap);
- if ((pixmap_priv->base.fbo)
- && (pixmap_priv->base.fbo->pbo_valid)) {
+ if ((pixmap_priv->fbo)
+ && (pixmap_priv->fbo->pbo_valid)) {
data = NULL;
- pbo = pixmap_priv->base.fbo->pbo;
+ pbo = pixmap_priv->fbo->pbo;
}
else {
data = pixmap->devPrivate.ptr;
@@ -1118,11 +1128,12 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, source_priv->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h);
+ glamor_set_destination_pixmap_fbo(glamor_priv, temp_fbo, 0, 0, w, h);
+ glamor_set_alu(screen, GXcopy);
glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
@@ -1133,62 +1144,3 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
return temp_fbo;
}
-
-/* fixup a fbo to the exact size as the pixmap. */
-/* XXX LARGE pixmap? */
-Bool
-glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
-{
- glamor_pixmap_fbo *old_fbo;
- glamor_pixmap_fbo *new_fbo = NULL;
- PixmapPtr scratch = NULL;
- glamor_pixmap_private *scratch_priv;
- DrawablePtr drawable;
- GCPtr gc = NULL;
- int ret = FALSE;
-
- drawable = &pixmap_priv->base.pixmap->drawable;
-
- if (!GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(pixmap_priv))
- return TRUE;
-
- old_fbo = pixmap_priv->base.fbo;
-
- if (!old_fbo)
- return FALSE;
-
- gc = GetScratchGC(drawable->depth, screen);
- if (!gc)
- goto fail;
-
- scratch = glamor_create_pixmap(screen, drawable->width, drawable->height,
- drawable->depth, GLAMOR_CREATE_PIXMAP_FIXUP);
-
- scratch_priv = glamor_get_pixmap_private(scratch);
-
- if (!scratch_priv->base.fbo)
- goto fail;
-
- ValidateGC(&scratch->drawable, gc);
- glamor_copy_area(drawable,
- &scratch->drawable,
- gc, 0, 0, drawable->width, drawable->height, 0, 0);
- old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
- new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
- glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo);
- glamor_pixmap_attach_fbo(scratch, old_fbo);
-
- DEBUGF("old %dx%d type %d\n",
- drawable->width, drawable->height, pixmap_priv->type);
- DEBUGF("copy tex %d %dx%d to tex %d %dx%d \n",
- old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex,
- new_fbo->width, new_fbo->height);
- ret = TRUE;
- fail:
- if (gc)
- FreeScratchGC(gc);
- if (scratch)
- glamor_destroy_pixmap(scratch);
-
- return ret;
-}
diff --git a/xorg-server/glamor/glamor_points.c b/xorg-server/glamor/glamor_points.c
index 84383d254..df7e5a23f 100644
--- a/xorg-server/glamor/glamor_points.c
+++ b/xorg-server/glamor/glamor_points.c
@@ -55,17 +55,17 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
glamor_make_current(glamor_priv);
if (prog->failed)
- goto bail_ctx;
+ goto bail;
if (!prog->prog) {
if (!glamor_build_program(screen, prog,
&glamor_facet_point,
&glamor_fill_solid))
- goto bail_ctx;
+ goto bail;
}
if (!glamor_use_program(pixmap, gc, prog, NULL))
- goto bail_ctx;
+ goto bail;
vbo_ppt = glamor_get_vbo_space(screen, npt * (2 * sizeof (INT16)), &vbo_offset);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
@@ -102,13 +102,10 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
}
glDisable(GL_SCISSOR_TEST);
- glDisable(GL_COLOR_LOGIC_OP);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
@@ -121,18 +118,3 @@ glamor_poly_point(DrawablePtr drawable, GCPtr gc, int mode, int npt,
return;
miPolyPoint(drawable, gc, mode, npt, ppt);
}
-
-Bool
-glamor_poly_point_nf(DrawablePtr drawable, GCPtr gc, int mode, int npt,
- DDXPointPtr ppt)
-{
- if (glamor_poly_point_gl(drawable, gc, mode, npt, ppt))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
- return FALSE;
-
- miPolyPoint(drawable, gc, mode, npt, ppt);
- return TRUE;
-}
-
diff --git a/xorg-server/glamor/glamor_prepare.c b/xorg-server/glamor/glamor_prepare.c
index fb85d9082..83ba7f16f 100644
--- a/xorg-server/glamor/glamor_prepare.c
+++ b/xorg-server/glamor/glamor_prepare.c
@@ -54,7 +54,7 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
* we'll assume that it's directly mapped
* by a lower level driver
*/
- if (!priv->base.prepared)
+ if (!priv->prepared)
return TRUE;
/* In X, multiple Drawables can be stored in the same Pixmap (such as
@@ -65,28 +65,28 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
* As a result, when doing a series of mappings for a fallback, we may
* need to add more boxes to the set of data we've downloaded, as we go.
*/
- RegionSubtract(&region, &region, &priv->base.prepare_region);
+ RegionSubtract(&region, &region, &priv->prepare_region);
if (!RegionNotEmpty(&region))
return TRUE;
if (access == GLAMOR_ACCESS_RW)
FatalError("attempt to remap buffer as writable");
- if (priv->base.pbo) {
- glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo);
+ if (priv->pbo) {
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->pbo);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
pixmap->devPrivate.ptr = NULL;
}
} else {
- RegionInit(&priv->base.prepare_region, box, 1);
+ RegionInit(&priv->prepare_region, box, 1);
if (glamor_priv->has_rw_pbo) {
- if (priv->base.pbo == 0)
- glGenBuffers(1, &priv->base.pbo);
+ if (priv->pbo == 0)
+ glGenBuffers(1, &priv->pbo);
gl_usage = GL_STREAM_READ;
- glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo);
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->pbo);
glBufferData(GL_PIXEL_PACK_BUFFER,
pixmap->devKind * pixmap->drawable.height, NULL,
gl_usage);
@@ -96,7 +96,7 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
if (!pixmap->devPrivate.ptr)
return FALSE;
}
- priv->base.map_access = access;
+ priv->map_access = access;
}
glamor_download_boxes(pixmap, RegionRects(&region), RegionNumRects(&region),
@@ -105,7 +105,7 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
RegionUninit(&region);
if (glamor_priv->has_rw_pbo) {
- if (priv->base.map_access == GLAMOR_ACCESS_RW)
+ if (priv->map_access == GLAMOR_ACCESS_RW)
gl_access = GL_READ_WRITE;
else
gl_access = GL_READ_ONLY;
@@ -114,7 +114,7 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}
- priv->base.prepared = TRUE;
+ priv->prepared = TRUE;
return TRUE;
}
@@ -133,34 +133,34 @@ glamor_fini_pixmap(PixmapPtr pixmap)
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
return;
- if (!priv->base.prepared)
+ if (!priv->prepared)
return;
if (glamor_priv->has_rw_pbo) {
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->base.pbo);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->pbo);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
pixmap->devPrivate.ptr = NULL;
}
- if (priv->base.map_access == GLAMOR_ACCESS_RW) {
+ if (priv->map_access == GLAMOR_ACCESS_RW) {
glamor_upload_boxes(pixmap,
- RegionRects(&priv->base.prepare_region),
- RegionNumRects(&priv->base.prepare_region),
+ RegionRects(&priv->prepare_region),
+ RegionNumRects(&priv->prepare_region),
0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind);
}
- RegionUninit(&priv->base.prepare_region);
+ RegionUninit(&priv->prepare_region);
if (glamor_priv->has_rw_pbo) {
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- glDeleteBuffers(1, &priv->base.pbo);
- priv->base.pbo = 0;
+ glDeleteBuffers(1, &priv->pbo);
+ priv->pbo = 0;
} else {
free(pixmap->devPrivate.ptr);
pixmap->devPrivate.ptr = NULL;
}
- priv->base.prepared = FALSE;
+ priv->prepared = FALSE;
}
Bool
diff --git a/xorg-server/glamor/glamor_priv.h b/xorg-server/glamor/glamor_priv.h
index ed6e2d192..898a9348a 100644
--- a/xorg-server/glamor/glamor_priv.h
+++ b/xorg-server/glamor/glamor_priv.h
@@ -48,9 +48,7 @@
"precision mediump float;\n" \
"#endif\n"
-#ifdef RENDER
#include "glyphstr.h"
-#endif
#include "glamor_debug.h"
#include "glamor_context.h"
@@ -74,7 +72,7 @@ typedef struct glamor_composite_shader {
union {
float source_solid_color[4];
struct {
- struct glamor_pixmap_private *source_priv;
+ PixmapPtr source_pixmap;
PicturePtr source;
};
};
@@ -82,7 +80,7 @@ typedef struct glamor_composite_shader {
union {
float mask_solid_color[4];
struct {
- struct glamor_pixmap_private *mask_priv;
+ PixmapPtr mask_pixmap;
PicturePtr mask;
};
};
@@ -236,6 +234,8 @@ typedef struct glamor_screen_private {
int has_buffer_storage;
int has_khr_debug;
int has_nv_texture_barrier;
+ int has_pack_subimage;
+ int has_unpack_subimage;
int max_fbo_size;
int has_rw_pbo;
@@ -369,7 +369,6 @@ typedef struct glamor_pixmap_fbo {
Bool external;
GLenum format;
GLenum type;
- glamor_screen_private *glamor_priv;
} glamor_pixmap_fbo;
/*
@@ -378,6 +377,14 @@ typedef struct glamor_pixmap_fbo {
* @is_picture: The drawable is attached to a picture.
* @pict_format: the corresponding picture's format.
* @pixmap: The corresponding pixmap's pointer.
+ * @box: current fbo's coords in the whole pixmap.
+ * @block_w: block width of this large pixmap.
+ * @block_h: block height of this large pixmap.
+ * @block_wcnt: block count in one block row.
+ * @block_hcnt: block count in one block column.
+ * @nbox: total block count.
+ * @box_array: contains each block's corresponding box.
+ * @fbo_array: contains each block's fbo pointer.
*
* For GLAMOR_TEXTURE_LARGE, nbox should larger than 1.
* And the box and fbo will both have nbox elements.
@@ -427,9 +434,6 @@ typedef struct glamor_pixmap_fbo {
* to the box and fbo elements. Thus the inner routines
* can handle it as normal, only the coords calculation need
* to aware of it's large pixmap.
- *
- * Currently, we haven't implemented the atlas pixmap.
- *
**/
typedef struct glamor_pixmap_clipped_regions {
@@ -437,7 +441,7 @@ typedef struct glamor_pixmap_clipped_regions {
RegionPtr region;
} glamor_pixmap_clipped_regions;
-typedef struct glamor_pixmap_private_base {
+typedef struct glamor_pixmap_private {
glamor_pixmap_type_t type;
enum glamor_fbo_state gl_fbo;
/**
@@ -449,10 +453,8 @@ typedef struct glamor_pixmap_private_base {
unsigned char is_picture:1;
unsigned char gl_tex:1;
glamor_pixmap_fbo *fbo;
- PixmapPtr pixmap;
BoxRec box;
int drm_stride;
- glamor_screen_private *glamor_priv;
PicturePtr picture;
GLuint pbo;
RegionRec prepare_region;
@@ -460,104 +462,125 @@ typedef struct glamor_pixmap_private_base {
#if GLAMOR_HAS_GBM
EGLImageKHR image;
#endif
-} glamor_pixmap_private_base_t;
-
-/*
- * @base.fbo: current fbo.
- * @box: current fbo's coords in the whole pixmap.
- * @block_w: block width of this large pixmap.
- * @block_h: block height of this large pixmap.
- * @block_wcnt: block count in one block row.
- * @block_hcnt: block count in one block column.
- * @nbox: total block count.
- * @box_array: contains each block's corresponding box.
- * @fbo_array: contains each block's fbo pointer.
- *
- **/
-typedef struct glamor_pixmap_private_large {
- union {
- glamor_pixmap_type_t type;
- glamor_pixmap_private_base_t base;
- };
- BoxRec box;
int block_w;
int block_h;
int block_wcnt;
int block_hcnt;
- int nbox;
BoxPtr box_array;
glamor_pixmap_fbo **fbo_array;
-} glamor_pixmap_private_large_t;
+} glamor_pixmap_private;
+
+extern DevPrivateKeyRec glamor_pixmap_private_key;
+
+static inline glamor_pixmap_private *
+glamor_get_pixmap_private(PixmapPtr pixmap)
+{
+ glamor_pixmap_private *priv;
+
+ if (pixmap == NULL)
+ return NULL;
+
+ priv = dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
+ if (!priv) {
+ glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
+ priv = dixLookupPrivate(&pixmap->devPrivates,
+ &glamor_pixmap_private_key);
+ }
+ return priv;
+}
+
+void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
/*
- * @box: the relative coords in the corresponding fbo.
+ * Returns TRUE if pixmap has no image object
*/
-typedef struct glamor_pixmap_private_atlas {
- union {
- glamor_pixmap_type_t type;
- glamor_pixmap_private_base_t base;
- };
- BoxRec box;
-} glamor_pixmap_private_atlas_t;
+static inline Bool
+glamor_pixmap_drm_only(PixmapPtr pixmap)
+{
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
-typedef struct glamor_pixmap_private {
- union {
- glamor_pixmap_type_t type;
- glamor_pixmap_private_base_t base;
- glamor_pixmap_private_large_t large;
- glamor_pixmap_private_atlas_t atlas;
- };
-} glamor_pixmap_private;
+ return priv && priv->type == GLAMOR_DRM_ONLY;
+}
+
+/*
+ * Returns TRUE if pixmap is plain memory (not a GL object at all)
+ */
+static inline Bool
+glamor_pixmap_is_memory(PixmapPtr pixmap)
+{
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+ return !priv || priv->type == GLAMOR_MEMORY;
+}
+
+/*
+ * Returns TRUE if pixmap requires multiple textures to hold it
+ */
+static inline Bool
+glamor_pixmap_priv_is_large(glamor_pixmap_private *priv)
+{
+ return priv && (priv->block_wcnt > 1 || priv->block_hcnt > 1);
+}
+
+static inline Bool
+glamor_pixmap_priv_is_small(glamor_pixmap_private *priv)
+{
+ return priv && priv->block_wcnt <= 1 && priv->block_hcnt <= 1;
+}
+
+static inline Bool
+glamor_pixmap_is_large(PixmapPtr pixmap)
+{
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+ return priv && glamor_pixmap_priv_is_large(priv);
+}
+/*
+ * Returns TRUE if pixmap has an FBO
+ */
+static inline Bool
+glamor_pixmap_has_fbo(PixmapPtr pixmap)
+{
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+ return priv && priv->gl_fbo == GLAMOR_FBO_NORMAL;
+}
static inline void
glamor_set_pixmap_fbo_current(glamor_pixmap_private *priv, int idx)
{
- if (priv->type == GLAMOR_TEXTURE_LARGE) {
- priv->large.base.fbo = priv->large.fbo_array[idx];
- priv->large.box = priv->large.box_array[idx];
+ if (glamor_pixmap_priv_is_large(priv)) {
+ priv->fbo = priv->fbo_array[idx];
+ priv->box = priv->box_array[idx];
}
}
static inline glamor_pixmap_fbo *
glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int x, int y)
{
- if (priv->type == GLAMOR_TEXTURE_LARGE) {
- assert(x < priv->large.block_wcnt);
- assert(y < priv->large.block_hcnt);
- return priv->large.fbo_array[y * priv->large.block_wcnt + x];
- }
- assert (x == 0);
- assert (y == 0);
- return priv->base.fbo;
+ assert(x < priv->block_wcnt);
+ assert(y < priv->block_hcnt);
+ return priv->fbo_array[y * priv->block_wcnt + x];
}
static inline BoxPtr
glamor_pixmap_box_at(glamor_pixmap_private *priv, int x, int y)
{
- if (priv->type == GLAMOR_TEXTURE_LARGE) {
- assert(x < priv->large.block_wcnt);
- assert(y < priv->large.block_hcnt);
- return &priv->large.box_array[y * priv->large.block_wcnt + x];
- }
- assert (x == 0);
- assert (y == 0);
- return &priv->base.box;
+ assert(x < priv->block_wcnt);
+ assert(y < priv->block_hcnt);
+ return &priv->box_array[y * priv->block_wcnt + x];
}
static inline int
glamor_pixmap_wcnt(glamor_pixmap_private *priv)
{
- if (priv->type == GLAMOR_TEXTURE_LARGE)
- return priv->large.block_wcnt;
- return 1;
+ return priv->block_wcnt;
}
static inline int
glamor_pixmap_hcnt(glamor_pixmap_private *priv)
{
- if (priv->type == GLAMOR_TEXTURE_LARGE)
- return priv->large.block_hcnt;
- return 1;
+ return priv->block_hcnt;
}
#define glamor_pixmap_loop(priv, x, y) \
@@ -590,7 +613,6 @@ typedef struct {
extern DevPrivateKeyRec glamor_gc_private_key;
extern DevPrivateKeyRec glamor_screen_private_key;
-extern DevPrivateKeyRec glamor_pixmap_private_key;
static inline glamor_screen_private *
glamor_get_screen_private(ScreenPtr screen)
@@ -605,22 +627,6 @@ glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv)
dixSetPrivate(&screen->devPrivates, &glamor_screen_private_key, priv);
}
-static inline glamor_pixmap_private *
-glamor_get_pixmap_private(PixmapPtr pixmap)
-{
- glamor_pixmap_private *priv;
-
- priv = dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
- if (!priv) {
- glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
- priv = dixLookupPrivate(&pixmap->devPrivates,
- &glamor_pixmap_private_key);
- }
- return priv;
-}
-
-void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
-
static inline glamor_gc_private *
glamor_get_gc_private(GCPtr gc)
{
@@ -652,9 +658,10 @@ glamor_pixmap_fbo *glamor_create_fbo_from_tex(glamor_screen_private *
int flag);
glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private *glamor_priv, int w,
int h, GLenum format, int flag);
-void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
-void glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv);
-
+void glamor_destroy_fbo(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo);
+void glamor_pixmap_destroy_fbo(glamor_screen_private *glamor_priv,
+ glamor_pixmap_private *priv);
void glamor_init_pixmap_fbo(ScreenPtr screen);
void glamor_fini_pixmap_fbo(ScreenPtr screen);
Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
@@ -679,13 +686,13 @@ void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
unsigned long fg_pixel, GLfloat *color);
int glamor_set_destination_pixmap(PixmapPtr pixmap);
-int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv);
-void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *, int, int, int, int);
+int glamor_set_destination_pixmap_priv(glamor_screen_private *glamor_priv, PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv);
+void glamor_set_destination_pixmap_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *, int, int, int, int);
/* nc means no check. caller must ensure this pixmap has valid fbo.
* usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly.
* */
-void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv);
+void glamor_set_destination_pixmap_priv_nc(glamor_screen_private *glamor_priv, PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv);
glamor_pixmap_fbo *glamor_es2_pixmap_read_prepare(PixmapPtr source, int x,
int y, int w, int h,
@@ -702,6 +709,7 @@ glamor_track_stipple(GCPtr gc);
/* glamor_glyphs.c */
Bool glamor_realize_glyph_caches(ScreenPtr screen);
+void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
void glamor_glyphs_fini(ScreenPtr screen);
void glamor_glyphs(CARD8 op,
PicturePtr pSrc,
@@ -715,9 +723,9 @@ Bool glamor_composite_clipped_region(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
- glamor_pixmap_private *soruce_pixmap_priv,
- glamor_pixmap_private *mask_pixmap_priv,
- glamor_pixmap_private *dest_pixmap_priv,
+ PixmapPtr source_pixmap,
+ PixmapPtr mask_pixmap,
+ PixmapPtr dest_pixmap,
RegionPtr region,
int x_source,
int y_source,
@@ -748,23 +756,6 @@ PicturePtr glamor_convert_gradient_picture(ScreenPtr screen,
int x_source,
int y_source, int width, int height);
-Bool glamor_composite_choose_shader(CARD8 op,
- PicturePtr source,
- PicturePtr mask,
- PicturePtr dest,
- glamor_pixmap_private *source_pixmap_priv,
- glamor_pixmap_private *mask_pixmap_priv,
- glamor_pixmap_private *dest_pixmap_priv,
- struct shader_key *s_key,
- glamor_composite_shader ** shader,
- struct blendinfo *op_info,
- PictFormatShort *psaved_source_format);
-
-void glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
- struct shader_key *key,
- glamor_composite_shader *shader,
- struct blendinfo *op_info);
-
void *glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
/* glamor_trapezoid.c */
@@ -831,19 +822,19 @@ Bool glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
int pbo);
glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions(glamor_pixmap_private *priv,
+glamor_compute_clipped_regions(PixmapPtr pixmap,
RegionPtr region, int *clipped_nbox,
int repeat_type, int reverse,
int upsidedown);
glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
+glamor_compute_clipped_regions_ext(PixmapPtr pixmap,
RegionPtr region, int *n_region,
int inner_block_w, int inner_block_h,
int reverse, int upsidedown);
glamor_pixmap_clipped_regions *
-glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
+glamor_compute_transform_clipped_regions(PixmapPtr pixmap,
struct pixman_transform *transform,
RegionPtr region,
int *n_region, int dx, int dy,
@@ -854,9 +845,9 @@ Bool glamor_composite_largepixmap_region(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
- glamor_pixmap_private *source_pixmap_priv,
- glamor_pixmap_private *mask_pixmap_priv,
- glamor_pixmap_private *dest_pixmap_priv,
+ PixmapPtr source_pixmap,
+ PixmapPtr mask_pixmap,
+ PixmapPtr dest_pixmap,
RegionPtr region, Bool force_clip,
INT16 x_source,
INT16 y_source,
@@ -894,10 +885,6 @@ void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap);
void glamor_destroy_picture(PicturePtr picture);
-/* fixup a fbo to the exact size as the pixmap. */
-Bool glamor_fixup_pixmap_priv(ScreenPtr screen,
- glamor_pixmap_private *pixmap_priv);
-
void glamor_picture_format_fixup(PicturePtr picture,
glamor_pixmap_private *pixmap_priv);
@@ -1095,4 +1082,6 @@ void glamor_xv_render(glamor_port_private *port_priv);
#include "glamor_font.h"
+#define GLAMOR_MIN_ALU_INSTRUCTIONS 128 /* Minimum required number of native ALU instructions */
+
#endif /* GLAMOR_PRIV_H */
diff --git a/xorg-server/glamor/glamor_program.c b/xorg-server/glamor/glamor_program.c
index 1d0328f2b..8aab53f4f 100644
--- a/xorg-server/glamor/glamor_program.c
+++ b/xorg-server/glamor/glamor_program.c
@@ -40,12 +40,12 @@ const glamor_facet glamor_fill_solid = {
static Bool
use_tile(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
{
- return glamor_set_tiled(pixmap, gc, prog->fill_offset_uniform, prog->fill_size_uniform);
+ return glamor_set_tiled(pixmap, gc, prog->fill_offset_uniform, prog->fill_size_inv_uniform);
}
static const glamor_facet glamor_fill_tile = {
.name = "tile",
- .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
+ .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
.fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n",
.locations = glamor_program_location_fill,
.use = use_tile,
@@ -56,12 +56,12 @@ use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
{
return glamor_set_stippled(pixmap, gc, prog->fg_uniform,
prog->fill_offset_uniform,
- prog->fill_size_uniform);
+ prog->fill_size_inv_uniform);
}
static const glamor_facet glamor_fill_stipple = {
.name = "stipple",
- .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
+ .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
.fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n"
" if (a == 0.0)\n"
" discard;\n"
@@ -81,7 +81,7 @@ use_opaque_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
static const glamor_facet glamor_fill_opaque_stipple = {
.name = "opaque_stipple",
- .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
+ .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
.fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n"
" if (a == 0.0)\n"
" gl_FragColor = bg;\n"
@@ -116,10 +116,10 @@ static glamor_location_var location_vars[] = {
{
.location = glamor_program_location_fill,
.vs_vars = ("uniform vec2 fill_offset;\n"
- "uniform vec2 fill_size;\n"
+ "uniform vec2 fill_size_inv;\n"
"varying vec2 fill_pos;\n"),
.fs_vars = ("uniform sampler2D sampler;\n"
- "uniform vec2 fill_size;\n"
+ "uniform vec2 fill_size_inv;\n"
"varying vec2 fill_pos;\n")
},
{
@@ -336,16 +336,13 @@ glamor_build_program(ScreenPtr screen,
prog->fg_uniform = glamor_get_uniform(prog, glamor_program_location_fg, "fg");
prog->bg_uniform = glamor_get_uniform(prog, glamor_program_location_bg, "bg");
prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_offset");
- prog->fill_size_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size");
+ prog->fill_size_inv_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size_inv");
prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font");
prog->bitplane_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitplane");
prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul");
prog->dash_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash");
prog->dash_length_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash_length");
- if (glGetError() != GL_NO_ERROR)
- goto fail;
-
free(version_string);
free(fs_vars);
free(vs_vars);
diff --git a/xorg-server/glamor/glamor_program.h b/xorg-server/glamor/glamor_program.h
index 56ba03aa8..fa3877c5d 100644
--- a/xorg-server/glamor/glamor_program.h
+++ b/xorg-server/glamor/glamor_program.h
@@ -60,7 +60,7 @@ struct _glamor_program {
GLint matrix_uniform;
GLint fg_uniform;
GLint bg_uniform;
- GLint fill_size_uniform;
+ GLint fill_size_inv_uniform;
GLint fill_offset_uniform;
GLint font_uniform;
GLint bitplane_uniform;
diff --git a/xorg-server/glamor/glamor_rects.c b/xorg-server/glamor/glamor_rects.c
index 3a5c3f3f9..c378e4a30 100644
--- a/xorg-server/glamor/glamor_rects.c
+++ b/xorg-server/glamor/glamor_rects.c
@@ -65,7 +65,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
&glamor_facet_polyfillrect_130);
if (!prog)
- goto bail_ctx;
+ goto bail;
/* Set up the vertex buffers for the points */
@@ -87,7 +87,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
&glamor_facet_polyfillrect_120);
if (!prog)
- goto bail_ctx;
+ goto bail;
/* Set up the vertex buffers for the points */
@@ -126,27 +126,17 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
if (glamor_priv->glsl_version >= 130)
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nrect);
else {
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
- glDrawArrays(GL_QUADS, 0, nrect * 4);
- } else {
- int i;
- for (i = 0; i < nrect; i++) {
- glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
- }
- }
+ glamor_glDrawArrays_GL_QUADS(glamor_priv, nrect);
}
}
}
glDisable(GL_SCISSOR_TEST);
- glDisable(GL_COLOR_LOGIC_OP);
if (glamor_priv->glsl_version >= 130)
glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
@@ -173,15 +163,3 @@ glamor_poly_fill_rect(DrawablePtr drawable,
return;
glamor_poly_fill_rect_bail(drawable, gc, nrect, prect);
}
-
-Bool
-glamor_poly_fill_rect_nf(DrawablePtr drawable,
- GCPtr gc, int nrect, xRectangle *prect)
-{
- if (glamor_poly_fill_rect_gl(drawable, gc, nrect, prect))
- return TRUE;
- if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
- return FALSE;
- glamor_poly_fill_rect_bail(drawable, gc, nrect, prect);
- return TRUE;
-}
diff --git a/xorg-server/glamor/glamor_render.c b/xorg-server/glamor/glamor_render.c
index 2386f2e2e..27c09fd48 100644
--- a/xorg-server/glamor/glamor_render.c
+++ b/xorg-server/glamor/glamor_render.c
@@ -34,7 +34,6 @@
#include "glamor_priv.h"
-#ifdef RENDER
#include "mipict.h"
#include "fbpict.h"
#if 0
@@ -483,15 +482,16 @@ glamor_set_composite_op(ScreenPtr screen,
static void
glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
PicturePtr picture,
- glamor_pixmap_private *pixmap_priv,
+ PixmapPtr pixmap,
GLuint wh_location, GLuint repeat_location)
{
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
float wh[4];
int repeat_type;
glamor_make_current(glamor_priv);
glActiveTexture(GL_TEXTURE0 + unit);
- glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
repeat_type = picture->repeatType;
switch (picture->repeatType) {
case RepeatNone:
@@ -542,13 +542,12 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
if (repeat_type != RepeatNone)
repeat_type += RepeatFix;
else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
- || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
- if (picture->transform
- || (GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(pixmap_priv)))
+ || glamor_pixmap_priv_is_large(pixmap_priv)) {
+ if (picture->transform)
repeat_type += RepeatFix;
}
if (repeat_type >= RepeatFix) {
- glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
+ glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, pixmap_priv);
if ((wh[0] != 1.0 || wh[1] != 1.0)
|| (glamor_priv->gl_flavor == GLAMOR_GL_ES2
&& repeat_type == RepeatFix))
@@ -788,7 +787,8 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
}
static void
-glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
+glamor_set_normalize_tcoords_generic(PixmapPtr pixmap,
+ glamor_pixmap_private *priv,
int repeat_type,
float *matrix,
float xscale, float yscale,
@@ -806,24 +806,27 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
x2, y2,
texcoords, stride);
else if (!matrix && repeat_type != RepeatNone)
- glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,
+ glamor_set_repeat_normalize_tcoords_ext(pixmap, priv, repeat_type,
xscale, yscale,
x1, y1,
x2, y2,
texcoords, stride);
else if (matrix && repeat_type != RepeatNone)
- glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type,
+ glamor_set_repeat_transformed_normalize_tcoords_ext(pixmap, priv, repeat_type,
matrix, xscale,
yscale, x1, y1, x2,
y2,
texcoords, stride);
}
-Bool
+static Bool
glamor_composite_choose_shader(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
+ PixmapPtr source_pixmap,
+ PixmapPtr mask_pixmap,
+ PixmapPtr dest_pixmap,
glamor_pixmap_private *source_pixmap_priv,
glamor_pixmap_private *mask_pixmap_priv,
glamor_pixmap_private *dest_pixmap_priv,
@@ -833,9 +836,6 @@ glamor_composite_choose_shader(CARD8 op,
PictFormatShort *psaved_source_format)
{
ScreenPtr screen = dest->pDrawable->pScreen;
- PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
- PixmapPtr source_pixmap = NULL;
- PixmapPtr mask_pixmap = NULL;
enum glamor_pixmap_status source_status = GLAMOR_NONE;
enum glamor_pixmap_status mask_status = GLAMOR_NONE;
PictFormatShort saved_source_format = 0;
@@ -928,13 +928,12 @@ glamor_composite_choose_shader(CARD8 op,
if (key.source == SHADER_SOURCE_TEXTURE ||
key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
- source_pixmap = source_pixmap_priv->base.pixmap;
if (source_pixmap == dest_pixmap) {
/* XXX source and the dest share the same texture.
* Does it need special handle? */
glamor_fallback("source == dest\n");
}
- if (source_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) {
+ if (source_pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED) {
#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
source_status = GLAMOR_UPLOAD_PENDING;
#else
@@ -946,12 +945,11 @@ glamor_composite_choose_shader(CARD8 op,
if (key.mask == SHADER_MASK_TEXTURE ||
key.mask == SHADER_MASK_TEXTURE_ALPHA) {
- mask_pixmap = mask_pixmap_priv->base.pixmap;
if (mask_pixmap == dest_pixmap) {
glamor_fallback("mask == dest\n");
goto fail;
}
- if (mask_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) {
+ if (mask_pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED) {
#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
mask_status = GLAMOR_UPLOAD_PENDING;
#else
@@ -1041,23 +1039,6 @@ glamor_composite_choose_shader(CARD8 op,
goto fail;
}
- /*Before enter the rendering stage, we need to fixup
- * transformed source and mask, if the transform is not int translate. */
- if (key.source != SHADER_SOURCE_SOLID
- && source->transform
- && !pixman_transform_is_int_translate(source->transform)
- && source_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
- if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv))
- goto fail;
- }
- if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID
- && mask->transform
- && !pixman_transform_is_int_translate(mask->transform)
- && mask_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
- if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv))
- goto fail;
- }
-
if (!glamor_set_composite_op(screen, op, op_info, dest, mask))
goto fail;
@@ -1071,7 +1052,7 @@ glamor_composite_choose_shader(CARD8 op,
memcpy(&(*shader)->source_solid_color[0],
source_solid_color, 4 * sizeof(float));
else {
- (*shader)->source_priv = source_pixmap_priv;
+ (*shader)->source_pixmap = source_pixmap;
(*shader)->source = source;
}
@@ -1079,7 +1060,7 @@ glamor_composite_choose_shader(CARD8 op,
memcpy(&(*shader)->mask_solid_color[0],
mask_solid_color, 4 * sizeof(float));
else {
- (*shader)->mask_priv = mask_pixmap_priv;
+ (*shader)->mask_pixmap = mask_pixmap;
(*shader)->mask = mask;
}
@@ -1095,16 +1076,13 @@ glamor_composite_choose_shader(CARD8 op,
return ret;
}
-void
-glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
+static void
+glamor_composite_set_shader_blend(glamor_screen_private *glamor_priv,
+ glamor_pixmap_private *dest_priv,
struct shader_key *key,
glamor_composite_shader *shader,
struct blendinfo *op_info)
{
- glamor_screen_private *glamor_priv;
-
- glamor_priv = dest_priv->base.glamor_priv;
-
glamor_make_current(glamor_priv);
glUseProgram(shader->prog);
@@ -1115,7 +1093,7 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
else {
glamor_set_composite_texture(glamor_priv, 0,
shader->source,
- shader->source_priv, shader->source_wh,
+ shader->source_pixmap, shader->source_wh,
shader->source_repeat_mode);
}
@@ -1127,7 +1105,7 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
else {
glamor_set_composite_texture(glamor_priv, 1,
shader->mask,
- shader->mask_priv, shader->mask_wh,
+ shader->mask_pixmap, shader->mask_wh,
shader->mask_repeat_mode);
}
}
@@ -1146,6 +1124,9 @@ glamor_composite_with_shader(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
+ PixmapPtr source_pixmap,
+ PixmapPtr mask_pixmap,
+ PixmapPtr dest_pixmap,
glamor_pixmap_private *source_pixmap_priv,
glamor_pixmap_private *mask_pixmap_priv,
glamor_pixmap_private *dest_pixmap_priv,
@@ -1153,10 +1134,7 @@ glamor_composite_with_shader(CARD8 op,
Bool two_pass_ca)
{
ScreenPtr screen = dest->pDrawable->pScreen;
- glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
- PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
- PixmapPtr source_pixmap = NULL;
- PixmapPtr mask_pixmap = NULL;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
GLfloat dst_xscale, dst_yscale;
GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1;
struct shader_key key, key_ca;
@@ -1172,6 +1150,7 @@ glamor_composite_with_shader(CARD8 op,
struct blendinfo op_info, op_info_ca;
if (!glamor_composite_choose_shader(op, source, mask, dest,
+ source_pixmap, mask_pixmap, dest_pixmap,
source_pixmap_priv, mask_pixmap_priv,
dest_pixmap_priv,
&key, &shader, &op_info,
@@ -1181,6 +1160,7 @@ glamor_composite_with_shader(CARD8 op,
}
if (two_pass_ca) {
if (!glamor_composite_choose_shader(PictOpAdd, source, mask, dest,
+ source_pixmap, mask_pixmap, dest_pixmap,
source_pixmap_priv,
mask_pixmap_priv, dest_pixmap_priv,
&key_ca, &shader_ca, &op_info_ca,
@@ -1190,8 +1170,9 @@ glamor_composite_with_shader(CARD8 op,
}
}
- glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
- glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
+ glamor_set_destination_pixmap_priv_nc(glamor_priv, dest_pixmap, dest_pixmap_priv);
+ glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv, &key, shader, &op_info);
+ glamor_set_alu(screen, GXcopy);
glamor_make_current(glamor_priv);
@@ -1203,10 +1184,9 @@ glamor_composite_with_shader(CARD8 op,
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
&dest_x_off, &dest_y_off);
- pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
+ pixmap_priv_get_dest_scale(dest_pixmap, dest_pixmap_priv, &dst_xscale, &dst_yscale);
if (glamor_priv->has_source_coords) {
- source_pixmap = source_pixmap_priv->base.pixmap;
glamor_get_drawable_deltas(source->pDrawable,
source_pixmap, &source_x_off, &source_y_off);
pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale);
@@ -1217,7 +1197,6 @@ glamor_composite_with_shader(CARD8 op,
}
if (glamor_priv->has_mask_coords) {
- mask_pixmap = mask_pixmap_priv->base.pixmap;
glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
&mask_x_off, &mask_y_off);
pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale);
@@ -1269,7 +1248,8 @@ glamor_composite_with_shader(CARD8 op,
vb_stride);
vertices += 2;
if (key.source != SHADER_SOURCE_SOLID) {
- glamor_set_normalize_tcoords_generic(source_pixmap_priv,
+ glamor_set_normalize_tcoords_generic(source_pixmap,
+ source_pixmap_priv,
source->repeatType,
psrc_matrix, src_xscale,
src_yscale, x_source,
@@ -1280,7 +1260,8 @@ glamor_composite_with_shader(CARD8 op,
}
if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
- glamor_set_normalize_tcoords_generic(mask_pixmap_priv,
+ glamor_set_normalize_tcoords_generic(mask_pixmap,
+ mask_pixmap_priv,
mask->repeatType,
pmask_matrix, mask_xscale,
mask_yscale, x_mask,
@@ -1299,11 +1280,11 @@ glamor_composite_with_shader(CARD8 op,
glamor_flush_composite_rects(screen);
nrect -= rect_processed;
if (two_pass_ca) {
- glamor_composite_set_shader_blend(dest_pixmap_priv,
+ glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv,
&key_ca, shader_ca, &op_info_ca);
glamor_flush_composite_rects(screen);
if (nrect)
- glamor_composite_set_shader_blend(dest_pixmap_priv,
+ glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv,
&key, shader, &op_info);
}
}
@@ -1390,17 +1371,21 @@ glamor_composite_clipped_region(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
- glamor_pixmap_private *source_pixmap_priv,
- glamor_pixmap_private *mask_pixmap_priv,
- glamor_pixmap_private *dest_pixmap_priv,
+ PixmapPtr source_pixmap,
+ PixmapPtr mask_pixmap,
+ PixmapPtr dest_pixmap,
RegionPtr region,
int x_source,
int y_source,
int x_mask, int y_mask, int x_dest, int y_dest)
{
+ glamor_pixmap_private *source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+ glamor_pixmap_private *mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+ glamor_pixmap_private *dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
ScreenPtr screen = dest->pDrawable->pScreen;
- PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
PicturePtr temp_src = source, temp_mask = mask;
+ PixmapPtr temp_src_pixmap = source_pixmap;
+ PixmapPtr temp_mask_pixmap = mask_pixmap;
glamor_pixmap_private *temp_src_priv = source_pixmap_priv;
glamor_pixmap_private *temp_mask_priv = mask_pixmap_priv;
int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
@@ -1430,12 +1415,6 @@ glamor_composite_clipped_region(CARD8 op,
DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n",
x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
- if (source_pixmap_priv)
- source_pixmap = source_pixmap_priv->base.pixmap;
-
- if (mask_pixmap_priv)
- mask_pixmap = mask_pixmap_priv->base.pixmap;
-
/* XXX is it possible source mask have non-zero drawable.x/y? */
if (source
&& ((!source->pDrawable
@@ -1453,8 +1432,8 @@ glamor_composite_clipped_region(CARD8 op,
temp_src = source;
goto out;
}
- temp_src_priv =
- glamor_get_pixmap_private((PixmapPtr) (temp_src->pDrawable));
+ temp_src_pixmap = (PixmapPtr) (temp_src->pDrawable);
+ temp_src_priv = glamor_get_pixmap_private(temp_src_pixmap);
x_temp_src = -extent->x1 + x_dest + dest->pDrawable->x;
y_temp_src = -extent->y1 + y_dest + dest->pDrawable->y;
}
@@ -1477,8 +1456,8 @@ glamor_composite_clipped_region(CARD8 op,
temp_mask = mask;
goto out;
}
- temp_mask_priv =
- glamor_get_pixmap_private((PixmapPtr) (temp_mask->pDrawable));
+ temp_mask_pixmap = (PixmapPtr) (temp_mask->pDrawable);
+ temp_mask_priv = glamor_get_pixmap_private(temp_mask_pixmap);
x_temp_mask = -extent->x1 + x_dest + dest->pDrawable->x;
y_temp_mask = -extent->y1 + y_dest + dest->pDrawable->y;
}
@@ -1540,6 +1519,7 @@ glamor_composite_clipped_region(CARD8 op,
DEBUGF("dest %d %d \n", prect[i].x_dst, prect[i].y_dst);
}
ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest,
+ temp_src_pixmap, temp_mask_pixmap, dest_pixmap,
temp_src_priv, temp_mask_priv,
dest_pixmap_priv,
box_cnt, prect, two_pass_ca);
@@ -1560,43 +1540,35 @@ glamor_composite_clipped_region(CARD8 op,
return ok;
}
-static Bool
-_glamor_composite(CARD8 op,
- PicturePtr source,
- PicturePtr mask,
- PicturePtr dest,
- INT16 x_source,
- INT16 y_source,
- INT16 x_mask,
- INT16 y_mask,
- INT16 x_dest, INT16 y_dest,
- CARD16 width, CARD16 height, Bool fallback)
+void
+glamor_composite(CARD8 op,
+ PicturePtr source,
+ PicturePtr mask,
+ PicturePtr dest,
+ INT16 x_source,
+ INT16 y_source,
+ INT16 x_mask,
+ INT16 y_mask,
+ INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
{
ScreenPtr screen = dest->pDrawable->pScreen;
- glamor_pixmap_private *dest_pixmap_priv;
- glamor_pixmap_private *source_pixmap_priv = NULL, *mask_pixmap_priv = NULL;
PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- Bool ret = TRUE;
RegionRec region;
BoxPtr extent;
int nbox, ok = FALSE;
int force_clip = 0;
- dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
-
if (source->pDrawable) {
source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
- source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
- if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY)
+ if (glamor_pixmap_drm_only(source_pixmap))
goto fail;
}
if (mask && mask->pDrawable) {
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
- mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
- if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
+ if (glamor_pixmap_drm_only(mask_pixmap))
goto fail;
}
@@ -1605,9 +1577,8 @@ _glamor_composite(CARD8 op,
source_pixmap, x_source, y_source, x_mask, y_mask, x_dest, y_dest,
width, height);
- if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+ if (!glamor_pixmap_has_fbo(dest_pixmap))
goto fail;
- }
if (op >= ARRAY_SIZE(composite_op_info))
goto fail;
@@ -1639,18 +1610,16 @@ _glamor_composite(CARD8 op,
(mask_pixmap ? mask->pDrawable->y : 0),
x_dest + dest->pDrawable->x,
y_dest + dest->pDrawable->y, width, height)) {
- ret = TRUE;
- goto done;
+ return;
}
nbox = REGION_NUM_RECTS(&region);
DEBUGF("first clipped when compositing.\n");
DEBUGRegionPrint(&region);
extent = RegionExtents(&region);
- if (nbox == 0) {
- ret = TRUE;
- goto done;
- }
+ if (nbox == 0)
+ return;
+
/* If destination is not a large pixmap, but the region is larger
* than texture size limitation, and source or mask is memory pixmap,
* then there may be need to load a large memory pixmap to a
@@ -1659,28 +1628,28 @@ _glamor_composite(CARD8 op,
* pixmap. */
if (!glamor_check_fbo_size(glamor_priv,
extent->x2 - extent->x1, extent->y2 - extent->y1)
- && (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE)
- && ((source_pixmap_priv
- && (source_pixmap_priv->type == GLAMOR_MEMORY ||
+ && glamor_pixmap_is_large(dest_pixmap)
+ && ((source_pixmap
+ && (glamor_pixmap_is_memory(source_pixmap) ||
source->repeatType == RepeatPad))
- || (mask_pixmap_priv &&
- (mask_pixmap_priv->type == GLAMOR_MEMORY ||
+ || (mask_pixmap &&
+ (glamor_pixmap_is_memory(mask_pixmap) ||
mask->repeatType == RepeatPad))
- || (!source_pixmap_priv &&
+ || (!source_pixmap &&
(source->pSourcePict->type != SourcePictTypeSolidFill))
- || (!mask_pixmap_priv && mask &&
+ || (!mask_pixmap && mask &&
mask->pSourcePict->type != SourcePictTypeSolidFill)))
force_clip = 1;
- if (force_clip || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
- || (source_pixmap_priv
- && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
- || (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE))
+ if (force_clip || glamor_pixmap_is_large(dest_pixmap)
+ || (source_pixmap
+ && glamor_pixmap_is_large(source_pixmap))
+ || (mask_pixmap && glamor_pixmap_is_large(mask_pixmap)))
ok = glamor_composite_largepixmap_region(op,
source, mask, dest,
- source_pixmap_priv,
- mask_pixmap_priv,
- dest_pixmap_priv,
+ source_pixmap,
+ mask_pixmap,
+ dest_pixmap,
&region, force_clip,
x_source, y_source,
x_mask, y_mask,
@@ -1688,9 +1657,9 @@ _glamor_composite(CARD8 op,
else
ok = glamor_composite_clipped_region(op, source,
mask, dest,
- source_pixmap_priv,
- mask_pixmap_priv,
- dest_pixmap_priv,
+ source_pixmap,
+ mask_pixmap,
+ dest_pixmap,
&region,
x_source, y_source,
x_mask, y_mask, x_dest, y_dest);
@@ -1698,17 +1667,9 @@ _glamor_composite(CARD8 op,
REGION_UNINIT(dest->pDrawable->pScreen, &region);
if (ok)
- goto done;
- fail:
+ return;
- if (!fallback && glamor_ddx_fallback_check_pixmap(&dest_pixmap->drawable)
- && (!source_pixmap
- || glamor_ddx_fallback_check_pixmap(&source_pixmap->drawable))
- && (!mask_pixmap
- || glamor_ddx_fallback_check_pixmap(&mask_pixmap->drawable))) {
- ret = FALSE;
- goto done;
- }
+ fail:
glamor_fallback
("from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c) to pict %p:%p %dx%d (%c)\n",
@@ -1739,40 +1700,6 @@ _glamor_composite(CARD8 op,
glamor_finish_access_picture(mask);
glamor_finish_access_picture(source);
glamor_finish_access_picture(dest);
-
- done:
- return ret;
-}
-
-void
-glamor_composite(CARD8 op,
- PicturePtr source,
- PicturePtr mask,
- PicturePtr dest,
- INT16 x_source,
- INT16 y_source,
- INT16 x_mask,
- INT16 y_mask,
- INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
-{
- _glamor_composite(op, source, mask, dest, x_source, y_source,
- x_mask, y_mask, x_dest, y_dest, width, height, TRUE);
-}
-
-Bool
-glamor_composite_nf(CARD8 op,
- PicturePtr source,
- PicturePtr mask,
- PicturePtr dest,
- INT16 x_source,
- INT16 y_source,
- INT16 x_mask,
- INT16 y_mask,
- INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
-{
- return _glamor_composite(op, source, mask, dest, x_source, y_source,
- x_mask, y_mask, x_dest, y_dest, width, height,
- FALSE);
}
static void
@@ -1823,21 +1750,27 @@ glamor_composite_glyph_rects(CARD8 op,
if (!(glamor_is_large_picture(src)
|| (mask && glamor_is_large_picture(mask))
|| glamor_is_large_picture(dst))) {
+ PixmapPtr src_pixmap = NULL;
+ PixmapPtr mask_pixmap = NULL;
+ PixmapPtr dst_pixmap = NULL;
+ PixmapPtr temp_src_pixmap = NULL;
glamor_pixmap_private *src_pixmap_priv = NULL;
glamor_pixmap_private *mask_pixmap_priv = NULL;
glamor_pixmap_private *dst_pixmap_priv;
glamor_pixmap_private *temp_src_priv = NULL;
BoxRec src_extent;
- dst_pixmap_priv = glamor_get_pixmap_private
- (glamor_get_drawable_pixmap(dst->pDrawable));
+ dst_pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
+ dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
- if (mask && mask->pDrawable)
- mask_pixmap_priv = glamor_get_pixmap_private
- (glamor_get_drawable_pixmap(mask->pDrawable));
- if (src->pDrawable)
- src_pixmap_priv = glamor_get_pixmap_private
- (glamor_get_drawable_pixmap(src->pDrawable));
+ if (mask && mask->pDrawable) {
+ mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
+ mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+ }
+ if (src->pDrawable) {
+ src_pixmap = glamor_get_drawable_pixmap(src->pDrawable);
+ src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+ }
if (!src->pDrawable
&& (src->pSourcePict->type != SourcePictTypeSolidFill)) {
@@ -1853,13 +1786,14 @@ glamor_composite_glyph_rects(CARD8 op,
if (!temp_src)
goto fallback;
- temp_src_priv = glamor_get_pixmap_private
- ((PixmapPtr) (temp_src->pDrawable));
+ temp_src_pixmap = (PixmapPtr) (temp_src->pDrawable);
+ temp_src_priv = glamor_get_pixmap_private(temp_src_pixmap);
glamor_composite_src_rect_translate(nrect, rects,
-src_extent.x1, -src_extent.y1);
}
else {
temp_src = src;
+ temp_src_pixmap = src_pixmap;
temp_src_priv = src_pixmap_priv;
}
@@ -1867,6 +1801,7 @@ glamor_composite_glyph_rects(CARD8 op,
if (op == PictOpOver) {
if (glamor_composite_with_shader(PictOpOutReverse,
temp_src, mask, dst,
+ temp_src_pixmap, mask_pixmap, dst_pixmap,
temp_src_priv,
mask_pixmap_priv,
dst_pixmap_priv, nrect, rects,
@@ -1876,7 +1811,9 @@ glamor_composite_glyph_rects(CARD8 op,
}
else {
if (glamor_composite_with_shader
- (op, temp_src, mask, dst, temp_src_priv, mask_pixmap_priv,
+ (op, temp_src, mask, dst,
+ temp_src_pixmap, mask_pixmap, dst_pixmap,
+ temp_src_priv, mask_pixmap_priv,
dst_pixmap_priv, nrect, rects, FALSE))
goto done;
}
@@ -1900,31 +1837,3 @@ glamor_composite_glyph_rects(CARD8 op,
if (temp_src && temp_src != src)
FreePicture(temp_src, 0);
}
-
-static Bool
-_glamor_composite_rects(CARD8 op,
- PicturePtr pDst,
- xRenderColor *color,
- int nRect, xRectangle *rects, Bool fallback)
-{
- miCompositeRects(op, pDst, color, nRect, rects);
- return TRUE;
-}
-
-void
-glamor_composite_rects(CARD8 op,
- PicturePtr pDst,
- xRenderColor *color, int nRect, xRectangle *rects)
-{
- _glamor_composite_rects(op, pDst, color, nRect, rects, TRUE);
-}
-
-Bool
-glamor_composite_rects_nf(CARD8 op,
- PicturePtr pDst,
- xRenderColor *color, int nRect, xRectangle *rects)
-{
- return _glamor_composite_rects(op, pDst, color, nRect, rects, FALSE);
-}
-
-#endif /* RENDER */
diff --git a/xorg-server/glamor/glamor_segs.c b/xorg-server/glamor/glamor_segs.c
index ff0daef10..e16732565 100644
--- a/xorg-server/glamor/glamor_segs.c
+++ b/xorg-server/glamor/glamor_segs.c
@@ -109,12 +109,10 @@ glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc,
}
glDisable(GL_SCISSOR_TEST);
- glDisable(GL_COLOR_LOGIC_OP);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE;
bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
@@ -168,21 +166,3 @@ glamor_poly_segment(DrawablePtr drawable, GCPtr gc,
glamor_poly_segment_bail(drawable, gc, nseg, segs);
}
-
-Bool
-glamor_poly_segment_nf(DrawablePtr drawable, GCPtr gc,
- int nseg, xSegment *segs)
-{
- if (glamor_poly_segment_gl(drawable, gc, nseg, segs))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable) &&
- glamor_ddx_fallback_check_gc(gc))
- {
- return FALSE;
- }
-
- glamor_poly_segment_bail(drawable, gc, nseg, segs);
- return TRUE;
-}
-
diff --git a/xorg-server/glamor/glamor_spans.c b/xorg-server/glamor/glamor_spans.c
index 582d11df3..b358c60bd 100644
--- a/xorg-server/glamor/glamor_spans.c
+++ b/xorg-server/glamor/glamor_spans.c
@@ -68,7 +68,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
&glamor_facet_fillspans_130);
if (!prog)
- goto bail_ctx;
+ goto bail;
/* Set up the vertex buffers for the points */
@@ -93,7 +93,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
&glamor_facet_fillspans_120);
if (!prog)
- goto bail_ctx;
+ goto bail;
/* Set up the vertex buffers for the points */
@@ -134,27 +134,17 @@ glamor_fill_spans_gl(DrawablePtr drawable,
if (glamor_priv->glsl_version >= 130)
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, n);
else {
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
- glDrawArrays(GL_QUADS, 0, 4 * n);
- } else {
- int i;
- for (i = 0; i < n; i++) {
- glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
- }
- }
+ glamor_glDrawArrays_GL_QUADS(glamor_priv, nbox);
}
}
}
glDisable(GL_SCISSOR_TEST);
- glDisable(GL_COLOR_LOGIC_OP);
if (glamor_priv->glsl_version >= 130)
glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
@@ -182,21 +172,6 @@ glamor_fill_spans(DrawablePtr drawable,
glamor_fill_spans_bail(drawable, gc, n, points, widths, sorted);
}
-Bool
-glamor_fill_spans_nf(DrawablePtr drawable,
- GCPtr gc,
- int n, DDXPointPtr points, int *widths, int sorted)
-{
- if (glamor_fill_spans_gl(drawable, gc, n, points, widths, sorted))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
- return FALSE;
-
- glamor_fill_spans_bail(drawable, gc, n, points, widths, sorted);
- return TRUE;
-}
-
static Bool
glamor_get_spans_gl(DrawablePtr drawable, int wmax,
DDXPointPtr points, int *widths, int count, char *dst)
@@ -226,7 +201,7 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->fb);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
d = dst;
@@ -282,20 +257,6 @@ glamor_get_spans(DrawablePtr drawable, int wmax,
glamor_get_spans_bail(drawable, wmax, points, widths, count, dst);
}
-Bool
-glamor_get_spans_nf(DrawablePtr drawable, int wmax,
- DDXPointPtr points, int *widths, int count, char *dst)
-{
- if (glamor_get_spans_gl(drawable, wmax, points, widths, count, dst))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable))
- return FALSE;
-
- glamor_get_spans_bail(drawable, wmax, points, widths, count, dst);
- return TRUE;
-}
-
static Bool
glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
DDXPointPtr points, int *widths, int numPoints, int sorted)
@@ -415,17 +376,3 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
return;
glamor_set_spans_bail(drawable, gc, src, points, widths, numPoints, sorted);
}
-
-Bool
-glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc, char *src,
- DDXPointPtr points, int *widths, int numPoints, int sorted)
-{
- if (glamor_set_spans_gl(drawable, gc, src, points, widths, numPoints, sorted))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
- return FALSE;
-
- glamor_set_spans_bail(drawable, gc, src, points, widths, numPoints, sorted);
- return TRUE;
-}
diff --git a/xorg-server/glamor/glamor_sync.c b/xorg-server/glamor/glamor_sync.c
index 5e158c33a..fbc47d4b3 100644
--- a/xorg-server/glamor/glamor_sync.c
+++ b/xorg-server/glamor/glamor_sync.c
@@ -94,8 +94,10 @@ glamor_sync_init(ScreenPtr screen)
return FALSE;
}
+#ifdef HAVE_XSHMFENCE
if (!miSyncShmScreenInit(screen))
return FALSE;
+#endif
screen_funcs = miSyncGetScreenFuncs(screen);
glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
diff --git a/xorg-server/glamor/glamor_text.c b/xorg-server/glamor/glamor_text.c
index 59cd0fdc8..c7c1ab738 100644
--- a/xorg-server/glamor/glamor_text.c
+++ b/xorg-server/glamor/glamor_text.c
@@ -210,7 +210,6 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glDisable(GL_COLOR_LOGIC_OP);
return x;
}
@@ -286,34 +285,18 @@ glamor_poly_text(DrawablePtr drawable, GCPtr gc,
prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_text_progs, &glamor_facet_poly_text);
if (!prog)
- goto bail_ctx;
+ goto bail;
x = glamor_text(drawable, gc, glamor_font, prog,
x, y, count, chars, charinfo, sixteen);
- glDisable(GL_COLOR_LOGIC_OP);
-
*final_pos = x;
return TRUE;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
-Bool
-glamor_poly_text8_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, char *chars, int *final_pos)
-{
- if (glamor_poly_text(drawable, gc, x, y, count, chars, FALSE, final_pos))
- return TRUE;
- if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
- return FALSE;
- *final_pos = miPolyText8(drawable, gc, x, y, count, chars);
- return TRUE;
-}
-
int
glamor_poly_text8(DrawablePtr drawable, GCPtr gc,
int x, int y, int count, char *chars)
@@ -325,19 +308,6 @@ glamor_poly_text8(DrawablePtr drawable, GCPtr gc,
return miPolyText8(drawable, gc, x, y, count, chars);
}
-Bool
-glamor_poly_text16_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, unsigned short *chars, int *final_pos)
-{
- if (glamor_poly_text(drawable, gc, x, y, count, (char *) chars, TRUE, final_pos))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
- return FALSE;
- *final_pos = miPolyText16(drawable, gc, x, y, count, chars);
- return TRUE;
-}
-
int
glamor_poly_text16(DrawablePtr drawable, GCPtr gc,
int x, int y, int count, unsigned short *chars)
@@ -493,17 +463,9 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
return TRUE;
bail:
- glDisable(GL_COLOR_LOGIC_OP);
return FALSE;
}
-Bool
-glamor_image_text8_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, char *chars)
-{
- return glamor_image_text(drawable, gc, x, y, count, chars, FALSE);
-}
-
void
glamor_image_text8(DrawablePtr drawable, GCPtr gc,
int x, int y, int count, char *chars)
@@ -512,13 +474,6 @@ glamor_image_text8(DrawablePtr drawable, GCPtr gc,
miImageText8(drawable, gc, x, y, count, chars);
}
-Bool
-glamor_image_text16_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, unsigned short *chars)
-{
- return glamor_image_text(drawable, gc, x, y, count, (char *) chars, TRUE);
-}
-
void
glamor_image_text16(DrawablePtr drawable, GCPtr gc,
int x, int y, int count, unsigned short *chars)
diff --git a/xorg-server/glamor/glamor_transfer.c b/xorg-server/glamor/glamor_transfer.c
index 891415565..aa5e8616e 100644
--- a/xorg-server/glamor/glamor_transfer.c
+++ b/xorg-server/glamor/glamor_transfer.c
@@ -73,7 +73,9 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
glamor_make_current(glamor_priv);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
+
+ if (glamor_priv->has_unpack_subimage)
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
glamor_pixmap_loop(priv, box_x, box_y) {
BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y);
@@ -92,25 +94,34 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
int y1 = MAX(boxes->y1 + dy_dst, box->y1);
int y2 = MIN(boxes->y2 + dy_dst, box->y2);
+ size_t ofs = (y1 - dy_dst + dy_src) * byte_stride;
+ ofs += (x1 - dx_dst + dx_src) * bytes_per_pixel;
+
boxes++;
if (x2 <= x1 || y2 <= y1)
continue;
- glPixelStorei(GL_UNPACK_SKIP_ROWS, y1 - dy_dst + dy_src);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1 - dx_dst + dx_src);
-
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- x1 - box->x1, y1 - box->y1,
- x2 - x1, y2 - y1,
- format, type,
- bits);
+ if (glamor_priv->has_unpack_subimage ||
+ x2 - x1 == byte_stride / bytes_per_pixel) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ x1 - box->x1, y1 - box->y1,
+ x2 - x1, y2 - y1,
+ format, type,
+ bits + ofs);
+ } else {
+ for (; y1 < y2; y1++, ofs += byte_stride)
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ x1 - box->x1, y1 - box->y1,
+ x2 - x1, 1,
+ format, type,
+ bits + ofs);
+ }
}
}
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ if (glamor_priv->has_unpack_subimage)
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}
/*
@@ -166,7 +177,8 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
glamor_make_current(glamor_priv);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
- glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
+ if (glamor_priv->has_pack_subimage)
+ glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
glamor_pixmap_loop(priv, box_x, box_y) {
BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y);
@@ -174,7 +186,7 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
BoxPtr boxes = in_boxes;
int nbox = in_nbox;
- glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->fb);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
while (nbox--) {
@@ -183,20 +195,25 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
int x2 = MIN(boxes->x2 + dx_src, box->x2);
int y1 = MAX(boxes->y1 + dy_src, box->y1);
int y2 = MIN(boxes->y2 + dy_src, box->y2);
+ size_t ofs = (y1 - dy_src + dy_dst) * byte_stride;
+ ofs += (x1 - dx_src + dx_dst) * bytes_per_pixel;
boxes++;
if (x2 <= x1 || y2 <= y1)
continue;
- glPixelStorei(GL_PACK_SKIP_PIXELS, x1 - dx_src + dx_dst);
- glPixelStorei(GL_PACK_SKIP_ROWS, y1 - dy_src + dy_dst);
- glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits);
+ if (glamor_priv->has_pack_subimage ||
+ x2 - x1 == byte_stride / bytes_per_pixel) {
+ glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits + ofs);
+ } else {
+ for (; y1 < y2; y1++, ofs += byte_stride)
+ glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, 1, format, type, bits + ofs);
+ }
}
}
- glPixelStorei(GL_PACK_ROW_LENGTH, 0);
- glPixelStorei(GL_PACK_SKIP_ROWS, 0);
- glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+ if (glamor_priv->has_pack_subimage)
+ glPixelStorei(GL_PACK_ROW_LENGTH, 0);
}
/*
diff --git a/xorg-server/glamor/glamor_transform.c b/xorg-server/glamor/glamor_transform.c
index c1df56018..6d29e9eb6 100644
--- a/xorg-server/glamor/glamor_transform.c
+++ b/xorg-server/glamor/glamor_transform.c
@@ -43,6 +43,8 @@ glamor_set_destination_drawable(DrawablePtr drawable,
int *p_off_x,
int *p_off_y)
{
+ ScreenPtr screen = drawable->pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
int off_x, off_y;
@@ -95,7 +97,7 @@ glamor_set_destination_drawable(DrawablePtr drawable,
scale_x, (off_x + center_adjust) * scale_x - 1.0f,
scale_y, (off_y + center_adjust) * scale_y - 1.0f);
- glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y),
+ glamor_set_destination_pixmap_fbo(glamor_priv, glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y),
0, 0, w, h);
}
@@ -158,7 +160,7 @@ glamor_set_texture(PixmapPtr pixmap,
int off_x,
int off_y,
GLint offset_uniform,
- GLint size_uniform)
+ GLint size_inv_uniform)
{
glamor_pixmap_private *texture_priv;
@@ -167,14 +169,14 @@ glamor_set_texture(PixmapPtr pixmap,
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(texture_priv))
return FALSE;
- if (texture_priv->type == GLAMOR_TEXTURE_LARGE)
+ if (glamor_pixmap_priv_is_large(texture_priv))
return FALSE;
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture_priv->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, texture_priv->fbo->tex);
glUniform2f(offset_uniform, off_x, off_y);
- glUniform2f(size_uniform, texture->drawable.width, texture->drawable.height);
+ glUniform2f(size_inv_uniform, 1.0f/texture->drawable.width, 1.0f/texture->drawable.height);
return TRUE;
}
@@ -182,7 +184,7 @@ Bool
glamor_set_tiled(PixmapPtr pixmap,
GCPtr gc,
GLint offset_uniform,
- GLint size_uniform)
+ GLint size_inv_uniform)
{
if (!glamor_set_alu(pixmap->drawable.pScreen, gc->alu))
return FALSE;
@@ -195,7 +197,7 @@ glamor_set_tiled(PixmapPtr pixmap,
-gc->patOrg.x,
-gc->patOrg.y,
offset_uniform,
- size_uniform);
+ size_inv_uniform);
}
static PixmapPtr
diff --git a/xorg-server/glamor/glamor_trapezoid.c b/xorg-server/glamor/glamor_trapezoid.c
index f8bf6c97f..a448a6b3e 100644
--- a/xorg-server/glamor/glamor_trapezoid.c
+++ b/xorg-server/glamor/glamor_trapezoid.c
@@ -32,7 +32,6 @@
#include "glamor_priv.h"
-#ifdef RENDER
#include "mipict.h"
#include "fbpict.h"
@@ -155,18 +154,3 @@ glamor_trapezoids(CARD8 op,
FreePicture(picture, 0);
}
-
-Bool
-glamor_trapezoids_nf(CARD8 op,
- PicturePtr src, PicturePtr dst,
- PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
- int ntrap, xTrapezoid *traps)
-{
- DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap);
-
- glamor_trapezoids(op, src, dst, mask_format, x_src,
- y_src, ntrap, traps);
- return TRUE;
-}
-
-#endif /* RENDER */
diff --git a/xorg-server/glamor/glamor_triangles.c b/xorg-server/glamor/glamor_triangles.c
index b89cb2de7..88a46c11f 100644
--- a/xorg-server/glamor/glamor_triangles.c
+++ b/xorg-server/glamor/glamor_triangles.c
@@ -28,29 +28,6 @@
#include "glamor_priv.h"
-static Bool
-_glamor_triangles(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris,
- Bool fallback)
-{
- if (!fallback && glamor_ddx_fallback_check_pixmap(pDst->pDrawable)
- && (!pSrc->pDrawable
- || glamor_ddx_fallback_check_pixmap(pSrc->pDrawable)))
- return FALSE;
-
- if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW) &&
- glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) {
- fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris);
- }
- glamor_finish_access_picture(pSrc);
- glamor_finish_access_picture(pDst);
-
- return TRUE;
-}
-
void
glamor_triangles(CARD8 op,
PicturePtr pSrc,
@@ -58,17 +35,10 @@ glamor_triangles(CARD8 op,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
{
- _glamor_triangles(op, pSrc, pDst, maskFormat,
- xSrc, ySrc, ntris, tris, TRUE);
-}
-
-Bool
-glamor_triangles_nf(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
-{
- return _glamor_triangles(op, pSrc, pDst, maskFormat,
- xSrc, ySrc, ntris, tris, FALSE);
+ if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW) &&
+ glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) {
+ fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris);
+ }
+ glamor_finish_access_picture(pSrc);
+ glamor_finish_access_picture(pDst);
}
diff --git a/xorg-server/glamor/glamor_utils.h b/xorg-server/glamor/glamor_utils.h
index c15d17ca3..0927ffb06 100644
--- a/xorg-server/glamor/glamor_utils.h
+++ b/xorg-server/glamor/glamor_utils.h
@@ -41,50 +41,46 @@
#define t_from_x_coord_y(_yscale_, _y_) (1.0 - (_y_) * (_yscale_))
#define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
-#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
+#define pixmap_priv_get_dest_scale(pixmap, _pixmap_priv_, _pxscale_, _pyscale_) \
do { \
int _w_,_h_; \
- PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, _w_, _h_); \
+ PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, _pixmap_priv_, _w_, _h_); \
*(_pxscale_) = 1.0 / _w_; \
*(_pyscale_) = 1.0 / _h_; \
} while(0)
#define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
do { \
- *(_pxscale_) = 1.0 / (_pixmap_priv_)->base.fbo->width; \
- *(_pyscale_) = 1.0 / (_pixmap_priv_)->base.fbo->height; \
+ *(_pxscale_) = 1.0 / (_pixmap_priv_)->fbo->width; \
+ *(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height; \
} while(0)
-#define GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(priv) \
- (priv->base.fbo->width != priv->base.pixmap->drawable.width \
- || priv->base.fbo->height != priv->base.pixmap->drawable.height) \
-
-#define PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, w, h) \
+#define PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, w, h) \
do { \
- if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
- w = priv->large.box.x2 - priv->large.box.x1; \
- h = priv->large.box.y2 - priv->large.box.y1; \
+ if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \
+ w = priv->box.x2 - priv->box.x1; \
+ h = priv->box.y2 - priv->box.y1; \
} else { \
- w = priv->base.pixmap->drawable.width; \
- h = priv->base.pixmap->drawable.height; \
+ w = (pixmap)->drawable.width; \
+ h = (pixmap)->drawable.height; \
} \
} while(0)
-#define glamor_pixmap_fbo_fix_wh_ratio(wh, priv) \
+#define glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, priv) \
do { \
int actual_w, actual_h; \
- PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, actual_w, actual_h); \
- wh[0] = (float)priv->base.fbo->width / actual_w; \
- wh[1] = (float)priv->base.fbo->height / actual_h; \
- wh[2] = 1.0 / priv->base.fbo->width; \
- wh[3] = 1.0 / priv->base.fbo->height; \
+ PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, actual_w, actual_h); \
+ wh[0] = (float)priv->fbo->width / actual_w; \
+ wh[1] = (float)priv->fbo->height / actual_h; \
+ wh[2] = 1.0 / priv->fbo->width; \
+ wh[3] = 1.0 / priv->fbo->height; \
} while(0)
#define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_) \
do { \
- if (_X_UNLIKELY(_priv_ && (_priv_)->type == GLAMOR_TEXTURE_LARGE)) { \
- *(_xoff_) = - (_priv_)->large.box.x1; \
- *(_yoff_) = - (_priv_)->large.box.y1; \
+ if (_X_UNLIKELY(_priv_ && glamor_pixmap_priv_is_large(_priv_))) { \
+ *(_xoff_) = - (_priv_)->box.x1; \
+ *(_yoff_) = - (_priv_)->box.y1; \
} else { \
*(_xoff_) = 0; \
*(_yoff_) = 0; \
@@ -193,33 +189,33 @@
txy = xy - bxy1; \
} while(0)
-#define _glamor_get_reflect_transform_coords(priv, repeat_type, \
+#define _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type, \
tx1, ty1, \
_x1_, _y1_) \
do { \
int odd_x, odd_y; \
float c, d; \
fodd_repeat_mod(_x1_,priv->box.x2, \
- priv->base.pixmap->drawable.width, \
+ (pixmap)->drawable.width, \
odd_x, c); \
fodd_repeat_mod(_y1_, priv->box.y2, \
- priv->base.pixmap->drawable.height, \
+ (pixmap)->drawable.height, \
odd_y, d); \
DEBUGF("c %f d %f oddx %d oddy %d \n", \
c, d, odd_x, odd_y); \
DEBUGF("x2 %d x1 %d fbo->width %d \n", priv->box.x2, \
- priv->box.x1, priv->base.fbo->width); \
+ priv->box.x1, priv->fbo->width); \
DEBUGF("y2 %d y1 %d fbo->height %d \n", priv->box.y2, \
- priv->box.y1, priv->base.fbo->height); \
+ priv->box.y1, priv->fbo->height); \
_glamor_repeat_reflect_fixup(tx1, _x1_, c, odd_x, \
- priv->base.pixmap->drawable.width, \
+ (pixmap)->drawable.width, \
priv->box.x1, priv->box.x2); \
_glamor_repeat_reflect_fixup(ty1, _y1_, d, odd_y, \
- priv->base.pixmap->drawable.height, \
+ (pixmap)->drawable.height, \
priv->box.y1, priv->box.y2); \
} while(0)
-#define _glamor_get_repeat_coords(priv, repeat_type, tx1, \
+#define _glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, \
ty1, tx2, ty2, \
_x1_, _y1_, _x2_, \
_y2_, c, d, odd_x, odd_y) \
@@ -228,10 +224,10 @@
DEBUGF("x1 y1 %d %d\n", \
_x1_, _y1_ ); \
DEBUGF("width %d box.x1 %d \n", \
- (priv)->base.pixmap->drawable.width, \
+ (pixmap)->drawable.width, \
priv->box.x1); \
if (odd_x) { \
- c = (priv)->base.pixmap->drawable.width \
+ c = (pixmap)->drawable.width \
- c; \
tx1 = c - priv->box.x1; \
tx2 = tx1 - ((_x2_) - (_x1_)); \
@@ -240,7 +236,7 @@
tx2 = tx1 + ((_x2_) - (_x1_)); \
} \
if (odd_y){ \
- d = (priv)->base.pixmap->drawable.height\
+ d = (pixmap)->drawable.height\
- d; \
ty1 = d - priv->box.y1; \
ty2 = ty1 - ((_y2_) - (_y1_)); \
@@ -257,11 +253,11 @@
} while(0)
/* _x1_ ... _y2_ may has fractional. */
-#define glamor_get_repeat_transform_coords(priv, repeat_type, tx1, \
+#define glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, tx1, \
ty1, _x1_, _y1_) \
do { \
DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \
- (priv)->base.pixmap->drawable.width, \
+ (pixmap)->drawable.width, \
priv->box.x1, priv->box.x2, priv->box.y1, \
priv->box.y2); \
DEBUGF("x1 %f y1 %f \n", _x1_, _y1_); \
@@ -269,33 +265,33 @@
tx1 = _x1_ - priv->box.x1; \
ty1 = _y1_ - priv->box.y1; \
} else \
- _glamor_get_reflect_transform_coords(priv, repeat_type, \
+ _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type, \
tx1, ty1, \
_x1_, _y1_); \
DEBUGF("tx1 %f ty1 %f \n", tx1, ty1); \
} while(0)
/* _x1_ ... _y2_ must be integer. */
-#define glamor_get_repeat_coords(priv, repeat_type, tx1, \
+#define glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, \
ty1, tx2, ty2, _x1_, _y1_, _x2_, \
_y2_) \
do { \
int c, d; \
int odd_x = 0, odd_y = 0; \
DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \
- (priv)->base.pixmap->drawable.width, \
+ (pixmap)->drawable.width, \
priv->box.x1, priv->box.x2, \
priv->box.y1, priv->box.y2); \
- modulus((_x1_), (priv)->base.pixmap->drawable.width, c); \
- modulus((_y1_), (priv)->base.pixmap->drawable.height, d); \
+ modulus((_x1_), (pixmap)->drawable.width, c); \
+ modulus((_y1_), (pixmap)->drawable.height, d); \
DEBUGF("c %d d %d \n", c, d); \
if (repeat_type == RepeatReflect) { \
odd_x = abs((_x1_ - c) \
- / (priv->base.pixmap->drawable.width)) & 1; \
+ / ((pixmap)->drawable.width)) & 1; \
odd_y = abs((_y1_ - d) \
- / (priv->base.pixmap->drawable.height)) & 1; \
+ / ((pixmap)->drawable.height)) & 1; \
} \
- _glamor_get_repeat_coords(priv, repeat_type, tx1, ty1, tx2, ty2,\
+ _glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, ty1, tx2, ty2, \
_x1_, _y1_, _x2_, _y2_, c, d, \
odd_x, odd_y); \
} while(0)
@@ -321,7 +317,7 @@
(texcoord)[1]); \
} while(0)
-#define glamor_set_transformed_point(priv, matrix, xscale, \
+#define glamor_set_transformed_point(priv, matrix, xscale, \
yscale, texcoord, \
x, y) \
do { \
@@ -404,7 +400,7 @@
texcoords+4); \
} while (0)
-#define glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \
+#define glamor_set_repeat_transformed_normalize_tcoords_ext(pixmap, priv, \
repeat_type, \
matrix, \
xscale, \
@@ -414,7 +410,7 @@
texcoords, \
stride) \
do { \
- if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) { \
+ if (_X_LIKELY(glamor_pixmap_priv_is_small(priv))) { \
glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, \
yscale, _x1_, _y1_, \
_x2_, _y2_, \
@@ -429,16 +425,16 @@
glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_); \
DEBUGF("transformed %f %f %f %f %f %f %f %f\n", \
tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4); \
- glamor_get_repeat_transform_coords((&priv->large), repeat_type, \
+ glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
ttx1, tty1, \
tx1, ty1); \
- glamor_get_repeat_transform_coords((&priv->large), repeat_type, \
+ glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
ttx2, tty2, \
tx2, ty2); \
- glamor_get_repeat_transform_coords((&priv->large), repeat_type, \
+ glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
ttx3, tty3, \
tx3, ty3); \
- glamor_get_repeat_transform_coords((&priv->large), repeat_type, \
+ glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
ttx4, tty4, \
tx4, ty4); \
DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \
@@ -454,7 +450,8 @@
} \
} while (0)
-#define glamor_set_repeat_transformed_normalize_tcoords( priv, \
+#define glamor_set_repeat_transformed_normalize_tcoords( pixmap, \
+ priv, \
repeat_type, \
matrix, \
xscale, \
@@ -463,7 +460,8 @@
_x2_, _y2_, \
texcoords) \
do { \
- glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \
+ glamor_set_repeat_transformed_normalize_tcoords_ext( pixmap, \
+ priv, \
repeat_type, \
matrix, \
xscale, \
@@ -495,7 +493,7 @@
x1, y1, x2, y2, \
vertices, stride) \
do { \
- if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
+ if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \
float tx1, tx2, ty1, ty2; \
int fbo_x_off, fbo_y_off; \
pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \
@@ -520,20 +518,20 @@
vertices, 2); \
} while(0)
-#define glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \
+#define glamor_set_repeat_normalize_tcoords_ext(pixmap, priv, repeat_type, \
xscale, yscale, \
_x1_, _y1_, _x2_, _y2_, \
vertices, stride) \
do { \
- if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
+ if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \
float tx1, tx2, ty1, ty2; \
if (repeat_type == RepeatPad) { \
- tx1 = _x1_ - priv->large.box.x1; \
- ty1 = _y1_ - priv->large.box.y1; \
+ tx1 = _x1_ - priv->box.x1; \
+ ty1 = _y1_ - priv->box.y1; \
tx2 = tx1 + ((_x2_) - (_x1_)); \
ty2 = ty1 + ((_y2_) - (_y1_)); \
} else { \
- glamor_get_repeat_coords((&priv->large), repeat_type, \
+ glamor_get_repeat_coords(pixmap, priv, repeat_type, \
tx1, ty1, tx2, ty2, \
_x1_, _y1_, _x2_, _y2_); \
} \
@@ -758,9 +756,9 @@ glamor_translate_boxes(BoxPtr boxes, int nbox, int dx, int dy)
|| _depth_ == 30 \
|| _depth_ == 32)
-#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->base.is_picture == 1)
-#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv && pixmap_priv->base.gl_fbo == GLAMOR_FBO_NORMAL)
-#define GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv) (pixmap_priv && (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED))
+#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->is_picture == 1)
+#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv && pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
+#define GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv) (pixmap_priv && (pixmap_priv->gl_fbo == GLAMOR_FBO_DOWNLOADED))
/**
* Borrow from uxa.
@@ -795,10 +793,10 @@ static inline GLenum
gl_iformat_for_pixmap(PixmapPtr pixmap)
{
glamor_screen_private *glamor_priv =
- glamor_get_screen_private(pixmap->drawable.pScreen);
+ glamor_get_screen_private((pixmap)->drawable.pScreen);
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
- (pixmap->drawable.depth == 1 || pixmap->drawable.depth == 8)) {
+ ((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) {
return GL_ALPHA;
} else {
return GL_RGBA;
@@ -813,9 +811,9 @@ format_for_pixmap(PixmapPtr pixmap)
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
- pict_format = pixmap_priv->base.picture->format;
+ pict_format = pixmap_priv->picture->format;
else
- pict_format = format_for_depth(pixmap->drawable.depth);
+ pict_format = format_for_depth((pixmap)->drawable.depth);
return pict_format;
}
@@ -939,47 +937,13 @@ glamor_pict_format_is_compatible(PicturePtr picture)
}
}
-/* return TRUE if we can access this pixmap at DDX driver. */
-inline static Bool
-glamor_ddx_fallback_check_pixmap(DrawablePtr drawable)
-{
- PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
- glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-
- return (!pixmap_priv
- || (pixmap_priv->type == GLAMOR_TEXTURE_DRM
- || pixmap_priv->type == GLAMOR_MEMORY
- || pixmap_priv->type == GLAMOR_DRM_ONLY));
-}
-
-inline static Bool
-glamor_ddx_fallback_check_gc(GCPtr gc)
-{
- PixmapPtr pixmap;
-
- if (!gc)
- return TRUE;
- switch (gc->fillStyle) {
- case FillStippled:
- case FillOpaqueStippled:
- pixmap = gc->stipple;
- break;
- case FillTiled:
- pixmap = gc->tile.pixmap;
- break;
- default:
- pixmap = NULL;
- }
- return (!pixmap || glamor_ddx_fallback_check_pixmap(&pixmap->drawable));
-}
-
inline static Bool
glamor_is_large_pixmap(PixmapPtr pixmap)
{
glamor_pixmap_private *priv;
priv = glamor_get_pixmap_private(pixmap);
- return (priv->type == GLAMOR_TEXTURE_LARGE);
+ return (glamor_pixmap_priv_is_large(priv));
}
inline static Bool
@@ -1005,8 +969,8 @@ static inline void
_glamor_dump_pixmap_bits(PixmapPtr pixmap, int x, int y, int w, int h)
{
int i, j;
- unsigned char *p = pixmap->devPrivate.ptr;
- int stride = pixmap->devKind;
+ unsigned char *p = (pixmap)->devPrivate.ptr;
+ int stride = (pixmap)->devKind;
p = p + y * stride + x;
@@ -1023,8 +987,8 @@ static inline void
_glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int w, int h)
{
int i, j;
- unsigned char *p = pixmap->devPrivate.ptr;
- int stride = pixmap->devKind;
+ unsigned char *p = (pixmap)->devPrivate.ptr;
+ int stride = (pixmap)->devKind;
p = p + y * stride + x;
@@ -1041,8 +1005,8 @@ static inline void
_glamor_dump_pixmap_sword(PixmapPtr pixmap, int x, int y, int w, int h)
{
int i, j;
- unsigned short *p = pixmap->devPrivate.ptr;
- int stride = pixmap->devKind / 2;
+ unsigned short *p = (pixmap)->devPrivate.ptr;
+ int stride = (pixmap)->devKind / 2;
p = p + y * stride + x;
@@ -1059,8 +1023,8 @@ static inline void
_glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h)
{
int i, j;
- unsigned int *p = pixmap->devPrivate.ptr;
- int stride = pixmap->devKind / 4;
+ unsigned int *p = (pixmap)->devPrivate.ptr;
+ int stride = (pixmap)->devKind / 4;
p = p + y * stride + x;
@@ -1076,11 +1040,11 @@ _glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h)
static inline void
glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h)
{
- w = ((x + w) > pixmap->drawable.width) ? (pixmap->drawable.width - x) : w;
- h = ((y + h) > pixmap->drawable.height) ? (pixmap->drawable.height - y) : h;
+ w = ((x + w) > (pixmap)->drawable.width) ? ((pixmap)->drawable.width - x) : w;
+ h = ((y + h) > (pixmap)->drawable.height) ? ((pixmap)->drawable.height - y) : h;
- glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
- switch (pixmap->drawable.depth) {
+ glamor_prepare_access(&(pixmap)->drawable, GLAMOR_ACCESS_RO);
+ switch ((pixmap)->drawable.depth) {
case 8:
_glamor_dump_pixmap_byte(pixmap, x, y, w, h);
break;
@@ -1097,9 +1061,9 @@ glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h)
_glamor_dump_pixmap_bits(pixmap, x, y, w, h);
break;
default:
- ErrorF("dump depth %d, not implemented.\n", pixmap->drawable.depth);
+ ErrorF("dump depth %d, not implemented.\n", (pixmap)->drawable.depth);
}
- glamor_finish_access(&pixmap->drawable);
+ glamor_finish_access(&(pixmap)->drawable);
}
static inline void
@@ -1297,7 +1261,7 @@ glamor_compare_pictures(ScreenPtr screen,
GLAMOR_CREATE_PIXMAP_CPU);
pixman_pic = CreatePicture(0,
- &pixmap->drawable,
+ &(pixmap)->drawable,
PictureMatchFormat(screen,
PIXMAN_FORMAT_DEPTH
(format), format), 0, 0,
@@ -1325,7 +1289,7 @@ glamor_compare_pictures(ScreenPtr screen,
GLAMOR_CREATE_PIXMAP_CPU);
pixman_pic = CreatePicture(0,
- &pixmap->drawable,
+ &(pixmap)->drawable,
PictureMatchFormat(screen,
PIXMAN_FORMAT_DEPTH
(format), format), 0, 0,
@@ -1429,4 +1393,21 @@ glamor_make_current(glamor_screen_private *glamor_priv)
}
}
+/**
+ * Helper function for implementing draws with GL_QUADS on GLES2,
+ * where we don't have them.
+ */
+static inline void
+glamor_glDrawArrays_GL_QUADS(glamor_screen_private *glamor_priv, unsigned count)
+{
+ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+ glDrawArrays(GL_QUADS, 0, count * 4);
+ } else {
+ unsigned i;
+ for (i = 0; i < count; i++)
+ glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
+ }
+}
+
+
#endif
diff --git a/xorg-server/glamor/glamor_window.c b/xorg-server/glamor/glamor_window.c
index 60647bf80..a39e723ef 100644
--- a/xorg-server/glamor/glamor_window.c
+++ b/xorg-server/glamor/glamor_window.c
@@ -79,16 +79,16 @@ glamor_set_window_pixmap(WindowPtr win, PixmapPtr pPixmap)
pixmap_priv = glamor_get_pixmap_private(old);
if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) &&
- pixmap_priv->base.picture->pDrawable == (DrawablePtr) win) {
- pic = pixmap_priv->base.picture;
- pixmap_priv->base.is_picture = 0;
- pixmap_priv->base.picture = NULL;
+ pixmap_priv->picture->pDrawable == (DrawablePtr) win) {
+ pic = pixmap_priv->picture;
+ pixmap_priv->is_picture = 0;
+ pixmap_priv->picture = NULL;
}
pixmap_priv = glamor_get_pixmap_private(pPixmap);
if (pixmap_priv) {
- pixmap_priv->base.is_picture = ! !pic;
- pixmap_priv->base.picture = pic;
+ pixmap_priv->is_picture = ! !pic;
+ pixmap_priv->picture = pic;
}
}
diff --git a/xorg-server/glamor/glamor_xv.c b/xorg-server/glamor/glamor_xv.c
index 83e24adb2..364104ddd 100644
--- a/xorg-server/glamor/glamor_xv.c
+++ b/xorg-server/glamor/glamor_xv.c
@@ -241,8 +241,8 @@ glamor_xv_render(glamor_port_private *port_priv)
{
ScreenPtr screen = port_priv->pPixmap->drawable.pScreen;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- glamor_pixmap_private *pixmap_priv =
- glamor_get_pixmap_private(port_priv->pPixmap);
+ PixmapPtr pixmap = port_priv->pPixmap;
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_pixmap_private *src_pixmap_priv[3];
float vertices[32], texcoords[8];
BoxPtr box = REGION_RECTS(&port_priv->clip);
@@ -282,10 +282,11 @@ glamor_xv_render(glamor_port_private *port_priv)
off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright;
gamma = 1.0;
- pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
+ pixmap_priv_get_dest_scale(pixmap, pixmap_priv, &dst_xscale, &dst_yscale);
glamor_get_drawable_deltas(port_priv->pDraw, port_priv->pPixmap, &dst_x_off,
&dst_y_off);
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+ glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
+ glamor_set_alu(screen, GXcopy);
for (i = 0; i < 3; i++) {
if (port_priv->src_pix[i]) {
@@ -306,21 +307,21 @@ glamor_xv_render(glamor_port_private *port_priv)
glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c
index 8fe751693..582e3af96 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -214,6 +214,8 @@ ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glUseProgram(glamor->texture_shader);
glViewport(0, 0, glamor->width, glamor->height);
+ if (!ephyr_glamor_gles2)
+ glDisable(GL_COLOR_LOGIC_OP);
glVertexAttribPointer(glamor->texture_shader_position_loc,
2, GL_FLOAT, FALSE, 0, position);
diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c
index f64861b50..c67ff60d3 100644
--- a/xorg-server/hw/kdrive/ephyr/hostx.c
+++ b/xorg-server/hw/kdrive/ephyr/hostx.c
@@ -443,7 +443,7 @@ hostx_init(void)
else
#endif
HostX.conn = xcb_connect(NULL, &HostX.screen);
- if (xcb_connection_has_error(HostX.conn)) {
+ if (!HostX.conn || xcb_connection_has_error(HostX.conn)) {
fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n");
exit(1);
}
@@ -1407,9 +1407,10 @@ ephyr_glamor_init(ScreenPtr screen)
ephyr_glamor_set_window_size(scrpriv->glamor,
scrpriv->win_width, scrpriv->win_height);
- glamor_init(screen,
- GLAMOR_USE_SCREEN |
- GLAMOR_USE_PICTURE_SCREEN);
+ if (!glamor_init(screen, 0)) {
+ FatalError("Failed to initialize glamor\n");
+ return FALSE;
+ }
return TRUE;
}
diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c
index c06aaaee1..97a1f97b2 100644
--- a/xorg-server/hw/xfree86/common/xf86Events.c
+++ b/xorg-server/hw/xfree86/common/xf86Events.c
@@ -583,10 +583,11 @@ xf86VTEnter(void)
/* Turn screen saver off when switching back */
dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
- /* If we use systemd-logind it will enable input devices for us */
- if (!systemd_logind_controls_session())
- for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
+ for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) {
+ /* Devices with server managed fds get enabled on logind resume */
+ if (!(pInfo->flags & XI86_SERVER_FD))
xf86EnableInputDeviceForVTSwitch(pInfo);
+ }
for (ih = InputHandlers; ih; ih = ih->next) {
if (ih->is_input)
diff --git a/xorg-server/hw/xfree86/common/xf86platformBus.c b/xorg-server/hw/xfree86/common/xf86platformBus.c
index 15988b8b1..c1aaba41a 100644
--- a/xorg-server/hw/xfree86/common/xf86platformBus.c
+++ b/xorg-server/hw/xfree86/common/xf86platformBus.c
@@ -153,8 +153,10 @@ xf86_check_platform_slot(const struct xf86_platform_device *pd)
for (i = 0; i < xf86NumEntities; i++) {
const EntityPtr u = xf86Entities[i];
- if (pd->pdev && u->bus.type == BUS_PCI)
- return !MATCH_PCI_DEVICES(pd->pdev, u->bus.id.pci);
+ if (pd->pdev && u->bus.type == BUS_PCI &&
+ MATCH_PCI_DEVICES(pd->pdev, u->bus.id.pci)) {
+ return FALSE;
+ }
if ((u->bus.type == BUS_PLATFORM) && (pd == u->bus.id.plat)) {
return FALSE;
}
@@ -426,6 +428,10 @@ xf86platformProbeDev(DriverPtr drvp)
/* find the main device or any device specificed in xorg.conf */
for (i = 0; i < numDevs; i++) {
+ /* skip inactive devices */
+ if (!devList[i]->active)
+ continue;
+
for (j = 0; j < xf86_num_platform_devices; j++) {
if (devList[i]->busID && *devList[i]->busID) {
if (xf86PlatformDeviceCheckBusID(&xf86_platform_devices[j], devList[i]->busID))
@@ -449,10 +455,14 @@ xf86platformProbeDev(DriverPtr drvp)
continue;
}
- /* if autoaddgpu devices is enabled then go find a few more and add them as GPU screens */
- if (xf86Info.autoAddGPU && numDevs) {
+ /* if autoaddgpu devices is enabled then go find any unclaimed platform
+ * devices and add them as GPU screens */
+ if (xf86Info.autoAddGPU) {
for (j = 0; j < xf86_num_platform_devices; j++) {
- probeSingleDevice(&xf86_platform_devices[j], drvp, devList[0], PLATFORM_PROBE_GPU_SCREEN);
+ if (probeSingleDevice(&xf86_platform_devices[j], drvp,
+ devList ? devList[0] : NULL,
+ PLATFORM_PROBE_GPU_SCREEN))
+ foundScreen = TRUE;
}
}
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/driver.c b/xorg-server/hw/xfree86/drivers/modesetting/driver.c
index d52517d1a..e2f3846ca 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/driver.c
+++ b/xorg-server/hw/xfree86/drivers/modesetting/driver.c
@@ -1049,10 +1049,7 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
#ifdef GLAMOR
if (ms->drmmode.glamor) {
- if (!glamor_init(pScreen,
- GLAMOR_USE_EGL_SCREEN |
- GLAMOR_USE_SCREEN |
- GLAMOR_USE_PICTURE_SCREEN)) {
+ if (!glamor_init(pScreen, GLAMOR_USE_EGL_SCREEN)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to initialize glamor at ScreenInit() time.\n");
return FALSE;
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c
index 9d592a7eb..a1947241b 100644
--- a/xorg-server/hw/xfree86/modes/xf86Crtc.c
+++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c
@@ -3026,6 +3026,27 @@ xf86OutputSetEDIDProperty(xf86OutputPtr output, void *data, int data_len)
}
}
+#define TILE_ATOM_NAME "TILE"
+/* changing this in the future could be tricky as people may hardcode 8 */
+#define TILE_PROP_NUM_ITEMS 8
+static void
+xf86OutputSetTileProperty(xf86OutputPtr output)
+{
+ Atom tile_atom = MakeAtom(TILE_ATOM_NAME, sizeof(TILE_ATOM_NAME) - 1, TRUE);
+
+ /* This may get called before the RandR resources have been created */
+ if (output->randr_output == NULL)
+ return;
+
+ if (output->tile_info.group_id != 0) {
+ RRChangeOutputProperty(output->randr_output, tile_atom, XA_INTEGER, 32,
+ PropModeReplace, TILE_PROP_NUM_ITEMS, (uint32_t *)&output->tile_info, FALSE, TRUE);
+ }
+ else {
+ RRDeleteOutputProperty(output->randr_output, tile_atom);
+ }
+}
+
#endif
/* Pull out a phyiscal size from a detailed timing if available. */
@@ -3071,6 +3092,38 @@ handle_detailed_physical_size(struct detailed_monitor_section
}
}
+Bool
+xf86OutputParseKMSTile(const char *tile_data, int tile_length,
+ struct xf86CrtcTileInfo *tile_info)
+{
+ int ret;
+
+ ret = sscanf(tile_data, "%d:%d:%d:%d:%d:%d:%d:%d",
+ &tile_info->group_id,
+ &tile_info->flags,
+ &tile_info->num_h_tile,
+ &tile_info->num_v_tile,
+ &tile_info->tile_h_loc,
+ &tile_info->tile_v_loc,
+ &tile_info->tile_h_size,
+ &tile_info->tile_v_size);
+ if (ret != 8)
+ return FALSE;
+ return TRUE;
+}
+
+void
+xf86OutputSetTile(xf86OutputPtr output, struct xf86CrtcTileInfo *tile_info)
+{
+ if (tile_info)
+ output->tile_info = *tile_info;
+ else
+ memset(&output->tile_info, 0, sizeof(output->tile_info));
+#ifdef RANDR_12_INTERFACE
+ xf86OutputSetTileProperty(output);
+#endif
+}
+
/**
* Set the EDID information for the specified output
*/
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.h b/xorg-server/hw/xfree86/modes/xf86Crtc.h
index 692bf40b9..3c5bbcfd5 100644
--- a/xorg-server/hw/xfree86/modes/xf86Crtc.h
+++ b/xorg-server/hw/xfree86/modes/xf86Crtc.h
@@ -70,6 +70,17 @@ typedef enum _xf86OutputStatus {
XF86OutputStatusUnknown
} xf86OutputStatus;
+struct xf86CrtcTileInfo {
+ uint32_t group_id;
+ uint32_t flags;
+ uint32_t num_h_tile;
+ uint32_t num_v_tile;
+ uint32_t tile_h_loc;
+ uint32_t tile_v_loc;
+ uint32_t tile_h_size;
+ uint32_t tile_v_size;
+};
+
typedef struct _xf86CrtcFuncs {
/**
* Turns the crtc on/off, or sets intermediate power levels if available.
@@ -226,7 +237,7 @@ typedef struct _xf86CrtcFuncs {
} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
-#define XF86_CRTC_VERSION 5
+#define XF86_CRTC_VERSION 6
struct _xf86Crtc {
/**
@@ -500,7 +511,7 @@ typedef struct _xf86OutputFuncs {
(*destroy) (xf86OutputPtr output);
} xf86OutputFuncsRec, *xf86OutputFuncsPtr;
-#define XF86_OUTPUT_VERSION 2
+#define XF86_OUTPUT_VERSION 3
struct _xf86Output {
/**
@@ -615,6 +626,8 @@ struct _xf86Output {
BoxRec initialTotalArea;
BoxRec initialTrackingArea;
INT16 initialBorder[4];
+
+ struct xf86CrtcTileInfo tile_info;
};
typedef struct _xf86ProviderFuncs {
@@ -881,6 +894,15 @@ extern _X_EXPORT void
xf86OutputSetEDID(xf86OutputPtr output, xf86MonPtr edid_mon);
/**
+ * Set the TILE information for the specified output
+ */
+extern _X_EXPORT void
+xf86OutputSetTile(xf86OutputPtr output, struct xf86CrtcTileInfo *tile_info);
+
+extern _X_EXPORT Bool
+xf86OutputParseKMSTile(const char *tile_data, int tile_length, struct xf86CrtcTileInfo *tile_info);
+
+/**
* Return the list of modes supported by the EDID information
* stored in 'output'
*/
diff --git a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c
index 49758f465..4ad41a374 100644
--- a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c
+++ b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c
@@ -40,8 +40,6 @@
#include "systemd-logind.h"
-#define DBUS_TIMEOUT 500 /* Wait max 0.5 seconds */
-
struct systemd_logind_info {
DBusConnection *conn;
char *session;
@@ -130,7 +128,7 @@ systemd_logind_take_fd(int _major, int _minor, const char *path,
}
reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
- DBUS_TIMEOUT, &error);
+ DBUS_TIMEOUT_USE_DEFAULT, &error);
if (!reply) {
LogMessage(X_ERROR, "systemd-logind: failed to take device %s: %s\n",
path, error.message);
@@ -207,7 +205,7 @@ systemd_logind_release_fd(int _major, int _minor, int fd)
}
reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
- DBUS_TIMEOUT, &error);
+ DBUS_TIMEOUT_USE_DEFAULT, &error);
if (!reply)
LogMessage(X_ERROR, "systemd-logind: failed to release device: %s\n",
error.message);
@@ -289,7 +287,7 @@ systemd_logind_ack_pause(struct systemd_logind_info *info,
}
reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
- DBUS_TIMEOUT, &error);
+ DBUS_TIMEOUT_USE_DEFAULT, &error);
if (!reply)
LogMessage(X_ERROR, "systemd-logind: failed to ack pause: %s\n",
error.message);
@@ -313,6 +311,9 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data)
dbus_int32_t major, minor;
char *pause_str;
+ if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
dbus_error_init(&error);
if (dbus_message_is_signal(message,
@@ -454,7 +455,7 @@ connect_hook(DBusConnection *connection, void *data)
}
reply = dbus_connection_send_with_reply_and_block(connection, msg,
- DBUS_TIMEOUT, &error);
+ DBUS_TIMEOUT_USE_DEFAULT, &error);
if (!reply) {
LogMessage(X_ERROR, "systemd-logind: failed to get session: %s\n",
error.message);
@@ -489,7 +490,7 @@ connect_hook(DBusConnection *connection, void *data)
}
reply = dbus_connection_send_with_reply_and_block(connection, msg,
- DBUS_TIMEOUT, &error);
+ DBUS_TIMEOUT_USE_DEFAULT, &error);
if (!reply) {
LogMessage(X_ERROR, "systemd-logind: TakeControl failed: %s\n",
error.message);
@@ -561,7 +562,7 @@ systemd_logind_release_control(struct systemd_logind_info *info)
}
reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
- DBUS_TIMEOUT, &error);
+ DBUS_TIMEOUT_USE_DEFAULT, &error);
if (!reply) {
LogMessage(X_ERROR, "systemd-logind: ReleaseControl failed: %s\n",
error.message);
diff --git a/xorg-server/hw/xquartz/quartz.c b/xorg-server/hw/xquartz/quartz.c
index d7229cecb..851ce4842 100644
--- a/xorg-server/hw/xquartz/quartz.c
+++ b/xorg-server/hw/xquartz/quartz.c
@@ -43,6 +43,7 @@
#include "darwinEvents.h"
#include "pseudoramiX.h"
#include "extension.h"
+#include "nonsdk_extinit.h"
#include "glx_extinit.h"
#define _APPLEWM_SERVER_
#include "applewmExt.h"
diff --git a/xorg-server/hw/xquartz/xpr/xprScreen.c b/xorg-server/hw/xquartz/xpr/xprScreen.c
index d0a525ff4..30f2218b6 100644
--- a/xorg-server/hw/xquartz/xpr/xprScreen.c
+++ b/xorg-server/hw/xquartz/xpr/xprScreen.c
@@ -54,6 +54,8 @@
#include "damage.h"
#endif
+#include "nonsdk_extinit.h"
+
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
// From NSApplication.h
extern const double NSAppKitVersionNumber;
diff --git a/xorg-server/hw/xwayland/Makefile.am b/xorg-server/hw/xwayland/Makefile.am
index 994554088..ab1bbb6a5 100644
--- a/xorg-server/hw/xwayland/Makefile.am
+++ b/xorg-server/hw/xwayland/Makefile.am
@@ -43,6 +43,7 @@ xwayland-glamor.c : $(nodist_Xwayland_SOURCES)
glamor_lib = $(top_builddir)/glamor/libglamor.la
Xwayland_LDADD += $(GLAMOR_LIBS) $(GBM_LIBS) -lEGL -lGL
+Xwayland_DEPENDENCIES = $(glamor_lib)
endif
EXTRA_DIST = drm.xml
diff --git a/xorg-server/hw/xwayland/xwayland-glamor.c b/xorg-server/hw/xwayland/xwayland-glamor.c
index dd8551840..d06006c70 100644
--- a/xorg-server/hw/xwayland/xwayland-glamor.c
+++ b/xorg-server/hw/xwayland/xwayland-glamor.c
@@ -549,11 +549,7 @@ xwl_glamor_init(struct xwl_screen *xwl_screen)
return FALSE;
}
- if (!glamor_init(xwl_screen->screen,
- GLAMOR_INVERTED_Y_AXIS |
- GLAMOR_USE_EGL_SCREEN |
- GLAMOR_USE_SCREEN |
- GLAMOR_USE_PICTURE_SCREEN)) {
+ if (!glamor_init(xwl_screen->screen, GLAMOR_USE_EGL_SCREEN)) {
ErrorF("Failed to initialize glamor\n");
return FALSE;
}
diff --git a/xorg-server/hw/xwin/InitOutput.c b/xorg-server/hw/xwin/InitOutput.c
index 654c58c14..b6f258313 100644
--- a/xorg-server/hw/xwin/InitOutput.c
+++ b/xorg-server/hw/xwin/InitOutput.c
@@ -58,6 +58,11 @@ typedef WINAPI HRESULT(*SHGETFOLDERPATHPROC) (HWND hwndOwner,
HANDLE hToken,
DWORD dwFlags, LPTSTR pszPath);
#endif
+
+#include "winmonitors.h"
+#include "nonsdk_extinit.h"
+#include "pseudoramiX/pseudoramiX.h"
+
#include "glx_extinit.h"
#ifdef XWIN_GLX_WINDOWS
#include "glx/glwindows.h"
@@ -733,13 +738,12 @@ winUseMsg(void)
ErrorF("-engine engine_type_id\n"
"\tOverride the server's automatically selected engine type:\n"
"\t\t1 - Shadow GDI\n"
- "\t\t2 - Shadow DirectDraw\n"
"\t\t4 - Shadow DirectDraw4 Non-Locking\n"
);
ErrorF("-fullscreen\n" "\tRun the server in fullscreen mode.\n");
- ErrorF("-hostintitle\n"
+ ErrorF("-[no]hostintitle\n"
"\tIn multiwindow mode, add remote host names to window titles.\n");
ErrorF("-ignoreinput\n" "\tIgnore keyboard and mouse input.\n");
@@ -973,6 +977,59 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
}
}
+ /*
+ Unless full xinerama has been explicitly enabled, register all native screens with pseudoramiX
+ */
+ if (!noPanoramiXExtension)
+ noPseudoramiXExtension = TRUE;
+
+ if ((g_ScreenInfo[0].fMultipleMonitors) && !noPseudoramiXExtension)
+ {
+ int pass;
+
+ PseudoramiXExtensionInit();
+
+ /* Add primary monitor on pass 0, other monitors on pass 1, to ensure
+ the primary monitor is first in XINERAMA list */
+ for (pass = 0; pass < 2; pass++)
+ {
+ int iMonitor;
+
+ for (iMonitor = 1; ; iMonitor++)
+ {
+ struct GetMonitorInfoData data;
+ QueryMonitor(iMonitor, &data);
+ if (data.bMonitorSpecifiedExists)
+ {
+ MONITORINFO mi;
+ mi.cbSize = sizeof(MONITORINFO);
+
+ if (GetMonitorInfo(data.monitorHandle, &mi))
+ {
+ /* pass == 1 XOR primary monitor flags is set */
+ if ((!(pass == 1)) != (!(mi.dwFlags & MONITORINFOF_PRIMARY)))
+ {
+ /*
+ Note the screen origin in a normalized coordinate space where (0,0) is at the top left
+ of the native virtual desktop area
+ */
+ data.monitorOffsetX = data.monitorOffsetX - GetSystemMetrics(SM_XVIRTUALSCREEN);
+ data.monitorOffsetY = data.monitorOffsetY - GetSystemMetrics(SM_YVIRTUALSCREEN);
+
+ winDebug ("InitOutput - screen %d added at virtual desktop coordinate (%d,%d) (pseudoramiX) \n",
+ iMonitor-1, data.monitorOffsetX, data.monitorOffsetY);
+
+ PseudoramiXAddScreen(data.monitorOffsetX, data.monitorOffsetY,
+ data.monitorWidth, data.monitorHeight);
+ }
+ }
+ }
+ else
+ break;
+ }
+ }
+ }
+
#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
/* Generate a cookie used by internal clients for authorization */
diff --git a/xorg-server/hw/xwin/Makefile.am b/xorg-server/hw/xwin/Makefile.am
index 0ea8ba769..4da3d12a4 100644
--- a/xorg-server/hw/xwin/Makefile.am
+++ b/xorg-server/hw/xwin/Makefile.am
@@ -71,12 +71,12 @@ SRCS = InitInput.c \
winmsgwindow.c \
winmultiwindowclass.c \
winmultiwindowicons.c \
+ winos.c \
winprefs.c \
winprefsyacc.y \
winprefslex.l \
winprocarg.c \
winscrinit.c \
- winshaddd.c \
winshadddnl.c \
winshadgdi.c \
wintaskbar.c \
diff --git a/xorg-server/hw/xwin/XWin.exe.manifest b/xorg-server/hw/xwin/XWin.exe.manifest
index 477334fb3..bd44b1066 100644
--- a/xorg-server/hw/xwin/XWin.exe.manifest
+++ b/xorg-server/hw/xwin/XWin.exe.manifest
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
- <description>The XWin X Windows server for Cygwin.</description>
+ <description>The XWin X Windows server</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
@@ -18,4 +18,18 @@
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <!-- Windows Vista -->
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ <!-- Windows 7 -->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ <!-- Windows 8 -->
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+ <!-- Windows 8.1 -->
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+ <!-- Windows 10 -->
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+ </application>
+ </compatibility>
</assembly>
diff --git a/xorg-server/hw/xwin/glx/gen_gl_wrappers.py b/xorg-server/hw/xwin/glx/gen_gl_wrappers.py
index 69ab1efa9..b9e8dda75 100644
--- a/xorg-server/hw/xwin/glx/gen_gl_wrappers.py
+++ b/xorg-server/hw/xwin/glx/gen_gl_wrappers.py
@@ -123,6 +123,36 @@ else:
errWarn = sys.stderr
diag = open(diagFilename, 'w')
+def ParseCmdRettype(cmd):
+ proto=noneStr(cmd.elem.find('proto'))
+ rettype=noneStr(proto.text)
+ if rettype.lower()!="void ":
+ plist = ([t for t in proto.itertext()])
+ rettype = ''.join(plist[:-1])
+ rettype=rettype.strip()
+ return rettype
+
+def ParseCmdParams(cmd):
+ params = cmd.elem.findall('param')
+ plist=[]
+ for param in params:
+ # construct the formal parameter definition from ptype and name
+ # elements, also using any text found around these in the
+ # param element, in the order it appears in the document
+ paramtype = ''
+ # also extract the formal parameter name from the name element
+ paramname = ''
+ for t in param.iter():
+ if t.tag == 'ptype' or t.tag == 'param':
+ paramtype = paramtype + noneStr(t.text)
+ if t.tag == 'name':
+ paramname = t.text + '_'
+ paramtype = paramtype + ' ' + paramname
+ if t.tail is not None:
+ paramtype = paramtype + t.tail.strip()
+ plist.append((paramtype, paramname))
+ return plist
+
class PreResolveOutputGenerator(OutputGenerator):
def __init__(self,
errFile = sys.stderr,
@@ -179,25 +209,15 @@ class WrapperOutputGenerator(OutputGenerator):
if prefix == 'wgl' and not name in used_wgl_ext_fns:
return
- proto=noneStr(cmd.elem.find('proto'))
- rettype=noneStr(proto.text)
- if rettype.lower()!="void ":
- plist = ([t for t in proto.itertext()])
- rettype = ''.join(plist[:-1])
- rettype=rettype.strip()
+ rettype=ParseCmdRettype(cmd)
+
if staticwrappers: self.outFile.write("static ")
self.outFile.write("%s %sWrapper("%(rettype, name))
- params = cmd.elem.findall('param')
- plist=[]
- for param in params:
- paramlist = ([t for t in param.itertext()])
- paramtype = ''.join(paramlist[:-1])
- paramname = paramlist[-1]
- plist.append((paramtype, paramname))
+ plist=ParseCmdParams(cmd)
Comma=""
if len(plist):
for ptype, pname in plist:
- self.outFile.write("%s%s%s_"%(Comma, ptype, pname))
+ self.outFile.write("%s%s"%(Comma, ptype))
Comma=", "
else:
self.outFile.write("void")
@@ -218,7 +238,7 @@ class WrapperOutputGenerator(OutputGenerator):
Comma=""
for ptype, pname in plist:
- self.outFile.write("%s%s_"%(Comma, pname))
+ self.outFile.write("%s%s"%(Comma, pname))
Comma=", "
# for GL 1.2+ functions, generate stdcall wrappers which use wglGetProcAddress()
@@ -244,7 +264,7 @@ class WrapperOutputGenerator(OutputGenerator):
Comma=""
for ptype, pname in plist:
- self.outFile.write("%s%s_"%(Comma, pname))
+ self.outFile.write("%s%s"%(Comma, pname))
Comma=", "
self.outFile.write(" );\n}\n\n")
@@ -270,24 +290,14 @@ class ThunkOutputGenerator(OutputGenerator):
def genCmd(self, cmd, name):
OutputGenerator.genCmd(self, cmd, name)
- proto=noneStr(cmd.elem.find('proto'))
- rettype=noneStr(proto.text)
- if rettype.lower()!="void ":
- plist = ([t for t in proto.itertext()])
- rettype = ''.join(plist[:-1])
- rettype=rettype.strip()
+ rettype=ParseCmdRettype(cmd)
self.outFile.write("%s %sWrapper("%(rettype, name))
- params = cmd.elem.findall('param')
- plist=[]
- for param in params:
- paramlist = ([t for t in param.itertext()])
- paramtype = ''.join(paramlist[:-1])
- paramname = paramlist[-1]
- plist.append((paramtype, paramname))
+ plist=ParseCmdParams(cmd)
+
Comma=""
if len(plist):
for ptype, pname in plist:
- self.outFile.write("%s%s%s_"%(Comma, ptype, pname))
+ self.outFile.write("%s%s"%(Comma, ptype))
Comma=", "
else:
self.outFile.write("void")
@@ -303,7 +313,7 @@ class ThunkOutputGenerator(OutputGenerator):
Comma=""
for ptype, pname in plist:
- self.outFile.write("%s%s_"%(Comma, pname))
+ self.outFile.write("%s%s"%(Comma, pname))
Comma=", "
# for GL 1.2+ functions, generate wrappers which use wglGetProcAddress()
@@ -317,7 +327,7 @@ class ThunkOutputGenerator(OutputGenerator):
Comma=""
for ptype, pname in plist:
- self.outFile.write("%s%s_"%(Comma, pname))
+ self.outFile.write("%s%s"%(Comma, pname))
Comma=", "
self.outFile.write(" );\n}\n\n")
@@ -372,24 +382,14 @@ class ShimOutputGenerator(OutputGenerator):
return
# for GL functions which are in the ABI, generate a shim which calls the function via GetProcAddress
- proto=noneStr(cmd.elem.find('proto'))
- rettype=noneStr(proto.text)
- if rettype.lower()!="void ":
- plist = ([t for t in proto.itertext()])
- rettype = ''.join(plist[:-1])
- rettype=rettype.strip()
+ rettype=ParseCmdRettype(cmd)
self.outFile.write("%s %s("%(rettype, name))
- params = cmd.elem.findall('param')
- plist=[]
- for param in params:
- paramlist = ([t for t in param.itertext()])
- paramtype = ''.join(paramlist[:-1])
- paramname = paramlist[-1]
- plist.append((paramtype, paramname))
+ plist=ParseCmdParams(cmd)
+
Comma=""
if len(plist):
for ptype, pname in plist:
- self.outFile.write("%s%s%s_"%(Comma, ptype, pname))
+ self.outFile.write("%s%s"%(Comma, ptype))
Comma=", "
else:
self.outFile.write("void")
@@ -401,7 +401,7 @@ class ShimOutputGenerator(OutputGenerator):
if len(plist):
Comma=""
for ptype, pname in plist:
- self.outFile.write("%s %s %s_"%(Comma, ptype, pname))
+ self.outFile.write("%s %s"%(Comma, ptype))
Comma=", "
else:
self.outFile.write("void")
@@ -417,7 +417,7 @@ class ShimOutputGenerator(OutputGenerator):
Comma=""
for ptype, pname in plist:
- self.outFile.write("%s%s_"%(Comma, pname))
+ self.outFile.write("%s%s"%(Comma, pname))
Comma=", "
self.outFile.write(" );\n}\n\n")
diff --git a/xorg-server/hw/xwin/man/XWin.man b/xorg-server/hw/xwin/man/XWin.man
index 15a57db02..d68ee2a41 100644
--- a/xorg-server/hw/xwin/man/XWin.man
+++ b/xorg-server/hw/xwin/man/XWin.man
@@ -76,6 +76,9 @@ preceeding \fB\-screen\fP parameter.
.B \-[no]multimonitors or \-[no]multiplemonitors
Create a screen 0 that covers all monitors [the primary monitor] on a system with
multiple monitors.
+Fake XINERAMA data is created describing the individual monitors,
+(This is similar to the 'merged framebuffer' or 'pseudo-xinerama' mode provided by
+some drivers for the xorg X server).
This option is currently enabled by default in \fB\-multiwindow\fP mode.
.TP 8
.B "\-screen \fIscreen_number\fP [\fIW\fP \fIH\fP [\fIX\fP \fIY\fP] | [[\fIW\fPx\fIH\fP[+\fIX\fP+\fIY\fP]][@\fIM\fP]] ] "
@@ -167,9 +170,10 @@ on its own is equivalent to \fB\-resize=randr\fP
.SH OPTIONS FOR MULTIWINDOW MODE
.TP 8
-.B \-hostintitle
+.B \-[no]hostintitle
Add the host name to the window title for X applications which are running
on remote hosts, when that information is available and it's useful to do so.
+The default is enabled.
.SH OPTIONS CONTROLLING WINDOWS INTEGRATION
.TP 8
@@ -244,9 +248,6 @@ functionality does not provide a benefit at any number of boxes; we
can only determine the usefulness of this feature through testing.
This option probably has limited effect on current \fIWindows\fP versions
as they already perform GDI batching.
-This parameter works in conjunction with engines 1, 2, and 4 (Shadow
-GDI, Shadow DirectDraw, and Shadow DirectDraw Non-Locking,
-respectively).
.TP 8
.B "\-engine \fIengine_type_id\fP"
This option, which is intended for Cygwin/X developers,
@@ -261,8 +262,6 @@ The engine type ids are:
.RS
.IP 1 4
Shadow GDI
-.IP 2 4
-Shadow DirectDraw
.IP 4 4
Shadow DirectDraw Non-Locking
.RE
diff --git a/xorg-server/hw/xwin/win.h b/xorg-server/hw/xwin/win.h
index b7d20ca73..5710ea852 100644
--- a/xorg-server/hw/xwin/win.h
+++ b/xorg-server/hw/xwin/win.h
@@ -101,7 +101,6 @@
#define WIN_SERVER_NONE 0x0L /* 0 */
#define WIN_SERVER_SHADOW_GDI 0x1L /* 1 */
-#define WIN_SERVER_SHADOW_DD 0x2L /* 2 */
#define WIN_SERVER_SHADOW_DDNL 0x4L /* 4 */
#define AltMapIndex Mod1MapIndex
@@ -468,35 +467,20 @@ typedef struct _winPrivScreenRec {
int iE3BCachedPress;
Bool fE3BFakeButton2Sent;
- /* Privates used by shadow fb GDI server */
+ /* Privates used by shadow fb GDI engine */
HBITMAP hbmpShadow;
HDC hdcScreen;
HDC hdcShadow;
HWND hwndScreen;
BITMAPINFOHEADER *pbmih;
- /* Privates used by shadow fb and primary fb DirectDraw servers */
+ /* Privates used by shadow fb DirectDraw Nonlocking engine */
LPDIRECTDRAW pdd;
- LPDIRECTDRAWSURFACE2 pddsPrimary;
- LPDIRECTDRAW2 pdd2;
-
- /* Privates used by shadow fb DirectDraw server */
- LPDIRECTDRAWSURFACE2 pddsShadow;
- LPDDSURFACEDESC pddsdShadow;
-
- /* Privates used by primary fb DirectDraw server */
- LPDIRECTDRAWSURFACE2 pddsOffscreen;
- LPDDSURFACEDESC pddsdOffscreen;
- LPDDSURFACEDESC pddsdPrimary;
-
- /* Privates used by shadow fb DirectDraw Nonlocking server */
LPDIRECTDRAW4 pdd4;
LPDIRECTDRAWSURFACE4 pddsShadow4;
LPDIRECTDRAWSURFACE4 pddsPrimary4;
- BOOL fRetryCreateSurface;
-
- /* Privates used by both shadow fb DirectDraw servers */
LPDIRECTDRAWCLIPPER pddcPrimary;
+ BOOL fRetryCreateSurface;
#ifdef XWIN_MULTIWINDOWEXTWM
/* Privates used by multi-window external window manager */
@@ -921,13 +905,6 @@ Bool
winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv);
/*
- * winshaddd.c
- */
-
-Bool
- winSetEngineFunctionsShadowDD(ScreenPtr pScreen);
-
-/*
* winshadddnl.c
*/
@@ -1219,6 +1196,12 @@ Bool
winCreateMsgWindowThread(void);
/*
+ * winos.c
+ */
+void
+winOS(void);
+
+/*
* END DDX and DIX Function Prototypes
*/
diff --git a/xorg-server/hw/xwin/winengine.c b/xorg-server/hw/xwin/winengine.c
index b473b3ac0..b8f8da06b 100644
--- a/xorg-server/hw/xwin/winengine.c
+++ b/xorg-server/hw/xwin/winengine.c
@@ -54,16 +54,9 @@ static HMODULE g_hmodDirectDraw = NULL;
void
winDetectSupportedEngines(void)
{
- OSVERSIONINFO osvi;
-
/* Initialize the engine support flags */
g_dwEnginesSupported = WIN_SERVER_SHADOW_GDI;
- /* Get operating system version information */
- ZeroMemory(&osvi, sizeof(osvi));
- osvi.dwOSVersionInfoSize = sizeof(osvi);
- GetVersionEx(&osvi);
-
/* Do we have DirectDraw? */
if (g_hmodDirectDraw != NULL) {
LPDIRECTDRAW lpdd = NULL;
@@ -85,12 +78,6 @@ winDetectSupportedEngines(void)
"winDetectSupportedEngines - DirectDraw not installed\n");
return;
}
- else {
- /* We have DirectDraw */
- winErrorFVerb(2,
- "winDetectSupportedEngines - DirectDraw installed, allowing ShadowDD\n");
- g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD;
- }
/* Try to query for DirectDraw4 interface */
ddrval = IDirectDraw_QueryInterface(lpdd,
@@ -187,9 +174,6 @@ winSetEngine(ScreenPtr pScreen)
case WIN_SERVER_SHADOW_GDI:
winSetEngineFunctionsShadowGDI(pScreen);
break;
- case WIN_SERVER_SHADOW_DD:
- winSetEngineFunctionsShadowDD(pScreen);
- break;
case WIN_SERVER_SHADOW_DDNL:
winSetEngineFunctionsShadowDDNL(pScreen);
break;
@@ -209,16 +193,6 @@ winSetEngine(ScreenPtr pScreen)
return TRUE;
}
- /* ShadowDD is next in line */
- if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DD) {
- winErrorFVerb(2, "winSetEngine - Using Shadow DirectDraw\n");
- pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DD;
-
- /* Set engine function pointers */
- winSetEngineFunctionsShadowDD(pScreen);
- return TRUE;
- }
-
/* ShadowGDI is next in line */
if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) {
winErrorFVerb(2, "winSetEngine - Using Shadow GDI DIB\n");
diff --git a/xorg-server/hw/xwin/winglobals.c b/xorg-server/hw/xwin/winglobals.c
index ad82b83f6..1382c8972 100644
--- a/xorg-server/hw/xwin/winglobals.c
+++ b/xorg-server/hw/xwin/winglobals.c
@@ -78,7 +78,7 @@ Bool g_fNoHelpMessageBox = FALSE;
Bool g_fSoftwareCursor = FALSE;
Bool g_fSilentDupError = FALSE;
Bool g_fNativeGl = TRUE;
-Bool g_fHostInTitle = FALSE;
+Bool g_fHostInTitle = TRUE;
pthread_mutex_t g_pmTerminating = PTHREAD_MUTEX_INITIALIZER;
#ifdef XWIN_CLIPBOARD
diff --git a/xorg-server/hw/xwin/winos.c b/xorg-server/hw/xwin/winos.c
new file mode 100644
index 000000000..0d825bb83
--- /dev/null
+++ b/xorg-server/hw/xwin/winos.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010-2014 Colin Harrison All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ *
+ * Author: Colin Harrison
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
+
+static const char*
+IsWow64(void)
+{
+#ifdef __x86_64__
+ return " (64-bit)";
+#else
+ WINBOOL bIsWow64;
+ LPFN_ISWOW64PROCESS fnIsWow64Process =
+ (LPFN_ISWOW64PROCESS) GetProcAddress(GetModuleHandle(TEXT("kernel32")),
+ "IsWow64Process");
+ if (NULL != fnIsWow64Process) {
+ if (fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
+ return bIsWow64 ? " (WoW64)" : " (32-bit)";
+ }
+
+ /* OS doesn't support IsWow64Process() */
+ return "";
+#endif
+}
+
+/*
+ * Report the OS version
+ */
+
+void
+winOS(void)
+{
+ OSVERSIONINFOEX osvi = {0};
+
+ /* Get operating system version information */
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ GetVersionEx((LPOSVERSIONINFO)&osvi);
+
+ ErrorF("OS: Windows NT %d.%d build %d%s\n",
+ (int)osvi.dwMajorVersion, (int)osvi.dwMinorVersion,
+ (int)osvi.dwBuildNumber, IsWow64());
+}
diff --git a/xorg-server/hw/xwin/winprocarg.c b/xorg-server/hw/xwin/winprocarg.c
index e8cccb4c2..73aa027d8 100644
--- a/xorg-server/hw/xwin/winprocarg.c
+++ b/xorg-server/hw/xwin/winprocarg.c
@@ -31,6 +31,10 @@ from The Open Group.
#include <xwin-config.h>
#endif
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
#include <../xfree86/common/xorgVersion.h>
#include "win.h"
#include "winconfig.h"
@@ -1094,6 +1098,11 @@ ddxProcessArgument(int argc, char *argv[], int i)
return 1;
}
+ if (IS_OPTION("-nohostintitle")) {
+ g_fHostInTitle = FALSE;
+ return 1;
+ }
+
return 0;
}
@@ -1181,6 +1190,17 @@ winLogVersionInfo(void)
ErrorF("Vendor: %s\n", XVENDORNAME);
ErrorF("Release: %d.%d.%d.%d\n", XORG_VERSION_MAJOR,
XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP);
+#ifdef HAVE_SYS_UTSNAME_H
+ {
+ struct utsname name;
+
+ if (uname(&name) >= 0) {
+ ErrorF("OS: %s %s %s %s %s\n", name.sysname, name.nodename,
+ name.release, name.version, name.machine);
+ }
+ }
+#endif
+ winOS();
if (strlen(BUILDERSTRING))
ErrorF("%s\n", BUILDERSTRING);
ErrorF("Contact: %s\n", BUILDERADDR);
diff --git a/xorg-server/hw/xwin/winscrinit.c b/xorg-server/hw/xwin/winscrinit.c
index ce0aada31..e68ee1227 100644
--- a/xorg-server/hw/xwin/winscrinit.c
+++ b/xorg-server/hw/xwin/winscrinit.c
@@ -216,15 +216,19 @@ winScreenInit(ScreenPtr pScreen, int argc, char **argv)
else
winErrorFVerb(2, "winScreenInit - Using software cursor\n");
- /*
- Note the screen origin in a normalized coordinate space where (0,0) is at the top left
- of the native virtual desktop area
- */
- pScreen->x = pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN);
- pScreen->y = pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN);
+ if (!noPanoramiXExtension) {
+ /*
+ Note the screen origin in a normalized coordinate space where (0,0) is at the top left
+ of the native virtual desktop area
+ */
+ pScreen->x =
+ pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN);
+ pScreen->y =
+ pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN);
- ErrorF("Screen %d added at virtual desktop coordinate (%d,%d).\n",
- pScreen->myNum, pScreen->x, pScreen->y);
+ ErrorF("Screen %d added at virtual desktop coordinate (%d,%d).\n",
+ pScreen->myNum, pScreen->x, pScreen->y);
+ }
#if CYGDEBUG || YES
winDebug("winScreenInit - returning\n");
@@ -309,8 +313,6 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
if (pScreenInfo->dwDepth == 8
&& (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
|| (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
- && pScreenInfo->fFullScreen)
- || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
&& pScreenInfo->fFullScreen))) {
winSetColormapFunctions(pScreen);
@@ -384,7 +386,6 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
/* Initialize the shadow framebuffer layer */
if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
- || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
|| pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)
#ifdef XWIN_MULTIWINDOWEXTWM
&& !pScreenInfo->fMWExtWM
diff --git a/xorg-server/hw/xwin/winshaddd.c b/xorg-server/hw/xwin/winshaddd.c
deleted file mode 100644
index 4904eb440..000000000
--- a/xorg-server/hw/xwin/winshaddd.c
+++ /dev/null
@@ -1,1221 +0,0 @@
-/*
- *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- *
- *Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- *"Software"), to deal in the Software without restriction, including
- *without limitation the rights to use, copy, modify, merge, publish,
- *distribute, sublicense, and/or sell copies of the Software, and to
- *permit persons to whom the Software is furnished to do so, subject to
- *the following conditions:
- *
- *The above copyright notice and this permission notice shall be
- *included in all copies or substantial portions of the Software.
- *
- *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
- *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- *Except as contained in this notice, the name of the XFree86 Project
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from the XFree86 Project.
- *
- * Authors: Dakshinamurthy Karra
- * Suhaib M Siddiqi
- * Peter Busch
- * Harold L Hunt II
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-
-/*
- * Local prototypes
- */
-
-static Bool
- winAllocateFBShadowDD(ScreenPtr pScreen);
-
-static void
- winShadowUpdateDD(ScreenPtr pScreen, shadowBufPtr pBuf);
-
-static Bool
- winCloseScreenShadowDD(ScreenPtr pScreen);
-
-static Bool
- winInitVisualsShadowDD(ScreenPtr pScreen);
-
-static Bool
- winAdjustVideoModeShadowDD(ScreenPtr pScreen);
-
-static Bool
- winBltExposedRegionsShadowDD(ScreenPtr pScreen);
-
-static Bool
- winActivateAppShadowDD(ScreenPtr pScreen);
-
-static Bool
- winRedrawScreenShadowDD(ScreenPtr pScreen);
-
-static Bool
- winRealizeInstalledPaletteShadowDD(ScreenPtr pScreen);
-
-static Bool
- winInstallColormapShadowDD(ColormapPtr pColormap);
-
-static Bool
- winStoreColorsShadowDD(ColormapPtr pmap, int ndef, xColorItem * pdefs);
-
-static Bool
- winCreateColormapShadowDD(ColormapPtr pColormap);
-
-static Bool
- winDestroyColormapShadowDD(ColormapPtr pColormap);
-
-static Bool
- winCreatePrimarySurfaceShadowDD(ScreenPtr pScreen);
-
-static Bool
- winReleasePrimarySurfaceShadowDD(ScreenPtr pScreen);
-
-/*
- * Create the primary surface and attach the clipper.
- * Used for both the initial surface creation and during
- * WM_DISPLAYCHANGE messages.
- */
-
-static Bool
-winCreatePrimarySurfaceShadowDD(ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- HRESULT ddrval = DD_OK;
- DDSURFACEDESC ddsd;
-
- /* Describe the primary surface */
- ZeroMemory(&ddsd, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-
- /* Create the primary surface */
- ddrval = IDirectDraw2_CreateSurface(pScreenPriv->pdd2,
- &ddsd, &pScreenPriv->pddsPrimary, NULL);
- if (FAILED(ddrval)) {
- ErrorF("winCreatePrimarySurfaceShadowDD - Could not create primary "
- "surface: %08x\n", (unsigned int) ddrval);
- return FALSE;
- }
-
-#if CYGDEBUG
- winDebug("winCreatePrimarySurfaceShadowDD - Created primary surface\n");
-#endif
-
- /*
- * Attach a clipper to the primary surface that will clip our blits to our
- * display window.
- */
- ddrval = IDirectDrawSurface2_SetClipper(pScreenPriv->pddsPrimary,
- pScreenPriv->pddcPrimary);
- if (FAILED(ddrval)) {
- ErrorF("winCreatePrimarySurfaceShadowDD - Primary attach clipper "
- "failed: %08x\n", (unsigned int) ddrval);
- return FALSE;
- }
-
-#if CYGDEBUG
- winDebug("winCreatePrimarySurfaceShadowDD - Attached clipper to "
- "primary surface\n");
-#endif
-
- /* Everything was correct */
- return TRUE;
-}
-
-/*
- * Detach the clipper and release the primary surface.
- * Called from WM_DISPLAYCHANGE.
- */
-
-static Bool
-winReleasePrimarySurfaceShadowDD(ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
-
- ErrorF("winReleasePrimarySurfaceShadowDD - Hello\n");
-
- /* Release the primary surface and clipper, if they exist */
- if (pScreenPriv->pddsPrimary) {
- /*
- * Detach the clipper from the primary surface.
- * NOTE: We do this explicity for clarity. The Clipper is not released.
- */
- IDirectDrawSurface2_SetClipper(pScreenPriv->pddsPrimary, NULL);
-
- ErrorF("winReleasePrimarySurfaceShadowDD - Detached clipper\n");
-
- /* Release the primary surface */
- IDirectDrawSurface2_Release(pScreenPriv->pddsPrimary);
- pScreenPriv->pddsPrimary = NULL;
- }
-
- ErrorF("winReleasePrimarySurfaceShadowDD - Released primary surface\n");
-
- return TRUE;
-}
-
-/*
- * Create a DirectDraw surface for the shadow framebuffer; also create
- * a primary surface object so we can blit to the display.
- *
- * Install a DirectDraw clipper on our primary surface object
- * that clips our blits to the unobscured client area of our display window.
- */
-
-static Bool
-winAllocateFBShadowDD(ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
- HRESULT ddrval = DD_OK;
- DDSURFACEDESC ddsd;
- DDSURFACEDESC *pddsdShadow = NULL;
-
-#if CYGDEBUG
- winDebug("winAllocateFBShadowDD\n");
-#endif
-
- /* Create a clipper */
- ddrval = (*g_fpDirectDrawCreateClipper) (0,
- &pScreenPriv->pddcPrimary, NULL);
- if (FAILED(ddrval)) {
- ErrorF("winAllocateFBShadowDD - Could not create clipper: %08x\n",
- (unsigned int) ddrval);
- return FALSE;
- }
-
-#if CYGDEBUG
- winDebug("winAllocateFBShadowDD - Created a clipper\n");
-#endif
-
- /* Attach the clipper to our display window */
- ddrval = IDirectDrawClipper_SetHWnd(pScreenPriv->pddcPrimary,
- 0, pScreenPriv->hwndScreen);
- if (FAILED(ddrval)) {
- ErrorF("winAllocateFBShadowDD - Clipper not attached to "
- "window: %08x\n", (unsigned int) ddrval);
- return FALSE;
- }
-
-#if CYGDEBUG
- winDebug("winAllocateFBShadowDD - Attached clipper to window\n");
-#endif
-
- /* Create a DirectDraw object, store the address at lpdd */
- ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL);
- if (FAILED(ddrval)) {
- ErrorF("winAllocateFBShadowDD - Could not start DirectDraw: %08x\n",
- (unsigned int) ddrval);
- return FALSE;
- }
-
-#if CYGDEBUG
- winDebug("winAllocateFBShadowDD () - Created and initialized DD\n");
-#endif
-
- /* Get a DirectDraw2 interface pointer */
- ddrval = IDirectDraw_QueryInterface(pScreenPriv->pdd,
- &IID_IDirectDraw2,
- (LPVOID *) &pScreenPriv->pdd2);
- if (FAILED(ddrval)) {
- ErrorF("winAllocateFBShadowDD - Failed DD2 query: %08x\n",
- (unsigned int) ddrval);
- return FALSE;
- }
-
- /* Are we full screen? */
- if (pScreenInfo->fFullScreen) {
- DDSURFACEDESC ddsdCurrent;
- DWORD dwRefreshRateCurrent = 0;
- HDC hdc = NULL;
-
- /* Set the cooperative level to full screen */
- ddrval = IDirectDraw2_SetCooperativeLevel(pScreenPriv->pdd2,
- pScreenPriv->hwndScreen,
- DDSCL_EXCLUSIVE
- | DDSCL_FULLSCREEN);
- if (FAILED(ddrval)) {
- ErrorF("winAllocateFBShadowDD - Could not set "
- "cooperative level: %08x\n", (unsigned int) ddrval);
- return FALSE;
- }
-
- /*
- * We only need to get the current refresh rate for comparison
- * if a refresh rate has been passed on the command line.
- */
- if (pScreenInfo->dwRefreshRate != 0) {
- ZeroMemory(&ddsdCurrent, sizeof(ddsdCurrent));
- ddsdCurrent.dwSize = sizeof(ddsdCurrent);
-
- /* Get information about current display settings */
- ddrval = IDirectDraw2_GetDisplayMode(pScreenPriv->pdd2,
- &ddsdCurrent);
- if (FAILED(ddrval)) {
- ErrorF("winAllocateFBShadowDD - Could not get current "
- "refresh rate: %08x. Continuing.\n",
- (unsigned int) ddrval);
- dwRefreshRateCurrent = 0;
- }
- else {
- /* Grab the current refresh rate */
- dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate;
- }
- }
-
- /* Clean up the refresh rate */
- if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) {
- /*
- * Refresh rate is non-specified or equal to current.
- */
- pScreenInfo->dwRefreshRate = 0;
- }
-
- /* Grab a device context for the screen */
- hdc = GetDC(NULL);
- if (hdc == NULL) {
- ErrorF("winAllocateFBShadowDD - GetDC () failed\n");
- return FALSE;
- }
-
- /* Only change the video mode when different than current mode */
- if (!pScreenInfo->fMultipleMonitors
- && (pScreenInfo->dwWidth != GetSystemMetrics(SM_CXSCREEN)
- || pScreenInfo->dwHeight != GetSystemMetrics(SM_CYSCREEN)
- || pScreenInfo->dwBPP != GetDeviceCaps(hdc, BITSPIXEL)
- || pScreenInfo->dwRefreshRate != 0)) {
- ErrorF("winAllocateFBShadowDD - Changing video mode\n");
-
- /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */
- ddrval = IDirectDraw2_SetDisplayMode(pScreenPriv->pdd2,
- pScreenInfo->dwWidth,
- pScreenInfo->dwHeight,
- pScreenInfo->dwBPP,
- pScreenInfo->dwRefreshRate, 0);
- if (FAILED(ddrval)) {
- ErrorF("winAllocateFBShadowDD - Could not set "
- "full screen display mode: %08x\n",
- (unsigned int) ddrval);
- ErrorF
- ("winAllocateFBShadowDD - Using default driver refresh rate\n");
- ddrval =
- IDirectDraw2_SetDisplayMode(pScreenPriv->pdd2,
- pScreenInfo->dwWidth,
- pScreenInfo->dwHeight,
- pScreenInfo->dwBPP, 0, 0);
- if (FAILED(ddrval)) {
- ErrorF
- ("winAllocateFBShadowDD - Could not set default refresh rate "
- "full screen display mode: %08x\n",
- (unsigned int) ddrval);
- return FALSE;
- }
- }
- }
- else {
- ErrorF("winAllocateFBShadowDD - Not changing video mode\n");
- }
-
- /* Release our DC */
- ReleaseDC(NULL, hdc);
- hdc = NULL;
- }
- else {
- /* Set the cooperative level for windowed mode */
- ddrval = IDirectDraw2_SetCooperativeLevel(pScreenPriv->pdd2,
- pScreenPriv->hwndScreen,
- DDSCL_NORMAL);
- if (FAILED(ddrval)) {
- ErrorF("winAllocateFBShadowDD - Could not set "
- "cooperative level: %08x\n", (unsigned int) ddrval);
- return FALSE;
- }
- }
-
- /* Create the primary surface */
- if (!winCreatePrimarySurfaceShadowDD(pScreen)) {
- ErrorF("winAllocateFBShadowDD - winCreatePrimarySurfaceShadowDD "
- "failed\n");
- return FALSE;
- }
-
- /* Describe the shadow surface to be created */
- /* NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface,
- * as drawing, locking, and unlocking take forever
- * with video memory surfaces. In addition,
- * video memory is a somewhat scarce resource,
- * so you shouldn't be allocating video memory when
- * you have the option of using system memory instead.
- */
- ZeroMemory(&ddsd, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
- ddsd.dwHeight = pScreenInfo->dwHeight;
- ddsd.dwWidth = pScreenInfo->dwWidth;
-
- /* Create the shadow surface */
- ddrval = IDirectDraw2_CreateSurface(pScreenPriv->pdd2,
- &ddsd, &pScreenPriv->pddsShadow, NULL);
- if (FAILED(ddrval)) {
- ErrorF("winAllocateFBShadowDD - Could not create shadow "
- "surface: %08x\n", (unsigned int) ddrval);
- return FALSE;
- }
-
-#if CYGDEBUG
- winDebug("winAllocateFBShadowDD - Created shadow\n");
-#endif
-
- /* Allocate a DD surface description for our screen privates */
- pddsdShadow = pScreenPriv->pddsdShadow = malloc(sizeof(DDSURFACEDESC));
- if (pddsdShadow == NULL) {
- ErrorF("winAllocateFBShadowDD - Could not allocate surface "
- "description memory\n");
- return FALSE;
- }
- ZeroMemory(pddsdShadow, sizeof(*pddsdShadow));
- pddsdShadow->dwSize = sizeof(*pddsdShadow);
-
-#if CYGDEBUG
- winDebug("winAllocateFBShadowDD - Locking shadow\n");
-#endif
-
- /* Lock the shadow surface */
- ddrval = IDirectDrawSurface2_Lock(pScreenPriv->pddsShadow,
- NULL, pddsdShadow, DDLOCK_WAIT, NULL);
- if (FAILED(ddrval) || pddsdShadow->lpSurface == NULL) {
- ErrorF("winAllocateFBShadowDD - Could not lock shadow "
- "surface: %08x\n", (unsigned int) ddrval);
- return FALSE;
- }
-
-#if CYGDEBUG
- winDebug("winAllocateFBShadowDD - Locked shadow\n");
-#endif
-
- /* We don't know how to deal with anything other than RGB */
- if (!(pddsdShadow->ddpfPixelFormat.dwFlags & DDPF_RGB)) {
- ErrorF("winAllocateFBShadowDD - Color format other than RGB\n");
- return FALSE;
- }
-
- /* Grab the pitch from the surface desc */
- pScreenInfo->dwStride = (pddsdShadow->u1.lPitch * 8)
- / pScreenInfo->dwBPP;
-
- /* Save the pointer to our surface memory */
- pScreenInfo->pfb = pddsdShadow->lpSurface;
-
- /* Grab the color depth and masks from the surface description */
- pScreenPriv->dwRedMask = pddsdShadow->ddpfPixelFormat.u2.dwRBitMask;
- pScreenPriv->dwGreenMask = pddsdShadow->ddpfPixelFormat.u3.dwGBitMask;
- pScreenPriv->dwBlueMask = pddsdShadow->ddpfPixelFormat.u4.dwBBitMask;
-
-#if CYGDEBUG
- winDebug("winAllocateFBShadowDD - Returning\n");
-#endif
-
- return TRUE;
-}
-
-static void
-winFreeFBShadowDD(ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-
- /* Free the shadow surface, if there is one */
- if (pScreenPriv->pddsShadow) {
- IDirectDrawSurface2_Unlock(pScreenPriv->pddsShadow, NULL);
- IDirectDrawSurface2_Release(pScreenPriv->pddsShadow);
- pScreenPriv->pddsShadow = NULL;
- }
-
- /* Detach the clipper from the primary surface and release the primary surface, if there is one */
- winReleasePrimarySurfaceShadowDD(pScreen);
-
- /* Release the clipper object */
- if (pScreenPriv->pddcPrimary) {
- IDirectDrawClipper_Release(pScreenPriv->pddcPrimary);
- pScreenPriv->pddcPrimary = NULL;
- }
-
- /* Free the DirectDraw2 object, if there is one */
- if (pScreenPriv->pdd2) {
- IDirectDraw2_RestoreDisplayMode(pScreenPriv->pdd2);
- IDirectDraw2_Release(pScreenPriv->pdd2);
- pScreenPriv->pdd2 = NULL;
- }
-
- /* Free the DirectDraw object, if there is one */
- if (pScreenPriv->pdd) {
- IDirectDraw_Release(pScreenPriv->pdd);
- pScreenPriv->pdd = NULL;
- }
-
- /* Invalidate the ScreenInfo's fb pointer */
- pScreenInfo->pfb = NULL;
-}
-
-/*
- * Transfer the damaged regions of the shadow framebuffer to the display.
- */
-
-static void
-winShadowUpdateDD(ScreenPtr pScreen, shadowBufPtr pBuf)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
- RegionPtr damage = shadowDamage(pBuf);
- HRESULT ddrval = DD_OK;
- RECT rcDest, rcSrc;
- POINT ptOrigin;
- DWORD dwBox = RegionNumRects(damage);
- BoxPtr pBox = RegionRects(damage);
- HRGN hrgnCombined = NULL;
-
- /*
- * Return immediately if the app is not active
- * and we are fullscreen, or if we have a bad display depth
- */
- if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
- || pScreenPriv->fBadDepth)
- return;
-
- /* Return immediately if we didn't get needed surfaces */
- if (!pScreenPriv->pddsPrimary || !pScreenPriv->pddsShadow)
- return;
-
- /* Get the origin of the window in the screen coords */
- ptOrigin.x = pScreenInfo->dwXOffset;
- ptOrigin.y = pScreenInfo->dwYOffset;
- MapWindowPoints(pScreenPriv->hwndScreen,
- HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
-
- /* Unlock the shadow surface, so we can blit */
- ddrval = IDirectDrawSurface2_Unlock(pScreenPriv->pddsShadow, NULL);
- if (FAILED(ddrval)) {
- ErrorF("winShadowUpdateDD - Unlock failed\n");
- return;
- }
-
- /*
- * Handle small regions with multiple blits,
- * handle large regions by creating a clipping region and
- * doing a single blit constrained to that clipping region.
- */
- if (pScreenInfo->dwClipUpdatesNBoxes == 0
- || dwBox < pScreenInfo->dwClipUpdatesNBoxes) {
- /* Loop through all boxes in the damaged region */
- while (dwBox--) {
- /* Assign damage box to source rectangle */
- rcSrc.left = pBox->x1;
- rcSrc.top = pBox->y1;
- rcSrc.right = pBox->x2;
- rcSrc.bottom = pBox->y2;
-
- /* Calculate destination rectange */
- rcDest.left = ptOrigin.x + rcSrc.left;
- rcDest.top = ptOrigin.y + rcSrc.top;
- rcDest.right = ptOrigin.x + rcSrc.right;
- rcDest.bottom = ptOrigin.y + rcSrc.bottom;
-
- /* Blit the damaged areas */
- ddrval = IDirectDrawSurface2_Blt(pScreenPriv->pddsPrimary,
- &rcDest,
- pScreenPriv->pddsShadow,
- &rcSrc, DDBLT_WAIT, NULL);
-
- /* Get a pointer to the next box */
- ++pBox;
- }
- }
- else {
- BoxPtr pBoxExtents = RegionExtents(damage);
-
- /* Compute a GDI region from the damaged region */
- hrgnCombined =
- CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
- pBoxExtents->y2);
-
- /* Install the GDI region as a clipping region */
- SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
- DeleteObject(hrgnCombined);
- hrgnCombined = NULL;
-
- /* Calculating a bounding box for the source is easy */
- rcSrc.left = pBoxExtents->x1;
- rcSrc.top = pBoxExtents->y1;
- rcSrc.right = pBoxExtents->x2;
- rcSrc.bottom = pBoxExtents->y2;
-
- /* Calculating a bounding box for the destination is trickier */
- rcDest.left = ptOrigin.x + rcSrc.left;
- rcDest.top = ptOrigin.y + rcSrc.top;
- rcDest.right = ptOrigin.x + rcSrc.right;
- rcDest.bottom = ptOrigin.y + rcSrc.bottom;
-
- /* Our Blt should be clipped to the invalidated region */
- ddrval = IDirectDrawSurface2_Blt(pScreenPriv->pddsPrimary,
- &rcDest,
- pScreenPriv->pddsShadow,
- &rcSrc, DDBLT_WAIT, NULL);
-
- /* Reset the clip region */
- SelectClipRgn(pScreenPriv->hdcScreen, NULL);
- }
-
- /* Relock the shadow surface */
- ddrval = IDirectDrawSurface2_Lock(pScreenPriv->pddsShadow,
- NULL,
- pScreenPriv->pddsdShadow,
- DDLOCK_WAIT, NULL);
- if (FAILED(ddrval)) {
- ErrorF("winShadowUpdateDD - Lock failed\n");
- return;
- }
-
- /* Has our memory pointer changed? */
- if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) {
- ErrorF("winShadowUpdateDD - Memory location of the shadow "
- "surface has changed, trying to update the root window "
- "pixmap header to point to the new address. If you get "
- "this message and " PROJECT_NAME " freezes or crashes "
- "after this message then send a problem report and your "
- "%s file to " BUILDERADDR "\n", g_pszLogFile);
-
- /* Location of shadow framebuffer has changed */
- winUpdateFBPointer(pScreen, pScreenPriv->pddsdShadow->lpSurface);
- }
-}
-
-static Bool
-winInitScreenShadowDD(ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
-
- /* Get a device context for the screen */
- pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen);
-
- return winAllocateFBShadowDD(pScreen);
-}
-
-/*
- * Call the wrapped CloseScreen function.
- *
- * Free our resources and private structures.
- */
-
-static Bool
-winCloseScreenShadowDD(ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
- Bool fReturn;
-
-#if CYGDEBUG
- winDebug("winCloseScreenShadowDD - Freeing screen resources\n");
-#endif
-
- /* Flag that the screen is closed */
- pScreenPriv->fClosed = TRUE;
- pScreenPriv->fActive = FALSE;
-
- /* Call the wrapped CloseScreen procedure */
- WIN_UNWRAP(CloseScreen);
- if (pScreen->CloseScreen)
- fReturn = (*pScreen->CloseScreen) (pScreen);
-
- winFreeFBShadowDD(pScreen);
-
- /* Free the screen DC */
- ReleaseDC(pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
-
- /* Delete the window property */
- RemoveProp(pScreenPriv->hwndScreen, WIN_SCR_PROP);
-
- /* Delete tray icon, if we have one */
- if (!pScreenInfo->fNoTrayIcon)
- winDeleteNotifyIcon(pScreenPriv);
-
- /* Free the exit confirmation dialog box, if it exists */
- if (g_hDlgExit != NULL) {
- DestroyWindow(g_hDlgExit);
- g_hDlgExit = NULL;
- }
-
- /* Kill our window */
- if (pScreenPriv->hwndScreen) {
- DestroyWindow(pScreenPriv->hwndScreen);
- pScreenPriv->hwndScreen = NULL;
- }
-
-#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
- /* Destroy the thread startup mutex */
- pthread_mutex_destroy(&pScreenPriv->pmServerStarted);
-#endif
-
- /* Kill our screeninfo's pointer to the screen */
- pScreenInfo->pScreen = NULL;
-
- /* Free the screen privates for this screen */
- free((void *) pScreenPriv);
-
- return fReturn;
-}
-
-/*
- * Tell mi what sort of visuals we need.
- *
- * Generally we only need one visual, as our screen can only
- * handle one format at a time, I believe. You may want
- * to verify that last sentence.
- */
-
-static Bool
-winInitVisualsShadowDD(ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
- DWORD dwRedBits, dwGreenBits, dwBlueBits;
-
- /* Count the number of ones in each color mask */
- dwRedBits = winCountBits(pScreenPriv->dwRedMask);
- dwGreenBits = winCountBits(pScreenPriv->dwGreenMask);
- dwBlueBits = winCountBits(pScreenPriv->dwBlueMask);
-
- /* Store the maximum number of ones in a color mask as the bitsPerRGB */
- if (dwRedBits == 0 || dwGreenBits == 0 || dwBlueBits == 0)
- pScreenPriv->dwBitsPerRGB = 8;
- else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
- pScreenPriv->dwBitsPerRGB = dwRedBits;
- else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
- pScreenPriv->dwBitsPerRGB = dwGreenBits;
- else
- pScreenPriv->dwBitsPerRGB = dwBlueBits;
-
- ErrorF("winInitVisualsShadowDD - Masks %08x %08x %08x BPRGB %d d %d "
- "bpp %d\n",
- (unsigned int) pScreenPriv->dwRedMask,
- (unsigned int) pScreenPriv->dwGreenMask,
- (unsigned int) pScreenPriv->dwBlueMask,
- (int) pScreenPriv->dwBitsPerRGB,
- (int) pScreenInfo->dwDepth, (int) pScreenInfo->dwBPP);
-
- /* Create a single visual according to the Windows screen depth */
- switch (pScreenInfo->dwDepth) {
- case 24:
- case 16:
- case 15:
- /* Create the real visual */
- if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
- TrueColorMask,
- pScreenPriv->dwBitsPerRGB,
- TrueColor,
- pScreenPriv->dwRedMask,
- pScreenPriv->dwGreenMask,
- pScreenPriv->dwBlueMask)) {
- ErrorF("winInitVisualsShadowDD - miSetVisualTypesAndMasks "
- "failed for TrueColor\n");
- return FALSE;
- }
-
-#ifdef XWIN_EMULATEPSEUDO
- if (!pScreenInfo->fEmulatePseudo)
- break;
-
- /* Setup a pseudocolor visual */
- if (!miSetVisualTypesAndMasks(8, PseudoColorMask, 8, -1, 0, 0, 0)) {
- ErrorF("winInitVisualsShadowDD - miSetVisualTypesAndMasks "
- "failed for PseudoColor\n");
- return FALSE;
- }
-#endif
- break;
-
- case 8:
- if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
- pScreenInfo->fFullScreen
- ? PseudoColorMask : StaticColorMask,
- pScreenPriv->dwBitsPerRGB,
- pScreenInfo->fFullScreen
- ? PseudoColor : StaticColor,
- pScreenPriv->dwRedMask,
- pScreenPriv->dwGreenMask,
- pScreenPriv->dwBlueMask)) {
- ErrorF("winInitVisualsShadowDD - miSetVisualTypesAndMasks "
- "failed\n");
- return FALSE;
- }
- break;
-
- default:
- ErrorF("winInitVisualsShadowDD - Unknown screen depth\n");
- return FALSE;
- }
-
-#if CYGDEBUG
- winDebug("winInitVisualsShadowDD - Returning\n");
-#endif
-
- return TRUE;
-}
-
-/*
- * Adjust the user proposed video mode
- */
-
-static Bool
-winAdjustVideoModeShadowDD(ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
- HDC hdc = NULL;
- DWORD dwBPP;
-
- /* We're in serious trouble if we can't get a DC */
- hdc = GetDC(NULL);
- if (hdc == NULL) {
- ErrorF("winAdjustVideoModeShadowDD - GetDC () failed\n");
- return FALSE;
- }
-
- /* Query GDI for current display depth */
- dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
-
- /* DirectDraw can only change the depth in fullscreen mode */
- if (!(pScreenInfo->fFullScreen && (pScreenInfo->dwBPP != WIN_DEFAULT_BPP))) {
- /* Otherwise, We'll use GDI's depth */
- pScreenInfo->dwBPP = dwBPP;
- }
-
- /* Release our DC */
- ReleaseDC(NULL, hdc);
- return TRUE;
-}
-
-/*
- * Blt exposed regions to the screen
- */
-
-static Bool
-winBltExposedRegionsShadowDD(ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
- RECT rcSrc, rcDest;
- POINT ptOrigin;
- HDC hdcUpdate = NULL;
- PAINTSTRUCT ps;
- HRESULT ddrval = DD_OK;
- Bool fReturn = TRUE;
- Bool fLocked = TRUE;
- int i;
-
- /* BeginPaint gives us an hdc that clips to the invalidated region */
- hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps);
- if (hdcUpdate == NULL) {
- ErrorF("winBltExposedRegionsShadowDD - BeginPaint () returned "
- "a NULL device context handle. Aborting blit attempt.\n");
- return FALSE;
- }
-
- /* Unlock the shadow surface, so we can blit */
- ddrval = IDirectDrawSurface2_Unlock(pScreenPriv->pddsShadow, NULL);
- if (FAILED(ddrval)) {
- fReturn = FALSE;
- goto winBltExposedRegionsShadowDD_Exit;
- }
- else {
- /* Flag that we have unlocked the shadow surface */
- fLocked = FALSE;
- }
-
- /* Get the origin of the window in the screen coords */
- ptOrigin.x = pScreenInfo->dwXOffset;
- ptOrigin.y = pScreenInfo->dwYOffset;
-
- MapWindowPoints(pScreenPriv->hwndScreen,
- HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
- rcDest.left = ptOrigin.x;
- rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
- rcDest.top = ptOrigin.y;
- rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
-
- /* Source can be enter shadow surface, as Blt should clip */
- rcSrc.left = 0;
- rcSrc.top = 0;
- rcSrc.right = pScreenInfo->dwWidth;
- rcSrc.bottom = pScreenInfo->dwHeight;
-
- /* Try to regain the primary surface and blit again if we've lost it */
- for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) {
- /* Our Blt should be clipped to the invalidated region */
- ddrval = IDirectDrawSurface2_Blt(pScreenPriv->pddsPrimary,
- &rcDest,
- pScreenPriv->pddsShadow,
- &rcSrc, DDBLT_WAIT, NULL);
- if (ddrval == DDERR_SURFACELOST) {
- /* Surface was lost */
- ErrorF("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt "
- "reported that the primary surface was lost, "
- "trying to restore, retry: %d\n", i + 1);
-
- /* Try to restore the surface, once */
- ddrval = IDirectDrawSurface2_Restore(pScreenPriv->pddsPrimary);
- ErrorF("winBltExposedRegionsShadowDD - "
- "IDirectDrawSurface2_Restore returned: ");
- if (ddrval == DD_OK)
- ErrorF("DD_OK\n");
- else if (ddrval == DDERR_WRONGMODE)
- ErrorF("DDERR_WRONGMODE\n");
- else if (ddrval == DDERR_INCOMPATIBLEPRIMARY)
- ErrorF("DDERR_INCOMPATIBLEPRIMARY\n");
- else if (ddrval == DDERR_UNSUPPORTED)
- ErrorF("DDERR_UNSUPPORTED\n");
- else if (ddrval == DDERR_INVALIDPARAMS)
- ErrorF("DDERR_INVALIDPARAMS\n");
- else if (ddrval == DDERR_INVALIDOBJECT)
- ErrorF("DDERR_INVALIDOBJECT\n");
- else
- ErrorF("unknown error: %08x\n", (unsigned int) ddrval);
-
- /* Loop around to try the blit one more time */
- continue;
- }
- else if (FAILED(ddrval)) {
- fReturn = FALSE;
- ErrorF("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt "
- "failed, but surface not lost: %08x %d\n",
- (unsigned int) ddrval, (int) ddrval);
- goto winBltExposedRegionsShadowDD_Exit;
- }
- else {
- /* Success, stop looping */
- break;
- }
- }
-
- /* Relock the shadow surface */
- ddrval = IDirectDrawSurface2_Lock(pScreenPriv->pddsShadow,
- NULL,
- pScreenPriv->pddsdShadow,
- DDLOCK_WAIT, NULL);
- if (FAILED(ddrval)) {
- fReturn = FALSE;
- ErrorF("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Lock "
- "failed\n");
- goto winBltExposedRegionsShadowDD_Exit;
- }
- else {
- /* Indicate that we have relocked the shadow surface */
- fLocked = TRUE;
- }
-
- /* Has our memory pointer changed? */
- if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
- winUpdateFBPointer(pScreen, pScreenPriv->pddsdShadow->lpSurface);
-
- winBltExposedRegionsShadowDD_Exit:
- /* EndPaint frees the DC */
- if (hdcUpdate != NULL)
- EndPaint(pScreenPriv->hwndScreen, &ps);
-
- /*
- * Relock the surface if it is not locked. We don't care if locking fails,
- * as it will cause the server to shutdown within a few more operations.
- */
- if (!fLocked) {
- IDirectDrawSurface2_Lock(pScreenPriv->pddsShadow,
- NULL,
- pScreenPriv->pddsdShadow, DDLOCK_WAIT, NULL);
-
- /* Has our memory pointer changed? */
- if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
- winUpdateFBPointer(pScreen, pScreenPriv->pddsdShadow->lpSurface);
-
- fLocked = TRUE;
- }
- return fReturn;
-}
-
-/*
- * Do any engine-specific appliation-activation processing
- */
-
-static Bool
-winActivateAppShadowDD(ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
-
- /*
- * Do we have a surface?
- * Are we active?
- * Are we fullscreen?
- */
- if (pScreenPriv != NULL
- && pScreenPriv->pddsPrimary != NULL && pScreenPriv->fActive) {
- /* Primary surface was lost, restore it */
- IDirectDrawSurface2_Restore(pScreenPriv->pddsPrimary);
- }
-
- return TRUE;
-}
-
-/*
- * Reblit the shadow framebuffer to the screen.
- */
-
-static Bool
-winRedrawScreenShadowDD(ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
- HRESULT ddrval = DD_OK;
- RECT rcSrc, rcDest;
- POINT ptOrigin;
-
- /* Get the origin of the window in the screen coords */
- ptOrigin.x = pScreenInfo->dwXOffset;
- ptOrigin.y = pScreenInfo->dwYOffset;
- MapWindowPoints(pScreenPriv->hwndScreen,
- HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
- rcDest.left = ptOrigin.x;
- rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
- rcDest.top = ptOrigin.y;
- rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
-
- /* Source can be entire shadow surface, as Blt should clip for us */
- rcSrc.left = 0;
- rcSrc.top = 0;
- rcSrc.right = pScreenInfo->dwWidth;
- rcSrc.bottom = pScreenInfo->dwHeight;
-
- /* Redraw the whole window, to take account for the new colors */
- ddrval = IDirectDrawSurface2_Blt(pScreenPriv->pddsPrimary,
- &rcDest,
- pScreenPriv->pddsShadow,
- &rcSrc, DDBLT_WAIT, NULL);
- if (FAILED(ddrval)) {
- ErrorF("winRedrawScreenShadowDD - IDirectDrawSurface_Blt () "
- "failed: %08x\n", (unsigned int) ddrval);
- }
-
- return TRUE;
-}
-
-/*
- * Realize the currently installed colormap
- */
-
-static Bool
-winRealizeInstalledPaletteShadowDD(ScreenPtr pScreen)
-{
- return TRUE;
-}
-
-/*
- * Install the specified colormap
- */
-
-static Bool
-winInstallColormapShadowDD(ColormapPtr pColormap)
-{
- ScreenPtr pScreen = pColormap->pScreen;
-
- winScreenPriv(pScreen);
- winCmapPriv(pColormap);
- HRESULT ddrval = DD_OK;
-
- /* Install the DirectDraw palette on the primary surface */
- ddrval = IDirectDrawSurface2_SetPalette(pScreenPriv->pddsPrimary,
- pCmapPriv->lpDDPalette);
- if (FAILED(ddrval)) {
- ErrorF("winInstallColormapShadowDD - Failed installing the "
- "DirectDraw palette.\n");
- return FALSE;
- }
-
- /* Save a pointer to the newly installed colormap */
- pScreenPriv->pcmapInstalled = pColormap;
-
- return TRUE;
-}
-
-/*
- * Store the specified colors in the specified colormap
- */
-
-static Bool
-winStoreColorsShadowDD(ColormapPtr pColormap, int ndef, xColorItem * pdefs)
-{
- ScreenPtr pScreen = pColormap->pScreen;
-
- winScreenPriv(pScreen);
- winCmapPriv(pColormap);
- ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
- HRESULT ddrval = DD_OK;
-
- /* Put the X colormap entries into the Windows logical palette */
- ddrval = IDirectDrawPalette_SetEntries(pCmapPriv->lpDDPalette,
- 0,
- pdefs[0].pixel,
- ndef,
- pCmapPriv->peColors
- + pdefs[0].pixel);
- if (FAILED(ddrval)) {
- ErrorF("winStoreColorsShadowDD - SetEntries () failed\n");
- return FALSE;
- }
-
- /* Don't install the DirectDraw palette if the colormap is not installed */
- if (pColormap != curpmap) {
- return TRUE;
- }
-
- if (!winInstallColormapShadowDD(pColormap)) {
- ErrorF("winStoreColorsShadowDD - Failed installing colormap\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*
- * Colormap initialization procedure
- */
-
-static Bool
-winCreateColormapShadowDD(ColormapPtr pColormap)
-{
- HRESULT ddrval = DD_OK;
- ScreenPtr pScreen = pColormap->pScreen;
-
- winScreenPriv(pScreen);
- winCmapPriv(pColormap);
-
- /* Create a DirectDraw palette */
- ddrval = IDirectDraw2_CreatePalette(pScreenPriv->pdd,
- DDPCAPS_8BIT | DDPCAPS_ALLOW256,
- pCmapPriv->peColors,
- &pCmapPriv->lpDDPalette, NULL);
- if (FAILED(ddrval)) {
- ErrorF("winCreateColormapShadowDD - CreatePalette failed\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*
- * Colormap destruction procedure
- */
-
-static Bool
-winDestroyColormapShadowDD(ColormapPtr pColormap)
-{
- winScreenPriv(pColormap->pScreen);
- winCmapPriv(pColormap);
- HRESULT ddrval = DD_OK;
-
- /*
- * Is colormap to be destroyed the default?
- *
- * Non-default colormaps should have had winUninstallColormap
- * called on them before we get here. The default colormap
- * will not have had winUninstallColormap called on it. Thus,
- * we need to handle the default colormap in a special way.
- */
- if (pColormap->flags & IsDefault) {
-#if CYGDEBUG
- winDebug("winDestroyColormapShadowDD - Destroying default "
- "colormap\n");
-#endif
-
- /*
- * FIXME: Walk the list of all screens, popping the default
- * palette out of each screen device context.
- */
-
- /* Pop the palette out of the primary surface */
- ddrval = IDirectDrawSurface2_SetPalette(pScreenPriv->pddsPrimary, NULL);
- if (FAILED(ddrval)) {
- ErrorF("winDestroyColormapShadowDD - Failed freeing the "
- "default colormap DirectDraw palette.\n");
- return FALSE;
- }
-
- /* Clear our private installed colormap pointer */
- pScreenPriv->pcmapInstalled = NULL;
- }
-
- /* Release the palette */
- IDirectDrawPalette_Release(pCmapPriv->lpDDPalette);
-
- /* Invalidate the colormap privates */
- pCmapPriv->lpDDPalette = NULL;
-
- return TRUE;
-}
-
-/*
- * Set engine specific functions
- */
-
-Bool
-winSetEngineFunctionsShadowDD(ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-
- /* Set our pointers */
- pScreenPriv->pwinAllocateFB = winAllocateFBShadowDD;
- pScreenPriv->pwinFreeFB = winFreeFBShadowDD;
- pScreenPriv->pwinShadowUpdate = winShadowUpdateDD;
- pScreenPriv->pwinInitScreen = winInitScreenShadowDD;
- pScreenPriv->pwinCloseScreen = winCloseScreenShadowDD;
- pScreenPriv->pwinInitVisuals = winInitVisualsShadowDD;
- pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDD;
- if (pScreenInfo->fFullScreen)
- pScreenPriv->pwinCreateBoundingWindow =
- winCreateBoundingWindowFullScreen;
- else
- pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
- pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
- pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDD;
- pScreenPriv->pwinActivateApp = winActivateAppShadowDD;
- pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDD;
- pScreenPriv->pwinRealizeInstalledPalette
- = winRealizeInstalledPaletteShadowDD;
- pScreenPriv->pwinInstallColormap = winInstallColormapShadowDD;
- pScreenPriv->pwinStoreColors = winStoreColorsShadowDD;
- pScreenPriv->pwinCreateColormap = winCreateColormapShadowDD;
- pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDD;
- pScreenPriv->pwinHotKeyAltTab =
- (winHotKeyAltTabProcPtr) (void (*)(void)) NoopDDA;
- pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDD;
- pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDD;
-#ifdef XWIN_MULTIWINDOW
- pScreenPriv->pwinFinishCreateWindowsWindow =
- (winFinishCreateWindowsWindowProcPtr) (void (*)(void)) NoopDDA;
-#endif
-
- return TRUE;
-}
diff --git a/xorg-server/hw/xwin/winwndproc.c b/xorg-server/hw/xwin/winwndproc.c
index 1bf3f5cde..3228fa481 100644
--- a/xorg-server/hw/xwin/winwndproc.c
+++ b/xorg-server/hw/xwin/winwndproc.c
@@ -162,8 +162,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
* their own mode when they become active.
*/
if (s_pScreenInfo->fFullScreen
- && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
- || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)) {
+ || (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)) {
break;
}
@@ -186,8 +185,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
*/
if (s_pScreenInfo->dwBPP !=
GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL)) {
- if ((s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD ||
- s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)) {
+ if (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL) {
/* Cannot display the visual until the depth is restored */
ErrorF("winWindowProc - Disruptive change in depth\n");
diff --git a/xorg-server/include/Makefile.am b/xorg-server/include/Makefile.am
index 168b00f70..738b582e9 100644
--- a/xorg-server/include/Makefile.am
+++ b/xorg-server/include/Makefile.am
@@ -33,6 +33,7 @@ sdk_HEADERS = \
misc.h \
miscstruct.h \
opaque.h \
+ nonsdk_extinit.h \
optionstr.h \
os.h \
pixmap.h \
diff --git a/xorg-server/include/extinit.h b/xorg-server/include/extinit.h
index fa5f29378..4ad4fcac0 100644
--- a/xorg-server/include/extinit.h
+++ b/xorg-server/include/extinit.h
@@ -163,11 +163,6 @@ extern void SELinuxExtensionInit(void);
extern void XTestExtensionInit(void);
#endif
-#ifdef INXQUARTZ
-extern _X_EXPORT Bool noPseudoramiXExtension;
-extern void PseudoramiXExtensionInit(void);
-#endif
-
#if defined(XV)
#include <X11/extensions/Xv.h>
#include <X11/extensions/XvMC.h>
diff --git a/xorg-server/include/nonsdk_extinit.h b/xorg-server/include/nonsdk_extinit.h
new file mode 100644
index 000000000..da8d370bd
--- /dev/null
+++ b/xorg-server/include/nonsdk_extinit.h
@@ -0,0 +1,35 @@
+/***********************************************************
+
+Copyright 2014 Jon TURNEY
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef NONSDK_EXT_INIT_H
+#define NONSDK_EXT_INIT_H
+
+/* this is separate from extinit.h to avoid references to these symbols being
+ pulled in by sdksyms */
+
+extern _X_EXPORT Bool noPseudoramiXExtension;
+extern void PseudoramiXExtensionInit(void);
+
+#endif
diff --git a/xorg-server/include/protocol-versions.h b/xorg-server/include/protocol-versions.h
index fc428c8cf..be532ff55 100644
--- a/xorg-server/include/protocol-versions.h
+++ b/xorg-server/include/protocol-versions.h
@@ -73,7 +73,7 @@
/* RandR */
#define SERVER_RANDR_MAJOR_VERSION 1
-#define SERVER_RANDR_MINOR_VERSION 4
+#define SERVER_RANDR_MINOR_VERSION 5
/* Record */
#define SERVER_RECORD_MAJOR_VERSION 1
diff --git a/xorg-server/mi/mifillarc.c b/xorg-server/mi/mifillarc.c
index 246d70ff4..888519edf 100644
--- a/xorg-server/mi/mifillarc.c
+++ b/xorg-server/mi/mifillarc.c
@@ -660,6 +660,11 @@ miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs_all, xArc * parcs)
if (narcs && nspans + arc->height > MAX_SPANS_PER_LOOP)
break;
nspans += arc->height;
+
+ /* A pie-slice arc may add another pile of spans */
+ if (pGC->arcMode == ArcPieSlice &&
+ (-FULLCIRCLE < arc->angle2 && arc->angle2 < FULLCIRCLE))
+ nspans += (arc->height + 1) >> 1;
}
pts = points = malloc (sizeof (DDXPointRec) * nspans +
diff --git a/xorg-server/mi/miinitext.c b/xorg-server/mi/miinitext.c
index 5872bf534..086d2c3fb 100644
--- a/xorg-server/mi/miinitext.c
+++ b/xorg-server/mi/miinitext.c
@@ -108,6 +108,9 @@ SOFTWARE.
#include "misc.h"
#include "extension.h"
#include "extinit.h"
+#ifdef INXQUARTZ
+#include "nonsdk_extinit.h"
+#endif
#include "micmap.h"
#include "globals.h"
diff --git a/xorg-server/os/log.c b/xorg-server/os/log.c
index 0532c2eb7..3db5c5333 100644
--- a/xorg-server/os/log.c
+++ b/xorg-server/os/log.c
@@ -355,6 +355,7 @@ vpnprintf(char *string, int size_in, const char *f, va_list args)
uint64_t ui;
int64_t si;
size_t size = size_in;
+ int precision;
for (; f_idx < f_len && s_idx < size - 1; f_idx++) {
int length_modifier = 0;
@@ -365,9 +366,29 @@ vpnprintf(char *string, int size_in, const char *f, va_list args)
f_idx++;
- /* silently swallow digit length modifiers */
- while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.'))
+ /* silently swallow minimum field width */
+ if (f[f_idx] == '*') {
f_idx++;
+ va_arg(args, int);
+ } else {
+ while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9')))
+ f_idx++;
+ }
+
+ /* is there a precision? */
+ precision = size;
+ if (f[f_idx] == '.') {
+ f_idx++;
+ if (f[f_idx] == '*') {
+ f_idx++;
+ /* precision is supplied in an int argument */
+ precision = va_arg(args, int);
+ } else {
+ /* silently swallow precision digits */
+ while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9')))
+ f_idx++;
+ }
+ }
/* non-digit length modifiers */
if (f_idx < f_len) {
@@ -383,9 +404,8 @@ vpnprintf(char *string, int size_in, const char *f, va_list args)
switch (f[f_idx]) {
case 's':
string_arg = va_arg(args, char*);
- p_len = strlen_sigsafe(string_arg);
- for (i = 0; i < p_len && s_idx < size - 1; i++)
+ for (i = 0; string_arg[i] != 0 && s_idx < size - 1 && s_idx < precision; i++)
string[s_idx++] = string_arg[i];
break;
diff --git a/xorg-server/os/xdmcp.c b/xorg-server/os/xdmcp.c
index b6e97c928..bc5a70706 100644
--- a/xorg-server/os/xdmcp.c
+++ b/xorg-server/os/xdmcp.c
@@ -48,6 +48,11 @@
#include <netdir.h>
#endif
+#define XSERV_t
+#define TRANS_SERVER
+#define TRANS_REOPEN
+#include <X11/Xtrans/Xtrans.h>
+
#ifdef XDMCP
#undef REQUEST
@@ -242,6 +247,14 @@ XdmcpUseMsg(void)
ErrorF("-displayID display-id manufacturer display ID for request\n");
}
+static void
+XdmcpDefaultListen(void)
+{
+ /* Even when configured --disable-listen-tcp, we should listen on tcp in
+ XDMCP modes */
+ _XSERVTransListen("tcp");
+}
+
int
XdmcpOptions(int argc, char **argv, int i)
{
@@ -249,11 +262,13 @@ XdmcpOptions(int argc, char **argv, int i)
get_manager_by_name(argc, argv, i++);
XDM_INIT_STATE = XDM_QUERY;
AccessUsingXdmcp();
+ XdmcpDefaultListen();
return i + 1;
}
if (strcmp(argv[i], "-broadcast") == 0) {
XDM_INIT_STATE = XDM_BROADCAST;
AccessUsingXdmcp();
+ XdmcpDefaultListen();
return i + 1;
}
#if defined(IPv6) && defined(AF_INET6)
@@ -261,6 +276,7 @@ XdmcpOptions(int argc, char **argv, int i)
i = get_mcast_options(argc, argv, ++i);
XDM_INIT_STATE = XDM_MULTICAST;
AccessUsingXdmcp();
+ XdmcpDefaultListen();
return i + 1;
}
#endif
@@ -268,6 +284,7 @@ XdmcpOptions(int argc, char **argv, int i)
get_manager_by_name(argc, argv, i++);
XDM_INIT_STATE = XDM_INDIRECT;
AccessUsingXdmcp();
+ XdmcpDefaultListen();
return i + 1;
}
if (strcmp(argv[i], "-port") == 0) {
diff --git a/xorg-server/pseudoramiX/pseudoramiX.c b/xorg-server/pseudoramiX/pseudoramiX.c
index f47c7836d..e59ca1312 100644
--- a/xorg-server/pseudoramiX/pseudoramiX.c
+++ b/xorg-server/pseudoramiX/pseudoramiX.c
@@ -39,7 +39,7 @@
#include "pseudoramiX.h"
#include "extnsionst.h"
-#include "extinit.h"
+#include "nonsdk_extinit.h"
#include "dixstruct.h"
#include "window.h"
#include <X11/extensions/panoramiXproto.h>
@@ -49,6 +49,7 @@
#define DEBUG_LOG PseudoramiXDebug
Bool noPseudoramiXExtension = FALSE;
+extern Bool noRRXineramaExtension;
extern int
ProcPanoramiXQueryVersion(ClientPtr client);
@@ -190,6 +191,9 @@ PseudoramiXExtensionInit(void)
}
}
+ /* Do not allow RRXinerama to initialize if we did */
+ noRRXineramaExtension = success;
+
if (!success) {
ErrorF("%s Extension (PseudoramiX) failed to initialize\n",
PANORAMIX_PROTOCOL_NAME);
diff --git a/xorg-server/pseudoramiX/pseudoramiX.h b/xorg-server/pseudoramiX/pseudoramiX.h
index f063919dd..5393062ee 100644
--- a/xorg-server/pseudoramiX/pseudoramiX.h
+++ b/xorg-server/pseudoramiX/pseudoramiX.h
@@ -2,8 +2,6 @@
* Minimal implementation of PanoramiX/Xinerama
*/
-extern int noPseudoramiXExtension;
-
void
PseudoramiXAddScreen(int x, int y, int w, int h);
void
diff --git a/xorg-server/randr/Makefile.am b/xorg-server/randr/Makefile.am
index ccaff3f02..90dc9ec9a 100644
--- a/xorg-server/randr/Makefile.am
+++ b/xorg-server/randr/Makefile.am
@@ -15,6 +15,7 @@ librandr_la_SOURCES = \
rrdispatch.c \
rrinfo.c \
rrmode.c \
+ rrmonitor.c \
rroutput.c \
rrpointer.c \
rrproperty.c \
diff --git a/xorg-server/randr/randr.c b/xorg-server/randr/randr.c
index 6e3f14b4e..ad1dda227 100644
--- a/xorg-server/randr/randr.c
+++ b/xorg-server/randr/randr.c
@@ -98,6 +98,8 @@ RRCloseScreen(ScreenPtr pScreen)
if (pScrPriv->provider)
RRProviderDestroy(pScrPriv->provider);
+ RRMonitorClose(pScreen);
+
free(pScrPriv->crtcs);
free(pScrPriv->outputs);
free(pScrPriv);
@@ -333,6 +335,8 @@ RRScreenInit(ScreenPtr pScreen)
pScrPriv->numCrtcs = 0;
pScrPriv->crtcs = NULL;
+ RRMonitorInit(pScreen);
+
RRNScreens += 1; /* keep count of screens that implement randr */
return TRUE;
}
diff --git a/xorg-server/randr/randrstr.h b/xorg-server/randr/randrstr.h
index 13e6a8596..438a52aeb 100644
--- a/xorg-server/randr/randrstr.h
+++ b/xorg-server/randr/randrstr.h
@@ -80,6 +80,7 @@ typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr;
typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr;
typedef struct _rrOutput RROutputRec, *RROutputPtr;
typedef struct _rrProvider RRProviderRec, *RRProviderPtr;
+typedef struct _rrMonitor RRMonitorRec, *RRMonitorPtr;
struct _rrMode {
int refcnt;
@@ -169,6 +170,22 @@ struct _rrProvider {
struct _rrProvider *output_source;
};
+typedef struct _rrMonitorGeometry {
+ BoxRec box;
+ CARD32 mmWidth;
+ CARD32 mmHeight;
+} RRMonitorGeometryRec, *RRMonitorGeometryPtr;
+
+struct _rrMonitor {
+ Atom name;
+ ScreenPtr pScreen;
+ int numOutputs;
+ RROutput *outputs;
+ Bool primary;
+ Bool automatic;
+ RRMonitorGeometryRec geometry;
+};
+
#if RANDR_12_INTERFACE
typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen,
CARD16 width,
@@ -338,6 +355,9 @@ typedef struct _rrScrPriv {
RRProviderDestroyProcPtr rrProviderDestroy;
+ int numMonitors;
+ RRMonitorPtr *monitors;
+
} rrScrPrivRec, *rrScrPrivPtr;
extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
@@ -981,6 +1001,30 @@ extern _X_EXPORT void
RRXineramaExtensionInit(void);
#endif
+void
+RRMonitorInit(ScreenPtr screen);
+
+Bool
+RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr *monitors_ret, int *nmon_ret);
+
+int
+RRMonitorCountList(ScreenPtr screen);
+
+void
+RRMonitorFreeList(RRMonitorPtr monitors, int nmon);
+
+void
+RRMonitorClose(ScreenPtr screen);
+
+int
+ProcRRGetMonitors(ClientPtr client);
+
+int
+ProcRRSetMonitor(ClientPtr client);
+
+int
+ProcRRDeleteMonitor(ClientPtr client);
+
#endif /* _RANDRSTR_H_ */
/*
diff --git a/xorg-server/randr/rrdispatch.c b/xorg-server/randr/rrdispatch.c
index b9346d3f9..13ac6b117 100644
--- a/xorg-server/randr/rrdispatch.c
+++ b/xorg-server/randr/rrdispatch.c
@@ -254,4 +254,7 @@ int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = {
ProcRRChangeProviderProperty, /* 39 */
ProcRRDeleteProviderProperty, /* 40 */
ProcRRGetProviderProperty, /* 41 */
+ ProcRRGetMonitors, /* 42 */
+ ProcRRSetMonitor, /* 43 */
+ ProcRRDeleteMonitor, /* 44 */
};
diff --git a/xorg-server/randr/rrmonitor.c b/xorg-server/randr/rrmonitor.c
new file mode 100644
index 000000000..fbdd352f6
--- /dev/null
+++ b/xorg-server/randr/rrmonitor.c
@@ -0,0 +1,748 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "randrstr.h"
+#include "swaprep.h"
+
+static Atom
+RRMonitorCrtcName(RRCrtcPtr crtc)
+{
+ char name[20];
+
+ if (crtc->numOutputs) {
+ RROutputPtr output = crtc->outputs[0];
+ return MakeAtom(output->name, output->nameLength, TRUE);
+ }
+ sprintf(name, "Monitor-%08x", crtc->id);
+ return MakeAtom(name, strlen(name), TRUE);
+}
+
+static Bool
+RRMonitorCrtcPrimary(RRCrtcPtr crtc)
+{
+ ScreenPtr screen = crtc->pScreen;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int o;
+
+ for (o = 0; o < crtc->numOutputs; o++)
+ if (crtc->outputs[o] == pScrPriv->primaryOutput)
+ return TRUE;
+ return FALSE;
+}
+
+#define DEFAULT_PIXELS_PER_MM (96.0 / 25.4)
+
+static void
+RRMonitorGetCrtcGeometry(RRCrtcPtr crtc, RRMonitorGeometryPtr geometry)
+{
+ ScreenPtr screen = crtc->pScreen;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ BoxRec panned_area;
+
+ /* Check to see if crtc is panned and return the full area when applicable. */
+ if (pScrPriv && pScrPriv->rrGetPanning &&
+ pScrPriv->rrGetPanning(screen, crtc, &panned_area, NULL, NULL) &&
+ (panned_area.x2 > panned_area.x1) &&
+ (panned_area.y2 > panned_area.y1)) {
+ geometry->box = panned_area;
+ }
+ else {
+ int width, height;
+
+ RRCrtcGetScanoutSize(crtc, &width, &height);
+ geometry->box.x1 = crtc->x;
+ geometry->box.y1 = crtc->y;
+ geometry->box.x2 = geometry->box.x1 + width;
+ geometry->box.y2 = geometry->box.y1 + height;
+ }
+ if (crtc->numOutputs && crtc->outputs[0]->mmWidth && crtc->outputs[0]->mmHeight) {
+ RROutputPtr output = crtc->outputs[0];
+ geometry->mmWidth = output->mmWidth;
+ geometry->mmHeight = output->mmHeight;
+ } else {
+ geometry->mmWidth = floor ((geometry->box.x2 - geometry->box.x1) / DEFAULT_PIXELS_PER_MM + 0.5);
+ geometry->mmHeight = floor ((geometry->box.y2 - geometry->box.y1) / DEFAULT_PIXELS_PER_MM + 0.5);
+ }
+}
+
+static Bool
+RRMonitorSetFromServer(RRCrtcPtr crtc, RRMonitorPtr monitor)
+{
+ int o;
+
+ monitor->name = RRMonitorCrtcName(crtc);
+ monitor->pScreen = crtc->pScreen;
+ monitor->numOutputs = crtc->numOutputs;
+ monitor->outputs = calloc(crtc->numOutputs, sizeof(RRCrtc));
+ if (!monitor->outputs)
+ return FALSE;
+ for (o = 0; o < crtc->numOutputs; o++)
+ monitor->outputs[o] = crtc->outputs[o]->id;
+ monitor->primary = RRMonitorCrtcPrimary(crtc);
+ monitor->automatic = TRUE;
+ RRMonitorGetCrtcGeometry(crtc, &monitor->geometry);
+ return TRUE;
+}
+
+static Bool
+RRMonitorAutomaticGeometry(RRMonitorPtr monitor)
+{
+ return (monitor->geometry.box.x1 == 0 &&
+ monitor->geometry.box.y1 == 0 &&
+ monitor->geometry.box.x2 == 0 &&
+ monitor->geometry.box.y2 == 0);
+}
+
+static void
+RRMonitorGetGeometry(RRMonitorPtr monitor, RRMonitorGeometryPtr geometry)
+{
+ if (RRMonitorAutomaticGeometry(monitor) && monitor->numOutputs > 0) {
+ ScreenPtr screen = monitor->pScreen;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ RRMonitorGeometryRec first = { .box = { 0, 0, 0, 0 }, .mmWidth = 0, .mmHeight = 0 };
+ RRMonitorGeometryRec this;
+ int c, o, co;
+ int active_crtcs = 0;
+
+ *geometry = first;
+ for (o = 0; o < monitor->numOutputs; o++) {
+ RRCrtcPtr crtc = NULL;
+ Bool in_use = FALSE;
+
+ for (c = 0; !in_use && c < pScrPriv->numCrtcs; c++) {
+ crtc = pScrPriv->crtcs[c];
+ if (!crtc->mode)
+ continue;
+ for (co = 0; !in_use && co < crtc->numOutputs; co++)
+ if (monitor->outputs[o] == crtc->outputs[co]->id)
+ in_use = TRUE;
+ }
+
+ if (!in_use)
+ continue;
+
+ RRMonitorGetCrtcGeometry(crtc, &this);
+
+ if (active_crtcs == 0) {
+ first = this;
+ *geometry = this;
+ } else {
+ geometry->box.x1 = min(this.box.x1, geometry->box.x1);
+ geometry->box.x2 = max(this.box.x2, geometry->box.x2);
+ geometry->box.y1 = min(this.box.y1, geometry->box.y1);
+ geometry->box.y2 = max(this.box.y2, geometry->box.y2);
+ }
+ active_crtcs++;
+ }
+
+ /* Adjust physical sizes to account for total area */
+ if (active_crtcs > 1 && first.box.x2 != first.box.x1 && first.box.y2 != first.box.y1) {
+ geometry->mmWidth = (this.box.x2 - this.box.x1) / (first.box.x2 - first.box.x1) * first.mmWidth;
+ geometry->mmHeight = (this.box.y2 - this.box.y1) / (first.box.y2 - first.box.y1) * first.mmHeight;
+ }
+ } else {
+ *geometry = monitor->geometry;
+ }
+}
+
+static Bool
+RRMonitorSetFromClient(RRMonitorPtr client_monitor, RRMonitorPtr monitor)
+{
+ monitor->name = client_monitor->name;
+ monitor->pScreen = client_monitor->pScreen;
+ monitor->numOutputs = client_monitor->numOutputs;
+ monitor->outputs = calloc(client_monitor->numOutputs, sizeof (RROutput));
+ if (!monitor->outputs && client_monitor->numOutputs)
+ return FALSE;
+ memcpy(monitor->outputs, client_monitor->outputs, client_monitor->numOutputs * sizeof (RROutput));
+ monitor->primary = client_monitor->primary;
+ monitor->automatic = client_monitor->automatic;
+ RRMonitorGetGeometry(client_monitor, &monitor->geometry);
+ return TRUE;
+}
+
+typedef struct _rrMonitorList {
+ int num_client;
+ int num_server;
+ RRCrtcPtr *server_crtc;
+ int num_crtcs;
+ int client_primary;
+ int server_primary;
+} RRMonitorListRec, *RRMonitorListPtr;
+
+static Bool
+RRMonitorInitList(ScreenPtr screen, RRMonitorListPtr mon_list, Bool get_active)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int m, o, c, sc;
+ int numCrtcs;
+ ScreenPtr slave;
+
+ if (!RRGetInfo(screen, FALSE))
+ return FALSE;
+
+ /* Count the number of crtcs in this and any slave screens */
+ numCrtcs = pScrPriv->numCrtcs;
+ xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ rrScrPrivPtr pSlavePriv;
+ pSlavePriv = rrGetScrPriv(slave);
+ numCrtcs += pSlavePriv->numCrtcs;
+ }
+ mon_list->num_crtcs = numCrtcs;
+
+ mon_list->server_crtc = calloc(numCrtcs * 2, sizeof (RRCrtcPtr));
+ if (!mon_list->server_crtc)
+ return FALSE;
+
+ /* Collect pointers to all of the active crtcs */
+ c = 0;
+ for (sc = 0; sc < pScrPriv->numCrtcs; sc++, c++) {
+ if (pScrPriv->crtcs[sc]->mode != NULL)
+ mon_list->server_crtc[c] = pScrPriv->crtcs[sc];
+ }
+
+ xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ rrScrPrivPtr pSlavePriv;
+ pSlavePriv = rrGetScrPriv(slave);
+ for (sc = 0; sc < pSlavePriv->numCrtcs; sc++, c++) {
+ if (pSlavePriv->crtcs[sc]->mode != NULL)
+ mon_list->server_crtc[c] = pSlavePriv->crtcs[sc];
+ }
+ }
+
+ /* Walk the list of client-defined monitors, clearing the covered
+ * CRTCs from the full list and finding whether one of the
+ * monitors is primary
+ */
+ mon_list->num_client = pScrPriv->numMonitors;
+ mon_list->client_primary = -1;
+
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ RRMonitorPtr monitor = pScrPriv->monitors[m];
+ if (get_active) {
+ RRMonitorGeometryRec geom;
+
+ RRMonitorGetGeometry(monitor, &geom);
+ if (geom.box.x2 - geom.box.x1 == 0 ||
+ geom.box.y2 - geom.box.y1 == 0) {
+ mon_list->num_client--;
+ continue;
+ }
+ }
+ if (monitor->primary && mon_list->client_primary == -1)
+ mon_list->client_primary = m;
+ for (o = 0; o < monitor->numOutputs; o++) {
+ for (c = 0; c < numCrtcs; c++) {
+ RRCrtcPtr crtc = mon_list->server_crtc[c];
+ if (crtc) {
+ int co;
+ for (co = 0; co < crtc->numOutputs; co++)
+ if (crtc->outputs[co]->id == monitor->outputs[o]) {
+ mon_list->server_crtc[c] = NULL;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* Now look at the active CRTCs, and count
+ * those not covered by a client monitor, as well
+ * as finding whether one of them is marked primary
+ */
+ mon_list->num_server = 0;
+ mon_list->server_primary = -1;
+
+ for (c = 0; c < mon_list->num_crtcs; c++) {
+ RRCrtcPtr crtc = mon_list->server_crtc[c];
+
+ if (!crtc)
+ continue;
+
+ mon_list->num_server++;
+
+ if (RRMonitorCrtcPrimary(crtc) && mon_list->server_primary == -1)
+ mon_list->server_primary = c;
+ }
+ return TRUE;
+}
+
+static void
+RRMonitorFiniList(RRMonitorListPtr list)
+{
+ free(list->server_crtc);
+}
+
+/* Construct a complete list of protocol-visible monitors, including
+ * the manually generated ones as well as those generated
+ * automatically from the remaining CRCTs
+ */
+
+Bool
+RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr *monitors_ret, int *nmon_ret)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ RRMonitorListRec list;
+ int m, c;
+ RRMonitorPtr mon, monitors;
+ Bool has_primary = FALSE;
+
+ if (!pScrPriv)
+ return FALSE;
+
+ if (!RRMonitorInitList(screen, &list, get_active))
+ return FALSE;
+
+ monitors = calloc(list.num_client + list.num_server, sizeof (RRMonitorRec));
+ if (!monitors) {
+ RRMonitorFiniList(&list);
+ return FALSE;
+ }
+
+ mon = monitors;
+
+ /* Fill in the primary monitor data first
+ */
+ if (list.client_primary >= 0) {
+ RRMonitorSetFromClient(pScrPriv->monitors[list.client_primary], mon);
+ mon++;
+ } else if (list.server_primary >= 0) {
+ RRMonitorSetFromServer(pScrPriv->crtcs[list.server_primary], mon);
+ mon++;
+ }
+
+ /* Fill in the client-defined monitors next
+ */
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ if (m == list.client_primary)
+ continue;
+ if (get_active) {
+ RRMonitorGeometryRec geom;
+
+ RRMonitorGetGeometry(pScrPriv->monitors[m], &geom);
+ if (geom.box.x2 - geom.box.x1 == 0 ||
+ geom.box.y2 - geom.box.y1 == 0) {
+ continue;
+ }
+ }
+ RRMonitorSetFromClient(pScrPriv->monitors[m], mon);
+ if (has_primary)
+ mon->primary = FALSE;
+ else if (mon->primary)
+ has_primary = TRUE;
+ mon++;
+ }
+
+ /* And finish with the list of crtc-inspired monitors
+ */
+ for (c = 0; c < pScrPriv->numCrtcs; c++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[c];
+ if (c == list.server_primary && list.client_primary < 0)
+ continue;
+
+ if (!list.server_crtc[c])
+ continue;
+
+ RRMonitorSetFromServer(crtc, mon);
+ if (has_primary)
+ mon->primary = FALSE;
+ else if (mon->primary)
+ has_primary = TRUE;
+ mon++;
+ }
+
+ RRMonitorFiniList(&list);
+ *nmon_ret = list.num_client + list.num_server;
+ *monitors_ret = monitors;
+ return TRUE;
+}
+
+int
+RRMonitorCountList(ScreenPtr screen)
+{
+ RRMonitorListRec list;
+ int nmon;
+
+ if (!RRMonitorInitList(screen, &list, FALSE))
+ return -1;
+ nmon = list.num_client + list.num_server;
+ RRMonitorFiniList(&list);
+ return nmon;
+}
+
+static void
+RRMonitorFree(RRMonitorPtr monitor)
+{
+ free(monitor);
+}
+
+static RRMonitorPtr
+RRMonitorAlloc(int noutput)
+{
+ RRMonitorPtr monitor;
+
+ monitor = calloc(1, sizeof (RRMonitorRec) + noutput * sizeof (RROutput));
+ if (!monitor)
+ return NULL;
+ monitor->numOutputs = noutput;
+ monitor->outputs = (RROutput *) (monitor + 1);
+ return monitor;
+}
+
+static int
+RRMonitorDelete(ClientPtr client, ScreenPtr screen, Atom name)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int m;
+
+ if (!pScrPriv) {
+ client->errorValue = name;
+ return BadAtom;
+ }
+
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ RRMonitorPtr monitor = pScrPriv->monitors[m];
+ if (monitor->name == name) {
+ memmove(pScrPriv->monitors + m, pScrPriv->monitors + m + 1,
+ (pScrPriv->numMonitors - (m + 1)) * sizeof (RRMonitorPtr));
+ --pScrPriv->numMonitors;
+ RRMonitorFree(monitor);
+ return Success;
+ }
+ }
+
+ client->errorValue = name;
+ return BadValue;
+}
+
+static Bool
+RRMonitorMatchesOutputName(ScreenPtr screen, Atom name)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int o;
+ const char *str = NameForAtom(name);
+ int len = strlen(str);
+
+ for (o = 0; o < pScrPriv->numOutputs; o++) {
+ RROutputPtr output = pScrPriv->outputs[o];
+
+ if (output->nameLength == len && !memcmp(output->name, str, len))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static int
+RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int m;
+ ScreenPtr slave;
+ RRMonitorPtr *monitors;
+
+ if (!pScrPriv)
+ return BadAlloc;
+
+ /* 'name' must not match the name of any Output on the screen, or
+ * a Value error results.
+ */
+
+ if (RRMonitorMatchesOutputName(screen, monitor->name)) {
+ client->errorValue = monitor->name;
+ return BadValue;
+ }
+
+ xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ if (RRMonitorMatchesOutputName(slave, monitor->name)) {
+ client->errorValue = monitor->name;
+ return BadValue;
+ }
+ }
+
+ /* 'name' must not match the name of any Monitor on the screen, or
+ * a Value error results.
+ */
+
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ if (pScrPriv->monitors[m]->name == monitor->name) {
+ client->errorValue = monitor->name;
+ return BadValue;
+ }
+ }
+
+ /* Allocate space for the new pointer. This is done before
+ * removing matching monitors as it may fail, and the request
+ * needs to not have any side-effects on failure
+ */
+ if (pScrPriv->numMonitors)
+ monitors = realloc(pScrPriv->monitors,
+ (pScrPriv->numMonitors + 1) * sizeof (RRMonitorPtr));
+ else
+ monitors = malloc(sizeof (RRMonitorPtr));
+
+ if (!monitors)
+ return BadAlloc;
+
+ pScrPriv->monitors = monitors;
+
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ RRMonitorPtr existing = pScrPriv->monitors[m];
+ int o, eo;
+
+ /* If 'name' matches an existing Monitor on the screen, the
+ * existing one will be deleted as if RRDeleteMonitor were called.
+ */
+ if (existing->name == monitor->name) {
+ (void) RRMonitorDelete(client, screen, existing->name);
+ continue;
+ }
+
+ /* For each output in 'info.outputs', each one is removed from all
+ * pre-existing Monitors. If removing the output causes the list
+ * of outputs for that Monitor to become empty, then that
+ * Monitor will be deleted as if RRDeleteMonitor were called.
+ */
+
+ for (eo = 0; eo < existing->numOutputs; eo++) {
+ for (o = 0; o < monitor->numOutputs; o++) {
+ if (monitor->outputs[o] == existing->outputs[eo]) {
+ memmove(existing->outputs + eo, existing->outputs + eo + 1,
+ (existing->numOutputs - (eo + 1)) * sizeof (RROutput));
+ --existing->numOutputs;
+ --eo;
+ break;
+ }
+ }
+ if (existing->numOutputs == 0) {
+ (void) RRMonitorDelete(client, screen, existing->name);
+ break;
+ }
+ }
+ if (monitor->primary)
+ existing->primary = FALSE;
+ }
+
+ /* Add the new one to the list
+ */
+ pScrPriv->monitors[pScrPriv->numMonitors++] = monitor;
+
+ return Success;
+}
+
+void
+RRMonitorFreeList(RRMonitorPtr monitors, int nmon)
+{
+ int m;
+
+ for (m = 0; m < nmon; m++)
+ free(monitors[m].outputs);
+ free(monitors);
+}
+
+void
+RRMonitorInit(ScreenPtr screen)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+
+ if (!pScrPriv)
+ return;
+
+ pScrPriv->numMonitors = 0;
+ pScrPriv->monitors = NULL;
+}
+
+void
+RRMonitorClose(ScreenPtr screen)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int m;
+
+ if (!pScrPriv)
+ return;
+
+ for (m = 0; m < pScrPriv->numMonitors; m++)
+ RRMonitorFree(pScrPriv->monitors[m]);
+ free(pScrPriv->monitors);
+ pScrPriv->monitors = NULL;
+ pScrPriv->numMonitors = 0;
+}
+
+static CARD32
+RRMonitorTimestamp(ScreenPtr screen)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+
+ /* XXX should take client monitor changes into account */
+ return pScrPriv->lastConfigTime.milliseconds;
+}
+
+int
+ProcRRGetMonitors(ClientPtr client)
+{
+ REQUEST(xRRGetMonitorsReq);
+ xRRGetMonitorsReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ };
+ WindowPtr window;
+ ScreenPtr screen;
+ int r;
+ RRMonitorPtr monitors;
+ int nmonitors;
+ int noutputs;
+ int m;
+ Bool get_active;
+ REQUEST_SIZE_MATCH(xRRGetMonitorsReq);
+ r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
+ if (r != Success)
+ return r;
+ screen = window->drawable.pScreen;
+
+ get_active = stuff->get_active;
+ if (!RRMonitorMakeList(screen, get_active, &monitors, &nmonitors))
+ return BadAlloc;
+
+ rep.timestamp = RRMonitorTimestamp(screen);
+
+ noutputs = 0;
+ for (m = 0; m < nmonitors; m++) {
+ rep.length += SIZEOF(xRRMonitorInfo) >> 2;
+ rep.length += monitors[m].numOutputs;
+ noutputs += monitors[m].numOutputs;
+ }
+
+ rep.nmonitors = nmonitors;
+ rep.noutputs = noutputs;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.timestamp);
+ swapl(&rep.nmonitors);
+ swapl(&rep.noutputs);
+ }
+ WriteToClient(client, sizeof(xRRGetMonitorsReply), &rep);
+
+ client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
+
+ for (m = 0; m < nmonitors; m++) {
+ RRMonitorPtr monitor = &monitors[m];
+ xRRMonitorInfo info = {
+ .name = monitor->name,
+ .primary = monitor->primary,
+ .automatic = monitor->automatic,
+ .noutput = monitor->numOutputs,
+ .x = monitor->geometry.box.x1,
+ .y = monitor->geometry.box.y1,
+ .width = monitor->geometry.box.x2 - monitor->geometry.box.x1,
+ .height = monitor->geometry.box.y2 - monitor->geometry.box.y1,
+ .widthInMillimeters = monitor->geometry.mmWidth,
+ .heightInMillimeters = monitor->geometry.mmHeight,
+ };
+ if (client->swapped) {
+ swapl(&info.name);
+ swaps(&info.noutput);
+ swaps(&info.x);
+ swaps(&info.y);
+ swaps(&info.width);
+ swaps(&info.height);
+ swapl(&info.widthInMillimeters);
+ swapl(&info.heightInMillimeters);
+ }
+
+ WriteToClient(client, sizeof(xRRMonitorInfo), &info);
+ WriteSwappedDataToClient(client, monitor->numOutputs * sizeof (RROutput), monitor->outputs);
+ }
+
+ RRMonitorFreeList(monitors, nmonitors);
+
+ return Success;
+}
+
+int
+ProcRRSetMonitor(ClientPtr client)
+{
+ REQUEST(xRRSetMonitorReq);
+ WindowPtr window;
+ ScreenPtr screen;
+ RRMonitorPtr monitor;
+ int r;
+
+ REQUEST_AT_LEAST_SIZE(xRRSetMonitorReq);
+
+ if (stuff->monitor.noutput != stuff->length - (SIZEOF(xRRSetMonitorReq) >> 2))
+ return BadLength;
+
+ r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
+ if (r != Success)
+ return r;
+ screen = window->drawable.pScreen;
+
+ if (!ValidAtom(stuff->monitor.name))
+ return BadAtom;
+
+ /* Allocate the new monitor */
+ monitor = RRMonitorAlloc(stuff->monitor.noutput);
+ if (!monitor)
+ return BadAlloc;
+
+ /* Fill in the bits from the request */
+ monitor->pScreen = screen;
+ monitor->name = stuff->monitor.name;
+ monitor->primary = stuff->monitor.primary;
+ monitor->automatic = FALSE;
+ memcpy(monitor->outputs, stuff + 1, stuff->monitor.noutput * sizeof (RROutput));
+ monitor->geometry.box.x1 = stuff->monitor.x;
+ monitor->geometry.box.y1 = stuff->monitor.y;
+ monitor->geometry.box.x2 = stuff->monitor.x + stuff->monitor.width;
+ monitor->geometry.box.y2 = stuff->monitor.y + stuff->monitor.height;
+ monitor->geometry.mmWidth = stuff->monitor.widthInMillimeters;
+ monitor->geometry.mmHeight = stuff->monitor.heightInMillimeters;
+
+ r = RRMonitorAdd(client, screen, monitor);
+ if (r != Success)
+ RRMonitorFree(monitor);
+ return r;
+}
+
+int
+ProcRRDeleteMonitor(ClientPtr client)
+{
+ REQUEST(xRRDeleteMonitorReq);
+ WindowPtr window;
+ ScreenPtr screen;
+ int r;
+
+ REQUEST_SIZE_MATCH(xRRDeleteMonitorReq);
+ r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
+ if (r != Success)
+ return r;
+ screen = window->drawable.pScreen;
+
+ if (!ValidAtom(stuff->name)) {
+ client->errorValue = stuff->name;
+ return BadAtom;
+ }
+
+ return RRMonitorDelete(client, screen, stuff->name);
+}
diff --git a/xorg-server/randr/rrsdispatch.c b/xorg-server/randr/rrsdispatch.c
index 47558cf75..cf2a3b024 100644
--- a/xorg-server/randr/rrsdispatch.c
+++ b/xorg-server/randr/rrsdispatch.c
@@ -565,6 +565,41 @@ static int SProcRRGetProviderProperty(ClientPtr client)
return ProcRandrVector[stuff->randrReqType] (client);
}
+static int SProcRRGetMonitors(ClientPtr client) {
+ REQUEST(xRRGetMonitorsReq);
+
+ REQUEST_SIZE_MATCH(xRRGetMonitorsReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int SProcRRSetMonitor(ClientPtr client) {
+ REQUEST(xRRSetMonitorReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRGetMonitorsReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ swapl(&stuff->monitor.name);
+ swaps(&stuff->monitor.noutput);
+ swaps(&stuff->monitor.x);
+ swaps(&stuff->monitor.y);
+ swaps(&stuff->monitor.width);
+ swaps(&stuff->monitor.height);
+ SwapRestL(stuff);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int SProcRRDeleteMonitor(ClientPtr client) {
+ REQUEST(xRRDeleteMonitorReq);
+
+ REQUEST_SIZE_MATCH(xRRDeleteMonitorReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ swapl(&stuff->name);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
int (*SProcRandrVector[RRNumberRequests]) (ClientPtr) = {
SProcRRQueryVersion, /* 0 */
/* we skip 1 to make old clients fail pretty immediately */
@@ -614,4 +649,7 @@ int (*SProcRandrVector[RRNumberRequests]) (ClientPtr) = {
SProcRRChangeProviderProperty, /* 39 */
SProcRRDeleteProviderProperty, /* 40 */
SProcRRGetProviderProperty, /* 41 */
+ SProcRRGetMonitors, /* 42 */
+ SProcRRSetMonitor, /* 43 */
+ SProcRRDeleteMonitor, /* 44 */
};
diff --git a/xorg-server/randr/rrxinerama.c b/xorg-server/randr/rrxinerama.c
index b336bd7cd..b6e9586d7 100644
--- a/xorg-server/randr/rrxinerama.c
+++ b/xorg-server/randr/rrxinerama.c
@@ -84,6 +84,8 @@ static int ProcRRXineramaIsActive(ClientPtr client);
static int ProcRRXineramaQueryScreens(ClientPtr client);
static int SProcRRXineramaDispatch(ClientPtr client);
+Bool noRRXineramaExtension = FALSE;
+
/* Proc */
int
@@ -147,35 +149,10 @@ ProcRRXineramaGetState(ClientPtr client)
return Success;
}
-static Bool
-RRXineramaCrtcActive(RRCrtcPtr crtc)
-{
- return crtc->mode != NULL && crtc->numOutputs > 0;
-}
-
static int
RRXineramaScreenCount(ScreenPtr pScreen)
{
- int i, n;
- ScreenPtr slave;
-
- n = 0;
- if (rrGetScrPriv(pScreen)) {
- rrScrPriv(pScreen);
- for (i = 0; i < pScrPriv->numCrtcs; i++)
- if (RRXineramaCrtcActive(pScrPriv->crtcs[i]))
- n++;
- }
-
- xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
- rrScrPrivPtr pSlavePriv;
- pSlavePriv = rrGetScrPriv(slave);
- for (i = 0; i < pSlavePriv->numCrtcs; i++)
- if (RRXineramaCrtcActive(pSlavePriv->crtcs[i]))
- n++;
- }
-
- return n;
+ return RRMonitorCountList(pScreen);
}
static Bool
@@ -274,42 +251,16 @@ ProcRRXineramaIsActive(ClientPtr client)
}
static void
-RRXineramaWriteCrtc(ClientPtr client, RRCrtcPtr crtc)
+RRXineramaWriteMonitor(ClientPtr client, RRMonitorPtr monitor)
{
xXineramaScreenInfo scratch;
- if (RRXineramaCrtcActive(crtc)) {
- ScreenPtr pScreen = crtc->pScreen;
- rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen);
- BoxRec panned_area;
-
- /* Check to see if crtc is panned and return the full area when applicable. */
- if (pScrPriv && pScrPriv->rrGetPanning &&
- pScrPriv->rrGetPanning(pScreen, crtc, &panned_area, NULL, NULL) &&
- (panned_area.x2 > panned_area.x1) &&
- (panned_area.y2 > panned_area.y1)) {
- scratch.x_org = panned_area.x1;
- scratch.y_org = panned_area.y1;
- scratch.width = panned_area.x2 - panned_area.x1;
- scratch.height = panned_area.y2 - panned_area.y1;
- }
- else {
- int width, height;
-
- RRCrtcGetScanoutSize(crtc, &width, &height);
- scratch.x_org = crtc->x;
- scratch.y_org = crtc->y;
- scratch.width = width;
- scratch.height = height;
- }
- if (client->swapped) {
- swaps(&scratch.x_org);
- swaps(&scratch.y_org);
- swaps(&scratch.width);
- swaps(&scratch.height);
- }
- WriteToClient(client, sz_XineramaScreenInfo, &scratch);
- }
+ scratch.x_org = monitor->geometry.box.x1;
+ scratch.y_org = monitor->geometry.box.y1;
+ scratch.width = monitor->geometry.box.x2 - monitor->geometry.box.x1;
+ scratch.height = monitor->geometry.box.y2 - monitor->geometry.box.y1;
+
+ WriteToClient(client, sz_XineramaScreenInfo, &scratch);
}
int
@@ -317,21 +268,23 @@ ProcRRXineramaQueryScreens(ClientPtr client)
{
xXineramaQueryScreensReply rep;
ScreenPtr pScreen = screenInfo.screens[RR_XINERAMA_SCREEN];
- int n = 0;
- int i;
+ int m;
+ RRMonitorPtr monitors = NULL;
+ int nmonitors = 0;
REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
if (RRXineramaScreenActive(pScreen)) {
RRGetInfo(pScreen, FALSE);
- n = RRXineramaScreenCount(pScreen);
+ if (!RRMonitorMakeList(pScreen, TRUE, &monitors, &nmonitors))
+ return BadAlloc;
}
rep = (xXineramaQueryScreensReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
- .length = bytes_to_int32(n * sz_XineramaScreenInfo),
- .number = n
+ .length = bytes_to_int32(nmonitors * sz_XineramaScreenInfo),
+ .number = nmonitors
};
if (client->swapped) {
swaps(&rep.sequenceNumber);
@@ -340,40 +293,11 @@ ProcRRXineramaQueryScreens(ClientPtr client)
}
WriteToClient(client, sizeof(xXineramaQueryScreensReply), &rep);
- if (n) {
- ScreenPtr slave;
- rrScrPriv(pScreen);
- int has_primary = 0;
- RRCrtcPtr primary_crtc = NULL;
-
- if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
- has_primary = 1;
- primary_crtc = pScrPriv->primaryOutput->crtc;
- RRXineramaWriteCrtc(client, pScrPriv->primaryOutput->crtc);
- }
-
- for (i = 0; i < pScrPriv->numCrtcs; i++) {
- if (has_primary &&
- primary_crtc == pScrPriv->crtcs[i]) {
- has_primary = 0;
- continue;
- }
- RRXineramaWriteCrtc(client, pScrPriv->crtcs[i]);
- }
-
- xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
- rrScrPrivPtr pSlavePriv;
- pSlavePriv = rrGetScrPriv(slave);
- for (i = 0; i < pSlavePriv->numCrtcs; i++) {
- if (has_primary &&
- primary_crtc == pSlavePriv->crtcs[i]) {
- has_primary = 0;
- continue;
- }
- RRXineramaWriteCrtc(client, pSlavePriv->crtcs[i]);
- }
- }
- }
+ for (m = 0; m < nmonitors; m++)
+ RRXineramaWriteMonitor(client, &monitors[m]);
+
+ if (monitors)
+ RRMonitorFreeList(monitors, nmonitors);
return Success;
}
@@ -488,6 +412,9 @@ RRXineramaExtensionInit(void)
return;
#endif
+ if (noRRXineramaExtension)
+ return;
+
/*
* Xinerama isn't capable enough to have multiple protocol screens each
* with their own output geometry. So if there's more than one protocol
diff --git a/xorg-server/xkeyboard-config/rules/base.xml.in b/xorg-server/xkeyboard-config/rules/base.xml.in
index 803de50ac..a75f02942 100644
--- a/xorg-server/xkeyboard-config/rules/base.xml.in
+++ b/xorg-server/xkeyboard-config/rules/base.xml.in
@@ -3833,6 +3833,12 @@
<_description>Spanish (Latin American, Sun dead keys)</_description>
</configItem>
</variant>
+ <variant>
+ <configItem>
+ <name>dvorak</name>
+ <_description>Spanish (Latin American, Dvorak)</_description>
+ </configItem>
+ </variant>
</variantList>
</layout>
<layout>
diff --git a/xorg-server/xkeyboard-config/symbols/de b/xorg-server/xkeyboard-config/symbols/de
index fa3c7ec97..1687bc810 100644
--- a/xorg-server/xkeyboard-config/symbols/de
+++ b/xorg-server/xkeyboard-config/symbols/de
@@ -43,6 +43,7 @@ xkb_symbols "basic" {
key <AB08> { [ comma, semicolon, periodcentered, multiply ] };
key <AB09> { [ period, colon, U2026, division ] };
key <AB10> { [ minus, underscore, endash, emdash ] };
+ key <LSGT> { [ less, greater, bar, NoSymbol ] };
include "kpdl(comma)"
diff --git a/xorg-server/xkeyboard-config/symbols/latam b/xorg-server/xkeyboard-config/symbols/latam
index 47c8976e7..f6717a415 100644
--- a/xorg-server/xkeyboard-config/symbols/latam
+++ b/xorg-server/xkeyboard-config/symbols/latam
@@ -66,3 +66,64 @@ xkb_symbols "deadtilde" {
key <AD12> { [ plus, asterisk, dead_tilde, dead_macron ] };
};
+
+// Latin American Spanish Dvorak mapping (note R-H exchange)
+partial alphanumeric_keys
+xkb_symbols "dvorak" {
+
+ name[Group1]="Spanish (Latin American, Dvorak)";
+
+ key <TLDE> {[ bar, degree, notsign, notsign ]};
+ key <AE01> {[ 1, exclam, bar, exclamdown ]};
+ key <AE02> {[ 2, quotedbl, at, oneeighth ]};
+ key <AE03> {[ 3, numbersign, periodcentered, sterling ]};
+ key <AE04> {[ 4, dollar, asciitilde, dollar ]};
+ key <AE05> {[ 5, percent, onehalf, threeeighths ]};
+ key <AE06> {[ 6, ampersand, notsign, fiveeighths ]};
+ key <AE07> {[ 7, slash, braceleft, seveneighths ]};
+ key <AE08> {[ 8, parenleft, bracketleft, trademark ]};
+ key <AE09> {[ 9, parenright, bracketright, plusminus ]};
+ key <AE10> {[ 0, equal, braceright, degree ]};
+ key <AE11> {[ apostrophe, question, backslash, questiondown ]};
+ key <AE12> {[ questiondown, exclamdown, dead_cedilla, dead_ogonek ]};
+
+ key <AD01> {[ period, colon, at ]};
+ key <AD02> {[ comma, semicolon ]};
+ key <AD03> {[ ntilde, Ntilde, lstroke, Lstroke ]};
+ key <AD04> {[ p, P, paragraph ]};
+ key <AD05> {[ y, Y, yen ]};
+ key <AD06> {[ f, F, tslash, Tslash ]};
+ key <AD07> {[ g, G, dstroke, Dstroke ]};
+ key <AD08> {[ c, C, cent, copyright ]};
+ key <AD09> {[ h, H, hstroke, Hstroke ]};
+ key <AD10> {[ l, L, sterling ]};
+ key <AD11> {[ dead_acute, dead_diaeresis, dead_diaeresis, dead_abovering ]};
+ key <AD12> {[ plus, asterisk, asciitilde, dead_macron ]};
+
+ key <AC01> {[ a, A, ae, AE ]};
+ key <AC02> {[ o, O, oslash, Oslash ]};
+ key <AC03> {[ e, E, EuroSign ]};
+ key <AC04> {[ u, U, aring, Aring ]};
+ key <AC05> {[ i, I, oe, OE ]};
+ key <AC06> {[ d, D, eth, ETH ]};
+ key <AC07> {[ r, R, registered, trademark ]};
+ key <AC08> {[ t, T, thorn, THORN ]};
+ key <AC09> {[ n, N, eng, ENG ]};
+ key <AC10> {[ s, S, ssharp, section ]};
+ key <AC11> {[ braceleft, bracketleft, dead_circumflex, braceleft ]};
+ key <BKSL> {[ braceright, bracketright, dead_grave, braceright ]};
+
+ key <LSGT> {[ less, greater, guillemotleft, guillemotright ]};
+ key <AB01> {[ minus, underscore, hyphen, macron ]};
+ key <AB02> {[ q, Q, currency ]};
+ key <AB03> {[ j, J ]};
+ key <AB04> {[ k, K, kra ]};
+ key <AB05> {[ x, X, multiply, division ]};
+ key <AB06> {[ b, B ]};
+ key <AB07> {[ m, M, mu ]};
+ key <AB08> {[ w, W ]};
+ key <AB09> {[ v, V ]};
+ key <AB10> {[ z, Z ]};
+
+ include "level3(ralt_switch)"
+};
diff --git a/xorg-server/xkeyboard-config/symbols/typo b/xorg-server/xkeyboard-config/symbols/typo
index 3b555f8c3..cce79f7ef 100644
--- a/xorg-server/xkeyboard-config/symbols/typo
+++ b/xorg-server/xkeyboard-config/symbols/typo
@@ -1,56 +1,67 @@
-// typographic keyboard
+// Typographic Keyboard
// Sergei Stolyarov <sergei@regolit.com>
-//
+
// Initial contribution by Alexey Ten <alexeyten+deb@gmail.com>
// Additional contribution and code cleanup by Artur Dryomov <artur.dryomov@gmail.com>
-//
-// Mainly based on the layout proposed by Ilya Birman,
+
+// Mainly based on the layout proposed by Ilya Birman
// http://ilyabirman.ru/projects/typography-layout/
-// default layout
default partial
xkb_symbols "base" {
-// 1st keyboard row
- key <TLDE> { [NoSymbol, NoSymbol, NoSymbol, approxeq] };
- key <AE01> { [NoSymbol, NoSymbol, onesuperior, exclamdown] }; // "1"
- key <AE02> { [NoSymbol, NoSymbol, twosuperior, onehalf] }; // "2"
- key <AE03> { [NoSymbol, NoSymbol, threesuperior, onethird] }; // "3"
- key <AE04> { [NoSymbol, NoSymbol, dollar, onequarter] }; // "4"
- key <AE05> { [NoSymbol, NoSymbol, permille] }; // "5"
- key <AE06> { [NoSymbol, NoSymbol, uparrow] }; // "6"
- key <AE07> { [NoSymbol, NoSymbol, ampersand, questiondown] }; // "7"
- key <AE08> { [NoSymbol, NoSymbol, infinity, oneeighth] }; // "8"
- key <AE09> { [NoSymbol, NoSymbol, leftarrow] }; // "9"
- key <AE10> { [NoSymbol, NoSymbol, rightarrow] }; // "0"
- key <AE11> { [NoSymbol, NoSymbol, emdash, endash] }; // "-"
- key <AE12> { [NoSymbol, NoSymbol, notequal, plusminus] }; // "="
-
-// 2nd keyboard row
- key <AD03> { [NoSymbol, NoSymbol, EuroSign] }; // "e"
- key <AD04> { [NoSymbol, NoSymbol, registered] }; // "r"
- key <AD05> { [NoSymbol, NoSymbol, trademark] }; // "t"
- key <AD06> { [NoSymbol, NoSymbol, yen] }; // "y"
- key <AD10> { [NoSymbol, NoSymbol, acute, doubleacute] }; // "p"
- key <AD11> { [NoSymbol, NoSymbol, bracketleft, braceleft] }; // [
- key <AD12> { [NoSymbol, NoSymbol, bracketright, braceright] }; // ]
-
-// 3rd keyboard row
- key <AC01> { [NoSymbol, NoSymbol, U0301] }; // "a"
- key <AC02> { [NoSymbol, NoSymbol, section] }; // "s"
- key <AC03> { [NoSymbol, NoSymbol, degree, division] }; // "d"
- key <AC04> { [NoSymbol, NoSymbol, sterling] }; // "f"
- key <AC07> { [NoSymbol, NoSymbol, doublelowquotemark, singlelowquotemark] }; // "j"
- key <AC08> { [NoSymbol, NoSymbol, leftdoublequotemark, leftsinglequotemark] }; // "k"
- key <AC09> { [NoSymbol, NoSymbol, rightdoublequotemark, rightsinglequotemark] }; // "l"
- key <AC10> { [NoSymbol, NoSymbol, leftsinglequotemark, minutes] }; // ";"
- key <AC11> { [NoSymbol, NoSymbol, rightsinglequotemark, seconds] }; // "'"
-
-// 4th keyboard row
- key <AB02> { [NoSymbol, NoSymbol, multiply, U22C5] }; // "x"
- key <AB03> { [NoSymbol, NoSymbol, copyright, cent] }; // "c"
- key <AB04> { [NoSymbol, NoSymbol, downarrow, U25CA] }; // "v"
- key <AB07> { [NoSymbol, NoSymbol, U2212, enfilledcircbullet] }; // "m"
- key <AB08> { [NoSymbol, NoSymbol, guillemotleft, less] }; // ","
- key <AB09> { [NoSymbol, NoSymbol, guillemotright, greater] }; // "."
- key <AB10> { [NoSymbol, NoSymbol, ellipsis] }; // "/"
+
+ // 1st keyboard row
+ key <TLDE> { [ NoSymbol, NoSymbol, NoSymbol, approxeq ] }; // "~"
+ key <AE01> { [ NoSymbol, NoSymbol, onesuperior, exclamdown ] }; // "1"
+ key <AE02> { [ NoSymbol, NoSymbol, twosuperior, onehalf ] }; // "2"
+ key <AE03> { [ NoSymbol, NoSymbol, threesuperior, onethird ] }; // "3"
+ key <AE04> { [ NoSymbol, NoSymbol, dollar, onequarter ] }; // "4"
+ key <AE05> { [ NoSymbol, NoSymbol, U2030, NoSymbol ] }; // "5"
+ key <AE06> { [ NoSymbol, NoSymbol, uparrow, NoSymbol ] }; // "6"
+ key <AE07> { [ NoSymbol, NoSymbol, ampersand, questiondown ] }; // "7"
+ key <AE08> { [ NoSymbol, NoSymbol, infinity, oneeighth ] }; // "8"
+ key <AE09> { [ NoSymbol, NoSymbol, leftarrow, NoSymbol ] }; // "9"
+ key <AE10> { [ NoSymbol, NoSymbol, rightarrow, NoSymbol ] }; // "0"
+ key <AE11> { [ NoSymbol, NoSymbol, emdash, endash ] }; // "-"
+ key <AE12> { [ NoSymbol, NoSymbol, notequal, plusminus ] }; // "="
+
+ // 2nd keyboard row
+ key <AD03> { [ NoSymbol, NoSymbol, EuroSign, NoSymbol ] }; // "e"
+ key <AD04> { [ NoSymbol, NoSymbol, registered, NoSymbol ] }; // "r"
+ key <AD05> { [ NoSymbol, NoSymbol, trademark, NoSymbol ] }; // "t"
+ key <AD06> { [ NoSymbol, NoSymbol, yen, NoSymbol ] }; // "y"
+ key <AD10> { [ NoSymbol, NoSymbol, acute, doubleacute ] }; // "p"
+ key <AD11> { [ NoSymbol, NoSymbol, bracketleft, braceleft ] }; // "["
+ key <AD12> { [ NoSymbol, NoSymbol, bracketright, braceright ] }; // "]"
+
+ // 3rd keyboard row
+ key <AC01> { [ NoSymbol, NoSymbol, U0301, NoSymbol ] }; // "a"
+ key <AC02> { [ NoSymbol, NoSymbol, section, NoSymbol ] }; // "s"
+ key <AC03> { [ NoSymbol, NoSymbol, degree, division ] }; // "d"
+ key <AC04> { [ NoSymbol, NoSymbol, sterling, NoSymbol ] }; // "f"
+ key <AC07> { [ NoSymbol, NoSymbol, doublelowquotemark, singlelowquotemark ] }; // "j"
+ key <AC08> { [ NoSymbol, NoSymbol, leftdoublequotemark, leftsinglequotemark ] }; // "k"
+ key <AC09> { [ NoSymbol, NoSymbol, rightdoublequotemark, rightsinglequotemark ] }; // "l"
+ key <AC10> { [ NoSymbol, NoSymbol, leftsinglequotemark, minutes ] }; // ";"
+ key <AC11> { [ NoSymbol, NoSymbol, rightsinglequotemark, seconds ] }; // "'"
+
+ // 4th keyboard row
+ key <AB02> { [ NoSymbol, NoSymbol, multiply, U22C5 ] }; // "x"
+ key <AB03> { [ NoSymbol, NoSymbol, copyright, cent ] }; // "c"
+ key <AB04> { [ NoSymbol, NoSymbol, downarrow, U25CA ] }; // "v"
+ key <AB07> { [ NoSymbol, NoSymbol, U2212, enfilledcircbullet ] }; // "m"
+ key <AB08> { [ NoSymbol, NoSymbol, guillemotleft, less ] }; // ","
+ key <AB09> { [ NoSymbol, NoSymbol, guillemotright, greater ] }; // "."
+ key <AB10> { [ NoSymbol, NoSymbol, ellipsis, NoSymbol ] }; // "/"
+
+ // 5th keyboard row
+ key <SPCE> { [ space, space, nobreakspace, nobreakspace ] }; // " "
+
+ // Reference
+ // U+2030 PER MILLE SIGN
+ // U+0301 COMBINING ACUTE ACCENT
+ // U+22C5 DOT OPERATOR
+ // U+25CA LOZENGE
+ // U+2212 MINUS SIGN
+
};