mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 10:54:16 +01:00
[tests] Remove D3D9 tests
This commit is contained in:
parent
632e26f687
commit
a11fb568b9
@ -135,9 +135,3 @@ dxvk_version = vcs_tag(
|
||||
)
|
||||
|
||||
subdir('src')
|
||||
|
||||
enable_tests = get_option('enable_tests')
|
||||
|
||||
if enable_tests
|
||||
subdir('tests')
|
||||
endif
|
||||
|
@ -1,4 +1,3 @@
|
||||
option('enable_tests', type : 'boolean', value : false)
|
||||
option('enable_dxgi', type : 'boolean', value : true, description: 'Build DXGI')
|
||||
option('enable_d3d9', type : 'boolean', value : true, description: 'Build D3D9')
|
||||
option('enable_d3d10', type : 'boolean', value : true, description: 'Build D3D10')
|
||||
|
@ -63,7 +63,6 @@ function build_arch {
|
||||
$opt_strip \
|
||||
--bindir "x$1" \
|
||||
--libdir "x$1" \
|
||||
-Denable_tests=false \
|
||||
-Dbuild_id=$opt_buildid \
|
||||
"$DXVK_BUILD_DIR/build.$1"
|
||||
|
||||
|
@ -11,7 +11,7 @@ if get_option('enable_dxgi')
|
||||
subdir('dxgi')
|
||||
endif
|
||||
|
||||
if get_option('enable_d3d10') or get_option('enable_d3d11') or get_option('enable_tests')
|
||||
if get_option('enable_d3d10') or get_option('enable_d3d11')
|
||||
subdir('dxbc')
|
||||
endif
|
||||
|
||||
@ -36,6 +36,6 @@ if get_option('enable_d3d9')
|
||||
endif
|
||||
|
||||
# Nothing selected
|
||||
if not get_option('enable_d3d9') and not get_option('enable_d3d10') and not get_option('enable_d3d11') and not get_option('enable_tests')
|
||||
warning('Nothing selected to be built. Are you missing a frontend or tests?')
|
||||
if not get_option('enable_d3d9') and not get_option('enable_d3d10') and not get_option('enable_d3d11')
|
||||
warning('Nothing selected to be built.?')
|
||||
endif
|
||||
|
@ -1,9 +0,0 @@
|
||||
test_d3d9_deps = [ util_dep, lib_d3d9, lib_d3dcompiler_47 ]
|
||||
|
||||
executable('d3d9-clear'+exe_ext, files('test_d3d9_clear.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true)
|
||||
executable('d3d9-buffer'+exe_ext, files('test_d3d9_buffer.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true)
|
||||
executable('d3d9-triangle'+exe_ext, files('test_d3d9_triangle.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true)
|
||||
executable('d3d9-l6v5u5'+exe_ext, files('test_d3d9_l6v5u5.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true)
|
||||
executable('d3d9-nv12'+exe_ext, files('test_d3d9_nv12.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true)
|
||||
executable('d3d9-bc-update-surface'+exe_ext, files('test_d3d9_bc_update_surface.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true)
|
||||
executable('d3d9-up'+exe_ext, files('test_d3d9_up.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true)
|
@ -1,362 +0,0 @@
|
||||
#include <cstring>
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
struct Extent2D {
|
||||
uint32_t w, h;
|
||||
};
|
||||
|
||||
const std::string g_vertexShaderCode = R"(
|
||||
|
||||
struct VS_INPUT {
|
||||
float3 Position : POSITION;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 Position : POSITION;
|
||||
float2 Texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
VS_OUTPUT main( VS_INPUT IN ) {
|
||||
VS_OUTPUT OUT;
|
||||
OUT.Position = float4(IN.Position, 0.6f);
|
||||
OUT.Texcoord = IN.Position.xy + float2(0.5, 0.5);
|
||||
OUT.Texcoord.y = 1.0 - OUT.Texcoord.y;
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
)";
|
||||
|
||||
const std::string g_pixelShaderCode = R"(
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 Position : POSITION;
|
||||
float2 Texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PS_OUTPUT {
|
||||
float4 Colour : COLOR;
|
||||
};
|
||||
|
||||
sampler g_frogTex : register( s0 );
|
||||
|
||||
PS_OUTPUT main( VS_OUTPUT IN ) {
|
||||
PS_OUTPUT OUT;
|
||||
|
||||
OUT.Colour = float4(1, 0, 0, 1);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
|
||||
)";
|
||||
|
||||
Logger Logger::s_instance("triangle.log");
|
||||
|
||||
class TriangleApp {
|
||||
|
||||
public:
|
||||
|
||||
TriangleApp(HINSTANCE instance, HWND window)
|
||||
: m_window(window) {
|
||||
HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 interface");
|
||||
|
||||
UINT adapter = D3DADAPTER_DEFAULT;
|
||||
|
||||
D3DADAPTER_IDENTIFIER9 adapterId;
|
||||
m_d3d->GetAdapterIdentifier(adapter, 0, &adapterId);
|
||||
|
||||
Logger::info(str::format("Using adapter: ", adapterId.Description));
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
|
||||
status = m_d3d->CreateDeviceEx(
|
||||
adapter,
|
||||
D3DDEVTYPE_HAL,
|
||||
m_window,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
¶ms,
|
||||
nullptr,
|
||||
&m_device);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 device");
|
||||
|
||||
|
||||
// Vertex Shader
|
||||
{
|
||||
Com<ID3DBlob> blob;
|
||||
|
||||
status = D3DCompile(
|
||||
g_vertexShaderCode.data(),
|
||||
g_vertexShaderCode.length(),
|
||||
nullptr, nullptr, nullptr,
|
||||
"main",
|
||||
"vs_2_0",
|
||||
0, 0, &blob,
|
||||
nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to compile vertex shader");
|
||||
|
||||
status = m_device->CreateVertexShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_vs);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create vertex shader");
|
||||
}
|
||||
|
||||
// Pixel Shader
|
||||
{
|
||||
Com<ID3DBlob> blob;
|
||||
|
||||
status = D3DCompile(
|
||||
g_pixelShaderCode.data(),
|
||||
g_pixelShaderCode.length(),
|
||||
nullptr, nullptr, nullptr,
|
||||
"main",
|
||||
"ps_3_0",
|
||||
0, 0, &blob,
|
||||
nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to compile pixel shader");
|
||||
|
||||
status = m_device->CreatePixelShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_ps);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create pixel shader");
|
||||
}
|
||||
|
||||
m_device->SetVertexShader(m_vs.ptr());
|
||||
m_device->SetPixelShader(m_ps.ptr());
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
|
||||
std::array<float, 9> vertices = {
|
||||
0.0f, 0.5f, 0.0f,
|
||||
0.5f, -0.5f, 0.0f,
|
||||
-0.5f, -0.5f, 0.0f,
|
||||
};
|
||||
|
||||
const size_t vbSize = vertices.size() * sizeof(float);
|
||||
|
||||
status = m_device->CreateVertexBuffer(vbSize, 0, 0, D3DPOOL_DEFAULT, &m_vb, nullptr);
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create vertex buffer");
|
||||
|
||||
void* data = nullptr;
|
||||
status = m_vb->Lock(0, 0, &data, 0);
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to lock vertex buffer");
|
||||
|
||||
std::memcpy(data, vertices.data(), vbSize);
|
||||
|
||||
status = m_vb->Unlock();
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to unlock vertex buffer");
|
||||
|
||||
m_device->SetStreamSource(0, m_vb.ptr(), 0, 3 * sizeof(float));
|
||||
|
||||
std::array<D3DVERTEXELEMENT9, 2> elements;
|
||||
|
||||
elements[0].Method = 0;
|
||||
elements[0].Offset = 0;
|
||||
elements[0].Stream = 0;
|
||||
elements[0].Type = D3DDECLTYPE_FLOAT3;
|
||||
elements[0].Usage = D3DDECLUSAGE_POSITION;
|
||||
elements[0].UsageIndex = 0;
|
||||
|
||||
elements[1] = D3DDECL_END();
|
||||
|
||||
HRESULT result = m_device->CreateVertexDeclaration(elements.data(), &m_decl);
|
||||
if (FAILED(result))
|
||||
throw DxvkError("Failed to create vertex decl");
|
||||
|
||||
m_device->SetVertexDeclaration(m_decl.ptr());
|
||||
|
||||
const uint32_t imageSize = 8;
|
||||
|
||||
Com<IDirect3DTexture9> texDefault;
|
||||
Com<IDirect3DSurface9> texDefaultSurf;
|
||||
status = m_device->CreateTexture(imageSize, imageSize, 4, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &texDefault, nullptr);
|
||||
status = texDefault->GetSurfaceLevel(2, &texDefaultSurf);
|
||||
|
||||
Com<IDirect3DTexture9> texSysmem;
|
||||
Com<IDirect3DSurface9> texSysmemSurf;
|
||||
status = m_device->CreateTexture(imageSize, imageSize, 4, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &texSysmem, nullptr);
|
||||
status = texSysmem->GetSurfaceLevel(2, &texSysmemSurf);
|
||||
|
||||
D3DLOCKED_RECT rect = {};
|
||||
status = texSysmemSurf->LockRect(&rect, nullptr, 0);
|
||||
std::memset(rect.pBits, 0xF0, 2 * rect.Pitch);
|
||||
status = texSysmemSurf->UnlockRect();
|
||||
|
||||
// 1 returns invalid call
|
||||
// 2 succeeds
|
||||
RECT sourceRect = { 0, 0, 2, 2 };
|
||||
POINT destPoint = { 0, 0 };
|
||||
status = m_device->UpdateSurface(texSysmemSurf.ptr(), &sourceRect, texDefaultSurf.ptr(), &destPoint);
|
||||
}
|
||||
|
||||
void run() {
|
||||
this->adjustBackBuffer();
|
||||
|
||||
m_device->BeginScene();
|
||||
|
||||
m_device->Clear(
|
||||
0,
|
||||
nullptr,
|
||||
D3DCLEAR_TARGET,
|
||||
D3DCOLOR_RGBA(44, 62, 80, 0),
|
||||
0,
|
||||
0);
|
||||
|
||||
m_device->Clear(
|
||||
0,
|
||||
nullptr,
|
||||
D3DCLEAR_ZBUFFER,
|
||||
0,
|
||||
0.5f,
|
||||
0);
|
||||
|
||||
m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
|
||||
|
||||
m_device->EndScene();
|
||||
|
||||
m_device->PresentEx(
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0);
|
||||
}
|
||||
|
||||
void adjustBackBuffer() {
|
||||
RECT windowRect = { 0, 0, 1024, 600 };
|
||||
GetClientRect(m_window, &windowRect);
|
||||
|
||||
Extent2D newSize = {
|
||||
static_cast<uint32_t>(windowRect.right - windowRect.left),
|
||||
static_cast<uint32_t>(windowRect.bottom - windowRect.top),
|
||||
};
|
||||
|
||||
if (m_windowSize.w != newSize.w
|
||||
|| m_windowSize.h != newSize.h) {
|
||||
m_windowSize = newSize;
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
HRESULT status = m_device->ResetEx(¶ms, nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Device reset failed");
|
||||
}
|
||||
}
|
||||
|
||||
void getPresentParams(D3DPRESENT_PARAMETERS& params) {
|
||||
params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
params.BackBufferCount = 1;
|
||||
params.BackBufferFormat = D3DFMT_X8R8G8B8;
|
||||
params.BackBufferWidth = m_windowSize.w;
|
||||
params.BackBufferHeight = m_windowSize.h;
|
||||
params.EnableAutoDepthStencil = 0;
|
||||
params.Flags = 0;
|
||||
params.FullScreen_RefreshRateInHz = 0;
|
||||
params.hDeviceWindow = m_window;
|
||||
params.MultiSampleQuality = 0;
|
||||
params.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
params.Windowed = TRUE;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
HWND m_window;
|
||||
Extent2D m_windowSize = { 1024, 600 };
|
||||
|
||||
Com<IDirect3D9Ex> m_d3d;
|
||||
Com<IDirect3DDevice9Ex> m_device;
|
||||
|
||||
Com<IDirect3DVertexShader9> m_vs;
|
||||
Com<IDirect3DPixelShader9> m_ps;
|
||||
Com<IDirect3DVertexBuffer9> m_vb;
|
||||
Com<IDirect3DVertexDeclaration9> m_decl;
|
||||
|
||||
};
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
HWND hWnd;
|
||||
WNDCLASSEXW wc;
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSEX));
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
wc.lpszClassName = L"WindowClass1";
|
||||
RegisterClassExW(&wc);
|
||||
|
||||
hWnd = CreateWindowExW(0,
|
||||
L"WindowClass1",
|
||||
L"Our First Windowed Program",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
300, 300,
|
||||
640, 480,
|
||||
nullptr,
|
||||
nullptr,
|
||||
hInstance,
|
||||
nullptr);
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
|
||||
MSG msg;
|
||||
|
||||
try {
|
||||
TriangleApp app(hInstance, hWnd);
|
||||
|
||||
while (true) {
|
||||
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
return msg.wParam;
|
||||
} else {
|
||||
app.run();
|
||||
}
|
||||
}
|
||||
} catch (const dxvk::DxvkError& e) {
|
||||
std::cerr << e.message() << std::endl;
|
||||
return msg.wParam;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
@ -1,220 +0,0 @@
|
||||
#include <cstring>
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
struct Extent2D {
|
||||
uint32_t w, h;
|
||||
};
|
||||
|
||||
DWORD g_UsagePermuatations[] = {
|
||||
0,
|
||||
D3DUSAGE_DYNAMIC,
|
||||
D3DUSAGE_WRITEONLY,
|
||||
D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC,
|
||||
};
|
||||
|
||||
DWORD g_MapFlagPermutations[] = {
|
||||
0,
|
||||
D3DLOCK_DISCARD,
|
||||
D3DLOCK_DONOTWAIT,
|
||||
D3DLOCK_NOOVERWRITE
|
||||
};
|
||||
|
||||
class BufferApp {
|
||||
|
||||
public:
|
||||
|
||||
BufferApp(HINSTANCE instance, HWND window)
|
||||
: m_window(window) {
|
||||
HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 interface");
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
|
||||
status = m_d3d->CreateDeviceEx(
|
||||
D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
m_window,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
¶ms,
|
||||
nullptr,
|
||||
&m_device);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 device");
|
||||
|
||||
uint8_t* data = new uint8_t[512];
|
||||
std::memset(data, 0xFC, 512);
|
||||
|
||||
for (uint32_t i = 0; i < ARRAYSIZE(g_UsagePermuatations); i++) {
|
||||
for (uint32_t j = 0; j < ARRAYSIZE(g_MapFlagPermutations); j++) {
|
||||
testBuffer(data, g_UsagePermuatations[i], g_MapFlagPermutations[j]);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void testBuffer(uint8_t* data, DWORD usage, DWORD mapFlags) {
|
||||
Com<IDirect3DVertexBuffer9> buffer;
|
||||
HRESULT status = m_device->CreateVertexBuffer(512, usage, 0, D3DPOOL_DEFAULT, &buffer, nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create buffer");
|
||||
|
||||
void* bufferMem = nullptr;
|
||||
status = buffer->Lock(0, 0, &bufferMem, mapFlags);
|
||||
|
||||
if (FAILED(status) || bufferMem == nullptr)
|
||||
throw DxvkError("Failed to lock buffer");
|
||||
|
||||
std::memcpy(bufferMem, data, 512);
|
||||
|
||||
status = buffer->Unlock();
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to unlock buffer");
|
||||
}
|
||||
|
||||
void run() {
|
||||
this->adjustBackBuffer();
|
||||
|
||||
m_device->BeginScene();
|
||||
|
||||
m_device->Clear(
|
||||
0,
|
||||
nullptr,
|
||||
D3DCLEAR_TARGET,
|
||||
D3DCOLOR_RGBA(255, 50, 139, 0),
|
||||
0.0f,
|
||||
0);
|
||||
|
||||
m_device->EndScene();
|
||||
|
||||
m_device->PresentEx(
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0);
|
||||
}
|
||||
|
||||
void adjustBackBuffer() {
|
||||
RECT windowRect = { 0, 0, 1024, 600 };
|
||||
GetClientRect(m_window, &windowRect);
|
||||
|
||||
Extent2D newSize = {
|
||||
static_cast<uint32_t>(windowRect.right - windowRect.left),
|
||||
static_cast<uint32_t>(windowRect.bottom - windowRect.top),
|
||||
};
|
||||
|
||||
if (m_windowSize.w != newSize.w
|
||||
|| m_windowSize.h != newSize.h) {
|
||||
m_windowSize = newSize;
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
HRESULT status = m_device->ResetEx(¶ms, nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Device reset failed");
|
||||
}
|
||||
}
|
||||
|
||||
void getPresentParams(D3DPRESENT_PARAMETERS& params) {
|
||||
params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
params.BackBufferCount = 1;
|
||||
params.BackBufferFormat = D3DFMT_X8R8G8B8;
|
||||
params.BackBufferWidth = m_windowSize.w;
|
||||
params.BackBufferHeight = m_windowSize.h;
|
||||
params.EnableAutoDepthStencil = FALSE;
|
||||
params.Flags = 0;
|
||||
params.FullScreen_RefreshRateInHz = 0;
|
||||
params.hDeviceWindow = m_window;
|
||||
params.MultiSampleQuality = 0;
|
||||
params.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
params.Windowed = TRUE;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
HWND m_window;
|
||||
Extent2D m_windowSize = { 1024, 600 };
|
||||
|
||||
Com<IDirect3D9Ex> m_d3d;
|
||||
Com<IDirect3DDevice9Ex> m_device;
|
||||
|
||||
};
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
HWND hWnd;
|
||||
WNDCLASSEXW wc;
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSEX));
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
wc.lpszClassName = L"WindowClass1";
|
||||
RegisterClassExW(&wc);
|
||||
|
||||
hWnd = CreateWindowExW(0,
|
||||
L"WindowClass1",
|
||||
L"Our First Windowed Program",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
300, 300,
|
||||
640, 480,
|
||||
nullptr,
|
||||
nullptr,
|
||||
hInstance,
|
||||
nullptr);
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
|
||||
MSG msg;
|
||||
|
||||
try {
|
||||
BufferApp app(hInstance, hWnd);
|
||||
|
||||
while (true) {
|
||||
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
return msg.wParam;
|
||||
} else {
|
||||
app.run();
|
||||
}
|
||||
}
|
||||
} catch (const dxvk::DxvkError& e) {
|
||||
std::cerr << e.message() << std::endl;
|
||||
return msg.wParam;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
@ -1,173 +0,0 @@
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
struct Extent2D {
|
||||
uint32_t w, h;
|
||||
};
|
||||
|
||||
class ClearApp {
|
||||
|
||||
public:
|
||||
|
||||
ClearApp(HINSTANCE instance, HWND window)
|
||||
: m_window(window) {
|
||||
HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 interface");
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
|
||||
status = m_d3d->CreateDeviceEx(
|
||||
D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
m_window,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
¶ms,
|
||||
nullptr,
|
||||
&m_device);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 device");
|
||||
}
|
||||
|
||||
void run() {
|
||||
this->adjustBackBuffer();
|
||||
|
||||
m_device->BeginScene();
|
||||
|
||||
m_device->Clear(
|
||||
0,
|
||||
nullptr,
|
||||
D3DCLEAR_TARGET,
|
||||
D3DCOLOR_RGBA(255, 0, 0, 0),
|
||||
0.0f,
|
||||
0);
|
||||
|
||||
m_device->EndScene();
|
||||
|
||||
m_device->PresentEx(
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0);
|
||||
}
|
||||
|
||||
void adjustBackBuffer() {
|
||||
RECT windowRect = { 0, 0, 1024, 600 };
|
||||
GetClientRect(m_window, &windowRect);
|
||||
|
||||
Extent2D newSize = {
|
||||
static_cast<uint32_t>(windowRect.right - windowRect.left),
|
||||
static_cast<uint32_t>(windowRect.bottom - windowRect.top),
|
||||
};
|
||||
|
||||
if (m_windowSize.w != newSize.w
|
||||
|| m_windowSize.h != newSize.h) {
|
||||
m_windowSize = newSize;
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
HRESULT status = m_device->ResetEx(¶ms, nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Device reset failed");
|
||||
}
|
||||
}
|
||||
|
||||
void getPresentParams(D3DPRESENT_PARAMETERS& params) {
|
||||
params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
params.BackBufferCount = 1;
|
||||
params.BackBufferFormat = D3DFMT_X8R8G8B8;
|
||||
params.BackBufferWidth = m_windowSize.w;
|
||||
params.BackBufferHeight = m_windowSize.h;
|
||||
params.EnableAutoDepthStencil = FALSE;
|
||||
params.Flags = 0;
|
||||
params.FullScreen_RefreshRateInHz = 0;
|
||||
params.hDeviceWindow = m_window;
|
||||
params.MultiSampleQuality = 0;
|
||||
params.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
params.Windowed = TRUE;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
HWND m_window;
|
||||
Extent2D m_windowSize = { 1024, 600 };
|
||||
|
||||
Com<IDirect3D9Ex> m_d3d;
|
||||
Com<IDirect3DDevice9Ex> m_device;
|
||||
|
||||
};
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
HWND hWnd;
|
||||
WNDCLASSEXW wc;
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSEX));
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
wc.lpszClassName = L"WindowClass1";
|
||||
RegisterClassExW(&wc);
|
||||
|
||||
hWnd = CreateWindowExW(0,
|
||||
L"WindowClass1",
|
||||
L"Our First Windowed Program",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
300, 300,
|
||||
640, 480,
|
||||
nullptr,
|
||||
nullptr,
|
||||
hInstance,
|
||||
nullptr);
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
|
||||
MSG msg;
|
||||
|
||||
try {
|
||||
ClearApp app(hInstance, hWnd);
|
||||
|
||||
while (true) {
|
||||
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
return msg.wParam;
|
||||
} else {
|
||||
app.run();
|
||||
}
|
||||
}
|
||||
} catch (const dxvk::DxvkError& e) {
|
||||
std::cerr << e.message() << std::endl;
|
||||
return msg.wParam;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
@ -1,361 +0,0 @@
|
||||
#include <cstring>
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
struct Extent2D {
|
||||
uint32_t w, h;
|
||||
};
|
||||
|
||||
const std::string g_vertexShaderCode = R"(
|
||||
|
||||
struct VS_INPUT {
|
||||
float3 Position : POSITION;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 Position : POSITION;
|
||||
};
|
||||
|
||||
VS_OUTPUT main( VS_INPUT IN ) {
|
||||
VS_OUTPUT OUT;
|
||||
OUT.Position = float4(IN.Position, 1.0f);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
)";
|
||||
|
||||
const std::string g_pixelShaderCode = R"(
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 Position : POSITION;
|
||||
};
|
||||
|
||||
struct PS_OUTPUT {
|
||||
float4 Colour : COLOR;
|
||||
};
|
||||
|
||||
sampler g_tex : register( s0 );
|
||||
|
||||
PS_OUTPUT main( VS_OUTPUT IN ) {
|
||||
PS_OUTPUT OUT;
|
||||
|
||||
float4 color = float4(tex2D(g_tex, float2(0.5, 0.5)).rgb, 1.0f);
|
||||
color.r = -color.r;
|
||||
color.g = -color.g;
|
||||
OUT.Colour = color;
|
||||
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
|
||||
)";
|
||||
|
||||
class TriangleApp {
|
||||
|
||||
public:
|
||||
|
||||
TriangleApp(HINSTANCE instance, HWND window)
|
||||
: m_window(window) {
|
||||
HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 interface");
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
|
||||
status = m_d3d->CreateDeviceEx(
|
||||
D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
m_window,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
¶ms,
|
||||
nullptr,
|
||||
&m_device);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 device");
|
||||
|
||||
// Vertex Shader
|
||||
{
|
||||
Com<ID3DBlob> blob;
|
||||
|
||||
status = D3DCompile(
|
||||
g_vertexShaderCode.data(),
|
||||
g_vertexShaderCode.length(),
|
||||
nullptr, nullptr, nullptr,
|
||||
"main",
|
||||
"vs_2_0",
|
||||
0, 0, &blob,
|
||||
nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to compile vertex shader");
|
||||
|
||||
status = m_device->CreateVertexShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_vs);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create vertex shader");
|
||||
}
|
||||
|
||||
// Pixel Shader
|
||||
{
|
||||
Com<ID3DBlob> blob;
|
||||
|
||||
status = D3DCompile(
|
||||
g_pixelShaderCode.data(),
|
||||
g_pixelShaderCode.length(),
|
||||
nullptr, nullptr, nullptr,
|
||||
"main",
|
||||
"ps_2_0",
|
||||
0, 0, &blob,
|
||||
nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to compile pixel shader");
|
||||
|
||||
status = m_device->CreatePixelShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_ps);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create pixel shader");
|
||||
}
|
||||
|
||||
m_device->SetVertexShader(m_vs.ptr());
|
||||
m_device->SetPixelShader(m_ps.ptr());
|
||||
|
||||
std::array<float, 9> vertices = {
|
||||
0.0f, 0.5f, 0.0f,
|
||||
0.5f, -0.5f, 0.0f,
|
||||
-0.5f, -0.5f, 0.0f,
|
||||
};
|
||||
|
||||
const size_t vbSize = vertices.size() * sizeof(float);
|
||||
|
||||
status = m_device->CreateVertexBuffer(vbSize, 0, 0, D3DPOOL_DEFAULT, &m_vb, nullptr);
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create vertex buffer");
|
||||
|
||||
void* data = nullptr;
|
||||
status = m_vb->Lock(0, 0, &data, 0);
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to lock vertex buffer");
|
||||
|
||||
std::memcpy(data, vertices.data(), vbSize);
|
||||
|
||||
status = m_vb->Unlock();
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to unlock vertex buffer");
|
||||
|
||||
m_device->SetStreamSource(0, m_vb.ptr(), 0, 3 * sizeof(float));
|
||||
|
||||
std::array<D3DVERTEXELEMENT9, 2> elements;
|
||||
|
||||
elements[0].Method = 0;
|
||||
elements[0].Offset = 0;
|
||||
elements[0].Stream = 0;
|
||||
elements[0].Type = D3DDECLTYPE_FLOAT3;
|
||||
elements[0].Usage = D3DDECLUSAGE_POSITION;
|
||||
elements[0].UsageIndex = 0;
|
||||
|
||||
elements[1] = D3DDECL_END();
|
||||
|
||||
HRESULT result = m_device->CreateVertexDeclaration(elements.data(), &m_decl);
|
||||
if (FAILED(result))
|
||||
throw DxvkError("Failed to create vertex decl");
|
||||
|
||||
m_device->SetVertexDeclaration(m_decl.ptr());
|
||||
|
||||
// The actual texture we want to test...
|
||||
|
||||
Com<IDirect3DTexture9> texture;
|
||||
status = m_device->CreateTexture(64, 64, 1, D3DUSAGE_DYNAMIC, D3DFMT_L6V5U5, D3DPOOL_DEFAULT, &texture, nullptr);
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
status = texture->LockRect(0, &rect, nullptr, 0);
|
||||
|
||||
uint16_t* texData = reinterpret_cast<uint16_t*>(rect.pBits);
|
||||
for (uint32_t i = 0; i < (rect.Pitch * 64) / sizeof(uint16_t); i++) {
|
||||
// -> U -1, V -1, L 1
|
||||
texData[i] = 0b1111111000010000;
|
||||
// -> U 1, V 1, L 1
|
||||
//texData[i] = 0b1111110111101111;
|
||||
}
|
||||
|
||||
status = texture->UnlockRect(0);
|
||||
|
||||
status = m_device->SetTexture(0, texture.ptr());
|
||||
|
||||
/////////////
|
||||
|
||||
/*Com<IDirect3DTexture9> texture2;
|
||||
status = m_device->CreateTexture(64, 64, 1, 0, D3DFMT_A8B8G8R8, D3DPOOL_MANAGED, &texture2, nullptr);
|
||||
status = texture2->LockRect(0, &rect, nullptr, 0);
|
||||
|
||||
uint32_t* texData2 = reinterpret_cast<uint32_t*>(rect.pBits);
|
||||
for (uint32_t i = 0; i < (rect.Pitch * 64) / sizeof(uint32_t); i++) {
|
||||
texData2[i] = 0b00000000000000000000000011111111;
|
||||
}
|
||||
|
||||
status = texture2->UnlockRect(0);
|
||||
|
||||
status = m_device->SetTexture(0, texture2.ptr());*/
|
||||
}
|
||||
|
||||
void run() {
|
||||
this->adjustBackBuffer();
|
||||
|
||||
m_device->BeginScene();
|
||||
|
||||
m_device->Clear(
|
||||
0,
|
||||
nullptr,
|
||||
D3DCLEAR_TARGET,
|
||||
D3DCOLOR_RGBA(44, 62, 80, 0),
|
||||
0,
|
||||
0);
|
||||
|
||||
m_device->Clear(
|
||||
0,
|
||||
nullptr,
|
||||
D3DCLEAR_ZBUFFER,
|
||||
0,
|
||||
0.5f,
|
||||
0);
|
||||
|
||||
m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
|
||||
|
||||
m_device->EndScene();
|
||||
|
||||
m_device->PresentEx(
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0);
|
||||
}
|
||||
|
||||
void adjustBackBuffer() {
|
||||
RECT windowRect = { 0, 0, 1024, 600 };
|
||||
GetClientRect(m_window, &windowRect);
|
||||
|
||||
Extent2D newSize = {
|
||||
static_cast<uint32_t>(windowRect.right - windowRect.left),
|
||||
static_cast<uint32_t>(windowRect.bottom - windowRect.top),
|
||||
};
|
||||
|
||||
if (m_windowSize.w != newSize.w
|
||||
|| m_windowSize.h != newSize.h) {
|
||||
m_windowSize = newSize;
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
HRESULT status = m_device->ResetEx(¶ms, nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Device reset failed");
|
||||
}
|
||||
}
|
||||
|
||||
void getPresentParams(D3DPRESENT_PARAMETERS& params) {
|
||||
params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
params.BackBufferCount = 1;
|
||||
params.BackBufferFormat = D3DFMT_X8R8G8B8;
|
||||
params.BackBufferWidth = m_windowSize.w;
|
||||
params.BackBufferHeight = m_windowSize.h;
|
||||
params.EnableAutoDepthStencil = 0;
|
||||
params.Flags = 0;
|
||||
params.FullScreen_RefreshRateInHz = 0;
|
||||
params.hDeviceWindow = m_window;
|
||||
params.MultiSampleQuality = 0;
|
||||
params.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
params.Windowed = TRUE;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
HWND m_window;
|
||||
Extent2D m_windowSize = { 1024, 600 };
|
||||
|
||||
Com<IDirect3D9Ex> m_d3d;
|
||||
Com<IDirect3DDevice9Ex> m_device;
|
||||
|
||||
Com<IDirect3DVertexShader9> m_vs;
|
||||
Com<IDirect3DPixelShader9> m_ps;
|
||||
Com<IDirect3DVertexBuffer9> m_vb;
|
||||
Com<IDirect3DVertexDeclaration9> m_decl;
|
||||
|
||||
};
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
HWND hWnd;
|
||||
WNDCLASSEXW wc;
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSEX));
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
wc.lpszClassName = L"WindowClass1";
|
||||
RegisterClassExW(&wc);
|
||||
|
||||
hWnd = CreateWindowExW(0,
|
||||
L"WindowClass1",
|
||||
L"Our First Windowed Program",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
300, 300,
|
||||
640, 480,
|
||||
nullptr,
|
||||
nullptr,
|
||||
hInstance,
|
||||
nullptr);
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
|
||||
MSG msg;
|
||||
|
||||
try {
|
||||
TriangleApp app(hInstance, hWnd);
|
||||
|
||||
while (true) {
|
||||
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
return msg.wParam;
|
||||
} else {
|
||||
app.run();
|
||||
}
|
||||
}
|
||||
} catch (const dxvk::DxvkError& e) {
|
||||
std::cerr << e.message() << std::endl;
|
||||
return msg.wParam;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
@ -1,370 +0,0 @@
|
||||
#include <cstring>
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#include "../test_utils.h"
|
||||
#include "test_d3d9_nv12.yuv.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
struct Extent2D {
|
||||
uint32_t w, h;
|
||||
};
|
||||
|
||||
const std::string g_vertexShaderCode = R"(
|
||||
|
||||
struct VS_INPUT {
|
||||
float3 Position : POSITION;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 Position : POSITION;
|
||||
float2 Texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
VS_OUTPUT main( VS_INPUT IN ) {
|
||||
VS_OUTPUT OUT;
|
||||
OUT.Position = float4(IN.Position, 0.6f);
|
||||
OUT.Texcoord = IN.Position.xy + float2(0.5, 0.5);
|
||||
OUT.Texcoord.y = 1.0 - OUT.Texcoord.y;
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
)";
|
||||
|
||||
const std::string g_pixelShaderCode = R"(
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 Position : POSITION;
|
||||
float2 Texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PS_OUTPUT {
|
||||
float4 Colour : COLOR;
|
||||
};
|
||||
|
||||
sampler g_frogTex : register( s0 );
|
||||
|
||||
PS_OUTPUT main( VS_OUTPUT IN ) {
|
||||
PS_OUTPUT OUT;
|
||||
|
||||
OUT.Colour = tex2D(g_frogTex, IN.Texcoord);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
|
||||
)";
|
||||
|
||||
Logger Logger::s_instance("triangle.log");
|
||||
|
||||
class TriangleApp {
|
||||
|
||||
public:
|
||||
|
||||
TriangleApp(HINSTANCE instance, HWND window)
|
||||
: m_window(window) {
|
||||
HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 interface");
|
||||
|
||||
UINT adapter = D3DADAPTER_DEFAULT;
|
||||
|
||||
D3DADAPTER_IDENTIFIER9 adapterId;
|
||||
m_d3d->GetAdapterIdentifier(adapter, 0, &adapterId);
|
||||
|
||||
Logger::info(str::format("Using adapter: ", adapterId.Description));
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
|
||||
status = m_d3d->CreateDeviceEx(
|
||||
adapter,
|
||||
D3DDEVTYPE_HAL,
|
||||
m_window,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
¶ms,
|
||||
nullptr,
|
||||
&m_device);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 device");
|
||||
|
||||
|
||||
// Vertex Shader
|
||||
{
|
||||
Com<ID3DBlob> blob;
|
||||
|
||||
status = D3DCompile(
|
||||
g_vertexShaderCode.data(),
|
||||
g_vertexShaderCode.length(),
|
||||
nullptr, nullptr, nullptr,
|
||||
"main",
|
||||
"vs_2_0",
|
||||
0, 0, &blob,
|
||||
nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to compile vertex shader");
|
||||
|
||||
status = m_device->CreateVertexShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_vs);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create vertex shader");
|
||||
}
|
||||
|
||||
// Pixel Shader
|
||||
{
|
||||
Com<ID3DBlob> blob;
|
||||
|
||||
status = D3DCompile(
|
||||
g_pixelShaderCode.data(),
|
||||
g_pixelShaderCode.length(),
|
||||
nullptr, nullptr, nullptr,
|
||||
"main",
|
||||
"ps_2_0",
|
||||
0, 0, &blob,
|
||||
nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to compile pixel shader");
|
||||
|
||||
status = m_device->CreatePixelShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_ps);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create pixel shader");
|
||||
}
|
||||
|
||||
m_device->SetVertexShader(m_vs.ptr());
|
||||
m_device->SetPixelShader(m_ps.ptr());
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
|
||||
std::array<float, 9> vertices = {
|
||||
0.0f, 0.5f, 0.0f,
|
||||
0.5f, -0.5f, 0.0f,
|
||||
-0.5f, -0.5f, 0.0f,
|
||||
};
|
||||
|
||||
const size_t vbSize = vertices.size() * sizeof(float);
|
||||
|
||||
status = m_device->CreateVertexBuffer(vbSize, 0, 0, D3DPOOL_DEFAULT, &m_vb, nullptr);
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create vertex buffer");
|
||||
|
||||
void* data = nullptr;
|
||||
status = m_vb->Lock(0, 0, &data, 0);
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to lock vertex buffer");
|
||||
|
||||
std::memcpy(data, vertices.data(), vbSize);
|
||||
|
||||
status = m_vb->Unlock();
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to unlock vertex buffer");
|
||||
|
||||
m_device->SetStreamSource(0, m_vb.ptr(), 0, 3 * sizeof(float));
|
||||
|
||||
std::array<D3DVERTEXELEMENT9, 2> elements;
|
||||
|
||||
elements[0].Method = 0;
|
||||
elements[0].Offset = 0;
|
||||
elements[0].Stream = 0;
|
||||
elements[0].Type = D3DDECLTYPE_FLOAT3;
|
||||
elements[0].Usage = D3DDECLUSAGE_POSITION;
|
||||
elements[0].UsageIndex = 0;
|
||||
|
||||
elements[1] = D3DDECL_END();
|
||||
|
||||
HRESULT result = m_device->CreateVertexDeclaration(elements.data(), &m_decl);
|
||||
if (FAILED(result))
|
||||
throw DxvkError("Failed to create vertex decl");
|
||||
|
||||
m_device->SetVertexDeclaration(m_decl.ptr());
|
||||
|
||||
const uint32_t imageSize = 320;
|
||||
|
||||
Com<IDirect3DTexture9> texture;
|
||||
Com<IDirect3DSurface9> texSurf;
|
||||
status = m_device->CreateTexture(imageSize, imageSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, nullptr);
|
||||
status = texture->GetSurfaceLevel(0, &texSurf);
|
||||
|
||||
Com<IDirect3DSurface9> nv12Surf;
|
||||
status = m_device->CreateOffscreenPlainSurface(imageSize, imageSize, (D3DFORMAT)MAKEFOURCC('N', 'V', '1', '2'), D3DPOOL_DEFAULT, &nv12Surf, nullptr);
|
||||
D3DLOCKED_RECT rect;
|
||||
nv12Surf->LockRect(&rect, nullptr, 0);
|
||||
char* dst = (char*)rect.pBits;
|
||||
char* src = (char*)test_d3d9_nv12_yuv;
|
||||
for (uint32_t i = 0; i < imageSize; i++)
|
||||
{
|
||||
std::memcpy(dst, src, imageSize);
|
||||
src += imageSize;
|
||||
dst += rect.Pitch;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < imageSize / 2; i++)
|
||||
{
|
||||
std::memcpy(dst, src, imageSize);
|
||||
src += imageSize;
|
||||
dst += rect.Pitch;
|
||||
}
|
||||
nv12Surf->UnlockRect();
|
||||
status = m_device->StretchRect(nv12Surf.ptr(), nullptr, texSurf.ptr(), nullptr, D3DTEXF_LINEAR);
|
||||
m_device->SetTexture(0, texture.ptr());
|
||||
}
|
||||
|
||||
void run() {
|
||||
this->adjustBackBuffer();
|
||||
|
||||
m_device->BeginScene();
|
||||
|
||||
m_device->Clear(
|
||||
0,
|
||||
nullptr,
|
||||
D3DCLEAR_TARGET,
|
||||
D3DCOLOR_RGBA(44, 62, 80, 0),
|
||||
0,
|
||||
0);
|
||||
|
||||
m_device->Clear(
|
||||
0,
|
||||
nullptr,
|
||||
D3DCLEAR_ZBUFFER,
|
||||
0,
|
||||
0.5f,
|
||||
0);
|
||||
|
||||
m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
|
||||
|
||||
m_device->EndScene();
|
||||
|
||||
m_device->PresentEx(
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0);
|
||||
}
|
||||
|
||||
void adjustBackBuffer() {
|
||||
RECT windowRect = { 0, 0, 1024, 600 };
|
||||
GetClientRect(m_window, &windowRect);
|
||||
|
||||
Extent2D newSize = {
|
||||
static_cast<uint32_t>(windowRect.right - windowRect.left),
|
||||
static_cast<uint32_t>(windowRect.bottom - windowRect.top),
|
||||
};
|
||||
|
||||
if (m_windowSize.w != newSize.w
|
||||
|| m_windowSize.h != newSize.h) {
|
||||
m_windowSize = newSize;
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
HRESULT status = m_device->ResetEx(¶ms, nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Device reset failed");
|
||||
}
|
||||
}
|
||||
|
||||
void getPresentParams(D3DPRESENT_PARAMETERS& params) {
|
||||
params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
params.BackBufferCount = 1;
|
||||
params.BackBufferFormat = D3DFMT_X8R8G8B8;
|
||||
params.BackBufferWidth = m_windowSize.w;
|
||||
params.BackBufferHeight = m_windowSize.h;
|
||||
params.EnableAutoDepthStencil = 0;
|
||||
params.Flags = 0;
|
||||
params.FullScreen_RefreshRateInHz = 0;
|
||||
params.hDeviceWindow = m_window;
|
||||
params.MultiSampleQuality = 0;
|
||||
params.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
params.Windowed = TRUE;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
HWND m_window;
|
||||
Extent2D m_windowSize = { 1024, 600 };
|
||||
|
||||
Com<IDirect3D9Ex> m_d3d;
|
||||
Com<IDirect3DDevice9Ex> m_device;
|
||||
|
||||
Com<IDirect3DVertexShader9> m_vs;
|
||||
Com<IDirect3DPixelShader9> m_ps;
|
||||
Com<IDirect3DVertexBuffer9> m_vb;
|
||||
Com<IDirect3DVertexDeclaration9> m_decl;
|
||||
|
||||
};
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
HWND hWnd;
|
||||
WNDCLASSEXW wc;
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSEX));
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
wc.lpszClassName = L"WindowClass1";
|
||||
RegisterClassExW(&wc);
|
||||
|
||||
hWnd = CreateWindowExW(0,
|
||||
L"WindowClass1",
|
||||
L"Our First Windowed Program",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
300, 300,
|
||||
640, 480,
|
||||
nullptr,
|
||||
nullptr,
|
||||
hInstance,
|
||||
nullptr);
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
|
||||
MSG msg;
|
||||
|
||||
try {
|
||||
TriangleApp app(hInstance, hWnd);
|
||||
|
||||
while (true) {
|
||||
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
return msg.wParam;
|
||||
} else {
|
||||
app.run();
|
||||
}
|
||||
}
|
||||
} catch (const dxvk::DxvkError& e) {
|
||||
std::cerr << e.message() << std::endl;
|
||||
return msg.wParam;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,529 +0,0 @@
|
||||
#include <cstring>
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
struct Extent2D {
|
||||
uint32_t w, h;
|
||||
};
|
||||
|
||||
const std::string g_vertexShaderCode = R"(
|
||||
|
||||
struct VS_INPUT {
|
||||
float3 Position : POSITION;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 Position : POSITION;
|
||||
};
|
||||
|
||||
VS_OUTPUT main( VS_INPUT IN ) {
|
||||
VS_OUTPUT OUT;
|
||||
OUT.Position = float4(IN.Position, 0.6f);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
)";
|
||||
|
||||
const std::string g_pixelShaderCode = R"(
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 Position : POSITION;
|
||||
};
|
||||
|
||||
struct PS_OUTPUT {
|
||||
float4 Colour : COLOR;
|
||||
};
|
||||
|
||||
sampler g_texDepth : register( s0 );
|
||||
|
||||
PS_OUTPUT main( VS_OUTPUT IN ) {
|
||||
PS_OUTPUT OUT;
|
||||
|
||||
OUT.Colour = tex2D(g_texDepth, float2(0, 0));
|
||||
OUT.Colour = 1.0;
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
|
||||
)";
|
||||
|
||||
Logger Logger::s_instance("triangle.log");
|
||||
|
||||
class TriangleApp {
|
||||
|
||||
public:
|
||||
|
||||
TriangleApp(HINSTANCE instance, HWND window)
|
||||
: m_window(window) {
|
||||
HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 interface");
|
||||
|
||||
UINT adapter = D3DADAPTER_DEFAULT;
|
||||
|
||||
D3DADAPTER_IDENTIFIER9 adapterId;
|
||||
m_d3d->GetAdapterIdentifier(adapter, 0, &adapterId);
|
||||
|
||||
Logger::info(str::format("Using adapter: ", adapterId.Description));
|
||||
|
||||
auto CheckSRGBFormat = [&](D3DFORMAT fmt, const char* name) {
|
||||
HRESULT status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt);
|
||||
Logger::warn(str::format("(linear) ", name, ": ", SUCCEEDED(status) ? "ok" : "nope"));
|
||||
|
||||
status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, fmt);
|
||||
Logger::warn(str::format("(srgb) ", name, ": ", SUCCEEDED(status) ? "ok" : "nope"));
|
||||
};
|
||||
|
||||
CheckSRGBFormat(D3DFMT_R5G6B5, "R5G6B5");
|
||||
CheckSRGBFormat(D3DFMT_X1R5G5B5, "X1R5G5B5");
|
||||
CheckSRGBFormat(D3DFMT_A1R5G5B5, "A1R5G5B5");
|
||||
CheckSRGBFormat(D3DFMT_A4R4G4B4, "A4R4G4B4");
|
||||
CheckSRGBFormat(D3DFMT_X4R4G4B4, "X4R4G4B4");
|
||||
CheckSRGBFormat(D3DFMT_G16R16, "G16R16");
|
||||
CheckSRGBFormat(D3DFMT_A2R10G10B10, "A2R10G10B10");
|
||||
CheckSRGBFormat(D3DFMT_A16B16G16R16, "A16B16G16R16");
|
||||
|
||||
//
|
||||
|
||||
DWORD quality;
|
||||
status = m_d3d->CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_D24S8);
|
||||
status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8);
|
||||
status = m_d3d->CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8);
|
||||
status = m_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, FALSE, D3DMULTISAMPLE_NONE, &quality);
|
||||
status = m_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, &quality);
|
||||
status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE);
|
||||
status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE);
|
||||
|
||||
// NULL
|
||||
constexpr D3DFORMAT NullFormat = D3DFORMAT(MAKEFOURCC('N', 'U', 'L', 'L'));
|
||||
|
||||
status = m_d3d->CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, D3DFMT_D24S8);
|
||||
status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, NullFormat);
|
||||
status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, NullFormat);
|
||||
status = m_d3d->CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat);
|
||||
status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, false);
|
||||
status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, true);
|
||||
//
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
|
||||
status = m_d3d->CreateDeviceEx(
|
||||
adapter,
|
||||
D3DDEVTYPE_HAL,
|
||||
m_window,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
¶ms,
|
||||
nullptr,
|
||||
&m_device);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 device");
|
||||
|
||||
// Funny Swapchain Refcounting
|
||||
// "One of the things COM does really well, is lifecycle management"
|
||||
// Implicit Swapchain
|
||||
{
|
||||
IDirect3DSurface9* pSurface1 = nullptr;
|
||||
IDirect3DSurface9* pSurface2 = nullptr;
|
||||
status = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface1);
|
||||
D3DPRESENT_PARAMETERS newParams = params;
|
||||
newParams.BackBufferWidth = 10;
|
||||
newParams.BackBufferHeight = 10;
|
||||
status = m_device->Reset(&newParams);
|
||||
status = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface2);
|
||||
|
||||
IDirect3DSwapChain9* pSwapChain2 = nullptr;
|
||||
IDirect3DSwapChain9* pSwapChain3 = nullptr;
|
||||
status = pSurface1->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain2));
|
||||
status = pSurface2->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain3));
|
||||
|
||||
printf("E_NOINTERFACE! for pSwapchain2");
|
||||
status = m_device->Reset(¶ms);
|
||||
}
|
||||
// Additional swapchain
|
||||
{
|
||||
IDirect3DSwapChain9* pSwapChain2 = nullptr;
|
||||
IDirect3DSwapChain9* pSwapChain3 = nullptr;
|
||||
IDirect3DSwapChain9* pSwapChain4 = nullptr;
|
||||
IDirect3DSurface9* pSurface = nullptr;
|
||||
status = m_device->CreateAdditionalSwapChain(¶ms, &pSwapChain2);
|
||||
status = pSwapChain2->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface);
|
||||
status = pSurface->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain3));
|
||||
pSwapChain2->Release();
|
||||
UINT count = pSwapChain2->Release();
|
||||
printf("Count: %u - Should be 0 and swapchain dead!", count);
|
||||
status = pSurface->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain4));
|
||||
// E_NOINTERFACE !
|
||||
printf("E_NOINTERFACE!");
|
||||
}
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
Com<IDirect3DSurface9> backbuffer;
|
||||
m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
Com<IDirect3DSwapChain9> swapchain;
|
||||
m_device->GetSwapChain(0, &swapchain);
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
DWORD bias = 0xDEADBEEF;
|
||||
status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias);
|
||||
status = m_device->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G', 'E', 'T', '4'));
|
||||
status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias);
|
||||
status = m_device->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G', 'E', 'T', '1'));
|
||||
status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias);
|
||||
|
||||
// Vertex Shader
|
||||
{
|
||||
Com<ID3DBlob> blob;
|
||||
|
||||
status = D3DCompile(
|
||||
g_vertexShaderCode.data(),
|
||||
g_vertexShaderCode.length(),
|
||||
nullptr, nullptr, nullptr,
|
||||
"main",
|
||||
"vs_2_0",
|
||||
0, 0, &blob,
|
||||
nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to compile vertex shader");
|
||||
|
||||
status = m_device->CreateVertexShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_vs);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create vertex shader");
|
||||
}
|
||||
|
||||
// Pixel Shader
|
||||
{
|
||||
Com<ID3DBlob> blob;
|
||||
|
||||
status = D3DCompile(
|
||||
g_pixelShaderCode.data(),
|
||||
g_pixelShaderCode.length(),
|
||||
nullptr, nullptr, nullptr,
|
||||
"main",
|
||||
"ps_2_0",
|
||||
0, 0, &blob,
|
||||
nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to compile pixel shader");
|
||||
|
||||
status = m_device->CreatePixelShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_ps);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create pixel shader");
|
||||
}
|
||||
|
||||
m_device->SetVertexShader(m_vs.ptr());
|
||||
m_device->SetPixelShader(m_ps.ptr());
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
Com<IDirect3DSurface9> nullSurface;
|
||||
status = m_device->CreateRenderTarget(64, 64, D3DFORMAT(MAKEFOURCC('N', 'U', 'L', 'L')), D3DMULTISAMPLE_NONE, 0, FALSE, &nullSurface, nullptr);
|
||||
|
||||
status = m_device->ColorFill(nullSurface.ptr(), nullptr, D3DCOLOR_RGBA(255, 0, 0, 255));
|
||||
|
||||
Com<IDirect3DTexture9> defaultTexture;
|
||||
status = m_device->CreateTexture(64, 64, 1, 0, D3DFMT_DXT3, D3DPOOL_DEFAULT, &defaultTexture, nullptr);
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
Com<IDirect3DSurface9> surface;
|
||||
status = defaultTexture->GetSurfaceLevel(0, &surface);
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
Com<IDirect3DTexture9> sysmemTexture;
|
||||
status = m_device->CreateTexture(64, 64, 1, 0, D3DFMT_DXT3, D3DPOOL_SYSTEMMEM, &sysmemTexture, nullptr);
|
||||
|
||||
Com<IDirect3DSurface9> offscreenSurface;
|
||||
status = m_device->CreateOffscreenPlainSurfaceEx(64, 64, D3DFMT_DXT3, D3DPOOL_DEFAULT, &offscreenSurface, nullptr, 0);
|
||||
|
||||
D3DLOCKED_RECT offscreenLock;
|
||||
status = offscreenSurface->LockRect(&offscreenLock, nullptr, 0);
|
||||
|
||||
std::memset(offscreenLock.pBits, 0xFF, offscreenLock.Pitch * (64 / 4));
|
||||
|
||||
status = offscreenSurface->UnlockRect();
|
||||
|
||||
//status = m_device->ColorFill(offscreenSurface.ptr(), nullptr, D3DCOLOR_ARGB(255, 255, 0, 0));
|
||||
|
||||
D3DLOCKED_RECT sysmemLock;
|
||||
status = sysmemTexture->LockRect(0, &sysmemLock, nullptr, 0);
|
||||
|
||||
//D3DLOCKED_RECT offscreenLock;
|
||||
status = offscreenSurface->LockRect(&offscreenLock, nullptr, 0);
|
||||
|
||||
std::memcpy(sysmemLock.pBits, offscreenLock.pBits, offscreenLock.Pitch * (64 / 4));
|
||||
|
||||
sysmemTexture->UnlockRect(0);
|
||||
offscreenSurface->UnlockRect();
|
||||
|
||||
status = m_device->UpdateTexture(sysmemTexture.ptr(), defaultTexture.ptr());
|
||||
|
||||
status = m_device->SetTexture(0, defaultTexture.ptr());
|
||||
|
||||
Com<IDirect3DSurface9> rt;
|
||||
status = m_device->CreateRenderTarget(1280, 720, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, nullptr);
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
Com<IDirect3DSurface9> rt2;
|
||||
status = m_device->CreateRenderTarget(1280, 720, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, nullptr);
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
rt2 = nullptr;
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
RECT stretchRect1 = { 0, 0, 640, 720 };
|
||||
RECT stretchRect2 = { 640, 0, 1280, 720 };
|
||||
status = m_device->StretchRect(rt.ptr(), &stretchRect1, rt.ptr(), &stretchRect2, D3DTEXF_LINEAR);
|
||||
|
||||
///
|
||||
|
||||
Com<IDirect3DSurface9> ds;
|
||||
//status = m_device->CreateDepthStencilSurface(1274, 695, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, FALSE, &ds, nullptr);
|
||||
status = m_device->CreateDepthStencilSurface(1280, 720, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, FALSE, &ds, nullptr);
|
||||
|
||||
status = m_device->SetDepthStencilSurface(ds.ptr());
|
||||
status = m_device->SetRenderState(D3DRS_ZWRITEENABLE, 1);
|
||||
status = m_device->SetRenderState(D3DRS_ZENABLE, 1);
|
||||
status = m_device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
|
||||
|
||||
|
||||
|
||||
std::array<float, 9> vertices = {
|
||||
0.0f, 0.5f, 0.0f,
|
||||
0.5f, -0.5f, 0.0f,
|
||||
-0.5f, -0.5f, 0.0f,
|
||||
};
|
||||
|
||||
const size_t vbSize = vertices.size() * sizeof(float);
|
||||
|
||||
status = m_device->CreateVertexBuffer(vbSize, 0, 0, D3DPOOL_DEFAULT, &m_vb, nullptr);
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create vertex buffer");
|
||||
|
||||
void* data = nullptr;
|
||||
status = m_vb->Lock(0, 0, &data, 0);
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to lock vertex buffer");
|
||||
|
||||
std::memcpy(data, vertices.data(), vbSize);
|
||||
|
||||
status = m_vb->Unlock();
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to unlock vertex buffer");
|
||||
|
||||
m_device->SetStreamSource(0, m_vb.ptr(), 0, 3 * sizeof(float));
|
||||
|
||||
std::array<D3DVERTEXELEMENT9, 2> elements;
|
||||
|
||||
elements[0].Method = 0;
|
||||
elements[0].Offset = 0;
|
||||
elements[0].Stream = 0;
|
||||
elements[0].Type = D3DDECLTYPE_FLOAT3;
|
||||
elements[0].Usage = D3DDECLUSAGE_POSITION;
|
||||
elements[0].UsageIndex = 0;
|
||||
|
||||
elements[1] = D3DDECL_END();
|
||||
|
||||
HRESULT result = m_device->CreateVertexDeclaration(elements.data(), &m_decl);
|
||||
if (FAILED(result))
|
||||
throw DxvkError("Failed to create vertex decl");
|
||||
|
||||
m_device->SetVertexDeclaration(m_decl.ptr());
|
||||
|
||||
///
|
||||
|
||||
Com<IDirect3DTexture9> myRT;
|
||||
status = m_device->CreateTexture(512, 256, 1, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &myRT, nullptr);
|
||||
|
||||
Com<IDirect3DSurface9> myRTSurf;
|
||||
myRT->GetSurfaceLevel(0, &myRTSurf);
|
||||
|
||||
Com<IDirect3DTexture9> myCopyThing;
|
||||
status = m_device->CreateTexture(512, 256, 1, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &myCopyThing, nullptr);
|
||||
|
||||
Com<IDirect3DSurface9> myCopyThingSurf;
|
||||
myCopyThing->GetSurfaceLevel(0, &myCopyThingSurf);
|
||||
|
||||
status = m_device->StretchRect(myRTSurf.ptr(), nullptr, myCopyThingSurf.ptr(), nullptr, D3DTEXF_NONE);
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
status = myCopyThing->LockRect(0, &rect, nullptr, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
|
||||
|
||||
m_device->SetRenderState(D3DRS_ALPHAREF, 256 + 255);
|
||||
m_device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_LESSEQUAL);
|
||||
m_device->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
|
||||
}
|
||||
|
||||
void run() {
|
||||
this->adjustBackBuffer();
|
||||
|
||||
m_device->BeginScene();
|
||||
|
||||
m_device->Clear(
|
||||
0,
|
||||
nullptr,
|
||||
D3DCLEAR_TARGET,
|
||||
D3DCOLOR_RGBA(44, 62, 80, 0),
|
||||
0,
|
||||
0);
|
||||
|
||||
m_device->Clear(
|
||||
0,
|
||||
nullptr,
|
||||
D3DCLEAR_ZBUFFER,
|
||||
0,
|
||||
0.5f,
|
||||
0);
|
||||
|
||||
m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
|
||||
|
||||
m_device->EndScene();
|
||||
|
||||
m_device->PresentEx(
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0);
|
||||
}
|
||||
|
||||
void adjustBackBuffer() {
|
||||
RECT windowRect = { 0, 0, 1024, 600 };
|
||||
GetClientRect(m_window, &windowRect);
|
||||
|
||||
Extent2D newSize = {
|
||||
static_cast<uint32_t>(windowRect.right - windowRect.left),
|
||||
static_cast<uint32_t>(windowRect.bottom - windowRect.top),
|
||||
};
|
||||
|
||||
if (m_windowSize.w != newSize.w
|
||||
|| m_windowSize.h != newSize.h) {
|
||||
m_windowSize = newSize;
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
HRESULT status = m_device->ResetEx(¶ms, nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Device reset failed");
|
||||
}
|
||||
}
|
||||
|
||||
void getPresentParams(D3DPRESENT_PARAMETERS& params) {
|
||||
params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
params.BackBufferCount = 1;
|
||||
params.BackBufferFormat = D3DFMT_X8R8G8B8;
|
||||
params.BackBufferWidth = m_windowSize.w;
|
||||
params.BackBufferHeight = m_windowSize.h;
|
||||
params.EnableAutoDepthStencil = 0;
|
||||
params.Flags = 0;
|
||||
params.FullScreen_RefreshRateInHz = 0;
|
||||
params.hDeviceWindow = m_window;
|
||||
params.MultiSampleQuality = 0;
|
||||
params.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
params.Windowed = TRUE;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
HWND m_window;
|
||||
Extent2D m_windowSize = { 1024, 600 };
|
||||
|
||||
Com<IDirect3D9Ex> m_d3d;
|
||||
Com<IDirect3DDevice9Ex> m_device;
|
||||
|
||||
Com<IDirect3DVertexShader9> m_vs;
|
||||
Com<IDirect3DPixelShader9> m_ps;
|
||||
Com<IDirect3DVertexBuffer9> m_vb;
|
||||
Com<IDirect3DVertexDeclaration9> m_decl;
|
||||
|
||||
};
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
HWND hWnd;
|
||||
WNDCLASSEXW wc;
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSEX));
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
wc.lpszClassName = L"WindowClass1";
|
||||
RegisterClassExW(&wc);
|
||||
|
||||
hWnd = CreateWindowExW(0,
|
||||
L"WindowClass1",
|
||||
L"Our First Windowed Program",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
300, 300,
|
||||
640, 480,
|
||||
nullptr,
|
||||
nullptr,
|
||||
hInstance,
|
||||
nullptr);
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
|
||||
MSG msg;
|
||||
|
||||
try {
|
||||
TriangleApp app(hInstance, hWnd);
|
||||
|
||||
while (true) {
|
||||
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
return msg.wParam;
|
||||
} else {
|
||||
app.run();
|
||||
}
|
||||
}
|
||||
} catch (const dxvk::DxvkError& e) {
|
||||
std::cerr << e.message() << std::endl;
|
||||
return msg.wParam;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
@ -1,429 +0,0 @@
|
||||
#include <cstring>
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#include "../test_utils.h"
|
||||
|
||||
using namespace dxvk;
|
||||
|
||||
struct Extent2D {
|
||||
uint32_t w, h;
|
||||
};
|
||||
|
||||
const std::string g_vertexShaderCode = R"(
|
||||
|
||||
struct VS_INPUT {
|
||||
float3 Position : POSITION;
|
||||
float3 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 Position : POSITION;
|
||||
float3 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
VS_OUTPUT main( VS_INPUT IN ) {
|
||||
VS_OUTPUT OUT;
|
||||
OUT.Position = float4(IN.Position, 0.6f);
|
||||
OUT.TexCoord = IN.TexCoord;
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
)";
|
||||
|
||||
const std::string g_pixelShaderCode = R"(
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 Position : POSITION;
|
||||
float3 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PS_OUTPUT {
|
||||
float4 Colour : COLOR;
|
||||
};
|
||||
|
||||
sampler g_texDepth : register( s0 );
|
||||
|
||||
PS_OUTPUT main( VS_OUTPUT IN ) {
|
||||
PS_OUTPUT OUT;
|
||||
|
||||
//OUT.Colour = tex2D(g_texDepth, float2(0, 0));
|
||||
//OUT.Colour = 1.0;
|
||||
|
||||
OUT.Colour = float4(IN.TexCoord.xyz, 1.0);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
|
||||
)";
|
||||
|
||||
Logger Logger::s_instance("triangle.log");
|
||||
|
||||
class TriangleApp {
|
||||
|
||||
public:
|
||||
|
||||
TriangleApp(HINSTANCE instance, HWND window)
|
||||
: m_window(window) {
|
||||
HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 interface");
|
||||
|
||||
UINT adapter = D3DADAPTER_DEFAULT;
|
||||
|
||||
D3DADAPTER_IDENTIFIER9 adapterId;
|
||||
m_d3d->GetAdapterIdentifier(adapter, 0, &adapterId);
|
||||
|
||||
Logger::info(str::format("Using adapter: ", adapterId.Description));
|
||||
|
||||
auto CheckSRGBFormat = [&](D3DFORMAT fmt, const char* name) {
|
||||
HRESULT status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt);
|
||||
Logger::warn(str::format("(linear) ", name, ": ", SUCCEEDED(status) ? "ok" : "nope"));
|
||||
|
||||
status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, fmt);
|
||||
Logger::warn(str::format("(srgb) ", name, ": ", SUCCEEDED(status) ? "ok" : "nope"));
|
||||
};
|
||||
|
||||
CheckSRGBFormat(D3DFMT_R5G6B5, "R5G6B5");
|
||||
CheckSRGBFormat(D3DFMT_X1R5G5B5, "X1R5G5B5");
|
||||
CheckSRGBFormat(D3DFMT_A1R5G5B5, "A1R5G5B5");
|
||||
CheckSRGBFormat(D3DFMT_A4R4G4B4, "A4R4G4B4");
|
||||
CheckSRGBFormat(D3DFMT_X4R4G4B4, "X4R4G4B4");
|
||||
CheckSRGBFormat(D3DFMT_G16R16, "G16R16");
|
||||
CheckSRGBFormat(D3DFMT_A2R10G10B10, "A2R10G10B10");
|
||||
CheckSRGBFormat(D3DFMT_A16B16G16R16, "A16B16G16R16");
|
||||
|
||||
//
|
||||
|
||||
DWORD quality;
|
||||
status = m_d3d->CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_D24S8);
|
||||
status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8);
|
||||
status = m_d3d->CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8);
|
||||
status = m_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, FALSE, D3DMULTISAMPLE_NONE, &quality);
|
||||
status = m_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, &quality);
|
||||
status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE);
|
||||
status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE);
|
||||
|
||||
// NULL
|
||||
constexpr D3DFORMAT NullFormat = D3DFORMAT(MAKEFOURCC('N', 'U', 'L', 'L'));
|
||||
|
||||
status = m_d3d->CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, D3DFMT_D24S8);
|
||||
status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, NullFormat);
|
||||
status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, NullFormat);
|
||||
status = m_d3d->CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat);
|
||||
status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, false);
|
||||
status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, true);
|
||||
//
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
|
||||
status = m_d3d->CreateDeviceEx(
|
||||
adapter,
|
||||
D3DDEVTYPE_HAL,
|
||||
m_window,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
¶ms,
|
||||
nullptr,
|
||||
&m_device);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create D3D9 device");
|
||||
|
||||
// Funny Swapchain Refcounting
|
||||
// "One of the things COM does really well, is lifecycle management"
|
||||
// Implicit Swapchain
|
||||
{
|
||||
IDirect3DSurface9* pSurface1 = nullptr;
|
||||
IDirect3DSurface9* pSurface2 = nullptr;
|
||||
status = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface1);
|
||||
D3DPRESENT_PARAMETERS newParams = params;
|
||||
newParams.BackBufferWidth = 10;
|
||||
newParams.BackBufferHeight = 10;
|
||||
status = m_device->Reset(&newParams);
|
||||
status = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface2);
|
||||
|
||||
IDirect3DSwapChain9* pSwapChain2 = nullptr;
|
||||
IDirect3DSwapChain9* pSwapChain3 = nullptr;
|
||||
status = pSurface1->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain2));
|
||||
status = pSurface2->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain3));
|
||||
|
||||
printf("E_NOINTERFACE! for pSwapchain2");
|
||||
status = m_device->Reset(¶ms);
|
||||
}
|
||||
// Additional swapchain
|
||||
{
|
||||
IDirect3DSwapChain9* pSwapChain2 = nullptr;
|
||||
IDirect3DSwapChain9* pSwapChain3 = nullptr;
|
||||
IDirect3DSwapChain9* pSwapChain4 = nullptr;
|
||||
IDirect3DSurface9* pSurface = nullptr;
|
||||
status = m_device->CreateAdditionalSwapChain(¶ms, &pSwapChain2);
|
||||
status = pSwapChain2->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface);
|
||||
status = pSurface->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain3));
|
||||
pSwapChain2->Release();
|
||||
UINT count = pSwapChain2->Release();
|
||||
printf("Count: %u - Should be 0 and swapchain dead!", count);
|
||||
status = pSurface->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain4));
|
||||
// E_NOINTERFACE !
|
||||
printf("E_NOINTERFACE!");
|
||||
}
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
Com<IDirect3DSurface9> backbuffer;
|
||||
m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
Com<IDirect3DSwapChain9> swapchain;
|
||||
m_device->GetSwapChain(0, &swapchain);
|
||||
|
||||
m_device->AddRef();
|
||||
|
||||
DWORD bias = 0xDEADBEEF;
|
||||
status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias);
|
||||
status = m_device->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G', 'E', 'T', '4'));
|
||||
status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias);
|
||||
status = m_device->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G', 'E', 'T', '1'));
|
||||
status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias);
|
||||
|
||||
// Vertex Shader
|
||||
{
|
||||
Com<ID3DBlob> blob;
|
||||
|
||||
status = D3DCompile(
|
||||
g_vertexShaderCode.data(),
|
||||
g_vertexShaderCode.length(),
|
||||
nullptr, nullptr, nullptr,
|
||||
"main",
|
||||
"vs_2_0",
|
||||
0, 0, &blob,
|
||||
nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to compile vertex shader");
|
||||
|
||||
status = m_device->CreateVertexShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_vs);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create vertex shader");
|
||||
}
|
||||
|
||||
// Pixel Shader
|
||||
{
|
||||
Com<ID3DBlob> blob;
|
||||
|
||||
status = D3DCompile(
|
||||
g_pixelShaderCode.data(),
|
||||
g_pixelShaderCode.length(),
|
||||
nullptr, nullptr, nullptr,
|
||||
"main",
|
||||
"ps_2_0",
|
||||
0, 0, &blob,
|
||||
nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to compile pixel shader");
|
||||
|
||||
status = m_device->CreatePixelShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_ps);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Failed to create pixel shader");
|
||||
}
|
||||
|
||||
m_device->SetVertexShader(m_vs.ptr());
|
||||
m_device->SetPixelShader(m_ps.ptr());
|
||||
|
||||
m_device->AddRef();
|
||||
}
|
||||
|
||||
void run() {
|
||||
this->adjustBackBuffer();
|
||||
|
||||
m_device->BeginScene();
|
||||
|
||||
m_device->Clear(
|
||||
0,
|
||||
nullptr,
|
||||
D3DCLEAR_TARGET,
|
||||
D3DCOLOR_RGBA(44, 62, 80, 0),
|
||||
0,
|
||||
0);
|
||||
|
||||
m_device->Clear(
|
||||
0,
|
||||
nullptr,
|
||||
D3DCLEAR_ZBUFFER,
|
||||
0,
|
||||
0.5f,
|
||||
0);
|
||||
|
||||
m_decl = nullptr;
|
||||
|
||||
std::array<D3DVERTEXELEMENT9, 3> elements;
|
||||
|
||||
elements[0].Method = 0;
|
||||
elements[0].Offset = 0;
|
||||
elements[0].Stream = 0;
|
||||
elements[0].Type = D3DDECLTYPE_FLOAT3;
|
||||
elements[0].Usage = D3DDECLUSAGE_POSITION;
|
||||
elements[0].UsageIndex = 0;
|
||||
|
||||
elements[1].Method = 0;
|
||||
elements[1].Offset = 12;
|
||||
elements[1].Stream = 0;
|
||||
elements[1].Type = D3DDECLTYPE_FLOAT3;
|
||||
elements[1].Usage = D3DDECLUSAGE_TEXCOORD;
|
||||
elements[1].UsageIndex = 0;
|
||||
|
||||
elements[2] = D3DDECL_END();
|
||||
|
||||
HRESULT result = m_device->CreateVertexDeclaration(elements.data(), &m_decl);
|
||||
if (FAILED(result))
|
||||
throw DxvkError("Failed to create vertex decl");
|
||||
|
||||
m_device->SetVertexDeclaration(m_decl.ptr());
|
||||
|
||||
float vertexData[] = {
|
||||
-1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, -1, 0, 1, 1, -1, -1, 0, 0, 1,
|
||||
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
};
|
||||
|
||||
m_device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, vertexData, 20);
|
||||
//m_device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 3, vertexData, 20);
|
||||
|
||||
//m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
|
||||
|
||||
m_device->EndScene();
|
||||
|
||||
m_device->PresentEx(
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0);
|
||||
}
|
||||
|
||||
void adjustBackBuffer() {
|
||||
RECT windowRect = { 0, 0, 1024, 600 };
|
||||
GetClientRect(m_window, &windowRect);
|
||||
|
||||
Extent2D newSize = {
|
||||
static_cast<uint32_t>(windowRect.right - windowRect.left),
|
||||
static_cast<uint32_t>(windowRect.bottom - windowRect.top),
|
||||
};
|
||||
|
||||
if (m_windowSize.w != newSize.w
|
||||
|| m_windowSize.h != newSize.h) {
|
||||
m_windowSize = newSize;
|
||||
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
getPresentParams(params);
|
||||
HRESULT status = m_device->ResetEx(¶ms, nullptr);
|
||||
|
||||
if (FAILED(status))
|
||||
throw DxvkError("Device reset failed");
|
||||
}
|
||||
}
|
||||
|
||||
void getPresentParams(D3DPRESENT_PARAMETERS& params) {
|
||||
params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
params.BackBufferCount = 1;
|
||||
params.BackBufferFormat = D3DFMT_X8R8G8B8;
|
||||
params.BackBufferWidth = m_windowSize.w;
|
||||
params.BackBufferHeight = m_windowSize.h;
|
||||
params.EnableAutoDepthStencil = 0;
|
||||
params.Flags = 0;
|
||||
params.FullScreen_RefreshRateInHz = 0;
|
||||
params.hDeviceWindow = m_window;
|
||||
params.MultiSampleQuality = 0;
|
||||
params.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
params.Windowed = TRUE;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
HWND m_window;
|
||||
Extent2D m_windowSize = { 1024, 600 };
|
||||
|
||||
Com<IDirect3D9Ex> m_d3d;
|
||||
Com<IDirect3DDevice9Ex> m_device;
|
||||
|
||||
Com<IDirect3DVertexShader9> m_vs;
|
||||
Com<IDirect3DPixelShader9> m_ps;
|
||||
Com<IDirect3DVertexBuffer9> m_vb;
|
||||
Com<IDirect3DVertexDeclaration9> m_decl;
|
||||
|
||||
};
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
HWND hWnd;
|
||||
WNDCLASSEXW wc;
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSEX));
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
wc.lpszClassName = L"WindowClass1";
|
||||
RegisterClassExW(&wc);
|
||||
|
||||
hWnd = CreateWindowExW(0,
|
||||
L"WindowClass1",
|
||||
L"Our First Windowed Program",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
300, 300,
|
||||
640, 480,
|
||||
nullptr,
|
||||
nullptr,
|
||||
hInstance,
|
||||
nullptr);
|
||||
ShowWindow(hWnd, nCmdShow);
|
||||
|
||||
MSG msg;
|
||||
|
||||
try {
|
||||
TriangleApp app(hInstance, hWnd);
|
||||
|
||||
while (true) {
|
||||
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
return msg.wParam;
|
||||
} else {
|
||||
app.run();
|
||||
}
|
||||
}
|
||||
} catch (const dxvk::DxvkError& e) {
|
||||
std::cerr << e.message() << std::endl;
|
||||
return msg.wParam;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
switch (message) {
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
@ -1 +0,0 @@
|
||||
subdir('d3d9')
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../src/util/com/com_guid.h"
|
||||
#include "../src/util/com/com_object.h"
|
||||
#include "../src/util/com/com_pointer.h"
|
||||
|
||||
#include "../src/util/log/log.h"
|
||||
#include "../src/util/log/log_debug.h"
|
||||
|
||||
#include "../src/util/rc/util_rc.h"
|
||||
#include "../src/util/rc/util_rc_ptr.h"
|
||||
|
||||
#include "../src/util/util_enum.h"
|
||||
#include "../src/util/util_error.h"
|
||||
#include "../src/util/util_string.h"
|
Loading…
x
Reference in New Issue
Block a user