avoid sdl renderer for vita, seems broken

This commit is contained in:
olebeck 2025-06-25 21:40:17 +02:00
parent b38091ba1b
commit d0020a3b9a
23 changed files with 863 additions and 144 deletions

View File

@ -71,7 +71,7 @@ if(VITA)
set(CMAKE_POSITION_INDEPENDENT_CODE OFF) set(CMAKE_POSITION_INDEPENDENT_CODE OFF)
set(ISLE_DEBUG OFF) set(ISLE_DEBUG OFF)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules")
set(VITA_USE_OPENGLES2 ON) #set(VITA_USE_OPENGLES2 ON)
endif() endif()
if(VITA_USE_OPENGLES2) if(VITA_USE_OPENGLES2)

View File

@ -18,7 +18,8 @@
"name": "debug", "name": "debug",
"inherits": ["release"], "inherits": ["release"],
"cacheVariables": { "cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug" "CMAKE_BUILD_TYPE": "Debug",
"ISLE_BUILD_CONFIG": false
} }
}, },

View File

@ -52,6 +52,7 @@
#ifdef __vita__ #ifdef __vita__
#include <SDL3/SDL_gxm.h> #include <SDL3/SDL_gxm.h>
#define USE_GXM
#endif #endif
#if defined(__vita__) && defined(USE_OPENGLES2) #if defined(__vita__) && defined(USE_OPENGLES2)
@ -724,7 +725,9 @@ MxResult IsleApp::SetupWindow()
(HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); (HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
#endif #endif
#if defined(__vita__) && defined(USE_OPENGLES2)
DDWindow = window; DDWindow = window;
#endif
SDL_DestroyProperties(props); SDL_DestroyProperties(props);

View File

@ -9,7 +9,6 @@ add_library(miniwin STATIC EXCLUDE_FROM_ALL
src/ddraw/ddpalette.cpp src/ddraw/ddpalette.cpp
src/ddraw/ddraw.cpp src/ddraw/ddraw.cpp
src/ddraw/ddsurface.cpp src/ddraw/ddsurface.cpp
src/ddraw/framebuffer.cpp
# D3DRM # D3DRM
src/d3drm/d3drm.cpp src/d3drm/d3drm.cpp
@ -22,11 +21,22 @@ add_library(miniwin STATIC EXCLUDE_FROM_ALL
src/internal/meshutils.cpp src/internal/meshutils.cpp
# D3DRM backends # D3DRM backends
src/d3drm/backends/sdl3gpu/renderer.cpp
src/d3drm/backends/sdl3gpu/shaders/generated/ShaderIndex.cpp
src/d3drm/backends/software/renderer.cpp src/d3drm/backends/software/renderer.cpp
) )
if(VITA)
target_sources(miniwin PRIVATE
src/ddraw/framebuffer_vita.cpp
)
else()
target_sources(miniwin PRIVATE
src/ddraw/framebuffer.cpp
src/d3drm/backends/sdl3gpu/renderer.cpp
src/d3drm/backends/sdl3gpu/shaders/generated/ShaderIndex.cpp
)
endif()
find_package(OpenGL) find_package(OpenGL)
find_package(GLEW) find_package(GLEW)
if(OpenGL_FOUND AND GLEW_FOUND) if(OpenGL_FOUND AND GLEW_FOUND)

View File

@ -1,4 +1,8 @@
all: main.frag.gxp main.vert.gxp clear.frag.gxp clear.vert.gxp shaders += main.frag.gxp main.vert.gxp
shaders += clear.frag.gxp clear.vert.gxp
shaders += blit.color.frag.gxp blit.tex.frag.gxp blit.vert.gxp
all: $(shaders)
%.vert.gxp: %.vert.cg %.vert.gxp: %.vert.cg
./psp2cgc.exe -Wperf -profile sce_vp_psp2 $< -o $@ ./psp2cgc.exe -Wperf -profile sce_vp_psp2 $< -o $@

View File

@ -0,0 +1,11 @@
void main(
float4 vPosition : POSITION,
float2 vTexCoord : TEXCOORD0,
uniform float4 uColor,
uniform int uUseTexture,
out float4 outColor : COLOR
) {
outColor = uColor;
}

Binary file not shown.

View File

@ -0,0 +1,12 @@
void main(
float4 vPosition : POSITION,
float2 vTexCoord : TEXCOORD0,
uniform float4x4 uTexMatrix,
uniform sampler2D uTexture,
out float4 outColor : COLOR
) {
float2 samplingCoord = mul(uTexMatrix, float4(vTexCoord, 0, 1)).xy;
outColor = tex2D(uTexture, samplingCoord);
}

Binary file not shown.

View File

@ -0,0 +1,12 @@
void main(
float2 aPosition : POSITION,
float2 aTexCoord : TEXCOORD0,
uniform float4x4 uScreenMatrix,
out float4 vPosition : POSITION,
out float2 vTexCoord : TEXCOORD0
) {
vPosition = mul(uScreenMatrix, float4(aPosition, 0, 1));
vTexCoord = aTexCoord;
}

Binary file not shown.

View File

@ -63,62 +63,65 @@ INCBIN("main.vert.gxp", main_vert_gxp_start);
INCBIN("main.frag.gxp", main_frag_gxp_start); INCBIN("main.frag.gxp", main_frag_gxp_start);
INCBIN("clear.vert.gxp", clear_vert_gxp_start); INCBIN("clear.vert.gxp", clear_vert_gxp_start);
INCBIN("clear.frag.gxp", clear_frag_gxp_start); INCBIN("clear.frag.gxp", clear_frag_gxp_start);
INCBIN("blit.vert.gxp", blit_vert_gxp_start);
INCBIN("blit.color.frag.gxp", blit_color_frag_gxp_start);
INCBIN("blit.tex.frag.gxp", blit_tex_frag_gxp_start);
const SceGxmProgram* clearVertexProgramGxp = (const SceGxmProgram*)&clear_vert_gxp_start; const SceGxmProgram* clearVertexProgramGxp = (const SceGxmProgram*)&clear_vert_gxp_start;
const SceGxmProgram* clearFragmentProgramGxp = (const SceGxmProgram*)&clear_frag_gxp_start; const SceGxmProgram* clearFragmentProgramGxp = (const SceGxmProgram*)&clear_frag_gxp_start;
const SceGxmProgram* mainVertexProgramGxp = (const SceGxmProgram*)&main_vert_gxp_start; const SceGxmProgram* mainVertexProgramGxp = (const SceGxmProgram*)&main_vert_gxp_start;
const SceGxmProgram* mainFragmentProgramGxp = (const SceGxmProgram*)&main_frag_gxp_start; const SceGxmProgram* mainFragmentProgramGxp = (const SceGxmProgram*)&main_frag_gxp_start;
const SceGxmProgram* blitVertexProgramGxp = (const SceGxmProgram*)&blit_vert_gxp_start;
const SceGxmProgram* blitColorFragmentProgramGxp = (const SceGxmProgram*)&blit_color_frag_gxp_start;
static const size_t clearMeshVerticiesSize = 3 * sizeof(float)*2; const SceGxmProgram* blitTexFragmentProgramGxp = (const SceGxmProgram*)&blit_tex_frag_gxp_start;
static const size_t clearMeshIndiciesSize = 3 * sizeof(uint16_t);
extern "C" int sceRazorGpuCaptureSetTrigger(int frames, const char* path); extern "C" int sceRazorGpuCaptureSetTrigger(int frames, const char* path);
extern "C" int sceRazorGpuCaptureEnableSalvage(const char* path); extern "C" int sceRazorGpuCaptureEnableSalvage(const char* path);
extern "C" int sceRazorGpuCaptureSetTriggerNextFrame(const char* path); extern "C" int sceRazorGpuCaptureSetTriggerNextFrame(const char* path);
static GXMRendererContext gxm_renderer_context;
#define GET_SHADER_PARAM(var, gxp, name) \ bool gxm_init() {
const SceGxmProgramParameter* var = sceGxmProgramFindParameterByName(gxp, name); \ if(SDL_gxm_is_init()) {
if(!var) { \ return true;
SDL_Log("Failed to find param %s", name); \
return false; \
} }
static bool create_gxm_renderer(int width, int height, GXMRendererData* data) { SDL_gxm_init();
const unsigned int alignedWidth = ALIGN(width, SCE_GXM_TILE_SIZEX);
const unsigned int alignedHeight = ALIGN(height, SCE_GXM_TILE_SIZEY);
unsigned int sampleCount = alignedWidth * alignedHeight; /*
unsigned int depthStrideInSamples = alignedWidth; SceGxmInitializeParams initializeParams;
SDL_memset(&initializeParams, 0, sizeof(SceGxmInitializeParams));
initializeParams.flags = 0;
initializeParams.displayQueueMaxPendingCount = VITA_GXM_PENDING_SWAPS;
initializeParams.displayQueueCallback = display_callback;
initializeParams.displayQueueCallbackDataSize = sizeof(GXMDisplayData);
initializeParams.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE;
int err = sceGxmInitialize(&initializeParams);
if (err != 0) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "gxm init failed: %d", err);
return err;
}
*/
return true;
}
static bool create_gxm_context() {
GXMRendererContext* data = &gxm_renderer_context;
if(data->context) {
return true;
}
if(!gxm_init()) {
return false;
}
const unsigned int patcherBufferSize = 64 * 1024; const unsigned int patcherBufferSize = 64 * 1024;
const unsigned int patcherVertexUsseSize = 64 * 1024; const unsigned int patcherVertexUsseSize = 64 * 1024;
const unsigned int patcherFragmentUsseSize = 64 * 1024; const unsigned int patcherFragmentUsseSize = 64 * 1024;
static const SceGxmBlendInfo blendInfoOpaque = {
.colorMask = SCE_GXM_COLOR_MASK_ALL,
.colorFunc = SCE_GXM_BLEND_FUNC_NONE,
.alphaFunc = SCE_GXM_BLEND_FUNC_NONE,
.colorSrc = SCE_GXM_BLEND_FACTOR_ZERO,
.colorDst = SCE_GXM_BLEND_FACTOR_ZERO,
.alphaSrc = SCE_GXM_BLEND_FACTOR_ZERO,
.alphaDst = SCE_GXM_BLEND_FACTOR_ZERO,
};
static const SceGxmBlendInfo blendInfoTransparent = {
.colorMask = SCE_GXM_COLOR_MASK_ALL,
.colorFunc = SCE_GXM_BLEND_FUNC_ADD,
.alphaFunc = SCE_GXM_BLEND_FUNC_ADD,
.colorSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA,
.colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.alphaSrc = SCE_GXM_BLEND_FACTOR_ONE,
.alphaDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
};
data->cdramPool = SDL_gxm_get_cdramPool(); data->cdramPool = SDL_gxm_get_cdramPool();
if(!data->cdramPool) { if(!data->cdramPool) {
SDL_Log("failed to allocate cdramPool"); SDL_Log("failed to allocate cdramPool");
@ -225,7 +228,62 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
if(SCE_ERR(sceGxmShaderPatcherCreate, &patcherParams, &data->shaderPatcher)) { if(SCE_ERR(sceGxmShaderPatcherCreate, &patcherParams, &data->shaderPatcher)) {
return false; return false;
} }
return true;
}
static void destroy_gxm_context() {
sceGxmShaderPatcherDestroy(gxm_renderer_context.shaderPatcher);
sceGxmDestroyContext(gxm_renderer_context.context);
vita_mem_fragment_usse_free(gxm_renderer_context.fragmentUsseRingBufferUid);
vita_mem_free(gxm_renderer_context.fragmentRingBufferUid);
vita_mem_free(gxm_renderer_context.vertexRingBufferUid);
vita_mem_free(gxm_renderer_context.vdmRingBufferUid);
SDL_free(gxm_renderer_context.contextHostMem);
}
bool get_gxm_context(SceGxmContext** context, SceGxmShaderPatcher** shaderPatcher, SceClibMspace* cdramPool) {
if(!create_gxm_context()) {
return false;
}
*context = gxm_renderer_context.context;
*shaderPatcher = gxm_renderer_context.shaderPatcher;
*cdramPool = gxm_renderer_context.cdramPool;
return true;
}
static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
const unsigned int alignedWidth = ALIGN(width, SCE_GXM_TILE_SIZEX);
const unsigned int alignedHeight = ALIGN(height, SCE_GXM_TILE_SIZEY);
unsigned int sampleCount = alignedWidth * alignedHeight;
unsigned int depthStrideInSamples = alignedWidth;
if(!get_gxm_context(&data->context, &data->shaderPatcher, &data->cdramPool)) {
return false;
}
static const SceGxmBlendInfo blendInfoOpaque = {
.colorMask = SCE_GXM_COLOR_MASK_ALL,
.colorFunc = SCE_GXM_BLEND_FUNC_NONE,
.alphaFunc = SCE_GXM_BLEND_FUNC_NONE,
.colorSrc = SCE_GXM_BLEND_FACTOR_ZERO,
.colorDst = SCE_GXM_BLEND_FACTOR_ZERO,
.alphaSrc = SCE_GXM_BLEND_FACTOR_ZERO,
.alphaDst = SCE_GXM_BLEND_FACTOR_ZERO,
};
static const SceGxmBlendInfo blendInfoTransparent = {
.colorMask = SCE_GXM_COLOR_MASK_ALL,
.colorFunc = SCE_GXM_BLEND_FUNC_ADD,
.alphaFunc = SCE_GXM_BLEND_FUNC_ADD,
.colorSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA,
.colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.alphaSrc = SCE_GXM_BLEND_FACTOR_ONE,
.alphaDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
};
/*
// render target // render target
SceGxmRenderTargetParams renderTargetParams; SceGxmRenderTargetParams renderTargetParams;
memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams)); memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams));
@ -265,6 +323,7 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
if(SCE_ERR(sceGxmSyncObjectCreate, &data->renderBufferSync)) { if(SCE_ERR(sceGxmSyncObjectCreate, &data->renderBufferSync)) {
return false; return false;
} }
*/
// depth & stencil // depth & stencil
@ -308,7 +367,7 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, clearFragmentProgramGxp, &data->clearFragmentProgramId)) { if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, clearFragmentProgramGxp, &data->clearFragmentProgramId)) {
return false; return false;
} }
GET_SHADER_PARAM(positionAttribute, clearVertexProgramGxp, "aPosition"); GET_SHADER_PARAM(positionAttribute, clearVertexProgramGxp, "aPosition", false);
SceGxmVertexAttribute vertexAttributes[1]; SceGxmVertexAttribute vertexAttributes[1];
SceGxmVertexStream vertexStreams[1]; SceGxmVertexStream vertexStreams[1];
@ -352,9 +411,9 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
return false; return false;
} }
GET_SHADER_PARAM(positionAttribute, mainVertexProgramGxp, "aPosition"); GET_SHADER_PARAM(positionAttribute, mainVertexProgramGxp, "aPosition", false);
GET_SHADER_PARAM(normalAttribute, mainVertexProgramGxp, "aNormal"); GET_SHADER_PARAM(normalAttribute, mainVertexProgramGxp, "aNormal", false);
GET_SHADER_PARAM(texCoordAttribute, mainVertexProgramGxp, "aTexCoord"); GET_SHADER_PARAM(texCoordAttribute, mainVertexProgramGxp, "aTexCoord", false);
SceGxmVertexAttribute vertexAttributes[3]; SceGxmVertexAttribute vertexAttributes[3];
SceGxmVertexStream vertexStreams[1]; SceGxmVertexStream vertexStreams[1];
@ -415,6 +474,8 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
// clear mesh // clear mesh
const size_t clearMeshVerticiesSize = 3 * sizeof(float)*2;
const size_t clearMeshIndiciesSize = 3 * sizeof(uint16_t);
data->clearMeshBuffer = sceClibMspaceMalloc(data->cdramPool, clearMeshVerticiesSize + clearMeshIndiciesSize); data->clearMeshBuffer = sceClibMspaceMalloc(data->cdramPool, clearMeshVerticiesSize + clearMeshIndiciesSize);
data->clearVerticies = (float*)data->clearMeshBuffer; data->clearVerticies = (float*)data->clearMeshBuffer;
data->clearIndicies = (uint16_t*)((uint8_t*)(data->clearMeshBuffer)+clearMeshVerticiesSize); data->clearIndicies = (uint16_t*)((uint8_t*)(data->clearMeshBuffer)+clearMeshVerticiesSize);
@ -434,18 +495,6 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
data->lightDataBuffer = sceClibMspaceMalloc(data->cdramPool, data->lightDataBuffer = sceClibMspaceMalloc(data->cdramPool,
3 * sizeof(SceneLightGXM) + 4 // 3 lights + light count 3 * sizeof(SceneLightGXM) + 4 // 3 lights + light count
); );
sceGxmSetFragmentUniformBuffer(data->context, 0, data->lightDataBuffer);
sceGxmSetFrontStencilRef(data->context, 1);
sceGxmSetFrontStencilFunc(
data->context,
SCE_GXM_STENCIL_FUNC_ALWAYS,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
0xFF,
0xFF
);
return true; return true;
} }
@ -486,34 +535,20 @@ extern "C" void load_razor() {
} }
} }
Direct3DRMRenderer* GXMRenderer::Create(IDirectDrawSurface* surface)
{
DDSURFACEDESC DDSDesc;
DDSDesc.dwSize = sizeof(DDSURFACEDESC);
surface->GetSurfaceDesc(&DDSDesc);
int width = DDSDesc.dwWidth;
int height = DDSDesc.dwHeight;
bool gxm_init() { FrameBufferImpl* frameBuffer = static_cast<FrameBufferImpl*>(surface);
if(SDL_gxm_is_init()) { if(!frameBuffer) {
return true; SDL_Log("cant create with something that isnt a framebuffer");
return nullptr;
} }
SDL_gxm_init();
/*
SceGxmInitializeParams initializeParams;
SDL_memset(&initializeParams, 0, sizeof(SceGxmInitializeParams));
initializeParams.flags = 0;
initializeParams.displayQueueMaxPendingCount = VITA_GXM_PENDING_SWAPS;
initializeParams.displayQueueCallback = display_callback;
initializeParams.displayQueueCallbackDataSize = sizeof(GXMDisplayData);
initializeParams.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE;
int err = sceGxmInitialize(&initializeParams);
if (err != 0) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "gxm init failed: %d", err);
return err;
}
*/
return true;
}
Direct3DRMRenderer* GXMRenderer::Create(DWORD width, DWORD height)
{
SDL_Log("GXMRenderer::Create width=%d height=%d", width, height); SDL_Log("GXMRenderer::Create width=%d height=%d", width, height);
bool success = gxm_init(); bool success = gxm_init();
@ -526,6 +561,7 @@ Direct3DRMRenderer* GXMRenderer::Create(DWORD width, DWORD height)
if(!success) { if(!success) {
return nullptr; return nullptr;
} }
gxm_data.frameBuffer = frameBuffer;
return new GXMRenderer(width, height, gxm_data); return new GXMRenderer(width, height, gxm_data);
} }
@ -541,23 +577,17 @@ GXMRenderer::~GXMRenderer() {
if(!m_initialized) { if(!m_initialized) {
return; return;
} }
sceGxmShaderPatcherDestroy(this->m_data.shaderPatcher);
sceGxmDestroyRenderTarget(this->m_data.renderTarget);
/*
sceGxmDestroyRenderTarget(this->m_data.renderTarget);
vita_mem_free(this->m_data.renderBufferUid); vita_mem_free(this->m_data.renderBufferUid);
sceGxmSyncObjectDestroy(this->m_data.renderBufferSync); sceGxmSyncObjectDestroy(this->m_data.renderBufferSync);
*/
vita_mem_free(this->m_data.depthBufferUid); vita_mem_free(this->m_data.depthBufferUid);
this->m_data.depthBufferData = nullptr; this->m_data.depthBufferData = nullptr;
vita_mem_free(this->m_data.stencilBufferUid); vita_mem_free(this->m_data.stencilBufferUid);
this->m_data.stencilBufferData = nullptr; this->m_data.stencilBufferData = nullptr;
sceGxmDestroyContext(this->m_data.context);
vita_mem_fragment_usse_free(this->m_data.fragmentUsseRingBufferUid);
vita_mem_free(this->m_data.fragmentRingBufferUid);
vita_mem_free(this->m_data.vertexRingBufferUid);
vita_mem_free(this->m_data.vdmRingBufferUid);
SDL_free(this->m_data.contextHostMem);
} }
void* GXMRenderer::AllocateGpu(size_t size, size_t align) { void* GXMRenderer::AllocateGpu(size_t size, size_t align) {
@ -811,19 +841,39 @@ HRESULT GXMRenderer::BeginFrame()
razor_triggered = true; razor_triggered = true;
} }
SceGxmRenderTarget* renderTarget = this->m_data.frameBuffer->GetRenderTarget();
GXMDisplayBuffer* backBuffer = this->m_data.frameBuffer->backBuffer();
sceGxmBeginScene( sceGxmBeginScene(
this->m_data.context, this->m_data.context,
0, 0,
this->m_data.renderTarget, renderTarget,
//this->m_data.renderTarget,
nullptr, nullptr,
nullptr, nullptr,
this->m_data.renderBufferSync, backBuffer->sync,
&this->m_data.renderSurface, &backBuffer->surface,
//this->m_data.renderBufferSync,
//&this->m_data.renderSurface,
&this->m_data.depthSurface &this->m_data.depthSurface
); );
sceGxmSetViewport(this->m_data.context, 0, m_width, 0, m_height, 0, 0); sceGxmSetViewport(this->m_data.context, 0, m_width, 0, m_height, 0, 0);
sceGxmSetFragmentUniformBuffer(this->m_data.context, 0, this->m_data.lightDataBuffer);
sceGxmSetFrontStencilRef(this->m_data.context, 1);
sceGxmSetFrontStencilFunc(
this->m_data.context,
SCE_GXM_STENCIL_FUNC_ALWAYS,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
0xFF,
0xFF
);
sceGxmSetFrontDepthFunc(this->m_data.context, SCE_GXM_DEPTH_FUNC_ALWAYS);
// clear screen // clear screen
sceGxmSetVertexProgram(this->m_data.context, this->m_data.clearVertexProgram); sceGxmSetVertexProgram(this->m_data.context, this->m_data.clearVertexProgram);
sceGxmSetFragmentProgram(this->m_data.context, this->m_data.clearFragmentProgram); sceGxmSetFragmentProgram(this->m_data.context, this->m_data.clearFragmentProgram);
@ -871,13 +921,6 @@ void GXMRenderer::EnableTransparency()
sceGxmSetFragmentProgram(this->m_data.context, this->m_data.transparentFragmentProgram); sceGxmSetFragmentProgram(this->m_data.context, this->m_data.transparentFragmentProgram);
} }
#define SET_UNIFORM(buffer, param, value) \
do { \
size_t __offset = sceGxmProgramParameterGetResourceIndex(param); \
void* __dst = (uint8_t*)(buffer) + (__offset * sizeof(uint32_t)); \
memcpy(__dst, reinterpret_cast<const void*>(&(value)), sizeof(value)); \
} while (0)
void TransposeD3DRMMATRIX4D(const D3DRMMATRIX4D input, D3DRMMATRIX4D output) { void TransposeD3DRMMATRIX4D(const D3DRMMATRIX4D input, D3DRMMATRIX4D output) {
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) { for (int j = 0; j < 4; ++j) {
@ -937,12 +980,14 @@ HRESULT GXMRenderer::FinalizeFrame()
nullptr, nullptr nullptr, nullptr
); );
/*
SDL_Surface* renderedImage = SDL_CreateSurfaceFrom( SDL_Surface* renderedImage = SDL_CreateSurfaceFrom(
m_width, m_height, SDL_PIXELFORMAT_ABGR8888, m_width, m_height, SDL_PIXELFORMAT_ABGR8888,
this->m_data.renderBuffer, this->m_width*4 this->m_data.renderBuffer, this->m_width*4
); );
SDL_BlitSurface(renderedImage, nullptr, DDBackBuffer, nullptr); SDL_BlitSurface(renderedImage, nullptr, DDBackBuffer, nullptr);
SDL_DestroySurface(renderedImage); SDL_DestroySurface(renderedImage);
*/
return DD_OK; return DD_OK;
} }

View File

@ -1,17 +1,17 @@
#pragma once #pragma once
#include <SDL3/SDL_log.h> #include <SDL3/SDL_log.h>
#include <psp2/gxm.h>
#include <psp2/kernel/clib.h>
static bool _sce_err(const char* expr, int err) { #define SCE_ERR(func, ...) ({ \
if(err >= 0) { sceClibPrintf(#func "\n"); \
SDL_Log("sce: %s", expr); int __sce_err_ret_val = func(__VA_ARGS__); \
return false; if (__sce_err_ret_val < 0) { \
} sceClibPrintf(#func " error: 0x%x\n", __sce_err_ret_val); \
SDL_Log("SCE_ERR: %s failed 0x%x", expr, err); } \
return true; __sce_err_ret_val < 0; \
} })
#define SCE_ERR(func, ...) _sce_err(#func, func(__VA_ARGS__))
#define ALIGN(x, a) (((x) + ((a)-1)) & ~((a)-1)) #define ALIGN(x, a) (((x) + ((a)-1)) & ~((a)-1))
@ -22,3 +22,24 @@ static bool _sce_err(const char* expr, int err) {
".incbin \"" filename "\"" \ ".incbin \"" filename "\"" \
); \ ); \
extern const void* symbol extern const void* symbol
#define SET_UNIFORM(buffer, param, value) \
do { \
size_t __offset = sceGxmProgramParameterGetResourceIndex(param); \
void* __dst = (uint8_t*)(buffer) + (__offset * sizeof(uint32_t)); \
memcpy(__dst, reinterpret_cast<const void*>(&(value)), sizeof(value)); \
} while (0)
#define GET_SHADER_PARAM(var, gxp, name, ret) \
const SceGxmProgramParameter* var = sceGxmProgramFindParameterByName(gxp, name); \
if(!var) { \
SDL_Log("Failed to find param %s", name); \
return ret; \
}
extern const SceGxmProgram* blitVertexProgramGxp;
extern const SceGxmProgram* blitColorFragmentProgramGxp;
extern const SceGxmProgram* blitTexFragmentProgramGxp;
bool get_gxm_context(SceGxmContext** context, SceGxmShaderPatcher** shaderPatcher, SceClibMspace* cdramPool);

View File

@ -147,9 +147,13 @@ HRESULT Direct3DRMImpl::CreateDeviceFromSurface(
surface->GetSurfaceDesc(&DDSDesc); surface->GetSurfaceDesc(&DDSDesc);
Direct3DRMRenderer* renderer; Direct3DRMRenderer* renderer;
if (SDL_memcmp(&guid, &SDL3_GPU_GUID, sizeof(GUID)) == 0) {
if(false) {}
#ifndef __vita__
else if (SDL_memcmp(&guid, &SDL3_GPU_GUID, sizeof(GUID)) == 0) {
renderer = Direct3DRMSDL3GPURenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); renderer = Direct3DRMSDL3GPURenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight);
} }
#endif
else if (SDL_memcmp(&guid, &SOFTWARE_GUID, sizeof(GUID)) == 0) { else if (SDL_memcmp(&guid, &SOFTWARE_GUID, sizeof(GUID)) == 0) {
renderer = new Direct3DRMSoftwareRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight); renderer = new Direct3DRMSoftwareRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight);
} }
@ -170,7 +174,7 @@ HRESULT Direct3DRMImpl::CreateDeviceFromSurface(
#endif #endif
#ifdef __vita__ #ifdef __vita__
else if (SDL_memcmp(&guid, &GXM_GUID, sizeof(GUID)) == 0) { else if (SDL_memcmp(&guid, &GXM_GUID, sizeof(GUID)) == 0) {
renderer = GXMRenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); renderer = GXMRenderer::Create(surface);
} }
#endif #endif
else { else {

View File

@ -349,17 +349,14 @@ HRESULT Direct3DRMViewportImpl::ForceUpdate(int x, int y, int w, int h)
HRESULT Direct3DRMViewportImpl::Clear() HRESULT Direct3DRMViewportImpl::Clear()
{ {
if (!DDBackBuffer) { if (!DDFrameBuffer) {
return DDERR_GENERIC; return DDERR_GENERIC;
} }
uint8_t r = (m_backgroundColor >> 16) & 0xFF; DDBLTFX DDBltFx;
uint8_t g = (m_backgroundColor >> 8) & 0xFF; DDBltFx.dwSize = sizeof(DDBLTFX);
uint8_t b = m_backgroundColor & 0xFF; DDBltFx.dwFillColor = m_backgroundColor;
DDFrameBuffer->Blt(nullptr, nullptr, nullptr, DDBLT_COLORFILL, &DDBltFx);
Uint32 color = SDL_MapRGB(SDL_GetPixelFormatDetails(DDBackBuffer->format), nullptr, r, g, b);
SDL_FillSurfaceRect(DDBackBuffer, nullptr, color);
return DD_OK; return DD_OK;
} }

View File

@ -28,7 +28,9 @@
SDL_Window* DDWindow; SDL_Window* DDWindow;
SDL_Surface* DDBackBuffer; SDL_Surface* DDBackBuffer;
FrameBufferImpl* DDFrameBuffer; FrameBufferImpl* DDFrameBuffer;
#ifndef __vita__
SDL_Renderer* DDRenderer; SDL_Renderer* DDRenderer;
#endif
HRESULT DirectDrawImpl::QueryInterface(const GUID& riid, void** ppvObject) HRESULT DirectDrawImpl::QueryInterface(const GUID& riid, void** ppvObject)
{ {
@ -85,7 +87,11 @@ HRESULT DirectDrawImpl::CreateSurface(
return DD_OK; return DD_OK;
} }
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) == DDSCAPS_PRIMARYSURFACE) { if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) == DDSCAPS_PRIMARYSURFACE) {
#ifdef __vita__
DDFrameBuffer = new FrameBufferImpl(lpDDSurfaceDesc);
#else
DDFrameBuffer = new FrameBufferImpl(); DDFrameBuffer = new FrameBufferImpl();
#endif
*lplpDDSurface = static_cast<IDirectDrawSurface*>(DDFrameBuffer); *lplpDDSurface = static_cast<IDirectDrawSurface*>(DDFrameBuffer);
return DD_OK; return DD_OK;
} }
@ -316,9 +322,11 @@ HRESULT DirectDrawImpl::SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags)
#endif #endif
} }
DDWindow = sdlWindow; DDWindow = sdlWindow;
#ifndef __vita__
DDRenderer = SDL_CreateRenderer(DDWindow, sdlRendererName); DDRenderer = SDL_CreateRenderer(DDWindow, sdlRendererName);
SDL_PropertiesID prop = SDL_GetRendererProperties(DDRenderer); SDL_PropertiesID prop = SDL_GetRendererProperties(DDRenderer);
SDL_SetRenderLogicalPresentation(DDRenderer, 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX); SDL_SetRenderLogicalPresentation(DDRenderer, 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX);
#endif
} }
return DD_OK; return DD_OK;
} }
@ -340,9 +348,12 @@ HRESULT DirectDrawImpl::CreateDevice(
pBackBuffer->GetSurfaceDesc(&DDSDesc); pBackBuffer->GetSurfaceDesc(&DDSDesc);
Direct3DRMRenderer* renderer; Direct3DRMRenderer* renderer;
if (SDL_memcmp(&guid, &SDL3_GPU_GUID, sizeof(GUID)) == 0) { if(false) {}
#ifndef __vita__
else if (SDL_memcmp(&guid, &SDL3_GPU_GUID, sizeof(GUID)) == 0) {
renderer = Direct3DRMSDL3GPURenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); renderer = Direct3DRMSDL3GPURenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight);
} }
#endif
#ifdef USE_OPENGLES2 #ifdef USE_OPENGLES2
else if (SDL_memcmp(&guid, &OpenGLES2_GUID, sizeof(GUID)) == 0) { else if (SDL_memcmp(&guid, &OpenGLES2_GUID, sizeof(GUID)) == 0) {
renderer = OpenGLES2Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); renderer = OpenGLES2Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight);
@ -360,7 +371,7 @@ HRESULT DirectDrawImpl::CreateDevice(
#endif #endif
#ifdef __vita__ #ifdef __vita__
else if (SDL_memcmp(&guid, &GXM_GUID, sizeof(GUID)) == 0) { else if (SDL_memcmp(&guid, &GXM_GUID, sizeof(GUID)) == 0) {
renderer = GXMRenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight); renderer = GXMRenderer::Create(pBackBuffer);
} }
#endif #endif
else if (SDL_memcmp(&guid, &SOFTWARE_GUID, sizeof(GUID)) == 0) { else if (SDL_memcmp(&guid, &SOFTWARE_GUID, sizeof(GUID)) == 0) {

View File

@ -43,6 +43,8 @@ HRESULT FrameBufferImpl::AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSur
return DDERR_GENERIC; return DDERR_GENERIC;
} }
#include <cstdio>
HRESULT FrameBufferImpl::Blt( HRESULT FrameBufferImpl::Blt(
LPRECT lpDestRect, LPRECT lpDestRect,
LPDIRECTDRAWSURFACE lpDDSrcSurface, LPDIRECTDRAWSURFACE lpDDSrcSurface,
@ -66,6 +68,7 @@ HRESULT FrameBufferImpl::Blt(
SDL_FillSurfaceRect(DDBackBuffer, &rect, color); SDL_FillSurfaceRect(DDBackBuffer, &rect, color);
return DD_OK; return DD_OK;
} }
auto start = SDL_GetTicksNS();
auto other = static_cast<DirectDrawSurfaceImpl*>(lpDDSrcSurface); auto other = static_cast<DirectDrawSurfaceImpl*>(lpDDSrcSurface);
if (!other) { if (!other) {
return DDERR_GENERIC; return DDERR_GENERIC;
@ -89,6 +92,8 @@ HRESULT FrameBufferImpl::Blt(
if (blitSource != other->m_surface) { if (blitSource != other->m_surface) {
SDL_DestroySurface(blitSource); SDL_DestroySurface(blitSource);
} }
auto end = SDL_GetTicksNS();
return DD_OK; return DD_OK;
} }
@ -114,6 +119,7 @@ HRESULT FrameBufferImpl::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDF
SDL_UpdateTexture(m_uploadBuffer, nullptr, DDBackBuffer->pixels, DDBackBuffer->pitch); SDL_UpdateTexture(m_uploadBuffer, nullptr, DDBackBuffer->pixels, DDBackBuffer->pitch);
SDL_RenderTexture(DDRenderer, m_uploadBuffer, nullptr, nullptr); SDL_RenderTexture(DDRenderer, m_uploadBuffer, nullptr, nullptr);
SDL_RenderPresent(DDRenderer); SDL_RenderPresent(DDRenderer);
printf("Flip\n");
return DD_OK; return DD_OK;
} }

View File

@ -0,0 +1,466 @@
#include "ddpalette_impl.h"
#include "ddraw_impl.h"
#include "dummysurface_impl.h"
#include "framebuffer_impl.h"
#include "miniwin.h"
#include <assert.h>
#include "../d3drm/backends/gxm/memory.h"
#include "../d3drm/backends/gxm/utils.h"
FrameBufferImpl::FrameBufferImpl(LPDDSURFACEDESC lpDDSurfaceDesc)
{
this->width = 960;
this->height = 544;
if(!get_gxm_context(&this->context, &this->shaderPatcher, &this->cdramPool)) {
return;
}
// render target
SceGxmRenderTargetParams renderTargetParams;
memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams));
renderTargetParams.flags = 0;
renderTargetParams.width = this->width;
renderTargetParams.height = this->height;
renderTargetParams.scenesPerFrame = 1;
renderTargetParams.multisampleMode = 0;
renderTargetParams.multisampleLocations = 0;
renderTargetParams.driverMemBlock = -1; // Invalid UID
if(SCE_ERR(sceGxmCreateRenderTarget, &renderTargetParams, &this->renderTarget)) {
return;
}
for(int i = 0; i < VITA_GXM_DISPLAY_BUFFER_COUNT; i++) {
this->displayBuffers[i].data = vita_mem_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
4 * this->width * this->height,
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
&this->displayBuffers[i].uid, "display", nullptr);
if(SCE_ERR(sceGxmColorSurfaceInit,
&this->displayBuffers[i].surface,
SCE_GXM_COLOR_FORMAT_A8B8G8R8,
SCE_GXM_COLOR_SURFACE_LINEAR,
SCE_GXM_COLOR_SURFACE_SCALE_NONE,
SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,
width, height, width,
this->displayBuffers[i].data
)) {
return;
};
if(SCE_ERR(sceGxmSyncObjectCreate, &this->displayBuffers[i].sync)) {
return;
}
}
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, this->shaderPatcher, blitVertexProgramGxp, &this->blitVertexProgramId)) {
return;
}
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, this->shaderPatcher, blitColorFragmentProgramGxp, &this->blitColorFragmentProgramId)) {
return;
}
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, this->shaderPatcher, blitTexFragmentProgramGxp, &this->blitTexFragmentProgramId)) {
return;
}
GET_SHADER_PARAM(positionAttribute, blitVertexProgramGxp, "aPosition",);
GET_SHADER_PARAM(texCoordAttribute, blitVertexProgramGxp, "aTexCoord",);
SceGxmVertexAttribute vertexAttributes[1];
SceGxmVertexStream vertexStreams[1];
vertexAttributes[0].streamIndex = 0;
vertexAttributes[0].offset = 0;
vertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
vertexAttributes[0].componentCount = 2;
vertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(positionAttribute);
vertexAttributes[1].streamIndex = 0;
vertexAttributes[1].offset = 8;
vertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
vertexAttributes[1].componentCount = 2;
vertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(texCoordAttribute);
vertexStreams[0].stride = sizeof(float)*4;
vertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
if(SCE_ERR(sceGxmShaderPatcherCreateVertexProgram,
this->shaderPatcher,
this->blitVertexProgramId,
vertexAttributes, 2,
vertexStreams, 1,
&this->blitVertexProgram
)) {
return;
}
if(SCE_ERR(sceGxmShaderPatcherCreateFragmentProgram,
this->shaderPatcher,
this->blitColorFragmentProgramId,
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
SCE_GXM_MULTISAMPLE_NONE,
NULL,
blitVertexProgramGxp,
&this->blitColorFragmentProgram
)) {
return;
}
if(SCE_ERR(sceGxmShaderPatcherCreateFragmentProgram,
this->shaderPatcher,
this->blitTexFragmentProgramId,
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
SCE_GXM_MULTISAMPLE_NONE,
NULL,
blitVertexProgramGxp,
&this->blitTexFragmentProgram
)) {
return;
}
this->uScreenMatrix = sceGxmProgramFindParameterByName(blitVertexProgramGxp, "uScreenMatrix"); // matrix4
this->uColor = sceGxmProgramFindParameterByName(blitColorFragmentProgramGxp, "uColor"); // vec4
this->uTexMatrix = sceGxmProgramFindParameterByName(blitTexFragmentProgramGxp, "uTexMatrix"); // matrix4
const size_t quadMeshVerticiesSize = 4 * sizeof(float)*4;
const size_t quadMeshIndiciesSize = 4 * sizeof(uint16_t);
this->quadMeshBuffer = sceClibMspaceMalloc(this->cdramPool, quadMeshVerticiesSize + quadMeshIndiciesSize);
this->quadVerticies = (float*)this->quadMeshBuffer;
this->quadIndicies = (uint16_t*)((uint8_t*)(this->quadMeshBuffer)+quadMeshVerticiesSize);
float quadVerts[] = {
// x, y, u, v
-1.0f, -1.0f, 0.0f, 1.0f, // Bottom-left
-1.0f, 1.0f, 0.0f, 0.0f, // Top-left
1.0f, -1.0f, 1.0f, 1.0f, // Bottom-right
1.0f, 1.0f, 1.0f, 0.0f // Top-right
};
memcpy(this->quadVerticies, quadVerts, quadMeshVerticiesSize);
this->quadIndicies[0] = 0;
this->quadIndicies[1] = 1;
this->quadIndicies[2] = 2;
this->quadIndicies[3] = 3;
this->backBufferIndex = 0;
this->frontBufferIndex = 1;
DDBackBuffer = SDL_CreateSurfaceFrom(this->width, this->height, SDL_PIXELFORMAT_RGBA8888, nullptr, 0);
if (!DDBackBuffer) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create surface: %s", SDL_GetError());
}
DDBackBuffer->pitch = this->width*4;
DDBackBuffer->pixels = this->backBuffer()->data;
}
FrameBufferImpl::~FrameBufferImpl()
{
if (m_palette) {
m_palette->Release();
}
}
// IUnknown interface
HRESULT FrameBufferImpl::QueryInterface(const GUID& riid, void** ppvObject)
{
MINIWIN_NOT_IMPLEMENTED();
return E_NOINTERFACE;
}
// IDirectDrawSurface interface
HRESULT FrameBufferImpl::AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface)
{
if (dynamic_cast<DummySurfaceImpl*>(lpDDSAttachedSurface)) {
return DD_OK;
}
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
#include <cstdio>
void calculateTexMatrix(SDL_Rect srcRect, int textureWidth, int textureHeight, float matrix[4][4]) {
float scaleX = srcRect.w / (float)textureWidth;
float scaleY = srcRect.h / (float)textureHeight;
float offsetX = srcRect.x / (float)textureWidth;
float offsetY = srcRect.y / (float)textureHeight;
memset(matrix, 0, sizeof(float) * 16);
matrix[0][0] = scaleX;
matrix[1][1] = scaleY;
matrix[2][2] = 1.0f;
matrix[3][3] = 1.0f;
matrix[0][3] = offsetX;
matrix[1][3] = offsetY;
}
void calculateScreenMatrix(SDL_Rect dstRect, int screenWidth, int screenHeight, float matrix[4][4]) {
float scaleX = (2.0f * dstRect.w) / screenWidth;
float scaleY = (2.0f * dstRect.h) / screenHeight;
float offsetX = (2.0f * dstRect.x) / screenWidth - 1.0f + scaleX * 0.5f;
float offsetY = 1.0f - (2.0f * dstRect.y) / screenHeight - scaleY * 0.5f;
memset(matrix, 0, sizeof(float) * 16);
matrix[0][0] = scaleX;
matrix[1][1] = scaleY;
matrix[2][2] = 1.0f;
matrix[3][3] = 1.0f;
matrix[0][3] = offsetX;
matrix[1][3] = offsetY;
}
HRESULT FrameBufferImpl::Blt(
LPRECT lpDestRect,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFlags dwFlags,
LPDDBLTFX lpDDBltFx
)
{
if (dynamic_cast<FrameBufferImpl*>(lpDDSrcSurface) == this) {
return Flip(nullptr, DDFLIP_WAIT);
}
if(!sceneStarted) {
SCE_ERR(sceGxmBeginScene,
this->context,
0,
this->renderTarget,
nullptr,
nullptr,
nullptr,
&this->backBuffer()->surface,
nullptr
);
sceGxmSetFrontStencilFunc(
this->context,
SCE_GXM_STENCIL_FUNC_NEVER,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
0xFF,
0xFF
);
sceGxmSetFrontDepthFunc(this->context, SCE_GXM_DEPTH_FUNC_ALWAYS);
sceneStarted = true;
}
bool colorFill = ((dwFlags & DDBLT_COLORFILL) == DDBLT_COLORFILL);
sceGxmSetVertexProgram(this->context, this->blitVertexProgram);
SCE_ERR(sceGxmSetVertexStream, this->context, 0, this->quadVerticies);
if(colorFill) {
sceGxmSetFragmentProgram(this->context, this->blitColorFragmentProgram);
} else {
sceGxmSetFragmentProgram(this->context, this->blitTexFragmentProgram);
}
void* vertUniforms;
void* fragUniforms;
SCE_ERR(sceGxmReserveVertexDefaultUniformBuffer, this->context, &vertUniforms);
SCE_ERR(sceGxmReserveFragmentDefaultUniformBuffer, this->context, &fragUniforms);
if(colorFill) {
SDL_Rect rect = {0, 0, this->width, this->height};
DirectDrawPaletteImpl* ddPal = static_cast<DirectDrawPaletteImpl*>(m_palette);
SDL_Palette* sdlPalette = ddPal ? ddPal->m_palette : nullptr;
uint8_t r,g,b,a;
SDL_GetRGBA(lpDDBltFx->dwFillColor, SDL_GetPixelFormatDetails(SDL_PIXELFORMAT_ABGR8888), sdlPalette, &r, &g, &b, &a);
float screenMatrix[4][4];
calculateScreenMatrix(rect, this->width, this->height, screenMatrix);
SET_UNIFORM(vertUniforms, this->uScreenMatrix, screenMatrix);
float color[4] = {
(float)r / 255.0f,
(float)g / 255.0f,
(float)b / 255.0f,
(float)a / 255.0f
};
SET_UNIFORM(fragUniforms, this->uColor, color);
} else {
auto other = static_cast<DirectDrawSurfaceImpl*>(lpDDSrcSurface);
if (!other) {
return DDERR_GENERIC;
}
SDL_Surface* blitSource = other->m_surface;
SDL_Rect srcRect = lpSrcRect ? ConvertRect(lpSrcRect) : SDL_Rect{0, 0, other->m_surface->w, other->m_surface->h};
SDL_Rect dstRect = lpDestRect ? ConvertRect(lpDestRect) : SDL_Rect{0, 0, this->width, this->height};
float screenMatrix[4][4];
calculateScreenMatrix(dstRect, this->width, this->height, screenMatrix);
SET_UNIFORM(vertUniforms, this->uScreenMatrix, screenMatrix);
float texMatrix[4][4];
calculateTexMatrix(srcRect, blitSource->w, blitSource->h, texMatrix);
SET_UNIFORM(vertUniforms, this->uTexMatrix, texMatrix);
SceGxmTextureFormat texFormat = SCE_GXM_TEXTURE_FORMAT_A8B8G8R8;
SceGxmTexture gxmTexture;
SCE_ERR(sceGxmTextureInitLinear, &gxmTexture, blitSource->pixels, texFormat, blitSource->w, blitSource->h, 0);
sceGxmTextureSetStride(&gxmTexture, blitSource->pitch);
SCE_ERR(sceGxmTextureSetMinFilter, &gxmTexture, SCE_GXM_TEXTURE_FILTER_POINT);
SCE_ERR(sceGxmTextureSetMagFilter, &gxmTexture, SCE_GXM_TEXTURE_FILTER_POINT);
SCE_ERR(sceGxmSetFragmentTexture, this->context, 0, &gxmTexture);
}
SCE_ERR(sceGxmDraw,
this->context,
SCE_GXM_PRIMITIVE_TRIANGLE_STRIP,
SCE_GXM_INDEX_FORMAT_U16,
this->quadIndicies,
4
);
return DD_OK;
}
HRESULT FrameBufferImpl::BltFast(
DWORD dwX,
DWORD dwY,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFastFlags dwTrans
)
{
RECT destRect = {
(int) dwX,
(int) dwY,
(int) (lpSrcRect->right - lpSrcRect->left + dwX),
(int) (lpSrcRect->bottom - lpSrcRect->top + dwY)
};
return Blt(&destRect, lpDDSrcSurface, lpSrcRect, DDBLT_NONE, nullptr);
}
HRESULT FrameBufferImpl::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags)
{
if(this->sceneStarted) {
sceGxmEndScene(this->context, nullptr, nullptr);
this->sceneStarted = false;
}
sceGxmPadHeartbeat(
&this->displayBuffers[this->backBufferIndex].surface,
this->displayBuffers[this->backBufferIndex].sync
);
VITA_GXM_DisplayData displayData;
displayData.address = this->displayBuffers[this->backBufferIndex].data;
sceGxmDisplayQueueAddEntry(
this->displayBuffers[this->frontBufferIndex].sync,
this->displayBuffers[this->backBufferIndex].sync,
&displayData
);
this->frontBufferIndex = this->backBufferIndex;
this->backBufferIndex = (this->backBufferIndex + 1) % VITA_GXM_DISPLAY_BUFFER_COUNT;
DDBackBuffer->pixels = this->backBuffer()->data;
return DD_OK;
}
HRESULT FrameBufferImpl::GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface)
{
if ((lpDDSCaps->dwCaps & DDSCAPS_BACKBUFFER) != DDSCAPS_BACKBUFFER) {
return DDERR_INVALIDPARAMS;
}
*lplpDDAttachedSurface = static_cast<IDirectDrawSurface*>(this);
return DD_OK;
}
HRESULT FrameBufferImpl::GetDC(HDC* lphDC)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT FrameBufferImpl::GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette)
{
if (!m_palette) {
return DDERR_GENERIC;
}
m_palette->AddRef();
*lplpDDPalette = m_palette;
return DD_OK;
}
HRESULT FrameBufferImpl::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat)
{
memset(lpDDPixelFormat, 0, sizeof(*lpDDPixelFormat));
lpDDPixelFormat->dwFlags = DDPF_RGB;
lpDDPixelFormat->dwFlags |= DDPF_PALETTEINDEXED8;
lpDDPixelFormat->dwRGBBitCount = 8;
lpDDPixelFormat->dwRBitMask = 0xff;
lpDDPixelFormat->dwGBitMask = 0xff;
lpDDPixelFormat->dwBBitMask = 0xff;
lpDDPixelFormat->dwRGBAlphaBitMask = 0xff;
return DD_OK;
}
HRESULT FrameBufferImpl::GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc)
{
lpDDSurfaceDesc->dwFlags = DDSD_PIXELFORMAT;
GetPixelFormat(&lpDDSurfaceDesc->ddpfPixelFormat);
lpDDSurfaceDesc->dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
lpDDSurfaceDesc->dwWidth = this->width;
lpDDSurfaceDesc->dwHeight = this->height;
return DD_OK;
}
HRESULT FrameBufferImpl::IsLost()
{
return DD_OK;
}
HRESULT FrameBufferImpl::Lock(LPRECT lpDestRect, DDSURFACEDESC* lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent)
{
GetSurfaceDesc(lpDDSurfaceDesc);
lpDDSurfaceDesc->lpSurface = this->backBuffer()->data;
lpDDSurfaceDesc->lPitch = this->width*4;
return DD_OK;
}
HRESULT FrameBufferImpl::ReleaseDC(HDC hDC)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT FrameBufferImpl::Restore()
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT FrameBufferImpl::SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper)
{
return DD_OK;
}
HRESULT FrameBufferImpl::SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT FrameBufferImpl::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette)
{
if (m_palette) {
m_palette->Release();
}
m_palette = lpDDPalette;
//SDL_SetSurfacePalette(DDBackBuffer, ((DirectDrawPaletteImpl*) m_palette)->m_palette);
m_palette->AddRef();
return DD_OK;
}
HRESULT FrameBufferImpl::Unlock(LPVOID lpSurfaceData)
{
return DD_OK;
}

View File

@ -26,7 +26,9 @@ struct Plane {
float d; float d;
}; };
#ifndef __vita__
extern SDL_Renderer* DDRenderer; extern SDL_Renderer* DDRenderer;
#endif
class Direct3DRMRenderer : public IDirect3DDevice2 { class Direct3DRMRenderer : public IDirect3DDevice2 {
public: public:
@ -51,6 +53,7 @@ class Direct3DRMRenderer : public IDirect3DDevice2 {
bool ConvertEventToRenderCoordinates(SDL_Event* event) bool ConvertEventToRenderCoordinates(SDL_Event* event)
{ {
return SDL_ConvertEventToRenderCoordinates(DDRenderer, event); //return SDL_ConvertEventToRenderCoordinates(DDRenderer, event);
return true;
} }
}; };

View File

@ -32,13 +32,8 @@ struct GXMMeshCacheEntry {
uint16_t indexCount; uint16_t indexCount;
}; };
typedef struct GXMRendererInit { typedef struct GXMRendererContext {
SceGxmContext* context; // context
SceGxmShaderPatcher* shaderPatcher;
SceClibMspace gpuPool;
} GXMRendererInit;
typedef struct GXMRendererData {
SceUID vdmRingBufferUid; SceUID vdmRingBufferUid;
SceUID vertexRingBufferUid; SceUID vertexRingBufferUid;
SceUID fragmentRingBufferUid; SceUID fragmentRingBufferUid;
@ -55,18 +50,7 @@ typedef struct GXMRendererData {
void* contextHostMem; void* contextHostMem;
SceGxmContext* context; SceGxmContext* context;
SceGxmRenderTarget* renderTarget; // shader patcher
SceUID renderBufferUid;
void* renderBuffer;
SceGxmColorSurface renderSurface;
SceGxmSyncObject* renderBufferSync;
SceUID depthBufferUid;
void* depthBufferData;
SceUID stencilBufferUid;
void* stencilBufferData;
SceGxmDepthStencilSurface depthSurface;
SceUID patcherBufferUid; SceUID patcherBufferUid;
void* patcherBuffer; void* patcherBuffer;
@ -79,38 +63,68 @@ typedef struct GXMRendererData {
void* patcherFragmentUsse; void* patcherFragmentUsse;
SceGxmShaderPatcher* shaderPatcher; SceGxmShaderPatcher* shaderPatcher;
} GXMRendererContext;
typedef struct GXMRendererData {
SceGxmContext* context;
SceGxmShaderPatcher* shaderPatcher;
SceClibMspace cdramPool;
// color buffer
/*
SceGxmRenderTarget* renderTarget;
SceUID renderBufferUid;
void* renderBuffer;
SceGxmColorSurface renderSurface;
SceGxmSyncObject* renderBufferSync;
*/
// depth buffer
SceUID depthBufferUid;
void* depthBufferData;
SceUID stencilBufferUid;
void* stencilBufferData;
SceGxmDepthStencilSurface depthSurface;
// clear shader
SceGxmShaderPatcherId clearVertexProgramId; SceGxmShaderPatcherId clearVertexProgramId;
SceGxmVertexProgram* clearVertexProgram; SceGxmVertexProgram* clearVertexProgram;
SceGxmShaderPatcherId clearFragmentProgramId; SceGxmShaderPatcherId clearFragmentProgramId;
SceGxmFragmentProgram* clearFragmentProgram; SceGxmFragmentProgram* clearFragmentProgram;
// main shader
SceGxmShaderPatcherId mainVertexProgramId; SceGxmShaderPatcherId mainVertexProgramId;
SceGxmShaderPatcherId mainFragmentProgramId; SceGxmShaderPatcherId mainFragmentProgramId;
SceGxmVertexProgram* mainVertexProgram; SceGxmVertexProgram* mainVertexProgram;
SceGxmFragmentProgram* opaqueFragmentProgram; SceGxmFragmentProgram* opaqueFragmentProgram;
SceGxmFragmentProgram* transparentFragmentProgram; SceGxmFragmentProgram* transparentFragmentProgram;
// main shader vertex uniforms
const SceGxmProgramParameter* uModelViewMatrixParam; const SceGxmProgramParameter* uModelViewMatrixParam;
const SceGxmProgramParameter* uNormalMatrixParam; const SceGxmProgramParameter* uNormalMatrixParam;
const SceGxmProgramParameter* uProjectionMatrixParam; const SceGxmProgramParameter* uProjectionMatrixParam;
// main shader fragment uniforms
const SceGxmProgramParameter* uLights; const SceGxmProgramParameter* uLights;
const SceGxmProgramParameter* uLightCount; const SceGxmProgramParameter* uLightCount;
const SceGxmProgramParameter* uShininess; const SceGxmProgramParameter* uShininess;
const SceGxmProgramParameter* uColor; const SceGxmProgramParameter* uColor;
const SceGxmProgramParameter* uUseTexture; const SceGxmProgramParameter* uUseTexture;
// clear mesh
void* clearMeshBuffer; void* clearMeshBuffer;
float* clearVerticies; float* clearVerticies;
uint16_t* clearIndicies; uint16_t* clearIndicies;
// scene light data
void* lightDataBuffer; void* lightDataBuffer;
FrameBufferImpl* frameBuffer;
} GXMRendererData; } GXMRendererData;
class GXMRenderer : public Direct3DRMRenderer { class GXMRenderer : public Direct3DRMRenderer {
public: public:
static Direct3DRMRenderer* Create(DWORD width, DWORD height); static Direct3DRMRenderer* Create(IDirectDrawSurface* surface);
GXMRenderer( GXMRenderer(
DWORD width, DWORD width,
DWORD height, DWORD height,

View File

@ -10,7 +10,9 @@
extern SDL_Window* DDWindow; extern SDL_Window* DDWindow;
extern SDL_Surface* DDBackBuffer; extern SDL_Surface* DDBackBuffer;
extern FrameBufferImpl* DDFrameBuffer; extern FrameBufferImpl* DDFrameBuffer;
#ifndef __vita__
extern SDL_Renderer* DDRenderer; extern SDL_Renderer* DDRenderer;
#endif
inline static SDL_Rect ConvertRect(const RECT* r) inline static SDL_Rect ConvertRect(const RECT* r)
{ {

View File

@ -1,5 +1,9 @@
#pragma once #pragma once
#ifdef __vita__
#include "framebuffer_impl_vita.h"
#else
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <ddsurface_impl.h> #include <ddsurface_impl.h>
#include <miniwin/ddraw.h> #include <miniwin/ddraw.h>
@ -40,3 +44,4 @@ struct FrameBufferImpl : public IDirectDrawSurface3 {
SDL_Texture* m_uploadBuffer; SDL_Texture* m_uploadBuffer;
IDirectDrawPalette* m_palette = nullptr; IDirectDrawPalette* m_palette = nullptr;
}; };
#endif

View File

@ -0,0 +1,92 @@
#pragma once
#include <SDL3/SDL.h>
#include <ddsurface_impl.h>
#include <miniwin/ddraw.h>
#include <SDL3/SDL_gxm.h>
#include <psp2/gxm.h>
#define VITA_GXM_DISPLAY_BUFFER_COUNT 2
typedef struct GXMDisplayBuffer {
SceUID uid;
SceGxmSyncObject* sync;
void* data;
SceGxmColorSurface surface;
} GXMDisplayBuffer;
typedef struct {
void *address;
int width;
int height;
} GXMDisplayData;
struct FrameBufferImpl : public IDirectDrawSurface3 {
FrameBufferImpl(LPDDSURFACEDESC lpDDSurfaceDesc);
~FrameBufferImpl() override;
// IUnknown interface
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
// IDirectDrawSurface interface
HRESULT AddAttachedSurface(IDirectDrawSurface* lpDDSAttachedSurface) override;
HRESULT Blt(
LPRECT lpDestRect,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFlags dwFlags,
LPDDBLTFX lpDDBltFx
) override;
HRESULT BltFast(DWORD dwX, DWORD dwY, IDirectDrawSurface* lpDDSrcSurface, LPRECT lpSrcRect, DDBltFastFlags dwTrans)
override;
HRESULT Flip(IDirectDrawSurface* lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) override;
HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, IDirectDrawSurface** lplpDDAttachedSurface) override;
HRESULT GetDC(HDC* lphDC) override;
HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) override;
HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) override;
HRESULT GetSurfaceDesc(DDSURFACEDESC* lpDDSurfaceDesc) override;
HRESULT IsLost() override;
HRESULT Lock(LPRECT lpDestRect, DDSURFACEDESC* lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) override;
HRESULT ReleaseDC(HDC hDC) override;
HRESULT Restore() override;
HRESULT SetClipper(IDirectDrawClipper* lpDDClipper) override;
HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) override;
HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) override;
HRESULT Unlock(LPVOID lpSurfaceData) override;
// added
inline GXMDisplayBuffer* backBuffer() {
return &displayBuffers[backBufferIndex];
}
inline SceGxmRenderTarget* GetRenderTarget() {
return this->renderTarget;
}
private:
SceGxmContext* context;
SceGxmShaderPatcher* shaderPatcher;
SceGxmRenderTarget* renderTarget;
SceClibMspace cdramPool;
SceGxmShaderPatcherId blitVertexProgramId;
SceGxmVertexProgram* blitVertexProgram;
SceGxmShaderPatcherId blitColorFragmentProgramId;
SceGxmFragmentProgram* blitColorFragmentProgram;
SceGxmShaderPatcherId blitTexFragmentProgramId;
SceGxmFragmentProgram* blitTexFragmentProgram;
const SceGxmProgramParameter* uScreenMatrix;
const SceGxmProgramParameter* uColor;
const SceGxmProgramParameter* uTexMatrix;
void* quadMeshBuffer;
float* quadVerticies;
uint16_t* quadIndicies;
GXMDisplayBuffer displayBuffers[VITA_GXM_DISPLAY_BUFFER_COUNT];
int backBufferIndex = 0;
int frontBufferIndex = 1;
int width;
int height;
bool sceneStarted;
IDirectDrawPalette* m_palette = nullptr;
};