読者です 読者をやめる 読者になる 読者になる

ゆとりーなの日記

日記的な事を書いて行くと思はれる

アライメントってのがよく分からん

まぁPSPSDKに渡す画像イメージのデータは16byte境界にアライメントされてなきゃいかんらしいので今まで普通にこういう配列をグローバルに定義しておいてこれを渡してたわけですね。

unsigned int __attribute__((aligned(16)))back_image_buffer[480 * 272];

まぁC言語であればこれでいいんでしょうが、我々が使っているのはC++ですから、これをクラスのメンバに持たせたいわけですね。オブジェクト指向ですはい。

class image {
 private:
  unsigned int __attribute__((aligned(16)))back_image_buffer_[480 * 272];
}

これのback_image_buffer_をPSPAPIに渡すと転ぶ転ぶ。最初一応組み込みみたいなもの?だからスタックとかヒープが少ないからかなとか思ってたんですね。動的確保したものでもこけてましたし。
しかしどうも調べたところ、最近は配列を確保してるところじゃなくてイメージを書き込むAPIのところでこけてるみたいだったんでひょっとするとアライメントの問題?と思うようになったわけです。VC++だとメンバにアラインメント指定の独自拡張を指定しても効果がないとかいう話をSSE周りの時に聞いたことがあったのでGCCもひょっとしてとか思ったわけですね。
まぁそれの真偽はさておき、最近のPSPSDKのmallocはどうも16byte境界にアライメントされたメモリを返してくれるっていうので試してみたわけですね。

class image {
 public:
  explicit image(const char * const file_name)
      : back_image_buffer_(static_cast<unsigned int*>(std::malloc(480 * 272))) {}
 
 private:
  unsigned int *back_image_buffer_;
};

これで耐えるだろうと思ったんですが、まぁ確かに落ちなくはなったんですが、ノイズが走るんですね。しかも致命的なことに、

const image test1("test1.dds");
const image test2("test2.dds");
test1.draw();

見たいな感じに二つインスタンス作って描画すると、一枚目を描画してるはずなのになんか二枚目の絵がめり込んでるんですね。ひょっとしてアライメント指定って先頭アドレスだけじゃなくて全部の要素が16byteに揃ってるってことなのかって気がしてきたのでunsigned intは多分4byteだろうからmallocで確保するメモリの量を4倍にしてみたわけですね。→mallocの仕様の勘違いでした。確保量にunsigned intのサイズ分掛けてあげないとダメですね。

class image {
 public:
  explicit image(const char * const file_name)
      : back_image_buffer_(static_cast<unsigned int*>(std::malloc(480 * 272 * 4))) {}
 
 private:
  unsigned int *back_image_buffer_;
};

これにて絵のノイズや重なりはなくなってまぁ一応解決を見たわけですが、どうもアライメントの理解が今ひとつ出来てません。
2枚目の絵が一枚目の絵にめり込んだってのは本当に必要なメモリ量の1/4しか確保してなかったから次のmallocで確保した領域が前の絵の必要な領域とかぶってしまったからだとしても、画像ファイル自体は、

sceIoRead(fd, back_image_buffer_, 480 * 272 * 4);

みたいに読み込んでるので1/4の分しか読み込んでない気がするのですがね。そうすると一枚目の絵はノイズで済まずに1/4というか、変な感じにしか描画されない気がするんですがね。
ひょっとするとsceIoReadも16byte境界に空気を読んで書き込んでるってことなんですかね。そうすると領域はみ出して書き込んでることになりますが、まぁ別に不正アクセスにはならんけどちゃんと確保してないからノイズが走ったってことになるんですかね。で、二枚目のmallocでは一枚目が不正に書き込んだ部分を確保してそこにまた書き込んでみたいな感じだったのでしょうか。なんだかよく分かりません。
あと東方紅魔郷PSP移植へのコメントが定期的に来るみたいなので取り敢えずリポジトリ作りました。GitHub - nagoya313/th06_psp: 東方紅魔郷のPSP移植の問い合わせが多い?のでリポジトリだけ置いとくにて適当にソース置いておく感じにします。
因みにSTG画面の比率ってこんなものでいいんですかね。

追記:
アホすぎました。確保サイズの要素分のサイズを掛けてなかったからっぽいですね。いくら普段使わないからってこれはひどいですね。因みにnewだとどうあがいてもノイズが走るみたいなのですが、このあたりはよく分からないですね。