diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index a8a1e2deba..c6d07b64ac 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -3,6 +3,8 @@ #include "D3D12Buffer.h" #include "Utilities/Log.h" +#include "D3D12GSRender.h" + const int g_vertexCount = 32; // Where are these type defined ??? @@ -220,4 +222,326 @@ std::vector getIALayout(ID3D12Device *device, bool ind return result; } +static +D3D12_RESOURCE_DESC getBufferResourceDesc(size_t sizeInByte) +{ + D3D12_RESOURCE_DESC BufferDesc = {}; + BufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + BufferDesc.Width = (UINT)sizeInByte; + BufferDesc.Height = 1; + BufferDesc.DepthOrArraySize = 1; + BufferDesc.SampleDesc.Count = 1; + BufferDesc.MipLevels = 1; + BufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + return BufferDesc; +} + +// D3D12GS member handling buffers + +std::pair, D3D12_INDEX_BUFFER_VIEW> D3D12GSRender::EnableVertexData(bool indexed_draw) +{ + std::pair, D3D12_INDEX_BUFFER_VIEW> result; + m_IASet = getIALayout(m_device, indexed_draw, m_vertex_data); + + const u32 data_offset = indexed_draw ? 0 : m_draw_array_first; + + for (u32 i = 0; i < m_vertex_count; ++i) + { + if (!m_vertex_data[i].IsEnabled()) continue; + const size_t item_size = m_vertex_data[i].GetTypeSize() * m_vertex_data[i].size; + const size_t data_size = m_vertex_data[i].data.size() - data_offset * item_size; + size_t subBufferSize = (data_offset + data_size) * item_size; + // 65536 alignment + size_t bufferHeapOffset = getCurrentResourceStorage().m_vertexIndexBuffersHeapFreeSpace; + bufferHeapOffset = (bufferHeapOffset + 65536 - 1) & ~65535; + + ID3D12Resource *vertexBuffer; + check(m_device->CreatePlacedResource( + getCurrentResourceStorage().m_vertexIndexBuffersHeap, + bufferHeapOffset, + &getBufferResourceDesc(subBufferSize), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&vertexBuffer) + )); + void *bufferMap; + check(vertexBuffer->Map(0, nullptr, (void**)&bufferMap)); + memcpy((char*)bufferMap + data_offset * item_size, &m_vertex_data[i].data[data_offset * item_size], data_size); + vertexBuffer->Unmap(0, nullptr); + getCurrentResourceStorage().m_inflightResources.push_back(vertexBuffer); + + D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {}; + vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress(); + vertexBufferView.SizeInBytes = (UINT)subBufferSize; + vertexBufferView.StrideInBytes = (UINT)item_size; + result.first.push_back(vertexBufferView); + getCurrentResourceStorage().m_vertexIndexBuffersHeapFreeSpace = bufferHeapOffset + subBufferSize; + } + + // Only handle quads now + switch (m_draw_mode - 1) + { + default: + case GL_POINTS: + case GL_LINES: + case GL_LINE_LOOP: + case GL_LINE_STRIP: + case GL_TRIANGLES: + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + case GL_QUAD_STRIP: + case GL_POLYGON: + m_forcedIndexBuffer = false; + break; + case GL_QUADS: + m_forcedIndexBuffer = true; + break; + } + + if (indexed_draw || m_forcedIndexBuffer) + { + size_t subBufferSize; + if (indexed_draw && !m_forcedIndexBuffer) + subBufferSize = m_indexed_array.m_data.size(); + else if (indexed_draw && m_forcedIndexBuffer) + subBufferSize = 6 * m_indexed_array.m_data.size() / 4; + else + subBufferSize = 2 * m_draw_array_count * 6 / 4; + // 65536 alignment + size_t bufferHeapOffset = getCurrentResourceStorage().m_vertexIndexBuffersHeapFreeSpace; + bufferHeapOffset = (bufferHeapOffset + 65536 - 1) & ~65535; + + ID3D12Resource *indexBuffer; + check(m_device->CreatePlacedResource( + getCurrentResourceStorage().m_vertexIndexBuffersHeap, + D3D12_HEAP_FLAG_NONE, + &getBufferResourceDesc(subBufferSize), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&indexBuffer) + )); + + unsigned short *bufferMap; + check(indexBuffer->Map(0, nullptr, (void**)&bufferMap)); + size_t forcedIndexCount = 0; + if (indexed_draw && !m_forcedIndexBuffer) + memcpy(bufferMap, m_indexed_array.m_data.data(), subBufferSize); + else if (indexed_draw && m_forcedIndexBuffer) + { + size_t indexcount = m_indexed_array.m_data.size() / 2; + unsigned short *indexList = (unsigned short*)m_indexed_array.m_data.data(); + for (unsigned i = 0; i < indexcount / 4; i++) + { + // First triangle + bufferMap[6 * i] = indexList[4 * i]; + bufferMap[6 * i + 1] = indexList[4 * i + 1]; + bufferMap[6 * i + 2] = indexList[4 * i + 2]; + // Second triangle + bufferMap[6 * i + 3] = indexList[4 * i + 2]; + bufferMap[6 * i + 4] = indexList[4 * i + 3]; + bufferMap[6 * i + 5] = indexList[4 * i]; + forcedIndexCount += 6; + } + } + else + { + for (unsigned i = 0; i < m_draw_array_count / 4; i++) + { + // First triangle + bufferMap[6 * i] = 4 * i; + bufferMap[6 * i + 1] = 4 * i + 1; + bufferMap[6 * i + 2] = 4 * i + 2; + // Second triangle + bufferMap[6 * i + 3] = 4 * i; + bufferMap[6 * i + 4] = 4 * i + 2; + bufferMap[6 * i + 5] = 4 * i + 3; + forcedIndexCount += 6; + } + } + indexBuffer->Unmap(0, nullptr); + getCurrentResourceStorage().m_inflightResources.push_back(indexBuffer); + getCurrentResourceStorage().m_vertexIndexBuffersHeapFreeSpace = bufferHeapOffset + subBufferSize; + getCurrentResourceStorage().m_indexBufferCount = forcedIndexCount; + + D3D12_INDEX_BUFFER_VIEW indexBufferView = {}; + indexBufferView.SizeInBytes = (UINT)subBufferSize; + indexBufferView.BufferLocation = indexBuffer->GetGPUVirtualAddress(); + switch (m_indexed_array.m_type) + { + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: + indexBufferView.Format = DXGI_FORMAT_R32_UINT; + break; + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: + indexBufferView.Format = DXGI_FORMAT_R16_UINT; + break; + } + if (m_forcedIndexBuffer) + indexBufferView.Format = DXGI_FORMAT_R16_UINT; + + result.second = indexBufferView; + } + return result; +} + +void D3D12GSRender::setScaleOffset() +{ + float scaleOffsetMat[16] = + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + // Scale + scaleOffsetMat[0] *= (float&)methodRegisters[NV4097_SET_VIEWPORT_SCALE + (0x4 * 0)] / (RSXThread::m_width / RSXThread::m_width_scale); + scaleOffsetMat[5] *= (float&)methodRegisters[NV4097_SET_VIEWPORT_SCALE + (0x4 * 1)] / (RSXThread::m_height / RSXThread::m_height_scale); + scaleOffsetMat[10] = (float&)methodRegisters[NV4097_SET_VIEWPORT_SCALE + (0x4 * 2)]; + + // Offset + scaleOffsetMat[3] = (float&)methodRegisters[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 0)] - (RSXThread::m_width / RSXThread::m_width_scale); + scaleOffsetMat[7] = (float&)methodRegisters[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 1)] - (RSXThread::m_height / RSXThread::m_height_scale); + scaleOffsetMat[11] = (float&)methodRegisters[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 2)]; + + scaleOffsetMat[3] /= RSXThread::m_width / RSXThread::m_width_scale; + scaleOffsetMat[7] /= RSXThread::m_height / RSXThread::m_height_scale; + + size_t constantBuffersHeapOffset = getCurrentResourceStorage().m_constantsBuffersHeapFreeSpace; + // 65536 alignment + constantBuffersHeapOffset = (constantBuffersHeapOffset + 65536 - 1) & ~65535; + + // Scale offset buffer + // Separate constant buffer + ID3D12Resource *scaleOffsetBuffer; + check(m_device->CreatePlacedResource( + getCurrentResourceStorage().m_constantsBuffersHeap, + constantBuffersHeapOffset, + &getBufferResourceDesc(256), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&scaleOffsetBuffer) + )); + + void *scaleOffsetMap; + check(scaleOffsetBuffer->Map(0, nullptr, &scaleOffsetMap)); + streamToBuffer(scaleOffsetMap, scaleOffsetMat, 16 * sizeof(float)); + scaleOffsetBuffer->Unmap(0, nullptr); + + D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {}; + constantBufferViewDesc.BufferLocation = scaleOffsetBuffer->GetGPUVirtualAddress(); + constantBufferViewDesc.SizeInBytes = (UINT)256; + D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_scaleOffsetDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + Handle.ptr += getCurrentResourceStorage().m_currentScaleOffsetBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle); + getCurrentResourceStorage().m_constantsBuffersHeapFreeSpace = constantBuffersHeapOffset + 256; + getCurrentResourceStorage().m_inflightResources.push_back(scaleOffsetBuffer); +} + +void D3D12GSRender::FillVertexShaderConstantsBuffer() +{ + for (const RSXTransformConstant& c : m_transform_constants) + { + size_t offset = c.id * 4 * sizeof(float); + float vector[] = { c.x, c.y, c.z, c.w }; + memcpy((char*)vertexConstantShadowCopy + offset, vector, 4 * sizeof(float)); + } + + size_t constantBuffersHeapOffset = getCurrentResourceStorage().m_constantsBuffersHeapFreeSpace; + // 65536 alignment + constantBuffersHeapOffset = (constantBuffersHeapOffset + 65536 - 1) & ~65535; + + ID3D12Resource *constantsBuffer; + check(m_device->CreatePlacedResource( + getCurrentResourceStorage().m_constantsBuffersHeap, + constantBuffersHeapOffset, + &getBufferResourceDesc(512 * 4 * sizeof(float)), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&constantsBuffer) + )); + + void *constantsBufferMap; + check(constantsBuffer->Map(0, nullptr, &constantsBufferMap)); + streamToBuffer(constantsBufferMap, vertexConstantShadowCopy, 512 * 4 * sizeof(float)); + constantsBuffer->Unmap(0, nullptr); + + D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {}; + constantBufferViewDesc.BufferLocation = constantsBuffer->GetGPUVirtualAddress(); + constantBufferViewDesc.SizeInBytes = 512 * 4 * sizeof(float); + D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_constantsBufferDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); + Handle.ptr += getCurrentResourceStorage().m_constantsBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle); + getCurrentResourceStorage().m_constantsBuffersHeapFreeSpace = constantBuffersHeapOffset + 512 * 4 * sizeof(float); + getCurrentResourceStorage().m_inflightResources.push_back(constantsBuffer); +} + +void D3D12GSRender::FillPixelShaderConstantsBuffer() +{ + // Get constant from fragment program + const std::vector &fragmentOffset = m_cachePSO.getFragmentConstantOffsetsCache(m_cur_fragment_prog); + size_t bufferSize = fragmentOffset.size() * 4 * sizeof(float) + 1; + // Multiple of 256 never 0 + bufferSize = (bufferSize + 255) & ~255; + + size_t constantBuffersHeapOffset = getCurrentResourceStorage().m_constantsBuffersHeapFreeSpace; + // 65536 alignment + constantBuffersHeapOffset = (constantBuffersHeapOffset + 65536 - 1) & ~65535; + + ID3D12Resource *constantsBuffer; + check(m_device->CreatePlacedResource( + getCurrentResourceStorage().m_constantsBuffersHeap, + constantBuffersHeapOffset, + &getBufferResourceDesc(bufferSize), + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&constantsBuffer) + )); + + size_t offset = 0; + void *constantsBufferMap; + check(constantsBuffer->Map(0, nullptr, &constantsBufferMap)); + for (size_t offsetInFP : fragmentOffset) + { + u32 vector[4]; + // Is it assigned by color register in command buffer ? + if (!m_fragment_constants.empty() && offsetInFP == m_fragment_constants.front().id - m_cur_fragment_prog->offset) + { + const RSXTransformConstant& c = m_fragment_constants.front(); + vector[0] = (u32&)c.x; + vector[1] = (u32&)c.y; + vector[2] = (u32&)c.z; + vector[3] = (u32&)c.w; + } + else + { + auto data = vm::ptr::make(m_cur_fragment_prog->addr + (u32)offsetInFP); + + u32 c0 = (data[0] >> 16 | data[0] << 16); + u32 c1 = (data[1] >> 16 | data[1] << 16); + u32 c2 = (data[2] >> 16 | data[2] << 16); + u32 c3 = (data[3] >> 16 | data[3] << 16); + + vector[0] = c0; + vector[1] = c1; + vector[2] = c2; + vector[3] = c3; + } + + streamToBuffer((char*)constantsBufferMap + offset, vector, 4 * sizeof(u32)); + offset += 4 * sizeof(u32); + } + + constantsBuffer->Unmap(0, nullptr); + + D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {}; + constantBufferViewDesc.BufferLocation = constantsBuffer->GetGPUVirtualAddress(); + constantBufferViewDesc.SizeInBytes = (UINT)bufferSize; + D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_constantsBufferDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); + Handle.ptr += getCurrentResourceStorage().m_constantsBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle); + getCurrentResourceStorage().m_constantsBuffersHeapFreeSpace = constantBuffersHeapOffset + bufferSize; + getCurrentResourceStorage().m_inflightResources.push_back(constantsBuffer); +} + + #endif \ No newline at end of file diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 556951333e..93bb435973 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -5,9 +5,6 @@ #include #include -// Some constants are the same between RSX and GL -#include - GetGSFrameCb2 GetGSFrame = nullptr; void SetGetD3DGSFrameCallback(GetGSFrameCb2 value) @@ -428,279 +425,6 @@ void D3D12GSRender::ExecCMD(u32 cmd) m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**) &commandList); } -std::pair, D3D12_INDEX_BUFFER_VIEW> D3D12GSRender::EnableVertexData(bool indexed_draw) -{ - std::pair, D3D12_INDEX_BUFFER_VIEW> result; - m_IASet = getIALayout(m_device, indexed_draw, m_vertex_data); - - const u32 data_offset = indexed_draw ? 0 : m_draw_array_first; - - for (u32 i = 0; i < m_vertex_count; ++i) - { - if (!m_vertex_data[i].IsEnabled()) continue; - const size_t item_size = m_vertex_data[i].GetTypeSize() * m_vertex_data[i].size; - const size_t data_size = m_vertex_data[i].data.size() - data_offset * item_size; - size_t subBufferSize = (data_offset + data_size) * item_size; - // 65536 alignment - size_t bufferHeapOffset = getCurrentResourceStorage().m_vertexIndexBuffersHeapFreeSpace; - bufferHeapOffset = (bufferHeapOffset + 65536 - 1) & ~65535; - - ID3D12Resource *vertexBuffer; - D3D12_RESOURCE_DESC vertexBufferDesc = {}; - vertexBufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - vertexBufferDesc.Width = (UINT)subBufferSize; - vertexBufferDesc.Height = 1; - vertexBufferDesc.DepthOrArraySize = 1; - vertexBufferDesc.SampleDesc.Count = 1; - vertexBufferDesc.MipLevels = 1; - vertexBufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - check(m_device->CreatePlacedResource( - getCurrentResourceStorage().m_vertexIndexBuffersHeap, - bufferHeapOffset, - &vertexBufferDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&vertexBuffer) - )); - void *bufferMap; - check(vertexBuffer->Map(0, nullptr, (void**)&bufferMap)); - memcpy((char*)bufferMap + data_offset * item_size, &m_vertex_data[i].data[data_offset * item_size], data_size); - vertexBuffer->Unmap(0, nullptr); - getCurrentResourceStorage().m_inflightResources.push_back(vertexBuffer); - - D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {}; - vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress(); - vertexBufferView.SizeInBytes = (UINT)subBufferSize; - vertexBufferView.StrideInBytes = (UINT)item_size; - result.first.push_back(vertexBufferView); - getCurrentResourceStorage().m_vertexIndexBuffersHeapFreeSpace = bufferHeapOffset + subBufferSize; - } - - // Only handle quads now - switch (m_draw_mode - 1) - { - default: - case GL_POINTS: - case GL_LINES: - case GL_LINE_LOOP: - case GL_LINE_STRIP: - case GL_TRIANGLES: - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: - case GL_QUAD_STRIP: - case GL_POLYGON: - m_forcedIndexBuffer = false; - break; - case GL_QUADS: - m_forcedIndexBuffer = true; - break; - } - - if (indexed_draw || m_forcedIndexBuffer) - { - size_t subBufferSize; - if (indexed_draw && !m_forcedIndexBuffer) - subBufferSize = m_indexed_array.m_data.size(); - else if (indexed_draw && m_forcedIndexBuffer) - subBufferSize = 6 * m_indexed_array.m_data.size() / 4; - else - subBufferSize = 2 * m_draw_array_count * 6 / 4; - // 65536 alignment - size_t bufferHeapOffset = getCurrentResourceStorage().m_vertexIndexBuffersHeapFreeSpace; - bufferHeapOffset = (bufferHeapOffset + 65536 - 1) & ~65535; - - - D3D12_RESOURCE_DESC resDesc = {}; - resDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - resDesc.Width = (UINT)subBufferSize; - resDesc.Height = 1; - resDesc.DepthOrArraySize = 1; - resDesc.SampleDesc.Count = 1; - resDesc.MipLevels = 1; - resDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - - ID3D12Resource *indexBuffer; - check(m_device->CreatePlacedResource( - getCurrentResourceStorage().m_vertexIndexBuffersHeap, - D3D12_HEAP_FLAG_NONE, - &resDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&indexBuffer) - )); - - unsigned short *bufferMap; - check(indexBuffer->Map(0, nullptr, (void**)&bufferMap)); - size_t forcedIndexCount = 0; - if (indexed_draw && !m_forcedIndexBuffer) - memcpy(bufferMap, m_indexed_array.m_data.data(), subBufferSize); - else if (indexed_draw && m_forcedIndexBuffer) - { - size_t indexcount = m_indexed_array.m_data.size() / 2; - unsigned short *indexList = (unsigned short*)m_indexed_array.m_data.data(); - for (unsigned i = 0; i < indexcount / 4; i++) - { - // First triangle - bufferMap[6 * i] = indexList[4 * i]; - bufferMap[6 * i + 1] = indexList[4 * i + 1]; - bufferMap[6 * i + 2] = indexList[4 * i + 2]; - // Second triangle - bufferMap[6 * i + 3] = indexList[4 * i + 2]; - bufferMap[6 * i + 4] = indexList[4 * i + 3]; - bufferMap[6 * i + 5] = indexList[4 * i]; - forcedIndexCount += 6; - } - } - else - { - for (unsigned i = 0; i < m_draw_array_count / 4; i++) - { - // First triangle - bufferMap[6 * i] = 4 * i; - bufferMap[6 * i + 1] = 4 * i + 1; - bufferMap[6 * i + 2] = 4 * i + 2; - // Second triangle - bufferMap[6 * i + 3] = 4 * i; - bufferMap[6 * i + 4] = 4 * i + 2; - bufferMap[6 * i + 5] = 4 * i + 3; - forcedIndexCount += 6; - } - } - indexBuffer->Unmap(0, nullptr); - getCurrentResourceStorage().m_inflightResources.push_back(indexBuffer); - getCurrentResourceStorage().m_vertexIndexBuffersHeapFreeSpace = bufferHeapOffset + subBufferSize; - getCurrentResourceStorage().m_indexBufferCount = forcedIndexCount; - - D3D12_INDEX_BUFFER_VIEW indexBufferView = {}; - indexBufferView.SizeInBytes = (UINT)subBufferSize; - indexBufferView.BufferLocation = indexBuffer->GetGPUVirtualAddress(); - switch (m_indexed_array.m_type) - { - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: - indexBufferView.Format = DXGI_FORMAT_R32_UINT; - break; - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: - indexBufferView.Format = DXGI_FORMAT_R16_UINT; - break; - } - if (m_forcedIndexBuffer) - indexBufferView.Format = DXGI_FORMAT_R16_UINT; - - result.second = indexBufferView; - } - return result; -} - -void D3D12GSRender::setScaleOffset() -{ - float scaleOffsetMat[16] = - { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, -1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; - - // Scale - scaleOffsetMat[0] *= (float&)methodRegisters[NV4097_SET_VIEWPORT_SCALE + (0x4 * 0)] / (RSXThread::m_width / RSXThread::m_width_scale); - scaleOffsetMat[5] *= (float&)methodRegisters[NV4097_SET_VIEWPORT_SCALE + (0x4 * 1)] / (RSXThread::m_height / RSXThread::m_height_scale); - scaleOffsetMat[10] = (float&)methodRegisters[NV4097_SET_VIEWPORT_SCALE + (0x4 * 2)]; - - // Offset - scaleOffsetMat[3] = (float&)methodRegisters[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 0)] - (RSXThread::m_width / RSXThread::m_width_scale); - scaleOffsetMat[7] = (float&)methodRegisters[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 1)] - (RSXThread::m_height / RSXThread::m_height_scale); - scaleOffsetMat[11] = (float&)methodRegisters[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 2)]; - - scaleOffsetMat[3] /= RSXThread::m_width / RSXThread::m_width_scale; - scaleOffsetMat[7] /= RSXThread::m_height / RSXThread::m_height_scale; - - size_t constantBuffersHeapOffset = getCurrentResourceStorage().m_constantsBuffersHeapFreeSpace; - // 65536 alignment - constantBuffersHeapOffset = (constantBuffersHeapOffset + 65536 - 1) & ~65535; - - D3D12_RESOURCE_DESC resDesc = {}; - resDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - resDesc.Width = 256; - resDesc.Height = 1; - resDesc.DepthOrArraySize = 1; - resDesc.SampleDesc.Count = 1; - resDesc.MipLevels = 1; - resDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - - // Scale offset buffer - // Separate constant buffer - ID3D12Resource *scaleOffsetBuffer; - check(m_device->CreatePlacedResource( - getCurrentResourceStorage().m_constantsBuffersHeap, - constantBuffersHeapOffset, - &resDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&scaleOffsetBuffer) - )); - - void *scaleOffsetMap; - check(scaleOffsetBuffer->Map(0, nullptr, &scaleOffsetMap)); - streamToBuffer(scaleOffsetMap, scaleOffsetMat, 16 * sizeof(float)); - scaleOffsetBuffer->Unmap(0, nullptr); - - D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {}; - constantBufferViewDesc.BufferLocation = scaleOffsetBuffer->GetGPUVirtualAddress(); - constantBufferViewDesc.SizeInBytes = (UINT)256; - D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_scaleOffsetDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); - Handle.ptr += getCurrentResourceStorage().m_currentScaleOffsetBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle); - getCurrentResourceStorage().m_constantsBuffersHeapFreeSpace = constantBuffersHeapOffset + 256; - getCurrentResourceStorage().m_inflightResources.push_back(scaleOffsetBuffer); -} - -void D3D12GSRender::FillVertexShaderConstantsBuffer() -{ - for (const RSXTransformConstant& c : m_transform_constants) - { - size_t offset = c.id * 4 * sizeof(float); - float vector[] = { c.x, c.y, c.z, c.w }; - memcpy((char*)vertexConstantShadowCopy + offset, vector, 4 * sizeof(float)); - } - - size_t constantBuffersHeapOffset = getCurrentResourceStorage().m_constantsBuffersHeapFreeSpace; - // 65536 alignment - constantBuffersHeapOffset = (constantBuffersHeapOffset + 65536 - 1) & ~65535; - - D3D12_RESOURCE_DESC resDesc = {}; - resDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - resDesc.Width = 512 * 4 * sizeof(float); - resDesc.Height = 1; - resDesc.DepthOrArraySize = 1; - resDesc.SampleDesc.Count = 1; - resDesc.MipLevels = 1; - resDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - - ID3D12Resource *constantsBuffer; - check(m_device->CreatePlacedResource( - getCurrentResourceStorage().m_constantsBuffersHeap, - constantBuffersHeapOffset, - &resDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&constantsBuffer) - )); - - void *constantsBufferMap; - check(constantsBuffer->Map(0, nullptr, &constantsBufferMap)); - streamToBuffer(constantsBufferMap, vertexConstantShadowCopy, 512 * 4 * sizeof(float)); - constantsBuffer->Unmap(0, nullptr); - - D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {}; - constantBufferViewDesc.BufferLocation = constantsBuffer->GetGPUVirtualAddress(); - constantBufferViewDesc.SizeInBytes = 512 * 4 * sizeof(float); - D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_constantsBufferDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); - Handle.ptr += getCurrentResourceStorage().m_constantsBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle); - getCurrentResourceStorage().m_constantsBuffersHeapFreeSpace = constantBuffersHeapOffset + 512 * 4 * sizeof(float); - getCurrentResourceStorage().m_inflightResources.push_back(constantsBuffer); -} - static D3D12_BLEND_OP getBlendOp() { @@ -727,84 +451,6 @@ D3D12_BLEND getBlendFactor(u16 glFactor) } } -void D3D12GSRender::FillPixelShaderConstantsBuffer() -{ - // Get constant from fragment program - const std::vector &fragmentOffset = m_cachePSO.getFragmentConstantOffsetsCache(m_cur_fragment_prog); - size_t bufferSize = fragmentOffset.size() * 4 * sizeof(float) + 1; - // Multiple of 256 never 0 - bufferSize = (bufferSize + 255) & ~255; - - size_t constantBuffersHeapOffset = getCurrentResourceStorage().m_constantsBuffersHeapFreeSpace; - // 65536 alignment - constantBuffersHeapOffset = (constantBuffersHeapOffset + 65536 - 1) & ~65535; - - D3D12_RESOURCE_DESC resDesc = {}; - resDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - resDesc.Width = (UINT)bufferSize; - resDesc.Height = 1; - resDesc.DepthOrArraySize = 1; - resDesc.SampleDesc.Count = 1; - resDesc.MipLevels = 1; - resDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - - ID3D12Resource *constantsBuffer; - check(m_device->CreatePlacedResource( - getCurrentResourceStorage().m_constantsBuffersHeap, - constantBuffersHeapOffset, - &resDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&constantsBuffer) - )); - - size_t offset = 0; - void *constantsBufferMap; - check(constantsBuffer->Map(0, nullptr, &constantsBufferMap)); - for (size_t offsetInFP : fragmentOffset) - { - u32 vector[4]; - // Is it assigned by color register in command buffer ? - if (!m_fragment_constants.empty() && offsetInFP == m_fragment_constants.front().id - m_cur_fragment_prog->offset) - { - const RSXTransformConstant& c = m_fragment_constants.front(); - vector[0] = (u32&)c.x; - vector[1] = (u32&)c.y; - vector[2] = (u32&)c.z; - vector[3] = (u32&)c.w; - } - else - { - auto data = vm::ptr::make(m_cur_fragment_prog->addr + (u32)offsetInFP); - - u32 c0 = (data[0] >> 16 | data[0] << 16); - u32 c1 = (data[1] >> 16 | data[1] << 16); - u32 c2 = (data[2] >> 16 | data[2] << 16); - u32 c3 = (data[3] >> 16 | data[3] << 16); - - vector[0] = c0; - vector[1] = c1; - vector[2] = c2; - vector[3] = c3; - } - - streamToBuffer((char*)constantsBufferMap + offset, vector, 4 * sizeof(u32)); - offset += 4 * sizeof(u32); - } - - constantsBuffer->Unmap(0, nullptr); - - D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {}; - constantBufferViewDesc.BufferLocation = constantsBuffer->GetGPUVirtualAddress(); - constantBufferViewDesc.SizeInBytes = (UINT)bufferSize; - D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_constantsBufferDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); - Handle.ptr += getCurrentResourceStorage().m_constantsBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle); - getCurrentResourceStorage().m_constantsBuffersHeapFreeSpace = constantBuffersHeapOffset + bufferSize; - getCurrentResourceStorage().m_inflightResources.push_back(constantsBuffer); -} - - bool D3D12GSRender::LoadProgram() { if (!m_cur_fragment_prog) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index 86a8808641..e69e0cef51 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -14,6 +14,9 @@ #include "D3D12PipelineState.h" #include "D3D12Buffer.h" +// Some constants are the same between RSX and GL +#include + #pragma comment (lib, "d3d12.lib") #pragma comment (lib, "dxgi.lib")