]> git.cworth.org Git - vogl/blobdiff - src/voglcommon/vogl_gl_replayer.cpp
- Initial support for KHR_debug API's in tracer/replayer
[vogl] / src / voglcommon / vogl_gl_replayer.cpp
index f11a954f30cea9a8d81bd1d7f680dfac1ee66f91..deb3ceabacb9efecab458370dbbe848f6712a19a 100644 (file)
@@ -1266,7 +1266,10 @@ GLint vogl_gl_replayer::determine_uniform_replay_location(GLuint trace_program,
 {
     VOGL_FUNC_TRACER
 
-    GLint replay_location = trace_location;
+    // Seems better to return -1 when we can't find the uniform (which can happen if the driver optimizes the program differently vs. tracing).
+    // Otherwise, we can pass an invalid handle down to the driver and this will crash AMD's fglrx.
+    //GLint replay_location = trace_location;
+    GLint replay_location = -1;
 
     glsl_program_hash_map::iterator it = get_shared_state()->m_glsl_program_hash_map.find(trace_program);
     if (it == get_shared_state()->m_glsl_program_hash_map.end())
@@ -1496,6 +1499,32 @@ void vogl_gl_replayer::debug_callback_arb(GLenum source, GLenum type, GLuint id,
     }
 }
 
+//----------------------------------------------------------------------------------------------------------------------
+// vogl_replayer::debug_callback
+//----------------------------------------------------------------------------------------------------------------------
+void vogl_gl_replayer::debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *pUser_param)
+{
+    VOGL_FUNC_TRACER
+
+    VOGL_NOTE_UNUSED(length);
+
+    char final_message[4096];
+
+    context_state *pContext_state = (context_state *)(pUser_param);
+
+    vogl_format_debug_output_arb(final_message, sizeof(final_message), source, type, id, severity, reinterpret_cast<const char *>(message));
+
+    if (pContext_state)
+    {
+        vogl_warning_printf("%s: Trace context: 0x%" PRIX64 ", Replay context 0x%" PRIX64 ", Last trace call counter: %" PRIu64 "\n%s\n", VOGL_FUNCTION_NAME,
+                           cast_val_to_uint64(pContext_state->m_trace_context), cast_val_to_uint64(pContext_state->m_replay_context), cast_val_to_uint64(pContext_state->m_last_call_counter), final_message);
+    }
+    else
+    {
+        vogl_warning_printf("%s: %s\n", VOGL_FUNCTION_NAME, final_message);
+    }
+}
+
 //----------------------------------------------------------------------------------------------------------------------
 // vogl_replayer::is_extension_supported
 //----------------------------------------------------------------------------------------------------------------------
@@ -3988,7 +4017,7 @@ vogl_gl_replayer::status_t vogl_gl_replayer::process_gl_entrypoint_packet_intern
         if (!vogl_display_list_state::is_call_listable(entrypoint_id, trace_packet))
         {
             if (!g_vogl_entrypoint_descs[entrypoint_id].m_whitelisted_for_displaylists)
-                process_entrypoint_error("%s: Failed serializing trace packet into display list shadow! Call is not listable.\n", VOGL_FUNCTION_NAME);
+                process_entrypoint_error("%s: Failed serializing trace packet into display list shadow! Call is not whitelisted for display list usage by vogl.\n", VOGL_FUNCTION_NAME);
             else
                 process_entrypoint_warning("%s: Failed serializing trace packet into display list shadow! Call with these parameters is not listable.\n", VOGL_FUNCTION_NAME);
         }
@@ -4008,7 +4037,8 @@ vogl_gl_replayer::status_t vogl_gl_replayer::process_gl_entrypoint_packet_intern
 // (typically pointers to fixed size buffers, or params directly controlling the size of buffers).
 #define VOGL_SIMPLE_REPLAY_FUNC_BEGIN(name, num_params) \
     case VOGL_ENTRYPOINT_##name:                        \
-    { GL_ENTRYPOINT(name)(
+    { if (!GL_ENTRYPOINT(name)) { process_entrypoint_error("vogl_gl_replayer::process_gl_entrypoint_packet_internal: Can't call NULL GL entrypoint %s (maybe a missing extension?)\n", #name); } else \
+    GL_ENTRYPOINT(name)(
 #define VOGL_SIMPLE_REPLAY_FUNC_PARAM_VALUE(type, index) trace_packet.get_param_value<type>(index)
 #define VOGL_SIMPLE_REPLAY_FUNC_PARAM_SEPERATOR ,
 #define VOGL_SIMPLE_REPLAY_FUNC_PARAM_CLIENT_MEMORY(type, index) trace_packet.get_param_client_memory<type>(index)
@@ -8445,14 +8475,6 @@ vogl_gl_replayer::status_t vogl_gl_replayer::process_gl_entrypoint_packet_intern
             // TODO - we need to hook up this extension to the tracer
             break;
         }
-        case VOGL_ENTRYPOINT_glDebugMessageCallbackARB:
-        case VOGL_ENTRYPOINT_glGetDebugMessageLogARB:
-        case VOGL_ENTRYPOINT_glDebugMessageControlARB:
-        case VOGL_ENTRYPOINT_glDebugMessageInsertARB:
-        {
-            // TODO
-            break;
-        }
         case VOGL_ENTRYPOINT_glBitmap:
         {
             VOGL_REPLAY_LOAD_PARAMS_HELPER_glBitmap;
@@ -8719,6 +8741,126 @@ vogl_gl_replayer::status_t vogl_gl_replayer::process_gl_entrypoint_packet_intern
 
             break;
         }
+        case VOGL_ENTRYPOINT_glDebugMessageInsert:
+        {
+            VOGL_REPLAY_LOAD_PARAMS_HELPER_glDebugMessageInsert;
+
+            VOGL_REPLAY_CALL_GL_HELPER_glDebugMessageInsert;
+            break;
+        }
+        case VOGL_ENTRYPOINT_glDebugMessageInsertARB:
+        {
+            VOGL_REPLAY_LOAD_PARAMS_HELPER_glDebugMessageInsertARB;
+
+            VOGL_REPLAY_CALL_GL_HELPER_glDebugMessageInsertARB;
+            break;
+        }
+        case VOGL_ENTRYPOINT_glDebugMessageCallbackARB:
+        {
+            GL_ENTRYPOINT(glDebugMessageCallbackARB)(debug_callback_arb, (GLvoid *)m_pCur_context_state);
+
+            break;
+        }
+        case VOGL_ENTRYPOINT_glDebugMessageCallback:
+        {
+            GL_ENTRYPOINT(glDebugMessageCallback)(debug_callback, (GLvoid *)m_pCur_context_state);
+
+            break;
+        }
+        case VOGL_ENTRYPOINT_glObjectLabel:
+        {
+            VOGL_REPLAY_LOAD_PARAMS_HELPER_glObjectLabel;
+
+            switch (identifier)
+            {
+                case GL_BUFFER:
+                {
+                    name = map_handle(get_shared_state()->m_buffers, name);
+                    break;
+                }
+                case GL_SHADER:
+                case GL_PROGRAM:
+                {
+                    name = map_handle(get_shared_state()->m_shadow_state.m_objs, name);
+                    break;
+                }
+                case GL_VERTEX_ARRAY:
+                {
+                    name = map_handle(get_shared_state()->m_vertex_array_objects, name);
+                    break;
+                }
+                case GL_QUERY:
+                {
+                    name = map_handle(get_shared_state()->m_queries, name);
+                    break;
+                }
+                case GL_SAMPLER:
+                {
+                    name = map_handle(get_shared_state()->m_sampler_objects, name);
+                    break;
+                }
+                case GL_TEXTURE:
+                {
+                    name = map_handle(get_shared_state()->m_shadow_state.m_textures, name);
+                    break;
+                }
+                case GL_RENDERBUFFER:
+                {
+                    name = map_handle(get_shared_state()->m_shadow_state.m_rbos, name);
+                    break;
+                }
+                case GL_FRAMEBUFFER:
+                {
+                    name = map_handle(get_shared_state()->m_framebuffers, name);
+                    break;
+                }
+                case GL_DISPLAY_LIST:
+                {
+                    name = map_handle(get_shared_state()->m_lists, name);
+                    break;
+                }
+                case GL_TRANSFORM_FEEDBACK: // TODO: Investigate this more
+                case GL_PROGRAM_PIPELINE: // TODO: We don't support program pipelines yet
+                default:
+                {
+                    process_entrypoint_error("%s: Unsupported object identifier 0x%X\n", VOGL_METHOD_NAME, identifier);
+                    return cStatusSoftFailure;
+                }
+            }
+
+            VOGL_REPLAY_CALL_GL_HELPER_glObjectLabel;
+
+            break;
+        }
+        case VOGL_ENTRYPOINT_glObjectPtrLabel:
+        {
+            vogl_sync_ptr_value trace_sync = trace_packet.get_param_ptr_value(0);
+            GLsizei length = trace_packet.get_param_value<GLsizei>(1);
+            const GLchar *pTrace_label = reinterpret_cast<const GLchar *>(trace_packet.get_param_client_memory_ptr(2));
+            GLsync replay_sync = NULL;
+
+            if (trace_sync)
+            {
+                gl_sync_hash_map::const_iterator it = get_shared_state()->m_syncs.find(trace_sync);
+                if (it == get_shared_state()->m_syncs.end())
+                {
+                    process_entrypoint_error("%s: Failed remapping trace sync value 0x%" PRIx64 "\n", VOGL_METHOD_NAME, static_cast<uint64_t>(trace_sync));
+                    return cStatusSoftFailure;
+                }
+                else
+                {
+                    replay_sync = it->second;
+                }
+            }
+
+            GL_ENTRYPOINT(glObjectPtrLabel)(replay_sync, length, pTrace_label);
+
+            break;
+        }
+        case VOGL_ENTRYPOINT_glGetDebugMessageLogARB:
+        case VOGL_ENTRYPOINT_glGetObjectLabel:
+        case VOGL_ENTRYPOINT_glGetObjectPtrLabel:
+        case VOGL_ENTRYPOINT_glGetDebugMessageLog:
         case VOGL_ENTRYPOINT_glAreTexturesResident:
         case VOGL_ENTRYPOINT_glAreTexturesResidentEXT:
         case VOGL_ENTRYPOINT_glGetActiveAtomicCounterBufferiv:
@@ -8770,7 +8912,7 @@ vogl_gl_replayer::status_t vogl_gl_replayer::process_gl_entrypoint_packet_intern
         case VOGL_ENTRYPOINT_glGetConvolutionParameteriv:
         case VOGL_ENTRYPOINT_glGetConvolutionParameterivEXT:
         case VOGL_ENTRYPOINT_glGetConvolutionParameterxvOES:
-        case VOGL_ENTRYPOINT_glGetDebugMessageLog:
+
         case VOGL_ENTRYPOINT_glGetDebugMessageLogAMD:
         case VOGL_ENTRYPOINT_glGetDetailTexFuncSGIS:
         case VOGL_ENTRYPOINT_glGetDoubleIndexedvEXT:
@@ -8872,10 +9014,8 @@ vogl_gl_replayer::status_t vogl_gl_replayer::process_gl_entrypoint_packet_intern
         case VOGL_ENTRYPOINT_glGetNamedStringivARB:
         case VOGL_ENTRYPOINT_glGetObjectBufferfvATI:
         case VOGL_ENTRYPOINT_glGetObjectBufferivATI:
-        case VOGL_ENTRYPOINT_glGetObjectLabel:
         case VOGL_ENTRYPOINT_glGetObjectParameterfvARB:
         case VOGL_ENTRYPOINT_glGetObjectParameterivAPPLE:
-        case VOGL_ENTRYPOINT_glGetObjectPtrLabel:
         case VOGL_ENTRYPOINT_glGetOcclusionQueryivNV:
         case VOGL_ENTRYPOINT_glGetOcclusionQueryuivNV:
         case VOGL_ENTRYPOINT_glGetPathColorGenfvNV: