~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/frontends/d3d10umd/Query.cpp

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
 *
3
 
 * Copyright 2012-2021 VMware, Inc.
4
 
 * All Rights Reserved.
5
 
 *
6
 
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 
 * copy of this software and associated documentation files (the
8
 
 * "Software"), to deal in the Software without restriction, including
9
 
 * without limitation the rights to use, copy, modify, merge, publish,
10
 
 * distribute, sub license, and/or sell copies of the Software, and to
11
 
 * permit persons to whom the Software is furnished to do so, subject to
12
 
 * the following conditions:
13
 
 *
14
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17
 
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18
 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
 
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
 
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21
 
 *
22
 
 * The above copyright notice and this permission notice (including the
23
 
 * next paragraph) shall be included in all copies or substantial portions
24
 
 * of the Software.
25
 
 *
26
 
 **************************************************************************/
27
 
 
28
 
/*
29
 
 * Query.cpp --
30
 
 *    Functions that manipulate query resources.
31
 
 */
32
 
 
33
 
 
34
 
#include "Query.h"
35
 
#include "State.h"
36
 
 
37
 
#include "Debug.h"
38
 
 
39
 
 
40
 
/*
41
 
 * ----------------------------------------------------------------------
42
 
 *
43
 
 * CalcPrivateQuerySize --
44
 
 *
45
 
 *    The CalcPrivateQuerySize function determines the size of the
46
 
 *    user-mode display driver's private region of memory (that is,
47
 
 *    the size of internal driver structures, not the size of the
48
 
 *    resource video memory) for a query.
49
 
 *
50
 
 * ----------------------------------------------------------------------
51
 
 */
52
 
 
53
 
SIZE_T APIENTRY
54
 
CalcPrivateQuerySize(D3D10DDI_HDEVICE hDevice,                          // IN
55
 
                     __in const D3D10DDIARG_CREATEQUERY *pCreateQuery)  // IN
56
 
{
57
 
   return sizeof(Query);
58
 
}
59
 
 
60
 
 
61
 
static uint
62
 
TranslateQueryType(D3D10DDI_QUERY query)
63
 
{
64
 
   switch (query) {
65
 
   case D3D10DDI_QUERY_EVENT:
66
 
      return PIPE_QUERY_GPU_FINISHED;
67
 
   case D3D10DDI_QUERY_OCCLUSION:
68
 
      return PIPE_QUERY_OCCLUSION_COUNTER;
69
 
   case D3D10DDI_QUERY_TIMESTAMP:
70
 
      return PIPE_QUERY_TIMESTAMP;
71
 
   case D3D10DDI_QUERY_TIMESTAMPDISJOINT:
72
 
      return PIPE_QUERY_TIMESTAMP_DISJOINT;
73
 
   case D3D10DDI_QUERY_PIPELINESTATS:
74
 
      return PIPE_QUERY_PIPELINE_STATISTICS;
75
 
   case D3D10DDI_QUERY_OCCLUSIONPREDICATE:
76
 
      return PIPE_QUERY_OCCLUSION_PREDICATE;
77
 
   case D3D10DDI_QUERY_STREAMOUTPUTSTATS:
78
 
      return PIPE_QUERY_SO_STATISTICS;
79
 
   case D3D10DDI_QUERY_STREAMOVERFLOWPREDICATE:
80
 
      return PIPE_QUERY_SO_OVERFLOW_PREDICATE;
81
 
   default:
82
 
      LOG_UNSUPPORTED(TRUE);
83
 
      return PIPE_QUERY_TYPES;
84
 
   }
85
 
}
86
 
 
87
 
 
88
 
/*
89
 
 * ----------------------------------------------------------------------
90
 
 *
91
 
 * CreateQuery --
92
 
 *
93
 
 *    The CreateQuery function creates driver-side resources for a
94
 
 *    query that the Microsoft Direct3D runtime subsequently issues
95
 
 *    for processing.
96
 
 *
97
 
 * ----------------------------------------------------------------------
98
 
 */
99
 
 
100
 
void APIENTRY
101
 
CreateQuery(D3D10DDI_HDEVICE hDevice,                          // IN
102
 
            __in const D3D10DDIARG_CREATEQUERY *pCreateQuery,  // IN
103
 
            D3D10DDI_HQUERY hQuery,                            // IN
104
 
            D3D10DDI_HRTQUERY hRTQuery)                        // IN
105
 
{
106
 
   LOG_ENTRYPOINT();
107
 
 
108
 
   Device *pDevice = CastDevice(hDevice);
109
 
   struct pipe_context *pipe = pDevice->pipe;
110
 
 
111
 
   Query *pQuery = CastQuery(hQuery);
112
 
   memset(pQuery, 0, sizeof *pQuery);
113
 
 
114
 
   pQuery->Type = pCreateQuery->Query;
115
 
   pQuery->Flags = pCreateQuery->MiscFlags;
116
 
 
117
 
   pQuery->pipe_type = TranslateQueryType(pCreateQuery->Query);
118
 
   if (pQuery->pipe_type < PIPE_QUERY_TYPES) {
119
 
      pQuery->handle = pipe->create_query(pipe, pQuery->pipe_type, 0);
120
 
   }
121
 
}
122
 
 
123
 
 
124
 
/*
125
 
 * ----------------------------------------------------------------------
126
 
 *
127
 
 * DestroyQuery --
128
 
 *
129
 
 *    The DestroyQuery function releases resources for a query.
130
 
 *
131
 
 * ----------------------------------------------------------------------
132
 
 */
133
 
 
134
 
void APIENTRY
135
 
DestroyQuery(D3D10DDI_HDEVICE hDevice, // IN
136
 
             D3D10DDI_HQUERY hQuery)   // IN
137
 
{
138
 
   LOG_ENTRYPOINT();
139
 
 
140
 
   struct pipe_context *pipe = CastPipeContext(hDevice);
141
 
   Query *pQuery = CastQuery(hQuery);
142
 
 
143
 
   if (pQuery->handle) {
144
 
      pipe->destroy_query(pipe, pQuery->handle);
145
 
   }
146
 
}
147
 
 
148
 
 
149
 
/*
150
 
 * ----------------------------------------------------------------------
151
 
 *
152
 
 * QueryBegin --
153
 
 *
154
 
 *    The QueryBegin function marks the beginning of a sequence of
155
 
 *    graphics commands for a query and transitions the query to the
156
 
 *    "building" state.
157
 
 *
158
 
 * ----------------------------------------------------------------------
159
 
 */
160
 
 
161
 
void APIENTRY
162
 
QueryBegin(D3D10DDI_HDEVICE hDevice,   // IN
163
 
           D3D10DDI_HQUERY hQuery)     // IN
164
 
{
165
 
   LOG_ENTRYPOINT();
166
 
 
167
 
   Device *pDevice = CastDevice(hDevice);
168
 
   struct pipe_context *pipe = pDevice->pipe;
169
 
 
170
 
   Query *pQuery = CastQuery(hQuery);
171
 
   struct pipe_query *state = CastPipeQuery(hQuery);
172
 
 
173
 
   if (state) {
174
 
      assert(pQuery->pipe_type < PIPE_QUERY_TYPES);
175
 
      pipe->begin_query(pipe, state);
176
 
   }
177
 
}
178
 
 
179
 
 
180
 
/*
181
 
 * ----------------------------------------------------------------------
182
 
 *
183
 
 * QueryEnd --
184
 
 *
185
 
 *    The QueryEnd function marks the end of a sequence of graphics
186
 
 *    commands for a query and transitions the query to the
187
 
 *    "issued" state.
188
 
 *
189
 
 * ----------------------------------------------------------------------
190
 
 */
191
 
 
192
 
void APIENTRY
193
 
QueryEnd(D3D10DDI_HDEVICE hDevice,  // IN
194
 
         D3D10DDI_HQUERY hQuery)    // IN
195
 
{
196
 
   LOG_ENTRYPOINT();
197
 
 
198
 
   Device *pDevice = CastDevice(hDevice);
199
 
   struct pipe_context *pipe = pDevice->pipe;
200
 
   Query *pQuery = CastQuery(hQuery);
201
 
   struct pipe_query *state = pQuery->handle;
202
 
 
203
 
   pQuery->SeqNo = ++pDevice->LastEmittedQuerySeqNo;
204
 
   pQuery->GetDataCount = 0;
205
 
 
206
 
   if (state) {
207
 
      pipe->end_query(pipe, state);
208
 
   }
209
 
}
210
 
 
211
 
 
212
 
/*
213
 
 * ----------------------------------------------------------------------
214
 
 *
215
 
 * QueryGetData --
216
 
 *
217
 
 *    The QueryGetData function polls for the state of a query operation.
218
 
 *
219
 
 * ----------------------------------------------------------------------
220
 
 */
221
 
 
222
 
void APIENTRY
223
 
QueryGetData(D3D10DDI_HDEVICE hDevice,                      // IN
224
 
             D3D10DDI_HQUERY hQuery,                        // IN
225
 
             __out_bcount_full_opt (DataSize) void *pData,  // OUT
226
 
             UINT DataSize,                                 // IN
227
 
             UINT Flags)                                    // IN
228
 
{
229
 
   LOG_ENTRYPOINT();
230
 
 
231
 
   Device *pDevice = CastDevice(hDevice);
232
 
   struct pipe_context *pipe = pDevice->pipe;
233
 
   Query *pQuery = CastQuery(hQuery);
234
 
   struct pipe_query *state = pQuery->handle;
235
 
 
236
 
   /*
237
 
    * Never return data for recently emitted queries immediately, to make
238
 
    * wgfasync happy.
239
 
    */
240
 
   if (DataSize == 0 &&
241
 
       (pQuery->SeqNo - pDevice->LastFinishedQuerySeqNo) > 0 &&
242
 
       (pQuery->GetDataCount++) == 0) {
243
 
      SetError(hDevice, DXGI_DDI_ERR_WASSTILLDRAWING);
244
 
      return;
245
 
   }
246
 
 
247
 
   boolean wait = !!(Flags & D3D10_DDI_GET_DATA_DO_NOT_FLUSH);
248
 
   union pipe_query_result result;
249
 
 
250
 
   memset(&result, 0, sizeof result);
251
 
 
252
 
   boolean ret;
253
 
 
254
 
   if (state) {
255
 
      ret = pipe->get_query_result(pipe, state, wait, &result);
256
 
   } else {
257
 
      LOG_UNSUPPORTED(TRUE);
258
 
      ret = TRUE;
259
 
   }
260
 
 
261
 
   if (!ret) {
262
 
      SetError(hDevice, DXGI_DDI_ERR_WASSTILLDRAWING);
263
 
      return;
264
 
   }
265
 
 
266
 
   if (pData) {
267
 
      switch (pQuery->Type) {
268
 
      case D3D10DDI_QUERY_EVENT:
269
 
      case D3D10DDI_QUERY_OCCLUSIONPREDICATE:
270
 
      case D3D10DDI_QUERY_STREAMOVERFLOWPREDICATE:
271
 
         *(BOOL *)pData = result.b;
272
 
         break;
273
 
      case D3D10DDI_QUERY_OCCLUSION:
274
 
      case D3D10DDI_QUERY_TIMESTAMP:
275
 
         *(UINT64 *)pData = result.u64;
276
 
         break;
277
 
      case D3D10DDI_QUERY_TIMESTAMPDISJOINT:
278
 
         {
279
 
            D3D10_DDI_QUERY_DATA_TIMESTAMP_DISJOINT *pResult =
280
 
              (D3D10_DDI_QUERY_DATA_TIMESTAMP_DISJOINT *)pData;
281
 
            pResult->Frequency = result.timestamp_disjoint.frequency;
282
 
            pResult->Disjoint = result.timestamp_disjoint.disjoint;
283
 
         }
284
 
         break;
285
 
      case D3D10DDI_QUERY_PIPELINESTATS:
286
 
         {
287
 
            D3D10_DDI_QUERY_DATA_PIPELINE_STATISTICS *pResult =
288
 
              (D3D10_DDI_QUERY_DATA_PIPELINE_STATISTICS *)pData;
289
 
            pResult->IAVertices = result.pipeline_statistics.ia_vertices;
290
 
            pResult->IAPrimitives = result.pipeline_statistics.ia_primitives;
291
 
            pResult->VSInvocations = result.pipeline_statistics.vs_invocations;
292
 
            pResult->GSInvocations = result.pipeline_statistics.gs_invocations;
293
 
            pResult->GSPrimitives = result.pipeline_statistics.gs_primitives;
294
 
            pResult->CInvocations = result.pipeline_statistics.c_invocations;
295
 
            pResult->CPrimitives = result.pipeline_statistics.c_primitives;
296
 
            pResult->PSInvocations = result.pipeline_statistics.ps_invocations;
297
 
            //pResult->HSInvocations = result.pipeline_statistics.hs_invocations;
298
 
            //pResult->DSInvocations = result.pipeline_statistics.ds_invocations;
299
 
            //pResult->CSInvocations = result.pipeline_statistics.cs_invocations;
300
 
         }
301
 
         break;
302
 
      case D3D10DDI_QUERY_STREAMOUTPUTSTATS:
303
 
         {
304
 
            D3D10_DDI_QUERY_DATA_SO_STATISTICS *pResult =
305
 
              (D3D10_DDI_QUERY_DATA_SO_STATISTICS *)pData;
306
 
            pResult->NumPrimitivesWritten = result.so_statistics.num_primitives_written;
307
 
            pResult->PrimitivesStorageNeeded = result.so_statistics.primitives_storage_needed;
308
 
         }
309
 
         break;
310
 
      default:
311
 
         assert(0);
312
 
         break;
313
 
      }
314
 
   }
315
 
 
316
 
   /*
317
 
    * Keep track of the last finished query, as wgfasync checks that queries
318
 
    * are completed in order.
319
 
    */
320
 
   if ((pQuery->SeqNo - pDevice->LastFinishedQuerySeqNo) > 0) {
321
 
      pDevice->LastFinishedQuerySeqNo = pQuery->SeqNo;
322
 
   }
323
 
   pQuery->GetDataCount = 0x80000000;
324
 
}
325
 
 
326
 
 
327
 
/*
328
 
 * ----------------------------------------------------------------------
329
 
 *
330
 
 * SetPredication --
331
 
 *
332
 
 *    The SetPredication function specifies whether rendering and
333
 
 *    resource-manipulation commands that follow are actually performed.
334
 
 *
335
 
 * ----------------------------------------------------------------------
336
 
 */
337
 
 
338
 
void APIENTRY
339
 
SetPredication(D3D10DDI_HDEVICE hDevice,  // IN
340
 
               D3D10DDI_HQUERY hQuery,    // IN
341
 
               BOOL PredicateValue)       // IN
342
 
{
343
 
   LOG_ENTRYPOINT();
344
 
 
345
 
   Device *pDevice = CastDevice(hDevice);
346
 
   struct pipe_context *pipe = pDevice->pipe;
347
 
   Query *pQuery = CastQuery(hQuery);
348
 
   struct pipe_query *state = CastPipeQuery(hQuery);
349
 
   enum pipe_render_cond_flag wait;
350
 
 
351
 
   wait = (pQuery && pQuery->Flags & D3D10DDI_QUERY_MISCFLAG_PREDICATEHINT) ?
352
 
             PIPE_RENDER_COND_NO_WAIT : PIPE_RENDER_COND_WAIT;
353
 
 
354
 
   pipe->render_condition(pipe, state, PredicateValue, wait);
355
 
 
356
 
   pDevice->pPredicate = pQuery;
357
 
   pDevice->PredicateValue = PredicateValue;
358
 
}
359
 
 
360
 
 
361
 
/*
362
 
 * ----------------------------------------------------------------------
363
 
 *
364
 
 * CheckPredicate --
365
 
 *
366
 
 *    Check predicate value and whether to draw or not.
367
 
 *
368
 
 * ----------------------------------------------------------------------
369
 
 */
370
 
 
371
 
BOOL
372
 
CheckPredicate(Device *pDevice)
373
 
{
374
 
   Query *pQuery = pDevice->pPredicate;
375
 
   if (!pQuery) {
376
 
      return TRUE;
377
 
   }
378
 
 
379
 
   assert(pQuery->Type == D3D10DDI_QUERY_OCCLUSIONPREDICATE ||
380
 
          pQuery->Type == D3D10DDI_QUERY_STREAMOVERFLOWPREDICATE);
381
 
 
382
 
   struct pipe_context *pipe = pDevice->pipe;
383
 
   struct pipe_query *query = pQuery->handle;
384
 
   assert(query);
385
 
 
386
 
   union pipe_query_result result;
387
 
   memset(&result, 0, sizeof result);
388
 
 
389
 
   boolean ret;
390
 
   ret = pipe->get_query_result(pipe, query, TRUE, &result);
391
 
   assert(ret == TRUE);
392
 
   if (!ret) {
393
 
      return TRUE;
394
 
   }
395
 
 
396
 
   if (!!result.b == !!pDevice->PredicateValue) {
397
 
      return FALSE;
398
 
   }
399
 
 
400
 
   return TRUE;
401
 
}
402
 
 
403
 
 
404
 
/*
405
 
 * ----------------------------------------------------------------------
406
 
 *
407
 
 * CheckCounterInfo --
408
 
 *
409
 
 *    The CheckCounterInfo function determines global information that
410
 
 *    is related to manipulating counters.
411
 
 *
412
 
 * ----------------------------------------------------------------------
413
 
 */
414
 
 
415
 
void APIENTRY
416
 
CheckCounterInfo(D3D10DDI_HDEVICE hDevice,                  // IN
417
 
                 __out D3D10DDI_COUNTER_INFO *pCounterInfo) // OUT
418
 
{
419
 
   //LOG_ENTRYPOINT();
420
 
 
421
 
   pCounterInfo->LastDeviceDependentCounter = (D3D10DDI_QUERY)0;
422
 
   pCounterInfo->NumSimultaneousCounters = 0;
423
 
   pCounterInfo->NumDetectableParallelUnits = 0;
424
 
}
425
 
 
426
 
 
427
 
/*
428
 
 * ----------------------------------------------------------------------
429
 
 *
430
 
 * CheckCounter --
431
 
 *
432
 
 *    The CheckCounter function retrieves information that
433
 
 *    describes a counter.
434
 
 *
435
 
 * ----------------------------------------------------------------------
436
 
 */
437
 
 
438
 
void APIENTRY
439
 
CheckCounter(
440
 
   D3D10DDI_HDEVICE hDevice,                                                                // IN
441
 
   D3D10DDI_QUERY Query,                                                                    // IN
442
 
   __out D3D10DDI_COUNTER_TYPE *pCounterType,                                               // OUT
443
 
   __out UINT *pActiveCounters,                                                             // OUT
444
 
   __out_ecount_part_z_opt (*pNameLength, *pNameLength) LPSTR pName,                        // OUT
445
 
   __inout_opt UINT *pNameLength,                                                           // OUT
446
 
   __out_ecount_part_z_opt (*pUnitsLength, *pUnitsLength) LPSTR pUnits,                     // OUT
447
 
   __inout_opt UINT *pUnitsLength,                                                          // OUT
448
 
   __out_ecount_part_z_opt (*pDescriptionLength, *pDescriptionLength) LPSTR pDescription,   // OUT
449
 
   __inout_opt UINT* pDescriptionLength)                                                    // OUT
450
 
{
451
 
   LOG_ENTRYPOINT();
452
 
 
453
 
   SetError(hDevice, DXGI_DDI_ERR_UNSUPPORTED);
454
 
}