summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-05-21 17:19:35 -0300
committerGravatar ameerj2021-07-22 21:51:33 -0400
commit69b910e9e7c2b9c361f4389cb1d136105b991bc0 (patch)
treec6a2200b1780159db83c650a0f7d17bf5504b1dd /src
parentglasm: Simplify patch reads (diff)
downloadyuzu-69b910e9e7c2b9c361f4389cb1d136105b991bc0.tar.gz
yuzu-69b910e9e7c2b9c361f4389cb1d136105b991bc0.tar.xz
yuzu-69b910e9e7c2b9c361f4389cb1d136105b991bc0.zip
video_core: Abstract transform feedback translation utility
Diffstat (limited to 'src')
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp25
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h15
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp86
-rw-r--r--src/video_core/transform_feedback.cpp98
-rw-r--r--src/video_core/transform_feedback.h30
6 files changed, 145 insertions, 111 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index b008c37c0..8250f736c 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -187,6 +187,8 @@ add_library(video_core STATIC
187 textures/decoders.h 187 textures/decoders.h
188 textures/texture.cpp 188 textures/texture.cpp
189 textures/texture.h 189 textures/texture.h
190 transform_feedback.cpp
191 transform_feedback.h
190 video_core.cpp 192 video_core.cpp
191 video_core.h 193 video_core.h
192 vulkan_common/vulkan_debug_callback.cpp 194 vulkan_common/vulkan_debug_callback.cpp
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index 24834e0f7..3a43c329f 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -15,9 +15,7 @@
15#include "video_core/renderer_vulkan/vk_state_tracker.h" 15#include "video_core/renderer_vulkan/vk_state_tracker.h"
16 16
17namespace Vulkan { 17namespace Vulkan {
18
19namespace { 18namespace {
20
21constexpr size_t POINT = 0; 19constexpr size_t POINT = 0;
22constexpr size_t LINE = 1; 20constexpr size_t LINE = 1;
23constexpr size_t POLYGON = 2; 21constexpr size_t POLYGON = 2;
@@ -39,6 +37,16 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = {
39 POLYGON, // Patches 37 POLYGON, // Patches
40}; 38};
41 39
40void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) {
41 std::ranges::transform(regs.tfb_layouts, state.layouts.begin(), [](const auto& layout) {
42 return VideoCommon::TransformFeedbackState::Layout{
43 .stream = layout.stream,
44 .varying_count = layout.varying_count,
45 .stride = layout.stride,
46 };
47 });
48 state.varyings = regs.tfb_varying_locs;
49}
42} // Anonymous namespace 50} // Anonymous namespace
43 51
44void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, 52void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
@@ -121,7 +129,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
121 dynamic_state.Refresh(regs); 129 dynamic_state.Refresh(regs);
122 } 130 }
123 if (xfb_enabled != 0) { 131 if (xfb_enabled != 0) {
124 xfb_state.Refresh(regs); 132 RefreshXfbState(xfb_state, regs);
125 } 133 }
126} 134}
127 135
@@ -164,17 +172,6 @@ void FixedPipelineState::BlendingAttachment::Refresh(const Maxwell& regs, size_t
164 enable.Assign(1); 172 enable.Assign(1);
165} 173}
166 174
167void FixedPipelineState::TransformFeedbackState::Refresh(const Maxwell& regs) {
168 std::ranges::transform(regs.tfb_layouts, layouts.begin(), [](const auto& layout) {
169 return Layout{
170 .stream = layout.stream,
171 .varying_count = layout.varying_count,
172 .stride = layout.stride,
173 };
174 });
175 varyings = regs.tfb_varying_locs;
176}
177
178void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) { 175void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) {
179 u32 packed_front_face = PackFrontFace(regs.front_face); 176 u32 packed_front_face = PackFrontFace(regs.front_face);
180 if (regs.screen_y_control.triangle_rast_flip != 0) { 177 if (regs.screen_y_control.triangle_rast_flip != 0) {
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
index 31de6b2c8..0f1eff9cd 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
@@ -12,6 +12,7 @@
12 12
13#include "video_core/engines/maxwell_3d.h" 13#include "video_core/engines/maxwell_3d.h"
14#include "video_core/surface.h" 14#include "video_core/surface.h"
15#include "video_core/transform_feedback.h"
15 16
16namespace Vulkan { 17namespace Vulkan {
17 18
@@ -130,18 +131,6 @@ struct FixedPipelineState {
130 } 131 }
131 }; 132 };
132 133
133 struct TransformFeedbackState {
134 struct Layout {
135 u32 stream;
136 u32 varying_count;
137 u32 stride;
138 };
139 std::array<Layout, Maxwell::NumTransformFeedbackBuffers> layouts;
140 std::array<std::array<u8, 128>, Maxwell::NumTransformFeedbackBuffers> varyings;
141
142 void Refresh(const Maxwell& regs);
143 };
144
145 struct DynamicState { 134 struct DynamicState {
146 union { 135 union {
147 u32 raw1; 136 u32 raw1;
@@ -213,7 +202,7 @@ struct FixedPipelineState {
213 std::array<BlendingAttachment, Maxwell::NumRenderTargets> attachments; 202 std::array<BlendingAttachment, Maxwell::NumRenderTargets> attachments;
214 std::array<u16, Maxwell::NumViewports> viewport_swizzles; 203 std::array<u16, Maxwell::NumViewports> viewport_swizzles;
215 DynamicState dynamic_state; 204 DynamicState dynamic_state;
216 TransformFeedbackState xfb_state; 205 VideoCommon::TransformFeedbackState xfb_state;
217 206
218 void Refresh(Tegra::Engines::Maxwell3D& maxwell3d, bool has_extended_dynamic_state); 207 void Refresh(Tegra::Engines::Maxwell3D& maxwell3d, bool has_extended_dynamic_state);
219 208
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 88db10b75..f86bf9c30 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -109,88 +109,6 @@ static Shader::AttributeType CastAttributeType(const FixedPipelineState::VertexA
109 return Shader::AttributeType::Float; 109 return Shader::AttributeType::Float;
110} 110}
111 111
112std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings(
113 const GraphicsPipelineCacheKey& key) {
114 static constexpr std::array VECTORS{
115 28, // gl_Position
116 32, // Generic 0
117 36, // Generic 1
118 40, // Generic 2
119 44, // Generic 3
120 48, // Generic 4
121 52, // Generic 5
122 56, // Generic 6
123 60, // Generic 7
124 64, // Generic 8
125 68, // Generic 9
126 72, // Generic 10
127 76, // Generic 11
128 80, // Generic 12
129 84, // Generic 13
130 88, // Generic 14
131 92, // Generic 15
132 96, // Generic 16
133 100, // Generic 17
134 104, // Generic 18
135 108, // Generic 19
136 112, // Generic 20
137 116, // Generic 21
138 120, // Generic 22
139 124, // Generic 23
140 128, // Generic 24
141 132, // Generic 25
142 136, // Generic 26
143 140, // Generic 27
144 144, // Generic 28
145 148, // Generic 29
146 152, // Generic 30
147 156, // Generic 31
148 160, // gl_FrontColor
149 164, // gl_FrontSecondaryColor
150 160, // gl_BackColor
151 164, // gl_BackSecondaryColor
152 192, // gl_TexCoord[0]
153 196, // gl_TexCoord[1]
154 200, // gl_TexCoord[2]
155 204, // gl_TexCoord[3]
156 208, // gl_TexCoord[4]
157 212, // gl_TexCoord[5]
158 216, // gl_TexCoord[6]
159 220, // gl_TexCoord[7]
160 };
161 std::vector<Shader::TransformFeedbackVarying> xfb(256);
162 for (size_t buffer = 0; buffer < Maxwell::NumTransformFeedbackBuffers; ++buffer) {
163 const auto& locations = key.state.xfb_state.varyings[buffer];
164 const auto& layout = key.state.xfb_state.layouts[buffer];
165 const u32 varying_count = layout.varying_count;
166 u32 highest = 0;
167 for (u32 offset = 0; offset < varying_count; ++offset) {
168 const u32 base_offset = offset;
169 const u8 location = locations[offset];
170
171 Shader::TransformFeedbackVarying varying;
172 varying.buffer = layout.stream;
173 varying.stride = layout.stride;
174 varying.offset = offset * 4;
175 varying.components = 1;
176
177 if (std::ranges::find(VECTORS, Common::AlignDown(location, 4)) != VECTORS.end()) {
178 UNIMPLEMENTED_IF_MSG(location % 4 != 0, "Unaligned TFB");
179
180 const u8 base_index = location / 4;
181 while (offset + 1 < varying_count && base_index == locations[offset + 1] / 4) {
182 ++offset;
183 ++varying.components;
184 }
185 }
186 xfb[location] = varying;
187 highest = std::max(highest, (base_offset + varying.components) * 4);
188 }
189 UNIMPLEMENTED_IF(highest != layout.stride);
190 }
191 return xfb;
192}
193
194Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineCacheKey& key, 112Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineCacheKey& key,
195 const Shader::IR::Program& program) { 113 const Shader::IR::Program& program) {
196 Shader::RuntimeInfo info; 114 Shader::RuntimeInfo info;
@@ -206,7 +124,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineCacheKey& key,
206 info.fixed_state_point_size = point_size; 124 info.fixed_state_point_size = point_size;
207 } 125 }
208 if (key.state.xfb_enabled != 0) { 126 if (key.state.xfb_enabled != 0) {
209 info.xfb_varyings = MakeTransformFeedbackVaryings(key); 127 info.xfb_varyings = VideoCommon::MakeTransformFeedbackVaryings(key.state.xfb_state);
210 } 128 }
211 info.convert_depth_mode = gl_ndc; 129 info.convert_depth_mode = gl_ndc;
212 } 130 }
@@ -248,7 +166,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineCacheKey& key,
248 info.fixed_state_point_size = point_size; 166 info.fixed_state_point_size = point_size;
249 } 167 }
250 if (key.state.xfb_enabled != 0) { 168 if (key.state.xfb_enabled != 0) {
251 info.xfb_varyings = MakeTransformFeedbackVaryings(key); 169 info.xfb_varyings = VideoCommon::MakeTransformFeedbackVaryings(key.state.xfb_state);
252 } 170 }
253 info.convert_depth_mode = gl_ndc; 171 info.convert_depth_mode = gl_ndc;
254 break; 172 break;
diff --git a/src/video_core/transform_feedback.cpp b/src/video_core/transform_feedback.cpp
new file mode 100644
index 000000000..db52fff93
--- /dev/null
+++ b/src/video_core/transform_feedback.cpp
@@ -0,0 +1,98 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <array>
7#include <vector>
8
9#include "common/alignment.h"
10#include "common/assert.h"
11#include "shader_recompiler/shader_info.h"
12#include "video_core/transform_feedback.h"
13
14namespace VideoCommon {
15
16std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings(
17 const TransformFeedbackState& state) {
18 static constexpr std::array VECTORS{
19 28, // gl_Position
20 32, // Generic 0
21 36, // Generic 1
22 40, // Generic 2
23 44, // Generic 3
24 48, // Generic 4
25 52, // Generic 5
26 56, // Generic 6
27 60, // Generic 7
28 64, // Generic 8
29 68, // Generic 9
30 72, // Generic 10
31 76, // Generic 11
32 80, // Generic 12
33 84, // Generic 13
34 88, // Generic 14
35 92, // Generic 15
36 96, // Generic 16
37 100, // Generic 17
38 104, // Generic 18
39 108, // Generic 19
40 112, // Generic 20
41 116, // Generic 21
42 120, // Generic 22
43 124, // Generic 23
44 128, // Generic 24
45 132, // Generic 25
46 136, // Generic 26
47 140, // Generic 27
48 144, // Generic 28
49 148, // Generic 29
50 152, // Generic 30
51 156, // Generic 31
52 160, // gl_FrontColor
53 164, // gl_FrontSecondaryColor
54 160, // gl_BackColor
55 164, // gl_BackSecondaryColor
56 192, // gl_TexCoord[0]
57 196, // gl_TexCoord[1]
58 200, // gl_TexCoord[2]
59 204, // gl_TexCoord[3]
60 208, // gl_TexCoord[4]
61 212, // gl_TexCoord[5]
62 216, // gl_TexCoord[6]
63 220, // gl_TexCoord[7]
64 };
65 std::vector<Shader::TransformFeedbackVarying> xfb(256);
66 for (size_t buffer = 0; buffer < state.layouts.size(); ++buffer) {
67 const auto& locations = state.varyings[buffer];
68 const auto& layout = state.layouts[buffer];
69 const u32 varying_count = layout.varying_count;
70 u32 highest = 0;
71 for (u32 offset = 0; offset < varying_count; ++offset) {
72 const u32 base_offset = offset;
73 const u8 location = locations[offset];
74
75 Shader::TransformFeedbackVarying varying{
76 .buffer = layout.stream,
77 .stride = layout.stride,
78 .offset = offset * 4,
79 .components = 1,
80 };
81 if (std::ranges::find(VECTORS, Common::AlignDown(location, 4)) != VECTORS.end()) {
82 UNIMPLEMENTED_IF_MSG(location % 4 != 0, "Unaligned TFB");
83
84 const u8 base_index = location / 4;
85 while (offset + 1 < varying_count && base_index == locations[offset + 1] / 4) {
86 ++offset;
87 ++varying.components;
88 }
89 }
90 xfb[location] = varying;
91 highest = std::max(highest, (base_offset + varying.components) * 4);
92 }
93 UNIMPLEMENTED_IF(highest != layout.stride);
94 }
95 return xfb;
96}
97
98} // namespace VideoCommon
diff --git a/src/video_core/transform_feedback.h b/src/video_core/transform_feedback.h
new file mode 100644
index 000000000..6832c6db1
--- /dev/null
+++ b/src/video_core/transform_feedback.h
@@ -0,0 +1,30 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <vector>
9
10#include "common/common_types.h"
11#include "shader_recompiler/profile.h"
12#include "video_core/engines/maxwell_3d.h"
13
14namespace VideoCommon {
15
16struct TransformFeedbackState {
17 struct Layout {
18 u32 stream;
19 u32 varying_count;
20 u32 stride;
21 };
22 std::array<Layout, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> layouts;
23 std::array<std::array<u8, 128>, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers>
24 varyings;
25};
26
27std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings(
28 const TransformFeedbackState& state);
29
30} // namespace VideoCommon