CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/GPU/Software/TransformUnit.h
Views: 1401
// Copyright (c) 2013- PPSSPP Project.12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0 or later versions.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official git repository and contact information can be found at15// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.1617#pragma once1819#include "CommonTypes.h"20#include "GPU/Common/DrawEngineCommon.h"21#include "GPU/Common/GPUDebugInterface.h"22#include "GPU/Software/SoftGpu.h"23#include "GPU/Math3D.h"2425using namespace Math3D;2627static constexpr int32_t SCREEN_SCALE_FACTOR = 16;2829typedef u16 u10; // TODO: erm... :/3031typedef Vec3<float> ModelCoords;32typedef Vec3<float> WorldCoords;33typedef Vec3<float> ViewCoords;34typedef Vec4<float> ClipCoords; // Range: -w <= x/y/z <= w3536class BinManager;37struct TransformState;3839enum class CullType {40CW = 0,41CCW = 1,42OFF = 2,43};4445struct ScreenCoords46{47ScreenCoords() {}48ScreenCoords(int x, int y, u16 z) : x(x), y(y), z(z) {}4950int x;51int y;52u16 z;5354Vec2<int> xy() const { return Vec2<int>(x, y); }5556ScreenCoords operator * (const float t) const57{58return ScreenCoords((int)(x * t), (int)(y * t), (u16)(z * t));59}6061ScreenCoords operator / (const int t) const62{63return ScreenCoords(x / t, y / t, z / t);64}6566ScreenCoords operator + (const ScreenCoords& oth) const67{68return ScreenCoords(x + oth.x, y + oth.y, z + oth.z);69}70};7172struct DrawingCoords {73DrawingCoords() {}74DrawingCoords(s16 x, s16 y) : x(x), y(y) {}7576s16 x;77s16 y;78};7980struct alignas(16) VertexData {81Vec3Packedf texturecoords;82float clipw;83uint32_t color0;84uint32_t color1;85ScreenCoords screenpos;86float fogdepth;87};8889struct ClipVertexData {90void Lerp(float t, const ClipVertexData &a, const ClipVertexData &b) {91clippos = ::Lerp(a.clippos, b.clippos, t);92// Ignore screenpos because Lerp() is only used pre-calculation of screenpos.93v.texturecoords = ::Lerp(a.v.texturecoords, b.v.texturecoords, t);94v.fogdepth = ::Lerp(a.v.fogdepth, b.v.fogdepth, t);9596u16 t_int = (u16)(t * 256);97v.color0 = LerpInt<Vec4<int>, 256>(Vec4<int>::FromRGBA(a.v.color0), Vec4<int>::FromRGBA(b.v.color0), t_int).ToRGBA();98v.color1 = LerpInt<Vec3<int>, 256>(Vec3<int>::FromRGB(a.v.color1), Vec3<int>::FromRGB(b.v.color1), t_int).ToRGB();99}100101bool OutsideRange() const {102return v.screenpos.x == 0x7FFFFFFF;103}104105ClipCoords clippos;106VertexData v;107};108109class VertexReader;110111class SoftwareDrawEngine;112class SoftwareVertexReader;113114class TransformUnit {115public:116TransformUnit();117~TransformUnit();118119bool IsStarted();120121static WorldCoords ModelToWorldNormal(const ModelCoords& coords);122static WorldCoords ModelToWorld(const ModelCoords& coords);123static ViewCoords WorldToView(const WorldCoords& coords);124static ClipCoords ViewToClip(const ViewCoords& coords);125static ScreenCoords ClipToScreen(const ClipCoords &coords, bool *outsideRangeFlag);126static inline DrawingCoords ScreenToDrawing(int x, int y) {127DrawingCoords ret;128// When offset > coord, this is negative and force-scissors.129ret.x = x / SCREEN_SCALE_FACTOR;130ret.y = y / SCREEN_SCALE_FACTOR;131return ret;132}133static inline DrawingCoords ScreenToDrawing(const ScreenCoords &coords) {134return ScreenToDrawing(coords.x, coords.y);135}136static ScreenCoords DrawingToScreen(const DrawingCoords &coords, u16 z);137138void SubmitPrimitive(const void* vertices, const void* indices, GEPrimitiveType prim_type, int vertex_count, u32 vertex_type, int *bytesRead, SoftwareDrawEngine *drawEngine);139void SubmitImmVertex(const ClipVertexData &vert, SoftwareDrawEngine *drawEngine);140141static bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices);142143void Flush(const char *reason);144void FlushIfOverlap(const char *reason, bool modifying, uint32_t addr, uint32_t stride, uint32_t w, uint32_t h);145void NotifyClutUpdate(const void *src);146147void GetStats(char *buffer, size_t bufsize);148149void SetDirty(SoftDirty flags);150SoftDirty GetDirty();151152private:153ClipVertexData ReadVertex(const VertexReader &vreader, const TransformState &state);154void SendTriangle(CullType cullType, const ClipVertexData *verts, int provoking = 2);155156u8 *decoded_ = nullptr;157BinManager *binner_ = nullptr;158159// Normally max verts per prim is 3, but we temporarily need 4 to detect rectangles from strips.160ClipVertexData data_[4];161// This is the index of the next vert in data (or higher, may need modulus.)162int data_index_ = 0;163GEPrimitiveType prev_prim_ = GE_PRIM_POINTS;164bool hasDraws_ = false;165bool isImmDraw_ = false;166167friend SoftwareVertexReader;168};169170class SoftwareDrawEngine : public DrawEngineCommon {171public:172SoftwareDrawEngine();173~SoftwareDrawEngine();174175void DeviceLost() override {}176void DeviceRestore(Draw::DrawContext *draw) override {}177178void NotifyConfigChanged() override;179void DispatchFlush() override;180void DispatchSubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, bool clockwise, int *bytesRead) override;181void DispatchSubmitImm(GEPrimitiveType prim, TransformedVertex *buffer, int vertexCount, int cullMode, bool continuation) override;182183VertexDecoder *FindVertexDecoder(u32 vtype);184185TransformUnit transformUnit;186187#if PPSSPP_ARCH(32BIT)188#undef new189void *operator new(size_t s) {190return AllocateAlignedMemory(s, 16);191}192void operator delete(void *p) {193FreeAlignedMemory(p);194}195#endif196197protected:198bool UpdateUseHWTessellation(bool enable) const override { return false; }199};200201202