15bd8deadSopenharmony_ciName
25bd8deadSopenharmony_ci
35bd8deadSopenharmony_ci    AMD_performance_monitor
45bd8deadSopenharmony_ci    
55bd8deadSopenharmony_ciName Strings
65bd8deadSopenharmony_ci
75bd8deadSopenharmony_ci    GL_AMD_performance_monitor
85bd8deadSopenharmony_ci    
95bd8deadSopenharmony_ciContributors
105bd8deadSopenharmony_ci
115bd8deadSopenharmony_ci    Dan Ginsburg
125bd8deadSopenharmony_ci    Aaftab Munshi
135bd8deadSopenharmony_ci    Dave Oldcorn
145bd8deadSopenharmony_ci    Maurice Ribble
155bd8deadSopenharmony_ci    Jonathan Zarge
165bd8deadSopenharmony_ci
175bd8deadSopenharmony_ciContact
185bd8deadSopenharmony_ci
195bd8deadSopenharmony_ci    Dan Ginsburg (dan.ginsburg 'at' amd.com)
205bd8deadSopenharmony_ci
215bd8deadSopenharmony_ciStatus
225bd8deadSopenharmony_ci
235bd8deadSopenharmony_ci    ???
245bd8deadSopenharmony_ci
255bd8deadSopenharmony_ciVersion
265bd8deadSopenharmony_ci
275bd8deadSopenharmony_ci    Last Modified Date: 11/29/2007
285bd8deadSopenharmony_ci
295bd8deadSopenharmony_ciNumber
305bd8deadSopenharmony_ci
315bd8deadSopenharmony_ci    OpenGL Extension #360
325bd8deadSopenharmony_ci    OpenGL ES Extension #50
335bd8deadSopenharmony_ci
345bd8deadSopenharmony_ciDependencies
355bd8deadSopenharmony_ci
365bd8deadSopenharmony_ci    None
375bd8deadSopenharmony_ci
385bd8deadSopenharmony_ciOverview
395bd8deadSopenharmony_ci
405bd8deadSopenharmony_ci    This extension enables the capture and reporting of performance monitors.
415bd8deadSopenharmony_ci    Performance monitors contain groups of counters which hold arbitrary counted 
425bd8deadSopenharmony_ci    data.  Typically, the counters hold information on performance-related
435bd8deadSopenharmony_ci    counters in the underlying hardware.  The extension is general enough to
445bd8deadSopenharmony_ci    allow the implementation to choose which counters to expose and pick the
455bd8deadSopenharmony_ci    data type and range of the counters.  The extension also allows counting to 
465bd8deadSopenharmony_ci    start and end on arbitrary boundaries during rendering.
475bd8deadSopenharmony_ci
485bd8deadSopenharmony_ciIssues
495bd8deadSopenharmony_ci
505bd8deadSopenharmony_ci    1.  Should this be an EGL or OpenGL/OpenGL ES extension?
515bd8deadSopenharmony_ci
525bd8deadSopenharmony_ci        Decision - Make this an OpenGL/OpenGL ES extension
535bd8deadSopenharmony_ci        
545bd8deadSopenharmony_ci        Reason - We would like to expose this extension in both OpenGL and 
555bd8deadSopenharmony_ci        OpenGL ES which makes EGL an unsuitable choice.  Further, support for 
565bd8deadSopenharmony_ci        EGL is not a requirement and there are platforms that support OpenGL ES 
575bd8deadSopenharmony_ci        but not EGL, making it difficult to make this an EGL extension.
585bd8deadSopenharmony_ci        
595bd8deadSopenharmony_ci    2.  Should the API support multipassing?
605bd8deadSopenharmony_ci    
615bd8deadSopenharmony_ci        Decision - No.
625bd8deadSopenharmony_ci        
635bd8deadSopenharmony_ci        Reason - Multipassing should really be left to the application to do.  
645bd8deadSopenharmony_ci        This makes the API unnecessarily complicated.  A major issue is that 
655bd8deadSopenharmony_ci        depending on which counters are to be sampled, the # of passes and which 
665bd8deadSopenharmony_ci        counters get selected in each pass can be difficult to determine.  It is 
675bd8deadSopenharmony_ci        much easier to give a list of counters categorized by groups with 
685bd8deadSopenharmony_ci        specific information on the number of counters that can be selected from 
695bd8deadSopenharmony_ci        each group.
705bd8deadSopenharmony_ci
715bd8deadSopenharmony_ci    3.  Should we define a 64-bit data type for UNSIGNED_INT64_AMD?
725bd8deadSopenharmony_ci
735bd8deadSopenharmony_ci        Decision - No.
745bd8deadSopenharmony_ci
755bd8deadSopenharmony_ci        Reason - While counters can be returned as 64-bit unsigned integers, the
765bd8deadSopenharmony_ci        data is passed back to the application inside of a void*.  Therefore,
775bd8deadSopenharmony_ci        there is no need in this extension to define a 64-bit data type (e.g.,
785bd8deadSopenharmony_ci        GLuint64).  It will be up the application to declare a native 64-bit
795bd8deadSopenharmony_ci        unsigned integer and cast the returned data to that type.
805bd8deadSopenharmony_ci
815bd8deadSopenharmony_ci
825bd8deadSopenharmony_ciNew Procedures and Functions
835bd8deadSopenharmony_ci
845bd8deadSopenharmony_ci    void GetPerfMonitorGroupsAMD(int *numGroups, sizei groupsSize, 
855bd8deadSopenharmony_ci                                 uint *groups)
865bd8deadSopenharmony_ci    
875bd8deadSopenharmony_ci    void GetPerfMonitorCountersAMD(uint group, int *numCounters, 
885bd8deadSopenharmony_ci                                   int *maxActiveCounters, sizei countersSize, 
895bd8deadSopenharmony_ci                                   uint *counters)
905bd8deadSopenharmony_ci
915bd8deadSopenharmony_ci    void GetPerfMonitorGroupStringAMD(uint group, sizei bufSize, sizei *length, 
925bd8deadSopenharmony_ci                                      char *groupString)
935bd8deadSopenharmony_ci
945bd8deadSopenharmony_ci    void GetPerfMonitorCounterStringAMD(uint group, uint counter, sizei bufSize,
955bd8deadSopenharmony_ci                                        sizei *length, char *counterString)
965bd8deadSopenharmony_ci 
975bd8deadSopenharmony_ci    void GetPerfMonitorCounterInfoAMD(uint group, uint counter, 
985bd8deadSopenharmony_ci                                      enum pname, void *data)
995bd8deadSopenharmony_ci    
1005bd8deadSopenharmony_ci    void GenPerfMonitorsAMD(sizei n, uint *monitors)
1015bd8deadSopenharmony_ci    
1025bd8deadSopenharmony_ci    void DeletePerfMonitorsAMD(sizei n, uint *monitors)
1035bd8deadSopenharmony_ci    
1045bd8deadSopenharmony_ci    void SelectPerfMonitorCountersAMD(uint monitor, boolean enable, 
1055bd8deadSopenharmony_ci                                      uint group, int numCounters, 
1065bd8deadSopenharmony_ci                                      uint *counterList)
1075bd8deadSopenharmony_ci
1085bd8deadSopenharmony_ci    void BeginPerfMonitorAMD(uint monitor)
1095bd8deadSopenharmony_ci        
1105bd8deadSopenharmony_ci    void EndPerfMonitorAMD(uint monitor)
1115bd8deadSopenharmony_ci
1125bd8deadSopenharmony_ci    void GetPerfMonitorCounterDataAMD(uint monitor, enum pname, sizei dataSize, 
1135bd8deadSopenharmony_ci                                      uint *data, int *bytesWritten)
1145bd8deadSopenharmony_ci
1155bd8deadSopenharmony_ci
1165bd8deadSopenharmony_ciNew Tokens
1175bd8deadSopenharmony_ci
1185bd8deadSopenharmony_ci    Accepted by the <pame> parameter of GetPerfMonitorCounterInfoAMD
1195bd8deadSopenharmony_ci    
1205bd8deadSopenharmony_ci        COUNTER_TYPE_AMD                           0x8BC0
1215bd8deadSopenharmony_ci        COUNTER_RANGE_AMD                          0x8BC1
1225bd8deadSopenharmony_ci        
1235bd8deadSopenharmony_ci    Returned as a valid value in <data> parameter of
1245bd8deadSopenharmony_ci    GetPerfMonitorCounterInfoAMD if <pname> = COUNTER_TYPE_AMD
1255bd8deadSopenharmony_ci        
1265bd8deadSopenharmony_ci        UNSIGNED_INT                               0x1405
1275bd8deadSopenharmony_ci        FLOAT                                      0x1406
1285bd8deadSopenharmony_ci        UNSIGNED_INT64_AMD                         0x8BC2
1295bd8deadSopenharmony_ci        PERCENTAGE_AMD                             0x8BC3
1305bd8deadSopenharmony_ci        
1315bd8deadSopenharmony_ci    Accepted by the <pname> parameter of GetPerfMonitorCounterDataAMD
1325bd8deadSopenharmony_ci        
1335bd8deadSopenharmony_ci        PERFMON_RESULT_AVAILABLE_AMD               0x8BC4
1345bd8deadSopenharmony_ci        PERFMON_RESULT_SIZE_AMD                    0x8BC5
1355bd8deadSopenharmony_ci        PERFMON_RESULT_AMD                         0x8BC6
1365bd8deadSopenharmony_ci
1375bd8deadSopenharmony_ciAddition to the GL specification
1385bd8deadSopenharmony_ci
1395bd8deadSopenharmony_ci    Add a new section called Performance Monitoring
1405bd8deadSopenharmony_ci    
1415bd8deadSopenharmony_ci    A performance monitor consists of a number of hardware and software counters
1425bd8deadSopenharmony_ci    that can be sampled by the GPU and reported back to the application.
1435bd8deadSopenharmony_ci    Performance counters are organized as a single hierarchy where counters are
1445bd8deadSopenharmony_ci    categorized into groups.  Each group has a list of counters that belong to
1455bd8deadSopenharmony_ci    the counter and can be sampled, and a maximum number of counters that can be 
1465bd8deadSopenharmony_ci    sampled.
1475bd8deadSopenharmony_ci    
1485bd8deadSopenharmony_ci    The command
1495bd8deadSopenharmony_ci    
1505bd8deadSopenharmony_ci        void GetPerfMonitorGroupsAMD(int *numGroups, sizei groupsSize, 
1515bd8deadSopenharmony_ci                                     uint *groups);
1525bd8deadSopenharmony_ci        
1535bd8deadSopenharmony_ci    returns the number of available groups in <numGroups>, if <numGroups> is
1545bd8deadSopenharmony_ci    not NULL.  If <groupsSize> is not 0 and <groups> is not NULL, then the list 
1555bd8deadSopenharmony_ci    of available groups is returned.  The number of entries that will be 
1565bd8deadSopenharmony_ci    returned in <groups> is determined by <groupsSize>.  If <groupsSize> is 0, 
1575bd8deadSopenharmony_ci    no information is copied.  Each group is identified by a unique unsigned int 
1585bd8deadSopenharmony_ci    identifier.
1595bd8deadSopenharmony_ci    
1605bd8deadSopenharmony_ci    The command
1615bd8deadSopenharmony_ci    
1625bd8deadSopenharmony_ci        void GetPerfMonitorCountersAMD(uint group, int *numCounters, 
1635bd8deadSopenharmony_ci                                       int *maxActiveCounters, 
1645bd8deadSopenharmony_ci                                       sizei countersSize, 
1655bd8deadSopenharmony_ci                                       uint *counters);
1665bd8deadSopenharmony_ci        
1675bd8deadSopenharmony_ci    returns the following information.  For each group, it returns the number of 
1685bd8deadSopenharmony_ci    available counters in <numCounters>, the max number of counters that can be
1695bd8deadSopenharmony_ci    active at any time in <maxActiveCounters>, and the list of counters in 
1705bd8deadSopenharmony_ci    <counters>.  The number of entries that can be returned in <counters> is
1715bd8deadSopenharmony_ci    determined by <countersSize>.  If <countersSize> is 0, no information is
1725bd8deadSopenharmony_ci    copied. Each counter in a group is identified by a unique unsigned int
1735bd8deadSopenharmony_ci    identifier.  If <group> does not reference a valid group ID, an 
1745bd8deadSopenharmony_ci    INVALID_VALUE error is generated.
1755bd8deadSopenharmony_ci
1765bd8deadSopenharmony_ci    
1775bd8deadSopenharmony_ci    The command
1785bd8deadSopenharmony_ci    
1795bd8deadSopenharmony_ci        void GetPerfMonitorGroupStringAMD(uint group, sizei bufSize, 
1805bd8deadSopenharmony_ci                                          sizei *length, char *groupString)
1815bd8deadSopenharmony_ci
1825bd8deadSopenharmony_ci        
1835bd8deadSopenharmony_ci    returns the string that describes the group name identified by <group> in 
1845bd8deadSopenharmony_ci    <groupString>.  The actual number of characters written to <groupString>,
1855bd8deadSopenharmony_ci    excluding the null terminator, is returned in <length>.  If <length> is 
1865bd8deadSopenharmony_ci    NULL, then no length is returned.  The maximum number of characters that
1875bd8deadSopenharmony_ci    may be written into <groupString>, including the null terminator, is 
1885bd8deadSopenharmony_ci    specified by <bufSize>.  If <bufSize> is 0 and <groupString> is NULL, the 
1895bd8deadSopenharmony_ci    number of characters that would be required to hold the group string,
1905bd8deadSopenharmony_ci    excluding the null terminator, is returned in <length>.  If <group> 
1915bd8deadSopenharmony_ci    does not reference a valid group ID, an INVALID_VALUE error is generated.
1925bd8deadSopenharmony_ci    
1935bd8deadSopenharmony_ci    
1945bd8deadSopenharmony_ci    The command
1955bd8deadSopenharmony_ci    
1965bd8deadSopenharmony_ci        void GetPerfMonitorCounterStringAMD(uint group, uint counter, 
1975bd8deadSopenharmony_ci                                            sizei bufSize, sizei *length, 
1985bd8deadSopenharmony_ci                                            char *counterString);
1995bd8deadSopenharmony_ci
2005bd8deadSopenharmony_ci    
2015bd8deadSopenharmony_ci    returns the string that describes the counter name identified by <group> 
2025bd8deadSopenharmony_ci    and <counter> in <counterString>.  The actual number of characters written 
2035bd8deadSopenharmony_ci    to <counterString>, excluding the null terminator, is returned in <length>.  
2045bd8deadSopenharmony_ci    If <length> is NULL, then no length is returned.  The maximum number of 
2055bd8deadSopenharmony_ci    characters that may be written into <counterString>, including the null 
2065bd8deadSopenharmony_ci    terminator, is specified by <bufSize>.  If <bufSize> is 0 and 
2075bd8deadSopenharmony_ci    <counterString> is NULL, the number of characters that would be required to 
2085bd8deadSopenharmony_ci    hold the counter string, excluding the null terminator, is returned in 
2095bd8deadSopenharmony_ci    <length>.  If <group> does not reference a valid group ID, or <counter> 
2105bd8deadSopenharmony_ci    does not reference a valid counter within the group ID, an INVALID_VALUE 
2115bd8deadSopenharmony_ci    error is generated.
2125bd8deadSopenharmony_ci       
2135bd8deadSopenharmony_ci    The command
2145bd8deadSopenharmony_ci    
2155bd8deadSopenharmony_ci        void GetPerfMonitorCounterInfoAMD(uint group, uint counter, 
2165bd8deadSopenharmony_ci                                          enum pname, void *data);
2175bd8deadSopenharmony_ci        
2185bd8deadSopenharmony_ci    returns the following information about a counter.  For a <counter> 
2195bd8deadSopenharmony_ci    belonging to <group>, we can query the counter type and counter range.  If 
2205bd8deadSopenharmony_ci    <pname> is COUNTER_TYPE_AMD, then <data> returns the type.  Valid type
2215bd8deadSopenharmony_ci    values returned are UNSIGNED_INT, UNSIGNED_INT64_AMD, PERCENTAGE_AMD, FLOAT.
2225bd8deadSopenharmony_ci    If type value returned is PERCENTAGE_AMD, then this describes a float
2235bd8deadSopenharmony_ci    value that is in the range [0.0 .. 100.0].  If <pname> is COUNTER_RANGE_AMD,
2245bd8deadSopenharmony_ci    <data> returns two values representing a minimum and a maximum. The 
2255bd8deadSopenharmony_ci    counter's type is used to determine the format in which the range values 
2265bd8deadSopenharmony_ci    are returned.  If <group> does not reference a valid group ID, or <counter> 
2275bd8deadSopenharmony_ci    does not reference a valid counter within the group ID, an INVALID_VALUE 
2285bd8deadSopenharmony_ci    error is generated.
2295bd8deadSopenharmony_ci
2305bd8deadSopenharmony_ci    
2315bd8deadSopenharmony_ci    The command
2325bd8deadSopenharmony_ci    
2335bd8deadSopenharmony_ci        void GenPerfMonitorsAMD(sizei n, uint *monitors)
2345bd8deadSopenharmony_ci        
2355bd8deadSopenharmony_ci    returns a list of monitors.  These monitors can then be used to select 
2365bd8deadSopenharmony_ci    groups/counters to be sampled, to start multiple monitoring sessions and to 
2375bd8deadSopenharmony_ci    return counter information sampled by the GPU.  At creation time, the 
2385bd8deadSopenharmony_ci    performance monitor object has all counters disabled.  The value of the
2395bd8deadSopenharmony_ci    PERFMON_RESULT_AVAILABLE_AMD, PERFMON_RESULT_AMD, and 
2405bd8deadSopenharmony_ci    PERFMON_RESULT_SIZE_AMD queries will all initially be 0.
2415bd8deadSopenharmony_ci    
2425bd8deadSopenharmony_ci    The command
2435bd8deadSopenharmony_ci    
2445bd8deadSopenharmony_ci        void DeletePerfMonitorsAMD(sizei n, uint *monitors)
2455bd8deadSopenharmony_ci        
2465bd8deadSopenharmony_ci    is used to delete the list of monitors created by a previous call to 
2475bd8deadSopenharmony_ci    GenPerfMonitors.  If a monitor ID in the list <monitors> does not 
2485bd8deadSopenharmony_ci    reference a previously generated performance monitor, an INVALID_VALUE
2495bd8deadSopenharmony_ci    error is generated.
2505bd8deadSopenharmony_ci    
2515bd8deadSopenharmony_ci    The command 
2525bd8deadSopenharmony_ci    
2535bd8deadSopenharmony_ci        void SelectPerfMonitorCountersAMD(uint monitor, boolean enable, 
2545bd8deadSopenharmony_ci                                          uint group, int numCounters, 
2555bd8deadSopenharmony_ci                                          uint *counterList);
2565bd8deadSopenharmony_ci        
2575bd8deadSopenharmony_ci    is used to enable or disable a list of counters from a group to be monitored 
2585bd8deadSopenharmony_ci    as identified by <monitor>.  The <enable> argument determines whether the
2595bd8deadSopenharmony_ci    counters should be enabled or disabled.  <group> specifies the group
2605bd8deadSopenharmony_ci    ID under which counters will be enabled or disabled.  The <numCounters>
2615bd8deadSopenharmony_ci    argument gives the number of counters to be selected from the list 
2625bd8deadSopenharmony_ci    <counterList>.  If <monitor> is not a valid monitor created by 
2635bd8deadSopenharmony_ci    GenPerfMonitorsAMD, then INVALID_VALUE error will be generated.  If <group>
2645bd8deadSopenharmony_ci    is not a valid group, the INVALID_VALUE error will be generated.  If 
2655bd8deadSopenharmony_ci    <numCounters> is less than 0, an INVALID_VALUE error will be generated. 
2665bd8deadSopenharmony_ci
2675bd8deadSopenharmony_ci    When SelectPerfMonitorCountersAMD is called on a monitor, any outstanding 
2685bd8deadSopenharmony_ci    results for that monitor become invalidated and the result queries 
2695bd8deadSopenharmony_ci    PERFMON_RESULT_SIZE_AMD and PERFMON_RESULT_AVAILABLE_AMD are reset to 0.
2705bd8deadSopenharmony_ci    
2715bd8deadSopenharmony_ci    The command
2725bd8deadSopenharmony_ci    
2735bd8deadSopenharmony_ci        void BeginPerfMonitorAMD(uint monitor);
2745bd8deadSopenharmony_ci        
2755bd8deadSopenharmony_ci    is used to start a monitor session.  Note that BeginPerfMonitor calls cannot 
2765bd8deadSopenharmony_ci    be nested.  In addition, it is quite possible that given the list of groups 
2775bd8deadSopenharmony_ci    and counters/group enabled for a monitor, it may not be able to sample the 
2785bd8deadSopenharmony_ci    necessary counters and so the monitor session will fail.  In such a case,
2795bd8deadSopenharmony_ci    an INVALID_OPERATION error will be generated.
2805bd8deadSopenharmony_ci
2815bd8deadSopenharmony_ci    While BeginPerfMonitorAMD does mark the beginning of performance counter
2825bd8deadSopenharmony_ci    collection, the counters do not begin collecting immediately.  Rather, the
2835bd8deadSopenharmony_ci    counters begin collection when BeginPerfMonitorAMD is processed by
2845bd8deadSopenharmony_ci    the hardware.  That is, the API is asynchronous, and performance counter
2855bd8deadSopenharmony_ci    collection does not begin until the graphics hardware processes the
2865bd8deadSopenharmony_ci    BeginPerfMonitorAMD command.  
2875bd8deadSopenharmony_ci    
2885bd8deadSopenharmony_ci    The command
2895bd8deadSopenharmony_ci    
2905bd8deadSopenharmony_ci        void EndPerfMonitorAMD(uint monitor);
2915bd8deadSopenharmony_ci        
2925bd8deadSopenharmony_ci    ends a monitor session started by BeginPerfMonitorAMD.  If a performance 
2935bd8deadSopenharmony_ci    monitor is not currently started, an INVALID_OPERATION error will be 
2945bd8deadSopenharmony_ci    generated.
2955bd8deadSopenharmony_ci    
2965bd8deadSopenharmony_ci    Note that there is an implied overhead to collecting performance counters
2975bd8deadSopenharmony_ci    that may or may not distort performance depending on the implementation.  
2985bd8deadSopenharmony_ci    For example, some counters may require a pipeline flush thereby causing a
2995bd8deadSopenharmony_ci    change in the performance of the application.  Further, the frequency at 
3005bd8deadSopenharmony_ci    which an application samples may distort the accuracy of counters which are 
3015bd8deadSopenharmony_ci    variant (e.g., non-deterministic based on the input).  While the effects 
3025bd8deadSopenharmony_ci    of sampling frequency are implementation dependent, general guidance can
3035bd8deadSopenharmony_ci    be given that sampling at a high frequency may distort both performance
3045bd8deadSopenharmony_ci    of the application and the accuracy of variant counters.
3055bd8deadSopenharmony_ci
3065bd8deadSopenharmony_ci    The command
3075bd8deadSopenharmony_ci    
3085bd8deadSopenharmony_ci        void GetPerfMonitorCounterDataAMD(uint monitor, enum pname, 
3095bd8deadSopenharmony_ci                                          sizei dataSize, 
3105bd8deadSopenharmony_ci                                          uint *data, sizei *bytesWritten);
3115bd8deadSopenharmony_ci        
3125bd8deadSopenharmony_ci    is used to return counter values that have been sampled for a monitor
3135bd8deadSopenharmony_ci    session.  If <pname> is PERFMON_RESULT_AVAILABLE_AMD, then <data> will
3145bd8deadSopenharmony_ci    indicate whether the result is available or not.  If <pname> is 
3155bd8deadSopenharmony_ci    PERFMON_RESULT_SIZE_AMD, <data> will contain actual size of all counter 
3165bd8deadSopenharmony_ci    results being sampled.  If <pname> is PERFMON_RESULT_AMD, <data> will
3175bd8deadSopenharmony_ci    contain results.  For each counter of a group that was selected to be 
3185bd8deadSopenharmony_ci    sampled, the information is returned as group ID, followed by counter ID, 
3195bd8deadSopenharmony_ci    followed by counter value.  The size of counter value returned will depend 
3205bd8deadSopenharmony_ci    on the counter value type.  The argument <dataSize> specifies the number of
3215bd8deadSopenharmony_ci    bytes available in the <data> buffer for writing.  If <bytesWritten> is not 
3225bd8deadSopenharmony_ci    NULL, it gives the number of bytes written into the <data> buffer.  It is an 
3235bd8deadSopenharmony_ci    INVALID_OPERATION error for <data> to be NULL.  If <pname> is 
3245bd8deadSopenharmony_ci    PERFMON_RESULT_AMD and <dataSize> is less than the number of bytes required 
3255bd8deadSopenharmony_ci    to store the results as reported by a PERFMON_RESULT_SIZE_AMD query, then 
3265bd8deadSopenharmony_ci    results will be written only up to the number of bytes specified by 
3275bd8deadSopenharmony_ci    <dataSize>.
3285bd8deadSopenharmony_ci
3295bd8deadSopenharmony_ci    If no BeginPerfMonitorAMD/EndPerfMonitorAMD has been issued for a monitor,
3305bd8deadSopenharmony_ci    then the result of querying for PERFMON_RESULT_AVAILABLE and 
3315bd8deadSopenharmony_ci    PERFMON_RESULT_SIZE will be 0.  When SelectPerfMonitorCountersAMD is called
3325bd8deadSopenharmony_ci    on a monitor, the results stored for the monitor become invalidated and
3335bd8deadSopenharmony_ci    the value of PERFMON_RESULT_AVAILABLE and PERFMON_RESULT_SIZE queries should
3345bd8deadSopenharmony_ci    behave as if no BeginPerfMonitorAMD/EndPerfMonitorAMD has been issued for
3355bd8deadSopenharmony_ci    the monitor.
3365bd8deadSopenharmony_ci
3375bd8deadSopenharmony_ciErrors
3385bd8deadSopenharmony_ci
3395bd8deadSopenharmony_ci    INVALID_OPERATION error will be generated if BeginPerfMonitorAMD is unable
3405bd8deadSopenharmony_ci    to begin monitoring with the currently selected counters.  
3415bd8deadSopenharmony_ci
3425bd8deadSopenharmony_ci    INVALID_OPERATION error will be generated if BeginPerfMonitorAMD is called
3435bd8deadSopenharmony_ci    when a performance monitor is already active.
3445bd8deadSopenharmony_ci
3455bd8deadSopenharmony_ci    INVALID_OPERATION error will be generated if EndPerfMonitorAMD is called
3465bd8deadSopenharmony_ci    when a performance monitor is not currently started.
3475bd8deadSopenharmony_ci
3485bd8deadSopenharmony_ci    INVALID_VALUE error will be generated if the <group> parameter to 
3495bd8deadSopenharmony_ci    GetPerfMonitorCountersAMD, GetPerfMonitorCounterStringAMD,
3505bd8deadSopenharmony_ci    GetPerfMonitorCounterStringAMD, GetPerfMonitorCounterInfoAMD, or
3515bd8deadSopenharmony_ci    SelectPerfMonitorCountersAMD does not reference a valid group ID.
3525bd8deadSopenharmony_ci
3535bd8deadSopenharmony_ci    INVALID_VALUE error will be generated if the <counter> parameter to
3545bd8deadSopenharmony_ci    GetPerfMonitorCounterInfoAMD does not reference a valid counter ID
3555bd8deadSopenharmony_ci    in the group specified by <group>.
3565bd8deadSopenharmony_ci
3575bd8deadSopenharmony_ci    INVALID_VALUE error will be generated if any of the monitor IDs
3585bd8deadSopenharmony_ci    in the <monitors> parameter to DeletePerfMonitorsAMD do not reference
3595bd8deadSopenharmony_ci    a valid generated monitor ID.
3605bd8deadSopenharmony_ci   
3615bd8deadSopenharmony_ci    INVALID_VALUE error will be generated if the <monitor> parameter to
3625bd8deadSopenharmony_ci    SelectPerfMonitorCountersAMD does not reference a monitor created by
3635bd8deadSopenharmony_ci    GenPerfMonitorsAMD.
3645bd8deadSopenharmony_ci
3655bd8deadSopenharmony_ci    INVALID_VALUE error will be generated if the <numCounters> parameter to
3665bd8deadSopenharmony_ci    SelectPerfMonitorCountersAMD is less than 0.
3675bd8deadSopenharmony_ci
3685bd8deadSopenharmony_ci     
3695bd8deadSopenharmony_ci
3705bd8deadSopenharmony_ciNew State
3715bd8deadSopenharmony_ci
3725bd8deadSopenharmony_ciSample Usage
3735bd8deadSopenharmony_ci
3745bd8deadSopenharmony_ci    typedef struct 
3755bd8deadSopenharmony_ci    {
3765bd8deadSopenharmony_ci            GLuint       *counterList;
3775bd8deadSopenharmony_ci            int         numCounters;
3785bd8deadSopenharmony_ci            int         maxActiveCounters;
3795bd8deadSopenharmony_ci    } CounterInfo;
3805bd8deadSopenharmony_ci
3815bd8deadSopenharmony_ci    void
3825bd8deadSopenharmony_ci    getGroupAndCounterList(GLuint **groupsList, int *numGroups, 
3835bd8deadSopenharmony_ci                           CounterInfo **counterInfo)
3845bd8deadSopenharmony_ci    {
3855bd8deadSopenharmony_ci        GLint          n;
3865bd8deadSopenharmony_ci        GLuint        *groups;
3875bd8deadSopenharmony_ci        CounterInfo   *counters;
3885bd8deadSopenharmony_ci
3895bd8deadSopenharmony_ci        glGetPerfMonitorGroupsAMD(&n, 0, NULL);
3905bd8deadSopenharmony_ci        groups = (GLuint*) malloc(n * sizeof(GLuint));
3915bd8deadSopenharmony_ci        glGetPerfMonitorGroupsAMD(NULL, n, groups);
3925bd8deadSopenharmony_ci        *numGroups = n;
3935bd8deadSopenharmony_ci
3945bd8deadSopenharmony_ci        *groupsList = groups;
3955bd8deadSopenharmony_ci        counters = (CounterInfo*) malloc(sizeof(CounterInfo) * n);
3965bd8deadSopenharmony_ci        for (int i = 0 ; i < n; i++ )
3975bd8deadSopenharmony_ci        {
3985bd8deadSopenharmony_ci            glGetPerfMonitorCountersAMD(groups[i], &counters[i].numCounters,
3995bd8deadSopenharmony_ci                                     &counters[i].maxActiveCounters, 0, NULL);
4005bd8deadSopenharmony_ci
4015bd8deadSopenharmony_ci            counters[i].counterList = (GLuint*)malloc(counters[i].numCounters * 
4025bd8deadSopenharmony_ci                                                      sizeof(int));
4035bd8deadSopenharmony_ci
4045bd8deadSopenharmony_ci            glGetPerfMonitorCountersAMD(groups[i], NULL, NULL,
4055bd8deadSopenharmony_ci                                        counters[i].numCounters, 
4065bd8deadSopenharmony_ci                                        counters[i].counterList);
4075bd8deadSopenharmony_ci        }
4085bd8deadSopenharmony_ci
4095bd8deadSopenharmony_ci        *counterInfo = counters;
4105bd8deadSopenharmony_ci    }
4115bd8deadSopenharmony_ci    
4125bd8deadSopenharmony_ci    static int  countersInitialized = 0;
4135bd8deadSopenharmony_ci        
4145bd8deadSopenharmony_ci    int
4155bd8deadSopenharmony_ci    getCounterByName(char *groupName, char *counterName, GLuint *groupID, 
4165bd8deadSopenharmony_ci                     GLuint *counterID)
4175bd8deadSopenharmony_ci    {
4185bd8deadSopenharmony_ci        int          numGroups;
4195bd8deadSopenharmony_ci        GLuint       *groups;
4205bd8deadSopenharmony_ci        CounterInfo  *counters;
4215bd8deadSopenharmony_ci        int          i = 0;
4225bd8deadSopenharmony_ci
4235bd8deadSopenharmony_ci        if (!countersInitialized)
4245bd8deadSopenharmony_ci        {
4255bd8deadSopenharmony_ci            getGroupAndCounterList(&groups, &numGroups, &counters);
4265bd8deadSopenharmony_ci            countersInitialized = 1;
4275bd8deadSopenharmony_ci        }
4285bd8deadSopenharmony_ci
4295bd8deadSopenharmony_ci        for ( i = 0; i < numGroups; i++ )
4305bd8deadSopenharmony_ci        {
4315bd8deadSopenharmony_ci           char curGroupName[256];
4325bd8deadSopenharmony_ci           glGetPerfMonitorGroupStringAMD(groups[i], 256, NULL, curGroupName);
4335bd8deadSopenharmony_ci           if (strcmp(groupName, curGroupName) == 0)
4345bd8deadSopenharmony_ci           {
4355bd8deadSopenharmony_ci               *groupID = groups[i];
4365bd8deadSopenharmony_ci               break;
4375bd8deadSopenharmony_ci           }
4385bd8deadSopenharmony_ci        }
4395bd8deadSopenharmony_ci
4405bd8deadSopenharmony_ci        if ( i == numGroups )
4415bd8deadSopenharmony_ci            return -1;           // error - could not find the group name
4425bd8deadSopenharmony_ci
4435bd8deadSopenharmony_ci        for ( int j = 0; j < counters[i].numCounters; j++ )
4445bd8deadSopenharmony_ci        {
4455bd8deadSopenharmony_ci            char curCounterName[256];
4465bd8deadSopenharmony_ci            
4475bd8deadSopenharmony_ci            glGetPerfMonitorCounterStringAMD(groups[i],
4485bd8deadSopenharmony_ci                                             counters[i].counterList[j], 
4495bd8deadSopenharmony_ci                                             256, NULL, curCounterName);
4505bd8deadSopenharmony_ci            if (strcmp(counterName, curCounterName) == 0)
4515bd8deadSopenharmony_ci            {
4525bd8deadSopenharmony_ci                *counterID = counters[i].counterList[j];
4535bd8deadSopenharmony_ci                return 0;
4545bd8deadSopenharmony_ci            }
4555bd8deadSopenharmony_ci        }
4565bd8deadSopenharmony_ci
4575bd8deadSopenharmony_ci        return -1;           // error - could not find the counter name
4585bd8deadSopenharmony_ci    }
4595bd8deadSopenharmony_ci
4605bd8deadSopenharmony_ci    void
4615bd8deadSopenharmony_ci    drawFrameWithCounters(void)
4625bd8deadSopenharmony_ci    {
4635bd8deadSopenharmony_ci        GLuint group[2];
4645bd8deadSopenharmony_ci        GLuint counter[2];
4655bd8deadSopenharmony_ci        GLuint monitor;
4665bd8deadSopenharmony_ci        GLuint *counterData;
4675bd8deadSopenharmony_ci
4685bd8deadSopenharmony_ci        // Get group/counter IDs by name.  Note that normally the
4695bd8deadSopenharmony_ci        // counter and group names need to be queried for because
4705bd8deadSopenharmony_ci        // each implementation of this extension on different hardware
4715bd8deadSopenharmony_ci        // could define different names and groups.  This is just provided
4725bd8deadSopenharmony_ci        // to demonstrate the API.
4735bd8deadSopenharmony_ci        getCounterByName("HW", "Hardware Busy", &group[0],
4745bd8deadSopenharmony_ci                         &counter[0]);
4755bd8deadSopenharmony_ci        getCounterByName("API", "Draw Calls", &group[1], 
4765bd8deadSopenharmony_ci                         &counter[1]);
4775bd8deadSopenharmony_ci                
4785bd8deadSopenharmony_ci        // create perf monitor ID
4795bd8deadSopenharmony_ci        glGenPerfMonitorsAMD(1, &monitor);
4805bd8deadSopenharmony_ci
4815bd8deadSopenharmony_ci        // enable the counters
4825bd8deadSopenharmony_ci        glSelectPerfMonitorCountersAMD(monitor, GL_TRUE, group[0], 1,
4835bd8deadSopenharmony_ci                                       &counter[0]);
4845bd8deadSopenharmony_ci        glSelectPerfMonitorCountersAMD(monitor, GL_TRUE, group[1], 1, 
4855bd8deadSopenharmony_ci                                       &counter[1]);
4865bd8deadSopenharmony_ci
4875bd8deadSopenharmony_ci        glBeginPerfMonitorAMD(monitor);
4885bd8deadSopenharmony_ci
4895bd8deadSopenharmony_ci        // RENDER FRAME HERE
4905bd8deadSopenharmony_ci        // ...
4915bd8deadSopenharmony_ci        
4925bd8deadSopenharmony_ci        glEndPerfMonitorAMD(monitor);
4935bd8deadSopenharmony_ci
4945bd8deadSopenharmony_ci        // read the counters
4955bd8deadSopenharmony_ci        GLint resultSize;
4965bd8deadSopenharmony_ci        glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_SIZE_AMD, 
4975bd8deadSopenharmony_ci                                       sizeof(GLint), &resultSize, NULL);
4985bd8deadSopenharmony_ci
4995bd8deadSopenharmony_ci        counterData = (GLuint*) malloc(resultSize);
5005bd8deadSopenharmony_ci
5015bd8deadSopenharmony_ci        GLsizei bytesWritten;
5025bd8deadSopenharmony_ci        glGetPerfMonitorCounterDataAMD(monitor, GL_PERFMON_RESULT_AMD,  
5035bd8deadSopenharmony_ci                                       resultSize, counterData, &bytesWritten);
5045bd8deadSopenharmony_ci
5055bd8deadSopenharmony_ci        // display or log counter info
5065bd8deadSopenharmony_ci        GLsizei wordCount = 0;
5075bd8deadSopenharmony_ci
5085bd8deadSopenharmony_ci        while ( (4 * wordCount) < bytesWritten )
5095bd8deadSopenharmony_ci        {
5105bd8deadSopenharmony_ci            GLuint groupId = counterData[wordCount];
5115bd8deadSopenharmony_ci            GLuint counterId = counterData[wordCount + 1];
5125bd8deadSopenharmony_ci
5135bd8deadSopenharmony_ci            // Determine the counter type
5145bd8deadSopenharmony_ci            GLuint counterType;
5155bd8deadSopenharmony_ci            glGetPerfMonitorCounterInfoAMD(groupId, counterId, 
5165bd8deadSopenharmony_ci                                           GL_COUNTER_TYPE_AMD, &counterType);
5175bd8deadSopenharmony_ci 
5185bd8deadSopenharmony_ci            if ( counterType == GL_UNSIGNED_INT64_AMD )
5195bd8deadSopenharmony_ci            {
5205bd8deadSopenharmony_ci                unsigned __int64 counterResult = 
5215bd8deadSopenharmony_ci                           *(unsigned __int64*)(&counterData[wordCount + 2]);
5225bd8deadSopenharmony_ci
5235bd8deadSopenharmony_ci                // Print counter result
5245bd8deadSopenharmony_ci
5255bd8deadSopenharmony_ci                wordCount += 4;
5265bd8deadSopenharmony_ci            }
5275bd8deadSopenharmony_ci            else if ( counterType == GL_FLOAT )
5285bd8deadSopenharmony_ci            {
5295bd8deadSopenharmony_ci                float counterResult = *(float*)(&counterData[wordCount + 2]);
5305bd8deadSopenharmony_ci
5315bd8deadSopenharmony_ci                // Print counter result
5325bd8deadSopenharmony_ci
5335bd8deadSopenharmony_ci                wordCount += 3;
5345bd8deadSopenharmony_ci            } 
5355bd8deadSopenharmony_ci            // else if ( ... ) check for other counter types 
5365bd8deadSopenharmony_ci            //   (GL_UNSIGNED_INT and GL_PERCENTAGE_AMD)
5375bd8deadSopenharmony_ci        }
5385bd8deadSopenharmony_ci    }
5395bd8deadSopenharmony_ci 
5405bd8deadSopenharmony_ciRevision History
5415bd8deadSopenharmony_ci    11/29/2007 - dginsburg
5425bd8deadSopenharmony_ci       + Clarified the default state of a performance monitor object on creation
5435bd8deadSopenharmony_ci
5445bd8deadSopenharmony_ci    11/09/2007 - dginsbur
5455bd8deadSopenharmony_ci       + Clarify what happens if SelectPerfMonitorCountersAMD is called on
5465bd8deadSopenharmony_ci         a monitor with outstanding query results.
5475bd8deadSopenharmony_ci       + Rename counterSize to countersSize
5485bd8deadSopenharmony_ci       + Remove some ';' typos
5495bd8deadSopenharmony_ci
5505bd8deadSopenharmony_ci    06/13/2007 - dginsbur
5515bd8deadSopenharmony_ci       + Add language on the asynchronous nature of the API and 
5525bd8deadSopenharmony_ci         counter accuracy/performance distortion.
5535bd8deadSopenharmony_ci       + Add myself as the contact
5545bd8deadSopenharmony_ci       + Remove INVALID_OPERATION error when countersList is NULL
5555bd8deadSopenharmony_ci       + Clarify 64-bit issue
5565bd8deadSopenharmony_ci       + Make PERCENTAGE_AMD counters float rather than uint
5575bd8deadSopenharmony_ci       + Clarify accuracy distortion on variant counters only
5585bd8deadSopenharmony_ci       + Tweak to overview language
5595bd8deadSopenharmony_ci
5605bd8deadSopenharmony_ci    06/09/2007 - dginsbur
5615bd8deadSopenharmony_ci       + Fill in errors section and make many more errors explicit
5625bd8deadSopenharmony_ci       + Fix the example code so it compiles
5635bd8deadSopenharmony_ci
5645bd8deadSopenharmony_ci    06/08/2007 - dginsbur
5655bd8deadSopenharmony_ci       + Modified GetPerfMonitorGroupString and GetPerfMonitorCounterString to
5665bd8deadSopenharmony_ci         be more client/server friendly.  
5675bd8deadSopenharmony_ci       + Modified example.
5685bd8deadSopenharmony_ci       + Renamed parameters/variables to follow GL conventions.
5695bd8deadSopenharmony_ci       + Modified several 'int' param types to 'sizei'
5705bd8deadSopenharmony_ci       + Modifid counters type from 'int' to 'uint'
5715bd8deadSopenharmony_ci       + Renamed argument 'cb' and 'cbret'
5725bd8deadSopenharmony_ci       + Better documented GetPerfMonitorCounterData 
5735bd8deadSopenharmony_ci       + Add AMD adornment in many places that were missing it
5745bd8deadSopenharmony_ci 
5755bd8deadSopenharmony_ci    06/07/2007 - dginsbur
5765bd8deadSopenharmony_ci       + Cleanup formatting, remove tabs, make fit in proper page width
5775bd8deadSopenharmony_ci       + Add FLOAT and UNSIGNED_INT to list of COUNTER_TYPEs
5785bd8deadSopenharmony_ci       + Fix some bugs in the example code
5795bd8deadSopenharmony_ci       + Rewrite introduction
5805bd8deadSopenharmony_ci       + Clarified Issue 1 reasoning
5815bd8deadSopenharmony_ci       + Added Issue 3 regarding use of 64-bit data types
5825bd8deadSopenharmony_ci       + Added revision history
5835bd8deadSopenharmony_ci
5845bd8deadSopenharmony_ci    03/21/2007 - Initial version written.  Written by amunshi.
5855bd8deadSopenharmony_ci
5865bd8deadSopenharmony_ci        
587