RSX/common: Clean BufferUtils code

* Add noexcept
* Use a_b_c code style
* Use anonymous namespace
This commit is contained in:
Vincent Lejeune 2015-10-27 01:19:04 +01:00
parent 42467ba40f
commit 1ec18bdf64
7 changed files with 177 additions and 244 deletions

View file

@ -79,7 +79,6 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Emu\RSX\D3D12\D3D12Utils.h" /> <ClInclude Include="Emu\RSX\D3D12\D3D12Utils.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12Buffer.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12CommonDecompiler.h" /> <ClInclude Include="Emu\RSX\D3D12\D3D12CommonDecompiler.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12Formats.h" /> <ClInclude Include="Emu\RSX\D3D12\D3D12Formats.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12FragmentProgramDecompiler.h" /> <ClInclude Include="Emu\RSX\D3D12\D3D12FragmentProgramDecompiler.h" />

View file

@ -8,9 +8,6 @@
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Emu\RSX\D3D12\D3D12Buffer.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\D3D12\D3D12CommonDecompiler.h"> <ClInclude Include="Emu\RSX\D3D12\D3D12CommonDecompiler.h">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClInclude> </ClInclude>

View file

@ -5,57 +5,7 @@
#define MIN2(x, y) ((x) < (y)) ? (x) : (y) #define MIN2(x, y) ((x) < (y)) ? (x) : (y)
#define MAX2(x, y) ((x) > (y)) ? (x) : (y) #define MAX2(x, y) ((x) > (y)) ? (x) : (y)
void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_t index, const rsx::data_array_format_info &vertex_array_desc) noexcept
inline
bool overlaps(const std::pair<size_t, size_t> &range1, const std::pair<size_t, size_t> &range2)
{
return !(range1.second < range2.first || range2.second < range1.first);
}
std::vector<VertexBufferFormat> FormatVertexData(const rsx::data_array_format_info *vertex_array_desc, const std::vector<u8> *vertex_data, size_t *vertex_data_size, size_t base_offset)
{
std::vector<VertexBufferFormat> Result;
for (size_t i = 0; i < rsx::limits::vertex_count; ++i)
{
const rsx::data_array_format_info &vertexData = vertex_array_desc[i];
if (!vertexData.size) continue;
u32 addrRegVal = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + i];
u32 addr = rsx::get_address(addrRegVal & 0x7fffffff, addrRegVal >> 31);
size_t elementCount = ((vertexData.array) ? vertex_data_size[i] : vertex_data[i].size()) / (vertexData.size * rsx::get_vertex_type_size(vertexData.type));
// If there is a single element, stride is 0, use the size of element instead
size_t stride = vertexData.stride;
size_t elementSize = rsx::get_vertex_type_size(vertexData.type);
size_t start = addr + base_offset;
size_t end = start + elementSize * vertexData.size + (elementCount - 1) * stride - 1;
std::pair<size_t, size_t> range = std::make_pair(start, end);
assert(start < end);
bool isMerged = false;
for (VertexBufferFormat &vbf : Result)
{
if (overlaps(vbf.range, range) && vbf.stride == stride)
{
// Extend buffer if necessary
vbf.range.first = MIN2(vbf.range.first, range.first);
vbf.range.second = MAX2(vbf.range.second, range.second);
vbf.elementCount = MAX2(vbf.elementCount, elementCount);
vbf.attributeId.push_back(i);
isMerged = true;
break;
}
}
if (isMerged)
continue;
VertexBufferFormat newRange = { range, std::vector<size_t>{ i }, elementCount, stride };
Result.emplace_back(newRange);
}
return Result;
}
void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_t index, const rsx::data_array_format_info &vertex_array_desc)
{ {
assert(vertex_array_desc.array); assert(vertex_array_desc.array);
@ -109,8 +59,10 @@ void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_
} }
} }
namespace
{
template<typename IndexType> template<typename IndexType>
void uploadAsIt(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 &min_index, u32 &max_index) void uploadAsIt(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 &min_index, u32 &max_index) noexcept
{ {
for (u32 i = 0; i < indexCount; ++i) for (u32 i = 0; i < indexCount; ++i)
{ {
@ -124,7 +76,7 @@ void uploadAsIt(char *dst, u32 address, size_t indexCount, bool is_primitive_res
} }
template<typename IndexType> template<typename IndexType>
void expandIndexedTriangleFan(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 &min_index, u32 &max_index) void expandIndexedTriangleFan(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 &min_index, u32 &max_index) noexcept
{ {
for (unsigned i = 0; i < indexCount - 2; i++) for (unsigned i = 0; i < indexCount - 2; i++)
{ {
@ -154,7 +106,7 @@ void expandIndexedTriangleFan(char *dst, u32 address, size_t indexCount, bool is
} }
template<typename IndexType> template<typename IndexType>
void expandIndexedQuads(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 &min_index, u32 &max_index) void expandIndexedQuads(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 &min_index, u32 &max_index) noexcept
{ {
for (unsigned i = 0; i < indexCount / 4; i++) for (unsigned i = 0; i < indexCount / 4; i++)
{ {
@ -193,9 +145,10 @@ void expandIndexedQuads(char *dst, u32 address, size_t indexCount, bool is_primi
} }
} }
} }
}
// Only handle quads and triangle fan now // Only handle quads and triangle fan now
bool isNativePrimitiveMode(unsigned m_draw_mode) bool is_primitive_native(unsigned m_draw_mode) noexcept
{ {
switch (m_draw_mode) switch (m_draw_mode)
{ {
@ -215,10 +168,10 @@ bool isNativePrimitiveMode(unsigned m_draw_mode)
} }
} }
size_t getIndexCount(unsigned m_draw_mode, unsigned initial_index_count) size_t get_index_count(unsigned m_draw_mode, unsigned initial_index_count) noexcept
{ {
// Index count // Index count
if (isNativePrimitiveMode(m_draw_mode)) if (is_primitive_native(m_draw_mode))
return initial_index_count; return initial_index_count;
switch (m_draw_mode) switch (m_draw_mode)
@ -232,7 +185,17 @@ size_t getIndexCount(unsigned m_draw_mode, unsigned initial_index_count)
} }
} }
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, unsigned draw_mode, unsigned first, unsigned count) size_t get_index_type_size(u32 type) noexcept
{
switch (type)
{
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: return 2;
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: return 4;
default: return 0;
}
}
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, unsigned draw_mode, unsigned first, unsigned count) noexcept
{ {
unsigned short *typedDst = (unsigned short *)(dst); unsigned short *typedDst = (unsigned short *)(dst);
switch (draw_mode) switch (draw_mode)
@ -261,7 +224,7 @@ void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst,
} }
} }
void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count, unsigned &min_index, unsigned &max_index) void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count, unsigned &min_index, unsigned &max_index) noexcept
{ {
u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf); u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf);
u32 type = rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4; u32 type = rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4;

View file

@ -12,36 +12,34 @@ struct VertexBufferFormat
size_t stride; size_t stride;
}; };
/**
/*
* Detect buffer containing interleaved vertex attribute.
* This minimizes memory upload size.
*/
std::vector<VertexBufferFormat> FormatVertexData(const rsx::data_array_format_info *vertex_array_desc, const std::vector<u8> *vertex_data, size_t *vertex_data_size, size_t base_offset);
/*
* Write count vertex attributes from index array buffer starting at first, using vertex_array_desc * Write count vertex attributes from index array buffer starting at first, using vertex_array_desc
*/ */
void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_t index, const rsx::data_array_format_info &vertex_array_desc); void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_t index, const rsx::data_array_format_info &vertex_array_desc) noexcept;
/* /*
* If primitive mode is not supported and need to be emulated (using an index buffer) returns false. * If primitive mode is not supported and need to be emulated (using an index buffer) returns false.
*/ */
bool isNativePrimitiveMode(unsigned m_draw_mode); bool is_primitive_native(unsigned m_draw_mode) noexcept;
/* /**
* Returns a fixed index count for emulated primitive, otherwise returns initial_index_count * Returns a fixed index count for emulated primitive, otherwise returns initial_index_count
*/ */
size_t getIndexCount(unsigned m_draw_mode, unsigned initial_index_count); size_t get_index_count(unsigned m_draw_mode, unsigned initial_index_count) noexcept;
/* /**
* Returns index type size in byte
*/
size_t get_index_type_size(u32 type) noexcept;
/**
* Write count indexes starting at first to dst buffer. * Write count indexes starting at first to dst buffer.
* Returns min/max index found during the process. * Returns min/max index found during the process.
* The function expands index buffer for non native primitive type. * The function expands index buffer for non native primitive type.
*/ */
void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count, unsigned &min_index, unsigned &max_index); void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count, unsigned &min_index, unsigned &max_index) noexcept;
/* /**
* Write index data needed to emulate non indexed non native primitive mode. * Write index data needed to emulate non indexed non native primitive mode.
*/ */
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count); void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count) noexcept;

View file

@ -1,6 +1,5 @@
#include "stdafx_d3d12.h" #include "stdafx_d3d12.h"
#ifdef _WIN32 #ifdef _WIN32
#include "D3D12Buffer.h"
#include "Utilities/Log.h" #include "Utilities/Log.h"
#include "D3D12GSRender.h" #include "D3D12GSRender.h"
@ -8,27 +7,25 @@
#include "../Common/BufferUtils.h" #include "../Common/BufferUtils.h"
#include "D3D12Formats.h" #include "D3D12Formats.h"
const int g_vertexCount = 32; namespace
{
// D3D12GS member handling buffers
/** /**
* *
*/ */
static D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const rsx::data_array_format_info &vertex_array_desc, const std::vector<u8> &vertex_data, ID3D12Device *device, DataHeap<ID3D12Resource, 65536> &vertex_index_heap)
D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const rsx::data_array_format_info &vertex_array_desc, const std::vector<u8> &vertex_data, ID3D12Device *device, DataHeap<ID3D12Resource, 65536> &vertexIndexHeap)
{ {
size_t subBufferSize = vertex_data.size(); size_t buffer_size = vertex_data.size();
assert(vertexIndexHeap.canAlloc(subBufferSize)); assert(vertex_index_heap.canAlloc(buffer_size));
size_t heapOffset = vertexIndexHeap.alloc(subBufferSize); size_t heap_offset = vertex_index_heap.alloc(buffer_size);
void *buffer; void *buffer;
ThrowIfFailed(vertexIndexHeap.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); ThrowIfFailed(vertex_index_heap.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
void *bufferMap = (char*)buffer + heapOffset; void *bufferMap = (char*)buffer + heap_offset;
memcpy(bufferMap, vertex_data.data(), vertex_data.size()); memcpy(bufferMap, vertex_data.data(), vertex_data.size());
vertexIndexHeap.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); vertex_index_heap.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
return vertexIndexHeap.m_heap->GetGPUVirtualAddress() + heapOffset; return vertex_index_heap.m_heap->GetGPUVirtualAddress() + heap_offset;
}
} }
void D3D12GSRender::load_vertex_data(u32 first, u32 count) void D3D12GSRender::load_vertex_data(u32 first, u32 count)
@ -41,7 +38,7 @@ void D3D12GSRender::upload_vertex_attributes(const std::vector<std::pair<u32, u3
{ {
m_vertex_buffer_views.clear(); m_vertex_buffer_views.clear();
m_IASet.clear(); m_IASet.clear();
size_t inputSlot = 0; size_t input_slot = 0;
size_t vertex_count = 0; size_t vertex_count = 0;
@ -59,32 +56,34 @@ void D3D12GSRender::upload_vertex_attributes(const std::vector<std::pair<u32, u3
u32 type_size = rsx::get_vertex_type_size(info.type); u32 type_size = rsx::get_vertex_type_size(info.type);
u32 element_size = type_size * info.size; u32 element_size = type_size * info.size;
size_t subBufferSize = element_size * vertex_count; size_t buffer_size = element_size * vertex_count;
assert(m_vertexIndexData.canAlloc(subBufferSize)); assert(m_vertexIndexData.canAlloc(buffer_size));
size_t heapOffset = m_vertexIndexData.alloc(subBufferSize); size_t heap_offset = m_vertexIndexData.alloc(buffer_size);
void *buffer; void *buffer;
ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
void *bufferMap = (char*)buffer + heapOffset; void *mapped_buffer = (char*)buffer + heap_offset;
for (const auto &range : vertex_ranges) for (const auto &range : vertex_ranges)
{ {
write_vertex_array_data_to_buffer(bufferMap, range.first, range.second, index, info); write_vertex_array_data_to_buffer(mapped_buffer, range.first, range.second, index, info);
bufferMap = (char*)bufferMap + range.second * element_size; mapped_buffer = (char*)mapped_buffer + range.second * element_size;
} }
m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {}; D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view =
vertexBufferView.BufferLocation = m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heapOffset; {
vertexBufferView.SizeInBytes = (UINT)subBufferSize; m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heap_offset,
vertexBufferView.StrideInBytes = (UINT)element_size; (UINT)buffer_size,
m_vertex_buffer_views.push_back(vertexBufferView); (UINT)element_size
};
m_vertex_buffer_views.push_back(vertex_buffer_view);
m_timers.m_bufferUploadSize += subBufferSize; m_timers.m_bufferUploadSize += buffer_size;
D3D12_INPUT_ELEMENT_DESC IAElement = {}; D3D12_INPUT_ELEMENT_DESC IAElement = {};
IAElement.SemanticName = "TEXCOORD"; IAElement.SemanticName = "TEXCOORD";
IAElement.SemanticIndex = (UINT)index; IAElement.SemanticIndex = (UINT)index;
IAElement.InputSlot = (UINT)inputSlot++; IAElement.InputSlot = (UINT)input_slot++;
IAElement.Format = get_vertex_attribute_format(info.type, info.size); IAElement.Format = get_vertex_attribute_format(info.type, info.size);
IAElement.AlignedByteOffset = 0; IAElement.AlignedByteOffset = 0;
IAElement.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; IAElement.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
@ -107,26 +106,27 @@ void D3D12GSRender::upload_vertex_attributes(const std::vector<std::pair<u32, u3
u32 type_size = rsx::get_vertex_type_size(info.type); u32 type_size = rsx::get_vertex_type_size(info.type);
u32 element_size = type_size * info.size; u32 element_size = type_size * info.size;
size_t subBufferSize = data.size(); size_t buffer_size = data.size();
assert(m_vertexIndexData.canAlloc(subBufferSize)); assert(m_vertexIndexData.canAlloc(buffer_size));
size_t heapOffset = m_vertexIndexData.alloc(subBufferSize); size_t heap_offset = m_vertexIndexData.alloc(buffer_size);
void *buffer; void *buffer;
ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
void *bufferMap = (char*)buffer + heapOffset; void *mapped_buffer = (char*)buffer + heap_offset;
memcpy(bufferMap, data.data(), data.size()); memcpy(mapped_buffer, data.data(), data.size());
m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {}; D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view = {
vertexBufferView.BufferLocation = m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heapOffset; m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heap_offset,
vertexBufferView.SizeInBytes = (UINT)subBufferSize; (UINT)buffer_size,
vertexBufferView.StrideInBytes = (UINT)element_size; (UINT)element_size
m_vertex_buffer_views.push_back(vertexBufferView); };
m_vertex_buffer_views.push_back(vertex_buffer_view);
D3D12_INPUT_ELEMENT_DESC IAElement = {}; D3D12_INPUT_ELEMENT_DESC IAElement = {};
IAElement.SemanticName = "TEXCOORD"; IAElement.SemanticName = "TEXCOORD";
IAElement.SemanticIndex = (UINT)index; IAElement.SemanticIndex = (UINT)index;
IAElement.InputSlot = (UINT)inputSlot++; IAElement.InputSlot = (UINT)input_slot++;
IAElement.Format = get_vertex_attribute_format(info.type, info.size); IAElement.Format = get_vertex_attribute_format(info.type, info.size);
IAElement.AlignedByteOffset = 0; IAElement.AlignedByteOffset = 0;
IAElement.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA; IAElement.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
@ -142,7 +142,7 @@ void D3D12GSRender::load_vertex_index_data(u32 first, u32 count)
void D3D12GSRender::setScaleOffset(size_t descriptorIndex) void D3D12GSRender::setScaleOffset(size_t descriptorIndex)
{ {
float scaleOffsetMat[16] = float scale_offset_matrix[16] =
{ {
1.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, -1.0f, 0.0f, 0.0f,
@ -154,52 +154,53 @@ void D3D12GSRender::setScaleOffset(size_t descriptorIndex)
int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16;
// Scale // Scale
scaleOffsetMat[0] *= (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE] / (clip_w / 2.f); scale_offset_matrix[0] *= (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE] / (clip_w / 2.f);
scaleOffsetMat[5] *= (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 1] / (clip_h / 2.f); scale_offset_matrix[5] *= (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 1] / (clip_h / 2.f);
scaleOffsetMat[10] = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 2]; scale_offset_matrix[10] = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 2];
// Offset // Offset
scaleOffsetMat[3] = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET] - (clip_w / 2.f); scale_offset_matrix[3] = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET] - (clip_w / 2.f);
scaleOffsetMat[7] = -((float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 1] - (clip_h / 2.f)); scale_offset_matrix[7] = -((float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 1] - (clip_h / 2.f));
scaleOffsetMat[11] = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 2]; scale_offset_matrix[11] = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 2];
scaleOffsetMat[3] /= clip_w / 2.f; scale_offset_matrix[3] /= clip_w / 2.f;
scaleOffsetMat[7] /= clip_h / 2.f; scale_offset_matrix[7] /= clip_h / 2.f;
assert(m_constantsData.canAlloc(256)); assert(m_constantsData.canAlloc(256));
size_t heapOffset = m_constantsData.alloc(256); size_t heap_offset = m_constantsData.alloc(256);
// Scale offset buffer // Scale offset buffer
// Separate constant buffer // Separate constant buffer
void *scaleOffsetMap; void *mapped_buffer;
ThrowIfFailed(m_constantsData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + 256), &scaleOffsetMap)); ThrowIfFailed(m_constantsData.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + 256), &mapped_buffer));
streamToBuffer((char*)scaleOffsetMap + heapOffset, scaleOffsetMat, 16 * sizeof(float)); streamToBuffer((char*)mapped_buffer + heap_offset, scale_offset_matrix, 16 * sizeof(float));
int isAlphaTested = !!(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE]); int is_alpha_tested = !!(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE]);
float alpha_ref = (float&)rsx::method_registers[NV4097_SET_ALPHA_REF]; float alpha_ref = (float&)rsx::method_registers[NV4097_SET_ALPHA_REF];
memcpy((char*)scaleOffsetMap + heapOffset + 16 * sizeof(float), &isAlphaTested, sizeof(int)); memcpy((char*)mapped_buffer + heap_offset + 16 * sizeof(float), &is_alpha_tested, sizeof(int));
memcpy((char*)scaleOffsetMap + heapOffset + 17 * sizeof(float), &alpha_ref, sizeof(float)); memcpy((char*)mapped_buffer + heap_offset + 17 * sizeof(float), &alpha_ref, sizeof(float));
m_constantsData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + 256)); m_constantsData.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + 256));
D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {}; D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = {
constantBufferViewDesc.BufferLocation = m_constantsData.m_heap->GetGPUVirtualAddress() + heapOffset; m_constantsData.m_heap->GetGPUVirtualAddress() + heap_offset,
constantBufferViewDesc.SizeInBytes = (UINT)256; 256
m_device->CreateConstantBufferView(&constantBufferViewDesc, };
m_device->CreateConstantBufferView(&constant_buffer_view_desc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart()) CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart())
.Offset((INT)descriptorIndex, g_descriptorStrideSRVCBVUAV)); .Offset((INT)descriptorIndex, g_descriptorStrideSRVCBVUAV));
} }
void D3D12GSRender::FillVertexShaderConstantsBuffer(size_t descriptorIndex) void D3D12GSRender::FillVertexShaderConstantsBuffer(size_t descriptor_index)
{ {
for (const auto &entry : transform_constants) for (const auto &entry : transform_constants)
local_transform_constants[entry.first] = entry.second; local_transform_constants[entry.first] = entry.second;
size_t bufferSize = 512 * 4 * sizeof(float); size_t buffer_size = 512 * 4 * sizeof(float);
assert(m_constantsData.canAlloc(bufferSize)); assert(m_constantsData.canAlloc(buffer_size));
size_t heapOffset = m_constantsData.alloc(bufferSize); size_t heap_offset = m_constantsData.alloc(buffer_size);
void *constantsBufferMap; void *mapped_buffer;
ThrowIfFailed(m_constantsData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + bufferSize), &constantsBufferMap)); ThrowIfFailed(m_constantsData.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &mapped_buffer));
for (const auto &entry : local_transform_constants) for (const auto &entry : local_transform_constants)
{ {
float data[4] = { float data[4] = {
@ -208,118 +209,101 @@ void D3D12GSRender::FillVertexShaderConstantsBuffer(size_t descriptorIndex)
entry.second.z, entry.second.z,
entry.second.w entry.second.w
}; };
streamToBuffer((char*)constantsBufferMap + heapOffset + entry.first * 4 * sizeof(float), data, 4 * sizeof(float)); streamToBuffer((char*)mapped_buffer + heap_offset + entry.first * 4 * sizeof(float), data, 4 * sizeof(float));
} }
m_constantsData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + bufferSize)); m_constantsData.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {}; D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = {
constantBufferViewDesc.BufferLocation = m_constantsData.m_heap->GetGPUVirtualAddress() + heapOffset; m_constantsData.m_heap->GetGPUVirtualAddress() + heap_offset,
constantBufferViewDesc.SizeInBytes = (UINT)bufferSize; (UINT)buffer_size
m_device->CreateConstantBufferView(&constantBufferViewDesc, };
m_device->CreateConstantBufferView(&constant_buffer_view_desc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart()) CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart())
.Offset((INT)descriptorIndex, g_descriptorStrideSRVCBVUAV)); .Offset((INT)descriptor_index, g_descriptorStrideSRVCBVUAV));
} }
void D3D12GSRender::FillPixelShaderConstantsBuffer(size_t descriptorIndex) void D3D12GSRender::FillPixelShaderConstantsBuffer(size_t descriptor_index)
{ {
// Get constant from fragment program // Get constant from fragment program
const std::vector<size_t> &fragmentOffset = m_cachePSO.getFragmentConstantOffsetsCache(&fragment_program); const std::vector<size_t> &fragment_constant_offsets = m_cachePSO.getFragmentConstantOffsetsCache(&fragment_program);
size_t bufferSize = fragmentOffset.size() * 4 * sizeof(float) + 1; size_t buffer_size = fragment_constant_offsets.size() * 4 * sizeof(float) + 1;
// Multiple of 256 never 0 // Multiple of 256 never 0
bufferSize = (bufferSize + 255) & ~255; buffer_size = (buffer_size + 255) & ~255;
assert(m_constantsData.canAlloc(bufferSize)); assert(m_constantsData.canAlloc(buffer_size));
size_t heapOffset = m_constantsData.alloc(bufferSize); size_t heap_offset = m_constantsData.alloc(buffer_size);
size_t offset = 0; size_t offset = 0;
void *constantsBufferMap; void *mapped_buffer;
ThrowIfFailed(m_constantsData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + bufferSize), &constantsBufferMap)); ThrowIfFailed(m_constantsData.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &mapped_buffer));
for (size_t offsetInFP : fragmentOffset) for (size_t offset_in_fragment_program : fragment_constant_offsets)
{ {
u32 vector[4]; u32 vector[4];
// Is it assigned by color register in command buffer ? auto data = vm::ps3::ptr<u32>::make(fragment_program.addr + (u32)offset_in_fragment_program);
// TODO : we loop every iteration, we might do better...
bool isCommandBufferSetConstant = false;
/* for (const auto& entry : fragment_constants)
{
size_t fragmentId = entry.first - fragment_program.offset;
if (fragmentId == offsetInFP)
{
isCommandBufferSetConstant = true;
vector[0] = (u32&)entry.second.x;
vector[1] = (u32&)entry.second.y;
vector[2] = (u32&)entry.second.z;
vector[3] = (u32&)entry.second.w;
break;
}
}*/
if (!isCommandBufferSetConstant)
{
auto data = vm::ps3::ptr<u32>::make(fragment_program.addr + (u32)offsetInFP);
u32 c0 = (data[0] >> 16 | data[0] << 16); u32 c0 = (data[0] >> 16 | data[0] << 16);
u32 c1 = (data[1] >> 16 | data[1] << 16); u32 c1 = (data[1] >> 16 | data[1] << 16);
u32 c2 = (data[2] >> 16 | data[2] << 16); u32 c2 = (data[2] >> 16 | data[2] << 16);
u32 c3 = (data[3] >> 16 | data[3] << 16); u32 c3 = (data[3] >> 16 | data[3] << 16);
vector[0] = c0; vector[0] = c0;
vector[1] = c1; vector[1] = c1;
vector[2] = c2; vector[2] = c2;
vector[3] = c3; vector[3] = c3;
}
streamToBuffer((char*)constantsBufferMap + heapOffset + offset, vector, 4 * sizeof(u32)); streamToBuffer((char*)mapped_buffer + heap_offset + offset, vector, 4 * sizeof(u32));
offset += 4 * sizeof(u32); offset += 4 * sizeof(u32);
} }
m_constantsData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + bufferSize)); m_constantsData.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {}; D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = {
constantBufferViewDesc.BufferLocation = m_constantsData.m_heap->GetGPUVirtualAddress() + heapOffset; m_constantsData.m_heap->GetGPUVirtualAddress() + heap_offset,
constantBufferViewDesc.SizeInBytes = (UINT)bufferSize; (UINT)buffer_size
m_device->CreateConstantBufferView(&constantBufferViewDesc, };
m_device->CreateConstantBufferView(&constant_buffer_view_desc,
CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart()) CD3DX12_CPU_DESCRIPTOR_HANDLE(getCurrentResourceStorage().m_descriptorsHeap->GetCPUDescriptorHandleForHeapStart())
.Offset((INT)descriptorIndex, g_descriptorStrideSRVCBVUAV)); .Offset((INT)descriptor_index, g_descriptorStrideSRVCBVUAV));
} }
void D3D12GSRender::upload_vertex_index_data(ID3D12GraphicsCommandList *cmdlist) void D3D12GSRender::upload_vertex_index_data(ID3D12GraphicsCommandList *command_list)
{ {
// Index count // Index count
m_renderingInfo.m_count = 0; m_renderingInfo.m_count = 0;
for (const auto &pair : m_first_count_pairs) for (const auto &pair : m_first_count_pairs)
m_renderingInfo.m_count += getIndexCount(draw_mode, pair.second); m_renderingInfo.m_count += get_index_count(draw_mode, pair.second);
if (!m_renderingInfo.m_indexed) if (!m_renderingInfo.m_indexed)
{ {
// Non indexed // Non indexed
upload_vertex_attributes(m_first_count_pairs); upload_vertex_attributes(m_first_count_pairs);
cmdlist->IASetVertexBuffers(0, (UINT)m_vertex_buffer_views.size(), m_vertex_buffer_views.data()); command_list->IASetVertexBuffers(0, (UINT)m_vertex_buffer_views.size(), m_vertex_buffer_views.data());
if (isNativePrimitiveMode(draw_mode)) if (is_primitive_native(draw_mode))
return; return;
// Handle non native primitive // Handle non native primitive
// Alloc // Alloc
size_t subBufferSize = align(m_renderingInfo.m_count * sizeof(u16), 64); size_t buffer_size = align(m_renderingInfo.m_count * sizeof(u16), 64);
assert(m_vertexIndexData.canAlloc(subBufferSize)); assert(m_vertexIndexData.canAlloc(buffer_size));
size_t heapOffset = m_vertexIndexData.alloc(subBufferSize); size_t heap_offset = m_vertexIndexData.alloc(buffer_size);
void *buffer; void *buffer;
ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
void *bufferMap = (char*)buffer + heapOffset; void *mapped_buffer = (char*)buffer + heap_offset;
size_t first = 0; size_t first = 0;
for (const auto &pair : m_first_count_pairs) for (const auto &pair : m_first_count_pairs)
{ {
size_t element_count = getIndexCount(draw_mode, pair.second); size_t element_count = get_index_count(draw_mode, pair.second);
write_index_array_for_non_indexed_non_native_primitive_to_buffer((char*)bufferMap, draw_mode, first, pair.second); write_index_array_for_non_indexed_non_native_primitive_to_buffer((char*)mapped_buffer, draw_mode, (u32)first, (u32)pair.second);
bufferMap = (char*)bufferMap + element_count * sizeof(u16); mapped_buffer = (char*)mapped_buffer + element_count * sizeof(u16);
first += pair.second; first += pair.second;
} }
m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_INDEX_BUFFER_VIEW indexBufferView = { D3D12_INDEX_BUFFER_VIEW index_buffer_view = {
m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heapOffset, m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heap_offset,
(UINT)subBufferSize, (UINT)buffer_size,
DXGI_FORMAT_R16_UINT DXGI_FORMAT_R16_UINT
}; };
cmdlist->IASetIndexBuffer(&indexBufferView); command_list->IASetIndexBuffer(&index_buffer_view);
m_renderingInfo.m_indexed = true; m_renderingInfo.m_indexed = true;
} }
else else
@ -327,35 +311,35 @@ void D3D12GSRender::upload_vertex_index_data(ID3D12GraphicsCommandList *cmdlist)
u32 indexed_type = rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4; u32 indexed_type = rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4;
// Index type // Index type
size_t indexSize = (indexed_type == CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16) ? 2 : 4; size_t index_size = get_index_type_size(indexed_type);
// Alloc // Alloc
size_t subBufferSize = align(m_renderingInfo.m_count * indexSize, 64); size_t buffer_size = align(m_renderingInfo.m_count * index_size, 64);
assert(m_vertexIndexData.canAlloc(subBufferSize)); assert(m_vertexIndexData.canAlloc(buffer_size));
size_t heapOffset = m_vertexIndexData.alloc(subBufferSize); size_t heap_offset = m_vertexIndexData.alloc(buffer_size);
void *buffer; void *buffer;
ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
void *bufferMap = (char*)buffer + heapOffset; void *mapped_buffer = (char*)buffer + heap_offset;
u32 min_index = (u32)-1, max_index = 0; u32 min_index = (u32)-1, max_index = 0;
for (const auto &pair : m_first_count_pairs) for (const auto &pair : m_first_count_pairs)
{ {
size_t element_count = getIndexCount(draw_mode, pair.second); size_t element_count = get_index_count(draw_mode, pair.second);
write_index_array_data_to_buffer((char*)bufferMap, draw_mode, pair.first, pair.second, min_index, max_index); write_index_array_data_to_buffer((char*)mapped_buffer, draw_mode, pair.first, pair.second, min_index, max_index);
bufferMap = (char*)bufferMap + element_count * indexSize; mapped_buffer = (char*)mapped_buffer + element_count * index_size;
} }
m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_INDEX_BUFFER_VIEW indexBufferView = { D3D12_INDEX_BUFFER_VIEW index_buffer_view = {
m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heapOffset, m_vertexIndexData.m_heap->GetGPUVirtualAddress() + heap_offset,
(UINT)subBufferSize, (UINT)buffer_size,
get_index_type(indexed_type) get_index_type(indexed_type)
}; };
m_timers.m_bufferUploadSize += subBufferSize; m_timers.m_bufferUploadSize += buffer_size;
cmdlist->IASetIndexBuffer(&indexBufferView); command_list->IASetIndexBuffer(&index_buffer_view);
m_renderingInfo.m_indexed = true; m_renderingInfo.m_indexed = true;
upload_vertex_attributes({ std::make_pair(0, max_index + 1) }); upload_vertex_attributes({ std::make_pair(0, max_index + 1) });
cmdlist->IASetVertexBuffers(0, (UINT)m_vertex_buffer_views.size(), m_vertex_buffer_views.data()); command_list->IASetVertexBuffers(0, (UINT)m_vertex_buffer_views.size(), m_vertex_buffer_views.data());
} }
} }

View file

@ -1,7 +0,0 @@
#pragma once
#include <d3d12.h>
#include "Emu/Memory/vm.h"
#include "Emu/RSX/RSXThread.h"
std::vector<D3D12_INPUT_ELEMENT_DESC> getIALayout(ID3D12Device *device, bool indexedDraw, const rsx::data_array_format_info *vertexData);

View file

@ -10,7 +10,6 @@
#include "D3D12RenderTargetSets.h" #include "D3D12RenderTargetSets.h"
#include "D3D12PipelineState.h" #include "D3D12PipelineState.h"
#include "D3D12Buffer.h"
#include "d3dx12.h" #include "d3dx12.h"