mirror of
https://github.com/xemu-project/nxdk_pgraph_tests.git
synced 2025-02-18 17:17:50 +00:00
Merge branch 'volumetric_texture'
This commit is contained in:
commit
0c6940b005
@ -39,7 +39,8 @@ TestHost::TestHost(uint32_t framebuffer_width, uint32_t framebuffer_height, uint
|
||||
static constexpr uint32_t kMaxPaletteSize = 256 * 4;
|
||||
uint32_t palette_size = kMaxPaletteSize * 4;
|
||||
|
||||
uint32_t total_size = texture_size + palette_size;
|
||||
static constexpr uint32_t kMaxTextures = 4;
|
||||
uint32_t total_size = texture_size * kMaxTextures + palette_size;
|
||||
|
||||
texture_memory_ = static_cast<uint8_t *>(
|
||||
MmAllocateContiguousMemoryEx(total_size, 0, MAXRAM, 0, PAGE_WRITECOMBINE | PAGE_READWRITE));
|
||||
@ -845,16 +846,21 @@ int TestHost::SetTexture(SDL_Surface *surface, uint32_t stage) {
|
||||
return texture_stage_[stage].SetTexture(surface, texture_memory_);
|
||||
}
|
||||
|
||||
int TestHost::SetVolumetricTexture(const SDL_Surface **surface, uint32_t depth, uint32_t stage) {
|
||||
return texture_stage_[stage].SetVolumetricTexture(surface, depth, texture_memory_);
|
||||
}
|
||||
|
||||
int TestHost::SetRawTexture(const uint8_t *source, uint32_t width, uint32_t height, uint32_t depth, uint32_t pitch,
|
||||
uint32_t bytes_per_pixel, bool swizzle, uint32_t stage) {
|
||||
uint32_t max_stride = max_texture_width_ * 4;
|
||||
uint32_t max_texture_size = max_stride * max_texture_height_ * max_texture_depth_;
|
||||
const uint32_t max_stride = max_texture_width_ * 4;
|
||||
const uint32_t max_texture_size = max_stride * max_texture_height_ * max_texture_depth_;
|
||||
|
||||
uint32_t surface_size = pitch * height * depth;
|
||||
const uint32_t layer_size = pitch * height;
|
||||
const uint32_t surface_size = layer_size * depth;
|
||||
ASSERT(surface_size < max_texture_size && "Texture too large.");
|
||||
|
||||
// TODO: Handle 3d textures.
|
||||
return texture_stage_[stage].SetRawTexture(source, width, height, pitch, bytes_per_pixel, swizzle, texture_memory_);
|
||||
return texture_stage_[stage].SetRawTexture(source, width, height, depth, pitch, bytes_per_pixel, swizzle,
|
||||
texture_memory_);
|
||||
}
|
||||
|
||||
int TestHost::SetPalette(const uint32_t *palette, PaletteSize size, uint32_t stage) {
|
||||
|
@ -152,13 +152,14 @@ class TestHost {
|
||||
|
||||
public:
|
||||
TestHost(uint32_t framebuffer_width, uint32_t framebuffer_height, uint32_t max_texture_width,
|
||||
uint32_t max_texture_height, uint32_t max_texture_depth = 16);
|
||||
uint32_t max_texture_height, uint32_t max_texture_depth = 4);
|
||||
~TestHost();
|
||||
|
||||
TextureStage &GetTextureStage(uint32_t stage) { return texture_stage_[stage]; }
|
||||
void SetTextureFormat(const TextureFormatInfo &fmt, uint32_t stage = 0);
|
||||
void SetDefaultTextureParams(uint32_t stage = 0);
|
||||
int SetTexture(SDL_Surface *surface, uint32_t stage = 0);
|
||||
int SetVolumetricTexture(const SDL_Surface **surface, uint32_t depth, uint32_t stage = 0);
|
||||
int SetRawTexture(const uint8_t *source, uint32_t width, uint32_t height, uint32_t depth, uint32_t pitch,
|
||||
uint32_t bytes_per_pixel, bool swizzle, uint32_t stage = 0);
|
||||
|
||||
|
@ -135,17 +135,7 @@ void TestSuite::Initialize() {
|
||||
}
|
||||
|
||||
p = pb_push1(p, NV097_SET_FOG_ENABLE, false);
|
||||
|
||||
{
|
||||
uint32_t matrix_enable = NV097_SET_TEXTURE_MATRIX_ENABLE;
|
||||
p = pb_push1(p, matrix_enable, 0x0);
|
||||
matrix_enable += 4;
|
||||
p = pb_push1(p, matrix_enable, 0x0);
|
||||
matrix_enable += 4;
|
||||
p = pb_push1(p, matrix_enable, 0x0);
|
||||
matrix_enable += 4;
|
||||
p = pb_push1(p, matrix_enable, 0x0);
|
||||
}
|
||||
p = pb_push4(p, NV097_SET_TEXTURE_MATRIX_ENABLE, 0, 0, 0, 0);
|
||||
|
||||
p = pb_push1(p, NV097_SET_FRONT_FACE, NV097_SET_FRONT_FACE_V_CW);
|
||||
p = pb_push1(p, NV097_SET_CULL_FACE, NV097_SET_CULL_FACE_V_BACK);
|
||||
|
@ -31,7 +31,7 @@ TextureFormatTests::TextureFormatTests(TestHost &host, std::string output_dir)
|
||||
std::string name = MakeTestName(format);
|
||||
|
||||
if (format.xbox_format != NV097_SET_TEXTURE_FORMAT_COLOR_SZ_I8_A8R8G8B8) {
|
||||
tests_[name] = [this, format]() { this->Test(format); };
|
||||
tests_[name] = [this, format]() { Test(format); };
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,6 +126,9 @@ void TextureFormatTests::TestPalettized(TestHost::PaletteSize size) {
|
||||
std::string TextureFormatTests::MakeTestName(const TextureFormatInfo &texture_format) {
|
||||
std::string test_name = "TexFmt_";
|
||||
test_name += texture_format.name;
|
||||
if (!texture_format.xbox_swizzled) {
|
||||
test_name += "_L";
|
||||
}
|
||||
return std::move(test_name);
|
||||
}
|
||||
|
||||
@ -154,12 +157,13 @@ static int GenerateGradientSurface(SDL_Surface **gradient_surface, int width, in
|
||||
}
|
||||
|
||||
auto pixels = static_cast<uint32_t *>((*gradient_surface)->pixels);
|
||||
for (int y = 0; y < height; ++y)
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x, ++pixels) {
|
||||
int x_normal = static_cast<int>(static_cast<float>(x) * 255.0f / static_cast<float>(width));
|
||||
int y_normal = static_cast<int>(static_cast<float>(y) * 255.0f / static_cast<float>(height));
|
||||
*pixels = SDL_MapRGBA((*gradient_surface)->format, y_normal, x_normal, 255 - y_normal, x_normal + y_normal);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(*gradient_surface);
|
||||
|
||||
|
@ -12,21 +12,32 @@
|
||||
#include "texture_format.h"
|
||||
#include "vertex_buffer.h"
|
||||
|
||||
static int GenerateSurface(SDL_Surface **gradient_surface, int width, int height, int layer);
|
||||
static int GeneratePalettizedSurface(uint8_t **ret, uint32_t width, uint32_t height, uint32_t depth,
|
||||
TestHost::PaletteSize palette_size);
|
||||
static uint32_t *GeneratePalette(TestHost::PaletteSize size);
|
||||
|
||||
static const VolumeTextureTests::TestConfig kTestConfigs[] = {
|
||||
{"Indexed", GetTextureFormatInfo(NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8B8G8R8), false},
|
||||
};
|
||||
|
||||
static constexpr const char *kTestName = "Palettized";
|
||||
static constexpr uint32_t kBackgroundColor = 0xFE202020;
|
||||
static const uint32_t kTextureWidth = 256;
|
||||
static const uint32_t kTextureHeight = 256;
|
||||
static const uint32_t kTextureDepth = 4;
|
||||
|
||||
VolumeTextureTests::VolumeTextureTests(TestHost &host, std::string output_dir)
|
||||
: TestSuite(host, std::move(output_dir), "Volume texture") {
|
||||
for (auto &config : kTestConfigs) {
|
||||
tests_[kTestName] = [this, &config]() { Test(config); };
|
||||
for (auto i = 0; i < kNumFormats; ++i) {
|
||||
auto &format = kTextureFormats[i];
|
||||
if (!format.xbox_swizzled) {
|
||||
// Linear volumetric formats are not supported by the hardware.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (format.xbox_format != NV097_SET_TEXTURE_FORMAT_COLOR_SZ_I8_A8R8G8B8) {
|
||||
tests_[format.name] = [this, format]() { Test(format); };
|
||||
}
|
||||
}
|
||||
|
||||
auto palettized = GetTextureFormatInfo(NV097_SET_TEXTURE_FORMAT_COLOR_SZ_I8_A8R8G8B8);
|
||||
tests_[palettized.name] = [this]() { TestPalettized(); };
|
||||
}
|
||||
|
||||
void VolumeTextureTests::Initialize() {
|
||||
@ -38,20 +49,23 @@ void VolumeTextureTests::Initialize() {
|
||||
host_.SetXDKDefaultViewportAndFixedFunctionMatrices();
|
||||
host_.SetTextureStageEnabled(0, true);
|
||||
|
||||
host_.SetShaderStageProgram(TestHost::STAGE_2D_PROJECTIVE);
|
||||
host_.SetShaderStageProgram(TestHost::STAGE_3D_PROJECTIVE);
|
||||
|
||||
host_.SetInputColorCombiner(0, TestHost::SRC_TEX0, false, TestHost::MAP_UNSIGNED_IDENTITY, TestHost::SRC_ZERO, false,
|
||||
TestHost::MAP_UNSIGNED_INVERT);
|
||||
host_.SetInputAlphaCombiner(0, TestHost::SRC_TEX0, true, TestHost::MAP_UNSIGNED_IDENTITY, TestHost::SRC_ZERO, false,
|
||||
TestHost::MAP_UNSIGNED_INVERT);
|
||||
|
||||
host_.SetOutputColorCombiner(0, TestHost::DST_DIFFUSE);
|
||||
host_.SetOutputAlphaCombiner(0, TestHost::DST_DIFFUSE);
|
||||
host_.SetOutputColorCombiner(0, TestHost::DST_R0);
|
||||
host_.SetOutputAlphaCombiner(0, TestHost::DST_R0);
|
||||
|
||||
host_.SetFinalCombiner0(TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, false,
|
||||
false, TestHost::SRC_DIFFUSE);
|
||||
host_.SetFinalCombiner1(TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, false, false, TestHost::SRC_DIFFUSE,
|
||||
true);
|
||||
false, TestHost::SRC_R0);
|
||||
host_.SetFinalCombiner1(TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, false, false, TestHost::SRC_R0, true);
|
||||
|
||||
auto p = pb_begin();
|
||||
p = pb_push1(p, NV097_SET_TEXTURE_BORDER_COLOR, 0xFFFFFF);
|
||||
pb_end(p);
|
||||
}
|
||||
|
||||
void VolumeTextureTests::CreateGeometry() {
|
||||
@ -62,54 +76,83 @@ void VolumeTextureTests::CreateGeometry() {
|
||||
const float mid_width = 0;
|
||||
const float mid_height = 0;
|
||||
|
||||
// const uint32_t num_quads = 4;
|
||||
// std::shared_ptr<VertexBuffer> buffer = host_.AllocateVertexBuffer(6 * num_quads);
|
||||
// buffer->SetTexCoord0Count(2);
|
||||
//
|
||||
// const float spacing = 0.05f;
|
||||
// int index = 0;
|
||||
//
|
||||
// buffer->DefineBiTri(index++, left, top, mid_width - spacing, mid_height + spacing);
|
||||
//
|
||||
// buffer->DefineBiTri(index++, mid_width + spacing, top, right, mid_height + spacing);
|
||||
//
|
||||
// buffer->DefineBiTri(index++, left, mid_height - spacing, mid_width - spacing, bottom);
|
||||
//
|
||||
// buffer->DefineBiTri(index++, mid_width + spacing, mid_height - spacing, right, bottom);
|
||||
//
|
||||
// // Set texcoords.
|
||||
// auto vertex = buffer->Lock();
|
||||
//
|
||||
// auto set_bitri_texcoords = [&vertex](float p) {
|
||||
// vertex++->SetTexCoord0(0.0f, 0.0f, p, 0.0);
|
||||
// vertex++->SetTexCoord0(1.0f, 0.0f, p, 0.0);
|
||||
// vertex++->SetTexCoord0(1.0f, 1.0f, p, 0.0);
|
||||
//
|
||||
// vertex++->SetTexCoord0(0.0f, 0.0f, p, 0.0);
|
||||
// vertex++->SetTexCoord0(1.0f, 1.0f, p, 0.0);
|
||||
// vertex++->SetTexCoord0(0.0f, 1.0f, p, 0.0);
|
||||
// };
|
||||
//
|
||||
// set_bitri_texcoords(0.0f);
|
||||
//
|
||||
// set_bitri_texcoords(0.33f);
|
||||
//
|
||||
// set_bitri_texcoords(0.66f);
|
||||
//
|
||||
// set_bitri_texcoords(1.0f);
|
||||
//
|
||||
// buffer->Unlock();
|
||||
|
||||
const uint32_t num_quads = 1;
|
||||
const uint32_t num_quads = 4;
|
||||
std::shared_ptr<VertexBuffer> buffer = host_.AllocateVertexBuffer(6 * num_quads);
|
||||
buffer->SetTexCoord0Count(3);
|
||||
|
||||
const float spacing = 0.05f;
|
||||
int index = 0;
|
||||
buffer->DefineBiTri(index++, left, top, right, bottom);
|
||||
buffer->Linearize(static_cast<float>(host_.GetMaxTextureWidth()), static_cast<float>(host_.GetMaxTextureHeight()));
|
||||
|
||||
buffer->DefineBiTri(index++, left, top, mid_width - spacing, mid_height + spacing);
|
||||
|
||||
buffer->DefineBiTri(index++, mid_width + spacing, top, right, mid_height + spacing);
|
||||
|
||||
buffer->DefineBiTri(index++, left, mid_height - spacing, mid_width - spacing, bottom);
|
||||
|
||||
buffer->DefineBiTri(index++, mid_width + spacing, mid_height - spacing, right, bottom);
|
||||
|
||||
// Set texcoords.
|
||||
auto vertex = buffer->Lock();
|
||||
|
||||
auto set_bitri_texcoords = [&vertex](float p) {
|
||||
vertex++->SetTexCoord0(0.0f, 0.0f, p, 0.0);
|
||||
vertex++->SetTexCoord0(1.0f, 0.0f, p, 0.0);
|
||||
vertex++->SetTexCoord0(1.0f, 1.0f, p, 0.0);
|
||||
|
||||
vertex++->SetTexCoord0(0.0f, 0.0f, p, 0.0);
|
||||
vertex++->SetTexCoord0(1.0f, 1.0f, p, 0.0);
|
||||
vertex++->SetTexCoord0(0.0f, 1.0f, p, 0.0);
|
||||
};
|
||||
|
||||
set_bitri_texcoords(0.0f);
|
||||
|
||||
set_bitri_texcoords(0.33f);
|
||||
|
||||
set_bitri_texcoords(0.66f);
|
||||
|
||||
set_bitri_texcoords(1.0f);
|
||||
|
||||
buffer->Unlock();
|
||||
|
||||
buffer->Linearize(static_cast<float>(kTextureWidth), static_cast<float>(kTextureHeight));
|
||||
}
|
||||
|
||||
void VolumeTextureTests::Test(const TestConfig &config) {
|
||||
static constexpr uint32_t kBackgroundColor = 0xFF303030;
|
||||
void VolumeTextureTests::Test(const TextureFormatInfo &texture_format) {
|
||||
const uint32_t width = kTextureWidth;
|
||||
const uint32_t height = kTextureHeight;
|
||||
|
||||
host_.SetTextureFormat(texture_format);
|
||||
auto **layers = new SDL_Surface *[kTextureDepth];
|
||||
|
||||
for (auto d = 0; d < kTextureDepth; ++d) {
|
||||
int update_texture_result = GenerateSurface(&layers[d], (int)width, (int)height, d);
|
||||
ASSERT(!update_texture_result && "Failed to generate SDL surface");
|
||||
}
|
||||
|
||||
int update_texture_result = host_.SetVolumetricTexture((const SDL_Surface **)layers, kTextureDepth);
|
||||
ASSERT(!update_texture_result && "Failed to set texture");
|
||||
|
||||
for (auto d = 0; d < kTextureDepth; ++d) {
|
||||
SDL_FreeSurface(layers[d]);
|
||||
}
|
||||
delete[] layers;
|
||||
|
||||
auto &stage = host_.GetTextureStage(0);
|
||||
stage.SetDimensions(width, height, kTextureDepth);
|
||||
|
||||
host_.PrepareDraw(kBackgroundColor);
|
||||
host_.DrawArrays(TestHost::POSITION | TestHost::DIFFUSE | TestHost::TEXCOORD0);
|
||||
|
||||
pb_print("N: %s\n", texture_format.name);
|
||||
pb_print("F: 0x%x\n", texture_format.xbox_format);
|
||||
pb_print("SZ: %d\n", texture_format.xbox_swizzled);
|
||||
pb_print("C: %d\n", texture_format.require_conversion);
|
||||
pb_draw_text_screen();
|
||||
|
||||
host_.FinishDraw(allow_saving_, output_dir_, texture_format.name);
|
||||
}
|
||||
|
||||
void VolumeTextureTests::TestPalettized() {
|
||||
host_.PrepareDraw(kBackgroundColor);
|
||||
|
||||
TestHost::PaletteSize palette_size = TestHost::PALETTE_256;
|
||||
@ -117,16 +160,18 @@ void VolumeTextureTests::Test(const TestConfig &config) {
|
||||
host_.SetTextureFormat(texture_format);
|
||||
|
||||
uint8_t *surface = nullptr;
|
||||
uint32_t depth = 1;
|
||||
int err = GeneratePalettizedSurface(&surface, (int)host_.GetMaxTextureWidth(), (int)host_.GetMaxTextureHeight(),
|
||||
depth, palette_size);
|
||||
const uint32_t width = kTextureWidth;
|
||||
const uint32_t height = kTextureHeight;
|
||||
int err = GeneratePalettizedSurface(&surface, width, height, kTextureDepth, palette_size);
|
||||
ASSERT(!err && "Failed to generate palettized surface");
|
||||
|
||||
err = host_.SetRawTexture(surface, host_.GetMaxTextureWidth(), host_.GetMaxTextureHeight(), depth,
|
||||
host_.GetMaxTextureWidth(), 1, texture_format.xbox_swizzled);
|
||||
err = host_.SetRawTexture(surface, width, height, kTextureDepth, width, 1, texture_format.xbox_swizzled);
|
||||
delete[] surface;
|
||||
ASSERT(!err && "Failed to set texture");
|
||||
|
||||
auto stage = host_.GetTextureStage(0);
|
||||
stage.SetDimensions(width, height, kTextureDepth);
|
||||
|
||||
auto palette = GeneratePalette(palette_size);
|
||||
err = host_.SetPalette(palette, palette_size);
|
||||
delete[] palette;
|
||||
@ -134,18 +179,57 @@ void VolumeTextureTests::Test(const TestConfig &config) {
|
||||
|
||||
host_.DrawArrays();
|
||||
|
||||
// /* PrepareDraw some text on the screen */
|
||||
pb_print("N: %s\n", config.format.name);
|
||||
pb_print("F: 0x%x\n", config.format.xbox_format);
|
||||
pb_print("SZ: %d\n", config.format.xbox_swizzled);
|
||||
pb_print("C: %d\n", config.format.require_conversion);
|
||||
// pb_print("W: %d\n", host_.GetMaxTextureWidth());
|
||||
// pb_print("H: %d\n", host_.GetMaxTextureHeight());
|
||||
// pb_print("P: %d\n", texture_format.xbox_bpp * host_.GetMaxTextureWidth());
|
||||
// pb_print("ERR: %d\n", update_texture_result);
|
||||
pb_print("N: %s\n", texture_format.name);
|
||||
pb_print("F: 0x%x\n", texture_format.xbox_format);
|
||||
pb_print("SZ: %d\n", texture_format.xbox_swizzled);
|
||||
pb_print("C: %d\n", texture_format.require_conversion);
|
||||
pb_draw_text_screen();
|
||||
|
||||
host_.FinishDraw(allow_saving_, output_dir_, config.name);
|
||||
host_.FinishDraw(allow_saving_, output_dir_, texture_format.name);
|
||||
}
|
||||
|
||||
static int GenerateSurface(SDL_Surface **gradient_surface, int width, int height, int layer) {
|
||||
*gradient_surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_RGBA8888);
|
||||
if (!(*gradient_surface)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (SDL_LockSurface(*gradient_surface)) {
|
||||
SDL_FreeSurface(*gradient_surface);
|
||||
*gradient_surface = nullptr;
|
||||
return 2;
|
||||
}
|
||||
|
||||
uint32_t red_mask = 0xFF;
|
||||
uint32_t green_mask = 0xFF;
|
||||
uint32_t blue_mask = 0xFF;
|
||||
|
||||
layer %= 4;
|
||||
|
||||
if (layer == 1) {
|
||||
red_mask = 0;
|
||||
green_mask = 0;
|
||||
} else if (layer == 2) {
|
||||
green_mask = 0;
|
||||
blue_mask = 0;
|
||||
} else if (layer == 3) {
|
||||
red_mask = 0;
|
||||
blue_mask = 0;
|
||||
}
|
||||
|
||||
auto pixels = static_cast<uint32_t *>((*gradient_surface)->pixels);
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x, ++pixels) {
|
||||
int x_normal = static_cast<int>(static_cast<float>(x) * 255.0f / static_cast<float>(width));
|
||||
int y_normal = static_cast<int>(static_cast<float>(y) * 255.0f / static_cast<float>(height));
|
||||
*pixels = SDL_MapRGBA((*gradient_surface)->format, y_normal & red_mask, x_normal & green_mask,
|
||||
(255 - y_normal) & blue_mask, x_normal + y_normal);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(*gradient_surface);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GeneratePalettizedSurface(uint8_t **ret, uint32_t width, uint32_t height, uint32_t depth,
|
||||
@ -157,26 +241,27 @@ static int GeneratePalettizedSurface(uint8_t **ret, uint32_t width, uint32_t hei
|
||||
|
||||
auto pixel = *ret;
|
||||
|
||||
uint32_t layer_size = width * height;
|
||||
for (auto d = 0; d < depth; ++d) {
|
||||
uint32_t layer_size = width * height;
|
||||
|
||||
uint32_t half_size = layer_size >> 1;
|
||||
uint32_t half_size = layer_size >> 1;
|
||||
|
||||
for (uint32_t i = 0; i < half_size; ++i, ++pixel) {
|
||||
*pixel = i & (palette_size - 1);
|
||||
for (uint32_t i = 0; i < half_size; ++i, ++pixel) {
|
||||
*pixel = (d << 2) & (palette_size - 1);
|
||||
}
|
||||
|
||||
for (uint32_t i = half_size; i < layer_size; i += 4) {
|
||||
uint8_t value = (i + (d << 2)) & (palette_size - 1);
|
||||
*pixel++ = value;
|
||||
*pixel++ = value;
|
||||
*pixel++ = value;
|
||||
*pixel++ = value;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = half_size; i < layer_size; i += 4) {
|
||||
uint8_t value = i & (palette_size - 1);
|
||||
*pixel++ = value;
|
||||
*pixel++ = value;
|
||||
*pixel++ = value;
|
||||
*pixel++ = value;
|
||||
}
|
||||
|
||||
// TODO: Layer 1+.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t *GeneratePalette(TestHost::PaletteSize size) {
|
||||
auto ret = new uint32_t[size];
|
||||
|
||||
|
@ -8,14 +8,8 @@
|
||||
|
||||
class TestHost;
|
||||
|
||||
// Tests 3d texture behavior.
|
||||
class VolumeTextureTests : public TestSuite {
|
||||
public:
|
||||
struct TestConfig {
|
||||
char name[30]{0};
|
||||
TextureFormatInfo format;
|
||||
bool is_palettized{false};
|
||||
};
|
||||
|
||||
public:
|
||||
VolumeTextureTests(TestHost &host, std::string output_dir);
|
||||
|
||||
@ -23,7 +17,9 @@ class VolumeTextureTests : public TestSuite {
|
||||
|
||||
private:
|
||||
void CreateGeometry();
|
||||
void Test(const TestConfig &config);
|
||||
|
||||
void Test(const TextureFormatInfo &texture_format);
|
||||
void TestPalettized();
|
||||
};
|
||||
|
||||
#endif // NXDK_PGRAPH_TESTS_VOLUME_TEXTURE_TESTS_H
|
||||
|
@ -28,18 +28,18 @@ void TextureStage::Commit(uint32_t memory_dma_offset, uint32_t palette_dma_offse
|
||||
|
||||
auto p = pb_begin();
|
||||
|
||||
// NV097_SET_TEXTURE_CONTROL0
|
||||
p = pb_push1(p, NV20_TCL_PRIMITIVE_3D_TX_ENABLE(stage_),
|
||||
NV097_SET_TEXTURE_CONTROL0_ENABLE | NV097_SET_TEXTURE_CONTROL0_MAX_LOD_CLAMP);
|
||||
|
||||
uint32_t dimensionality = GetDimensionality();
|
||||
|
||||
uint32_t size_u = 0;
|
||||
uint32_t size_v = 0;
|
||||
uint32_t size_u = bsf((int)width_);
|
||||
uint32_t size_v = bsf((int)height_);
|
||||
uint32_t size_p = 0;
|
||||
// if (format_.xbox_swizzled) {
|
||||
size_u = bsf((int)width_);
|
||||
size_v = bsf((int)height_);
|
||||
if (dimensionality > 2) {
|
||||
size_p = bsf((int)depth_);
|
||||
}
|
||||
// }
|
||||
|
||||
const uint32_t DMA_A = 1;
|
||||
const uint32_t DMA_B = 2;
|
||||
@ -71,13 +71,12 @@ void TextureStage::Commit(uint32_t memory_dma_offset, uint32_t palette_dma_offse
|
||||
// NV097_SET_TEXTURE_ADDRESS
|
||||
p = pb_push1(p, NV20_TCL_PRIMITIVE_3D_TX_WRAP(stage_), 0x00030303);
|
||||
|
||||
// NV097_SET_TEXTURE_CONTROL0
|
||||
p = pb_push1(p, NV20_TCL_PRIMITIVE_3D_TX_ENABLE(stage_),
|
||||
NV097_SET_TEXTURE_CONTROL0_ENABLE | NV097_SET_TEXTURE_CONTROL0_MAX_LOD_CLAMP);
|
||||
|
||||
// set stage 0 texture filters (AA!)
|
||||
// NV097_SET_TEXTURE_FILTER
|
||||
p = pb_push1(p, NV20_TCL_PRIMITIVE_3D_TX_FILTER(stage_), 0x04074000);
|
||||
p = pb_push1(p, NV20_TCL_PRIMITIVE_3D_TX_FILTER(stage_), 0x1012000);
|
||||
// Note: Using 0x04074000 breaks 3d textures (the resultant buffer is 0'd out).
|
||||
|
||||
p = pb_push4(p, NV097_SET_TEXTURE_MATRIX_ENABLE, 0, 0, 0, 0);
|
||||
|
||||
uint32_t palette_config = 0;
|
||||
if (format_.xbox_format == NV097_SET_TEXTURE_FORMAT_COLOR_SZ_I8_A8R8G8B8) {
|
||||
@ -96,10 +95,11 @@ void TextureStage::Commit(uint32_t memory_dma_offset, uint32_t palette_dma_offse
|
||||
|
||||
int TextureStage::SetTexture(const SDL_Surface *surface, uint8_t *memory_base) const {
|
||||
auto pixels = static_cast<uint32_t *>(surface->pixels);
|
||||
uint8_t *dest = memory_base + texture_memory_offset_;
|
||||
|
||||
// if conversion required, do so, otherwise use SDL to convert
|
||||
if (format_.require_conversion) {
|
||||
uint8_t *dest = memory_base + texture_memory_offset_;
|
||||
|
||||
// TODO: potential reference material -
|
||||
// https://github.com/scalablecory/colors/blob/master/color.c
|
||||
switch (format_.xbox_format) {
|
||||
@ -156,21 +156,72 @@ int TextureStage::SetTexture(const SDL_Surface *surface, uint8_t *memory_base) c
|
||||
return 4;
|
||||
}
|
||||
|
||||
SetRawTexture((const uint8_t *)new_surf->pixels, new_surf->w, new_surf->h, new_surf->pitch,
|
||||
SetRawTexture((const uint8_t *)new_surf->pixels, new_surf->w, new_surf->h, 1, new_surf->pitch,
|
||||
new_surf->format->BytesPerPixel, format_.xbox_swizzled, memory_base);
|
||||
|
||||
SDL_FreeSurface(new_surf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TextureStage::SetRawTexture(const uint8_t *source, uint32_t width, uint32_t height, uint32_t pitch,
|
||||
int TextureStage::SetVolumetricTexture(const SDL_Surface **layers, uint32_t depth, uint8_t *memory_base) const {
|
||||
ASSERT(format_.xbox_swizzled && "Volumetric textures using linear formats are not supported by XBOX.")
|
||||
|
||||
auto **new_surfaces = new SDL_Surface *[depth];
|
||||
|
||||
for (auto i = 0; i < depth; ++i) {
|
||||
auto *surface = const_cast<SDL_Surface *>(layers[i]);
|
||||
new_surfaces[i] = SDL_ConvertSurfaceFormat(surface, format_.sdl_format, 0);
|
||||
|
||||
if (!new_surfaces[i]) {
|
||||
ASSERT(!"Failed to convert surface format.");
|
||||
// This will leak memory, but the ASSERT will halt execution anyway.
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
const int32_t width = new_surfaces[0]->w;
|
||||
int32_t height = new_surfaces[0]->h;
|
||||
int32_t pitch = new_surfaces[0]->pitch;
|
||||
int32_t bytes_per_pixel = new_surfaces[0]->format->BytesPerPixel;
|
||||
|
||||
uint32_t converted_surface_size = pitch * height;
|
||||
auto *flattened = new uint8_t[converted_surface_size * depth];
|
||||
uint8_t *dest = flattened;
|
||||
for (auto i = 0; i < depth; ++i) {
|
||||
SDL_Surface *s = new_surfaces[i];
|
||||
ASSERT(s->w == width && "Volumetric surface layers must have identical dimensions");
|
||||
ASSERT(s->h == height && "Volumetric surface layers must have identical dimensions");
|
||||
ASSERT(s->pitch == pitch && "Volumetric surface layers must have identical dimensions");
|
||||
ASSERT(s->format->BytesPerPixel == bytes_per_pixel && "Volumetric surface layers must have identical dimensions");
|
||||
|
||||
memcpy(dest, s->pixels, converted_surface_size);
|
||||
dest += converted_surface_size;
|
||||
}
|
||||
|
||||
for (auto i = 0; i < depth; ++i) {
|
||||
SDL_FreeSurface(new_surfaces[i]);
|
||||
}
|
||||
delete[] new_surfaces;
|
||||
|
||||
int ret = SetRawTexture(flattened, width, height, depth, pitch, bytes_per_pixel, format_.xbox_swizzled, memory_base);
|
||||
|
||||
delete[] flattened;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int TextureStage::SetRawTexture(const uint8_t *source, uint32_t width, uint32_t height, uint32_t depth, uint32_t pitch,
|
||||
uint32_t bytes_per_pixel, bool swizzle, uint8_t *memory_base) const {
|
||||
uint8_t *dest = memory_base + texture_memory_offset_;
|
||||
|
||||
if (swizzle) {
|
||||
swizzle_rect(source, width, height, dest, pitch, bytes_per_pixel);
|
||||
if (depth > 1) {
|
||||
swizzle_box(source, width, height, depth, dest, pitch, pitch * height, bytes_per_pixel);
|
||||
} else {
|
||||
swizzle_rect(source, width, height, dest, pitch, bytes_per_pixel);
|
||||
}
|
||||
} else {
|
||||
memcpy(dest, source, pitch * height);
|
||||
memcpy(dest, source, pitch * height * depth);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -39,8 +39,9 @@ class TextureStage {
|
||||
void Commit(uint32_t memory_dma_offset, uint32_t palette_dma_offset) const;
|
||||
|
||||
int SetTexture(const SDL_Surface *surface, uint8_t *memory_base) const;
|
||||
int SetRawTexture(const uint8_t *source, uint32_t width, uint32_t height, uint32_t pitch, uint32_t bytes_per_pixel,
|
||||
bool swizzle, uint8_t *memory_base) const;
|
||||
int SetVolumetricTexture(const SDL_Surface **layers, uint32_t depth, uint8_t *memory_base) const;
|
||||
int SetRawTexture(const uint8_t *source, uint32_t width, uint32_t height, uint32_t depth, uint32_t pitch,
|
||||
uint32_t bytes_per_pixel, bool swizzle, uint8_t *memory_base) const;
|
||||
|
||||
int SetPalette(const uint32_t *palette, uint32_t length, uint8_t *memory_base);
|
||||
|
||||
|
@ -91,8 +91,8 @@ typedef struct Vertex {
|
||||
inline void SetTexCoord0(const float u, const float v, const float s, const float q) {
|
||||
texcoord0[0] = u;
|
||||
texcoord0[1] = v;
|
||||
texcoord0[1] = s;
|
||||
texcoord0[1] = q;
|
||||
texcoord0[2] = s;
|
||||
texcoord0[3] = q;
|
||||
}
|
||||
|
||||
inline void SetTexCoord1(const float* value) { memcpy(texcoord1, value, sizeof(texcoord1)); }
|
||||
@ -105,8 +105,8 @@ typedef struct Vertex {
|
||||
inline void SetTexCoord1(const float u, const float v, const float s, const float q) {
|
||||
texcoord1[0] = u;
|
||||
texcoord1[1] = v;
|
||||
texcoord1[1] = s;
|
||||
texcoord1[1] = q;
|
||||
texcoord1[2] = s;
|
||||
texcoord1[3] = q;
|
||||
}
|
||||
|
||||
inline void SetTexCoord2(const float* value) { memcpy(texcoord2, value, sizeof(texcoord2)); }
|
||||
@ -119,8 +119,8 @@ typedef struct Vertex {
|
||||
inline void SetTexCoord2(const float u, const float v, const float s, const float q) {
|
||||
texcoord2[0] = u;
|
||||
texcoord2[1] = v;
|
||||
texcoord2[1] = s;
|
||||
texcoord2[1] = q;
|
||||
texcoord2[2] = s;
|
||||
texcoord2[3] = q;
|
||||
}
|
||||
|
||||
inline void SetTexCoord3(const float* value) { memcpy(texcoord3, value, sizeof(texcoord3)); }
|
||||
@ -133,8 +133,8 @@ typedef struct Vertex {
|
||||
inline void SetTexCoord3(const float u, const float v, const float s, const float q) {
|
||||
texcoord3[0] = u;
|
||||
texcoord3[1] = v;
|
||||
texcoord3[1] = s;
|
||||
texcoord3[1] = q;
|
||||
texcoord3[2] = s;
|
||||
texcoord3[3] = q;
|
||||
}
|
||||
|
||||
inline void SetDiffuseGrey(float val) { SetDiffuse(val, val, val); }
|
||||
|
2
third_party/swizzle.c
vendored
2
third_party/swizzle.c
vendored
@ -100,7 +100,7 @@ void swizzle_box(const uint8_t *src_buf, unsigned int width,
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
const uint8_t *src = src_buf + y * row_pitch + x * bytes_per_pixel;
|
||||
uint8_t *dst = dst_buf + get_swizzled_offset(x, y, 0, mask_x, mask_y, 0,
|
||||
uint8_t *dst = dst_buf + get_swizzled_offset(x, y, z, mask_x, mask_y, mask_z,
|
||||
bytes_per_pixel);
|
||||
memcpy(dst, src, bytes_per_pixel);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user