Skip to content

Commit a1b6694

Browse files
authored
CP: WinPIX: Changes to support bitfields in PIX's shader debugger (#6219) (#6299)
Two related sets of changes: 1) Modify the value-to-declare pass to tolerate bitfields, which are detected by their habit of being smaller than the type in which they are contained. The pass produces dbg.declare statements that map each HLSL variable to some storage. With bitfields, that mapping becomes many-to-one, because many bitfields can be stored in the same basic type. Most of the changes are to preserve the size of the bitfield as the code descends the type hierarchy into the underlying basic type, which is what motivates these new "type overrride" parameters to some functions. Complications to watch out for are min16 types, which may or may not be their own purpose-made (16-bit) types depending on whether or not they are enabled. 2) Modify the PIX debug-info API to return enough data to PIX to allow it to extract (by bit shifting) a bitfield from the underlying type. This bit is also about preserving knowledge of the field's size as opposed to its containing type's size, hence the new dxcapi interface/method. --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> (cherry picked from commit a23d586)
1 parent d5ece2e commit a1b6694

7 files changed

Lines changed: 436 additions & 81 deletions

File tree

include/dxc/dxcpix.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,23 @@ struct __declspec(uuid("9ba0d9d3-457b-426f-8019-9f3849982aa2")) IDxcPixArrayType
4747
};
4848

4949
struct __declspec(uuid("6c707d08-7995-4a84-bae5-e6d8291f3b78"))
50+
IDxcPixStructField0 : public IUnknown {
51+
virtual STDMETHODIMP GetName(_Outptr_result_z_ BSTR *Name) = 0;
52+
53+
virtual STDMETHODIMP GetType(_COM_Outptr_ IDxcPixType **ppType) = 0;
54+
55+
virtual STDMETHODIMP GetOffsetInBits(_Out_ DWORD *pOffsetInBits) = 0;
56+
};
57+
58+
struct __declspec(uuid("de45597c-5869-4f97-a77b-d6650b9a16cf"))
5059
IDxcPixStructField : public IUnknown {
5160
virtual STDMETHODIMP GetName(_Outptr_result_z_ BSTR *Name) = 0;
5261

5362
virtual STDMETHODIMP GetType(_COM_Outptr_ IDxcPixType **ppType) = 0;
5463

5564
virtual STDMETHODIMP GetOffsetInBits(_Out_ DWORD *pOffsetInBits) = 0;
65+
66+
virtual STDMETHODIMP GetFieldSizeInBits(_Out_ DWORD *pFieldSizeInBits) = 0;
5667
};
5768

5869
struct __declspec(uuid("24c08c44-684b-4b1c-b41b-f8772383d074"))

lib/DxilDia/DxcPixEntrypoints.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ HRESULT CreateEntrypointWrapper(IMalloc *pMalloc, IUnknown *pReal, REFIID iid,
232232
// Entrypoint is the base class for all entrypoints, providing
233233
// the default QueryInterface implementation, as well as a
234234
// more convenient way of calling SetupAndRun.
235-
template <typename I> class Entrypoint : public I {
235+
template <typename I, typename IParent = I> class Entrypoint : public I {
236236
protected:
237237
using IInterface = I;
238238

@@ -251,15 +251,16 @@ template <typename I> class Entrypoint : public I {
251251

252252
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,
253253
void **ppvObject) override final {
254-
return SetupAndRun(m_pMalloc,
255-
std::mem_fn(&Entrypoint<IInterface>::QueryInterfaceImpl),
256-
ThisPtr(this), iid, CheckNotNull(OutParam(ppvObject)));
254+
return SetupAndRun(
255+
m_pMalloc,
256+
std::mem_fn(&Entrypoint<IInterface, IParent>::QueryInterfaceImpl),
257+
ThisPtr(this), iid, CheckNotNull(OutParam(ppvObject)));
257258
}
258259

259260
HRESULT STDMETHODCALLTYPE QueryInterfaceImpl(REFIID iid, void **ppvObject) {
260261
// Special-casing so we don't need to create a new wrapper.
261-
if (iid == __uuidof(IInterface) || iid == __uuidof(IUnknown) ||
262-
iid == __uuidof(INoMarshal)) {
262+
if (iid == __uuidof(IInterface) || iid == __uuidof(IParent) ||
263+
iid == __uuidof(IUnknown) || iid == __uuidof(INoMarshal)) {
263264
this->AddRef();
264265
*ppvObject = this;
265266
return S_OK;
@@ -275,6 +276,11 @@ template <typename I> class Entrypoint : public I {
275276
Name(IMalloc *M, IInterface *pI) : Entrypoint<IInterface>(M, pI) {} \
276277
DXC_MICROCOM_TM_ALLOC(Name)
277278

279+
#define DEFINE_ENTRYPOINT_BOILERPLATE2(Name, ParentIFace) \
280+
Name(IMalloc *M, IInterface *pI) \
281+
: Entrypoint<IInterface, ParentIFace>(M, pI) {} \
282+
DXC_MICROCOM_TM_ALLOC(Name)
283+
278284
struct IUnknownEntrypoint : public Entrypoint<IUnknown> {
279285
DEFINE_ENTRYPOINT_BOILERPLATE(IUnknownEntrypoint);
280286
};
@@ -390,8 +396,10 @@ struct IDxcPixArrayTypeEntrypoint : public Entrypoint<IDxcPixArrayType> {
390396
};
391397
DEFINE_ENTRYPOINT_WRAPPER_TRAIT(IDxcPixArrayType);
392398

393-
struct IDxcPixStructFieldEntrypoint : public Entrypoint<IDxcPixStructField> {
394-
DEFINE_ENTRYPOINT_BOILERPLATE(IDxcPixStructFieldEntrypoint);
399+
struct IDxcPixStructFieldEntrypoint
400+
: public Entrypoint<IDxcPixStructField, IDxcPixStructField0> {
401+
DEFINE_ENTRYPOINT_BOILERPLATE2(IDxcPixStructFieldEntrypoint,
402+
IDxcPixStructField0);
395403

396404
STDMETHODIMP GetName(BSTR *Name) override {
397405
return InvokeOnReal(&IInterface::GetName, CheckNotNull(OutParam(Name)));
@@ -401,6 +409,11 @@ struct IDxcPixStructFieldEntrypoint : public Entrypoint<IDxcPixStructField> {
401409
return InvokeOnReal(&IInterface::GetType, CheckNotNull(OutParam(ppType)));
402410
}
403411

412+
STDMETHODIMP GetFieldSizeInBits(DWORD *pFieldSizeInBits) override {
413+
return InvokeOnReal(&IInterface::GetFieldSizeInBits,
414+
CheckNotNull(OutParam(pFieldSizeInBits)));
415+
}
416+
404417
STDMETHODIMP GetOffsetInBits(DWORD *pOffsetInBits) override {
405418
return InvokeOnReal(&IInterface::GetOffsetInBits,
406419
CheckNotNull(OutParam(pOffsetInBits)));

lib/DxilDia/DxcPixLiveVariables_FragmentIterator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ InitialOffsetInBitsFromDIExpression(const llvm::DataLayout &DataLayout,
9999
}
100100

101101
FragmentOffsetInBits = Expression->getBitPieceOffset();
102-
assert(Expression->getBitPieceSize() ==
102+
assert(Expression->getBitPieceSize() <=
103103
DataLayout.getTypeAllocSizeInBits(Alloca->getAllocatedType()));
104104
}
105105

lib/DxilDia/DxcPixTypes.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,3 +291,10 @@ dxil_debug_info::DxcPixStructField::GetOffsetInBits(DWORD *pOffsetInBits) {
291291
*pOffsetInBits = m_pField->getOffsetInBits();
292292
return S_OK;
293293
}
294+
295+
STDMETHODIMP
296+
dxil_debug_info::DxcPixStructField::GetFieldSizeInBits(
297+
DWORD *pFieldSizeInBits) {
298+
*pFieldSizeInBits = m_pField->getSizeInBits();
299+
return S_OK;
300+
}

lib/DxilDia/DxcPixTypes.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ class DxcPixStructType : public IDxcPixStructType2 {
208208
STDMETHODIMP GetBaseType(IDxcPixType **ppType) override;
209209
};
210210

211+
struct __declspec(uuid("6c707d08-7995-4a84-bae5-e6d8291f3b78"))
212+
PreviousDxcPixStructField {};
213+
211214
class DxcPixStructField : public IDxcPixStructField {
212215
private:
213216
DXC_MICROCOM_TM_REF_FIELDS()
@@ -228,6 +231,12 @@ class DxcPixStructField : public IDxcPixStructField {
228231

229232
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,
230233
void **ppvObject) override {
234+
if (IsEqualIID(iid, __uuidof(PreviousDxcPixStructField))) {
235+
*(IDxcPixStructField **)ppvObject = this;
236+
this->AddRef();
237+
return S_OK;
238+
}
239+
231240
return DoBasicQueryInterface<IDxcPixStructField>(this, iid, ppvObject);
232241
}
233242

@@ -236,5 +245,7 @@ class DxcPixStructField : public IDxcPixStructField {
236245
STDMETHODIMP GetType(IDxcPixType **ppType) override;
237246

238247
STDMETHODIMP GetOffsetInBits(DWORD *pOffsetInBits) override;
248+
249+
STDMETHODIMP GetFieldSizeInBits(DWORD *pFieldSizeInBits) override;
239250
};
240251
} // namespace dxil_debug_info

0 commit comments

Comments
 (0)