[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#241331: fix libGL builds on sparc



Attached is a patch stolen from xfree86's bugzilla (#923).
I've rediffed it, to fit into 4.3.0-7. Builds fine on sparc, and glx
apps are fine with indirect mesa rendering again.
(to get dri working with sunffb - fails initialization due to a missing
symbol - is another story; I will open a new bug for it sometime, after
testing a little fix discussed with DaveM)

The corresponding upstream changeset can be found at:
http://cvsweb.xfree86.org/cvsweb/xc/lib/GL/glx/glxext.c.diff?r1=1.21&r2=1.22

I don't see any problematic license changes in it.

Please apply.

 - Christian

--- xc/lib/GL/glx/glxext.c.orig	2003-02-21 06:31:24.000000000 +0100
+++ xc/lib/GL/glx/glxext.c	2004-04-06 00:05:43.000000000 +0200
@@ -58,6 +58,37 @@
 void __glXDumpDrawBuffer(__GLXcontext *ctx);
 #endif
 
+#ifdef USE_SPARC_ASM
+/*
+ * This is where our dispatch table's bounds are.
+ * And the static mesa_init is taken directly from
+ * Mesa's 'sparc.c' initializer.
+ * 
+ * We need something like this here, because this version
+ * of openGL/glx never initializes a Mesa context, and so
+ * the address of the dispatch table pointer never gets stuffed
+ * into the dispatch jump table otherwise.
+ * 
+ * It matters only on SPARC, and only if you are using assembler
+ * code instead of C-code indirect dispatch.
+ * 
+ * -- FEM, 04.xii.03
+ */
+extern unsigned int _mesa_sparc_glapi_begin;
+extern unsigned int _mesa_sparc_glapi_end;
+extern void __glapi_sparc_icache_flush(unsigned int *);
+static void _glx_mesa_init_sparc_glapi_relocs(void);
+static int _mesa_sparc_needs_init = 1;
+#define INIT_MESA_SPARC { \
+    if(_mesa_sparc_needs_init) { \
+      _glx_mesa_init_sparc_glapi_relocs(); \
+      _mesa_sparc_needs_init = 0; \
+  } \
+}
+#else
+#define INIT_MESA_SPARC
+#endif
+
 /*
 ** We setup some dummy structures here so that the API can be used
 ** even if no context is current.
@@ -489,6 +520,7 @@
     }
 #endif
 
+    INIT_MESA_SPARC
     /* The one and only long long lock */
     __glXLock();
 
@@ -603,6 +635,7 @@
 
 	if (gc->currentDpy == dpy) {
 	    /* Use opcode from gc because its right */
+            INIT_MESA_SPARC
 	    return gc->majorOpcode;
 	} else {
 	    /*
@@ -1029,3 +1062,64 @@
     }	    
 }
 #endif
+
+/*
+ * Used only when we are sparc, using sparc assembler.
+ *
+ */
+
+static void
+_glx_mesa_init_sparc_glapi_relocs(void)
+{
+#ifdef  USE_SPARC_ASM
+	unsigned int *insn_ptr, *end_ptr;
+	unsigned long disp_addr;
+
+	insn_ptr = &_mesa_sparc_glapi_begin;
+	end_ptr = &_mesa_sparc_glapi_end;
+	disp_addr = (unsigned long) &_glapi_Dispatch;
+
+	/*
+         * Verbatim from Mesa sparc.c.  It's needed because there doesn't
+         * seem to be a better way to do this:
+         *
+         * UNCONDITIONAL_JUMP ( (*_glapi_Dispatch) + entry_offset )
+         *
+         * This code is patching in the ADDRESS of the pointer to the
+         * dispatch table.  Hence, it must be called exactly once, because
+         * that address is not going to change.
+         *
+         * What it points to can change, but Mesa (and hence, we) assume
+         * that there is only one pointer.
+         *
+	 */
+	while (insn_ptr < end_ptr) {
+#if ( defined(__sparc_v9__) && ( !defined(__linux__) || defined(__linux_64__) ) )	
+/*
+	This code patches for 64-bit addresses.  This had better
+	not happen for Sparc/Linux, no matter what architecture we
+	are building for.  So, don't do this.
+
+        The 'defined(__linux_64__)' is used here as a placeholder for
+        when we do do 64-bit usermode on sparc linux.
+	*/
+		insn_ptr[0] |= (disp_addr >> (32 + 10));
+		insn_ptr[1] |= ((disp_addr & 0xffffffff) >> 10);
+		__glapi_sparc_icache_flush(&insn_ptr[0]);
+		insn_ptr[2] |= ((disp_addr >> 32) & ((1 << 10) - 1));
+		insn_ptr[3] |= (disp_addr & ((1 << 10) - 1));
+		__glapi_sparc_icache_flush(&insn_ptr[2]);
+		insn_ptr += 11;
+#else
+		insn_ptr[0] |= (disp_addr >> 10);
+		insn_ptr[1] |= (disp_addr & ((1 << 10) - 1));
+		__glapi_sparc_icache_flush(&insn_ptr[0]);
+		insn_ptr += 5;
+#endif
+#else
+                /* Just no-op
+                 *
+                 */ 
+#endif  /* sparc ASM in use */
+	}
+}

Reply to: