isle-portable/miniwin/src/internal/d3drmrenderer_gxm.h
olebeck 47736862a7
Add PSVita port (#541)
* add psvita to cmake

* no PIE for vita

* add modules to vpk

* use custom pvr apphint

* select correct renderer for sdl renderer

* patch sdl3 shaders, got something on screen!

* use proper cmake patch for sdl

* add missing module

* remove test window which causes a bug in the vita sdl port to show up

* add gxm renderer (not working with display yet)

* avoid sdl renderer for vita, seems broken

* make gxm renderer work with new d3drm

* fix rendering somewhat, some geometry shows up

* support paletted textures directly to avoid copying the texture twice

* fix Draw2DImage

* make 3d work, broken lights

* clean up a bit

* fix normals matrix

* remove some unneeded changes

* forgot env var

* wrong env dest

* run clang format

* correct texture address mode, use tlsf instead of sceClibMspace

* double buffered uniforms seem to work now

* missed a line

* update GXMRenderer_EnumDevice

* hopefully actually fix uniform buffers

* run clang-format

* remove a change thats not needed

* improve fragment shader performance

* add vita to dist folder

* add base for vita config app

* add config self to vpk

* transform touch events to virtual size

* add livearea graphics

* Update cmake file to include livearea assets

* put manual in the right place

* add sample rco

* add messagebox on vita

* triple buffer textures because fences arent a thing on vita and making draw&cpu sync would be too slow

* make config app not crash on launch

* change defaults

* update gxm renderer with interface changes

* split 2d and 3d shaders completely

* update gxm renderer

* fix transition on gxm

* clang format

* move config cmake

* move CONFIG_vita

* always clear before drawing 2d image

* hopefully fix windows build

* clang-format fix broken includes

* order again

* undo moving qt cmake to its own list

* move uic search path

* use ifdefs for all d3drm backends, cpack to generate vpk

* cmake wrong escape

* small cleanups in gxm renderer

* defer texture delete to avoid overwriting the texture during a frame

* clang-format

* more of the layout for config

* remove top buttons

* use SceAppSettings instead of custom ui

* use select for back to info center on vita, to make screenshots possible again

* remove accidentally left in add_subdirectory

* adjust diskpath to be like other ports

* use vita_create_vpk and not cpack

* gxm: msaa support, fix wrong file path

* gxm: add mipmaps (disabled)

* clang-format

* fix open isle.ini with fopen

* add missing strings

* use iniparser_set not dictionary_set

* add default save path to config

* load config app after initializing ini on vita

* fix config build

* change the default disk & cd path, update the paf library

* update paf library headers

* include orders for clang-format

* clean up

* make shader compiler not required

* move asm language

* warn instead of error when shader source is changed when no compiler is found

---------

Co-authored-by: Li <li@silica.codes>
Co-authored-by: Christian Semmler <mail@csemmler.com>
2025-10-31 23:23:12 +00:00

182 lines
5.4 KiB
C++

#pragma once
#include "../d3drm/backends/gxm/gxm_context.h"
#include "d3drmrenderer.h"
#include "d3drmtexture_impl.h"
#include "ddpalette_impl.h"
#include "ddraw_impl.h"
#include <SDL3/SDL.h>
#include <psp2/gxm.h>
#include <psp2/kernel/clib.h>
#include <psp2/types.h>
#include <vector>
DEFINE_GUID(GXM_GUID, 0x682656F3, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x58, 0x4D);
#define GXM_VERTEX_BUFFER_COUNT 2
#define GXM_FRAGMENT_BUFFER_COUNT 3
#define GXM_WITH_RAZOR DEBUG
struct GXMTextureCacheEntry {
IDirect3DRMTexture* texture;
Uint32 version;
SceGxmTexture gxmTexture;
SceGxmNotification* notification; // latest frame it was used in
};
struct GXMMeshCacheEntry {
const MeshGroup* meshGroup;
int version;
bool flat;
void* meshData;
void* vertexBuffer;
void* indexBuffer;
uint16_t indexCount;
};
struct SceneLightGXM {
float color[4];
float vec[4];
float isDirectional;
float _align;
};
struct GXMSceneLightUniform {
SceneLightGXM lights[2];
float ambientLight[3];
};
class GXMRenderer : public Direct3DRMRenderer {
public:
static Direct3DRMRenderer* Create(DWORD width, DWORD height, DWORD msaaSamples);
GXMRenderer(DWORD width, DWORD height, SceGxmMultisampleMode msaaMode);
~GXMRenderer() override;
void PushLights(const SceneLight* lightsArray, size_t count) override;
void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override;
void SetFrustumPlanes(const Plane* frustumPlanes) override;
Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUi, float scaleX, float scaleY) override;
Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override;
HRESULT BeginFrame() override;
void EnableTransparency() override;
void SubmitDraw(
DWORD meshId,
const D3DRMMATRIX4D& modelViewMatrix,
const D3DRMMATRIX4D& worldMatrix,
const D3DRMMATRIX4D& viewMatrix,
const Matrix3x3& normalMatrix,
const Appearance& appearance
) override;
HRESULT FinalizeFrame() override;
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
void Clear(float r, float g, float b) override;
void Flip() override;
void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override;
void Download(SDL_Surface* target) override;
void SetDither(bool dither) override;
void DeferredDelete(int index);
private:
void AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture);
void AddMeshDestroyCallback(Uint32 id, IDirect3DRMMesh* mesh);
GXMMeshCacheEntry GXMUploadMesh(const MeshGroup& meshGroup);
void StartScene();
const SceGxmTexture* UseTexture(GXMTextureCacheEntry& texture);
inline GXMVertex2D* QuadVerticesBuffer()
{
GXMVertex2D* verts = &this->quadVertices[this->currentVertexBufferIndex][this->quadsUsed * 4];
this->quadsUsed += 1;
if (this->quadsUsed >= 50) {
SDL_Log("QuadVerticesBuffer overflow");
this->quadsUsed = 0; // declare bankruptcy
}
return verts;
}
inline GXMSceneLightUniform* LightsBuffer() { return this->lights[this->currentFragmentBufferIndex]; }
std::vector<GXMTextureCacheEntry> m_textures;
std::vector<GXMMeshCacheEntry> m_meshes;
D3DRMMATRIX4D m_projection;
std::vector<SceneLight> m_lights;
std::vector<SceGxmTexture> m_textures_delete[GXM_FRAGMENT_BUFFER_COUNT];
std::vector<void*> m_buffers_delete[GXM_FRAGMENT_BUFFER_COUNT];
bool transparencyEnabled = false;
// shader
SceGxmShaderPatcherId mainVertexProgramId;
SceGxmShaderPatcherId mainColorFragmentProgramId;
SceGxmShaderPatcherId mainTextureFragmentProgramId;
SceGxmVertexProgram* mainVertexProgram;
SceGxmFragmentProgram* opaqueColorFragmentProgram;
SceGxmFragmentProgram* blendedColorFragmentProgram;
SceGxmFragmentProgram* opaqueTextureFragmentProgram;
SceGxmFragmentProgram* blendedTextureFragmentProgram;
// main shader vertex uniforms
const SceGxmProgramParameter* uModelViewMatrix;
const SceGxmProgramParameter* uNormalMatrix;
const SceGxmProgramParameter* uProjectionMatrix;
// main shader fragment uniforms
const SceGxmProgramParameter* uShininess;
const SceGxmProgramParameter* uColor;
const SceGxmProgramParameter* uLights;
const SceGxmProgramParameter* uAmbientLight;
// uniforms / quad meshes
GXMSceneLightUniform* lights[GXM_FRAGMENT_BUFFER_COUNT];
GXMVertex2D* quadVertices[GXM_VERTEX_BUFFER_COUNT];
uint16_t* quadIndices;
int quadsUsed = 0;
bool cleared = false;
SceGxmNotification vertexNotifications[GXM_VERTEX_BUFFER_COUNT];
SceGxmNotification fragmentNotifications[GXM_FRAGMENT_BUFFER_COUNT];
int currentFragmentBufferIndex = 0;
int currentVertexBufferIndex = 0;
#ifdef GXM_WITH_RAZOR
bool last_dpad_up;
bool last_dpad_down;
bool last_dpad_left;
bool last_dpad_right;
#endif
bool m_initialized = false;
};
int gxm_library_init();
inline static void GXMRenderer_EnumDevice(LPD3DENUMDEVICESCALLBACK cb, void* ctx)
{
D3DDEVICEDESC halDesc = {};
halDesc.dcmColorModel = D3DCOLORMODEL::RGB;
halDesc.dwFlags = D3DDD_DEVICEZBUFFERBITDEPTH;
halDesc.dwDeviceZBufferBitDepth = DDBD_16;
halDesc.dwDeviceZBufferBitDepth |= DDBD_32;
halDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE;
halDesc.dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND;
halDesc.dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR;
D3DDEVICEDESC helDesc = {};
helDesc.dwDeviceRenderBitDepth = DDBD_32;
int ret = gxm_library_init();
if (ret < 0) {
SDL_Log("gxm_library_init failed: %08x", ret);
return;
}
EnumDevice(cb, ctx, "GXM HAL", &halDesc, &helDesc, GXM_GUID);
}