diff --git a/rpcs3/D3D12GSRender.vcxproj b/rpcs3/D3D12GSRender.vcxproj
index a610917e18..4ef08e2967 100644
--- a/rpcs3/D3D12GSRender.vcxproj
+++ b/rpcs3/D3D12GSRender.vcxproj
@@ -63,7 +63,7 @@
- true
+ false
diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp
index 71cad3cf89..a95b377179 100644
--- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp
+++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp
@@ -9,15 +9,18 @@
#include "../rsx_methods.h"
-std::vector D3D12GSRender::upload_vertex_attributes(const std::vector > &vertex_ranges)
+std::vector D3D12GSRender::upload_vertex_attributes(
+ const std::vector > &vertex_ranges,
+ gsl::not_null command_list)
{
- std::vector vertex_buffer_views;
-
- m_IASet.clear();
+ std::vector vertex_buffer_views;
+ command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertex_buffer_data.Get(), D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, D3D12_RESOURCE_STATE_COPY_DEST));
size_t input_slot = 0;
size_t vertex_count = 0;
+ size_t offset_in_vertex_buffers_buffer = 0;
+
for (const auto &pair : vertex_ranges)
vertex_count += pair.second;
@@ -34,9 +37,9 @@ std::vector D3D12GSRender::upload_vertex_attributes(co
// Active vertex array
const rsx::data_array_format_info &info = vertex_arrays_info[index];
- u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
-
+ size_t element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
size_t buffer_size = element_size * vertex_count;
+
size_t heap_offset = m_buffer_data.alloc(buffer_size);
void *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
@@ -47,25 +50,22 @@ std::vector D3D12GSRender::upload_vertex_attributes(co
}
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
- D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view =
- {
- m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
- (UINT)buffer_size,
- (UINT)element_size
+ command_list->CopyBufferRegion(m_vertex_buffer_data.Get(), offset_in_vertex_buffers_buffer, m_buffer_data.get_heap(), heap_offset, buffer_size);
+
+ D3D12_SHADER_RESOURCE_VIEW_DESC vertex_buffer_view = {
+ get_vertex_attribute_format(info.type, info.size),
+ D3D12_SRV_DIMENSION_BUFFER,
+ D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING
};
+ vertex_buffer_view.Buffer.FirstElement = offset_in_vertex_buffers_buffer / element_size;
+ vertex_buffer_view.Buffer.NumElements = buffer_size / element_size;
vertex_buffer_views.push_back(vertex_buffer_view);
+ offset_in_vertex_buffers_buffer = (offset_in_vertex_buffers_buffer + buffer_size + 191) / 192; // 192 is multiple of 2, 4, 6, 8, 12, 16, 24, 32, 48, 64
+ offset_in_vertex_buffers_buffer *= 192;
+
m_timers.m_buffer_upload_size += buffer_size;
- D3D12_INPUT_ELEMENT_DESC IAElement = {};
- IAElement.SemanticName = "TEXCOORD";
- IAElement.SemanticIndex = (UINT)index;
- IAElement.InputSlot = (UINT)input_slot++;
- IAElement.Format = get_vertex_attribute_format(info.type, info.size);
- IAElement.AlignedByteOffset = 0;
- IAElement.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
- IAElement.InstanceDataStepRate = 0;
- m_IASet.push_back(IAElement);
}
else if (register_vertex_info[index].size > 0)
{
@@ -74,34 +74,31 @@ std::vector D3D12GSRender::upload_vertex_attributes(co
const std::vector &data = register_vertex_data[index];
- u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
-
+ size_t element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
size_t buffer_size = data.size();
+
size_t heap_offset = m_buffer_data.alloc(buffer_size);
void *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
memcpy(mapped_buffer, data.data(), data.size());
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
- D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view = {
- m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
- (UINT)buffer_size,
- (UINT)element_size
+ command_list->CopyBufferRegion(m_vertex_buffer_data.Get(), offset_in_vertex_buffers_buffer, m_buffer_data.get_heap(), heap_offset, buffer_size);
+
+ D3D12_SHADER_RESOURCE_VIEW_DESC vertex_buffer_view = {
+ get_vertex_attribute_format(info.type, info.size),
+ D3D12_SRV_DIMENSION_BUFFER,
+ D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING
};
+ vertex_buffer_view.Buffer.FirstElement = offset_in_vertex_buffers_buffer / element_size;
+ vertex_buffer_view.Buffer.NumElements = buffer_size / element_size;
vertex_buffer_views.push_back(vertex_buffer_view);
- D3D12_INPUT_ELEMENT_DESC IAElement = {};
- IAElement.SemanticName = "TEXCOORD";
- IAElement.SemanticIndex = (UINT)index;
- IAElement.InputSlot = (UINT)input_slot++;
- IAElement.Format = get_vertex_attribute_format(info.type, info.size);
- IAElement.AlignedByteOffset = 0;
- IAElement.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
- IAElement.InstanceDataStepRate = 1;
- m_IASet.push_back(IAElement);
+ offset_in_vertex_buffers_buffer = (offset_in_vertex_buffers_buffer + buffer_size + 191) / 192; // 192 is multiple of 2, 4, 6, 8, 12, 16, 24, 32, 48, 64
+ offset_in_vertex_buffers_buffer *= 192;
}
}
-
+ command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertex_buffer_data.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));
return vertex_buffer_views;
}
@@ -190,7 +187,7 @@ void D3D12GSRender::upload_and_bind_fragment_shader_constants(size_t descriptor_
std::tuple D3D12GSRender::upload_inlined_vertex_array()
{
UINT offset = 0;
- m_IASet.clear();
+
// Bind attributes
for (int index = 0; index < rsx::limits::vertex_count; ++index)
{
@@ -199,16 +196,6 @@ std::tuple D3D12GSRender::upload_inlined_verte
if (!info.size) // disabled
continue;
- D3D12_INPUT_ELEMENT_DESC IAElement = {};
- IAElement.SemanticName = "TEXCOORD";
- IAElement.SemanticIndex = (UINT)index;
- IAElement.InputSlot = 0;
- IAElement.Format = get_vertex_attribute_format(info.type, info.size);
- IAElement.AlignedByteOffset = offset;
- IAElement.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
- IAElement.InstanceDataStepRate = 0;
- m_IASet.push_back(IAElement);
-
offset += rsx::get_vertex_type_size_on_host(info.type, info.size);
}
@@ -258,11 +245,11 @@ std::tuple D3D12GSRender::generate_index_buffer
return std::make_tuple(index_buffer_view, index_count);
}
-std::tuple D3D12GSRender::upload_and_set_vertex_index_data(ID3D12GraphicsCommandList *command_list)
+std::tuple> D3D12GSRender::upload_and_set_vertex_index_data(ID3D12GraphicsCommandList *command_list)
{
if (draw_command == Draw_command::draw_command_inlined_array)
{
- size_t vertex_count;
+/* size_t vertex_count;
D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view;
std::tie(vertex_buffer_view, vertex_count) = upload_inlined_vertex_array();
command_list->IASetVertexBuffers(0, (UINT)1, &vertex_buffer_view);
@@ -274,28 +261,25 @@ std::tuple D3D12GSRender::upload_and_set_vertex_index_data(ID3D12G
size_t index_count;
std::tie(index_buffer_view, index_count) = generate_index_buffer_for_emulated_primitives_array({ { 0, (u32)vertex_count } });
command_list->IASetIndexBuffer(&index_buffer_view);
- return std::make_tuple(true, index_count);
+ return std::make_tuple(true, index_count);*/
}
if (draw_command == Draw_command::draw_command_array)
{
- const std::vector &vertex_buffer_views = upload_vertex_attributes(first_count_commands);
- command_list->IASetVertexBuffers(0, (UINT)vertex_buffer_views.size(), vertex_buffer_views.data());
-
if (is_primitive_native(draw_mode))
{
// Index count
size_t vertex_count = 0;
for (const auto &pair : first_count_commands)
vertex_count += pair.second;
- return std::make_tuple(false, vertex_count);
+ return std::make_tuple(false, vertex_count, upload_vertex_attributes(first_count_commands, command_list));
}
D3D12_INDEX_BUFFER_VIEW index_buffer_view;
size_t index_count;
std::tie(index_buffer_view, index_count) = generate_index_buffer_for_emulated_primitives_array(first_count_commands);
command_list->IASetIndexBuffer(&index_buffer_view);
- return std::make_tuple(true, index_count);
+ return std::make_tuple(true, index_count, upload_vertex_attributes(first_count_commands, command_list));
}
assert(draw_command == Draw_command::draw_command_indexed);
@@ -337,10 +321,7 @@ std::tuple D3D12GSRender::upload_and_set_vertex_index_data(ID3D12G
m_timers.m_buffer_upload_size += buffer_size;
command_list->IASetIndexBuffer(&index_buffer_view);
- const std::vector &vertex_buffer_views = upload_vertex_attributes({ std::make_pair(0, max_index + 1) });
- command_list->IASetVertexBuffers(0, (UINT)vertex_buffer_views.size(), vertex_buffer_views.data());
-
- return std::make_tuple(true, index_count);
+ return std::make_tuple(true, index_count, upload_vertex_attributes({ std::make_pair(0, max_index + 1) }, command_list));
}
#endif
diff --git a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp
index f40c238929..bdc6debbb5 100644
--- a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp
+++ b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp
@@ -123,7 +123,7 @@ void D3D12FragmentDecompiler::insertConstants(std::stringstream & OS)
for (ParamItem PI : PT.items)
{
size_t textureIndex = atoi(PI.name.data() + 3);
- OS << "Texture2D " << PI.name << " : register(t" << textureIndex << ");" << std::endl;
+ OS << "Texture2D " << PI.name << " : register(t" << textureIndex + 16 << ");" << std::endl;
OS << "sampler " << PI.name << "sampler : register(s" << textureIndex << ");" << std::endl;
}
}
@@ -132,7 +132,7 @@ void D3D12FragmentDecompiler::insertConstants(std::stringstream & OS)
for (ParamItem PI : PT.items)
{
size_t textureIndex = atoi(PI.name.data() + 3);
- OS << "TextureCube " << PI.name << " : register(t" << textureIndex << ");" << std::endl;
+ OS << "TextureCube " << PI.name << " : register(t" << textureIndex + 16 << ");" << std::endl;
OS << "sampler " << PI.name << "sampler : register(s" << textureIndex << ");" << std::endl;
}
}
diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp
index 9d89cdf53f..86b2e23749 100644
--- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp
+++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp
@@ -143,33 +143,38 @@ D3D12GSRender::D3D12GSRender()
m_device->CreateRenderTargetView(m_backbuffer[1].Get(), &renter_target_view_desc, m_backbuffer_descriptor_heap[1]->GetCPUDescriptorHandleForHeapStart());
// Common root signatures
- for (unsigned texture_count = 0; texture_count < 17; texture_count++)
+ for (int vertex_buffer_count = 1; vertex_buffer_count <= 16; vertex_buffer_count++)
{
- CD3DX12_DESCRIPTOR_RANGE descriptorRange[] =
+ for (unsigned texture_count = 0; texture_count < 17; texture_count++)
{
- // Scale Offset data
- CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0),
- // Constants
- CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 1),
- // Textures
- CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, texture_count, 0),
- // Samplers
- CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, texture_count, 0),
- };
- CD3DX12_ROOT_PARAMETER RP[2];
- RP[0].InitAsDescriptorTable((texture_count > 0) ? 3 : 2, &descriptorRange[0]);
- RP[1].InitAsDescriptorTable(1, &descriptorRange[3]);
+ CD3DX12_DESCRIPTOR_RANGE descriptorRange[] =
+ {
+ // Vertex buffer
+ CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, vertex_buffer_count, 0),
+ // Scale Offset data
+ CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0),
+ // Constants
+ CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 1),
+ // Textures
+ CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, texture_count, 16),
+ // Samplers
+ CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, texture_count, 0),
+ };
+ CD3DX12_ROOT_PARAMETER RP[2];
+ RP[0].InitAsDescriptorTable((texture_count > 0) ? 4 : 3, &descriptorRange[0]);
+ RP[1].InitAsDescriptorTable(1, &descriptorRange[4]);
- Microsoft::WRL::ComPtr rootSignatureBlob;
- Microsoft::WRL::ComPtr errorBlob;
- CHECK_HRESULT(wrapD3D12SerializeRootSignature(
- &CD3DX12_ROOT_SIGNATURE_DESC((texture_count > 0) ? 2 : 1, RP, 0, 0, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT),
- D3D_ROOT_SIGNATURE_VERSION_1, &rootSignatureBlob, &errorBlob));
+ Microsoft::WRL::ComPtr rootSignatureBlob;
+ Microsoft::WRL::ComPtr errorBlob;
+ CHECK_HRESULT(wrapD3D12SerializeRootSignature(
+ &CD3DX12_ROOT_SIGNATURE_DESC((texture_count > 0) ? 2 : 1, RP, 0, 0),
+ D3D_ROOT_SIGNATURE_VERSION_1, &rootSignatureBlob, &errorBlob));
- m_device->CreateRootSignature(0,
- rootSignatureBlob->GetBufferPointer(),
- rootSignatureBlob->GetBufferSize(),
- IID_PPV_ARGS(m_root_signatures[texture_count].GetAddressOf()));
+ m_device->CreateRootSignature(0,
+ rootSignatureBlob->GetBufferPointer(),
+ rootSignatureBlob->GetBufferSize(),
+ IID_PPV_ARGS(m_root_signatures[texture_count][vertex_buffer_count - 1].GetAddressOf()));
+ }
}
m_per_frame_storage[0].init(m_device.Get());
@@ -194,6 +199,17 @@ D3D12GSRender::D3D12GSRender()
m_readback_resources.init(m_device.Get(), 1024 * 1024 * 128, D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_STATE_COPY_DEST);
m_buffer_data.init(m_device.Get(), 1024 * 1024 * 896, D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ);
+ CHECK_HRESULT(
+ m_device->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
+ D3D12_HEAP_FLAG_NONE,
+ &CD3DX12_RESOURCE_DESC::Buffer(1024 * 1024 * 16),
+ D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
+ nullptr,
+ IID_PPV_ARGS(m_vertex_buffer_data.GetAddressOf())
+ )
+ );
+
if (rpcs3::config.rsx.d3d12.overlay.value())
init_d2d_structures();
}
@@ -250,9 +266,14 @@ void D3D12GSRender::end()
std::chrono::time_point vertex_index_duration_start = std::chrono::system_clock::now();
+ size_t currentDescriptorIndex = get_current_resource_storage().descriptors_heap_index;
+
size_t vertex_count;
bool indexed_draw;
- std::tie(indexed_draw, vertex_count) = upload_and_set_vertex_index_data(get_current_resource_storage().command_list.Get());
+ std::vector vertex_buffer_views;
+ std::tie(indexed_draw, vertex_count, vertex_buffer_views) = upload_and_set_vertex_index_data(get_current_resource_storage().command_list.Get());
+
+ size_t vertex_buffer_count = vertex_buffer_views.size();
std::chrono::time_point vertex_index_duration_end = std::chrono::system_clock::now();
m_timers.m_vertex_index_duration += std::chrono::duration_cast(vertex_index_duration_end - vertex_index_duration_start).count();
@@ -262,16 +283,23 @@ void D3D12GSRender::end()
std::chrono::time_point program_load_end = std::chrono::system_clock::now();
m_timers.m_program_load_duration += std::chrono::duration_cast(program_load_end - program_load_start).count();
- get_current_resource_storage().command_list->SetGraphicsRootSignature(m_root_signatures[std::get<2>(m_current_pso)].Get());
+ get_current_resource_storage().command_list->SetGraphicsRootSignature(m_root_signatures[std::get<2>(m_current_pso)][vertex_buffer_count - 1].Get());
get_current_resource_storage().command_list->OMSetStencilRef(rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF]);
std::chrono::time_point constants_duration_start = std::chrono::system_clock::now();
- size_t currentDescriptorIndex = get_current_resource_storage().descriptors_heap_index;
+ size_t offset = 0;
+ for (const auto view : vertex_buffer_views)
+ {
+ m_device->CreateShaderResourceView(m_vertex_buffer_data.Get(), &view,
+ CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
+ .Offset((INT)currentDescriptorIndex + offset++, g_descriptor_stride_srv_cbv_uav));
+ }
+
// Constants
- upload_and_bind_scale_offset_matrix(currentDescriptorIndex);
- upload_and_bind_vertex_shader_constants(currentDescriptorIndex + 1);
- upload_and_bind_fragment_shader_constants(currentDescriptorIndex + 2);
+ upload_and_bind_scale_offset_matrix(currentDescriptorIndex + vertex_buffer_count);
+ upload_and_bind_vertex_shader_constants(currentDescriptorIndex + 1 + vertex_buffer_count);
+ upload_and_bind_fragment_shader_constants(currentDescriptorIndex + 2 + vertex_buffer_count);
std::chrono::time_point constants_duration_end = std::chrono::system_clock::now();
m_timers.m_constants_duration += std::chrono::duration_cast(constants_duration_end - constants_duration_start).count();
@@ -281,8 +309,7 @@ void D3D12GSRender::end()
std::chrono::time_point texture_duration_start = std::chrono::system_clock::now();
if (std::get<2>(m_current_pso) > 0)
{
- upload_and_bind_textures(get_current_resource_storage().command_list.Get(), currentDescriptorIndex + 3, std::get<2>(m_current_pso) > 0);
-
+ upload_and_bind_textures(get_current_resource_storage().command_list.Get(), currentDescriptorIndex + 3 + vertex_buffer_count, std::get<2>(m_current_pso) > 0);
get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(0,
CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetGPUDescriptorHandleForHeapStart())
@@ -294,16 +321,15 @@ void D3D12GSRender::end()
);
get_current_resource_storage().current_sampler_index += std::get<2>(m_current_pso);
- get_current_resource_storage().descriptors_heap_index += std::get<2>(m_current_pso) + 3;
+ get_current_resource_storage().descriptors_heap_index += std::get<2>(m_current_pso) + 3 + vertex_buffer_count;
}
else
{
- get_current_resource_storage().command_list->SetDescriptorHeaps(1, get_current_resource_storage().descriptors_heap.GetAddressOf());
get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(0,
CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetGPUDescriptorHandleForHeapStart())
.Offset((INT)currentDescriptorIndex, g_descriptor_stride_srv_cbv_uav)
);
- get_current_resource_storage().descriptors_heap_index += 3;
+ get_current_resource_storage().descriptors_heap_index += 3 + vertex_buffer_count;
}
std::chrono::time_point texture_duration_end = std::chrono::system_clock::now();
diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h
index f9618600c4..433142f0b6 100644
--- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h
+++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h
@@ -56,7 +56,7 @@ private:
ComPtr m_backbuffer[2];
ComPtr m_backbuffer_descriptor_heap[2];
// m_rootSignatures[N] is RS with N texture/sample
- ComPtr m_root_signatures[17];
+ ComPtr m_root_signatures[17][16]; // indexed by [texture count][vertex count]
// TODO: Use a tree structure to parse more efficiently
data_cache m_texture_cache;
@@ -115,11 +115,10 @@ private:
// Textures, constants, index and vertex buffers storage
data_heap m_buffer_data;
data_heap m_readback_resources;
+ ComPtr m_vertex_buffer_data;
render_targets m_rtts;
- std::vector m_IASet;
-
INT g_descriptor_stride_srv_cbv_uav;
INT g_descriptor_stride_dsv;
INT g_descriptor_stride_rtv;
@@ -150,14 +149,15 @@ private:
* Non native primitive type are emulated by index buffers expansion.
* Returns whether the draw call is indexed or not and the vertex count to draw.
*/
- std::tuple upload_and_set_vertex_index_data(ID3D12GraphicsCommandList *command_list);
+ std::tuple > upload_and_set_vertex_index_data(ID3D12GraphicsCommandList *command_list);
/**
* Upload all enabled vertex attributes for vertex in ranges described by vertex_ranges.
* A range in vertex_range is a pair whose first element is the index of the beginning of the
* range, and whose second element is the number of vertex in this range.
*/
- std::vector upload_vertex_attributes(const std::vector > &vertex_ranges);
+ std::vector upload_vertex_attributes(const std::vector > &vertex_ranges,
+ gsl::not_null command_list);
std::tuple upload_inlined_vertex_array();
diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp
index c8a26cba2a..92720cf196 100644
--- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp
+++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp
@@ -251,7 +251,6 @@ void D3D12GSRender::load_program()
for (unsigned i = 0; i < prop.numMRT; i++)
prop.Blend.RenderTarget[i].RenderTargetWriteMask = mask;
- prop.IASet = m_IASet;
if (!!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE])
{
Index_array_type index_type = to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h
index 831146f246..56a6d7e087 100644
--- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h
+++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h
@@ -10,7 +10,6 @@ struct D3D12PipelineProperties
D3D12_PRIMITIVE_TOPOLOGY_TYPE Topology;
DXGI_FORMAT DepthStencilFormat;
DXGI_FORMAT RenderTargetsFormat;
- std::vector IASet;
D3D12_BLEND_DESC Blend;
unsigned numMRT : 3;
D3D12_DEPTH_STENCIL_DESC DepthStencil;
@@ -19,23 +18,6 @@ struct D3D12PipelineProperties
bool operator==(const D3D12PipelineProperties &in) const
{
- if (IASet.size() != in.IASet.size())
- return false;
- for (unsigned i = 0; i < IASet.size(); i++)
- {
- const D3D12_INPUT_ELEMENT_DESC &a = IASet[i], &b = in.IASet[i];
- if (a.AlignedByteOffset != b.AlignedByteOffset)
- return false;
- if (a.Format != b.Format)
- return false;
- if (a.InputSlot != b.InputSlot)
- return false;
- if (a.InstanceDataStepRate != b.InstanceDataStepRate)
- return false;
- if (a.SemanticIndex != b.SemanticIndex)
- return false;
- }
-
if (memcmp(&DepthStencil, &in.DepthStencil, sizeof(D3D12_DEPTH_STENCIL_DESC)))
return false;
if (memcmp(&Blend, &in.Blend, sizeof(D3D12_BLEND_DESC)))
@@ -118,24 +100,6 @@ bool has_attribute(size_t attribute, const std::vector
return false;
}
-static
-std::vector completes_IA_desc(const std::vector &desc, const std::vector &inputs)
-{
- std::vector result(desc);
- for (size_t attribute : inputs)
- {
- if (has_attribute(attribute, desc))
- continue;
- D3D12_INPUT_ELEMENT_DESC extra_ia_desc = {};
- extra_ia_desc.SemanticIndex = (UINT)attribute;
- extra_ia_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
- extra_ia_desc.SemanticName = "TEXCOORD";
- extra_ia_desc.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
- result.push_back(extra_ia_desc);
- }
- return result;
-}
-
struct D3D12Traits
{
using vertex_program_type = Shader;
@@ -184,7 +148,7 @@ struct D3D12Traits
static
pipeline_storage_type build_pipeline(
const vertex_program_type &vertexProgramData, const fragment_program_type &fragmentProgramData, const pipeline_properties &pipelineProperties,
- ID3D12Device *device, gsl::span, 17> root_signatures)
+ ID3D12Device *device, gsl::span, 17, 16> root_signatures)
{
std::tuple, size_t> result = {};
D3D12_GRAPHICS_PIPELINE_STATE_DESC graphicPipelineStateDesc = {};
@@ -199,7 +163,7 @@ struct D3D12Traits
graphicPipelineStateDesc.PS.BytecodeLength = fragmentProgramData.bytecode->GetBufferSize();
graphicPipelineStateDesc.PS.pShaderBytecode = fragmentProgramData.bytecode->GetBufferPointer();
- graphicPipelineStateDesc.pRootSignature = root_signatures[fragmentProgramData.m_textureCount].Get();
+ graphicPipelineStateDesc.pRootSignature = root_signatures[fragmentProgramData.m_textureCount][vertexProgramData.vertex_shader_inputs.size() - 1].Get();
graphicPipelineStateDesc.BlendState = pipelineProperties.Blend;
graphicPipelineStateDesc.DepthStencilState = pipelineProperties.DepthStencil;
@@ -211,10 +175,6 @@ struct D3D12Traits
graphicPipelineStateDesc.RTVFormats[i] = pipelineProperties.RenderTargetsFormat;
graphicPipelineStateDesc.DSVFormat = pipelineProperties.DepthStencilFormat;
- const std::vector &completed_IA_desc = completes_IA_desc(pipelineProperties.IASet, vertexProgramData.vertex_shader_inputs);
-
- graphicPipelineStateDesc.InputLayout.pInputElementDescs = completed_IA_desc.data();
- graphicPipelineStateDesc.InputLayout.NumElements = (UINT)completed_IA_desc.size();
graphicPipelineStateDesc.SampleDesc.Count = 1;
graphicPipelineStateDesc.SampleMask = UINT_MAX;
graphicPipelineStateDesc.NodeMask = 1;
diff --git a/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp
index 7d663411d6..9c51e69492 100644
--- a/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp
+++ b/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp
@@ -54,18 +54,25 @@ void D3D12VertexProgramDecompiler::insertHeader(std::stringstream &OS)
void D3D12VertexProgramDecompiler::insertInputs(std::stringstream & OS, const std::vector& inputs)
{
- OS << "struct VertexInput" << std::endl;
- OS << "{" << std::endl;
+ std::vector> input_data;
for (const ParamType PT : inputs)
{
for (const ParamItem &PI : PT.items)
{
- OS << " " << PT.type << " " << PI.name << ": TEXCOORD" << PI.location << ";" << std::endl;
+ input_data.push_back(std::make_tuple(PI.location, PI.name));
input_slots.push_back(PI.location);
}
}
- OS << "};" << std::endl;
+ std::sort(input_data.begin(), input_data.end());
+
+ size_t t_register = 0;
+ for (const auto &attribute : input_data)
+ {
+
+ OS << "Texture1D " << std::get<1>(attribute) << "_buffer : register(t" << t_register++ << ");\n";
+
+ }
}
void D3D12VertexProgramDecompiler::insertConstants(std::stringstream & OS, const std::vector & constants)
@@ -142,7 +149,7 @@ static const reg_info reg_table[] =
void D3D12VertexProgramDecompiler::insertMainStart(std::stringstream & OS)
{
- OS << "PixelInput main(VertexInput In)" << std::endl;
+ OS << "PixelInput main(uint vertex_id : SV_VertexID)" << std::endl;
OS << "{" << std::endl;
// Declare inside main function
@@ -162,7 +169,7 @@ void D3D12VertexProgramDecompiler::insertMainStart(std::stringstream & OS)
for (const ParamType PT : m_parr.params[PF_PARAM_IN])
{
for (const ParamItem &PI : PT.items)
- OS << " " << PT.type << " " << PI.name << " = In." << PI.name << ";" << std::endl;
+ OS << " " << PT.type << " " << PI.name << " = " << PI.name << "_buffer.Load(vertex_id);" << std::endl;
}
}