ArkNESS

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

thekamal
Posts: 9
Joined: Fri Mar 04, 2022 4:25 pm

ArkNESS

Post by thekamal »

HI all,

I've just released the initial version of my NES emulator called ArkNESS. I built this around the idea of trying to do as much of the PPU processing on the GPU. It doesn't require a very powerful GPU (my Ryzen 3 APU w/Vega graphics laptop works just fine), but it does need DX12 (so Win10 or WIn11) with a shader model 5.0 GPU.

https://github.com/thekamalp/ArkNESS/re ... rel0.1.zip

It supports many of the more popular mappers (0, 1, 2, 3, 4, 5, 7, 9, 69, 71 to be exact), and I ran roughly 150 games (although not very far in each), and at least one game in the each of the tricky-to-emulate categories.

It only uses NTSC timing for now, but many PAL games do "just work", although I haven't tested many PAL titles.

Let me know what you think of it. Any feedback (good, bad or otherwise) is always welcome.

And thank you to all who contribute to this board and wiki page. I couldn't have done this without the invaluable information posted here.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: ArkNESS

Post by Dwedit »

Tried it out.
There's a crash in K3.dll shortly after you attempt to run the program, reading from 00000008 (Access violation).
The offending function is "k3win32Dx12WinImpl::ResizeBackBuffer", when it calls "k3gfxObj::getImpl".
Stack trace shows that "k3winObj::Create" is the first K3 related thing the program calls, and the error happens within K3 after that.


If you weren't running with a debugger attached, you'd simply see the program fail to do anything upon running it.


Edit:

Found the code for K3...

void k3win32Dx12WinImpl::ResizeBackBuffer()
{
DXGI_FORMAT dxgi_fmt = ConvertToDXGIFormat(_color_fmt, k3DxgiSurfaceType::COLOR);
UINT swap_chain_flags = 0;
HRESULT hr;
uint32_t n;

k3gfxImpl* gfxImpl = gfx->getImpl(); // <- dies inside this function, tries to read 8 bytes after a null pointer
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: ArkNESS

Post by Quietust »

The first time I tried running it (on a Surface Book which I otherwise rarely use, which apparently has a custom GeForce 940M GPU variant), it complained that zlib1.dll was missing. Once I fixed that (by giving it a 32-bit version of roughly the same vintage as the bundled freetype6.dll), I got what I'm assuming is the exact same k3.dll crash Dwedit described above:

Code: Select all

Problem Event Name:	APPCRASH
Application Name:	ArkNESS.exe
Application Version:	0.0.0.0
Application Timestamp:	62217779
Fault Module Name:	k3.dll
Fault Module Version:	0.0.0.0
Fault Module Timestamp:	621ecc95
Exception Code:	c0000005
Exception Offset:	00021da0
OS Version:	10.0.19044.2.0.0.256.48
Locale ID:	1033
Additional Information 1:	2beb
Additional Information 2:	2beba6fb4680d73a8c78ca7c24ccdb46
Additional Information 3:	d2cb
Additional Information 4:	d2cbb00663312a7bb5565a7450e897dd
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
thekamal
Posts: 9
Joined: Fri Mar 04, 2022 4:25 pm

Re: ArkNESS

Post by thekamal »

I think it's failing to create the D3D12 device, and I'm not catching it and gracefully exiting (shame on me). I created the debug version of this, and added some checks for anything bad happening at initialization. It should now print a message box on what exactly is not being created properly, and should exit without a fault (did some crude testing by forcing some functions to fail).

I also included zlib1.dll. Didn't realize freetype required it.
Attachments
ArkNESS-dbg0.1.zip
(2.98 MiB) Downloaded 39 times
thekamal
Posts: 9
Joined: Fri Mar 04, 2022 4:25 pm

Re: ArkNESS

Post by thekamal »

I think I know what I did wrong. I ask for feature level 12_0, even though I don't actually use anything related to it (like shader model 6). I changed it to feature level 11, which should be compatible with more devices.

https://github.com/thekamalp/ArkNESS/re ... el0.1a.zip
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: ArkNESS

Post by Dwedit »

Getting the error message "Could not create sampler heap".

Code: Select all

    D3D12_DESCRIPTOR_HEAP_DESC desc_heap_desc;
    desc_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
    desc_heap_desc.NumDescriptors = num_views;
    desc_heap_desc.NodeMask = 0;
    desc_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
    hr = gfx->_data->_dev->CreateDescriptorHeap(&desc_heap_desc, IID_PPV_ARGS(&gfx->_data->_shader_heap[0]));
    if (hr != S_OK) {
        k3error::Handler("Could not create descriptor heap", "k3gfxObj::Create");
        return NULL;
    }
    desc_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
    desc_heap_desc.NumDescriptors = num_samplers;
    hr = gfx->_data->_dev->CreateDescriptorHeap(&desc_heap_desc, IID_PPV_ARGS(&gfx->_data->_shader_heap[1]));
    if (hr != S_OK) {
        k3error::Handler("Could not create sampler heap", "k3gfxObj::Create");
        return NULL;
    }
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
thekamal
Posts: 9
Joined: Fri Mar 04, 2022 4:25 pm

Re: ArkNESS

Post by thekamal »

I think I found my problem. This program does not need dynamic samplers, so it sets the sampler heap size to 0, so k3 attempts to create a 0 sized heap. My AMD drivers (and the dx12 debug layer) seems to fine with this, but this is obviously failing in other drivers, and clearly doesn't make any sense.

I also noticed an unrelated missing transition barrier that the debug layer reported. Fixed that as well.

https://github.com/thekamalp/ArkNESS/re ... el0.1b.zip
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: ArkNESS

Post by Dwedit »

K3.dll missing
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
thekamal
Posts: 9
Joined: Fri Mar 04, 2022 4:25 pm

Re: ArkNESS

Post by thekamal »

Sorry, getting a little sloppy...

Try this.

https://github.com/thekamalp/ArkNESS/re ... el0.1c.zip
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: ArkNESS

Post by Dwedit »

Now it runs, but it triggers a Stack Overflow exception if I try to pick a large directory.

Perhaps consider using a normal Win32 file dialog, those let you type in file paths easily. I can't even pick drive letters with that file picker.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
WedNESday
Posts: 1284
Joined: Thu Sep 15, 2005 9:23 am
Location: Berlin, Germany
Contact:

Re: ArkNESS

Post by WedNESday »

1. Just out of interest, any particular reason as to why you're offloading as much work as possible onto the GPU?

2. Not everyone will have a GPU that is D3D12 compatible. Consider toning down the D3D requirements to reach more users. For instance, WedNESday previously managed perfectly fine with just D3D8.
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: ArkNESS

Post by Quietust »

WedNESday wrote: Sun Mar 06, 2022 9:31 am 2. Not everyone will have a GPU that is D3D12 compatible.
For that matter, there are still people out there whose operating systems are not D3D12-compatible - Windows 8.1 is on its final year of extended support, and there are even people out there running Windows 7.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: ArkNESS

Post by Dwedit »

I think the intent here was a proof-of-concept for running more of the PPU on the GPU, and possibly learning how to use D3D12.

D3D8 might be way too old. Direct3D 9.0c was its ultimate replacement on 98/2000/XP, and D3D9 is not considered deprecated today.

The old video cards of the D3D9 era don't like dependent texture reads. Either they would not work at all, or would be slow. But emulating a NES PPU would have lots of dependent texture reads.
First, you need to know coordinates, and what the correct mirroring mode is at that pixel. Then you can perform the Nametable and Attribute Table fetch. Then you can perform the Pattern Table fetch and decode, and addition of attributes to the value. Then you lookup the palette from there.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
thekamal
Posts: 9
Joined: Fri Mar 04, 2022 4:25 pm

Re: ArkNESS

Post by thekamal »

> I think the intent here was a proof-of-concept for running more of the PPU on the GPU, and possibly learning how to use D3D12.
Yes that's exactly right...I could have done this in dx11, but I wanted to learn dx12 (and there is a fairly steep learning curve to it). And using the GPU does lighten the load on the CPU by quite a bit (although, this is mostly academic...most platforms with a dx12 capable GPU would almost certainly have a powerful enough CPU to do the PPU processing).

As for going to dx9, the biggest issue is not having bit manipulation in the shader language (I believe it was introduced in shadel 5). And there is a lot of dependent texture fetches and Dwedit mentions...I think I'm using 3 levels of indirection...nametable -> pattern -> palette.

I'm working on Dwedit suggestion of using the win32 open dialog instead of my own. The main reason I crafted my own is to create a platform agnostic interface with the same look and feel, and I also wanted to be able to control the menu entirely using the joypad. I hope one day to eventually port it over to a mobile platform. But I agree it's a bit more painful to use than the windows dialog.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: ArkNESS

Post by Dwedit »

Android basically requires you to use their file dialog now, otherwise you can't access files.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Post Reply