mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	video_core: fixed arithmetic overflow warnings & improved code style
- Fixed all warnings, for renderer_opengl items, which were indicating a possible incorrect behavior from integral promotion rules and types larger than those in which arithmetic is typically performed. - Added const for variables where possible and meaningful. - Added constexpr where possible.
This commit is contained in:
		
							parent
							
								
									6d64ecf359
								
							
						
					
					
						commit
						64e45b04e0
					
				| @ -505,7 +505,7 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) { | |||||||
| 
 | 
 | ||||||
|     S8Z24 input_pixel{}; |     S8Z24 input_pixel{}; | ||||||
|     Z24S8 output_pixel{}; |     Z24S8 output_pixel{}; | ||||||
|     const auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::S8Z24)}; |     constexpr auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::S8Z24)}; | ||||||
|     for (size_t y = 0; y < height; ++y) { |     for (size_t y = 0; y < height; ++y) { | ||||||
|         for (size_t x = 0; x < width; ++x) { |         for (size_t x = 0; x < width; ++x) { | ||||||
|             const size_t offset{bpp * (y * width + x)}; |             const size_t offset{bpp * (y * width + x)}; | ||||||
| @ -518,7 +518,7 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) { | static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) { | ||||||
|     const auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::G8R8U)}; |     constexpr auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::G8R8U)}; | ||||||
|     for (size_t y = 0; y < height; ++y) { |     for (size_t y = 0; y < height; ++y) { | ||||||
|         for (size_t x = 0; x < width; ++x) { |         for (size_t x = 0; x < width; ++x) { | ||||||
|             const size_t offset{bpp * (y * width + x)}; |             const size_t offset{bpp * (y * width + x)}; | ||||||
| @ -584,12 +584,13 @@ void CachedSurface::LoadGLBuffer() { | |||||||
|             UNREACHABLE(); |             UNREACHABLE(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         gl_buffer.resize(params.depth * copy_size); |         gl_buffer.resize(static_cast<size_t>(params.depth) * copy_size); | ||||||
|         morton_to_gl_fns[static_cast<size_t>(params.pixel_format)]( |         morton_to_gl_fns[static_cast<size_t>(params.pixel_format)]( | ||||||
|             params.width, params.block_height, params.height, gl_buffer.data(), copy_size, |             params.width, params.block_height, params.height, gl_buffer.data(), copy_size, | ||||||
|             params.addr); |             params.addr); | ||||||
|     } else { |     } else { | ||||||
|         const u8* const texture_src_data_end{texture_src_data + (params.depth * copy_size)}; |         const u8* const texture_src_data_end{texture_src_data + | ||||||
|  |                                              (static_cast<size_t>(params.depth) * copy_size)}; | ||||||
|         gl_buffer.assign(texture_src_data, texture_src_data_end); |         gl_buffer.assign(texture_src_data, texture_src_data_end); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -608,18 +609,20 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle | |||||||
| 
 | 
 | ||||||
|     MICROPROFILE_SCOPE(OpenGL_TextureUL); |     MICROPROFILE_SCOPE(OpenGL_TextureUL); | ||||||
| 
 | 
 | ||||||
|     ASSERT(gl_buffer.size() == |     ASSERT(gl_buffer.size() == static_cast<size_t>(params.width) * params.height * | ||||||
|            params.width * params.height * GetGLBytesPerPixel(params.pixel_format) * params.depth); |                                    GetGLBytesPerPixel(params.pixel_format) * params.depth); | ||||||
| 
 | 
 | ||||||
|     const auto& rect{params.GetRect()}; |     const auto& rect{params.GetRect()}; | ||||||
| 
 | 
 | ||||||
|     // Load data from memory to the surface
 |     // Load data from memory to the surface
 | ||||||
|     GLint x0 = static_cast<GLint>(rect.left); |     const GLint x0 = static_cast<GLint>(rect.left); | ||||||
|     GLint y0 = static_cast<GLint>(rect.bottom); |     const GLint y0 = static_cast<GLint>(rect.bottom); | ||||||
|     size_t buffer_offset = (y0 * params.width + x0) * GetGLBytesPerPixel(params.pixel_format); |     const size_t buffer_offset = | ||||||
|  |         static_cast<size_t>(static_cast<size_t>(y0) * params.width + static_cast<size_t>(x0)) * | ||||||
|  |         GetGLBytesPerPixel(params.pixel_format); | ||||||
| 
 | 
 | ||||||
|     const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); |     const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); | ||||||
|     GLuint target_tex = texture.handle; |     const GLuint target_tex = texture.handle; | ||||||
|     OpenGLState cur_state = OpenGLState::GetCurState(); |     OpenGLState cur_state = OpenGLState::GetCurState(); | ||||||
| 
 | 
 | ||||||
|     const auto& old_tex = cur_state.texture_units[0]; |     const auto& old_tex = cur_state.texture_units[0]; | ||||||
|  | |||||||
| @ -13,8 +13,8 @@ namespace OpenGL { | |||||||
| 
 | 
 | ||||||
| /// Gets the address for the specified shader stage program
 | /// Gets the address for the specified shader stage program
 | ||||||
| static VAddr GetShaderAddress(Maxwell::ShaderProgram program) { | static VAddr GetShaderAddress(Maxwell::ShaderProgram program) { | ||||||
|     auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); |     const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); | ||||||
|     auto& shader_config = gpu.regs.shader_config[static_cast<size_t>(program)]; |     const auto& shader_config = gpu.regs.shader_config[static_cast<size_t>(program)]; | ||||||
|     return *gpu.memory_manager.GpuToCpuAddress(gpu.regs.code_address.CodeAddress() + |     return *gpu.memory_manager.GpuToCpuAddress(gpu.regs.code_address.CodeAddress() + | ||||||
|                                                shader_config.offset); |                                                shader_config.offset); | ||||||
| } | } | ||||||
| @ -86,7 +86,7 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) { | GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) { | ||||||
|     auto search{resource_cache.find(buffer.GetHash())}; |     const auto search{resource_cache.find(buffer.GetHash())}; | ||||||
|     if (search == resource_cache.end()) { |     if (search == resource_cache.end()) { | ||||||
|         const GLuint index{ |         const GLuint index{ | ||||||
|             glGetProgramResourceIndex(program.handle, GL_UNIFORM_BLOCK, buffer.GetName().c_str())}; |             glGetProgramResourceIndex(program.handle, GL_UNIFORM_BLOCK, buffer.GetName().c_str())}; | ||||||
| @ -98,7 +98,7 @@ GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& b | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GLint CachedShader::GetUniformLocation(const GLShader::SamplerEntry& sampler) { | GLint CachedShader::GetUniformLocation(const GLShader::SamplerEntry& sampler) { | ||||||
|     auto search{uniform_cache.find(sampler.GetHash())}; |     const auto search{uniform_cache.find(sampler.GetHash())}; | ||||||
|     if (search == uniform_cache.end()) { |     if (search == uniform_cache.end()) { | ||||||
|         const GLint index{glGetUniformLocation(program.handle, sampler.GetName().c_str())}; |         const GLint index{glGetUniformLocation(program.handle, sampler.GetName().c_str())}; | ||||||
|         uniform_cache[sampler.GetHash()] = index; |         uniform_cache[sampler.GetHash()] = index; | ||||||
|  | |||||||
| @ -113,7 +113,7 @@ private: | |||||||
| 
 | 
 | ||||||
|     /// Scans a range of code for labels and determines the exit method.
 |     /// Scans a range of code for labels and determines the exit method.
 | ||||||
|     ExitMethod Scan(u32 begin, u32 end, std::set<u32>& labels) { |     ExitMethod Scan(u32 begin, u32 end, std::set<u32>& labels) { | ||||||
|         auto [iter, inserted] = |         const auto [iter, inserted] = | ||||||
|             exit_method_map.emplace(std::make_pair(begin, end), ExitMethod::Undetermined); |             exit_method_map.emplace(std::make_pair(begin, end), ExitMethod::Undetermined); | ||||||
|         ExitMethod& exit_method = iter->second; |         ExitMethod& exit_method = iter->second; | ||||||
|         if (!inserted) |         if (!inserted) | ||||||
| @ -131,22 +131,22 @@ private: | |||||||
|                     if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) { |                     if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) { | ||||||
|                         return exit_method = ExitMethod::AlwaysEnd; |                         return exit_method = ExitMethod::AlwaysEnd; | ||||||
|                     } else { |                     } else { | ||||||
|                         ExitMethod not_met = Scan(offset + 1, end, labels); |                         const ExitMethod not_met = Scan(offset + 1, end, labels); | ||||||
|                         return exit_method = ParallelExit(ExitMethod::AlwaysEnd, not_met); |                         return exit_method = ParallelExit(ExitMethod::AlwaysEnd, not_met); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 case OpCode::Id::BRA: { |                 case OpCode::Id::BRA: { | ||||||
|                     u32 target = offset + instr.bra.GetBranchTarget(); |                     const u32 target = offset + instr.bra.GetBranchTarget(); | ||||||
|                     labels.insert(target); |                     labels.insert(target); | ||||||
|                     ExitMethod no_jmp = Scan(offset + 1, end, labels); |                     const ExitMethod no_jmp = Scan(offset + 1, end, labels); | ||||||
|                     ExitMethod jmp = Scan(target, end, labels); |                     const ExitMethod jmp = Scan(target, end, labels); | ||||||
|                     return exit_method = ParallelExit(no_jmp, jmp); |                     return exit_method = ParallelExit(no_jmp, jmp); | ||||||
|                 } |                 } | ||||||
|                 case OpCode::Id::SSY: { |                 case OpCode::Id::SSY: { | ||||||
|                     // The SSY instruction uses a similar encoding as the BRA instruction.
 |                     // The SSY instruction uses a similar encoding as the BRA instruction.
 | ||||||
|                     ASSERT_MSG(instr.bra.constant_buffer == 0, |                     ASSERT_MSG(instr.bra.constant_buffer == 0, | ||||||
|                                "Constant buffer SSY is not supported"); |                                "Constant buffer SSY is not supported"); | ||||||
|                     u32 target = offset + instr.bra.GetBranchTarget(); |                     const u32 target = offset + instr.bra.GetBranchTarget(); | ||||||
|                     labels.insert(target); |                     labels.insert(target); | ||||||
|                     // Continue scanning for an exit method.
 |                     // Continue scanning for an exit method.
 | ||||||
|                     break; |                     break; | ||||||
| @ -346,8 +346,8 @@ public: | |||||||
|      */ |      */ | ||||||
|     void SetRegisterToInputAttibute(const Register& reg, u64 elem, Attribute::Index attribute, |     void SetRegisterToInputAttibute(const Register& reg, u64 elem, Attribute::Index attribute, | ||||||
|                                     const Tegra::Shader::IpaMode& input_mode) { |                                     const Tegra::Shader::IpaMode& input_mode) { | ||||||
|         std::string dest = GetRegisterAsFloat(reg); |         const std::string dest = GetRegisterAsFloat(reg); | ||||||
|         std::string src = GetInputAttribute(attribute, input_mode) + GetSwizzle(elem); |         const std::string src = GetInputAttribute(attribute, input_mode) + GetSwizzle(elem); | ||||||
|         shader.AddLine(dest + " = " + src + ';'); |         shader.AddLine(dest + " = " + src + ';'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -359,8 +359,8 @@ public: | |||||||
|      * @param reg The register to use as the source value. |      * @param reg The register to use as the source value. | ||||||
|      */ |      */ | ||||||
|     void SetOutputAttributeToRegister(Attribute::Index attribute, u64 elem, const Register& reg) { |     void SetOutputAttributeToRegister(Attribute::Index attribute, u64 elem, const Register& reg) { | ||||||
|         std::string dest = GetOutputAttribute(attribute); |         const std::string dest = GetOutputAttribute(attribute); | ||||||
|         std::string src = GetRegisterAsFloat(reg); |         const std::string src = GetRegisterAsFloat(reg); | ||||||
| 
 | 
 | ||||||
|         if (!dest.empty()) { |         if (!dest.empty()) { | ||||||
|             // Can happen with unknown/unimplemented output attributes, in which case we ignore the
 |             // Can happen with unknown/unimplemented output attributes, in which case we ignore the
 | ||||||
| @ -393,9 +393,9 @@ public: | |||||||
|                                    GLSLRegister::Type type) { |                                    GLSLRegister::Type type) { | ||||||
|         declr_const_buffers[cbuf_index].MarkAsUsedIndirect(cbuf_index, stage); |         declr_const_buffers[cbuf_index].MarkAsUsedIndirect(cbuf_index, stage); | ||||||
| 
 | 
 | ||||||
|         std::string final_offset = fmt::format("({} + {})", index_str, offset / 4); |         const std::string final_offset = fmt::format("({} + {})", index_str, offset / 4); | ||||||
|         std::string value = 'c' + std::to_string(cbuf_index) + '[' + final_offset + " / 4][" + |         const std::string value = 'c' + std::to_string(cbuf_index) + '[' + final_offset + " / 4][" + | ||||||
|                             final_offset + " % 4]"; |                                   final_offset + " % 4]"; | ||||||
| 
 | 
 | ||||||
|         if (type == GLSLRegister::Type::Float) { |         if (type == GLSLRegister::Type::Float) { | ||||||
|             return value; |             return value; | ||||||
| @ -468,10 +468,10 @@ public: | |||||||
|     /// necessary.
 |     /// necessary.
 | ||||||
|     std::string AccessSampler(const Sampler& sampler, Tegra::Shader::TextureType type, |     std::string AccessSampler(const Sampler& sampler, Tegra::Shader::TextureType type, | ||||||
|                               bool is_array) { |                               bool is_array) { | ||||||
|         size_t offset = static_cast<size_t>(sampler.index.Value()); |         const size_t offset = static_cast<size_t>(sampler.index.Value()); | ||||||
| 
 | 
 | ||||||
|         // If this sampler has already been used, return the existing mapping.
 |         // If this sampler has already been used, return the existing mapping.
 | ||||||
|         auto itr = |         const auto itr = | ||||||
|             std::find_if(used_samplers.begin(), used_samplers.end(), |             std::find_if(used_samplers.begin(), used_samplers.end(), | ||||||
|                          [&](const SamplerEntry& entry) { return entry.GetOffset() == offset; }); |                          [&](const SamplerEntry& entry) { return entry.GetOffset() == offset; }); | ||||||
| 
 | 
 | ||||||
| @ -481,8 +481,8 @@ public: | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Otherwise create a new mapping for this sampler
 |         // Otherwise create a new mapping for this sampler
 | ||||||
|         size_t next_index = used_samplers.size(); |         const size_t next_index = used_samplers.size(); | ||||||
|         SamplerEntry entry{stage, offset, next_index, type, is_array}; |         const SamplerEntry entry{stage, offset, next_index, type, is_array}; | ||||||
|         used_samplers.emplace_back(entry); |         used_samplers.emplace_back(entry); | ||||||
|         return entry.GetName(); |         return entry.GetName(); | ||||||
|     } |     } | ||||||
| @ -699,7 +699,7 @@ private: | |||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         bool IsColorComponentOutputEnabled(u32 render_target, u32 component) const { |         bool IsColorComponentOutputEnabled(u32 render_target, u32 component) const { | ||||||
|             u32 bit = render_target * 4 + component; |             const u32 bit = render_target * 4 + component; | ||||||
|             return enabled_color_outputs & (1 << bit); |             return enabled_color_outputs & (1 << bit); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| @ -707,7 +707,7 @@ private: | |||||||
| 
 | 
 | ||||||
|     /// Gets the Subroutine object corresponding to the specified address.
 |     /// Gets the Subroutine object corresponding to the specified address.
 | ||||||
|     const Subroutine& GetSubroutine(u32 begin, u32 end) const { |     const Subroutine& GetSubroutine(u32 begin, u32 end) const { | ||||||
|         auto iter = subroutines.find(Subroutine{begin, end, suffix}); |         const auto iter = subroutines.find(Subroutine{begin, end, suffix}); | ||||||
|         ASSERT(iter != subroutines.end()); |         ASSERT(iter != subroutines.end()); | ||||||
|         return *iter; |         return *iter; | ||||||
|     } |     } | ||||||
| @ -752,7 +752,7 @@ private: | |||||||
|         // Can't assign to the constant predicate.
 |         // Can't assign to the constant predicate.
 | ||||||
|         ASSERT(pred != static_cast<u64>(Pred::UnusedIndex)); |         ASSERT(pred != static_cast<u64>(Pred::UnusedIndex)); | ||||||
| 
 | 
 | ||||||
|         std::string variable = 'p' + std::to_string(pred) + '_' + suffix; |         const std::string variable = 'p' + std::to_string(pred) + '_' + suffix; | ||||||
|         shader.AddLine(variable + " = " + value + ';'); |         shader.AddLine(variable + " = " + value + ';'); | ||||||
|         declr_predicates.insert(std::move(variable)); |         declr_predicates.insert(std::move(variable)); | ||||||
|     } |     } | ||||||
| @ -1033,7 +1033,11 @@ private: | |||||||
|         if (header.writes_depth) { |         if (header.writes_depth) { | ||||||
|             // The depth output is always 2 registers after the last color output, and current_reg
 |             // The depth output is always 2 registers after the last color output, and current_reg
 | ||||||
|             // already contains one past the last color register.
 |             // already contains one past the last color register.
 | ||||||
|             shader.AddLine("gl_FragDepth = " + regs.GetRegisterAsFloat(current_reg + 1) + ';'); | 
 | ||||||
|  |             shader.AddLine( | ||||||
|  |                 "gl_FragDepth = " + | ||||||
|  |                 regs.GetRegisterAsFloat(static_cast<Tegra::Shader::Register>(current_reg) + 1) + | ||||||
|  |                 ';'); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -1435,7 +1439,7 @@ private: | |||||||
|                 if (instr.alu_integer.negate_b) |                 if (instr.alu_integer.negate_b) | ||||||
|                     op_b = "-(" + op_b + ')'; |                     op_b = "-(" + op_b + ')'; | ||||||
| 
 | 
 | ||||||
|                 std::string shift = std::to_string(instr.alu_integer.shift_amount.Value()); |                 const std::string shift = std::to_string(instr.alu_integer.shift_amount.Value()); | ||||||
| 
 | 
 | ||||||
|                 regs.SetRegisterToInteger(instr.gpr0, true, 0, |                 regs.SetRegisterToInteger(instr.gpr0, true, 0, | ||||||
|                                           "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); |                                           "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); | ||||||
| @ -1453,7 +1457,7 @@ private: | |||||||
|             case OpCode::Id::SEL_C: |             case OpCode::Id::SEL_C: | ||||||
|             case OpCode::Id::SEL_R: |             case OpCode::Id::SEL_R: | ||||||
|             case OpCode::Id::SEL_IMM: { |             case OpCode::Id::SEL_IMM: { | ||||||
|                 std::string condition = |                 const std::string condition = | ||||||
|                     GetPredicateCondition(instr.sel.pred, instr.sel.neg_pred != 0); |                     GetPredicateCondition(instr.sel.pred, instr.sel.neg_pred != 0); | ||||||
|                 regs.SetRegisterToInteger(instr.gpr0, true, 0, |                 regs.SetRegisterToInteger(instr.gpr0, true, 0, | ||||||
|                                           '(' + condition + ") ? " + op_a + " : " + op_b, 1, 1); |                                           '(' + condition + ") ? " + op_a + " : " + op_b, 1, 1); | ||||||
| @ -1475,8 +1479,9 @@ private: | |||||||
|             case OpCode::Id::LOP3_C: |             case OpCode::Id::LOP3_C: | ||||||
|             case OpCode::Id::LOP3_R: |             case OpCode::Id::LOP3_R: | ||||||
|             case OpCode::Id::LOP3_IMM: { |             case OpCode::Id::LOP3_IMM: { | ||||||
|                 std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); |                 const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); | ||||||
|                 std::string lut; |                 std::string lut; | ||||||
|  | 
 | ||||||
|                 if (opcode->GetId() == OpCode::Id::LOP3_R) { |                 if (opcode->GetId() == OpCode::Id::LOP3_R) { | ||||||
|                     lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')'; |                     lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')'; | ||||||
|                 } else { |                 } else { | ||||||
| @ -1491,9 +1496,9 @@ private: | |||||||
|             case OpCode::Id::IMNMX_IMM: { |             case OpCode::Id::IMNMX_IMM: { | ||||||
|                 ASSERT_MSG(instr.imnmx.exchange == Tegra::Shader::IMinMaxExchange::None, |                 ASSERT_MSG(instr.imnmx.exchange == Tegra::Shader::IMinMaxExchange::None, | ||||||
|                            "Unimplemented"); |                            "Unimplemented"); | ||||||
|                 std::string condition = |                 const std::string condition = | ||||||
|                     GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0); |                     GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0); | ||||||
|                 std::string parameters = op_a + ',' + op_b; |                 const std::string parameters = op_a + ',' + op_b; | ||||||
|                 regs.SetRegisterToInteger(instr.gpr0, instr.imnmx.is_signed, 0, |                 regs.SetRegisterToInteger(instr.gpr0, instr.imnmx.is_signed, 0, | ||||||
|                                           '(' + condition + ") ? min(" + parameters + ") : max(" + |                                           '(' + condition + ") ? min(" + parameters + ") : max(" + | ||||||
|                                               parameters + ')', |                                               parameters + ')', | ||||||
| @ -1510,7 +1515,7 @@ private: | |||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         case OpCode::Type::Ffma: { |         case OpCode::Type::Ffma: { | ||||||
|             std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); |             const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|             std::string op_b = instr.ffma.negate_b ? "-" : ""; |             std::string op_b = instr.ffma.negate_b ? "-" : ""; | ||||||
|             std::string op_c = instr.ffma.negate_c ? "-" : ""; |             std::string op_c = instr.ffma.negate_c ? "-" : ""; | ||||||
| 
 | 
 | ||||||
| @ -1720,7 +1725,7 @@ private: | |||||||
|                 shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + |                 shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + | ||||||
|                                " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);"); |                                " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);"); | ||||||
| 
 | 
 | ||||||
|                 std::string op_a = |                 const std::string op_a = | ||||||
|                     regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, "index", |                     regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, "index", | ||||||
|                                             GLSLRegister::Type::Float); |                                             GLSLRegister::Type::Float); | ||||||
| 
 | 
 | ||||||
| @ -1730,7 +1735,7 @@ private: | |||||||
|                     break; |                     break; | ||||||
| 
 | 
 | ||||||
|                 case Tegra::Shader::UniformType::Double: { |                 case Tegra::Shader::UniformType::Double: { | ||||||
|                     std::string op_b = |                     const std::string op_b = | ||||||
|                         regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, |                         regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, | ||||||
|                                                 "index", GLSLRegister::Type::Float); |                                                 "index", GLSLRegister::Type::Float); | ||||||
|                     regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); |                     regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); | ||||||
| @ -1760,13 +1765,13 @@ private: | |||||||
| 
 | 
 | ||||||
|                 switch (texture_type) { |                 switch (texture_type) { | ||||||
|                 case Tegra::Shader::TextureType::Texture1D: { |                 case Tegra::Shader::TextureType::Texture1D: { | ||||||
|                     std::string x = regs.GetRegisterAsFloat(instr.gpr8); |                     const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|                     coord = "float coords = " + x + ';'; |                     coord = "float coords = " + x + ';'; | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 case Tegra::Shader::TextureType::Texture2D: { |                 case Tegra::Shader::TextureType::Texture2D: { | ||||||
|                     std::string x = regs.GetRegisterAsFloat(instr.gpr8); |                     const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|                     std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |                     const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||||||
|                     coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |                     coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
| @ -1776,8 +1781,8 @@ private: | |||||||
|                     UNREACHABLE(); |                     UNREACHABLE(); | ||||||
| 
 | 
 | ||||||
|                     // Fallback to interpreting as a 2D texture for now
 |                     // Fallback to interpreting as a 2D texture for now
 | ||||||
|                     std::string x = regs.GetRegisterAsFloat(instr.gpr8); |                     const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|                     std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |                     const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||||||
|                     coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |                     coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||||||
|                     texture_type = Tegra::Shader::TextureType::Texture2D; |                     texture_type = Tegra::Shader::TextureType::Texture2D; | ||||||
|                 } |                 } | ||||||
| @ -1811,13 +1816,13 @@ private: | |||||||
|                 switch (texture_type) { |                 switch (texture_type) { | ||||||
|                 case Tegra::Shader::TextureType::Texture2D: { |                 case Tegra::Shader::TextureType::Texture2D: { | ||||||
|                     if (is_array) { |                     if (is_array) { | ||||||
|                         std::string index = regs.GetRegisterAsInteger(instr.gpr8); |                         const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | ||||||
|                         std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |                         const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||||||
|                         std::string y = regs.GetRegisterAsFloat(instr.gpr20); |                         const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||||||
|                         coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; |                         coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; | ||||||
|                     } else { |                     } else { | ||||||
|                         std::string x = regs.GetRegisterAsFloat(instr.gpr8); |                         const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|                         std::string y = regs.GetRegisterAsFloat(instr.gpr20); |                         const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||||||
|                         coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |                         coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||||||
|                     } |                     } | ||||||
|                     break; |                     break; | ||||||
| @ -1828,8 +1833,8 @@ private: | |||||||
|                     UNREACHABLE(); |                     UNREACHABLE(); | ||||||
| 
 | 
 | ||||||
|                     // Fallback to interpreting as a 2D texture for now
 |                     // Fallback to interpreting as a 2D texture for now
 | ||||||
|                     std::string x = regs.GetRegisterAsFloat(instr.gpr8); |                     const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|                     std::string y = regs.GetRegisterAsFloat(instr.gpr20); |                     const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||||||
|                     coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |                     coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||||||
|                     texture_type = Tegra::Shader::TextureType::Texture2D; |                     texture_type = Tegra::Shader::TextureType::Texture2D; | ||||||
|                     is_array = false; |                     is_array = false; | ||||||
| @ -1850,8 +1855,8 @@ private: | |||||||
|                         LOG_CRITICAL(HW_GPU, "Unhandled 2d array texture"); |                         LOG_CRITICAL(HW_GPU, "Unhandled 2d array texture"); | ||||||
|                         UNREACHABLE(); |                         UNREACHABLE(); | ||||||
|                     } else { |                     } else { | ||||||
|                         std::string x = regs.GetRegisterAsInteger(instr.gpr8); |                         const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | ||||||
|                         std::string y = regs.GetRegisterAsInteger(instr.gpr20); |                         const std::string y = regs.GetRegisterAsInteger(instr.gpr20); | ||||||
|                         coord = "ivec2 coords = ivec2(" + x + ", " + y + ");"; |                         coord = "ivec2 coords = ivec2(" + x + ", " + y + ");"; | ||||||
|                     } |                     } | ||||||
|                     break; |                     break; | ||||||
| @ -1874,8 +1879,8 @@ private: | |||||||
| 
 | 
 | ||||||
|                 switch (instr.tld4.texture_type) { |                 switch (instr.tld4.texture_type) { | ||||||
|                 case Tegra::Shader::TextureType::Texture2D: { |                 case Tegra::Shader::TextureType::Texture2D: { | ||||||
|                     std::string x = regs.GetRegisterAsFloat(instr.gpr8); |                     const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|                     std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |                     const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||||||
|                     coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |                     coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
| @ -1959,12 +1964,12 @@ private: | |||||||
|             // We can't use the constant predicate as destination.
 |             // We can't use the constant predicate as destination.
 | ||||||
|             ASSERT(instr.fsetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); |             ASSERT(instr.fsetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); | ||||||
| 
 | 
 | ||||||
|             std::string second_pred = |             const std::string second_pred = | ||||||
|                 GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0); |                 GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0); | ||||||
| 
 | 
 | ||||||
|             std::string combiner = GetPredicateCombiner(instr.fsetp.op); |             const std::string combiner = GetPredicateCombiner(instr.fsetp.op); | ||||||
| 
 | 
 | ||||||
|             std::string predicate = GetPredicateComparison(instr.fsetp.cond, op_a, op_b); |             const std::string predicate = GetPredicateComparison(instr.fsetp.cond, op_a, op_b); | ||||||
|             // Set the primary predicate to the result of Predicate OP SecondPredicate
 |             // Set the primary predicate to the result of Predicate OP SecondPredicate
 | ||||||
|             SetPredicate(instr.fsetp.pred3, |             SetPredicate(instr.fsetp.pred3, | ||||||
|                          '(' + predicate + ") " + combiner + " (" + second_pred + ')'); |                          '(' + predicate + ") " + combiner + " (" + second_pred + ')'); | ||||||
| @ -1978,7 +1983,8 @@ private: | |||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         case OpCode::Type::IntegerSetPredicate: { |         case OpCode::Type::IntegerSetPredicate: { | ||||||
|             std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.isetp.is_signed); |             const std::string op_a = | ||||||
|  |                 regs.GetRegisterAsInteger(instr.gpr8, 0, instr.isetp.is_signed); | ||||||
|             std::string op_b; |             std::string op_b; | ||||||
| 
 | 
 | ||||||
|             if (instr.is_b_imm) { |             if (instr.is_b_imm) { | ||||||
| @ -1995,12 +2001,12 @@ private: | |||||||
|             // We can't use the constant predicate as destination.
 |             // We can't use the constant predicate as destination.
 | ||||||
|             ASSERT(instr.isetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); |             ASSERT(instr.isetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); | ||||||
| 
 | 
 | ||||||
|             std::string second_pred = |             const std::string second_pred = | ||||||
|                 GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0); |                 GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0); | ||||||
| 
 | 
 | ||||||
|             std::string combiner = GetPredicateCombiner(instr.isetp.op); |             const std::string combiner = GetPredicateCombiner(instr.isetp.op); | ||||||
| 
 | 
 | ||||||
|             std::string predicate = GetPredicateComparison(instr.isetp.cond, op_a, op_b); |             const std::string predicate = GetPredicateComparison(instr.isetp.cond, op_a, op_b); | ||||||
|             // Set the primary predicate to the result of Predicate OP SecondPredicate
 |             // Set the primary predicate to the result of Predicate OP SecondPredicate
 | ||||||
|             SetPredicate(instr.isetp.pred3, |             SetPredicate(instr.isetp.pred3, | ||||||
|                          '(' + predicate + ") " + combiner + " (" + second_pred + ')'); |                          '(' + predicate + ") " + combiner + " (" + second_pred + ')'); | ||||||
| @ -2014,20 +2020,20 @@ private: | |||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         case OpCode::Type::PredicateSetPredicate: { |         case OpCode::Type::PredicateSetPredicate: { | ||||||
|             std::string op_a = |             const std::string op_a = | ||||||
|                 GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0); |                 GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0); | ||||||
|             std::string op_b = |             const std::string op_b = | ||||||
|                 GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0); |                 GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0); | ||||||
| 
 | 
 | ||||||
|             // We can't use the constant predicate as destination.
 |             // We can't use the constant predicate as destination.
 | ||||||
|             ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); |             ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); | ||||||
| 
 | 
 | ||||||
|             std::string second_pred = |             const std::string second_pred = | ||||||
|                 GetPredicateCondition(instr.psetp.pred39, instr.psetp.neg_pred39 != 0); |                 GetPredicateCondition(instr.psetp.pred39, instr.psetp.neg_pred39 != 0); | ||||||
| 
 | 
 | ||||||
|             std::string combiner = GetPredicateCombiner(instr.psetp.op); |             const std::string combiner = GetPredicateCombiner(instr.psetp.op); | ||||||
| 
 | 
 | ||||||
|             std::string predicate = |             const std::string predicate = | ||||||
|                 '(' + op_a + ") " + GetPredicateCombiner(instr.psetp.cond) + " (" + op_b + ')'; |                 '(' + op_a + ") " + GetPredicateCombiner(instr.psetp.cond) + " (" + op_b + ')'; | ||||||
| 
 | 
 | ||||||
|             // Set the primary predicate to the result of Predicate OP SecondPredicate
 |             // Set the primary predicate to the result of Predicate OP SecondPredicate
 | ||||||
| @ -2053,7 +2059,7 @@ private: | |||||||
|             std::string op_b = instr.fset.neg_b ? "-" : ""; |             std::string op_b = instr.fset.neg_b ? "-" : ""; | ||||||
| 
 | 
 | ||||||
|             if (instr.is_b_imm) { |             if (instr.is_b_imm) { | ||||||
|                 std::string imm = GetImmediate19(instr); |                 const std::string imm = GetImmediate19(instr); | ||||||
|                 if (instr.fset.neg_imm) |                 if (instr.fset.neg_imm) | ||||||
|                     op_b += "(-" + imm + ')'; |                     op_b += "(-" + imm + ')'; | ||||||
|                 else |                 else | ||||||
| @ -2073,13 +2079,14 @@ private: | |||||||
| 
 | 
 | ||||||
|             // The fset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the
 |             // The fset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the
 | ||||||
|             // condition is true, and to 0 otherwise.
 |             // condition is true, and to 0 otherwise.
 | ||||||
|             std::string second_pred = |             const std::string second_pred = | ||||||
|                 GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); |                 GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); | ||||||
| 
 | 
 | ||||||
|             std::string combiner = GetPredicateCombiner(instr.fset.op); |             const std::string combiner = GetPredicateCombiner(instr.fset.op); | ||||||
| 
 | 
 | ||||||
|             std::string predicate = "((" + GetPredicateComparison(instr.fset.cond, op_a, op_b) + |             const std::string predicate = "((" + | ||||||
|                                     ") " + combiner + " (" + second_pred + "))"; |                                           GetPredicateComparison(instr.fset.cond, op_a, op_b) + | ||||||
|  |                                           ") " + combiner + " (" + second_pred + "))"; | ||||||
| 
 | 
 | ||||||
|             if (instr.fset.bf) { |             if (instr.fset.bf) { | ||||||
|                 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); |                 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); | ||||||
| @ -2090,7 +2097,7 @@ private: | |||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         case OpCode::Type::IntegerSet: { |         case OpCode::Type::IntegerSet: { | ||||||
|             std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.iset.is_signed); |             const std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.iset.is_signed); | ||||||
| 
 | 
 | ||||||
|             std::string op_b; |             std::string op_b; | ||||||
| 
 | 
 | ||||||
| @ -2107,13 +2114,14 @@ private: | |||||||
| 
 | 
 | ||||||
|             // The iset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the
 |             // The iset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the
 | ||||||
|             // condition is true, and to 0 otherwise.
 |             // condition is true, and to 0 otherwise.
 | ||||||
|             std::string second_pred = |             const std::string second_pred = | ||||||
|                 GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0); |                 GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0); | ||||||
| 
 | 
 | ||||||
|             std::string combiner = GetPredicateCombiner(instr.iset.op); |             const std::string combiner = GetPredicateCombiner(instr.iset.op); | ||||||
| 
 | 
 | ||||||
|             std::string predicate = "((" + GetPredicateComparison(instr.iset.cond, op_a, op_b) + |             const std::string predicate = "((" + | ||||||
|                                     ") " + combiner + " (" + second_pred + "))"; |                                           GetPredicateComparison(instr.iset.cond, op_a, op_b) + | ||||||
|  |                                           ") " + combiner + " (" + second_pred + "))"; | ||||||
| 
 | 
 | ||||||
|             if (instr.iset.bf) { |             if (instr.iset.bf) { | ||||||
|                 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); |                 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); | ||||||
| @ -2263,7 +2271,7 @@ private: | |||||||
|             case OpCode::Id::BRA: { |             case OpCode::Id::BRA: { | ||||||
|                 ASSERT_MSG(instr.bra.constant_buffer == 0, |                 ASSERT_MSG(instr.bra.constant_buffer == 0, | ||||||
|                            "BRA with constant buffers are not implemented"); |                            "BRA with constant buffers are not implemented"); | ||||||
|                 u32 target = offset + instr.bra.GetBranchTarget(); |                 const u32 target = offset + instr.bra.GetBranchTarget(); | ||||||
|                 shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); |                 shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
| @ -2287,7 +2295,7 @@ private: | |||||||
|                 // has a similar structure to the BRA opcode.
 |                 // has a similar structure to the BRA opcode.
 | ||||||
|                 ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported"); |                 ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported"); | ||||||
| 
 | 
 | ||||||
|                 u32 target = offset + instr.bra.GetBranchTarget(); |                 const u32 target = offset + instr.bra.GetBranchTarget(); | ||||||
|                 EmitPushToSSYStack(target); |                 EmitPushToSSYStack(target); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
| @ -2381,10 +2389,10 @@ private: | |||||||
|                     shader.AddLine("case " + std::to_string(label) + "u: {"); |                     shader.AddLine("case " + std::to_string(label) + "u: {"); | ||||||
|                     ++shader.scope; |                     ++shader.scope; | ||||||
| 
 | 
 | ||||||
|                     auto next_it = labels.lower_bound(label + 1); |                     const auto next_it = labels.lower_bound(label + 1); | ||||||
|                     u32 next_label = next_it == labels.end() ? subroutine.end : *next_it; |                     const u32 next_label = next_it == labels.end() ? subroutine.end : *next_it; | ||||||
| 
 | 
 | ||||||
|                     u32 compile_end = CompileRange(label, next_label); |                     const u32 compile_end = CompileRange(label, next_label); | ||||||
|                     if (compile_end > next_label && compile_end != PROGRAM_END) { |                     if (compile_end > next_label && compile_end != PROGRAM_END) { | ||||||
|                         // This happens only when there is a label inside a IF/LOOP block
 |                         // This happens only when there is a label inside a IF/LOOP block
 | ||||||
|                         shader.AddLine(" jmp_to = " + std::to_string(compile_end) + "u; break; }"); |                         shader.AddLine(" jmp_to = " + std::to_string(compile_end) + "u; break; }"); | ||||||
| @ -2447,7 +2455,8 @@ boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, | |||||||
|                                                 Maxwell3D::Regs::ShaderStage stage, |                                                 Maxwell3D::Regs::ShaderStage stage, | ||||||
|                                                 const std::string& suffix) { |                                                 const std::string& suffix) { | ||||||
|     try { |     try { | ||||||
|         auto subroutines = ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines(); |         const auto subroutines = | ||||||
|  |             ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines(); | ||||||
|         GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix); |         GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix); | ||||||
|         return ProgramResult{generator.GetShaderCode(), generator.GetEntries()}; |         return ProgramResult{generator.GetShaderCode(), generator.GetEntries()}; | ||||||
|     } catch (const DecompileFail& exception) { |     } catch (const DecompileFail& exception) { | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ GLuint LoadShader(const char* source, GLenum type) { | |||||||
|     default: |     default: | ||||||
|         UNREACHABLE(); |         UNREACHABLE(); | ||||||
|     } |     } | ||||||
|     GLuint shader_id = glCreateShader(type); |     const GLuint shader_id = glCreateShader(type); | ||||||
|     glShaderSource(shader_id, 1, &source, nullptr); |     glShaderSource(shader_id, 1, &source, nullptr); | ||||||
|     LOG_DEBUG(Render_OpenGL, "Compiling {} shader...", debug_type); |     LOG_DEBUG(Render_OpenGL, "Compiling {} shader...", debug_type); | ||||||
|     glCompileShader(shader_id); |     glCompileShader(shader_id); | ||||||
|  | |||||||
| @ -29,7 +29,7 @@ OGLStreamBuffer::OGLStreamBuffer(GLenum target, GLsizeiptr size, bool prefer_coh | |||||||
|     if (GLAD_GL_ARB_buffer_storage) { |     if (GLAD_GL_ARB_buffer_storage) { | ||||||
|         persistent = true; |         persistent = true; | ||||||
|         coherent = prefer_coherent; |         coherent = prefer_coherent; | ||||||
|         GLbitfield flags = |         const GLbitfield flags = | ||||||
|             GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (coherent ? GL_MAP_COHERENT_BIT : 0); |             GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (coherent ? GL_MAP_COHERENT_BIT : 0); | ||||||
|         glBufferStorage(gl_target, allocate_size, nullptr, flags); |         glBufferStorage(gl_target, allocate_size, nullptr, flags); | ||||||
|         mapped_ptr = static_cast<u8*>(glMapBufferRange( |         mapped_ptr = static_cast<u8*>(glMapBufferRange( | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Patrick Elsässer
						Patrick Elsässer