mirror of
https://github.com/xemu-project/nxdk_pgraph_tests.git
synced 2024-11-23 10:09:40 +00:00
Adds PVIDEO test.
This commit is contained in:
parent
e6a53b08d7
commit
16f961da3d
1
Makefile
1
Makefile
@ -61,6 +61,7 @@ SRCS = \
|
||||
$(SRCDIR)/tests/material_color_source_tests.cpp \
|
||||
$(SRCDIR)/tests/null_surface_tests.cpp \
|
||||
$(SRCDIR)/tests/overlapping_draw_modes_tests.cpp \
|
||||
$(SRCDIR)/tests/pvideo_tests.cpp \
|
||||
$(SRCDIR)/tests/set_vertex_data_tests.cpp \
|
||||
$(SRCDIR)/tests/shade_model_tests.cpp \
|
||||
$(SRCDIR)/tests/stencil_tests.cpp \
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "tests/material_color_tests.h"
|
||||
#include "tests/null_surface_tests.h"
|
||||
#include "tests/overlapping_draw_modes_tests.h"
|
||||
#include "tests/pvideo_tests.h"
|
||||
#include "tests/set_vertex_data_tests.h"
|
||||
#include "tests/shade_model_tests.h"
|
||||
#include "tests/stencil_tests.h"
|
||||
@ -397,6 +398,10 @@ static void register_suites(TestHost& host, std::vector<std::shared_ptr<TestSuit
|
||||
auto suite = std::make_shared<OverlappingDrawModesTests>(host, output_directory);
|
||||
test_suites.push_back(suite);
|
||||
}
|
||||
{
|
||||
auto suite = std::make_shared<PvideoTests>(host, output_directory);
|
||||
test_suites.push_back(suite);
|
||||
}
|
||||
{
|
||||
auto suite = std::make_shared<SetVertexDataTests>(host, output_directory);
|
||||
test_suites.push_back(suite);
|
||||
|
@ -207,4 +207,45 @@
|
||||
|
||||
#define NV097_SET_DOT_RGBMAPPING 0X00001E74
|
||||
|
||||
// NV_PVIDEO_INTR is already defined in outer.h
|
||||
#define NV_PVIDEO_INTR_BUFFER_0 (1 << 0)
|
||||
#define NV_PVIDEO_INTR_BUFFER_1 (1 << 4)
|
||||
#define NV_PVIDEO_INTR_EN 0x00008140
|
||||
#define NV_PVIDEO_INTR_EN_BUFFER_0 (1 << 0)
|
||||
#define NV_PVIDEO_INTR_EN_BUFFER_1 (1 << 4)
|
||||
#define NV_PVIDEO_BUFFER 0x00008700
|
||||
#define NV_PVIDEO_BUFFER_0_USE (1 << 0)
|
||||
#define NV_PVIDEO_BUFFER_1_USE (1 << 4)
|
||||
#define NV_PVIDEO_STOP 0x00008704
|
||||
#define NV_PVIDEO_BASE 0x00008900
|
||||
#define NV_PVIDEO_LIMIT 0x00008908
|
||||
#define NV_PVIDEO_LUMINANCE 0x00008910
|
||||
#define NV_PVIDEO_CHROMINANCE 0x00008918
|
||||
#define NV_PVIDEO_OFFSET 0x00008920
|
||||
#define NV_PVIDEO_SIZE_IN 0x00008928
|
||||
#define NV_PVIDEO_SIZE_IN_WIDTH 0x000007FF
|
||||
#define NV_PVIDEO_SIZE_IN_HEIGHT 0x07FF0000
|
||||
#define NV_PVIDEO_POINT_IN 0x00008930
|
||||
#define NV_PVIDEO_POINT_IN_S 0x00007FFF
|
||||
#define NV_PVIDEO_POINT_IN_T 0xFFFE0000
|
||||
#define NV_PVIDEO_DS_DX 0x00008938
|
||||
#define NV_PVIDEO_DT_DY 0x00008940
|
||||
#define NV_PVIDEO_POINT_OUT 0x00008948
|
||||
#define NV_PVIDEO_POINT_OUT_X 0x00000FFF
|
||||
#define NV_PVIDEO_POINT_OUT_Y 0x0FFF0000
|
||||
#define NV_PVIDEO_SIZE_OUT 0x00008950
|
||||
#define NV_PVIDEO_SIZE_OUT_WIDTH 0x00000FFF
|
||||
#define NV_PVIDEO_SIZE_OUT_HEIGHT 0x0FFF0000
|
||||
#define NV_PVIDEO_FORMAT 0x00008958
|
||||
#define NV_PVIDEO_FORMAT_PITCH 0x00001FFF
|
||||
#define NV_PVIDEO_FORMAT_COLOR 0x00030000
|
||||
#define NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8 1
|
||||
#define NV_PVIDEO_FORMAT_DISPLAY (1 << 20)
|
||||
#define NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY 1
|
||||
#define NV_PVIDEO_COLOR_KEY 0x00008B00
|
||||
#define NV_PVIDEO_COLOR_KEY_RED 0x00FF0000
|
||||
#define NV_PVIDEO_COLOR_KEY_GREEN 0x0000FF00
|
||||
#define NV_PVIDEO_COLOR_KEY_BLUE 0x000000FF
|
||||
#define NV_PVIDEO_COLOR_KEY_ALPHA 0xFF000000
|
||||
|
||||
#endif // NXDK_ZBUFFER_TESTS_NXDK_MISSING_DEFINES_H
|
||||
|
148
src/tests/pvideo_tests.cpp
Normal file
148
src/tests/pvideo_tests.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
#include "pvideo_tests.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "shaders/precalculated_vertex_shader.h"
|
||||
#include "texture_generator.h"
|
||||
|
||||
static constexpr const char kStopBehavior[] = "Stop";
|
||||
|
||||
PvideoTests::PvideoTests(TestHost &host, std::string output_dir) : TestSuite(host, std::move(output_dir), "PVIDEO") {
|
||||
tests_[kStopBehavior] = [this]() { TestStopBehavior(); };
|
||||
}
|
||||
|
||||
void PvideoTests::Initialize() {
|
||||
TestSuite::Initialize();
|
||||
auto shader = std::make_shared<PrecalculatedVertexShader>();
|
||||
host_.SetVertexShaderProgram(shader);
|
||||
|
||||
host_.SetFinalCombiner1Just(TestHost::SRC_ZERO, true, true);
|
||||
|
||||
video_ = (uint8_t *)MmAllocateContiguousMemory(host_.GetFramebufferWidth() * 2 * host_.GetFramebufferHeight());
|
||||
|
||||
uint32_t pitch = host_.GetFramebufferWidth() * 4;
|
||||
auto *temp = new uint8_t[pitch * host_.GetFramebufferHeight()];
|
||||
GenerateRGBACheckerboard(temp, 0, 0, host_.GetFramebufferWidth(), host_.GetFramebufferHeight(), pitch);
|
||||
SetVideoFrameCR8YB8CB8YA8(temp, host_.GetFramebufferWidth(), host_.GetFramebufferHeight());
|
||||
delete[] temp;
|
||||
}
|
||||
|
||||
void PvideoTests::Deinitialize() {
|
||||
TestSuite::Deinitialize();
|
||||
if (video_) {
|
||||
MmFreeContiguousMemory(video_);
|
||||
video_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PvideoTests::SetVideoFrameCR8YB8CB8YA8(const void *pixels, uint32_t width, uint32_t height) {
|
||||
uint8_t *dest = video_;
|
||||
auto source = reinterpret_cast<const uint32_t *>(pixels);
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; x += 2, source += 2) {
|
||||
float R0, G0, B0, R1, G1, B1;
|
||||
|
||||
R0 = static_cast<float>(source[0] & 0xFF);
|
||||
G0 = static_cast<float>((source[0] >> 8) & 0xFF);
|
||||
B0 = static_cast<float>((source[0] >> 16) & 0xFF);
|
||||
|
||||
R1 = static_cast<float>(source[1] & 0xFF);
|
||||
G1 = static_cast<float>((source[1] >> 8) & 0xFF);
|
||||
B1 = static_cast<float>((source[1] >> 16) & 0xFF);
|
||||
|
||||
dest[0] = static_cast<uint8_t>((0.257f * R0) + (0.504f * G0) + (0.098f * B0) + 16); // Y0
|
||||
dest[1] = static_cast<uint8_t>(-(0.148f * R1) - (0.291f * G1) + (0.439f * B1) + 128); // U
|
||||
dest[2] = static_cast<uint8_t>((0.257f * R1) + (0.504f * G1) + (0.098f * B1) + 16); // Y1
|
||||
dest[3] = static_cast<uint8_t>((0.439f * R1) - (0.368f * G1) - (0.071f * B1) + 128); // V
|
||||
dest += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ClearPvideoInterrupts() { VIDEOREG(NV_PVIDEO_INTR) = 0x00000011; }
|
||||
|
||||
static void SetPvideoInterruptEnabled(bool enable_zero, bool enable_one) {
|
||||
uint32_t val = SET_MASK(NV_PVIDEO_INTR_EN_BUFFER_0, enable_zero) | SET_MASK(NV_PVIDEO_INTR_EN_BUFFER_1, enable_one);
|
||||
VIDEOREG(NV_PVIDEO_INTR_EN) = val;
|
||||
}
|
||||
|
||||
static void SetPvideoBuffer(bool enable_zero, bool enable_one) {
|
||||
uint32_t val = SET_MASK(NV_PVIDEO_BUFFER_0_USE, enable_zero) | SET_MASK(NV_PVIDEO_BUFFER_1_USE, enable_one);
|
||||
VIDEOREG(NV_PVIDEO_BUFFER) = val;
|
||||
}
|
||||
|
||||
static void SetPvideoStop(uint32_t value = 0) { VIDEOREG(NV_PVIDEO_STOP) = value; }
|
||||
|
||||
static void SetPvideoBase(uint32_t addr) { VIDEOREG(NV_PVIDEO_BASE) = addr; }
|
||||
|
||||
static void SetPvideoLimit(uint32_t limit) { VIDEOREG(NV_PVIDEO_LIMIT) = limit; }
|
||||
|
||||
static void SetPvideoOffset(uint32_t offset) { VIDEOREG(NV_PVIDEO_OFFSET) = offset; }
|
||||
|
||||
static void SetPvideoIn(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
VIDEOREG(NV_PVIDEO_POINT_IN) = SET_MASK(NV_PVIDEO_POINT_IN_S, x) | SET_MASK(NV_PVIDEO_POINT_IN_T, y);
|
||||
VIDEOREG(NV_PVIDEO_SIZE_IN) = SET_MASK(NV_PVIDEO_SIZE_IN_WIDTH, width) | SET_MASK(NV_PVIDEO_SIZE_IN_HEIGHT, height);
|
||||
}
|
||||
|
||||
static void SetPvideoOut(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
VIDEOREG(NV_PVIDEO_POINT_OUT) = SET_MASK(NV_PVIDEO_POINT_OUT_X, x) | SET_MASK(NV_PVIDEO_POINT_OUT_Y, y);
|
||||
VIDEOREG(NV_PVIDEO_SIZE_OUT) =
|
||||
SET_MASK(NV_PVIDEO_SIZE_OUT_WIDTH, width) | SET_MASK(NV_PVIDEO_SIZE_OUT_HEIGHT, height);
|
||||
}
|
||||
|
||||
static void SetPvideoFormat(uint32_t format, uint32_t pitch, bool color_keyed) {
|
||||
VIDEOREG(NV_PVIDEO_FORMAT) = SET_MASK(NV_PVIDEO_FORMAT_PITCH, pitch) | SET_MASK(NV_PVIDEO_FORMAT_COLOR, format) |
|
||||
SET_MASK(NV_PVIDEO_FORMAT_DISPLAY, color_keyed);
|
||||
}
|
||||
|
||||
static void SetPvideoColorKey(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
||||
VIDEOREG(NV_PVIDEO_COLOR_KEY) = SET_MASK(NV_PVIDEO_COLOR_KEY_RED, r) | SET_MASK(NV_PVIDEO_COLOR_KEY_GREEN, g) |
|
||||
SET_MASK(NV_PVIDEO_COLOR_KEY_BLUE, b) | SET_MASK(NV_PVIDEO_COLOR_KEY_ALPHA, a);
|
||||
}
|
||||
|
||||
static void SetPvideoLuminanceChrominance() {
|
||||
VIDEOREG(NV_PVIDEO_LUMINANCE) = 0x00001000;
|
||||
VIDEOREG(NV_PVIDEO_CHROMINANCE) = 0x00001000;
|
||||
}
|
||||
|
||||
void PvideoTests::TestStopBehavior() {
|
||||
host_.PrepareDraw(0xFF250535);
|
||||
|
||||
uint32_t pitch = host_.GetFramebufferWidth() * 2;
|
||||
|
||||
ClearPvideoInterrupts();
|
||||
|
||||
// Seen in Dragon Ball Z Saga, has no observable effect.
|
||||
// VIDEOREG(NV_PVIDEO_SIZE_IN) = 0xFFFFFFFF;
|
||||
|
||||
VIDEOREG(NV_PVIDEO_POINT_IN) = 0;
|
||||
|
||||
SetPvideoBase(VRAM_ADDR(video_));
|
||||
uint32_t end = VRAM_ADDR(video_) + pitch * host_.GetFramebufferHeight();
|
||||
SetPvideoLimit(end);
|
||||
SetPvideoOffset(0);
|
||||
|
||||
// TODO: See if it's necessary to set these.
|
||||
SetPvideoLuminanceChrominance();
|
||||
|
||||
for (uint32_t i = 0; i < 10; ++i) {
|
||||
SetPvideoStop();
|
||||
SetPvideoColorKey(0, 0, 0, 0);
|
||||
// SetPvideoOffset(0);
|
||||
// SetPvideoOffset(VRAM_ADDR(video_));
|
||||
SetPvideoIn(0, 0, host_.GetFramebufferWidth(), host_.GetFramebufferHeight());
|
||||
VIDEOREG(NV_PVIDEO_DS_DX) = 0x00100000;
|
||||
VIDEOREG(NV_PVIDEO_DT_DY) = 0x00100000;
|
||||
SetPvideoOut(0, 0, host_.GetFramebufferWidth(), host_.GetFramebufferHeight());
|
||||
SetPvideoFormat(NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8, pitch, false);
|
||||
SetPvideoInterruptEnabled(true, false);
|
||||
SetPvideoBuffer(true, false);
|
||||
}
|
||||
|
||||
// This is the key value, if stop is set to 1, the PVIDEO overlay is torn down completely. If it is not, it stays up
|
||||
// in spite of being stopped.
|
||||
SetPvideoStop(1);
|
||||
SetPvideoBuffer(false, false);
|
||||
|
||||
host_.FinishDraw(false, output_dir_, kStopBehavior);
|
||||
}
|
21
src/tests/pvideo_tests.h
Normal file
21
src/tests/pvideo_tests.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "test_host.h"
|
||||
#include "test_suite.h"
|
||||
|
||||
class PvideoTests : public TestSuite {
|
||||
public:
|
||||
PvideoTests(TestHost &host, std::string output_dir);
|
||||
void Initialize() override;
|
||||
void Deinitialize() override;
|
||||
|
||||
private:
|
||||
void TestStopBehavior();
|
||||
void SetVideoFrameCR8YB8CB8YA8(const void *pixels, uint32_t width, uint32_t height);
|
||||
|
||||
private:
|
||||
uint8_t *video_{nullptr};
|
||||
};
|
Loading…
Reference in New Issue
Block a user