mirror of
https://github.com/xemu-project/nxdk_pgraph_tests.git
synced 2024-11-26 19:40:45 +00:00
Adds test for DMA corruption due to pgraph dirty surface callback. (#97)
This commit is contained in:
parent
1fa684b5ec
commit
ac827c9de3
1
Makefile
1
Makefile
@ -51,6 +51,7 @@ SRCS = \
|
||||
$(SRCDIR)/tests/combiner_tests.cpp \
|
||||
$(SRCDIR)/tests/depth_format_fixed_function_tests.cpp \
|
||||
$(SRCDIR)/tests/depth_format_tests.cpp \
|
||||
$(SRCDIR)/tests/dma_corruption_around_surface_tests.cpp \
|
||||
$(SRCDIR)/tests/fog_tests.cpp \
|
||||
$(SRCDIR)/tests/front_face_tests.cpp \
|
||||
$(SRCDIR)/tests/image_blit_tests.cpp \
|
||||
|
21
src/main.cpp
21
src/main.cpp
@ -34,6 +34,7 @@
|
||||
#include "tests/combiner_tests.h"
|
||||
#include "tests/depth_format_fixed_function_tests.h"
|
||||
#include "tests/depth_format_tests.h"
|
||||
#include "tests/dma_corruption_around_surface_tests.h"
|
||||
#include "tests/fog_tests.h"
|
||||
#include "tests/front_face_tests.h"
|
||||
#include "tests/image_blit_tests.h"
|
||||
@ -458,6 +459,18 @@ static void register_suites(TestHost& host, std::vector<std::shared_ptr<TestSuit
|
||||
auto suite = std::make_shared<CombinerTests>(host, output_directory);
|
||||
test_suites.push_back(suite);
|
||||
}
|
||||
{
|
||||
auto suite = std::make_shared<DepthFormatTests>(host, output_directory);
|
||||
test_suites.push_back(suite);
|
||||
}
|
||||
{
|
||||
auto suite = std::make_shared<DepthFormatFixedFunctionTests>(host, output_directory);
|
||||
test_suites.push_back(suite);
|
||||
}
|
||||
{
|
||||
auto suite = std::make_shared<DMACorruptionAroundSurfaceTests>(host, output_directory);
|
||||
test_suites.push_back(suite);
|
||||
}
|
||||
{
|
||||
auto suite = std::make_shared<FogTests>(host, output_directory);
|
||||
test_suites.push_back(suite);
|
||||
@ -478,14 +491,6 @@ static void register_suites(TestHost& host, std::vector<std::shared_ptr<TestSuit
|
||||
auto suite = std::make_shared<FrontFaceTests>(host, output_directory);
|
||||
test_suites.push_back(suite);
|
||||
}
|
||||
{
|
||||
auto suite = std::make_shared<DepthFormatTests>(host, output_directory);
|
||||
test_suites.push_back(suite);
|
||||
}
|
||||
{
|
||||
auto suite = std::make_shared<DepthFormatFixedFunctionTests>(host, output_directory);
|
||||
test_suites.push_back(suite);
|
||||
}
|
||||
{
|
||||
auto suite = std::make_shared<ImageBlitTests>(host, output_directory);
|
||||
test_suites.push_back(suite);
|
||||
|
147
src/tests/dma_corruption_around_surface_tests.cpp
Normal file
147
src/tests/dma_corruption_around_surface_tests.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
#include "dma_corruption_around_surface_tests.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <pbkit/pbkit.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "debug_output.h"
|
||||
#include "pbkit_ext.h"
|
||||
#include "shaders/precalculated_vertex_shader.h"
|
||||
#include "test_host.h"
|
||||
#include "texture_generator.h"
|
||||
|
||||
#define SET_MASK(mask, val) (((val) << (__builtin_ffs(mask) - 1)) & (mask))
|
||||
|
||||
#define NV2A_MMIO_BASE 0xFD000000
|
||||
#define BLOCKPGRAPH_ADDR 0x400000
|
||||
#define PGRAPH_ADDR(a) (NV2A_MMIO_BASE + BLOCKPGRAPH_ADDR + (a))
|
||||
|
||||
// From pbkit.c, DMA_A is set to channel 3 by default
|
||||
// NV097_SET_CONTEXT_DMA_A == NV20_TCL_PRIMITIVE_3D_SET_OBJECT1
|
||||
static constexpr uint32_t kDefaultDMAChannelA = 3;
|
||||
// From pbkit.c, DMA_COLOR is set to channel 9 by default.
|
||||
// NV097_SET_CONTEXT_DMA_COLOR == NV20_TCL_PRIMITIVE_3D_SET_OBJECT3
|
||||
static constexpr uint32_t kDefaultDMAColorChannel = 9;
|
||||
|
||||
static constexpr char kTestName[] = "DMAOverlap";
|
||||
static constexpr uint32_t kTextureSize = 128;
|
||||
|
||||
static constexpr uint32_t kCheckerSize = 8;
|
||||
static constexpr uint32_t kCheckerboardA = 0xFF808080;
|
||||
static constexpr uint32_t kCheckerboardB = 0xFF3333C0;
|
||||
|
||||
DMACorruptionAroundSurfaceTests::DMACorruptionAroundSurfaceTests(TestHost &host, std::string output_dir)
|
||||
: TestSuite(host, std::move(output_dir), "DMA corruption around surfaces") {
|
||||
tests_[kTestName] = [this]() { Test(); };
|
||||
}
|
||||
|
||||
void DMACorruptionAroundSurfaceTests::Initialize() {
|
||||
TestSuite::Initialize();
|
||||
auto shader = std::make_shared<PrecalculatedVertexShader>();
|
||||
host_.SetVertexShaderProgram(shader);
|
||||
}
|
||||
|
||||
void DMACorruptionAroundSurfaceTests::Test() {
|
||||
host_.PrepareDraw(0xFF050505);
|
||||
|
||||
const uint32_t kRenderBufferPitch = kTextureSize * 4;
|
||||
const auto kHalfTextureSize = kRenderBufferPitch * (kTextureSize >> 1);
|
||||
|
||||
// Configure a surface pointing at texture memory and do a no-op draw to force xemu to create a SurfaceBinding.
|
||||
{
|
||||
const auto kTextureMemory = reinterpret_cast<uint32_t>(host_.GetTextureMemoryForStage(0));
|
||||
auto p = pb_begin();
|
||||
p = pb_push1(p, NV097_SET_SURFACE_PITCH,
|
||||
SET_MASK(NV097_SET_SURFACE_PITCH_COLOR, kRenderBufferPitch) |
|
||||
SET_MASK(NV097_SET_SURFACE_PITCH_ZETA, kRenderBufferPitch));
|
||||
p = pb_push1(p, NV097_SET_CONTEXT_DMA_COLOR, kDefaultDMAChannelA);
|
||||
p = pb_push1(p, NV097_SET_SURFACE_COLOR_OFFSET, VRAM_ADDR(kTextureMemory + kHalfTextureSize));
|
||||
pb_end(p);
|
||||
|
||||
host_.SetSurfaceFormatImmediate(TestHost::SCF_A8R8G8B8, TestHost::SZF_Z16, kTextureSize, kTextureSize);
|
||||
NoOpDraw();
|
||||
}
|
||||
|
||||
// Do a CPU copy to texture memory
|
||||
WaitForGPU();
|
||||
GenerateRGBACheckerboard(host_.GetTextureMemoryForStage(0), 0, 0, kTextureSize, kTextureSize, kRenderBufferPitch,
|
||||
0xFFCC3333, kCheckerboardB, kCheckerSize);
|
||||
|
||||
// Point the output surface back at the framebuffer.
|
||||
{
|
||||
const uint32_t kFramebufferPitch = host_.GetFramebufferWidth() * 4;
|
||||
auto p = pb_begin();
|
||||
p = pb_push1(p, NV097_SET_CONTEXT_DMA_COLOR, kDefaultDMAColorChannel);
|
||||
p = pb_push1(p, NV097_SET_SURFACE_COLOR_OFFSET, 0);
|
||||
p = pb_push1(p, NV097_SET_SURFACE_PITCH,
|
||||
SET_MASK(NV097_SET_SURFACE_PITCH_COLOR, kFramebufferPitch) |
|
||||
SET_MASK(NV097_SET_SURFACE_PITCH_ZETA, kFramebufferPitch));
|
||||
pb_end(p);
|
||||
}
|
||||
|
||||
// Restore the surface format to allow the texture to be rendered.
|
||||
host_.SetSurfaceFormatImmediate(TestHost::SCF_A8R8G8B8, TestHost::SZF_Z16, host_.GetFramebufferWidth(),
|
||||
host_.GetFramebufferHeight());
|
||||
|
||||
// Draw a quad with the texture.
|
||||
Draw();
|
||||
|
||||
pb_print("%s\n", kTestName);
|
||||
pb_draw_text_screen();
|
||||
|
||||
host_.FinishDraw(allow_saving_, output_dir_, kTestName);
|
||||
}
|
||||
|
||||
void DMACorruptionAroundSurfaceTests::Draw() const {
|
||||
host_.SetFinalCombiner0Just(TestHost::SRC_TEX0);
|
||||
host_.SetFinalCombiner1Just(TestHost::SRC_ZERO, true, true);
|
||||
host_.SetTextureStageEnabled(0, true);
|
||||
host_.SetShaderStageProgram(TestHost::STAGE_2D_PROJECTIVE);
|
||||
|
||||
auto &texture_stage = host_.GetTextureStage(0);
|
||||
texture_stage.SetFormat(GetTextureFormatInfo(NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8R8G8B8));
|
||||
texture_stage.SetImageDimensions(kTextureSize, kTextureSize);
|
||||
host_.SetupTextureStages();
|
||||
|
||||
static constexpr float inset = 64.0f;
|
||||
const float left = inset;
|
||||
const float right = host_.GetFramebufferWidthF() - inset;
|
||||
const float top = inset;
|
||||
const float bottom = host_.GetFramebufferHeightF() - inset;
|
||||
const float mid_x = left + (right - left) * 0.5f;
|
||||
const float mid_y = top + (bottom - top) * 0.5f;
|
||||
|
||||
host_.Begin(TestHost::PRIMITIVE_QUADS);
|
||||
host_.SetTexCoord0(0.0f, 0.0f);
|
||||
host_.SetVertex(left, mid_y, 0.1f, 1.0f);
|
||||
|
||||
host_.SetTexCoord0(kTextureSize, 0.0f);
|
||||
host_.SetVertex(mid_x, top, 0.1f, 1.0f);
|
||||
|
||||
host_.SetTexCoord0(kTextureSize, kTextureSize);
|
||||
host_.SetVertex(right, mid_y, 0.1f, 1.0f);
|
||||
|
||||
host_.SetTexCoord0(0.0f, kTextureSize);
|
||||
host_.SetVertex(mid_x, bottom, 0.1f, 1.0f);
|
||||
host_.End();
|
||||
|
||||
host_.SetTextureStageEnabled(0, false);
|
||||
host_.SetShaderStageProgram(TestHost::STAGE_NONE);
|
||||
}
|
||||
|
||||
void DMACorruptionAroundSurfaceTests::NoOpDraw() const {
|
||||
host_.Begin(TestHost::PRIMITIVE_TRIANGLES);
|
||||
host_.SetVertex(0.0f, 0.0f, 0.1f, 1.0f);
|
||||
host_.SetVertex(0.0f, 0.0f, 0.1f, 1.0f);
|
||||
host_.SetVertex(0.0f, 0.0f, 0.1f, 1.0f);
|
||||
host_.End();
|
||||
}
|
||||
|
||||
void DMACorruptionAroundSurfaceTests::WaitForGPU() const {
|
||||
auto p = pb_begin();
|
||||
p = pb_push1(p, NV097_NO_OPERATION, 0);
|
||||
p = pb_push1(p, NV097_WAIT_FOR_IDLE, 0);
|
||||
pb_end(p);
|
||||
}
|
26
src/tests/dma_corruption_around_surface_tests.h
Normal file
26
src/tests/dma_corruption_around_surface_tests.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef NXDK_PGRAPH_TESTS_DMA_CORRUPTION_AROUND_SURFACE_TESTS_H
|
||||
#define NXDK_PGRAPH_TESTS_DMA_CORRUPTION_AROUND_SURFACE_TESTS_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "test_host.h"
|
||||
#include "test_suite.h"
|
||||
|
||||
struct TextureFormatInfo;
|
||||
class VertexBuffer;
|
||||
|
||||
class DMACorruptionAroundSurfaceTests : public TestSuite {
|
||||
public:
|
||||
DMACorruptionAroundSurfaceTests(TestHost &host, std::string output_dir);
|
||||
void Initialize() override;
|
||||
|
||||
private:
|
||||
void Test();
|
||||
|
||||
void Draw() const;
|
||||
void NoOpDraw() const;
|
||||
void WaitForGPU() const;
|
||||
};
|
||||
|
||||
#endif // NXDK_PGRAPH_TESTS_DMA_CORRUPTION_AROUND_SURFACE_TESTS_H
|
Loading…
Reference in New Issue
Block a user