ПрограммированиеФорумГрафика

не пойму в чем косяк : DX11, XMMATRIX

#0
1:30, 3 июля 2010

Вот, делаю небольшой проект на DX11, для передачи в шейдер использую готовую структуру из СДК - XMMATRIX, #include <xnamath.h>... Походу выполнения стала возникать некоторая проблема, свел все к минимуму и сделал тестовый пример чтобы разобраться.. но так и не пойму в чем дело...
Вот тестовый пример:
Суть такая есть класс CTestMatrix, от него наследуется класс CNewTestMatrix, у класса CNewTestMatrix есть единственный член XMMATRIX test;
Так вот при обращении к этому члену в конструкторе класса CNewTestMatrix  происходит Unhandled exception at 0x00a61547 in simple_dx11_qt_app.exe: 0xC0000005: Access violation reading location 0x00000000.
Такое чувство что обращение по нулевому указателю, но как такое может быть хз... И такое происходит именно при наследовании, т.е. если юзать этот класс просто так, то все работает нормально.
Код ниже:
Хедер класса test_matrix.h

#ifndef _TEST_MATRIX_H_
#define _TEST_MATRIX_H_

#include <d3d11.h>
#include <d3dx11.h>
#include <xnamath.h>

//////////////////////////////////////////////////////////////////////////
class CTestMatrix
{
public:
    CTestMatrix(){};
    ~CTestMatrix(){};
};
//////////////////////////////////////////////////////////////////////////
class CNewTestMatrix : public CTestMatrix
{
public:
    CNewTestMatrix();
    ~CNewTestMatrix(){};
protected:
    XMMATRIX test;
};
//////////////////////////////////////////////////////////////////////////
#endif //_TEST_MATRIX_H_

Цепепшник класса test_matrix.cpp

#include "test_matrix.h"

CNewTestMatrix::CNewTestMatrix()
{
    XMMATRIX temp;
    temp.r[0] = test.r[0];    /// Тут происходит краш : Access violation reading location 0x00000000.
}

Майн:

#include "test_matrix.h"

int main(int argc, char** argv)
{
    CNewTestMatrix* aaa = new CNewTestMatrix;
}

Вот смущает немного сам класс матрицы, что перед ним стоит какоето выравнивание по 16бит, причем первый дефайн не проходит и срабатывает именно то описание структуры которое с выравниванием
Класс матрицы:

// Matrix type: Sixteen 32 bit floating point components aligned on a
// 16 byte boundary and mapped to four hardware vector registers
#if (defined(_XM_X86_) || defined(_XM_X64_)) && defined(_XM_NO_INTRINSICS_)
typedef struct _XMMATRIX
#else
typedef _DECLSPEC_ALIGN_16_ struct _XMMATRIX  // срабатывает это описание , хз че такое _XM_NO_INTRINSICS_ не определяется ............
#endif
{
    union
    {
        XMVECTOR r[4];
        struct
        {
            FLOAT _11, _12, _13, _14;
            FLOAT _21, _22, _23, _24;
            FLOAT _31, _32, _33, _34;
            FLOAT _41, _42, _43, _44;
        };
        FLOAT m[4][4];
    };

#ifdef __cplusplus

    _XMMATRIX() {};
    _XMMATRIX(FXMVECTOR R0, FXMVECTOR R1, FXMVECTOR R2, CXMVECTOR R3);
    _XMMATRIX(FLOAT m00, FLOAT m01, FLOAT m02, FLOAT m03,
              FLOAT m10, FLOAT m11, FLOAT m12, FLOAT m13,
              FLOAT m20, FLOAT m21, FLOAT m22, FLOAT m23,
              FLOAT m30, FLOAT m31, FLOAT m32, FLOAT m33);
    _XMMATRIX(CONST FLOAT *pArray);

    FLOAT       operator() (UINT Row, UINT Column) CONST { return m[Row][Column]; }
    FLOAT&      operator() (UINT Row, UINT Column) { return m[Row][Column]; }

    _XMMATRIX&  operator= (CONST _XMMATRIX& M);

#ifndef XM_NO_OPERATOR_OVERLOADS
    _XMMATRIX&  operator*= (CONST _XMMATRIX& M);
    _XMMATRIX   operator* (CONST _XMMATRIX& M) CONST;
#endif // !XM_NO_OPERATOR_OVERLOADS

#endif // __cplusplus

} XMMATRIX;
#1
2:05, 3 июля 2010

вообщем падает вроде из за выравнивания, но че делать не пойму пока

#2
4:58, 3 июля 2010

попробуй переопределить оператор new/delete как-то так:

#define INL __forceinline

INL PVOID __cdecl operator new (size_t sz) {
  return _aligned_malloc(sz, 16);
}

INL PVOID __cdecl operator new [] (size_t sz) {
  return _aligned_malloc(sz, 16);
}

INL void __cdecl operator delete(PVOID pVoid, size_t) {
  _aligned_free(pVoid); 
}

INL void __cdecl operator delete(PVOID pVoid) {
  _aligned_free(pVoid); 
}

INL void __cdecl operator delete [] (PVOID pVoid, size_t sz) {
  _aligned_free(pVoid); 
}

INL void __cdecl operator delete [] (PVOID pVoid) {
  _aligned_free(pVoid); 
}
#3
12:49, 3 июля 2010

хз, мб легче тогдауж задефайнить  _XM_NO_INTRINSICS_, чтобы матрица без выравнивания была, тогда краши прекращаются, но с другой стороны, правильно ли это

#4
12:49, 3 июля 2010

из МСДНа 

When _XM_NO_INTRINSICS_ is defined, XNA Math operations are implemented without using any platform-specific intrinsics. Instead, XNA Math will use only standard floating point operations.

By default, _XM_NO_INTRINSICS_ is not defined.

#5
16:49, 3 июля 2010

Вахтанг Кикабидзе
c _XM_NO_INTRINSICS_ мат. библа не будет юзать SSE оптимизацию - глянь исходники и всё увидишь.

#6
8:45, 5 июля 2010

для записи значений в матрицы и вектора XNA надо использовать Load* и Save*
в "типизированные" объекты (например, FLOAT4X4) вроде можно свободно писать (см. документацию)

Прошло более 1 года
#7
0:04, 27 фев 2012

Столкнулся с примерно такойже проблемой, вот такой код вызывает краш:

m_testMatrix = XMMatrixIdentity();

но в тоже время работает такой код:

XMMATRIX m = XMMatrixIdentity();
  memcpy(&m_testMatrix,&m,sizeof(m));

и не работает такой

XMMATRIX m = XMMatrixIdentity();
  memcpy(&m_testMatrix,&m,sizeof(m));
  m_testMatrix = m; //тут краш

при этом вполне можно обращаться к элементам матрицы так (без краша)

m_testMatrix._11 = 1.f
m_testMatrix._22 = 1.f

но самое ужасное, что в одном примере из книжки вполнесебе хорошо работает такой код:

viewMatrix_ = XMMatrixIdentity( );
projMatrix_ = XMMatrixPerspectiveFovLH( XM_PIDIV4, 800.0f / 600.0f, 0.01f, 100.0f );

viewMatrix_ = XMMatrixTranspose( viewMatrix_ );
projMatrix_ = XMMatrixTranspose( projMatrix_ );
+ хэдер примера

Возможно ли, что это из-за того, что мой тип проекта - статическая либа, а пример нет?
и кстати #define _XM_NO_INTRINSICS_ не помогает :(

edit вообщем временно остался на memcpy. подскажите, в этом же нет чего-то ужасного в смысле по производительности?

#8
1:33, 27 фев 2012

tapahob
В первом случае объект находится в хипе, и скорее всего не выровнен.
Во втором случае единичная матрица формируется на стэке, где она выравнивается автоматически.
Для классов, содержащих SSE типы, нужно делать aligned allocator.

#9
19:38, 29 фев 2012

Суссюр
> Для классов, содержащих SSE типы, нужно делать aligned allocator.
Спасибо за ответ, aligned allocator вкатил, но нагуглился другой вариант

+ Показать

собственно вопрос, куда дописать этот параметр\ключ? пробовал в C\C++ -> Command line -> additional options и куда-то еще - не помогло.

Прошло более 3 лет
#10
21:20, 1 апр 2015

tapahob
> собственно вопрос, куда дописать этот параметр\ключ? пробовал в C\C++ ->
> Command line -> additional options и куда-то еще - не помогло.


Не знаю кому как, но мне лично это пригодилось. Вдруг еще кто с таким вопросом встретиться

https://msdn.microsoft.com/ru-ru/library/7t5yh4fd.aspx

(если страницу когда-то удалят, то вот)
1)    Откройте диалоговое окно Страницы свойств проекта.

2)    Выберите папку Свойства конфигурации, а затем папку C/C++.

3)    Выберете страницу свойств Создание кода.

4)    Измените свойство Включить расширенный набор инструкций.

#11
21:58, 1 апр 2015

sawich
> Не знаю кому как, но мне лично это пригодилось. Вдруг еще кто с таким вопросом встретиться
Добро пожаловать в 21 век.

ПрограммированиеФорумГрафика

Тема в архиве.