summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Feng Chen2023-01-05 12:27:41 +0800
committerGravatar Feng Chen2023-01-05 12:41:28 +0800
commit1e8cee2ddfeb87d4501f66197625a31c09b57e48 (patch)
tree1a0a5c62497e765222354825bdea05b54398747e
parentMerge pull request #9501 from FernandoS27/yfc-rel-2 (diff)
downloadyuzu-1e8cee2ddfeb87d4501f66197625a31c09b57e48.tar.gz
yuzu-1e8cee2ddfeb87d4501f66197625a31c09b57e48.tar.xz
yuzu-1e8cee2ddfeb87d4501f66197625a31c09b57e48.zip
video_core: Implement maxwell3d draw texture method
-rw-r--r--src/video_core/engines/draw_manager.cpp31
-rw-r--r--src/video_core/engines/draw_manager.h20
-rw-r--r--src/video_core/engines/maxwell_3d.cpp1
-rw-r--r--src/video_core/engines/maxwell_3d.h16
-rw-r--r--src/video_core/host_shaders/blit_color_float.frag13
-rw-r--r--src/video_core/renderer_opengl/blit_image.cpp59
-rw-r--r--src/video_core/renderer_opengl/blit_image.h38
7 files changed, 177 insertions, 1 deletions
diff --git a/src/video_core/engines/draw_manager.cpp b/src/video_core/engines/draw_manager.cpp
index 2437121ce..2685481f9 100644
--- a/src/video_core/engines/draw_manager.cpp
+++ b/src/video_core/engines/draw_manager.cpp
@@ -51,6 +51,10 @@ void DrawManager::ProcessMethodCall(u32 method, u32 argument) {
51 LOG_WARNING(HW_GPU, "(STUBBED) called"); 51 LOG_WARNING(HW_GPU, "(STUBBED) called");
52 break; 52 break;
53 } 53 }
54 case MAXWELL3D_REG_INDEX(draw_texture.src_y0): {
55 DrawTexture();
56 break;
57 }
54 default: 58 default:
55 break; 59 break;
56 } 60 }
@@ -179,6 +183,33 @@ void DrawManager::DrawIndexSmall(u32 argument) {
179 ProcessDraw(true, 1); 183 ProcessDraw(true, 1);
180} 184}
181 185
186void DrawManager::DrawTexture() {
187 const auto& regs{maxwell3d->regs};
188 draw_texture_state.dst_x0 = static_cast<float>(regs.draw_texture.dst_x0) / 4096.f;
189 draw_texture_state.dst_y0 = static_cast<float>(regs.draw_texture.dst_y0) / 4096.f;
190 const auto dst_width = static_cast<float>(regs.draw_texture.dst_width) / 4096.f;
191 const auto dst_height = static_cast<float>(regs.draw_texture.dst_height) / 4096.f;
192 const bool lower_left{regs.window_origin.mode !=
193 Maxwell3D::Regs::WindowOrigin::Mode::UpperLeft};
194 if (lower_left) {
195 draw_texture_state.dst_y0 -= dst_height;
196 }
197 draw_texture_state.dst_x1 = draw_texture_state.dst_x0 + dst_width;
198 draw_texture_state.dst_y1 = draw_texture_state.dst_y0 + dst_height;
199 draw_texture_state.src_x0 = static_cast<float>(regs.draw_texture.src_x0) / 4096.f;
200 draw_texture_state.src_y0 = static_cast<float>(regs.draw_texture.src_y0) / 4096.f;
201 draw_texture_state.src_x1 =
202 (static_cast<float>(regs.draw_texture.dx_du) / 4294967295.f) * dst_width +
203 draw_texture_state.src_x0;
204 draw_texture_state.src_y1 =
205 (static_cast<float>(regs.draw_texture.dy_dv) / 4294967295.f) * dst_height +
206 draw_texture_state.src_y0;
207 draw_texture_state.src_sampler = regs.draw_texture.src_sampler;
208 draw_texture_state.src_texture = regs.draw_texture.src_texture;
209
210 maxwell3d->rasterizer->DrawTexture();
211}
212
182void DrawManager::UpdateTopology() { 213void DrawManager::UpdateTopology() {
183 const auto& regs{maxwell3d->regs}; 214 const auto& regs{maxwell3d->regs};
184 switch (regs.primitive_topology_control) { 215 switch (regs.primitive_topology_control) {
diff --git a/src/video_core/engines/draw_manager.h b/src/video_core/engines/draw_manager.h
index 58d1b2d59..7c22c49f1 100644
--- a/src/video_core/engines/draw_manager.h
+++ b/src/video_core/engines/draw_manager.h
@@ -32,6 +32,19 @@ public:
32 std::vector<u8> inline_index_draw_indexes; 32 std::vector<u8> inline_index_draw_indexes;
33 }; 33 };
34 34
35 struct DrawTextureState {
36 f32 dst_x0;
37 f32 dst_y0;
38 f32 dst_x1;
39 f32 dst_y1;
40 f32 src_x0;
41 f32 src_y0;
42 f32 src_x1;
43 f32 src_y1;
44 u32 src_sampler;
45 u32 src_texture;
46 };
47
35 struct IndirectParams { 48 struct IndirectParams {
36 bool is_indexed; 49 bool is_indexed;
37 bool include_count; 50 bool include_count;
@@ -64,6 +77,10 @@ public:
64 return draw_state; 77 return draw_state;
65 } 78 }
66 79
80 const DrawTextureState& GetDrawTextureState() const {
81 return draw_texture_state;
82 }
83
67 IndirectParams& GetIndirectParams() { 84 IndirectParams& GetIndirectParams() {
68 return indirect_state; 85 return indirect_state;
69 } 86 }
@@ -81,6 +98,8 @@ private:
81 98
82 void DrawIndexSmall(u32 argument); 99 void DrawIndexSmall(u32 argument);
83 100
101 void DrawTexture();
102
84 void UpdateTopology(); 103 void UpdateTopology();
85 104
86 void ProcessDraw(bool draw_indexed, u32 instance_count); 105 void ProcessDraw(bool draw_indexed, u32 instance_count);
@@ -89,6 +108,7 @@ private:
89 108
90 Maxwell3D* maxwell3d{}; 109 Maxwell3D* maxwell3d{};
91 State draw_state{}; 110 State draw_state{};
111 DrawTextureState draw_texture_state{};
92 IndirectParams indirect_state{}; 112 IndirectParams indirect_state{};
93}; 113};
94} // namespace Tegra::Engines 114} // namespace Tegra::Engines
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index fbfd1ddd2..a0555ef3f 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -149,6 +149,7 @@ bool Maxwell3D::IsMethodExecutable(u32 method) {
149 case MAXWELL3D_REG_INDEX(inline_index_4x8.index0): 149 case MAXWELL3D_REG_INDEX(inline_index_4x8.index0):
150 case MAXWELL3D_REG_INDEX(vertex_array_instance_first): 150 case MAXWELL3D_REG_INDEX(vertex_array_instance_first):
151 case MAXWELL3D_REG_INDEX(vertex_array_instance_subsequent): 151 case MAXWELL3D_REG_INDEX(vertex_array_instance_subsequent):
152 case MAXWELL3D_REG_INDEX(draw_texture.src_y0):
152 case MAXWELL3D_REG_INDEX(wait_for_idle): 153 case MAXWELL3D_REG_INDEX(wait_for_idle):
153 case MAXWELL3D_REG_INDEX(shadow_ram_control): 154 case MAXWELL3D_REG_INDEX(shadow_ram_control):
154 case MAXWELL3D_REG_INDEX(load_mme.instruction_ptr): 155 case MAXWELL3D_REG_INDEX(load_mme.instruction_ptr):
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 0b2fd2928..c89969bb4 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1599,6 +1599,20 @@ public:
1599 }; 1599 };
1600 static_assert(sizeof(TIRModulationCoeff) == 0x4); 1600 static_assert(sizeof(TIRModulationCoeff) == 0x4);
1601 1601
1602 struct DrawTexture {
1603 s32 dst_x0;
1604 s32 dst_y0;
1605 s32 dst_width;
1606 s32 dst_height;
1607 s64 dx_du;
1608 s64 dy_dv;
1609 u32 src_sampler;
1610 u32 src_texture;
1611 s32 src_x0;
1612 s32 src_y0;
1613 };
1614 static_assert(sizeof(DrawTexture) == 0x30);
1615
1602 struct ReduceColorThreshold { 1616 struct ReduceColorThreshold {
1603 union { 1617 union {
1604 BitField<0, 8, u32> all_hit_once; 1618 BitField<0, 8, u32> all_hit_once;
@@ -2751,7 +2765,7 @@ public:
2751 u32 reserved_sw_method2; ///< 0x102C 2765 u32 reserved_sw_method2; ///< 0x102C
2752 std::array<TIRModulationCoeff, 5> tir_modulation_coeff; ///< 0x1030 2766 std::array<TIRModulationCoeff, 5> tir_modulation_coeff; ///< 0x1030
2753 std::array<u32, 15> spare_nop; ///< 0x1044 2767 std::array<u32, 15> spare_nop; ///< 0x1044
2754 INSERT_PADDING_BYTES_NOINIT(0x30); 2768 DrawTexture draw_texture; ///< 0x1080
2755 std::array<u32, 7> reserved_sw_method3_to_7; ///< 0x10B0 2769 std::array<u32, 7> reserved_sw_method3_to_7; ///< 0x10B0
2756 ReduceColorThreshold reduce_color_thresholds_unorm8; ///< 0x10CC 2770 ReduceColorThreshold reduce_color_thresholds_unorm8; ///< 0x10CC
2757 std::array<u32, 4> reserved_sw_method10_to_13; ///< 0x10D0 2771 std::array<u32, 4> reserved_sw_method10_to_13; ///< 0x10D0
diff --git a/src/video_core/host_shaders/blit_color_float.frag b/src/video_core/host_shaders/blit_color_float.frag
new file mode 100644
index 000000000..c0c832296
--- /dev/null
+++ b/src/video_core/host_shaders/blit_color_float.frag
@@ -0,0 +1,13 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#version 450
5
6layout(binding = 0) uniform sampler2D tex;
7
8layout(location = 0) in vec2 texcoord;
9layout(location = 0) out vec4 color;
10
11void main() {
12 color = textureLod(tex, texcoord, 0);
13}
diff --git a/src/video_core/renderer_opengl/blit_image.cpp b/src/video_core/renderer_opengl/blit_image.cpp
new file mode 100644
index 000000000..9a560a73b
--- /dev/null
+++ b/src/video_core/renderer_opengl/blit_image.cpp
@@ -0,0 +1,59 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <algorithm>
5
6#include "video_core/host_shaders/blit_color_float_frag.h"
7#include "video_core/host_shaders/full_screen_triangle_vert.h"
8#include "video_core/renderer_opengl/blit_image.h"
9#include "video_core/renderer_opengl/gl_shader_manager.h"
10#include "video_core/renderer_opengl/gl_shader_util.h"
11
12namespace OpenGL {
13
14BlitImageHelper::BlitImageHelper(ProgramManager& program_manager_)
15 : program_manager(program_manager_),
16 full_screen_vert(CreateProgram(HostShaders::FULL_SCREEN_TRIANGLE_VERT, GL_VERTEX_SHADER)),
17 blit_color_to_color_frag(
18 CreateProgram(HostShaders::BLIT_COLOR_FLOAT_FRAG, GL_FRAGMENT_SHADER)) {}
19
20BlitImageHelper::~BlitImageHelper() = default;
21
22void BlitImageHelper::BlitColor(GLuint dst_framebuffer, GLuint src_image_view, GLuint src_sampler,
23 const Region2D& dst_region, const Region2D& src_region,
24 const Extent3D& src_size) {
25 glEnable(GL_CULL_FACE);
26 glDisable(GL_COLOR_LOGIC_OP);
27 glDisable(GL_DEPTH_TEST);
28 glDisable(GL_STENCIL_TEST);
29 glDisable(GL_POLYGON_OFFSET_FILL);
30 glDisable(GL_RASTERIZER_DISCARD);
31 glDisable(GL_ALPHA_TEST);
32 glDisablei(GL_BLEND, 0);
33 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
34 glCullFace(GL_BACK);
35 glFrontFace(GL_CW);
36 glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
37 glDepthRangeIndexed(0, 0.0, 0.0);
38
39 program_manager.BindPresentPrograms(full_screen_vert.handle, blit_color_to_color_frag.handle);
40 glProgramUniform2f(full_screen_vert.handle, 0,
41 static_cast<float>(src_region.end.x - src_region.start.x) /
42 static_cast<float>(src_size.width),
43 static_cast<float>(src_region.end.y - src_region.start.y) /
44 static_cast<float>(src_size.height));
45 glProgramUniform2f(full_screen_vert.handle, 1,
46 static_cast<float>(src_region.start.x) / static_cast<float>(src_size.width),
47 static_cast<float>(src_region.start.y) /
48 static_cast<float>(src_size.height));
49 glViewport(std::min(dst_region.start.x, dst_region.end.x),
50 std::min(dst_region.start.y, dst_region.end.y),
51 std::abs(dst_region.end.x - dst_region.start.x),
52 std::abs(dst_region.end.y - dst_region.start.y));
53 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_framebuffer);
54 glBindSampler(0, src_sampler);
55 glBindTextureUnit(0, src_image_view);
56 glClear(GL_COLOR_BUFFER_BIT);
57 glDrawArrays(GL_TRIANGLES, 0, 3);
58}
59} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/blit_image.h b/src/video_core/renderer_opengl/blit_image.h
new file mode 100644
index 000000000..5a2b12d16
--- /dev/null
+++ b/src/video_core/renderer_opengl/blit_image.h
@@ -0,0 +1,38 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <glad/glad.h>
7
8#include "video_core/engines/fermi_2d.h"
9#include "video_core/renderer_opengl/gl_resource_manager.h"
10#include "video_core/texture_cache/types.h"
11
12namespace OpenGL {
13
14using VideoCommon::Extent3D;
15using VideoCommon::Offset2D;
16using VideoCommon::Region2D;
17
18class ProgramManager;
19class Framebuffer;
20class ImageView;
21
22class BlitImageHelper {
23public:
24 explicit BlitImageHelper(ProgramManager& program_manager);
25 ~BlitImageHelper();
26
27 void BlitColor(GLuint dst_framebuffer, GLuint src_image_view, GLuint src_sampler,
28 const Region2D& dst_region, const Region2D& src_region,
29 const Extent3D& src_size);
30
31private:
32 ProgramManager& program_manager;
33
34 OGLProgram full_screen_vert;
35 OGLProgram blit_color_to_color_frag;
36};
37
38} // namespace OpenGL