mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-11-02 20:13:58 +00:00
Some adjustments to vertex attributes
This commit is contained in:
@@ -14,6 +14,10 @@
|
|||||||
namespace Tegra::Engines {
|
namespace Tegra::Engines {
|
||||||
|
|
||||||
void Maxwell3D::DrawManager::ProcessMethodCall(Maxwell3D& maxwell3d, u32 method, u32 argument) {
|
void Maxwell3D::DrawManager::ProcessMethodCall(Maxwell3D& maxwell3d, u32 method, u32 argument) {
|
||||||
|
if (draw_state.draw_mode == DrawMode::InstanceArray &&
|
||||||
|
method != MAXWELL3D_REG_INDEX(vertex_array_instance_subsequent)) {
|
||||||
|
DrawDeferred(maxwell3d);
|
||||||
|
}
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case MAXWELL3D_REG_INDEX(clear_surface):
|
case MAXWELL3D_REG_INDEX(clear_surface):
|
||||||
return Clear(maxwell3d, 1);
|
return Clear(maxwell3d, 1);
|
||||||
@@ -73,6 +77,15 @@ void Maxwell3D::DrawManager::Clear(Maxwell3D& maxwell3d, u32 layer_count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Maxwell3D::DrawManager::DrawDeferred(Maxwell3D& maxwell3d) {
|
void Maxwell3D::DrawManager::DrawDeferred(Maxwell3D& maxwell3d) {
|
||||||
|
if (draw_state.draw_mode == DrawMode::InstanceArray) {
|
||||||
|
const u32 instance_count = draw_state.instance_count + 1;
|
||||||
|
draw_state.draw_mode = DrawMode::General;
|
||||||
|
draw_state.instance_count = 0;
|
||||||
|
if (maxwell3d.ShouldExecute()) {
|
||||||
|
maxwell3d.rasterizer->Draw(false, instance_count);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (draw_state.draw_mode != DrawMode::Instance || draw_state.instance_count == 0) {
|
if (draw_state.draw_mode != DrawMode::Instance || draw_state.instance_count == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -89,16 +102,25 @@ void Maxwell3D::DrawManager::DrawArray(Maxwell3D& maxwell3d, Maxwell3D::Regs::Pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Maxwell3D::DrawManager::DrawArrayInstanced(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, bool subsequent) {
|
void Maxwell3D::DrawManager::DrawArrayInstanced(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, bool subsequent) {
|
||||||
|
if (subsequent && draw_state.draw_mode == DrawMode::InstanceArray &&
|
||||||
|
instance_topology == topology && draw_state.vertex_buffer.first == vertex_first &&
|
||||||
|
draw_state.vertex_buffer.count == vertex_count) {
|
||||||
|
++draw_state.instance_count;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
u32 base_instance = 0;
|
||||||
|
if (subsequent) {
|
||||||
|
base_instance = draw_state.base_instance + draw_state.instance_count + 1;
|
||||||
|
}
|
||||||
|
DrawDeferred(maxwell3d);
|
||||||
|
instance_topology = topology;
|
||||||
draw_state.topology = topology;
|
draw_state.topology = topology;
|
||||||
draw_state.vertex_buffer.first = vertex_first;
|
draw_state.vertex_buffer.first = vertex_first;
|
||||||
draw_state.vertex_buffer.count = vertex_count;
|
draw_state.vertex_buffer.count = vertex_count;
|
||||||
if (!subsequent) {
|
draw_state.base_instance = base_instance;
|
||||||
draw_state.instance_count = 1;
|
draw_state.instance_count = 0;
|
||||||
}
|
draw_state.draw_mode = DrawMode::InstanceArray;
|
||||||
draw_state.base_instance = draw_state.instance_count - 1;
|
UpdateTopology(maxwell3d);
|
||||||
draw_state.draw_mode = DrawMode::Instance;
|
|
||||||
draw_state.instance_count++;
|
|
||||||
ProcessDraw(maxwell3d, false, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Maxwell3D::DrawManager::DrawIndex(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 index_first, u32 index_count, u32 base_index, u32 base_instance, u32 num_instances) {
|
void Maxwell3D::DrawManager::DrawIndex(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 index_first, u32 index_count, u32 base_index, u32 base_instance, u32 num_instances) {
|
||||||
|
|||||||
@@ -3034,7 +3034,7 @@ public:
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
struct DrawManager {
|
struct DrawManager {
|
||||||
enum class DrawMode : u32 { General = 0, Instance, InlineIndex };
|
enum class DrawMode : u32 { General = 0, Instance, InlineIndex, InstanceArray };
|
||||||
struct State {
|
struct State {
|
||||||
Maxwell3D::Regs::PrimitiveTopology topology{};
|
Maxwell3D::Regs::PrimitiveTopology topology{};
|
||||||
DrawMode draw_mode{};
|
DrawMode draw_mode{};
|
||||||
@@ -3086,6 +3086,7 @@ public:
|
|||||||
void ProcessDraw(Maxwell3D& maxwell3d, bool draw_indexed, u32 instance_count);
|
void ProcessDraw(Maxwell3D& maxwell3d, bool draw_indexed, u32 instance_count);
|
||||||
void ProcessDrawIndirect(Maxwell3D& maxwell3d);
|
void ProcessDrawIndirect(Maxwell3D& maxwell3d);
|
||||||
State draw_state{};
|
State draw_state{};
|
||||||
|
Maxwell3D::Regs::PrimitiveTopology instance_topology{};
|
||||||
DrawTextureState draw_texture_state{};
|
DrawTextureState draw_texture_state{};
|
||||||
IndirectParams indirect_state{};
|
IndirectParams indirect_state{};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -705,7 +705,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||||||
if (instanced) {
|
if (instanced) {
|
||||||
vertex_binding_divisors.push_back({
|
vertex_binding_divisors.push_back({
|
||||||
.binding = static_cast<u32>(index),
|
.binding = static_cast<u32>(index),
|
||||||
.divisor = key.state.binding_divisors[index],
|
.divisor = (std::min)(key.state.binding_divisors[index],
|
||||||
|
device.GetMaxVertexAttribDivisor()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1918,13 +1918,17 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
|
|||||||
for (u32 binding = 0; binding < max_bindings; ++binding) {
|
for (u32 binding = 0; binding < max_bindings; ++binding) {
|
||||||
const auto& input_binding{regs.vertex_streams[binding]};
|
const auto& input_binding{regs.vertex_streams[binding]};
|
||||||
const bool is_instanced{regs.vertex_stream_instances.IsInstancingEnabled(binding)};
|
const bool is_instanced{regs.vertex_stream_instances.IsInstancingEnabled(binding)};
|
||||||
|
u32 divisor = 1;
|
||||||
|
if (is_instanced) {
|
||||||
|
divisor = (std::min)(input_binding.frequency, device.GetMaxVertexAttribDivisor());
|
||||||
|
}
|
||||||
bindings.push_back({
|
bindings.push_back({
|
||||||
.sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT,
|
.sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.binding = binding,
|
.binding = binding,
|
||||||
.stride = input_binding.stride,
|
.stride = input_binding.stride,
|
||||||
.inputRate = is_instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
|
.inputRate = is_instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
|
||||||
.divisor = is_instanced ? input_binding.frequency : 1,
|
.divisor = divisor,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1130,11 +1130,19 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
|||||||
SetNext(next, properties.custom_border_color);
|
SetNext(next, properties.custom_border_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extensions.vertex_attribute_divisor) {
|
||||||
|
properties.vertex_attribute_divisor.sType =
|
||||||
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT;
|
||||||
|
SetNext(next, properties.vertex_attribute_divisor);
|
||||||
|
}
|
||||||
|
|
||||||
// Perform the property fetch.
|
// Perform the property fetch.
|
||||||
physical.GetProperties2(properties2);
|
physical.GetProperties2(properties2);
|
||||||
|
|
||||||
// Store base properties
|
// Store base properties
|
||||||
properties.properties = properties2.properties;
|
properties.properties = properties2.properties;
|
||||||
|
max_vertex_attrib_divisor =
|
||||||
|
(std::max)(1U, properties.vertex_attribute_divisor.maxVertexAttribDivisor);
|
||||||
|
|
||||||
// Unload extensions if feature support is insufficient.
|
// Unload extensions if feature support is insufficient.
|
||||||
RemoveUnsuitableExtensions();
|
RemoveUnsuitableExtensions();
|
||||||
|
|||||||
@@ -984,6 +984,10 @@ FN_MAX_LIMIT_LIST
|
|||||||
return properties.properties.limits.maxVertexInputBindings;
|
return properties.properties.limits.maxVertexInputBindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 GetMaxVertexAttribDivisor() const {
|
||||||
|
return max_vertex_attrib_divisor;
|
||||||
|
}
|
||||||
|
|
||||||
u32 GetMaxViewports() const {
|
u32 GetMaxViewports() const {
|
||||||
return properties.properties.limits.maxViewports;
|
return properties.properties.limits.maxViewports;
|
||||||
}
|
}
|
||||||
@@ -1188,6 +1192,7 @@ private:
|
|||||||
VkPhysicalDeviceMaintenance5PropertiesKHR maintenance5{};
|
VkPhysicalDeviceMaintenance5PropertiesKHR maintenance5{};
|
||||||
VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve{};
|
VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve{};
|
||||||
VkPhysicalDeviceCustomBorderColorPropertiesEXT custom_border_color{};
|
VkPhysicalDeviceCustomBorderColorPropertiesEXT custom_border_color{};
|
||||||
|
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vertex_attribute_divisor{};
|
||||||
|
|
||||||
VkPhysicalDeviceProperties properties{};
|
VkPhysicalDeviceProperties properties{};
|
||||||
};
|
};
|
||||||
@@ -1195,6 +1200,7 @@ private:
|
|||||||
Extensions extensions{};
|
Extensions extensions{};
|
||||||
Features features{};
|
Features features{};
|
||||||
Properties properties{};
|
Properties properties{};
|
||||||
|
u32 max_vertex_attrib_divisor{1};
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures2 features2{};
|
VkPhysicalDeviceFeatures2 features2{};
|
||||||
VkPhysicalDeviceProperties2 properties2{};
|
VkPhysicalDeviceProperties2 properties2{};
|
||||||
|
|||||||
Reference in New Issue
Block a user