mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
d3d12; Live buffer related code and factorise resource_desc for buffers
This commit is contained in:
parent
9814a92a25
commit
22f413be3a
3 changed files with 327 additions and 354 deletions
|
@ -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<D3D12_INPUT_ELEMENT_DESC> 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<std::vector<D3D12_VERTEX_BUFFER_VIEW>, D3D12_INDEX_BUFFER_VIEW> D3D12GSRender::EnableVertexData(bool indexed_draw)
|
||||
{
|
||||
std::pair<std::vector<D3D12_VERTEX_BUFFER_VIEW>, 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<size_t> &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<u32>::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
|
|
@ -5,9 +5,6 @@
|
|||
#include <dxgi1_4.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
// Some constants are the same between RSX and GL
|
||||
#include <GL\GL.h>
|
||||
|
||||
GetGSFrameCb2 GetGSFrame = nullptr;
|
||||
|
||||
void SetGetD3DGSFrameCallback(GetGSFrameCb2 value)
|
||||
|
@ -428,279 +425,6 @@ void D3D12GSRender::ExecCMD(u32 cmd)
|
|||
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**) &commandList);
|
||||
}
|
||||
|
||||
std::pair<std::vector<D3D12_VERTEX_BUFFER_VIEW>, D3D12_INDEX_BUFFER_VIEW> D3D12GSRender::EnableVertexData(bool indexed_draw)
|
||||
{
|
||||
std::pair<std::vector<D3D12_VERTEX_BUFFER_VIEW>, 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<size_t> &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<u32>::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)
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#include "D3D12PipelineState.h"
|
||||
#include "D3D12Buffer.h"
|
||||
|
||||
// Some constants are the same between RSX and GL
|
||||
#include <GL\GL.h>
|
||||
|
||||
#pragma comment (lib, "d3d12.lib")
|
||||
#pragma comment (lib, "dxgi.lib")
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue