SWVertexLoader.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // Copyright 2009 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "VideoBackends/Software/SWVertexLoader.h"
  4. #include <cstddef>
  5. #include <limits>
  6. #include "Common/Assert.h"
  7. #include "Common/CommonTypes.h"
  8. #include "Common/Logging/Log.h"
  9. #include "Core/System.h"
  10. #include "VideoBackends/Software/NativeVertexFormat.h"
  11. #include "VideoBackends/Software/Rasterizer.h"
  12. #include "VideoBackends/Software/SWRenderer.h"
  13. #include "VideoBackends/Software/Tev.h"
  14. #include "VideoBackends/Software/TransformUnit.h"
  15. #include "VideoCommon/BoundingBox.h"
  16. #include "VideoCommon/CPMemory.h"
  17. #include "VideoCommon/DataReader.h"
  18. #include "VideoCommon/IndexGenerator.h"
  19. #include "VideoCommon/OpcodeDecoding.h"
  20. #include "VideoCommon/PixelShaderManager.h"
  21. #include "VideoCommon/Statistics.h"
  22. #include "VideoCommon/VertexLoaderBase.h"
  23. #include "VideoCommon/VertexLoaderManager.h"
  24. #include "VideoCommon/VertexShaderManager.h"
  25. #include "VideoCommon/VideoConfig.h"
  26. #include "VideoCommon/XFMemory.h"
  27. SWVertexLoader::SWVertexLoader() = default;
  28. SWVertexLoader::~SWVertexLoader() = default;
  29. DataReader SWVertexLoader::PrepareForAdditionalData(OpcodeDecoder::Primitive primitive, u32 count,
  30. u32 stride, bool cullall)
  31. {
  32. // The software renderer needs cullall to be false for zfreeze to work
  33. return VertexManagerBase::PrepareForAdditionalData(primitive, count, stride, false);
  34. }
  35. void SWVertexLoader::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_vertex)
  36. {
  37. using OpcodeDecoder::Primitive;
  38. Primitive primitive_type = Primitive::GX_DRAW_QUADS;
  39. switch (m_current_primitive_type)
  40. {
  41. case PrimitiveType::Points:
  42. primitive_type = Primitive::GX_DRAW_POINTS;
  43. break;
  44. case PrimitiveType::Lines:
  45. primitive_type = Primitive::GX_DRAW_LINES;
  46. break;
  47. case PrimitiveType::Triangles:
  48. primitive_type = Primitive::GX_DRAW_TRIANGLES;
  49. break;
  50. case PrimitiveType::TriangleStrip:
  51. primitive_type = Primitive::GX_DRAW_TRIANGLE_STRIP;
  52. break;
  53. }
  54. // Flush bounding box here because software overrides the base function
  55. if (g_bounding_box->IsEnabled())
  56. g_bounding_box->Flush();
  57. m_setup_unit.Init(primitive_type);
  58. Rasterizer::SetTevKonstColors();
  59. for (u32 i = 0; i < m_index_generator.GetIndexLen(); i++)
  60. {
  61. const u16 index = m_cpu_index_buffer[i];
  62. memset(static_cast<void*>(&m_vertex), 0, sizeof(m_vertex));
  63. // parse the videocommon format to our own struct format (m_vertex)
  64. SetFormat();
  65. ParseVertex(VertexLoaderManager::GetCurrentVertexFormat()->GetVertexDeclaration(), index);
  66. // transform this vertex so that it can be used for rasterization (outVertex)
  67. OutputVertexData* outVertex = m_setup_unit.GetVertex();
  68. TransformUnit::TransformPosition(&m_vertex, outVertex);
  69. TransformUnit::TransformNormal(&m_vertex, outVertex);
  70. TransformUnit::TransformColor(&m_vertex, outVertex);
  71. TransformUnit::TransformTexCoord(&m_vertex, outVertex);
  72. // assemble and rasterize the primitive
  73. m_setup_unit.SetupVertex();
  74. INCSTAT(g_stats.this_frame.num_vertices_loaded);
  75. }
  76. INCSTAT(g_stats.this_frame.num_drawn_objects);
  77. }
  78. void SWVertexLoader::SetFormat()
  79. {
  80. m_vertex.posMtx = xfmem.MatrixIndexA.PosNormalMtxIdx;
  81. m_vertex.texMtx[0] = xfmem.MatrixIndexA.Tex0MtxIdx;
  82. m_vertex.texMtx[1] = xfmem.MatrixIndexA.Tex1MtxIdx;
  83. m_vertex.texMtx[2] = xfmem.MatrixIndexA.Tex2MtxIdx;
  84. m_vertex.texMtx[3] = xfmem.MatrixIndexA.Tex3MtxIdx;
  85. m_vertex.texMtx[4] = xfmem.MatrixIndexB.Tex4MtxIdx;
  86. m_vertex.texMtx[5] = xfmem.MatrixIndexB.Tex5MtxIdx;
  87. m_vertex.texMtx[6] = xfmem.MatrixIndexB.Tex6MtxIdx;
  88. m_vertex.texMtx[7] = xfmem.MatrixIndexB.Tex7MtxIdx;
  89. }
  90. template <typename T, typename I>
  91. static T ReadNormalized(I value)
  92. {
  93. T casted = (T)value;
  94. if (!std::numeric_limits<T>::is_integer && std::numeric_limits<I>::is_integer)
  95. {
  96. // normalize if non-float is converted to a float
  97. casted *= (T)(1.0 / std::numeric_limits<I>::max());
  98. }
  99. return casted;
  100. }
  101. template <typename T, bool swap = false>
  102. static void ReadVertexAttribute(T* dst, DataReader src, const AttributeFormat& format,
  103. int base_component, int components, bool reverse)
  104. {
  105. if (format.enable)
  106. {
  107. src.Skip(format.offset);
  108. src.Skip(base_component * GetElementSize(format.type));
  109. int i;
  110. for (i = 0; i < std::min(format.components - base_component, components); i++)
  111. {
  112. int i_dst = reverse ? components - i - 1 : i;
  113. switch (format.type)
  114. {
  115. case ComponentFormat::UByte:
  116. dst[i_dst] = ReadNormalized<T, u8>(src.Read<u8, swap>());
  117. break;
  118. case ComponentFormat::Byte:
  119. dst[i_dst] = ReadNormalized<T, s8>(src.Read<s8, swap>());
  120. break;
  121. case ComponentFormat::UShort:
  122. dst[i_dst] = ReadNormalized<T, u16>(src.Read<u16, swap>());
  123. break;
  124. case ComponentFormat::Short:
  125. dst[i_dst] = ReadNormalized<T, s16>(src.Read<s16, swap>());
  126. break;
  127. case ComponentFormat::Float:
  128. case ComponentFormat::InvalidFloat5:
  129. case ComponentFormat::InvalidFloat6:
  130. case ComponentFormat::InvalidFloat7:
  131. dst[i_dst] = ReadNormalized<T, float>(src.Read<float, swap>());
  132. break;
  133. }
  134. ASSERT_MSG(VIDEO, !format.integer || (format.type < ComponentFormat::Float),
  135. "only non-float values are allowed to be streamed as integer");
  136. }
  137. for (; i < components; i++)
  138. {
  139. int i_dst = reverse ? components - i - 1 : i;
  140. dst[i_dst] = i == 3;
  141. }
  142. }
  143. }
  144. static void ParseColorAttributes(InputVertexData* dst, DataReader& src,
  145. const PortableVertexDeclaration& vdec)
  146. {
  147. const auto set_default_color = [](std::array<u8, 4>& color) {
  148. color[Tev::ALP_C] = g_ActiveConfig.iMissingColorValue & 0xFF;
  149. color[Tev::BLU_C] = (g_ActiveConfig.iMissingColorValue >> 8) & 0xFF;
  150. color[Tev::GRN_C] = (g_ActiveConfig.iMissingColorValue >> 16) & 0xFF;
  151. color[Tev::RED_C] = (g_ActiveConfig.iMissingColorValue >> 24) & 0xFF;
  152. };
  153. if (vdec.colors[0].enable)
  154. {
  155. // Use color0 for channel 0, and color1 for channel 1 if both colors 0 and 1 are present.
  156. ReadVertexAttribute<u8>(dst->color[0].data(), src, vdec.colors[0], 0, 4, true);
  157. if (vdec.colors[1].enable)
  158. ReadVertexAttribute<u8>(dst->color[1].data(), src, vdec.colors[1], 0, 4, true);
  159. else
  160. set_default_color(dst->color[1]);
  161. }
  162. else
  163. {
  164. // If only one of the color attributes is enabled, it is directed to color 0.
  165. if (vdec.colors[1].enable)
  166. ReadVertexAttribute<u8>(dst->color[0].data(), src, vdec.colors[1], 0, 4, true);
  167. else
  168. set_default_color(dst->color[0]);
  169. set_default_color(dst->color[1]);
  170. }
  171. }
  172. void SWVertexLoader::ParseVertex(const PortableVertexDeclaration& vdec, int index)
  173. {
  174. DataReader src(m_cpu_vertex_buffer.data(),
  175. m_cpu_vertex_buffer.data() + m_cpu_vertex_buffer.size());
  176. src.Skip(index * vdec.stride);
  177. ReadVertexAttribute<float>(&m_vertex.position[0], src, vdec.position, 0, 3, false);
  178. for (std::size_t i = 0; i < m_vertex.normal.size(); i++)
  179. {
  180. ReadVertexAttribute<float>(&m_vertex.normal[i][0], src, vdec.normals[i], 0, 3, false);
  181. }
  182. if (!vdec.normals[0].enable)
  183. {
  184. auto& system = Core::System::GetInstance();
  185. auto& vertex_shader_manager = system.GetVertexShaderManager();
  186. m_vertex.normal[0][0] = vertex_shader_manager.constants.cached_normal[0];
  187. m_vertex.normal[0][1] = vertex_shader_manager.constants.cached_normal[1];
  188. m_vertex.normal[0][2] = vertex_shader_manager.constants.cached_normal[2];
  189. }
  190. if (!vdec.normals[1].enable)
  191. {
  192. auto& system = Core::System::GetInstance();
  193. auto& vertex_shader_manager = system.GetVertexShaderManager();
  194. m_vertex.normal[1][0] = vertex_shader_manager.constants.cached_tangent[0];
  195. m_vertex.normal[1][1] = vertex_shader_manager.constants.cached_tangent[1];
  196. m_vertex.normal[1][2] = vertex_shader_manager.constants.cached_tangent[2];
  197. }
  198. if (!vdec.normals[2].enable)
  199. {
  200. auto& system = Core::System::GetInstance();
  201. auto& vertex_shader_manager = system.GetVertexShaderManager();
  202. m_vertex.normal[2][0] = vertex_shader_manager.constants.cached_binormal[0];
  203. m_vertex.normal[2][1] = vertex_shader_manager.constants.cached_binormal[1];
  204. m_vertex.normal[2][2] = vertex_shader_manager.constants.cached_binormal[2];
  205. }
  206. ParseColorAttributes(&m_vertex, src, vdec);
  207. for (std::size_t i = 0; i < m_vertex.texCoords.size(); i++)
  208. {
  209. ReadVertexAttribute<float>(m_vertex.texCoords[i].data(), src, vdec.texcoords[i], 0, 2, false);
  210. // the texmtr is stored as third component of the texCoord
  211. if (vdec.texcoords[i].components >= 3)
  212. {
  213. ReadVertexAttribute<u8>(&m_vertex.texMtx[i], src, vdec.texcoords[i], 2, 1, false);
  214. }
  215. }
  216. ReadVertexAttribute<u8>(&m_vertex.posMtx, src, vdec.posmtx, 0, 1, false);
  217. }