diff --git a/miniwin/src/d3drm/backends/gxm/gxm_context.h b/miniwin/src/d3drm/backends/gxm/gxm_context.h index fbecb961..db4115e1 100644 --- a/miniwin/src/d3drm/backends/gxm/gxm_context.h +++ b/miniwin/src/d3drm/backends/gxm/gxm_context.h @@ -5,6 +5,11 @@ #define GXM_DISPLAY_BUFFER_COUNT 3 +typedef struct Vertex2D { + float position[2]; + float texCoord[2]; +} Vertex2D; + typedef struct GXMContext { // context SceUID vdmRingBufferUid; @@ -36,12 +41,14 @@ typedef struct GXMContext { SceGxmShaderPatcher* shaderPatcher; // clear - SceGxmShaderPatcherId clearVertexProgramId; - SceGxmShaderPatcherId clearFragmentProgramId; - SceGxmVertexProgram* clearVertexProgram; - SceGxmFragmentProgram* clearFragmentProgram; - const SceGxmProgramParameter* clear_uColor; - float* clearVertices; + SceGxmShaderPatcherId planeVertexProgramId; + SceGxmShaderPatcherId colorFragmentProgramId; + SceGxmShaderPatcherId imageFragmentProgramId; + SceGxmVertexProgram* planeVertexProgram; + SceGxmFragmentProgram* colorFragmentProgram; + SceGxmFragmentProgram* imageFragmentProgram; + const SceGxmProgramParameter* color_uColor; + Vertex2D* clearVertices; uint16_t* clearIndices; // display diff --git a/miniwin/src/d3drm/backends/gxm/renderer.cpp b/miniwin/src/d3drm/backends/gxm/renderer.cpp index 53ca76b6..341c1afd 100644 --- a/miniwin/src/d3drm/backends/gxm/renderer.cpp +++ b/miniwin/src/d3drm/backends/gxm/renderer.cpp @@ -20,6 +20,7 @@ #include +#define WITH_RAZOR bool with_razor = false; bool with_razor_hud = false; bool gxm_initialized = false; @@ -36,19 +37,16 @@ const SceGxmMultisampleMode msaaMode = SCE_GXM_MULTISAMPLE_NONE; #define SCE_GXM_PRECOMPUTED_ALIGNMENT 16 -INCBIN(main_vert_gxp, "shaders/main.vert.gxp"); -INCBIN(main_color_frag_gxp, "shaders/main.color.frag.gxp"); -INCBIN(main_texture_frag_gxp, "shaders/main.texture.frag.gxp"); -INCBIN(image_frag_gxp, "shaders/image.frag.gxp"); -INCBIN(clear_vert_gxp, "shaders/clear.vert.gxp"); -INCBIN(clear_frag_gxp, "shaders/clear.frag.gxp"); +#define INCSHADER(filename, name) INCBIN(name, filename); const SceGxmProgram* name = (const SceGxmProgram*) _inc_##name##Data; + +INCSHADER("shaders/main.vert.gxp", mainVertexProgramGxp); +INCSHADER("shaders/main.color.frag.gxp", mainColorFragmentProgramGxp); +INCSHADER("shaders/main.texture.frag.gxp", mainTextureFragmentProgramGxp); + +INCSHADER("shaders/plane.vert.gxp", planeVertexProgramGxp); +INCSHADER("shaders/image.frag.gxp", imageFragmentProgramGxp); +INCSHADER("shaders/color.frag.gxp", colorFragmentProgramGxp); -const SceGxmProgram* mainVertexProgramGxp = (const SceGxmProgram*) _inc_main_vert_gxpData; -const SceGxmProgram* mainColorFragmentProgramGxp = (const SceGxmProgram*) _inc_main_color_frag_gxpData; -const SceGxmProgram* mainTextureFragmentProgramGxp = (const SceGxmProgram*) _inc_main_texture_frag_gxpData; -const SceGxmProgram* imageFragmentProgramGxp = (const SceGxmProgram*) _inc_image_frag_gxpData; -const SceGxmProgram* clearVertexProgramGxp = (const SceGxmProgram*) _inc_clear_vert_gxpData; -const SceGxmProgram* clearFragmentProgramGxp = (const SceGxmProgram*) _inc_clear_frag_gxpData; static const SceGxmBlendInfo blendInfoOpaque = { .colorMask = SCE_GXM_COLOR_MASK_ALL, @@ -86,71 +84,72 @@ static void display_callback(const void* callback_data) sceDisplayWaitSetFrameBuf(); } -#ifdef DEBUG -#include +#ifdef WITH_RAZOR + #include -static int load_skprx(const char* name) -{ - int modid = taiLoadKernelModule(name, 0, nullptr); - if (modid < 0) { - sceClibPrintf("%s load: 0x%08x\n", name, modid); - return modid; - } - int status; - int ret = taiStartKernelModule(modid, 0, nullptr, 0, nullptr, &status); - if (ret < 0) { - sceClibPrintf("%s start: 0x%08x\n", name, ret); - } - return ret; -} - -static int load_suprx(const char* name) -{ - int modid = _sceKernelLoadModule(name, 0, nullptr); - if (modid < 0) { - sceClibPrintf("%s load: 0x%08x\n", name, modid); - return modid; - } - int status; - int ret = sceKernelStartModule(modid, 0, nullptr, 0, nullptr, &status); - if (ret < 0) { - sceClibPrintf("%s start: 0x%08x\n", name, ret); - } - return ret; -} - -static const bool extra_debug = false; - -static void load_razor() -{ - if (load_suprx("app0:librazorcapture_es4.suprx") >= 0) { - with_razor = true; + static int load_skprx(const char* name) + { + int modid = taiLoadKernelModule(name, 0, nullptr); + if (modid < 0) { + sceClibPrintf("%s load: 0x%08x\n", name, modid); + return modid; + } + int status; + int ret = taiStartKernelModule(modid, 0, nullptr, 0, nullptr, &status); + if (ret < 0) { + sceClibPrintf("%s start: 0x%08x\n", name, ret); + } + return ret; } - if (extra_debug) { - load_skprx("ux0:app/LEGO00001/syslibtrace.skprx"); - load_skprx("ux0:app/LEGO00001/pamgr.skprx"); + static int load_suprx(const char* name) + { + sceClibPrintf("loading %s\n", name); + int modid = _sceKernelLoadModule(name, 0, nullptr); + if (modid < 0) { + sceClibPrintf("%s load: 0x%08x\n", name, modid); + return modid; + } + int status; + int ret = sceKernelStartModule(modid, 0, nullptr, 0, nullptr, &status); + if (ret < 0) { + sceClibPrintf("%s start: 0x%08x\n", name, ret); + } + return ret; + } - if (load_suprx("app0:libperf.suprx") >= 0) { + static const bool extra_debug = false; + + static void load_razor() + { + if (load_suprx("app0:librazorcapture_es4.suprx") >= 0) { + with_razor = true; } - if (load_suprx("app0:librazorhud_es4.suprx") >= 0) { - with_razor_hud = true; + if (extra_debug) { + load_skprx("ux0:app/LEGO00001/syslibtrace.skprx"); + load_skprx("ux0:app/LEGO00001/pamgr.skprx"); + + if (load_suprx("app0:libperf.suprx") >= 0) { + } + + if (load_suprx("app0:librazorhud_es4.suprx") >= 0) { + with_razor_hud = true; + } + } + + if (with_razor) { + //sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx"); + } + + if (with_razor_hud) { + sceRazorGpuTraceSetFilename("ux0:data/gpu_trace", 3); } } - - if (with_razor) { - //sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx"); - } - - if (with_razor_hud) { - sceRazorGpuTraceSetFilename("ux0:data/gpu_trace", 3); - } -} #else -bool load_razor() { - return true; -} + bool load_razor() { + return true; + } #endif int gxm_library_init() @@ -392,18 +391,34 @@ int GXMContext::init() tlsf_create(this->cdramPool); tlsf_add_pool(this->cdramPool, this->cdramMem, CDRAM_POOL_SIZE); - // clear shader + // register plane, color, image shaders + if (ret = SCE_ERR( sceGxmShaderPatcherRegisterProgram, + this->shaderPatcher, + planeVertexProgramGxp, + &this->planeVertexProgramId + ); ret < 0) { + return ret; + } + if (ret = SCE_ERR(sceGxmShaderPatcherRegisterProgram, + this->shaderPatcher, + colorFragmentProgramGxp, + &this->colorFragmentProgramId + ); ret < 0) { + return ret; + } + if (ret = SCE_ERR(sceGxmShaderPatcherRegisterProgram, + this->shaderPatcher, + imageFragmentProgramGxp, + &this->imageFragmentProgramId + ); ret < 0) { + return ret; + } - if (ret = SCE_ERR( sceGxmShaderPatcherRegisterProgram, this->shaderPatcher, clearVertexProgramGxp, &this->clearVertexProgramId); ret < 0) { - return ret; - } - if (ret = SCE_ERR( sceGxmShaderPatcherRegisterProgram, this->shaderPatcher, clearFragmentProgramGxp, &this->clearFragmentProgramId); ret < 0) { - return ret; - } { - GET_SHADER_PARAM(positionAttribute, clearVertexProgramGxp, "aPosition", -1); + GET_SHADER_PARAM(positionAttribute, planeVertexProgramGxp, "aPosition", -1); + GET_SHADER_PARAM(texCoordAttribute, planeVertexProgramGxp, "aTexCoord", -1); - SceGxmVertexAttribute vertexAttributes[1]; + SceGxmVertexAttribute vertexAttributes[2]; SceGxmVertexStream vertexStreams[1]; // position @@ -413,18 +428,25 @@ int GXMContext::init() vertexAttributes[0].componentCount = 2; vertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(positionAttribute); - vertexStreams[0].stride = 4 * 2; + // uv + 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 (ret = SCE_ERR( sceGxmShaderPatcherCreateVertexProgram, this->shaderPatcher, - this->clearVertexProgramId, + this->planeVertexProgramId, vertexAttributes, - 1, + 2, vertexStreams, 1, - &this->clearVertexProgram + &this->planeVertexProgram ); ret < 0) { return ret; } @@ -432,25 +454,38 @@ int GXMContext::init() if (ret = SCE_ERR( sceGxmShaderPatcherCreateFragmentProgram, this->shaderPatcher, - this->clearFragmentProgramId, + this->colorFragmentProgramId, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, SCE_GXM_MULTISAMPLE_NONE, NULL, - clearVertexProgramGxp, - &this->clearFragmentProgram + planeVertexProgramGxp, + &this->colorFragmentProgram + ); ret < 0) { + return ret; + } + + if (ret = SCE_ERR( + sceGxmShaderPatcherCreateFragmentProgram, + this->shaderPatcher, + this->imageFragmentProgramId, + SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, + SCE_GXM_MULTISAMPLE_NONE, + &blendInfoTransparent, + planeVertexProgramGxp, + &this->imageFragmentProgram ); ret < 0) { return ret; } } - // clear uniforms - this->clear_uColor = sceGxmProgramFindParameterByName(clearFragmentProgramGxp, "uColor"); // vec4 + this->color_uColor = sceGxmProgramFindParameterByName(colorFragmentProgramGxp, "uColor"); // vec4 + + this->clearVertices = static_cast(this->alloc(sizeof(Vertex2D)*4, 4)); + this->clearVertices[0] = Vertex2D{ .position = {-1.0, 1.0}, .texCoord = {0, 0} }; + this->clearVertices[1] = Vertex2D{ .position = {1.0, 1.0}, .texCoord = {0, 0} }; + this->clearVertices[2] = Vertex2D{ .position = {-1.0, -1.0}, .texCoord = {0, 0} }; + this->clearVertices[3] = Vertex2D{ .position = {1.0,-1.0}, .texCoord = {0, 0} }; - this->clearVertices = static_cast(this->alloc(sizeof(float)*4*2, 4)); - this->clearVertices[0] = -1.0; this->clearVertices[1] = 1.0; - this->clearVertices[2] = 1.0; this->clearVertices[3] = 1.0; - this->clearVertices[4] = -1.0; this->clearVertices[5] = -1.0; - this->clearVertices[6] = 1.0; this->clearVertices[7] = -1.0; this->clearIndices = static_cast(this->alloc(sizeof(uint16_t) * 4, 4)); this->clearIndices[0] = 0; this->clearIndices[1] = 1; @@ -495,21 +530,18 @@ void GXMContext::clear(float r, float g, float b, bool new_scene) { float color[] = {r, g, b, 1}; - sceGxmSetVertexProgram(this->context, this->clearVertexProgram); - sceGxmSetFragmentProgram(this->context, this->clearFragmentProgram); + sceGxmSetVertexProgram(this->context, this->planeVertexProgram); + sceGxmSetFragmentProgram(this->context, this->colorFragmentProgram); void* vertUniforms; void* fragUniforms; sceGxmReserveVertexDefaultUniformBuffer(gxm->context, &vertUniforms); sceGxmReserveFragmentDefaultUniformBuffer(gxm->context, &fragUniforms); - if(!fragUniforms) { - SDL_Log("failed to reserve fragment uniform buffer!!"); - } - sceGxmSetVertexStream(gxm->context, 0, this->clearVertices); - sceGxmSetUniformDataF(fragUniforms, this->clear_uColor, 0, 4, color); + sceGxmSetUniformDataF(fragUniforms, this->color_uColor, 0, 4, color); + sceGxmSetFrontDepthFunc(gxm->context, SCE_GXM_DEPTH_FUNC_ALWAYS); sceGxmDraw(gxm->context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, this->clearIndices, 4); if(new_scene) { sceGxmEndScene(this->context, nullptr, nullptr); @@ -659,14 +691,6 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height) ); ret < 0) { return; } - if (ret = SCE_ERR( - sceGxmShaderPatcherRegisterProgram, - gxm->shaderPatcher, - imageFragmentProgramGxp, - &this->imageFragmentProgramId - ); ret < 0) { - return; - } // main shader { @@ -770,40 +794,27 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height) return; } - // image - if (ret = SCE_ERR( - sceGxmShaderPatcherCreateFragmentProgram, - gxm->shaderPatcher, - this->imageFragmentProgramId, - SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, - msaaMode, - &blendInfoTransparent, - mainVertexProgramGxp, - &this->imageFragmentProgram - ); ret < 0) { - return; - } - // vertex uniforms + //this->uNormalMatrix = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uNormalMatrix"); + //this->uWorldViewProjection = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uWorldViewProjection"); + //this->uWorld = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uWorld"); + //this->uViewInverse = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uViewInverse"); + this->uModelViewMatrix = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uModelViewMatrix"); this->uNormalMatrix = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uNormalMatrix"); this->uProjectionMatrix = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uProjectionMatrix"); // fragment uniforms - this->color_uLights = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uLights"); // SceneLight[3] - this->color_uAmbientLight = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uAmbientLight"); // vec3 - this->color_uShininess = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uShininess"); // float - this->color_uColor = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uColor"); // vec4 - this->texture_uLights = sceGxmProgramFindParameterByName(mainTextureFragmentProgramGxp, "uLights"); // SceneLight[3] - this->texture_uAmbientLight = sceGxmProgramFindParameterByName(mainTextureFragmentProgramGxp, "uAmbientLight"); // vec3 - this->texture_uShininess = sceGxmProgramFindParameterByName(mainTextureFragmentProgramGxp, "uShininess"); // float - this->texture_uColor = sceGxmProgramFindParameterByName(mainTextureFragmentProgramGxp, "uColor"); // vec4 + this->uLights = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uLights"); // SceneLight[2] + this->uAmbientLight = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uAmbientLight"); // vec3 + this->uShininess = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uShininess"); // float + this->uColor = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uColor"); // vec4 for (int i = 0; i < GXM_FRAGMENT_BUFFER_COUNT; i++) { this->lights[i] = static_cast(gxm->alloc(sizeof(GXMSceneLightUniform), 4)); } for (int i = 0; i < GXM_VERTEX_BUFFER_COUNT; i++) { - this->quadVertices[i] = static_cast(gxm->alloc(sizeof(Vertex) * 4 * 50, 4)); + this->quadVertices[i] = static_cast(gxm->alloc(sizeof(Vertex2D) * 4 * 50, 4)); } this->quadIndices = static_cast(gxm->alloc(sizeof(uint16_t) * 4, 4)); this->quadIndices[0] = 0; @@ -1407,15 +1418,17 @@ HRESULT GXMRenderer::BeginFrame() lightData->lights[i].color[2] = light.color.b; lightData->lights[i].color[3] = light.color.a; - lightData->lights[i].position[0] = light.position.x; - lightData->lights[i].position[1] = light.position.y; - lightData->lights[i].position[2] = light.position.z; - lightData->lights[i].position[3] = light.positional; - - lightData->lights[i].direction[0] = light.direction.x; - lightData->lights[i].direction[1] = light.direction.y; - lightData->lights[i].direction[2] = light.direction.z; - lightData->lights[i].direction[3] = light.directional; + bool isDirectional = light.directional == 1.0; + if(isDirectional) { + lightData->lights[i].vec[0] = light.direction.x; + lightData->lights[i].vec[1] = light.direction.y; + lightData->lights[i].vec[2] = light.direction.z; + } else { + lightData->lights[i].vec[0] = light.position.x; + lightData->lights[i].vec[1] = light.position.y; + lightData->lights[i].vec[2] = light.position.z; + } + lightData->lights[i].isDirectional = isDirectional; i++; } sceGxmSetFragmentUniformBuffer(gxm->context, 0, lightData); @@ -1437,6 +1450,15 @@ static void transpose4x4(const float src[4][4], float dst[4][4]) } } +static void transpose3x3(const float src[3][3], float dst[3][3]) +{ + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + dst[j][i] = src[i][j]; + } + } +} + static const D3DRMMATRIX4D identity4x4 = { {1.0, 0.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0}, @@ -1461,65 +1483,54 @@ void GXMRenderer::SubmitDraw( { auto& mesh = m_meshes[meshId]; +#ifdef DEBUG char marker[256]; snprintf(marker, sizeof(marker), "SubmitDraw: %d", meshId); sceGxmPushUserMarker(gxm->context, marker); +#endif - sceGxmSetVertexProgram(gxm->context, this->mainVertexProgram); bool textured = appearance.textureId != NO_TEXTURE_ID; - const SceGxmFragmentProgram *fragmentProgram; if(this->transparencyEnabled) { fragmentProgram = textured ? this->blendedTextureFragmentProgram : this->blendedColorFragmentProgram; } else { fragmentProgram = textured ? this->opaqueTextureFragmentProgram : this->opaqueColorFragmentProgram; } + sceGxmSetVertexProgram(gxm->context, this->mainVertexProgram); sceGxmSetFragmentProgram(gxm->context, fragmentProgram); - const SceGxmProgramParameter* uColor = textured ? this->texture_uColor : this->color_uColor; - const SceGxmProgramParameter* uShininess = textured ? this->texture_uShininess : this->color_uShininess; + void* vertUniforms; + void* fragUniforms; + sceGxmReserveVertexDefaultUniformBuffer(gxm->context, &vertUniforms); + sceGxmReserveFragmentDefaultUniformBuffer(gxm->context, &fragUniforms); + // vertex uniforms + sceGxmSetUniformDataF(vertUniforms, this->uModelViewMatrix, 0, 4*4, &modelViewMatrix[0][0]); + sceGxmSetUniformDataF(vertUniforms, this->uNormalMatrix, 0, 3*3, &normalMatrix[0][0]); + sceGxmSetUniformDataF(vertUniforms, this->uProjectionMatrix, 0, 4*4, &this->m_projection[0][0]); + + // fragment uniforms float color[4] = { appearance.color.r / 255.0f, appearance.color.g / 255.0f, appearance.color.b / 255.0f, appearance.color.a / 255.0f }; - - void* vertUniforms; - void* fragUniforms; -#ifdef GXM_PRECOMPUTE - sceGxmSetPrecomputedVertexState(gxm->context, &mesh.vertexState[this->currentVertexBufferIndex]); - sceGxmSetPrecomputedFragmentState(gxm->context, &mesh.fragmentState[this->currentFragmentBufferIndex]); - vertUniforms = sceGxmPrecomputedVertexStateGetDefaultUniformBuffer(&mesh.vertexState[this->currentVertexBufferIndex]); - fragUniforms = sceGxmPrecomputedFragmentStateGetDefaultUniformBuffer(&mesh.fragmentState[this->currentFragmentBufferIndex]); -#else - sceGxmReserveVertexDefaultUniformBuffer(gxm->context, &vertUniforms); - sceGxmReserveFragmentDefaultUniformBuffer(gxm->context, &fragUniforms); -#endif - - SET_UNIFORM(vertUniforms, this->uModelViewMatrix, modelViewMatrix); - SET_UNIFORM(vertUniforms, this->uProjectionMatrix, m_projection); - sceGxmSetUniformDataF(vertUniforms, this->uNormalMatrix, 0, 9, static_cast(normalMatrix[0])); - - SET_UNIFORM(fragUniforms, uColor, color); - SET_UNIFORM(fragUniforms, uShininess, appearance.shininess); + sceGxmSetUniformDataF(fragUniforms, this->uColor, 0, 4, color); + sceGxmSetUniformDataF(fragUniforms, this->uShininess, 0, 1, &appearance.shininess); if (textured) { auto& texture = m_textures[appearance.textureId]; this->UseTexture(texture); } - -#ifdef GXM_PRECOMPUTE - sceGxmDrawPrecomputed(gxm->context, &mesh.drawState); - sceGxmSetPrecomputedVertexState(gxm->gxm->context, NULL); - sceGxmSetPrecomputedFragmentState(gxm->context, NULL); -#else sceGxmSetVertexStream(gxm->context, 0, mesh.vertexBuffer); + sceGxmSetFrontDepthFunc(gxm->context, SCE_GXM_DEPTH_FUNC_LESS); sceGxmDraw(gxm->context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, mesh.indexBuffer, mesh.indexCount); -#endif + +#ifdef DEBUG sceGxmPopUserMarker(gxm->context); +#endif } HRESULT GXMRenderer::FinalizeFrame() @@ -1564,15 +1575,17 @@ void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const S { this->StartScene(); +#ifdef DEBUG char marker[256]; snprintf(marker, sizeof(marker), "Draw2DImage: %d", textureId); sceGxmPushUserMarker(gxm->context, marker); +#endif - sceGxmSetVertexProgram(gxm->context, this->mainVertexProgram); + sceGxmSetVertexProgram(gxm->context, gxm->planeVertexProgram); if(textureId != NO_TEXTURE_ID) { - sceGxmSetFragmentProgram(gxm->context, this->imageFragmentProgram); + sceGxmSetFragmentProgram(gxm->context, gxm->imageFragmentProgram); } else { - sceGxmSetFragmentProgram(gxm->context, gxm->clearFragmentProgram); + sceGxmSetFragmentProgram(gxm->context, gxm->colorFragmentProgram); } void* vertUniforms; @@ -1585,8 +1598,8 @@ void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const S float top = -this->m_viewportTransform.offsetY / this->m_viewportTransform.scale; float bottom = (this->m_height - this->m_viewportTransform.offsetY) / this->m_viewportTransform.scale; -#define virtualToNDCX(x) (((x - left) / (right - left))); -#define virtualToNDCY(y) (((y - top) / (bottom - top))); +#define virtualToNDCX(x) (((x - left) / (right - left)) * 2 - 1); +#define virtualToNDCY(y) -(((y - top) / (bottom - top)) * 2 - 1); float x1_virtual = static_cast(dstRect.x); float y1_virtual = static_cast(dstRect.y); @@ -1598,25 +1611,6 @@ void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const S float x2 = virtualToNDCX(x2_virtual); float y2 = virtualToNDCY(y2_virtual); - D3DRMMATRIX4D projection; - CreateOrthoMatrix(0.0, 1.0, 1.0, 0.0, projection); - static const Matrix3x3 normal = { - {1.f, 0.f, 0.f}, - {0.f, 1.f, 0.f}, - {0.f, 0.f, 1.f} - }; - - D3DRMMATRIX4D identity; - memset(identity, 0, sizeof(identity)); - identity[0][0] = 1.0f; - identity[1][1] = 1.0f; - identity[2][2] = 1.0f; - identity[3][3] = 1.0f; - - SET_UNIFORM(vertUniforms, this->uModelViewMatrix, identity); // float4x4 - SET_UNIFORM(vertUniforms, this->uNormalMatrix, normal); // float3x3 - SET_UNIFORM(vertUniforms, this->uProjectionMatrix, projection); // float4x4 - float u1 = 0.0; float v1 = 0.0; float u2 = 0.0; @@ -1633,21 +1627,25 @@ void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const S u2 = static_cast(srcRect.x + srcRect.w) / texW; v2 = static_cast(srcRect.y + srcRect.h) / texH; } else { - SET_UNIFORM(fragUniforms, gxm->clear_uColor, color); + SET_UNIFORM(fragUniforms, gxm->color_uColor, color); } - Vertex* quadVertices = this->QuadVerticesBuffer(); - quadVertices[0] = Vertex{.position = {x1, y1, 0}, .normal = {0, 0, 0}, .texCoord = {u1, v1}}; - quadVertices[1] = Vertex{.position = {x2, y1, 0}, .normal = {0, 0, 0}, .texCoord = {u2, v1}}; - quadVertices[2] = Vertex{.position = {x1, y2, 0}, .normal = {0, 0, 0}, .texCoord = {u1, v2}}; - quadVertices[3] = Vertex{.position = {x2, y2, 0}, .normal = {0, 0, 0}, .texCoord = {u2, v2}}; + Vertex2D* quadVertices = this->QuadVerticesBuffer(); + quadVertices[0] = Vertex2D{.position = {x1, y1}, .texCoord = {u1, v1}}; + quadVertices[1] = Vertex2D{.position = {x2, y1}, .texCoord = {u2, v1}}; + quadVertices[2] = Vertex2D{.position = {x1, y2}, .texCoord = {u1, v2}}; + quadVertices[3] = Vertex2D{.position = {x2, y2}, .texCoord = {u2, v2}}; sceGxmSetVertexStream(gxm->context, 0, quadVertices); sceGxmSetFrontDepthWriteEnable(gxm->context, SCE_GXM_DEPTH_WRITE_DISABLED); + sceGxmSetFrontDepthFunc(gxm->context, SCE_GXM_DEPTH_FUNC_ALWAYS); sceGxmDraw(gxm->context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, this->quadIndices, 4); sceGxmSetFrontDepthWriteEnable(gxm->context, SCE_GXM_DEPTH_WRITE_ENABLED); + +#ifdef DEBUG sceGxmPopUserMarker(gxm->context); +#endif } void GXMRenderer::SetDither(bool dither) @@ -1665,8 +1663,8 @@ void GXMRenderer::Download(SDL_Surface* target) SDL_Surface* src = SDL_CreateSurfaceFrom( VITA_GXM_SCREEN_WIDTH, VITA_GXM_SCREEN_HEIGHT, - SDL_PIXELFORMAT_RGBA8888, - gxm->displayBuffers[gxm->frontBufferIndex], + SDL_PIXELFORMAT_BGRA8888, + gxm->displayBuffers[gxm->backBufferIndex], VITA_GXM_SCREEN_STRIDE*4 ); SDL_BlitSurfaceScaled(src, &srcRect, target, nullptr, SDL_SCALEMODE_NEAREST); diff --git a/miniwin/src/d3drm/backends/gxm/shaders/Makefile b/miniwin/src/d3drm/backends/gxm/shaders/Makefile index 2874d72a..741b7731 100644 --- a/miniwin/src/d3drm/backends/gxm/shaders/Makefile +++ b/miniwin/src/d3drm/backends/gxm/shaders/Makefile @@ -1,4 +1,4 @@ -shaders += clear.vert.gxp clear.frag.gxp image.frag.gxp +shaders += plane.vert.gxp color.frag.gxp image.frag.gxp shaders += main.vert.gxp main.color.frag.gxp main.texture.frag.gxp PERFS = $(shaders:.gxp=.perf.txt) @@ -24,4 +24,4 @@ main.texture.frag.gxp: main.frag.cg | cache ./psp2cgc.exe $(CGCFLAGS) -DTEXTURED=1 -profile sce_fp_psp2 $< -o $@ %.perf.txt: %.gxp - ./psp2shaderperf.exe -disasm $< > $@ + ./psp2shaderperf.exe -stats -symbols -disasm $< > $@ diff --git a/miniwin/src/d3drm/backends/gxm/shaders/clear.vert.cg b/miniwin/src/d3drm/backends/gxm/shaders/clear.vert.cg deleted file mode 100644 index 2dcecd12..00000000 --- a/miniwin/src/d3drm/backends/gxm/shaders/clear.vert.cg +++ /dev/null @@ -1,5 +0,0 @@ - -float4 main(float2 aPosition : POSITION) : POSITION -{ - return float4(aPosition, 1.f, 1.f); -} diff --git a/miniwin/src/d3drm/backends/gxm/shaders/clear.vert.gxp b/miniwin/src/d3drm/backends/gxm/shaders/clear.vert.gxp deleted file mode 100644 index 1c55c497..00000000 Binary files a/miniwin/src/d3drm/backends/gxm/shaders/clear.vert.gxp and /dev/null differ diff --git a/miniwin/src/d3drm/backends/gxm/shaders/clear.frag.cg b/miniwin/src/d3drm/backends/gxm/shaders/color.frag.cg similarity index 100% rename from miniwin/src/d3drm/backends/gxm/shaders/clear.frag.cg rename to miniwin/src/d3drm/backends/gxm/shaders/color.frag.cg diff --git a/miniwin/src/d3drm/backends/gxm/shaders/clear.frag.gxp b/miniwin/src/d3drm/backends/gxm/shaders/color.frag.gxp similarity index 71% rename from miniwin/src/d3drm/backends/gxm/shaders/clear.frag.gxp rename to miniwin/src/d3drm/backends/gxm/shaders/color.frag.gxp index 4814e137..854275fb 100644 Binary files a/miniwin/src/d3drm/backends/gxm/shaders/clear.frag.gxp and b/miniwin/src/d3drm/backends/gxm/shaders/color.frag.gxp differ diff --git a/miniwin/src/d3drm/backends/gxm/shaders/image.frag.cg b/miniwin/src/d3drm/backends/gxm/shaders/image.frag.cg index 02302350..b3bc6b02 100644 --- a/miniwin/src/d3drm/backends/gxm/shaders/image.frag.cg +++ b/miniwin/src/d3drm/backends/gxm/shaders/image.frag.cg @@ -1,8 +1,6 @@ void main( float4 vPosition : POSITION, - float3 vViewPos : TEXCOORD1, - float3 vNormal : TEXCOORD2, - float2 vTexCoord : TEXCOORD3, + float2 vTexCoord : TEXCOORD0, uniform sampler2D uTexture, diff --git a/miniwin/src/d3drm/backends/gxm/shaders/image.frag.gxp b/miniwin/src/d3drm/backends/gxm/shaders/image.frag.gxp index da4ecbf4..9ca3b63e 100644 Binary files a/miniwin/src/d3drm/backends/gxm/shaders/image.frag.gxp and b/miniwin/src/d3drm/backends/gxm/shaders/image.frag.gxp differ diff --git a/miniwin/src/d3drm/backends/gxm/shaders/main.color.frag.gxp b/miniwin/src/d3drm/backends/gxm/shaders/main.color.frag.gxp index ee751d0e..6954ddd7 100644 Binary files a/miniwin/src/d3drm/backends/gxm/shaders/main.color.frag.gxp and b/miniwin/src/d3drm/backends/gxm/shaders/main.color.frag.gxp differ diff --git a/miniwin/src/d3drm/backends/gxm/shaders/main.frag.cg b/miniwin/src/d3drm/backends/gxm/shaders/main.frag.cg index cb8173cf..b94eec3f 100644 --- a/miniwin/src/d3drm/backends/gxm/shaders/main.frag.cg +++ b/miniwin/src/d3drm/backends/gxm/shaders/main.frag.cg @@ -1,7 +1,7 @@ struct SceneLight { float4 color; - float4 position; - float4 direction; + float4 vec; + float isDirectional; }; void main( @@ -27,30 +27,21 @@ void main( for (int i = 0; i < 2; ++i) { float3 lightColor = uLights[i].color.rgb; - float isDirectional = uLights[i].direction.w; - float isPositional = uLights[i].position.w; + float isDirectional = uLights[i].isDirectional; - // TODO: make faster by removing the if statements - // directional - float3 lightVec; - if (isDirectional) { - lightVec = -normalize(uLights[i].direction.xyz); - } else { - lightVec = uLights[i].position.xyz - vViewPos; - } - lightVec = normalize(lightVec); + float3 lightVec = normalize(lerp(uLights[i].vec.xyz - vViewPos, -uLights[i].vec.xyz, isDirectional)); + + float3 halfVec = normalize(viewVec + lightVec); + float dotNL = max(dot(vNormal, lightVec), 0.0); + float dotNH = max(dot(vNormal, halfVec), 0.0); // Diffuse contribution - float dotNL = max(dot(vNormal, lightVec), 0.0); diffuse += dotNL * lightColor; // Specular - //float enableSpec = (dotNL > 0.0) * (uShininess > 0.0); - if (dotNL > 0.0 && uShininess > 0.0) { - float3 halfVec = normalize(lightVec + viewVec); - float dotNH = max(dot(vNormal, halfVec), 0.0); - float spec = pow(dotNH, uShininess); - specular += spec * lightColor; + float spec = pow(dotNH, uShininess); + if(uShininess > 0.0) { + specular += spec * lightColor * sign(dotNL); } } diff --git a/miniwin/src/d3drm/backends/gxm/shaders/main.texture.frag.gxp b/miniwin/src/d3drm/backends/gxm/shaders/main.texture.frag.gxp index 1a26a16f..e6638dfd 100644 Binary files a/miniwin/src/d3drm/backends/gxm/shaders/main.texture.frag.gxp and b/miniwin/src/d3drm/backends/gxm/shaders/main.texture.frag.gxp differ diff --git a/miniwin/src/d3drm/backends/gxm/shaders/plane.vert.cg b/miniwin/src/d3drm/backends/gxm/shaders/plane.vert.cg new file mode 100644 index 00000000..532431d6 --- /dev/null +++ b/miniwin/src/d3drm/backends/gxm/shaders/plane.vert.cg @@ -0,0 +1,11 @@ + +void main( + float2 aPosition : POSITION, + float2 aTexCoord : TEXCOORD0, + + out float4 vPosition : POSITION, + out float2 vTexCoord : TEXCOORD0 +) : POSITION { + vPosition = float4(aPosition, 1.f, 1.f); + vTexCoord = aTexCoord; +} diff --git a/miniwin/src/d3drm/backends/gxm/shaders/plane.vert.gxp b/miniwin/src/d3drm/backends/gxm/shaders/plane.vert.gxp new file mode 100644 index 00000000..ea8292f3 Binary files /dev/null and b/miniwin/src/d3drm/backends/gxm/shaders/plane.vert.gxp differ diff --git a/miniwin/src/internal/d3drmrenderer_gxm.h b/miniwin/src/internal/d3drmrenderer_gxm.h index 530ff853..64445582 100644 --- a/miniwin/src/internal/d3drmrenderer_gxm.h +++ b/miniwin/src/internal/d3drmrenderer_gxm.h @@ -56,12 +56,11 @@ typedef struct GXMDisplayData { struct SceneLightGXM { float color[4]; - float position[4]; - float direction[4]; + float vec[4]; + float isDirectional; + float _align; }; -static_assert(sizeof(SceneLightGXM) == 4*4*3); - struct GXMSceneLightUniform { SceneLightGXM lights[2]; float ambientLight[3]; @@ -121,8 +120,8 @@ class GXMRenderer : public Direct3DRMRenderer { return gxmTexture; } - inline Vertex* QuadVerticesBuffer() { - Vertex* verts = &this->quadVertices[this->currentVertexBufferIndex][this->quadsUsed*4]; + inline Vertex2D* QuadVerticesBuffer() { + Vertex2D* verts = &this->quadVertices[this->currentVertexBufferIndex][this->quadsUsed*4]; this->quadsUsed += 1; if(this->quadsUsed >= 50) { SDL_Log("QuadVerticesBuffer overflow"); @@ -146,35 +145,32 @@ class GXMRenderer : public Direct3DRMRenderer { SceGxmShaderPatcherId mainVertexProgramId; SceGxmShaderPatcherId mainColorFragmentProgramId; SceGxmShaderPatcherId mainTextureFragmentProgramId; - SceGxmShaderPatcherId imageFragmentProgramId; SceGxmVertexProgram* mainVertexProgram; - // with lighting SceGxmFragmentProgram* opaqueColorFragmentProgram; SceGxmFragmentProgram* blendedColorFragmentProgram; SceGxmFragmentProgram* opaqueTextureFragmentProgram; SceGxmFragmentProgram* blendedTextureFragmentProgram; - // no lighting - SceGxmFragmentProgram* imageFragmentProgram; // main shader vertex uniforms + //const SceGxmProgramParameter* uNormalMatrix; + //const SceGxmProgramParameter* uWorldViewProjection; + //const SceGxmProgramParameter* uWorld; + //const SceGxmProgramParameter* uViewInverse; const SceGxmProgramParameter* uModelViewMatrix; const SceGxmProgramParameter* uNormalMatrix; const SceGxmProgramParameter* uProjectionMatrix; + // main shader fragment uniforms - const SceGxmProgramParameter* color_uLights; - const SceGxmProgramParameter* color_uAmbientLight; - const SceGxmProgramParameter* color_uShininess; - const SceGxmProgramParameter* color_uColor; - const SceGxmProgramParameter* texture_uLights; - const SceGxmProgramParameter* texture_uAmbientLight; - const SceGxmProgramParameter* texture_uShininess; - const SceGxmProgramParameter* texture_uColor; + const SceGxmProgramParameter* uShininess; + const SceGxmProgramParameter* uColor; + const SceGxmProgramParameter* uLights; + const SceGxmProgramParameter* uAmbientLight; // uniforms / quad meshes GXMSceneLightUniform* lights[GXM_FRAGMENT_BUFFER_COUNT]; - Vertex* quadVertices[GXM_VERTEX_BUFFER_COUNT]; + Vertex2D* quadVertices[GXM_VERTEX_BUFFER_COUNT]; uint16_t* quadIndices; int quadsUsed = 0;