diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 27 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_util.h | 27 |
5 files changed, 59 insertions, 19 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index e1ceec268..8ea26c9c1 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -193,6 +193,11 @@ union Instruction { BitField<50, 1, u64> abs_d; BitField<56, 1, u64> negate_imm; + union { + BitField<39, 3, u64> pred; + BitField<42, 1, u64> negate_pred; + } fmnmx; + float GetImm20_19() const { float result{}; u32 imm{static_cast<u32>(imm20_19)}; @@ -320,6 +325,7 @@ public: ISETP_C, ISETP_IMM, ISETP_R, + PSETP, }; enum class Type { @@ -331,6 +337,7 @@ public: FloatSet, FloatSetPredicate, IntegerSetPredicate, + PredicateSetPredicate, Conversion, Unknown, }; @@ -477,6 +484,7 @@ private: INST("010010110110----", Id::ISETP_C, Type::IntegerSetPredicate, "ISETP_C"), INST("010110110110----", Id::ISETP_R, Type::IntegerSetPredicate, "ISETP_R"), INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerSetPredicate, "ISETP_IMM"), + INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), }; #undef INST std::stable_sort(table.begin(), table.end(), [](const auto& a, const auto& b) { diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 907236136..35c1b1890 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -75,14 +75,11 @@ RasterizerOpenGL::RasterizerOpenGL() { // Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0 state.clip_distance[0] = true; - // Generate VBO, VAO and UBO - vertex_buffer = OGLStreamBuffer::MakeBuffer(GLAD_GL_ARB_buffer_storage, GL_ARRAY_BUFFER); - vertex_buffer->Create(VERTEX_BUFFER_SIZE, VERTEX_BUFFER_SIZE / 2); + // Generate VAO and UBO sw_vao.Create(); uniform_buffer.Create(); state.draw.vertex_array = sw_vao.handle; - state.draw.vertex_buffer = vertex_buffer->GetHandle(); state.draw.uniform_buffer = uniform_buffer.handle; state.Apply(); @@ -90,7 +87,6 @@ RasterizerOpenGL::RasterizerOpenGL() { framebuffer.Create(); hw_vao.Create(); - hw_vao_enabled_attributes.fill(false); stream_buffer = OGLStreamBuffer::MakeBuffer(has_ARB_buffer_storage, GL_ARRAY_BUFFER); stream_buffer->Create(STREAM_BUFFER_SIZE, STREAM_BUFFER_SIZE / 2); @@ -181,8 +177,6 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); glVertexAttribBinding(index, attrib.buffer); - - hw_vao_enabled_attributes[index] = true; } return {array_ptr, buffer_offset}; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 9709e595e..4b915c76a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -134,21 +134,17 @@ private: std::unique_ptr<GLShader::ProgramManager> shader_program_manager; OGLVertexArray sw_vao; OGLVertexArray hw_vao; - std::array<bool, 16> hw_vao_enabled_attributes; std::array<SamplerInfo, GLShader::NumTextureSamplers> texture_samplers; std::array<std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::MaxConstBuffers>, Tegra::Engines::Maxwell3D::Regs::MaxShaderStage> ssbos; - static constexpr size_t VERTEX_BUFFER_SIZE = 128 * 1024 * 1024; - std::unique_ptr<OGLStreamBuffer> vertex_buffer; + static constexpr size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; + std::unique_ptr<OGLStreamBuffer> stream_buffer; OGLBuffer uniform_buffer; OGLFramebuffer framebuffer; - static constexpr size_t STREAM_BUFFER_SIZE = 4 * 1024 * 1024; - std::unique_ptr<OGLStreamBuffer> stream_buffer; - size_t CalculateVertexArraysSize() const; std::pair<u8*, GLintptr> SetupVertexArrays(u8* array_ptr, GLintptr buffer_offset); diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index abbf0893d..1aa24da46 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -580,14 +580,17 @@ private: * @param instr Instruction to generate the if condition for. * @returns string containing the predicate condition. */ - std::string GetPredicateCondition(Instruction instr) const { + std::string GetPredicateCondition(u64 index, bool negate) const { using Tegra::Shader::Pred; - ASSERT(instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)); + std::string variable; - std::string variable = - 'p' + std::to_string(static_cast<u64>(instr.pred.pred_index.Value())); + // Index 7 is used as an 'Always True' condition. + if (index == static_cast<u64>(Pred::UnusedIndex)) + variable = "true"; + else + variable = 'p' + std::to_string(index); - if (instr.negate_pred) { + if (negate) { return "!(" + variable + ')'; } @@ -634,7 +637,9 @@ private: "NeverExecute predicate not implemented"); if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) { - shader.AddLine("if (" + GetPredicateCondition(instr) + ')'); + shader.AddLine("if (" + + GetPredicateCondition(instr.pred.pred_index, instr.negate_pred != 0) + + ')'); shader.AddLine('{'); ++shader.scope; } @@ -730,6 +735,16 @@ private: } break; } + case OpCode::Id::FMNMX: { + std::string condition = + GetPredicateCondition(instr.alu.fmnmx.pred, instr.alu.fmnmx.negate_pred != 0); + std::string parameters = op_a + ',' + op_b; + regs.SetRegisterToFloat(instr.gpr0, 0, + '(' + condition + ") ? min(" + parameters + ") : max(" + + parameters + ')', + 1, 1); + break; + } case OpCode::Id::RRO: { NGLOG_DEBUG(HW_GPU, "Skipping RRO instruction"); break; diff --git a/src/video_core/renderer_opengl/gl_shader_util.h b/src/video_core/renderer_opengl/gl_shader_util.h index a1fa9e814..2036a06a9 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.h +++ b/src/video_core/renderer_opengl/gl_shader_util.h @@ -4,6 +4,7 @@ #pragma once +#include <string> #include <vector> #include <glad/glad.h> #include "common/assert.h" @@ -12,6 +13,27 @@ namespace GLShader { /** + * Utility function to log the source code of a list of shaders. + * @param shaders The OpenGL shaders whose source we will print. + */ +template <typename... T> +void LogShaderSource(T... shaders) { + auto shader_list = {shaders...}; + + for (const auto& shader : shader_list) { + if (shader == 0) + continue; + + GLint source_length; + glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &source_length); + + std::string source(source_length, ' '); + glGetShaderSource(shader, source_length, nullptr, &source[0]); + NGLOG_INFO(Render_OpenGL, "Shader source {}", source); + } +} + +/** * Utility function to create and compile an OpenGL GLSL shader * @param source String of the GLSL shader program * @param type Type of the shader (GL_VERTEX_SHADER, GL_GEOMETRY_SHADER or GL_FRAGMENT_SHADER) @@ -55,6 +77,11 @@ GLuint LoadProgram(bool separable_program, T... shaders) { } } + if (result == GL_FALSE) { + // There was a problem linking the shader, print the source for debugging purposes. + LogShaderSource(shaders...); + } + ASSERT_MSG(result == GL_TRUE, "Shader not linked"); ((shaders == 0 ? (void)0 : glDetachShader(program_id, shaders)), ...); |
