Commit dfa003f7 authored by pcy's avatar pcy
Browse files

lol

parent 4166c52d
...@@ -39,6 +39,9 @@ t: debug ...@@ -39,6 +39,9 @@ t: debug
FNA_KEYBOARD_USE_SCANCODES=1 FNA_OPENGL_DISABLE_LATESWAPTEAR=1 \ FNA_KEYBOARD_USE_SCANCODES=1 FNA_OPENGL_DISABLE_LATESWAPTEAR=1 \
FNA_OPENGL_FORCE_CORE_PROFILE=1 \ FNA_OPENGL_FORCE_CORE_PROFILE=1 \
$(MONO) --debug=mdb-optimizations "$(TARGET)" $(MONO) --debug=mdb-optimizations "$(TARGET)"
#FNA_GRAPHICS_MOJOSHADER_PROFILE=glsl120
# FNA_GRAPHICS_FORCE_GLDEVICE=ModernGLDevice \
#
tx: xb tx: xb
TERM=xterm MONO_PATH="$$PWD/lib/:$$MONO_PATH" \ TERM=xterm MONO_PATH="$$PWD/lib/:$$MONO_PATH" \
......
...@@ -57,15 +57,16 @@ namespace PoroCYon.FNAGLSL { ...@@ -57,15 +57,16 @@ namespace PoroCYon.FNAGLSL {
public partial class GLSLEffect : Effect { public partial class GLSLEffect : Effect {
public struct ActiveEffect : IDisposable { public struct ActiveEffect : IDisposable {
internal GraphicsDevice gd;
internal uint oldprgm; internal uint oldprgm;
internal List<TexT> texs; internal List<TexT> texs;
bool disposed; bool disposed;
internal ActiveEffect(uint old, List<TexT> ts) { internal ActiveEffect(GraphicsDevice d, uint old, List<TexT> ts) {
oldprgm = old; disposed = false; texs = ts; gd = d; oldprgm = old; disposed = false; texs = ts;
} }
public void Dispose() { public unsafe void Dispose() {
if (disposed) return; if (disposed) return;
GL.GetError(); GL.GetError();
...@@ -93,12 +94,18 @@ namespace PoroCYon.FNAGLSL { ...@@ -93,12 +94,18 @@ namespace PoroCYon.FNAGLSL {
texs.Clear(); texs.Clear();
} }
GL.DebugMessageControl(GL.DONT_CARE, GL.DEBUG_TYPE_ERROR,
GL.DONT_CARE, 0, null, 1);
GL.GetError();
disposed = true; disposed = true;
} }
} }
static int maxTextureSlots = -1; static int maxTextureSlots = -1;
GraphicsDevice gd;
uint[] glshdrs; uint[] glshdrs;
uint glprgm; uint glprgm;
...@@ -111,6 +118,7 @@ namespace PoroCYon.FNAGLSL { ...@@ -111,6 +118,7 @@ namespace PoroCYon.FNAGLSL {
public unsafe GLSLEffect(GraphicsDevice gd, public unsafe GLSLEffect(GraphicsDevice gd,
IDictionary<GLSLPurpose, string> shaders) IDictionary<GLSLPurpose, string> shaders)
: base(/*UGLY hack*/new BasicEffect(gd)) { : base(/*UGLY hack*/new BasicEffect(gd)) {
this.gd = gd;
fakeTech = Techniques[0]; fakeTech = Techniques[0];
unifDataBacking = IntPtr.Zero; unifDataBacking = IntPtr.Zero;
...@@ -120,9 +128,6 @@ namespace PoroCYon.FNAGLSL { ...@@ -120,9 +128,6 @@ namespace PoroCYon.FNAGLSL {
GL.Init(gd); GL.Init(gd);
GL.GetError(); // ignore errors from FNA/mojoshader GL.GetError(); // ignore errors from FNA/mojoshader
GL.Enable(GL.DEBUG_OUTPUT_SYNCHRONOUS);
GL.Throw();
if (maxTextureSlots < 0) { if (maxTextureSlots < 0) {
maxTextureSlots = GL.GetIntegerv(GL.MAX_COMBINED_TEXTURE_IMAGE_UNITS); maxTextureSlots = GL.GetIntegerv(GL.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
GL.Throw(); GL.Throw();
...@@ -295,7 +300,7 @@ namespace PoroCYon.FNAGLSL { ...@@ -295,7 +300,7 @@ namespace PoroCYon.FNAGLSL {
///<summary> ///<summary>
///USAGE: using (var eff &eq; glslEffect.Bind()) { ... gd.DrawPrimitives(...); ... } ///USAGE: using (var eff &eq; glslEffect.Bind()) { ... gd.DrawPrimitives(...); ... }
///</summary> ///</summary>
public ActiveEffect Bind() { // TODO: how to warn on discarding the retval? public unsafe ActiveEffect Bind() { // TODO: how to warn on discarding the retval?
GL.GetError(); // ignore errors from FNA/mojoshader GL.GetError(); // ignore errors from FNA/mojoshader
// workaround FNA crap // workaround FNA crap
...@@ -310,7 +315,24 @@ namespace PoroCYon.FNAGLSL { ...@@ -310,7 +315,24 @@ namespace PoroCYon.FNAGLSL {
ApplyUnifs(); ApplyUnifs();
return new ActiveEffect(oldprgm, usedTextures); /*
* FNA will fail binding vertex attributes because it sets the
* vertex array buffer to 0 while passing non-null ptrs to
* glVertexAttribArray, which is an INVALID_OPERATION. When FNA is
* compiled with debugging enabled, this will throw an exception.
* (libmojoshader will also call a glUniform which will also most
* likely fail)
*
* so what we do is we disable DEBUG_TYPE_ERRORs and set up vertex
* attributes ourselves (and undo that afterwards)
*/
// TODO: we kinda need the vertex format in the first place...
GL.DebugMessageControl(GL.DONT_CARE, GL.DEBUG_TYPE_ERROR,
GL.DONT_CARE, 0, null, 0);
GL.GetError();
return new ActiveEffect(gd, oldprgm, usedTextures);
} }
[Obsolete("Please use Bind() instead")] [Obsolete("Please use Bind() instead")]
public ActiveEffect Apply() { return Bind(); } public ActiveEffect Apply() { return Bind(); }
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
...@@ -71,7 +72,7 @@ namespace PoroCYon.FNAGLSL { ...@@ -71,7 +72,7 @@ namespace PoroCYon.FNAGLSL {
} }
} }
static T GetProcAddress<T>(string name) static T GetProcAddress<T>(string name, bool req = true)
where T : class { where T : class {
if (!typeof(T).IsSubclassOf(typeof(Delegate))) { if (!typeof(T).IsSubclassOf(typeof(Delegate))) {
throw new ArgumentException("Type '" + typeof(T) + "' is not a delegate type!"); throw new ArgumentException("Type '" + typeof(T) + "' is not a delegate type!");
...@@ -79,7 +80,8 @@ namespace PoroCYon.FNAGLSL { ...@@ -79,7 +80,8 @@ namespace PoroCYon.FNAGLSL {
IntPtr fn = SDL_GL_GetProcAddress("gl"+name); IntPtr fn = SDL_GL_GetProcAddress("gl"+name);
if (fn == IntPtr.Zero) { if (fn == IntPtr.Zero) {
throw new NotSupportedException("gl"+name); if (req) throw new NotSupportedException("gl"+name);
else return null;
} }
return (T)(object)Marshal.GetDelegateForFunctionPointer(fn, typeof(T)); return (T)(object)Marshal.GetDelegateForFunctionPointer(fn, typeof(T));
...@@ -98,11 +100,66 @@ namespace PoroCYon.FNAGLSL { ...@@ -98,11 +100,66 @@ namespace PoroCYon.FNAGLSL {
InitProcs(); InitProcs();
inited = true; inited = true;
GL.Enable(GL.DEBUG_OUTPUT);
GL.Throw();
GL.DebugMessageCallback(DebugCb, IntPtr.Zero);
GL.Enable(GL.DEBUG_OUTPUT_SYNCHRONOUS);
GL.Throw();
} }
public static void Deinit() { public static void Deinit() {
GL.DebugMessageCallback(null, IntPtr.Zero);
DeinitProcs(); DeinitProcs();
inited = false; inited = false;
} }
static void DebugCb(uint src, uint typ, uint id,
uint sev, int len, sbyte* msg, IntPtr ud) {
//if (sev == DEBUG_SEVERITY_NOTIFICATION) return;
string str = new string(msg, 0, len);
string ssrc = "???", styp = "???", ssev = "???";
switch (src) {
case DEBUG_SOURCE_API: ssrc = "API"; break;
case DEBUG_SOURCE_WINDOW_SYSTEM: ssrc = "winsys"; break;
case DEBUG_SOURCE_SHADER_COMPILER: ssrc = "shdrc"; break;
case DEBUG_SOURCE_THIRD_PARTY: ssrc = "3rdp"; break;
case DEBUG_SOURCE_APPLICATION: ssrc = "app"; break;
case DEBUG_SOURCE_OTHER: ssrc = "other"; break;
}
switch (typ) {
case DEBUG_TYPE_ERROR: styp = "err"; break;
case DEBUG_TYPE_DEPRECATED_BEHAVIOR: styp = "depr"; break;
case DEBUG_TYPE_UNDEFINED_BEHAVIOR: styp = "und"; break;
case DEBUG_TYPE_PORTABILITY: styp = "port"; break;
case DEBUG_TYPE_PERFORMANCE: styp = "perf"; break;
case DEBUG_TYPE_MARKER: styp = "mark"; break;
case DEBUG_TYPE_PUSH_GROUP: styp = "push"; break;
case DEBUG_TYPE_POP_GROUP: styp = "pop"; break;
case DEBUG_TYPE_OTHER: styp = "other"; break;
}
switch (sev) {
case DEBUG_SEVERITY_HIGH: ssev = "high"; break;
case DEBUG_SEVERITY_MEDIUM: ssev = "med"; break;
case DEBUG_SEVERITY_LOW: ssev = "low"; break;
case DEBUG_SEVERITY_NOTIFICATION: ssev = "notif"; break;
}
Console.WriteLine("GL dbgcb: src="+ssrc+" typ="+styp+" sev="+ssev+" id="+id
+":\t"+str);
if (sev == DEBUG_SEVERITY_HIGH || typ == DEBUG_TYPE_ERROR) {
Console.WriteLine(new StackTrace(true));
Console.WriteLine();
}
}
} }
} }
...@@ -10,11 +10,10 @@ namespace PoroCYon.FNAGLSL { ...@@ -10,11 +10,10 @@ namespace PoroCYon.FNAGLSL {
LINK_STATUS = 0x8B82, LINK_STATUS = 0x8B82,
CURRENT_PROGRAM = 0x8B8D, CURRENT_PROGRAM = 0x8B8D,
DEBUG_OUTPUT_SYNCHRONOUS = 0x8242,
ACTIVE_ATTRIBUTES = 0x8B89, ACTIVE_ATTRIBUTES = 0x8B89,
ACTIVE_UNIFORMS = 0x8B86, ACTIVE_UNIFORMS = 0x8B86,
INVALID_INDEX = 0xFFFFFFFFu, INVALID_INDEX = 0xFFFFFFFFu,
DONT_CARE = 0x1100,
MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D, MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D,
ACTIVE_TEXTURE = 0x84E0, ACTIVE_TEXTURE = 0x84E0,
...@@ -50,7 +49,33 @@ namespace PoroCYon.FNAGLSL { ...@@ -50,7 +49,33 @@ namespace PoroCYon.FNAGLSL {
UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = 0x8A45, UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = 0x8A45,
UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46, UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46,
UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER = 0x84F0, UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER = 0x84F0,
UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x84F1; UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x84F1,
DEBUG_OUTPUT = 0x92E0,
DEBUG_OUTPUT_SYNCHRONOUS = 0x8242,
DEBUG_SOURCE_API = 0x8246,
DEBUG_SOURCE_WINDOW_SYSTEM = 0x8247,
DEBUG_SOURCE_SHADER_COMPILER = 0x8248,
DEBUG_SOURCE_THIRD_PARTY = 0x8249,
DEBUG_SOURCE_APPLICATION = 0x824A,
DEBUG_SOURCE_OTHER = 0x824B,
DEBUG_TYPE_ERROR = 0x824C,
DEBUG_TYPE_DEPRECATED_BEHAVIOR = 0x824D,
DEBUG_TYPE_UNDEFINED_BEHAVIOR = 0x824E,
DEBUG_TYPE_PORTABILITY = 0x824F,
DEBUG_TYPE_PERFORMANCE = 0x8250,
DEBUG_TYPE_MARKER = 0x8268,
DEBUG_TYPE_PUSH_GROUP = 0x8269,
DEBUG_TYPE_POP_GROUP = 0x829A,
DEBUG_TYPE_OTHER = 0x8251,
DEBUG_SEVERITY_HIGH = 0x9146,
DEBUG_SEVERITY_MEDIUM = 0x9147,
DEBUG_SEVERITY_LOW = 0x9148,
DEBUG_SEVERITY_NOTIFICATION = 0x826B;
public const byte FALSE = 0, TRUE = 1; public const byte FALSE = 0, TRUE = 1;
......
...@@ -52,6 +52,8 @@ namespace PoroCYon.FNAGLSL { ...@@ -52,6 +52,8 @@ namespace PoroCYon.FNAGLSL {
_Enable = GetProcAddress<Enable_T>("Enable"); _Enable = GetProcAddress<Enable_T>("Enable");
_Disable = GetProcAddress<Disable_T>("Disable"); _Disable = GetProcAddress<Disable_T>("Disable");
_DebugMessageCallback = GetProcAddress<DebugMessageCallback_T>("DebugMessageCallback", false);
_DebugMessageControl = GetProcAddress<DebugMessageControl_T>("DebugMessageControl", false);
_Uniform1fv = GetProcAddress<Uniform1fv_T>("Uniform1fv"); _Uniform1fv = GetProcAddress<Uniform1fv_T>("Uniform1fv");
_Uniform2fv = GetProcAddress<Uniform2fv_T>("Uniform2fv"); _Uniform2fv = GetProcAddress<Uniform2fv_T>("Uniform2fv");
...@@ -118,6 +120,8 @@ namespace PoroCYon.FNAGLSL { ...@@ -118,6 +120,8 @@ namespace PoroCYon.FNAGLSL {
_Enable = null; _Enable = null;
_Disable = null; _Disable = null;
_DebugMessageCallback = null;
_DebugMessageControl = null;
_Uniform1fv = null; _Uniform1fv = null;
_Uniform2fv = null; _Uniform2fv = null;
...@@ -615,6 +619,25 @@ namespace PoroCYon.FNAGLSL { ...@@ -615,6 +619,25 @@ namespace PoroCYon.FNAGLSL {
delegate void Disable_T(GLenum cap); delegate void Disable_T(GLenum cap);
static Disable_T _Disable; static Disable_T _Disable;
public static void Disable(GLenum cap) { _Disable(cap); } public static void Disable(GLenum cap) { _Disable(cap); }
public delegate void DEBUGPROC(GLenum src, GLenum typ, GLuint id,
GLenum sev, GLsizei len, GLchar* msg, IntPtr ud);
/*public delegate void DEBUGPROC_mgd(GLenum src, GLenum typ, GLuint id,
GLenum sev, string msg, IntPtr ud);*/
delegate void DebugMessageCallback_T(IntPtr cb, IntPtr ud);
static DebugMessageCallback_T _DebugMessageCallback;
public static void DebugMessageCallback(DEBUGPROC cb, IntPtr ud) {
if (_DebugMessageCallback != null)
_DebugMessageCallback(Marshal.GetFunctionPointerForDelegate(cb), ud);
}
delegate void DebugMessageControl_T(GLenum src, GLenum typ, GLenum sev, GLsizei cnt, GLuint* ids, GLboolean en);
static DebugMessageControl_T _DebugMessageControl;
public static void DebugMessageControl(GLenum src, GLenum typ, GLenum sev, GLsizei cnt, GLuint* ids, GLboolean en) {
if (_DebugMessageControl != null)
_DebugMessageControl(src, typ, sev, cnt, ids, en);
}
} }
} }
...@@ -16,6 +16,8 @@ namespace PoroCYon.FNAGLSL { ...@@ -16,6 +16,8 @@ namespace PoroCYon.FNAGLSL {
"texture" , BindingFlags.GetField|BindingFlags.NonPublic|BindingFlags.Instance); "texture" , BindingFlags.GetField|BindingFlags.NonPublic|BindingFlags.Instance);
readonly static FieldInfo tx_texture_fi = typeof(Texture).GetField( readonly static FieldInfo tx_texture_fi = typeof(Texture).GetField(
"texture" , BindingFlags.GetField|BindingFlags.NonPublic|BindingFlags.Instance); "texture" , BindingFlags.GetField|BindingFlags.NonPublic|BindingFlags.Instance);
readonly static FieldInfo gd_vbufCnt_fi = typeof(GraphicsDevice).GetField(
"vertexBufferCount", BindingFlags.GetField|BindingFlags.NonPublic|BindingFlags.Instance);
readonly static PropertyInfo ef_Techniques_pi = typeof(Effect).GetProperty( readonly static PropertyInfo ef_Techniques_pi = typeof(Effect).GetProperty(
"Techniques", BindingFlags.SetProperty|BindingFlags.Public|BindingFlags.Instance), "Techniques", BindingFlags.SetProperty|BindingFlags.Public|BindingFlags.Instance),
...@@ -224,6 +226,12 @@ namespace PoroCYon.FNAGLSL { ...@@ -224,6 +226,12 @@ namespace PoroCYon.FNAGLSL {
return (int)gltex_Target_pi.GetValue(igltex, null); return (int)gltex_Target_pi.GetValue(igltex, null);
} }
public static int GetVertexBufferCount(this GraphicsDevice gd) =>
(int)gd_vbufCnt_fi.GetValue(gd);
public static void SetVertexBufferCount(this GraphicsDevice gd, int value) {
gd_vbufCnt_fi.SetValue(gd, value);
}
} }
} }
...@@ -8,8 +8,8 @@ using Microsoft.Xna.Framework.Graphics; ...@@ -8,8 +8,8 @@ using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
using PoroCYon.FNAGLSL; using PoroCYon.FNAGLSL;
//using VertexType = Microsoft.Xna.Framework.Graphics.VertexPositionColorTexture; using VertexType = Microsoft.Xna.Framework.Graphics.VertexPositionColorTexture;
[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)] /*[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]
struct VertexType { struct VertexType {
Vector3 pos; Vector3 pos;
Vector2 uv ; Vector2 uv ;
...@@ -28,7 +28,7 @@ struct VertexType { ...@@ -28,7 +28,7 @@ struct VertexType {
, new VertexElement(0+sizeof(Vector3)+sizeof(Vector2), , new VertexElement(0+sizeof(Vector3)+sizeof(Vector2),
VertexElementFormat.Color , VertexElementUsage.Color , 0) VertexElementFormat.Color , VertexElementUsage.Color , 0)
); );
} }*/
class TestGame : Game { class TestGame : Game {
GraphicsDeviceManager gdm; GraphicsDeviceManager gdm;
...@@ -207,7 +207,7 @@ class TestGame : Game { ...@@ -207,7 +207,7 @@ class TestGame : Game {
using (var act = glsl.Bind()) { using (var act = glsl.Bind()) {
GraphicsDevice.DrawUserPrimitives<VertexType>( GraphicsDevice.DrawUserPrimitives<VertexType>(
PrimitiveType.TriangleStrip, vertices_fs, 0, 2, VertexType.Format); PrimitiveType.TriangleStrip, vertices_fs, 0, 2, VertexType.VertexDeclaration/*Format*/);
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment