UWP开发细节记录:DirectX::XMMATRIX 的坑

这两天写的代码概率性的崩溃在 XMMatrixMultiply() 函数,XMMatrixMultiply() 本身是 inline 函数可以看到崩溃处的代码:

vX = _mm_mul_ps(vX,M2.r[0]);

经查,_mm_mul_ps 是 SSE2 指令要求内存地址 16 字节对齐。猜想可能是字节未对齐引发的问题,打印出矩阵参数的地址,果然,发生崩溃时都是未对齐到 16 字节的情况。

XMMATRIX 声明中指定了对齐到 16 字节,如下:

__declspec(align(16)) struct XMMATRIX
{
    ...
};

但是显然没起到效果,继续查发现是用到 XMMATRIX 变量被定义成了类成员变量,该类的实例是 new 出来的:

class MyClass
{
   XMMATRIX matrix_;
};

MyClass* ptr= new MyClass(); // 这里应该有一个编译警告

而 new 操作符只保证对齐到不大于 alignof(std::max_align_t)  也就是 8 字节,导致成员变量 matrix_ 也只能对齐到 8 字节。 解决方法先将成员变量 martix_ 赋值给一个局部变量,然后通过局部变量调用 XMMatrixMultiply() 函数。直接使用 new 会有一条对象可能无法对齐到 16 字节的警告信息,但因为我是用 std::make_shared 直接生成智能指针,编译器没能给出这条警告——这也是个坑,最终导致了前面的崩溃问题。

注意 XMMatrixMultiply() 的声明,第一个参数是值传参,第二个是引用传参,问题就处在引用传参上:

1 typedef const XMMATRIX FXMMATRIX
2 typedef const XMMATRIX& CXMMATRIX;
3
4 inline XMMATRIX XM_CALLCONV XMMatrixMultiply (FXMMATRIX M1, CXMMATRIX M2); //注意第二个参数是引用传参

MSDN 中对 XMMatrixMultiply 函数的声明和实际代码并不一致:

XMMATRIX XMMatrixMultiply(
  [in] XMMATRIX M1,
  [in] XMMATRIX M2
);

如果真的两个参数都是值传参也就没有字节对齐的问题了。

最终结论:XMMATRIX 结构体要求 16 字节对齐,只能用作局部变量或全局变量——在静态存储区或栈上分配内存可以确保 align(16) 声明有效,永远不要用 new 分配堆内存,也不要用作类成员变量;如果需要在成员变量中保存矩阵可以用 DirectX::XMFLOAT4X4 ,使用时再转换为 XMMATRIX 。

顺便吐槽一下,MSDN 以前被称为写得最好的开发文档是当之无愧的,现在只能呵呵了。最近两年新增的文档(比如 UWP 和 DX11 的文档)明显敷衍了事,函数说明经常一句话了事,看文档和直接对着函数声明猜用法都没什么区别了,这次居然还出现了函数声明不一致的情况,这样下去吃枣药丸哪。

时间: 2024-12-19 12:52:05

UWP开发细节记录:DirectX::XMMATRIX 的坑的相关文章

UWP开发细节记录:加载图像文件到D2D位图和D3D纹理

在UWP中加载文件一般先创建 StorageFile 对象,然后调用StorageFile.OpenReadAsync 方法得到一个IRandomAccessStream 接口用来读取数据: 1 StorageFile image_file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/sample.jpg", UriKind.Absolute)); 2 IRandomAcce

UWP开发细节记录:判断文件类型

StorageFile.ContentType 属性,是 string 类型,用来表示文件内容的 MIME 类型.例如,音乐文件可能有 "audio/mpeg" MIME 类型.(MSDN) MIME 类型的定义可以下面的链接找到: MIME Types - http://blogs.msdn.com/b/jaimer/archive/2008/01/04/mime-types.aspx MIME 参考手册 - http://www.w3school.com.cn/media/medi

记UWP开发——多线程操作/并发操作中的坑

一切都要从新版风车动漫UWP的图片缓存功能说起. 起因便是风车动漫官网的番剧更新都很慢,所以图片更新也非常慢.在开发新版的过程中,我很简单就想到了图片多次重复下载导致的资源浪费问题. 所以我给app加了一个缓存机制: 创建一个用户控件CoverView,将首页GridView.ItemTemplate里的Image全部换成CoverView CoverView一旦接到ImageUrl的修改,就会自动向后台的PictureHelper申请指定Url的图片 PictureHelper会先判断本地是否

讲讲我在Windows10(uwp)开发中遇到的一些坑.

7月29日发布的Windows10正式版,当天安装好以后,在网络不太好的情况下,经过多次尝试终于装上了Visual Studio 2015和Windows 10 10240的SDK.这两周一直在开发UWP,讲讲在其中遇到的一些坑,不定时更新,有兴趣的可以关注下. 1.DataType在UWP中缺失的问题 在WPF中使用过MVVMLight的都知道,我们可以在App.xaml文件中通过DataType将ViewModel和View绑定在一起. 1 <DataTemplate DataType=&quo

Windows UWP 开发 - 前言

Windows 10 发布近一年了,Visual Studio 2015 也已推出 Update2,UWP 应用开发不仅时机成熟了而且也已经很方便了.所以我打算写一系列的文章来记录我是如何开发 UWP 应用的,对于我自己来说算是笔记,同时也供其它朋友参考.UWP 应用和之前的 WPF.Silverlight 非常相似,其 UI 部分基于 DirectX 技术,使用 XAML 描述构建,即灵活效果也很出色.逻辑代码支持 C++.C#.VB 和 JavaScript,因此对于绝大多数程序员来说开发语

UWP开发入门(二十一)——保持Ui线程处于响应状态

GUI的程序有时候会因为等待一个耗时操作完成,导致界面卡死.本篇我们就UWP开发中可能遇到的情况,来讨论如何优化处理. 假设当前存在点击按钮跳转页面的操作,通过按钮打开的新页面,在初始化过程中存在一些耗时的操作. public void OnNavigatedTo(object obj) { var watch = new Stopwatch(); Debug.WriteLine("---------------Start"); watch.Start(); //假设耗时1秒 DoBu

Windows10(uwp)开发中的侧滑

还是在持续的开发一款Windows10的应用中,除了上篇博客讲讲我在Windows10(uwp)开发中遇到的一些坑,其实还有很多不完善的地方,比如(UIElement.Foreground).(GradientBrush.GradientStops)[1].(GradientStop.Offset)这种设置无法生效,还有RelativePanel内的元素不能自动的适应大小,要去手动控制宽高度,以及窗口在靠边的时候一些尺寸上的错误等等.虽然是WPF技术之后的延续,但是很多地方还是要小心仔细的处理,

“智&#183;商”商业技能大赛网站开发心得记录

"智·商"商业技能大赛官方网站开发心得记录 现在才来写这篇东西-不是因为忙,而是懒! 这个寒假接到了师弟的一个需求, 请我帮忙去做他们学院一个活动的官方网站,我大概了解之后就接下来了,于是我找了我基友跟我一起做这个网站. 需求是这样的: 竞赛介绍:介绍竞赛来源.历史.举办单位.本届情况等: 通知公告:主要为比赛公告等: 注意事项:关于比赛的注意事项. 队伍注册:在线注册队伍,以队伍为单位参加比赛: 试卷设置:添加试卷试题:包括设置答案以及分值: 在线答题:提供在线同时统一答题功能: 初

javascrpit开发连连看记录-小游戏

工作之余,总想做点什么有意思的东西.但是苦于不知道做什么,也就一直没有什么动作.在一个午饭后,跟@jedmeng和@墨尘聊天过程中,发现可以写一些小东西来练练手,有以下几点好处: 1. 加强巩固前端相关知识 2. 可以用一些平时项目中想用但没用的新东西 3. 一块儿做相同的东西,可以分享各自不同的想法 先来一张效果图,也可以来这里玩玩~      接下来就介绍一下做这个小游戏,自己的一些步骤和思路: 首先就是熟悉连连看的规则,为此还专门下载了一个app感受了一下,规则简单的说就是:找到两个相同的