D3D12Renderer: fixed some compilation errors

Removed GSFrameBase2 and D3DGSFrame.
Added frame for NullRender.
Minor improvements and fixes
This commit is contained in:
DH 2015-10-05 03:42:48 +03:00
parent 1c890f85c5
commit 4fdeeace66
30 changed files with 609 additions and 677 deletions

View file

@ -10,17 +10,15 @@ struct MipmapLevelInfo
size_t rowPitch; size_t rowPitch;
}; };
unsigned LinearToSwizzleAddress(unsigned x, unsigned y, unsigned z, unsigned log2_width, unsigned log2_height, unsigned log2_depth);
/** /**
* Get size to store texture in a linear fashion. * Get size to store texture in a linear fashion.
* Storage is assumed to use a rowPitchAlignement boundary for every row of texture. * Storage is assumed to use a rowPitchAlignement boundary for every row of texture.
*/ */
size_t getPlacedTextureStorageSpace(const RSXTexture &texture, size_t rowPitchAlignement); size_t getPlacedTextureStorageSpace(const rsx::texture &texture, size_t rowPitchAlignement);
/** /**
* Write texture data to textureData. * Write texture data to textureData.
* Data are not packed, they are stored per rows using rowPitchAlignement. * Data are not packed, they are stored per rows using rowPitchAlignement.
* Similarly, offset for every mipmaplevel is aligned to rowPitchAlignement boundary. * Similarly, offset for every mipmaplevel is aligned to rowPitchAlignement boundary.
*/ */
std::vector<MipmapLevelInfo> uploadPlacedTexture(const RSXTexture &texture, size_t rowPitchAlignement, void* textureData); std::vector<MipmapLevelInfo> uploadPlacedTexture(const rsx::texture &texture, size_t rowPitchAlignement, void* textureData);

View file

@ -33,13 +33,6 @@ static void unloadD3D12FunctionPointers()
FreeLibrary(D3D11Module); FreeLibrary(D3D11Module);
} }
GetGSFrameCb2 GetGSFrame = nullptr;
void SetGetD3DGSFrameCallback(GetGSFrameCb2 value)
{
GetGSFrame = value;
}
void D3D12GSRender::ResourceStorage::Reset() void D3D12GSRender::ResourceStorage::Reset()
{ {
m_constantsBufferIndex = 0; m_constantsBufferIndex = 0;
@ -136,7 +129,7 @@ D3D12DLLManagement::~D3D12DLLManagement()
} }
D3D12GSRender::D3D12GSRender() D3D12GSRender::D3D12GSRender()
: GSRender(), m_D3D12Lib(), m_PSO(nullptr) : GSRender(frame_type::DX12), m_D3D12Lib(), m_PSO(nullptr)
{ {
m_previous_address_a = 0; m_previous_address_a = 0;
m_previous_address_b = 0; m_previous_address_b = 0;
@ -174,13 +167,14 @@ D3D12GSRender::D3D12GSRender()
g_descriptorStrideRTV = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); g_descriptorStrideRTV = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
g_descriptorStrideSamplers = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); g_descriptorStrideSamplers = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
m_frame = GetGSFrame(); DXGI_ADAPTER_DESC adaptaterDesc;
adaptater->GetDesc(&adaptaterDesc);
m_frame->title_message(adaptaterDesc.Description);
// Create swap chain and put them in a descriptor heap as rendertarget // Create swap chain and put them in a descriptor heap as rendertarget
DXGI_SWAP_CHAIN_DESC swapChain = {}; DXGI_SWAP_CHAIN_DESC swapChain = {};
swapChain.BufferCount = 2; swapChain.BufferCount = 2;
swapChain.Windowed = true; swapChain.Windowed = true;
swapChain.OutputWindow = m_frame->getHandle(); swapChain.OutputWindow = (HWND)m_frame->handle();
swapChain.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChain.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChain.SampleDesc.Count = 1; swapChain.SampleDesc.Count = 1;
@ -297,40 +291,20 @@ D3D12GSRender::~D3D12GSRender()
ReleaseD2DStructures(); ReleaseD2DStructures();
} }
void D3D12GSRender::Close() void D3D12GSRender::oninit_thread()
{
if (joinable())
{
join();
}
if (m_frame->IsShown())
{
m_frame->Hide();
}
}
void D3D12GSRender::OnInit()
{
m_frame->Show();
}
void D3D12GSRender::OnInitThread()
{ {
} }
void D3D12GSRender::OnExitThread() void D3D12GSRender::onexit_thread()
{ {
} }
void D3D12GSRender::OnReset() void D3D12GSRender::clear_surface(u32 arg)
{ {
} if ((arg & 0xf3) == 0)
return;
void D3D12GSRender::Clear(u32 cmd)
{
std::chrono::time_point<std::chrono::system_clock> startDuration = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> startDuration = std::chrono::system_clock::now();
assert(cmd == NV4097_CLEAR_SURFACE);
std::chrono::time_point<std::chrono::system_clock> rttDurationStart = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> rttDurationStart = std::chrono::system_clock::now();
PrepareRenderTargets(getCurrentResourceStorage().m_commandList.Get()); PrepareRenderTargets(getCurrentResourceStorage().m_commandList.Get());
@ -338,64 +312,77 @@ void D3D12GSRender::Clear(u32 cmd)
std::chrono::time_point<std::chrono::system_clock> rttDurationEnd = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> rttDurationEnd = std::chrono::system_clock::now();
m_timers.m_rttDuration += std::chrono::duration_cast<std::chrono::microseconds>(rttDurationEnd - rttDurationStart).count(); m_timers.m_rttDuration += std::chrono::duration_cast<std::chrono::microseconds>(rttDurationEnd - rttDurationStart).count();
/* if (m_set_color_mask) u32 scissor_horizontal = rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL];
{ u32 scissor_vertical = rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL];
glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); u16 scissor_x = scissor_horizontal;
checkForGlError("glColorMask"); u16 scissor_w = scissor_horizontal >> 16;
} u16 scissor_y = scissor_vertical;
u16 scissor_h = scissor_vertical >> 16;
if (m_set_scissor_horizontal && m_set_scissor_vertical) D3D12_RECT scissor;
{ scissor.left = scissor_x;
glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); scissor.top = scissor_y;
checkForGlError("glScissor"); scissor.right = scissor_x + scissor_w;
}*/ scissor.bottom = scissor_y + scissor_h;
// TODO: Merge depth and stencil clear when possible // TODO: Merge depth and stencil clear when possible
if (m_clear_surface_mask & 0x1) if (arg & 0x1)
{ {
u32 max_depth_value = m_surface_depth_format == CELL_GCM_SURFACE_Z16 ? 0x0000ffff : 0x00ffffff; u32 surface_depth_format = (rsx::method_registers[NV4097_SET_SURFACE_FORMAT] >> 5) & 0x7;
getCurrentResourceStorage().m_commandList->ClearDepthStencilView(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, m_clear_surface_z / (float)max_depth_value, 0, 0, nullptr); u32 max_depth_value = surface_depth_format == CELL_GCM_SURFACE_Z16 ? 0x0000ffff : 0x00ffffff;
u32 clear_depth = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8;
getCurrentResourceStorage().m_commandList->ClearDepthStencilView(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, clear_depth / (float)max_depth_value, 0, 0, &scissor);
} }
if (m_clear_surface_mask & 0x2) if (arg & 0x2)
getCurrentResourceStorage().m_commandList->ClearDepthStencilView(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_STENCIL, 0.f, m_clear_surface_s, 0, nullptr);
if (m_clear_surface_mask & 0xF0)
{ {
u8 clear_stencil = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] & 0xff;
getCurrentResourceStorage().m_commandList->ClearDepthStencilView(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_STENCIL, 0.f, clear_stencil, 0, &scissor);
}
if (arg & 0xF0)
{
u32 clear_color = rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE];
u8 clear_a = clear_color >> 24;
u8 clear_r = clear_color >> 16;
u8 clear_g = clear_color >> 8;
u8 clear_b = clear_color;
float clearColor[] = float clearColor[] =
{ {
m_clear_surface_color_r / 255.0f, clear_r / 255.0f,
m_clear_surface_color_g / 255.0f, clear_g / 255.0f,
m_clear_surface_color_b / 255.0f, clear_b / 255.0f,
m_clear_surface_color_a / 255.0f clear_a / 255.0f
}; };
size_t g_RTTIncrement = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); size_t g_RTTIncrement = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
switch (m_surface_color_target) switch (u32 color_target = rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])
{ {
case CELL_GCM_SURFACE_TARGET_NONE: break; case CELL_GCM_SURFACE_TARGET_NONE: break;
case CELL_GCM_SURFACE_TARGET_0: case CELL_GCM_SURFACE_TARGET_0:
case CELL_GCM_SURFACE_TARGET_1: case CELL_GCM_SURFACE_TARGET_1:
getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()), clearColor, 0, nullptr); getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()), clearColor, 0, &scissor);
break; break;
case CELL_GCM_SURFACE_TARGET_MRT1: case CELL_GCM_SURFACE_TARGET_MRT1:
getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()), clearColor, 0, nullptr); getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()), clearColor, 0, &scissor);
getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideRTV), clearColor, 0, nullptr); getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideRTV), clearColor, 0, &scissor);
break; break;
case CELL_GCM_SURFACE_TARGET_MRT2: case CELL_GCM_SURFACE_TARGET_MRT2:
getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()), clearColor, 0, nullptr); getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()), clearColor, 0, &scissor);
getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideRTV), clearColor, 0, nullptr); getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideRTV), clearColor, 0, &scissor);
getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(2, g_descriptorStrideRTV), clearColor, 0, nullptr); getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(2, g_descriptorStrideRTV), clearColor, 0, &scissor);
break; break;
case CELL_GCM_SURFACE_TARGET_MRT3: case CELL_GCM_SURFACE_TARGET_MRT3:
getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()), clearColor, 0, nullptr); getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()), clearColor, 0, &scissor);
getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideRTV), clearColor, 0, nullptr); getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptorStrideRTV), clearColor, 0, &scissor);
getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(2, g_descriptorStrideRTV), clearColor, 0, nullptr); getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(2, g_descriptorStrideRTV), clearColor, 0, &scissor);
getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(3, g_descriptorStrideRTV), clearColor, 0, nullptr); getCurrentResourceStorage().m_commandList->ClearRenderTargetView(CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart()).Offset(3, g_descriptorStrideRTV), clearColor, 0, &scissor);
break; break;
default: default:
LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target); LOG_ERROR(RSX, "Bad surface color target: %d", color_target);
} }
} }
@ -411,7 +398,24 @@ void D3D12GSRender::Clear(u32 cmd)
} }
} }
void D3D12GSRender::Draw() bool D3D12GSRender::domethod(u32 id, u32 arg)
{
switch (id)
{
case NV4097_CLEAR_SURFACE:
clear_surface(arg);
return true;
default:
return false;
}
}
void D3D12GSRender::begin()
{
}
void D3D12GSRender::end()
{ {
std::chrono::time_point<std::chrono::system_clock> startDuration = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> startDuration = std::chrono::system_clock::now();
@ -424,9 +428,10 @@ void D3D12GSRender::Draw()
std::chrono::time_point<std::chrono::system_clock> vertexIndexDurationStart = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> vertexIndexDurationStart = std::chrono::system_clock::now();
// Init vertex count // Init vertex count
if (m_indexed_array.m_count) if (!vertex_index_array.empty())
{ {
for (u32 i = 0; i < m_vertex_count; ++i) /*
for (u32 i = 0; i < rsx::limits::vertex_count; ++i)
{ {
if (!m_vertex_data[i].IsEnabled()) continue; if (!m_vertex_data[i].IsEnabled()) continue;
if (!m_vertex_data[i].addr) continue; if (!m_vertex_data[i].addr) continue;
@ -434,24 +439,25 @@ void D3D12GSRender::Draw()
const u32 tsize = m_vertex_data[i].GetTypeSize(); const u32 tsize = m_vertex_data[i].GetTypeSize();
m_vertexBufferSize[i] = (m_indexed_array.index_min + m_indexed_array.index_max - m_indexed_array.index_min + 1) * tsize * m_vertex_data[i].size; m_vertexBufferSize[i] = (m_indexed_array.index_min + m_indexed_array.index_max - m_indexed_array.index_min + 1) * tsize * m_vertex_data[i].size;
} }
*/
} }
else else
{ {
for (u32 i = 0; i < m_vertex_count; ++i) for (u32 i = 0; i < rsx::limits::vertex_count; ++i)
{ {
if (!m_vertex_data[i].IsEnabled()) continue; auto &info = vertex_arrays_info[i];
if (!m_vertex_data[i].addr) continue; if (info.size == 0)
continue;
const u32 tsize = m_vertex_data[i].GetTypeSize(); m_vertexBufferSize[i] = (draw_array_first + draw_array_count) * rsx::get_vertex_type_size(info.type) * info.size;
m_vertexBufferSize[i] = (m_draw_array_first + m_draw_array_count) * tsize * m_vertex_data[i].size;
} }
} }
if (m_indexed_array.m_count || m_draw_array_count) if (draw_array_count)
{ {
const std::vector<D3D12_VERTEX_BUFFER_VIEW> &vertexBufferViews = UploadVertexBuffers(m_indexed_array.m_count ? true : false); const std::vector<D3D12_VERTEX_BUFFER_VIEW> &vertexBufferViews = UploadVertexBuffers(!vertex_index_array.empty());
const D3D12_INDEX_BUFFER_VIEW &indexBufferView = uploadIndexBuffers(m_indexed_array.m_count ? true : false); const D3D12_INDEX_BUFFER_VIEW &indexBufferView = uploadIndexBuffers(!vertex_index_array.empty());
getCurrentResourceStorage().m_commandList->IASetVertexBuffers(0, (UINT)vertexBufferViews.size(), vertexBufferViews.data()); getCurrentResourceStorage().m_commandList->IASetVertexBuffers(0, (UINT)vertexBufferViews.size(), vertexBufferViews.data());
if (m_renderingInfo.m_indexed) if (m_renderingInfo.m_indexed)
getCurrentResourceStorage().m_commandList->IASetIndexBuffer(&indexBufferView); getCurrentResourceStorage().m_commandList->IASetIndexBuffer(&indexBufferView);
@ -471,7 +477,7 @@ void D3D12GSRender::Draw()
m_timers.m_programLoadDuration += std::chrono::duration_cast<std::chrono::microseconds>(programLoadEnd - programLoadStart).count(); m_timers.m_programLoadDuration += std::chrono::duration_cast<std::chrono::microseconds>(programLoadEnd - programLoadStart).count();
getCurrentResourceStorage().m_commandList->SetGraphicsRootSignature(m_rootSignatures[m_PSO->second].Get()); getCurrentResourceStorage().m_commandList->SetGraphicsRootSignature(m_rootSignatures[m_PSO->second].Get());
getCurrentResourceStorage().m_commandList->OMSetStencilRef(m_stencil_func_ref); getCurrentResourceStorage().m_commandList->OMSetStencilRef(rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF]);
std::chrono::time_point<std::chrono::system_clock> constantsDurationStart = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> constantsDurationStart = std::chrono::system_clock::now();
@ -553,7 +559,7 @@ void D3D12GSRender::Draw()
m_timers.m_textureDuration += std::chrono::duration_cast<std::chrono::microseconds>(textureDurationEnd - textureDurationStart).count(); m_timers.m_textureDuration += std::chrono::duration_cast<std::chrono::microseconds>(textureDurationEnd - textureDurationStart).count();
size_t numRTT; size_t numRTT;
switch (m_surface_color_target) switch (u32 color_target = rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])
{ {
case CELL_GCM_SURFACE_TARGET_NONE: break; case CELL_GCM_SURFACE_TARGET_NONE: break;
case CELL_GCM_SURFACE_TARGET_0: case CELL_GCM_SURFACE_TARGET_0:
@ -570,18 +576,24 @@ void D3D12GSRender::Draw()
numRTT = 4; numRTT = 4;
break; break;
default: default:
LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target); LOG_ERROR(RSX, "Bad surface color target: %d", color_target);
} }
getCurrentResourceStorage().m_commandList->OMSetRenderTargets((UINT)numRTT, &m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(), true, getCurrentResourceStorage().m_commandList->OMSetRenderTargets((UINT)numRTT, &m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(), true,
&CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart())); &CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart()));
u32 clip_horizontal = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL];
u32 clip_vertical = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL];
u32 clip_width = clip_horizontal >> 16;
u32 clip_height = clip_vertical >> 16;
D3D12_VIEWPORT viewport = D3D12_VIEWPORT viewport =
{ {
0.f, 0.f,
0.f, 0.f,
(float)m_surface_clip_w, (float)clip_width,
(float)m_surface_clip_h, (float)clip_height,
-1.f, -1.f,
1.f 1.f
}; };
@ -591,12 +603,12 @@ void D3D12GSRender::Draw()
{ {
0, 0,
0, 0,
(LONG)m_surface_clip_w, (LONG)clip_width,
(LONG)m_surface_clip_h, (LONG)clip_height,
}; };
getCurrentResourceStorage().m_commandList->RSSetScissorRects(1, &box); getCurrentResourceStorage().m_commandList->RSSetScissorRects(1, &box);
switch (m_draw_mode - 1) switch (draw_mode - 1)
{ {
case GL_POINTS: case GL_POINTS:
getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_POINTLIST); getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
@ -633,7 +645,6 @@ void D3D12GSRender::Draw()
else else
getCurrentResourceStorage().m_commandList->DrawInstanced((UINT)m_renderingInfo.m_count, 1, (UINT)m_renderingInfo.m_baseVertex, 0); getCurrentResourceStorage().m_commandList->DrawInstanced((UINT)m_renderingInfo.m_count, 1, (UINT)m_renderingInfo.m_baseVertex, 0);
m_indexed_array.Reset();
std::chrono::time_point<std::chrono::system_clock> endDuration = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> endDuration = std::chrono::system_clock::now();
m_timers.m_drawCallDuration += std::chrono::duration_cast<std::chrono::microseconds>(endDuration - startDuration).count(); m_timers.m_drawCallDuration += std::chrono::duration_cast<std::chrono::microseconds>(endDuration - startDuration).count();
m_timers.m_drawCallCount++; m_timers.m_drawCallCount++;
@ -663,12 +674,12 @@ isFlipSurfaceInLocalMemory(u32 surfaceColorTarget)
} }
} }
void D3D12GSRender::Flip() void D3D12GSRender::flip(int buffer)
{ {
ID3D12Resource *resourceToFlip; ID3D12Resource *resourceToFlip;
float viewport_w, viewport_h; float viewport_w, viewport_h;
if (!isFlipSurfaceInLocalMemory(m_surface_color_target)) if (!isFlipSurfaceInLocalMemory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
{ {
ResourceStorage &storage = getCurrentResourceStorage(); ResourceStorage &storage = getCurrentResourceStorage();
assert(storage.m_RAMFramebuffer == nullptr); assert(storage.m_RAMFramebuffer == nullptr);
@ -676,12 +687,11 @@ void D3D12GSRender::Flip()
size_t w = 0, h = 0, rowPitch = 0; size_t w = 0, h = 0, rowPitch = 0;
size_t offset = 0; size_t offset = 0;
if (m_read_buffer) if (false/*m_read_buffer*/)
{ {
CellGcmDisplayInfo* buffers = vm::get_ptr<CellGcmDisplayInfo>(m_gcm_buffers_addr); u32 addr = rsx::get_address(gcm_buffers[gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL);
u32 addr = GetAddress(buffers[m_gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL); w = gcm_buffers[gcm_current_buffer].width;
w = buffers[m_gcm_current_buffer].width; h = gcm_buffers[gcm_current_buffer].height;
h = buffers[m_gcm_current_buffer].height;
u8 *src_buffer = vm::get_ptr<u8>(addr); u8 *src_buffer = vm::get_ptr<u8>(addr);
rowPitch = align(w * 4, 256); rowPitch = align(w * 4, 256);
@ -751,7 +761,7 @@ void D3D12GSRender::Flip()
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = 1; srvDesc.Texture2D.MipLevels = 1;
if (isFlipSurfaceInLocalMemory(m_surface_color_target)) if (isFlipSurfaceInLocalMemory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
else else
srvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( srvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
@ -792,7 +802,7 @@ void D3D12GSRender::Flip()
if (!Ini.GSOverlay.GetValue()) if (!Ini.GSOverlay.GetValue())
getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backBuffer[m_swapChain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
if (isFlipSurfaceInLocalMemory(m_surface_color_target) && m_rtts.m_currentlyBoundRenderTargets[0] != nullptr) if (isFlipSurfaceInLocalMemory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) && m_rtts.m_currentlyBoundRenderTargets[0] != nullptr)
getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET)); getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.m_currentlyBoundRenderTargets[0], D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET));
ThrowIfFailed(getCurrentResourceStorage().m_commandList->Close()); ThrowIfFailed(getCurrentResourceStorage().m_commandList->Close());
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().m_commandList.GetAddressOf()); m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)getCurrentResourceStorage().m_commandList.GetAddressOf());
@ -841,8 +851,7 @@ void D3D12GSRender::Flip()
m_UAVHeap.m_getPos = newStorage.m_getPosUAVHeap; m_UAVHeap.m_getPos = newStorage.m_getPosUAVHeap;
} }
m_frame->Flip(nullptr); m_frame->flip(nullptr);
std::chrono::time_point<std::chrono::system_clock> flipEnd = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> flipEnd = std::chrono::system_clock::now();
m_timers.m_flipDuration += std::chrono::duration_cast<std::chrono::microseconds>(flipEnd - flipStart).count(); m_timers.m_flipDuration += std::chrono::duration_cast<std::chrono::microseconds>(flipEnd - flipStart).count();
@ -874,10 +883,14 @@ D3D12GSRender::ResourceStorage& D3D12GSRender::getNonCurrentResourceStorage()
ID3D12Resource * D3D12GSRender::writeColorBuffer(ID3D12Resource * RTT, ID3D12GraphicsCommandList * cmdlist) ID3D12Resource * D3D12GSRender::writeColorBuffer(ID3D12Resource * RTT, ID3D12GraphicsCommandList * cmdlist)
{ {
ID3D12Resource *Result; ID3D12Resource *Result;
size_t w = m_surface_clip_w, h = m_surface_clip_h;
u32 clip_width = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16;
u32 clip_height = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16;
size_t w = clip_width, h = clip_height;
DXGI_FORMAT dxgiFormat; DXGI_FORMAT dxgiFormat;
size_t rowPitch; size_t rowPitch;
switch (m_surface_color_format) switch (rsx::method_registers[NV4097_SET_SURFACE_FORMAT] & 0x1f)
{ {
case CELL_GCM_SURFACE_A8R8G8B8: case CELL_GCM_SURFACE_A8R8G8B8:
dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM; dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
@ -943,17 +956,33 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
HANDLE handle = CreateEvent(0, FALSE, FALSE, 0); HANDLE handle = CreateEvent(0, FALSE, FALSE, 0);
fence->SetEventOnCompletion(1, handle); fence->SetEventOnCompletion(1, handle);
u32 clip_width = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16;
u32 clip_height = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16;
ComPtr<ID3D12Resource> writeDest, depthConverted; ComPtr<ID3D12Resource> writeDest, depthConverted;
ComPtr<ID3D12DescriptorHeap> descriptorHeap; ComPtr<ID3D12DescriptorHeap> descriptorHeap;
size_t depthRowPitch = m_surface_clip_w; size_t depthRowPitch = clip_width;
depthRowPitch = (depthRowPitch + 255) & ~255; depthRowPitch = (depthRowPitch + 255) & ~255;
bool needTransfer = (m_set_context_dma_z && Ini.GSDumpDepthBuffer.GetValue()) || u32 dma_color_a = rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_A];
((m_set_context_dma_color_a || m_set_context_dma_color_b || m_set_context_dma_color_c || m_set_context_dma_color_d) && Ini.GSDumpColorBuffers.GetValue()); u32 dma_color_b = rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_B];
u32 dma_color_c = rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_C];
u32 dma_color_d = rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_D];
u32 dma_z = rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA];
if (m_set_context_dma_z && Ini.GSDumpDepthBuffer.GetValue()) u32 offset_color_a = rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET];
u32 offset_color_b = rsx::method_registers[NV4097_SET_SURFACE_COLOR_BOFFSET];
u32 offset_color_c = rsx::method_registers[NV4097_SET_SURFACE_COLOR_COFFSET];
u32 offset_color_d = rsx::method_registers[NV4097_SET_SURFACE_COLOR_DOFFSET];
u32 offset_z = rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET];
bool needTransfer = (dma_z && Ini.GSDumpDepthBuffer.GetValue()) ||
((dma_color_a || dma_color_b || dma_color_c || dma_color_d) && Ini.GSDumpColorBuffers.GetValue());
if (dma_z && Ini.GSDumpDepthBuffer.GetValue())
{ {
size_t sizeInByte = m_surface_clip_w * m_surface_clip_h * 2; size_t sizeInByte = clip_width * clip_height * 2;
assert(m_UAVHeap.canAlloc(sizeInByte)); assert(m_UAVHeap.canAlloc(sizeInByte));
size_t heapOffset = m_UAVHeap.alloc(sizeInByte); size_t heapOffset = m_UAVHeap.alloc(sizeInByte);
@ -961,14 +990,14 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
m_device->CreatePlacedResource( m_device->CreatePlacedResource(
m_UAVHeap.m_heap, m_UAVHeap.m_heap,
heapOffset, heapOffset,
&CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8_UNORM, m_surface_clip_w, m_surface_clip_h, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS), &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8_UNORM, clip_width, clip_height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS),
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
nullptr, nullptr,
IID_PPV_ARGS(depthConverted.GetAddressOf()) IID_PPV_ARGS(depthConverted.GetAddressOf())
) )
); );
sizeInByte = depthRowPitch * m_surface_clip_h; sizeInByte = depthRowPitch * clip_height;
assert(m_readbackResources.canAlloc(sizeInByte)); assert(m_readbackResources.canAlloc(sizeInByte));
heapOffset = m_readbackResources.alloc(sizeInByte); heapOffset = m_readbackResources.alloc(sizeInByte);
@ -988,7 +1017,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
m_device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(descriptorHeap.GetAddressOf())) m_device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(descriptorHeap.GetAddressOf()))
); );
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
switch (m_surface_depth_format) switch (u32 depth_format = ((rsx::method_registers[NV4097_SET_SURFACE_FORMAT] >> 5) & 0x7))
{ {
case 0: case 0:
break; break;
@ -999,7 +1028,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
break; break;
default: default:
LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface_depth_format); LOG_ERROR(RSX, "Bad depth format! (%d)", depth_format);
assert(0); assert(0);
} }
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
@ -1020,7 +1049,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
getCurrentResourceStorage().m_commandList->SetComputeRootSignature(m_convertRootSignature); getCurrentResourceStorage().m_commandList->SetComputeRootSignature(m_convertRootSignature);
getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, descriptorHeap.GetAddressOf()); getCurrentResourceStorage().m_commandList->SetDescriptorHeaps(1, descriptorHeap.GetAddressOf());
getCurrentResourceStorage().m_commandList->SetComputeRootDescriptorTable(0, descriptorHeap->GetGPUDescriptorHandleForHeapStart()); getCurrentResourceStorage().m_commandList->SetComputeRootDescriptorTable(0, descriptorHeap->GetGPUDescriptorHandleForHeapStart());
getCurrentResourceStorage().m_commandList->Dispatch(m_surface_clip_w / 8, m_surface_clip_h / 8, 1); getCurrentResourceStorage().m_commandList->Dispatch(clip_width / 8, clip_height / 8, 1);
D3D12_RESOURCE_BARRIER barriers[] = D3D12_RESOURCE_BARRIER barriers[] =
{ {
@ -1029,52 +1058,50 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
}; };
getCurrentResourceStorage().m_commandList->ResourceBarrier(2, barriers); getCurrentResourceStorage().m_commandList->ResourceBarrier(2, barriers);
getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(depthConverted.Get(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE)); getCurrentResourceStorage().m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(depthConverted.Get(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE));
getCurrentResourceStorage().m_commandList->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(writeDest.Get(), { 0, { DXGI_FORMAT_R8_UNORM, m_surface_clip_w, m_surface_clip_h, 1, (UINT)depthRowPitch } }), 0, 0, 0, getCurrentResourceStorage().m_commandList->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(writeDest.Get(), { 0, { DXGI_FORMAT_R8_UNORM, clip_width, clip_height, 1, (UINT)depthRowPitch } }), 0, 0, 0,
&CD3DX12_TEXTURE_COPY_LOCATION(depthConverted.Get(), 0), nullptr); &CD3DX12_TEXTURE_COPY_LOCATION(depthConverted.Get(), 0), nullptr);
invalidateTexture(rsx::get_address(offset_z, dma_z - 0xfeed0000)); }
invalidateAddress(GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000));
}
ID3D12Resource *rtt0, *rtt1, *rtt2, *rtt3; ID3D12Resource *rtt0, *rtt1, *rtt2, *rtt3;
if (Ini.GSDumpColorBuffers.GetValue()) if (Ini.GSDumpColorBuffers.GetValue())
{ {
switch (m_surface_color_target) switch (u32 color_target = rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])
{ {
case CELL_GCM_SURFACE_TARGET_NONE: case CELL_GCM_SURFACE_TARGET_NONE:
break; break;
case CELL_GCM_SURFACE_TARGET_0: case CELL_GCM_SURFACE_TARGET_0:
if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get()); if (dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get());
break; break;
case CELL_GCM_SURFACE_TARGET_1: case CELL_GCM_SURFACE_TARGET_1:
if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get()); if (dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get());
break; break;
case CELL_GCM_SURFACE_TARGET_MRT1: case CELL_GCM_SURFACE_TARGET_MRT1:
if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get()); if (dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get());
if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], getCurrentResourceStorage().m_commandList.Get()); if (dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], getCurrentResourceStorage().m_commandList.Get());
break; break;
case CELL_GCM_SURFACE_TARGET_MRT2: case CELL_GCM_SURFACE_TARGET_MRT2:
if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get()); if (dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get());
if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], getCurrentResourceStorage().m_commandList.Get()); if (dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], getCurrentResourceStorage().m_commandList.Get());
if (m_context_dma_color_c) rtt2 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[2], getCurrentResourceStorage().m_commandList.Get()); if (dma_color_c) rtt2 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[2], getCurrentResourceStorage().m_commandList.Get());
break; break;
case CELL_GCM_SURFACE_TARGET_MRT3: case CELL_GCM_SURFACE_TARGET_MRT3:
if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get()); if (dma_color_a) rtt0 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[0], getCurrentResourceStorage().m_commandList.Get());
if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], getCurrentResourceStorage().m_commandList.Get()); if (dma_color_b) rtt1 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[1], getCurrentResourceStorage().m_commandList.Get());
if (m_context_dma_color_c) rtt2 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[2], getCurrentResourceStorage().m_commandList.Get()); if (dma_color_c) rtt2 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[2], getCurrentResourceStorage().m_commandList.Get());
if (m_context_dma_color_d) rtt3 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[3], getCurrentResourceStorage().m_commandList.Get()); if (dma_color_d) rtt3 = writeColorBuffer(m_rtts.m_currentlyBoundRenderTargets[3], getCurrentResourceStorage().m_commandList.Get());
break; break;
} }
if (m_context_dma_color_a) invalidateAddress(GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000)); if (dma_color_a) invalidateTexture(rsx::get_address(offset_color_a, dma_color_a - 0xfeed0000));
if (m_context_dma_color_b) invalidateAddress(GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000)); if (dma_color_b) invalidateTexture(rsx::get_address(offset_color_b, dma_color_b - 0xfeed0000));
if (m_context_dma_color_c) invalidateAddress(GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000)); if (dma_color_c) invalidateTexture(rsx::get_address(offset_color_c, dma_color_c - 0xfeed0000));
if (m_context_dma_color_d) invalidateAddress(GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000)); if (dma_color_d) invalidateTexture(rsx::get_address(offset_color_d, dma_color_d - 0xfeed0000));
} }
if (needTransfer) if (needTransfer)
{ {
ThrowIfFailed(getCurrentResourceStorage().m_commandList->Close()); ThrowIfFailed(getCurrentResourceStorage().m_commandList->Close());
@ -1087,103 +1114,103 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
WaitForSingleObject(handle, INFINITE); WaitForSingleObject(handle, INFINITE);
CloseHandle(handle); CloseHandle(handle);
if (m_set_context_dma_z && Ini.GSDumpDepthBuffer.GetValue()) if (dma_z && Ini.GSDumpDepthBuffer.GetValue())
{ {
u32 address = GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000); u32 address = rsx::get_address(offset_z, dma_z - 0xfeed0000);
auto ptr = vm::get_ptr<void>(address); auto ptr = vm::get_ptr<void>(address);
char *ptrAsChar = (char*)ptr; char *ptrAsChar = (char*)ptr;
unsigned char *writeDestPtr; unsigned char *writeDestPtr;
ThrowIfFailed(writeDest->Map(0, nullptr, (void**)&writeDestPtr)); ThrowIfFailed(writeDest->Map(0, nullptr, (void**)&writeDestPtr));
for (unsigned row = 0; row < m_surface_clip_h; row++) for (unsigned row = 0; row < clip_height; row++)
{ {
for (unsigned i = 0; i < m_surface_clip_w; i++) for (unsigned i = 0; i < clip_width; i++)
{ {
unsigned char c = writeDestPtr[row * depthRowPitch + i]; unsigned char c = writeDestPtr[row * depthRowPitch + i];
ptrAsChar[4 * (row * m_surface_clip_w + i)] = c; ptrAsChar[4 * (row * clip_width + i)] = c;
ptrAsChar[4 * (row * m_surface_clip_w + i) + 1] = c; ptrAsChar[4 * (row * clip_width + i) + 1] = c;
ptrAsChar[4 * (row * m_surface_clip_w + i) + 2] = c; ptrAsChar[4 * (row * clip_width + i) + 2] = c;
ptrAsChar[4 * (row * m_surface_clip_w + i) + 3] = c; ptrAsChar[4 * (row * clip_width + i) + 3] = c;
} }
} }
} }
size_t srcPitch, dstPitch; size_t srcPitch, dstPitch;
switch (m_surface_color_format) switch (rsx::method_registers[NV4097_SET_SURFACE_FORMAT] & 0x1f)
{ {
case CELL_GCM_SURFACE_A8R8G8B8: case CELL_GCM_SURFACE_A8R8G8B8:
srcPitch = align(m_surface_clip_w * 4, 256); srcPitch = align(clip_width * 4, 256);
dstPitch = m_surface_clip_w * 4; dstPitch = clip_width * 4;
break; break;
case CELL_GCM_SURFACE_F_W16Z16Y16X16: case CELL_GCM_SURFACE_F_W16Z16Y16X16:
srcPitch = align(m_surface_clip_w * 8, 256); srcPitch = align(clip_width * 8, 256);
dstPitch = m_surface_clip_w * 8; dstPitch = clip_width * 8;
break; break;
} }
if (Ini.GSDumpColorBuffers.GetValue()) if (Ini.GSDumpColorBuffers.GetValue())
{ {
switch (m_surface_color_target) switch (u32 color_target = rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])
{ {
case CELL_GCM_SURFACE_TARGET_NONE: case CELL_GCM_SURFACE_TARGET_NONE:
break; break;
case CELL_GCM_SURFACE_TARGET_0: case CELL_GCM_SURFACE_TARGET_0:
{ {
u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); u32 address = rsx::get_address(offset_color_a, dma_color_a - 0xfeed0000);
void *dstAddress = vm::get_ptr<void>(address); void *dstAddress = vm::get_ptr<void>(address);
copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, clip_width, clip_height);
} }
break; break;
case CELL_GCM_SURFACE_TARGET_1: case CELL_GCM_SURFACE_TARGET_1:
{ {
u32 address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); u32 address = rsx::get_address(offset_color_b, dma_color_b - 0xfeed0000);
void *dstAddress = vm::get_ptr<void>(address); void *dstAddress = vm::get_ptr<void>(address);
copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, clip_width, clip_height);
} }
break; break;
case CELL_GCM_SURFACE_TARGET_MRT1: case CELL_GCM_SURFACE_TARGET_MRT1:
{ {
u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); u32 address = rsx::get_address(offset_color_a, dma_color_a - 0xfeed0000);
void *dstAddress = vm::get_ptr<void>(address); void *dstAddress = vm::get_ptr<void>(address);
copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, clip_width, clip_height);
address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); address = rsx::get_address(offset_color_b, dma_color_b - 0xfeed0000);
dstAddress = vm::get_ptr<void>(address); dstAddress = vm::get_ptr<void>(address);
copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, clip_width, clip_height);
} }
break; break;
case CELL_GCM_SURFACE_TARGET_MRT2: case CELL_GCM_SURFACE_TARGET_MRT2:
{ {
u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); u32 address = rsx::get_address(offset_color_a, dma_color_a - 0xfeed0000);
void *dstAddress = vm::get_ptr<void>(address); void *dstAddress = vm::get_ptr<void>(address);
copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, clip_width, clip_height);
address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); address = rsx::get_address(offset_color_b, dma_color_b - 0xfeed0000);
dstAddress = vm::get_ptr<void>(address); dstAddress = vm::get_ptr<void>(address);
copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, clip_width, clip_height);
address = GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000); address = rsx::get_address(offset_color_c, dma_color_c - 0xfeed0000);
dstAddress = vm::get_ptr<void>(address); dstAddress = vm::get_ptr<void>(address);
copyToCellRamAndRelease(dstAddress, rtt2, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); copyToCellRamAndRelease(dstAddress, rtt2, srcPitch, dstPitch, clip_width, clip_height);
} }
break; break;
case CELL_GCM_SURFACE_TARGET_MRT3: case CELL_GCM_SURFACE_TARGET_MRT3:
{ {
u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); u32 address = rsx::get_address(offset_color_a, dma_color_a - 0xfeed0000);
void *dstAddress = vm::get_ptr<void>(address); void *dstAddress = vm::get_ptr<void>(address);
copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); copyToCellRamAndRelease(dstAddress, rtt0, srcPitch, dstPitch, clip_width, clip_height);
address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); address = rsx::get_address(offset_color_b, dma_color_b - 0xfeed0000);
dstAddress = vm::get_ptr<void>(address); dstAddress = vm::get_ptr<void>(address);
copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); copyToCellRamAndRelease(dstAddress, rtt1, srcPitch, dstPitch, clip_width, clip_height);
address = GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000); address = rsx::get_address(offset_color_c, dma_color_c - 0xfeed0000);
dstAddress = vm::get_ptr<void>(address); dstAddress = vm::get_ptr<void>(address);
copyToCellRamAndRelease(dstAddress, rtt2, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); copyToCellRamAndRelease(dstAddress, rtt2, srcPitch, dstPitch, clip_width, clip_height);
address = GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000); address = rsx::get_address(offset_color_d, dma_color_d - 0xfeed0000);
dstAddress = vm::get_ptr<void>(address); dstAddress = vm::get_ptr<void>(address);
copyToCellRamAndRelease(dstAddress, rtt3, srcPitch, dstPitch, m_surface_clip_w, m_surface_clip_h); copyToCellRamAndRelease(dstAddress, rtt3, srcPitch, dstPitch, clip_width, clip_height);
} }
break; break;
} }
} }
vm::write32(m_label_addr + offset, value); vm::ps3::write32(label_addr + offset, value);
} }
void D3D12GSRender::semaphorePFIFOAcquire(u32 offset, u32 value) void D3D12GSRender::semaphorePFIFOAcquire(u32 offset, u32 value)
@ -1191,7 +1218,7 @@ void D3D12GSRender::semaphorePFIFOAcquire(u32 offset, u32 value)
const std::chrono::time_point<std::chrono::system_clock> enterWait = std::chrono::system_clock::now(); const std::chrono::time_point<std::chrono::system_clock> enterWait = std::chrono::system_clock::now();
while (true) while (true)
{ {
volatile u32 val = vm::read32(m_label_addr + offset); volatile u32 val = vm::ps3::read32(label_addr + offset);
if (val == value) break; if (val == value) break;
std::chrono::time_point<std::chrono::system_clock> waitPoint = std::chrono::system_clock::now(); std::chrono::time_point<std::chrono::system_clock> waitPoint = std::chrono::system_clock::now();
long long elapsedTime = std::chrono::duration_cast<std::chrono::seconds>(waitPoint - enterWait).count(); long long elapsedTime = std::chrono::duration_cast<std::chrono::seconds>(waitPoint - enterWait).count();

View file

@ -41,28 +41,6 @@
* are not currently correctly signaled which leads to deadlock. * are not currently correctly signaled which leads to deadlock.
*/ */
class GSFrameBase2
{
public:
GSFrameBase2() {}
GSFrameBase2(const GSFrameBase2&) = delete;
virtual void Close() = 0;
virtual bool IsShown() = 0;
virtual void Hide() = 0;
virtual void Show() = 0;
virtual void* GetNewContext() = 0;
virtual void SetCurrent(void* ctx) = 0;
virtual void DeleteContext(void* ctx) = 0;
virtual void Flip(void* ctx) = 0;
virtual HWND getHandle() const = 0;
};
typedef GSFrameBase2*(*GetGSFrameCb2)();
void SetGetD3DGSFrameCallback(GetGSFrameCb2 value);
template<typename T> template<typename T>
struct InitHeap struct InitHeap
{ {
@ -470,28 +448,26 @@ private:
u32 m_previous_address_d; u32 m_previous_address_d;
u32 m_previous_address_z; u32 m_previous_address_z;
public: public:
GSFrameBase2 *m_frame;
u32 m_draw_frames; u32 m_draw_frames;
u32 m_skip_frames; u32 m_skip_frames;
std::unordered_map<size_t, RSXTransformConstant> m_vertexConstants; std::unordered_map<size_t, color4f> m_vertexConstants;
D3D12GSRender(); D3D12GSRender();
virtual ~D3D12GSRender(); virtual ~D3D12GSRender();
virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) override; void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value);
virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) override; void semaphorePGRAPHBackendRelease(u32 offset, u32 value);
virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override; void semaphorePFIFOAcquire(u32 offset, u32 value);
virtual void notifyProgramChange() override; void notifyProgramChange();
virtual void notifyBlendStateChange() override; void notifyBlendStateChange();
virtual void notifyDepthStencilStateChange() override; void notifyDepthStencilStateChange();
virtual void notifyRasterizerStateChange() override; void notifyRasterizerStateChange();
private: private:
void InitD2DStructures(); void InitD2DStructures();
void ReleaseD2DStructures(); void ReleaseD2DStructures();
ID3D12Resource *writeColorBuffer(ID3D12Resource *RTT, ID3D12GraphicsCommandList *cmdlist); ID3D12Resource *writeColorBuffer(ID3D12Resource *RTT, ID3D12GraphicsCommandList *cmdlist);
virtual void Close() override;
bool LoadProgram(); bool LoadProgram();
@ -533,14 +509,19 @@ private:
*/ */
void renderOverlay(); void renderOverlay();
void clear_surface(u32 arg);
protected: protected:
virtual void OnInit() override; void begin() override;
virtual void OnInitThread() override; void end() override;
virtual void OnExitThread() override;
virtual void OnReset() override; void oninit_thread() override;
virtual void Clear(u32 cmd) override; void onexit_thread() override;
virtual void Draw() override; bool domethod(u32 id, u32 arg) override;
virtual void Flip() override; void flip(int buffer) override;
//TODO
//u64 timestamp() const override;
}; };
#endif #endif

View file

@ -29,11 +29,11 @@ void D3D12GSRender::PrepareRenderTargets(ID3D12GraphicsCommandList *copycmdlist)
m_previous_address_z = m_surface_offset_z; m_previous_address_z = m_surface_offset_z;
// FBO location has changed, previous data might be copied // FBO location has changed, previous data might be copied
u32 address_a = m_set_context_dma_color_a ? GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000) : 0; u32 address_a = m_set_context_dma_color_a ? rsx::get_address(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000) : 0;
u32 address_b = m_set_context_dma_color_b ? GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000) : 0; u32 address_b = m_set_context_dma_color_b ? rsx::get_address(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000) : 0;
u32 address_c = m_set_context_dma_color_c ? GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000) : 0; u32 address_c = m_set_context_dma_color_c ? rsx::get_address(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000) : 0;
u32 address_d = m_set_context_dma_color_d ? GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000) : 0; u32 address_d = m_set_context_dma_color_d ? rsx::get_address(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000) : 0;
u32 address_z = m_set_context_dma_z ? GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000) : 0; u32 address_z = m_set_context_dma_z ? rsx::get_address(m_surface_offset_z, m_context_dma_z - 0xfeed0000) : 0;
// Make previous RTTs sampleable // Make previous RTTs sampleable
for (unsigned i = 0; i < 4; i++) for (unsigned i = 0; i < 4; i++)

View file

@ -104,19 +104,19 @@ D3D12_FILTER getSamplerFilter(u32 minFilter, u32 magFilter)
} }
static static
D3D12_SAMPLER_DESC getSamplerDesc(const RSXTexture &texture) D3D12_SAMPLER_DESC getSamplerDesc(const rsx::texture &texture)
{ {
D3D12_SAMPLER_DESC samplerDesc = {}; D3D12_SAMPLER_DESC samplerDesc = {};
samplerDesc.Filter = getSamplerFilter(texture.GetMinFilter(), texture.GetMagFilter()); samplerDesc.Filter = getSamplerFilter(texture.min_filter(), texture.mag_filter());
samplerDesc.AddressU = getSamplerWrap(texture.GetWrapS()); samplerDesc.AddressU = getSamplerWrap(texture.wrap_s());
samplerDesc.AddressV = getSamplerWrap(texture.GetWrapT()); samplerDesc.AddressV = getSamplerWrap(texture.wrap_t());
samplerDesc.AddressW = getSamplerWrap(texture.GetWrapR()); samplerDesc.AddressW = getSamplerWrap(texture.wrap_r());
samplerDesc.ComparisonFunc = getSamplerCompFunc[texture.GetZfunc()]; samplerDesc.ComparisonFunc = getSamplerCompFunc[texture.zfunc()];
samplerDesc.MaxAnisotropy = (UINT)getSamplerMaxAniso(texture.GetMaxAniso()); samplerDesc.MaxAnisotropy = (UINT)getSamplerMaxAniso(texture.max_aniso());
samplerDesc.MipLODBias = texture.GetBias(); samplerDesc.MipLODBias = texture.bias();
samplerDesc.BorderColor[4] = (FLOAT)texture.GetBorderColor(); samplerDesc.BorderColor[4] = (FLOAT)texture.border_color();
samplerDesc.MinLOD = (FLOAT)(texture.GetMinLOD() >> 8); samplerDesc.MinLOD = (FLOAT)(texture.min_lod() >> 8);
samplerDesc.MaxLOD = (FLOAT)(texture.GetMaxLOD() >> 8); samplerDesc.MaxLOD = (FLOAT)(texture.max_lod() >> 8);
return samplerDesc; return samplerDesc;
} }
@ -127,15 +127,15 @@ D3D12_SAMPLER_DESC getSamplerDesc(const RSXTexture &texture)
*/ */
static static
ComPtr<ID3D12Resource> uploadSingleTexture( ComPtr<ID3D12Resource> uploadSingleTexture(
const RSXTexture &texture, const rsx::texture &texture,
ID3D12Device *device, ID3D12Device *device,
ID3D12GraphicsCommandList *commandList, ID3D12GraphicsCommandList *commandList,
DataHeap<ID3D12Resource, 65536> &textureBuffersHeap) DataHeap<ID3D12Resource, 65536> &textureBuffersHeap)
{ {
ComPtr<ID3D12Resource> vramTexture; ComPtr<ID3D12Resource> vramTexture;
size_t w = texture.GetWidth(), h = texture.GetHeight(); size_t w = texture.width(), h = texture.height();
int format = texture.GetFormat() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
DXGI_FORMAT dxgiFormat = getTextureDXGIFormat(format); DXGI_FORMAT dxgiFormat = getTextureDXGIFormat(format);
size_t textureSize = getPlacedTextureStorageSpace(texture, 256); size_t textureSize = getPlacedTextureStorageSpace(texture, 256);
@ -148,7 +148,7 @@ ComPtr<ID3D12Resource> uploadSingleTexture(
std::vector<MipmapLevelInfo> mipInfos = uploadPlacedTexture(texture, 256, textureData); std::vector<MipmapLevelInfo> mipInfos = uploadPlacedTexture(texture, 256, textureData);
textureBuffersHeap.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + textureSize)); textureBuffersHeap.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + textureSize));
D3D12_RESOURCE_DESC texturedesc = CD3DX12_RESOURCE_DESC::Tex2D(dxgiFormat, (UINT)w, (UINT)h, 1, texture.GetMipmap()); D3D12_RESOURCE_DESC texturedesc = CD3DX12_RESOURCE_DESC::Tex2D(dxgiFormat, (UINT)w, (UINT)h, 1, texture.mipmap());
textureSize = device->GetResourceAllocationInfo(0, 1, &texturedesc).SizeInBytes; textureSize = device->GetResourceAllocationInfo(0, 1, &texturedesc).SizeInBytes;
ThrowIfFailed(device->CreateCommittedResource( ThrowIfFailed(device->CreateCommittedResource(
@ -216,11 +216,11 @@ void updateExistingTexture(
* Get number of bytes occupied by texture in RSX mem * Get number of bytes occupied by texture in RSX mem
*/ */
static static
size_t getTextureSize(const RSXTexture &texture) size_t getTextureSize(const rsx::texture &texture)
{ {
size_t w = texture.GetWidth(), h = texture.GetHeight(); size_t w = texture.width(), h = texture.height();
int format = texture.GetFormat() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
// TODO: Take mipmaps into account // TODO: Take mipmaps into account
switch (format) switch (format)
{ {
@ -288,17 +288,17 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist)
{ {
size_t usedTexture = 0; size_t usedTexture = 0;
for (u32 i = 0; i < m_textures_count; ++i) for (u32 i = 0; i < rsx::limits::textures_count; ++i)
{ {
if (!m_textures[i].IsEnabled()) continue; if (!textures[i].enabled()) continue;
size_t w = m_textures[i].GetWidth(), h = m_textures[i].GetHeight(); size_t w = textures[i].width(), h = textures[i].height();
if (!w || !h) continue; if (!w || !h) continue;
const u32 texaddr = GetAddress(m_textures[i].GetOffset(), m_textures[i].GetLocation()); const u32 texaddr = rsx::get_address(textures[i].offset(), textures[i].location());
int format = m_textures[i].GetFormat() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); int format = textures[i].format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
DXGI_FORMAT dxgiFormat = getTextureDXGIFormat(format); DXGI_FORMAT dxgiFormat = getTextureDXGIFormat(format);
bool is_swizzled = !(m_textures[i].GetFormat() & CELL_GCM_TEXTURE_LN); bool is_swizzled = !(textures[i].format() & CELL_GCM_TEXTURE_LN);
ID3D12Resource *vramTexture; ID3D12Resource *vramTexture;
std::unordered_map<u32, ID3D12Resource* >::const_iterator ItRTT = m_rtts.m_renderTargets.find(texaddr); std::unordered_map<u32, ID3D12Resource* >::const_iterator ItRTT = m_rtts.m_renderTargets.find(texaddr);
@ -324,13 +324,13 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist)
getCurrentResourceStorage().m_dirtyTextures.push_back(m_textureCache.removeFromCache(texaddr)); getCurrentResourceStorage().m_dirtyTextures.push_back(m_textureCache.removeFromCache(texaddr));
ComPtr<ID3D12Resource> tex = uploadSingleTexture(m_textures[i], m_device.Get(), cmdlist, m_textureUploadData); ComPtr<ID3D12Resource> tex = uploadSingleTexture(m_textures[i], m_device.Get(), cmdlist, m_textureUploadData);
vramTexture = tex.Get(); vramTexture = tex.Get();
m_textureCache.storeAndProtectData(texaddr, texaddr, getTextureSize(m_textures[i]), format, w, h, m_textures[i].GetMipmap(), tex); m_textureCache.storeAndProtectData(texaddr, texaddr, getTextureSize(m_textures[i]), format, w, h, m_textures[i].mipmap(), tex);
} }
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Format = dxgiFormat; srvDesc.Format = dxgiFormat;
srvDesc.Texture2D.MipLevels = m_textures[i].GetMipmap(); srvDesc.Texture2D.MipLevels = textures[i].mipmap();
switch (format) switch (format)
{ {
@ -357,10 +357,10 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist)
{ {
u8 remap_a = m_textures[i].GetRemap() & 0x3; u8 remap_a = textures[i].remap() & 0x3;
u8 remap_r = (m_textures[i].GetRemap() >> 2) & 0x3; u8 remap_r = (textures[i].remap() >> 2) & 0x3;
u8 remap_g = (m_textures[i].GetRemap() >> 4) & 0x3; u8 remap_g = (textures[i].remap() >> 4) & 0x3;
u8 remap_b = (m_textures[i].GetRemap() >> 6) & 0x3; u8 remap_b = (textures[i].remap() >> 6) & 0x3;
if (isRenderTarget) if (isRenderTarget)
{ {
// ARGB format // ARGB format
@ -428,10 +428,10 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist)
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1 D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1
}; };
u8 remap_a = m_textures[i].GetRemap() & 0x3; u8 remap_a = textures[i].remap() & 0x3;
u8 remap_r = (m_textures[i].GetRemap() >> 2) & 0x3; u8 remap_r = (textures[i].remap() >> 2) & 0x3;
u8 remap_g = (m_textures[i].GetRemap() >> 4) & 0x3; u8 remap_g = (textures[i].remap() >> 4) & 0x3;
u8 remap_b = (m_textures[i].GetRemap() >> 6) & 0x3; u8 remap_b = (textures[i].remap() >> 6) & 0x3;
srvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( srvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
RemapValue[remap_a], RemapValue[remap_a],
@ -459,7 +459,7 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist)
getCurrentResourceStorage().m_samplerDescriptorHeapIndex = 1; getCurrentResourceStorage().m_samplerDescriptorHeapIndex = 1;
getCurrentResourceStorage().m_currentSamplerIndex = 0; getCurrentResourceStorage().m_currentSamplerIndex = 0;
} }
m_device->CreateSampler(&getSamplerDesc(m_textures[i]), m_device->CreateSampler(&getSamplerDesc(textures[i]),
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex]->GetCPUDescriptorHandleForHeapStart()) CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_samplerDescriptorHeap[getCurrentResourceStorage().m_samplerDescriptorHeapIndex]->GetCPUDescriptorHandleForHeapStart())
.Offset((UINT)getCurrentResourceStorage().m_currentSamplerIndex + (UINT)usedTexture, g_descriptorStrideSamplers)); .Offset((UINT)getCurrentResourceStorage().m_currentSamplerIndex + (UINT)usedTexture, g_descriptorStrideSamplers));

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "Utilities/types.h" #include "Utilities/types.h"
#include "Emu/Memory/vm.h"
enum enum
{ {
@ -242,6 +243,15 @@ enum
CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_P = 1 << 30, CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_P = 1 << 30,
CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_Q = 1 << 31, CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_Q = 1 << 31,
// Texture Filter
CELL_GCM_TEXTURE_NEAREST = 1,
CELL_GCM_TEXTURE_LINEAR = 2,
CELL_GCM_TEXTURE_NEAREST_NEAREST = 3,
CELL_GCM_TEXTURE_LINEAR_NEAREST = 4,
CELL_GCM_TEXTURE_NEAREST_LINEAR = 5,
CELL_GCM_TEXTURE_LINEAR_LINEAR = 6,
CELL_GCM_TEXTURE_CONVOLUTION_MIN = 7,
CELL_GCM_PRIMITIVE_POINTS = 1, CELL_GCM_PRIMITIVE_POINTS = 1,
CELL_GCM_PRIMITIVE_LINES = 2, CELL_GCM_PRIMITIVE_LINES = 2,
CELL_GCM_PRIMITIVE_LINE_LOOP = 3, CELL_GCM_PRIMITIVE_LINE_LOOP = 3,
@ -893,7 +903,7 @@ enum Method
namespace rsx namespace rsx
{ {
template<typename ...T> template<typename ...T>
static std::initializer_list<u32> make_command(u32 start_register, T... values) static std::array<u32, sizeof...(T) + 1> make_command(u32 start_register, T... values)
{ {
return{ (start_register << 2) | (sizeof...(values) << 18), values... }; return{ (start_register << 2) | (sizeof...(values) << 18), values... };
} }
@ -903,24 +913,23 @@ namespace rsx
return CELL_GCM_METHOD_FLAG_JUMP | offset; return CELL_GCM_METHOD_FLAG_JUMP | offset;
} }
template<typename ...T> template<typename AT, typename ...T>
static size_t make_command(vm::ps3::ptr<u32>& dst, u32 start_register, T... values) static size_t make_command(vm::ps3::ptr<u32, AT> &dst, u32 start_register, T... values)
{ {
std::initializer_list<u32> commands = make_command(start_register, values...); auto commands = make_command(start_register, values...);
for (auto &&command : commands) for (u32 command : commands)
{ {
vm::ps3::write32(dst.addr(), command); *dst++ = command;
dst++;
} }
return commands.size(); return commands.size();
} }
static size_t make_jump(vm::ps3::ptr<u32>& dst, u32 offset) template<typename AT>
static size_t make_jump(vm::ps3::ptr<u32, AT> &dst, u32 offset)
{ {
vm::ps3::write32(dst.addr(), make_jump(offset)); *dst++ = make_jump(offset);
dst++;
return 1; return 1;
} }

View file

@ -530,15 +530,8 @@ u32 GLTexture::id() const
return m_id; return m_id;
} }
GLGSRender::GLGSRender() GLGSRender::GLGSRender() : GSRender(frame_type::OpenGL)
{ {
m_frame = Emu.GetCallbacks().get_gs_frame().release();
}
GLGSRender::~GLGSRender()
{
m_context = nullptr;
m_frame->close();
} }
u32 GLGSRender::enable(u32 condition, u32 cap) u32 GLGSRender::enable(u32 condition, u32 cap)
@ -571,19 +564,6 @@ u32 GLGSRender::enable(u32 condition, u32 cap, u32 index)
extern CellGcmContextData current_context; extern CellGcmContextData current_context;
void GLGSRender::close()
{
if (joinable())
{
join();
}
if (m_frame->shown())
{
m_frame->hide();
}
}
void GLGSRender::begin() void GLGSRender::begin()
{ {
rsx::thread::begin(); rsx::thread::begin();
@ -627,8 +607,8 @@ void GLGSRender::begin()
if (enable(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE], GL_DEPTH_TEST)) if (enable(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE], GL_DEPTH_TEST))
{ {
//glcheck(glDepthFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC])); __glcheck glDepthFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC]);
//glcheck(glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK])); __glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]);
} }
if (enable(rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE], GL_DEPTH_BOUNDS_TEST_EXT)) if (enable(rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE], GL_DEPTH_BOUNDS_TEST_EXT))
@ -855,42 +835,6 @@ void apply_attrib_array(gl::glsl::program& program, int index, const std::vector
void GLGSRender::end() void GLGSRender::end()
{ {
if (!vertex_draw_count)
{
bool has_array = false;
for (int i = 0; i < rsx::limits::vertex_count; ++i)
{
if (vertex_arrays_info[i].array)
{
has_array = true;
break;
}
}
if (!has_array)
{
u32 min_count = ~0;
for (int i = 0; i < rsx::limits::vertex_count; ++i)
{
if (!vertex_arrays_info[i].size)
continue;
u32 count = u32(vertex_arrays[i].size()) /
rsx::get_vertex_type_size(vertex_arrays_info[i].type) * vertex_arrays_info[i].size;
if (count < min_count)
min_count = count;
}
if (min_count && min_count < ~0)
{
vertex_draw_count = min_count;
}
}
}
if (!draw_fbo || !vertex_draw_count) if (!draw_fbo || !vertex_draw_count)
{ {
rsx::thread::end(); rsx::thread::end();
@ -906,8 +850,12 @@ void GLGSRender::end()
if (!textures[i].enabled()) if (!textures[i].enabled())
continue; continue;
__glcheck m_gl_textures[i].init(textures[i]); int location;
__glcheck m_program.uniforms.texture("tex" + std::to_string(i), i, gl::texture_view(gl::texture::target::texture2D, m_gl_textures[i].id())); if (m_program.uniforms.has_location("tex" + std::to_string(i), &location))
{
__glcheck m_gl_textures[i].init(textures[i]);
__glcheck m_program.uniforms.texture(location, i, gl::texture_view(gl::texture::target::texture2D, m_gl_textures[i].id()));
}
} }
//initialize vertex attributes //initialize vertex attributes
@ -1096,18 +1044,19 @@ void GLGSRender::end()
void GLGSRender::oninit() void GLGSRender::oninit()
{ {
GSRender::oninit();
m_draw_frames = 1; m_draw_frames = 1;
m_skip_frames = 0; m_skip_frames = 0;
m_frame->show();
} }
void GLGSRender::oninit_thread() void GLGSRender::oninit_thread()
{ {
m_context = m_frame->new_context(); GSRender::oninit_thread();
m_frame->set_current(m_context);
gl::init(); gl::init();
LOG_NOTICE(Log::RSX, "%s", glGetString(GL_VERSION));
LOG_NOTICE(Log::RSX, "%s", glGetString(GL_SHADING_LANGUAGE_VERSION));
is_intel_vendor = strstr((const char*)glGetString(GL_VENDOR), "Intel"); is_intel_vendor = strstr((const char*)glGetString(GL_VENDOR), "Intel");

View file

@ -84,12 +84,10 @@ public:
bool is_intel_vendor; bool is_intel_vendor;
GLGSRender(); GLGSRender();
virtual ~GLGSRender();
private: private:
static u32 enable(u32 enable, u32 cap); static u32 enable(u32 enable, u32 cap);
static u32 enable(u32 enable, u32 cap, u32 index); static u32 enable(u32 enable, u32 cap, u32 index);
void close() override;
public: public:
bool load_program(); bool load_program();

View file

@ -70,7 +70,13 @@ namespace gl
void fbo::draw_buffers(const std::initializer_list<attachment>& indexes) const void fbo::draw_buffers(const std::initializer_list<attachment>& indexes) const
{ {
save_binding_state save(*this); save_binding_state save(*this);
__glcheck glDrawBuffers((GLsizei)indexes.size(), (const GLenum*)indexes.begin()); std::vector<GLenum> ids;
ids.reserve(indexes.size());
for (auto &index : indexes)
ids.push_back(index.id());
__glcheck glDrawBuffers((GLsizei)ids.size(), ids.data());
} }
void fbo::draw_arrays(draw_mode mode, GLsizei count, GLint first) const void fbo::draw_arrays(draw_mode mode, GLsizei count, GLint first) const

View file

@ -1831,6 +1831,21 @@ namespace gl
active_texture = 0; active_texture = 0;
} }
bool has_location(const std::string &name, int *location = nullptr)
{
int result = glGetUniformLocation(m_program.id(), name.c_str());
if (result < 0)
return false;
locations[name] = result;
if (location)
*location = result;
return true;
}
GLint location(const std::string &name) GLint location(const std::string &name)
{ {
auto finded = locations.find(name); auto finded = locations.find(name);
@ -1850,16 +1865,21 @@ namespace gl
return result; return result;
} }
int texture(const std::string &name, int active_texture, const gl::texture& texture) int texture(GLint location, int active_texture, const gl::texture& texture)
{ {
glActiveTexture(GL_TEXTURE0 + active_texture); glActiveTexture(GL_TEXTURE0 + active_texture);
texture.bind(); texture.bind();
(*this)[name] = active_texture; (*this)[location] = active_texture;
return active_texture; return active_texture;
} }
int texture(const std::string &name, const gl::texture& tex) int texture(const std::string &name, int active_texture, const gl::texture& texture_)
{
return texture(location(name), active_texture, texture_);
}
int texture(const std::string &name, const gl::texture& texture_)
{ {
int atex; int atex;
auto finded = locations.find(name); auto finded = locations.find(name);
@ -1873,7 +1893,7 @@ namespace gl
atex = active_texture++; atex = active_texture++;
} }
return texture(name, atex, tex); return texture(name, atex, texture_);
} }
uniform_t operator[](GLint location) uniform_t operator[](GLint location)

View file

@ -1,6 +1,6 @@
#pragma once #pragma once
struct GSRender; class GSRender;
struct GSInfo struct GSInfo
{ {

View file

@ -10,3 +10,58 @@ draw_context_t GSFrameBase::new_context()
{ {
return std::shared_ptr<void>(make_context(), [this](void* ctxt) { delete_context(ctxt); }); return std::shared_ptr<void>(make_context(), [this](void* ctxt) { delete_context(ctxt); });
} }
void GSFrameBase::title_message(const std::wstring& msg)
{
m_title_message = msg;
}
GSRender::GSRender(frame_type type) : m_frame(Emu.GetCallbacks().get_gs_frame(type).release())
{
}
GSRender::~GSRender()
{
m_context = nullptr;
if (m_frame)
{
m_frame->close();
}
}
void GSRender::oninit()
{
if (m_frame)
{
m_frame->show();
}
}
void GSRender::oninit_thread()
{
if (m_frame)
{
m_context = m_frame->new_context();
m_frame->set_current(m_context);
}
}
void GSRender::close()
{
if (m_frame && m_frame->shown())
{
m_frame->hide();
}
if (joinable())
{
join();
}
}
void GSRender::flip(int buffer)
{
if (m_frame)
m_frame->flip(m_context);
}

View file

@ -6,6 +6,9 @@ using draw_context_t = std::shared_ptr<void>;
class GSFrameBase class GSFrameBase
{ {
protected:
std::wstring m_title_message;
public: public:
GSFrameBase() = default; GSFrameBase() = default;
GSFrameBase(const GSFrameBase&) = delete; GSFrameBase(const GSFrameBase&) = delete;
@ -21,13 +24,34 @@ public:
virtual void flip(draw_context_t ctx) = 0; virtual void flip(draw_context_t ctx) = 0;
virtual size2i client_size() = 0; virtual size2i client_size() = 0;
virtual void* handle() const = 0;
void title_message(const std::wstring&);
protected: protected:
virtual void delete_context(void* ctx) = 0; virtual void delete_context(void* ctx) = 0;
virtual void* make_context() = 0; virtual void* make_context() = 0;
}; };
struct GSRender : public rsx::thread enum class frame_type
{ {
virtual ~GSRender() = default; Null,
virtual void close()=0; OpenGL,
DX12
};
class GSRender : public rsx::thread
{
protected:
GSFrameBase* m_frame;
draw_context_t m_context;
public:
GSRender(frame_type type);
virtual ~GSRender();
void oninit() override;
void oninit_thread() override;
void close();
void flip(int buffer) override;
}; };

View file

@ -0,0 +1,16 @@
#include "stdafx.h"
#include "NullGSRender.h"
#include "Emu/System.h"
NullGSRender::NullGSRender() : GSRender(frame_type::Null)
{
}
void NullGSRender::onexit_thread()
{
}
bool NullGSRender::domethod(u32 cmd, u32 value)
{
return false;
}

View file

@ -3,29 +3,10 @@
class NullGSRender final : public GSRender class NullGSRender final : public GSRender
{ {
public:
NullGSRender();
private: private:
void oninit() override void onexit_thread() override;
{ bool domethod(u32 cmd, u32 value) override;
}
void oninit_thread() override
{
}
void onexit_thread() override
{
}
bool domethod(u32 cmd, u32 value) override
{
return false;
}
void flip(int buffer) override
{
}
void close() override
{
}
}; };

View file

@ -47,13 +47,13 @@ namespace rsx
__forceinline void semaphore_acquire(thread* rsx, u32 arg) __forceinline void semaphore_acquire(thread* rsx, u32 arg)
{ {
//TODO: dma //TODO: dma
while (vm::read32(rsx->label_addr + method_registers[NV406E_SEMAPHORE_OFFSET]) != arg) /*while (vm::read32(rsx->label_addr + method_registers[NV406E_SEMAPHORE_OFFSET]) != arg)
{ {
if (Emu.IsStopped()) if (Emu.IsStopped())
break; break;
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }*/
} }
__forceinline void semaphore_release(thread* rsx, u32 arg) __forceinline void semaphore_release(thread* rsx, u32 arg)
@ -201,6 +201,42 @@ namespace rsx
return; return;
} }
if (!rsx->vertex_draw_count)
{
bool has_array = false;
for (int i = 0; i < rsx::limits::vertex_count; ++i)
{
if (rsx->vertex_arrays_info[i].array)
{
has_array = true;
break;
}
}
if (!has_array)
{
u32 min_count = ~0;
for (int i = 0; i < rsx::limits::vertex_count; ++i)
{
if (!rsx->vertex_arrays_info[i].size)
continue;
u32 count = u32(rsx->vertex_arrays[i].size()) /
rsx::get_vertex_type_size(rsx->vertex_arrays_info[i].type) * rsx->vertex_arrays_info[i].size;
if (count < min_count)
min_count = count;
}
if (min_count && min_count < ~0)
{
rsx->vertex_draw_count = min_count;
}
}
}
rsx->end(); rsx->end();
rsx->vertex_draw_count = 0; rsx->vertex_draw_count = 0;
} }

View file

@ -32,11 +32,11 @@ namespace rsx
u8 _u8[0x10000]; u8 _u8[0x10000];
u32 _u32[0x10000 >> 2]; u32 _u32[0x10000 >> 2];
/* /*
struct struct alignas(4)
{ {
u8 pad[NV4097_SET_TEXTURE_OFFSET - 4]; u8 pad[NV4097_SET_TEXTURE_OFFSET - 4];
struct texture_t struct alignas(4) texture_t
{ {
u32 offset; u32 offset;

View file

@ -505,12 +505,11 @@ s32 cellGcmSetPrepareFlip(PPUThread& ppu, vm::ptr<CellGcmContextData> ctxt, u32
} }
} }
*ctxt->current++ = 0x3fead | (1 << 18); u32 command_size = rsx::make_command(ctxt->current, GCM_FLIP_COMMAND, id);
*ctxt->current++ = id;
if (ctxt.addr() == gcm_info.context_addr) if (ctxt.addr() == gcm_info.context_addr)
{ {
vm::get_ref<CellGcmControl>(gcm_info.control_addr).put += 8; vm::get_ref<CellGcmControl>(gcm_info.control_addr).put += command_size * sizeof(u32);
} }
return id; return id;

View file

@ -11,7 +11,7 @@ struct EmuCallbacks
std::function<std::unique_ptr<class KeyboardHandlerBase>()> get_kb_handler; std::function<std::unique_ptr<class KeyboardHandlerBase>()> get_kb_handler;
std::function<std::unique_ptr<class MouseHandlerBase>()> get_mouse_handler; std::function<std::unique_ptr<class MouseHandlerBase>()> get_mouse_handler;
std::function<std::unique_ptr<class PadHandlerBase>()> get_pad_handler; std::function<std::unique_ptr<class PadHandlerBase>()> get_pad_handler;
std::function<std::unique_ptr<class GSFrameBase>()> get_gs_frame; std::function<std::unique_ptr<class GSFrameBase>(enum class frame_type)> get_gs_frame;
std::function<std::unique_ptr<class MsgDialogBase>()> get_msg_dialog; std::function<std::unique_ptr<class MsgDialogBase>()> get_msg_dialog;
std::function<std::unique_ptr<class SaveDialogBase>()> get_save_dialog; std::function<std::unique_ptr<class SaveDialogBase>()> get_save_dialog;
}; };

View file

@ -1,103 +0,0 @@
#include "stdafx_gui.h"
#if defined(DX12_SUPPORT)
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "D3DGSFrame.h"
#include "Utilities/Timer.h"
D3DGSFrame::D3DGSFrame()
: GSFrame(nullptr, "GSFrame[DirectX 12]")
, m_frames(0)
{
SetIcon(wxICON(frame_icon));
canvas = new wxWindow(this, wxID_ANY);
canvas->SetSize(GetClientSize());
canvas->Bind(wxEVT_LEFT_DCLICK, &GSFrame::OnLeftDclick, this);
}
D3DGSFrame::~D3DGSFrame()
{
}
void D3DGSFrame::Close()
{
GSFrame::Close();
}
bool D3DGSFrame::IsShown()
{
return GSFrame::IsShown();
}
void D3DGSFrame::Hide()
{
GSFrame::Hide();
}
void D3DGSFrame::Show()
{
GSFrame::Show();
}
void* D3DGSFrame::GetNewContext()
{
return nullptr;//new wxGLContext(GetCanvas());
}
void D3DGSFrame::SetCurrent(void* ctx)
{
// GetCanvas()->SetCurrent(*(wxGLContext*)ctx);
}
void D3DGSFrame::DeleteContext(void* ctx)
{
// delete (wxGLContext*)ctx;
}
void D3DGSFrame::Flip(void* context)
{
if (!canvas) return;
// canvas->SetCurrent(*(wxGLContext*)context);
static Timer fps_t;
// canvas->SwapBuffers();
m_frames++;
const std::string sub_title = Emu.GetTitle() + (Emu.GetTitleID().length() ? " [" + Emu.GetTitleID() + "] | " : " | ") + " | ";
if (fps_t.GetElapsedTimeInSec() >= 0.5)
{
// can freeze on exit
SetTitle(wxString(sub_title.c_str(), wxConvUTF8) + wxString::Format("FPS: %.2f", (double)m_frames / fps_t.GetElapsedTimeInSec()));
m_frames = 0;
fps_t.Start();
}
}
void D3DGSFrame::OnSize(wxSizeEvent& event)
{
if (canvas) canvas->SetSize(GetClientSize());
event.Skip();
}
void D3DGSFrame::SetViewport(int x, int y, u32 w, u32 h)
{
/*
//ConLog.Warning("SetViewport(x=%d, y=%d, w=%d, h=%d)", x, y, w, h);
const wxSize client = GetClientSize();
const wxSize viewport = AspectRatio(client, wxSize(w, h));
const int vx = (client.GetX() - viewport.GetX()) / 2;
const int vy = (client.GetY() - viewport.GetY()) / 2;
glViewport(vx + x, vy + y, viewport.GetWidth(), viewport.GetHeight());
*/
}
HWND D3DGSFrame::getHandle() const
{
return canvas->GetHandle();
}
#endif

View file

@ -1,36 +0,0 @@
#pragma once
#if defined(DX12_SUPPORT)
#include "Emu/RSX/D3D12/D3D12GSRender.h"
#include "Gui/GSFrame.h"
#include "wx/window.h"
struct D3DGSFrame : public GSFrame, public GSFrameBase2
{
wxWindow* canvas;
u32 m_frames;
D3DGSFrame();
~D3DGSFrame();
virtual void Close() override;
virtual bool IsShown() override;
virtual void Hide() override;
virtual void Show() override;
virtual void* GetNewContext() override;
virtual void SetCurrent(void* ctx) override;
virtual void DeleteContext(void* ctx) override;
virtual void Flip(void* context) override;
wxWindow* GetCanvas() const { return canvas; }
virtual void SetViewport(int x, int y, u32 w, u32 h) override;
virtual HWND getHandle() const override;
private:
virtual void OnSize(wxSizeEvent& event);
};
#endif

View file

@ -1,54 +1,22 @@
#include "stdafx_gui.h" #include "stdafx_gui.h"
#include "Utilities/Log.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "GLGSFrame.h" #include "GLGSFrame.h"
#include "D3DGSFrame.h"
#include "Utilities/Timer.h"
#ifndef _WIN32 GLGSFrame::GLGSFrame() : GSFrame("OpenGL")
#include "frame_icon.xpm"
#endif
GLGSFrame::GLGSFrame()
: GSFrame(nullptr, "GSFrame[OpenGL]")
, m_frames(0)
{ {
SetIcon(wxICON(frame_icon)); m_canvas = new wxGLCanvas(this, wxID_ANY, NULL);
canvas = new wxGLCanvas(this, wxID_ANY, NULL); m_canvas->SetSize(GetClientSize());
canvas->SetSize(GetClientSize());
canvas->Bind(wxEVT_LEFT_DCLICK, &GSFrame::OnLeftDclick, this); m_canvas->Bind(wxEVT_LEFT_DCLICK, &GSFrame::OnLeftDclick, this);
}
void GLGSFrame::close()
{
GSFrame::Close();
}
bool GLGSFrame::shown()
{
return GSFrame::IsShown();
}
void GLGSFrame::hide()
{
GSFrame::Hide();
}
void GLGSFrame::show()
{
GSFrame::Show();
} }
void* GLGSFrame::make_context() void* GLGSFrame::make_context()
{ {
return new wxGLContext(GetCanvas()); return new wxGLContext(m_canvas);
} }
void GLGSFrame::set_current(draw_context_t ctx) void GLGSFrame::set_current(draw_context_t ctx)
{ {
GetCanvas()->SetCurrent(*(wxGLContext*)ctx.get()); m_canvas->SetCurrent(*(wxGLContext*)ctx.get());
} }
void GLGSFrame::delete_context(void* ctx) void GLGSFrame::delete_context(void* ctx)
@ -58,47 +26,18 @@ void GLGSFrame::delete_context(void* ctx)
void GLGSFrame::flip(draw_context_t context) void GLGSFrame::flip(draw_context_t context)
{ {
if (!canvas) return; GSFrame::flip(context);
canvas->SetCurrent(*(wxGLContext*)context.get());
static Timer fps_t; if (!m_canvas) return;
canvas->SwapBuffers();
m_frames++;
const std::string sub_title = Emu.GetTitle() + (Emu.GetTitleID().length() ? " [" + Emu.GetTitleID() + "] | " : " | "); m_canvas->SetCurrent(*(wxGLContext*)context.get());
m_canvas->SwapBuffers();
if (fps_t.GetElapsedTimeInSec() >= 0.5)
{
// can freeze on exit
SetTitle(wxString(sub_title.c_str(), wxConvUTF8) + wxString::Format("FPS: %.2f", (double)m_frames / fps_t.GetElapsedTimeInSec()));
m_frames = 0;
fps_t.Start();
}
}
size2i GLGSFrame::client_size()
{
wxSize size = GetClientSize();
return{ size.GetWidth(), size.GetHeight() };
} }
void GLGSFrame::OnSize(wxSizeEvent& event) void GLGSFrame::OnSize(wxSizeEvent& event)
{ {
if (canvas) canvas->SetSize(GetClientSize()); if (m_canvas)
m_canvas->SetSize(GetClientSize());
event.Skip(); event.Skip();
}
void GLGSFrame::SetViewport(int x, int y, u32 w, u32 h)
{
/*
//ConLog.Warning("SetViewport(x=%d, y=%d, w=%d, h=%d)", x, y, w, h);
const wxSize client = GetClientSize();
const wxSize viewport = AspectRatio(client, wxSize(w, h));
const int vx = (client.GetX() - viewport.GetX()) / 2;
const int vy = (client.GetY() - viewport.GetY()) / 2;
glViewport(vx + x, vy + y, viewport.GetWidth(), viewport.GetHeight());
*/
} }

View file

@ -1,30 +1,18 @@
#pragma once #pragma once
#include "Emu/RSX/GL/GLGSRender.h"
#include "Gui/GSFrame.h" #include "Gui/GSFrame.h"
#include "wx/glcanvas.h" #include "wx/glcanvas.h"
struct GLGSFrame : public GSFrame, public GSFrameBase class GLGSFrame : public GSFrame
{ {
wxGLCanvas* canvas; wxGLCanvas* m_canvas;
u32 m_frames;
public:
GLGSFrame(); GLGSFrame();
void close() override;
bool shown() override;
void hide() override;
void show() override;
void* make_context() override; void* make_context() override;
void set_current(draw_context_t context) override; void set_current(draw_context_t context) override;
void delete_context(void* context) override; void delete_context(void* context) override;
void flip(draw_context_t context) override; void flip(draw_context_t context) override;
size2i client_size() override;
wxGLCanvas* GetCanvas() const { return canvas; }
virtual void SetViewport(int x, int y, u32 w, u32 h) override;
private: private:
virtual void OnSize(wxSizeEvent& event); virtual void OnSize(wxSizeEvent& event);

View file

@ -3,32 +3,21 @@
#include "Emu/System.h" #include "Emu/System.h"
#include "Emu/SysCalls/Modules/cellVideoOut.h" #include "Emu/SysCalls/Modules/cellVideoOut.h"
#include "rpcs3.h" #include "rpcs3.h"
#include "Utilities/Timer.h"
#ifndef _WIN32
#include "frame_icon.xpm"
#endif
BEGIN_EVENT_TABLE(GSFrame, wxFrame) BEGIN_EVENT_TABLE(GSFrame, wxFrame)
EVT_PAINT(GSFrame::OnPaint) EVT_PAINT(GSFrame::OnPaint)
EVT_SIZE(GSFrame::OnSize) EVT_SIZE(GSFrame::OnSize)
END_EVENT_TABLE() END_EVENT_TABLE()
wxSize AspectRatio(wxSize rs, const wxSize as) GSFrame::GSFrame(const wxString& title) : wxFrame(nullptr, wxID_ANY, "GSFrame[" + title + "]")
{ {
const double aq = (double)as.x / as.y; SetIcon(wxICON(frame_icon));
const double rq = (double)rs.x / rs.y;
const double q = aq / rq;
if (q > 1.0)
{
rs.y /= q;
}
else if (q < 1.0)
{
rs.x *= q;
}
return rs;
}
GSFrame::GSFrame(wxWindow* parent, const wxString& title) : wxFrame(parent, wxID_ANY, title)
{
CellVideoOutResolution res = ResolutionTable[ResolutionIdToNum(Ini.GSResolution.GetValue())]; CellVideoOutResolution res = ResolutionTable[ResolutionIdToNum(Ini.GSResolution.GetValue())];
SetClientSize(res.width, res.height); SetClientSize(res.width, res.height);
wxGetApp().Bind(wxEVT_KEY_DOWN, &GSFrame::OnKeyDown, this); wxGetApp().Bind(wxEVT_KEY_DOWN, &GSFrame::OnKeyDown, this);
@ -45,19 +34,6 @@ void GSFrame::OnClose(wxCloseEvent& event)
Emu.Stop(); Emu.Stop();
} }
/*
void GSFrame::OnSize(wxSizeEvent&)
{
const wxSize client = GetClientSize();
const wxSize viewport = AspectRatio(client, m_size);
const int x = (client.GetX() - viewport.GetX()) / 2;
const int y = (client.GetY() - viewport.GetY()) / 2;
SetViewport(wxPoint(x, y), viewport);
}
*/
void GSFrame::OnKeyDown(wxKeyEvent& event) void GSFrame::OnKeyDown(wxKeyEvent& event)
{ {
switch (event.GetKeyCode()) switch (event.GetKeyCode())
@ -73,13 +49,72 @@ void GSFrame::OnFullScreen()
ShowFullScreen(!IsFullScreen()); ShowFullScreen(!IsFullScreen());
} }
void GSFrame::close()
/*
void GSFrame::SetSize(int width, int height)
{ {
m_size.SetWidth(width); wxFrame::Close();
m_size.SetHeight(height); }
//wxFrame::SetSize(width, height);
OnSize(wxSizeEvent()); bool GSFrame::shown()
{
return wxFrame::IsShown();
}
void GSFrame::hide()
{
wxFrame::Hide();
}
void GSFrame::show()
{
wxFrame::Show();
}
void* GSFrame::handle() const
{
return GetHandle();
}
void* GSFrame::make_context()
{
return nullptr;
}
void GSFrame::set_current(draw_context_t ctx)
{
}
void GSFrame::delete_context(void* ctx)
{
}
size2i GSFrame::client_size()
{
wxSize size = GetClientSize();
return{ size.GetWidth(), size.GetHeight() };
}
void GSFrame::flip(draw_context_t)
{
++m_frames;
static Timer fps_t;
if (fps_t.GetElapsedTimeInSec() >= 0.5)
{
std::string title = fmt::format("FPS: %.2f", (double)m_frames / fps_t.GetElapsedTimeInSec());
if (!m_title_message.empty())
title += " | " + m_title_message;
if (!Emu.GetTitle().empty())
title += " | " + Emu.GetTitle();
if (!Emu.GetTitleID().empty())
title += " | [" + Emu.GetTitleID() + "]";
// can freeze on exit
SetTitle(wxString(title.c_str(), wxConvUTF8));
m_frames = 0;
fps_t.Start();
}
} }
*/

View file

@ -1,21 +1,34 @@
#pragma once #pragma once
#include "Emu/RSX/GSRender.h"
wxSize AspectRatio(wxSize rs, const wxSize as); class GSFrame : public wxFrame, public GSFrameBase
class GSFrame : public wxFrame
{ {
protected: u64 m_frames;
GSFrame(wxWindow* parent, const wxString& title);
virtual void SetViewport(int x, int y, u32 w, u32 h) {} public:
GSFrame(const wxString& title);
protected:
virtual void OnPaint(wxPaintEvent& event); virtual void OnPaint(wxPaintEvent& event);
virtual void OnClose(wxCloseEvent& event); virtual void OnClose(wxCloseEvent& event);
//virtual void OnSize(wxSizeEvent&);
void OnKeyDown(wxKeyEvent& event); void OnKeyDown(wxKeyEvent& event);
void OnFullScreen(); void OnFullScreen();
void close() override;
bool shown() override;
void hide() override;
void show() override;
void* handle() const override;
void* make_context() override;
void set_current(draw_context_t context) override;
void delete_context(void* context) override;
void flip(draw_context_t context) override;
size2i client_size() override;
public: public:
void OnLeftDclick(wxMouseEvent&) void OnLeftDclick(wxMouseEvent&)
{ {

View file

@ -75,6 +75,7 @@
<ClCompile Include="Emu\RSX\D3D12\D3D12CommonDecompiler.cpp" /> <ClCompile Include="Emu\RSX\D3D12\D3D12CommonDecompiler.cpp" />
<ClCompile Include="Emu\RSX\GL\GLCommonDecompiler.cpp" /> <ClCompile Include="Emu\RSX\GL\GLCommonDecompiler.cpp" />
<ClCompile Include="Emu\RSX\GL\gl_helpers.cpp" /> <ClCompile Include="Emu\RSX\GL\gl_helpers.cpp" />
<ClCompile Include="Emu\RSX\Null\NullGSRender.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\sys_dbg.cpp" /> <ClCompile Include="Emu\SysCalls\lv2\sys_dbg.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\sys_fs.cpp" /> <ClCompile Include="Emu\SysCalls\lv2\sys_fs.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellAtracMulti.cpp" /> <ClCompile Include="Emu\SysCalls\Modules\cellAtracMulti.cpp" />

View file

@ -992,6 +992,9 @@
<ClCompile Include="Emu\RSX\GL\gl_helpers.cpp"> <ClCompile Include="Emu\RSX\GL\gl_helpers.cpp">
<Filter>Emu\GPU\RSX\GL</Filter> <Filter>Emu\GPU\RSX\GL</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Emu\RSX\Null\NullGSRender.cpp">
<Filter>Emu\GPU\RSX\Null</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Crypto\aes.h"> <ClInclude Include="Crypto\aes.h">

View file

@ -26,7 +26,6 @@
#include "Gui/SaveDataDialog.h" #include "Gui/SaveDataDialog.h"
#include "Gui/GLGSFrame.h" #include "Gui/GLGSFrame.h"
#include "Gui/D3DGSFrame.h"
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
#ifdef _WIN32 #ifdef _WIN32
@ -112,18 +111,20 @@ bool Rpcs3App::OnInit()
} }
}; };
callbacks.get_gs_frame = []() -> std::unique_ptr<GSFrameBase> callbacks.get_gs_frame = [](frame_type type) -> std::unique_ptr<GSFrameBase>
{ {
return std::make_unique<GLGSFrame>(); switch (type)
}; {
case frame_type::OpenGL:
return std::make_unique<GLGSFrame>();
// TODO: unify with get_gs_frame callback case frame_type::DX12:
#if defined(DX12_SUPPORT) return std::make_unique<GSFrame>("DirectX 12");
SetGetD3DGSFrameCallback([]() ->GSFrameBase2*
{ case frame_type::Null:
return new D3DGSFrame(); return std::make_unique<GSFrame>("Null");
}); }
#endif };
callbacks.get_msg_dialog = []() -> std::unique_ptr<MsgDialogBase> callbacks.get_msg_dialog = []() -> std::unique_ptr<MsgDialogBase>
{ {

View file

@ -511,7 +511,6 @@
<ClCompile Include="Gui\CgDisasm.cpp" /> <ClCompile Include="Gui\CgDisasm.cpp" />
<ClCompile Include="Gui\CompilerELF.cpp" /> <ClCompile Include="Gui\CompilerELF.cpp" />
<ClCompile Include="Gui\ConLogFrame.cpp" /> <ClCompile Include="Gui\ConLogFrame.cpp" />
<ClCompile Include="Gui\D3DGSFrame.cpp" />
<ClCompile Include="Gui\Debugger.cpp" /> <ClCompile Include="Gui\Debugger.cpp" />
<ClCompile Include="Gui\DisAsmFrame.cpp" /> <ClCompile Include="Gui\DisAsmFrame.cpp" />
<ClCompile Include="Gui\GameViewer.cpp" /> <ClCompile Include="Gui\GameViewer.cpp" />
@ -561,7 +560,6 @@
<ClInclude Include="Gui\CgDisasm.h" /> <ClInclude Include="Gui\CgDisasm.h" />
<ClInclude Include="Gui\CompilerELF.h" /> <ClInclude Include="Gui\CompilerELF.h" />
<ClInclude Include="Gui\ConLogFrame.h" /> <ClInclude Include="Gui\ConLogFrame.h" />
<ClInclude Include="Gui\D3DGSFrame.h" />
<ClInclude Include="Gui\Debugger.h" /> <ClInclude Include="Gui\Debugger.h" />
<ClInclude Include="Gui\DisAsmFrame.h" /> <ClInclude Include="Gui\DisAsmFrame.h" />
<ClInclude Include="Gui\FrameBase.h" /> <ClInclude Include="Gui\FrameBase.h" />

View file

@ -102,9 +102,6 @@
<ClCompile Include="Gui\SaveDataDialog.cpp"> <ClCompile Include="Gui\SaveDataDialog.cpp">
<Filter>Gui</Filter> <Filter>Gui</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Gui\D3DGSFrame.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="Gui\SettingsDialog.cpp"> <ClCompile Include="Gui\SettingsDialog.cpp">
<Filter>Gui</Filter> <Filter>Gui</Filter>
</ClCompile> </ClCompile>
@ -216,9 +213,6 @@
<Filter>Gui</Filter> <Filter>Gui</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="Gui\D3DGSFrame.h">
<Filter>Gui</Filter>
</ClInclude>
<ClInclude Include="Gui\SettingsDialog.h"> <ClInclude Include="Gui\SettingsDialog.h">
<Filter>Gui</Filter> <Filter>Gui</Filter>
</ClInclude> </ClInclude>