diff --git a/miniwin/src/d3drm/backends/gxm/gxm_memory.h b/miniwin/src/d3drm/backends/gxm/gxm_memory.h index 28c81336..da0ccc43 100644 --- a/miniwin/src/d3drm/backends/gxm/gxm_memory.h +++ b/miniwin/src/d3drm/backends/gxm/gxm_memory.h @@ -6,7 +6,7 @@ void* patcher_host_alloc(void* user_data, unsigned int size); void patcher_host_free(void* user_data, void* mem); -void* vita_mem_alloc(unsigned int type, size_t size, size_t alignment, int attribs, SceUID* uid); +void* vita_mem_alloc(unsigned int type, size_t size, size_t alignment, int attribs, SceUID* uid, const char* name); void vita_mem_free(SceUID uid); void* vita_mem_vertex_usse_alloc(unsigned int size, SceUID* uid, unsigned int* usse_offset); diff --git a/miniwin/src/d3drm/backends/gxm/renderer.cpp b/miniwin/src/d3drm/backends/gxm/renderer.cpp index 48a47d02..bc1000f4 100644 --- a/miniwin/src/d3drm/backends/gxm/renderer.cpp +++ b/miniwin/src/d3drm/backends/gxm/renderer.cpp @@ -16,6 +16,8 @@ #define INCBIN_PREFIX _inc_ #include "incbin.h" +#include + bool with_razor = false; bool with_razor_hud = false; bool gxm_initialized = false; @@ -28,13 +30,17 @@ bool gxm_initialized = false; #define VITA_GXM_COLOR_FORMAT SCE_GXM_COLOR_FORMAT_A8B8G8R8 #define VITA_GXM_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8 +#define SCE_GXM_PRECOMPUTED_ALIGNMENT 16 + INCBIN(main_vert_gxp, "shaders/main.vert.gxp"); -INCBIN(main_frag_gxp, "shaders/main.frag.gxp"); +INCBIN(main_color_frag_gxp, "shaders/main.color.frag.gxp"); +INCBIN(main_texture_frag_gxp, "shaders/main.texture.frag.gxp"); INCBIN(color_frag_gxp, "shaders/color.frag.gxp"); INCBIN(image_frag_gxp, "shaders/image.frag.gxp"); const SceGxmProgram* mainVertexProgramGxp = (const SceGxmProgram*) _inc_main_vert_gxpData; -const SceGxmProgram* mainFragmentProgramGxp = (const SceGxmProgram*) _inc_main_frag_gxpData; +const SceGxmProgram* mainColorFragmentProgramGxp = (const SceGxmProgram*) _inc_main_color_frag_gxpData; +const SceGxmProgram* mainTextureFragmentProgramGxp = (const SceGxmProgram*) _inc_main_texture_frag_gxpData; const SceGxmProgram* colorFragmentProgramGxp = (const SceGxmProgram*) _inc_color_frag_gxpData; const SceGxmProgram* imageFragmentProgramGxp = (const SceGxmProgram*) _inc_image_frag_gxpData; @@ -129,7 +135,7 @@ static void load_razor() } if (with_razor) { - sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx"); + //sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx"); } if (with_razor_hud) { @@ -183,7 +189,8 @@ static bool create_gxm_context() SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE, 4, SCE_GXM_MEMORY_ATTRIB_READ, - &data->vdmRingBufferUid + &data->vdmRingBufferUid, + "vdmRingBuffer" ); data->vertexRingBuffer = vita_mem_alloc( @@ -191,7 +198,8 @@ static bool create_gxm_context() SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE, 4, SCE_GXM_MEMORY_ATTRIB_READ, - &data->vertexRingBufferUid + &data->vertexRingBufferUid, + "vertexRingBuffer" ); data->fragmentRingBuffer = vita_mem_alloc( @@ -199,7 +207,8 @@ static bool create_gxm_context() SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE, 4, SCE_GXM_MEMORY_ATTRIB_READ, - &data->fragmentRingBufferUid + &data->fragmentRingBufferUid, + "fragmentRingBuffer" ); data->fragmentUsseRingBuffer = vita_mem_fragment_usse_alloc( @@ -234,7 +243,8 @@ static bool create_gxm_context() patcherBufferSize, 4, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, - &data->patcherBufferUid + &data->patcherBufferUid, + "patcherBuffer" ); data->patcherVertexUsse = @@ -373,7 +383,8 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height) 4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT, SCE_GXM_COLOR_SURFACE_ALIGNMENT, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, - &this->displayBuffersUid[i] + &this->displayBuffersUid[i], + "displayBuffers" ); if (SCE_ERR( @@ -402,7 +413,8 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height) 4 * sampleCount, SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, - &this->depthBufferUid + &this->depthBufferUid, + "depthBufferData" ); this->stencilBufferData = vita_mem_alloc( @@ -410,7 +422,8 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height) 4 * sampleCount, SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, - &this->stencilBufferUid + &this->stencilBufferUid, + "stencilBufferData" ); if (SCE_ERR( @@ -445,8 +458,16 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height) if (SCE_ERR( sceGxmShaderPatcherRegisterProgram, this->shaderPatcher, - mainFragmentProgramGxp, - &this->mainFragmentProgramId + mainColorFragmentProgramGxp, + &this->mainColorFragmentProgramId + )) { + return; + } + if (SCE_ERR( + sceGxmShaderPatcherRegisterProgram, + this->shaderPatcher, + mainTextureFragmentProgramGxp, + &this->mainTextureFragmentProgramId )) { return; } @@ -505,30 +526,58 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height) } } - // main opaque + // main color opaque if (SCE_ERR( sceGxmShaderPatcherCreateFragmentProgram, this->shaderPatcher, - this->mainFragmentProgramId, + this->mainColorFragmentProgramId, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, SCE_GXM_MULTISAMPLE_NONE, &blendInfoOpaque, mainVertexProgramGxp, - &this->opaqueFragmentProgram + &this->opaqueColorFragmentProgram )) { return; } - // main transparent + // main color blended if (SCE_ERR( sceGxmShaderPatcherCreateFragmentProgram, this->shaderPatcher, - this->mainFragmentProgramId, + this->mainColorFragmentProgramId, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, SCE_GXM_MULTISAMPLE_NONE, &blendInfoTransparent, mainVertexProgramGxp, - &this->transparentFragmentProgram + &this->blendedColorFragmentProgram + )) { + return; + } + + // main texture opaque + if (SCE_ERR( + sceGxmShaderPatcherCreateFragmentProgram, + this->shaderPatcher, + this->mainTextureFragmentProgramId, + SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, + SCE_GXM_MULTISAMPLE_NONE, + &blendInfoOpaque, + mainVertexProgramGxp, + &this->opaqueTextureFragmentProgram + )) { + return; + } + + // main texture transparent + if (SCE_ERR( + sceGxmShaderPatcherCreateFragmentProgram, + this->shaderPatcher, + this->mainTextureFragmentProgramId, + SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, + SCE_GXM_MULTISAMPLE_NONE, + &blendInfoTransparent, + mainVertexProgramGxp, + &this->blendedTextureFragmentProgram )) { return; } @@ -567,11 +616,14 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height) this->uProjectionMatrix = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uProjectionMatrix"); // fragment uniforms - this->uLights = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uLights"); // SceneLight[3] - this->uLightCount = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uLightCount"); // int - this->uShininess = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uShininess"); // float - this->uColor = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uColor"); // vec4 - this->uUseTexture = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uUseTexture"); // int + 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 // clear uniforms this->colorShader_uColor = sceGxmProgramFindParameterByName(colorFragmentProgramGxp, "uColor"); // vec4 @@ -900,6 +952,108 @@ GXMMeshCacheEntry GXMRenderer::GXMUploadMesh(const MeshGroup& meshGroup) cache.indexBuffer = indexBuffer; cache.indexCount = indices.size(); +#ifdef GXM_PRECOMPUTE + bool isOpaque = meshGroup.color.a == 0xff; + const SceGxmTexture* texture = nullptr; + if(meshGroup.texture) { + Uint32 textureId = GetTextureId(meshGroup.texture, false); + texture = &this->m_textures[textureId].gxmTexture; + } + + const SceGxmProgram* fragmentProgramGxp; + const SceGxmFragmentProgram *fragmentProgram; + if(texture) { + fragmentProgramGxp = mainTextureFragmentProgramGxp; + fragmentProgram = isOpaque ? this->opaqueTextureFragmentProgram : this->blendedTextureFragmentProgram; + } else { + fragmentProgramGxp = mainColorFragmentProgramGxp; + fragmentProgram = isOpaque ? this->opaqueColorFragmentProgram : this->blendedColorFragmentProgram; + } + + // get sizes + const size_t drawSize = ALIGN(sceGxmGetPrecomputedDrawSize(this->mainVertexProgram), SCE_GXM_PRECOMPUTED_ALIGNMENT); + const size_t vertexStateSize = ALIGN(sceGxmGetPrecomputedVertexStateSize(this->mainVertexProgram), SCE_GXM_PRECOMPUTED_ALIGNMENT); + const size_t fragmentStateSize = ALIGN(sceGxmGetPrecomputedFragmentStateSize(fragmentProgram), SCE_GXM_PRECOMPUTED_ALIGNMENT); + const size_t precomputeDataSize = + drawSize + + vertexStateSize * GXM_VERTEX_BUFFER_COUNT + + fragmentStateSize * GXM_FRAGMENT_BUFFER_COUNT; + + const size_t vertexDefaultBufferSize = sceGxmProgramGetDefaultUniformBufferSize(mainVertexProgramGxp); + const size_t fragmentDefaultBufferSize = sceGxmProgramGetDefaultUniformBufferSize(fragmentProgramGxp); + const size_t uniformBuffersSize = + vertexDefaultBufferSize * GXM_VERTEX_BUFFER_COUNT; + fragmentStateSize * GXM_FRAGMENT_BUFFER_COUNT; + + sceClibPrintf("drawSize: %d\n", drawSize); + sceClibPrintf("vertexStateSize: %d\n", vertexStateSize); + sceClibPrintf("fragmentStateSize: %d\n", fragmentStateSize); + sceClibPrintf("precomputeDataSize: %d\n", precomputeDataSize); + sceClibPrintf("vertexDefaultBufferSize: %d\n", vertexDefaultBufferSize); + sceClibPrintf("fragmentDefaultBufferSize: %d\n", fragmentDefaultBufferSize); + sceClibPrintf("uniformBuffersSize: %d\n", uniformBuffersSize); + + // allocate the precompute buffer, combined for all + uint8_t* precomputeData = (uint8_t*)cdram_alloc(precomputeDataSize, SCE_GXM_PRECOMPUTED_ALIGNMENT); + cache.precomputeData = precomputeData; + + uint8_t* uniformBuffers = (uint8_t*)cdram_alloc(uniformBuffersSize, 4); + cache.uniformBuffers = uniformBuffers; + + // init precomputed draw + SCE_ERR(sceGxmPrecomputedDrawInit, + &cache.drawState, + this->mainVertexProgram, + precomputeData + ); + void* vertexStreams[] = { vertexBuffer }; + sceGxmPrecomputedDrawSetAllVertexStreams(&cache.drawState, vertexStreams); + sceGxmPrecomputedDrawSetParams( + &cache.drawState, + SCE_GXM_PRIMITIVE_TRIANGLES, + SCE_GXM_INDEX_FORMAT_U16, + indexBuffer, + indices.size() + ); + precomputeData += drawSize; + + // init precomputed vertex state + for(int bufferIndex = 0; bufferIndex < GXM_VERTEX_BUFFER_COUNT; bufferIndex++) { + SCE_ERR(sceGxmPrecomputedVertexStateInit, + &cache.vertexState[bufferIndex], + this->mainVertexProgram, + precomputeData + ); + sceGxmPrecomputedVertexStateSetDefaultUniformBuffer( + &cache.vertexState[bufferIndex], + uniformBuffers + ); + precomputeData += vertexStateSize; + uniformBuffers += vertexDefaultBufferSize; + } + + // init precomputed fragment state + for(int bufferIndex = 0; bufferIndex < GXM_FRAGMENT_BUFFER_COUNT; bufferIndex++) { + SCE_ERR(sceGxmPrecomputedFragmentStateInit, + &cache.fragmentState[bufferIndex], + fragmentProgram, + precomputeData + ); + if(texture) { + sceGxmPrecomputedFragmentStateSetTexture( + &cache.fragmentState[bufferIndex], + 0, texture + ); + } + sceGxmPrecomputedFragmentStateSetDefaultUniformBuffer( + &cache.fragmentState[bufferIndex], + uniformBuffers + ); + precomputeData += fragmentStateSize; + uniformBuffers += fragmentDefaultBufferSize; + } + assert(precomputeData - (uint8_t*)cache.precomputeData <= precomputeDataSize); +#endif return cache; } @@ -1033,25 +1187,35 @@ HRESULT GXMRenderer::BeginFrame() this->StartScene(); auto lightData = this->LightsBuffer(); - int lightCount = std::min(static_cast(m_lights.size()), 3); - for (int i = 0; i < lightCount; ++i) { - const auto& src = m_lights[i]; - lightData->lights[i].color[0] = src.color.r; - lightData->lights[i].color[1] = src.color.g; - lightData->lights[i].color[2] = src.color.b; - lightData->lights[i].color[3] = src.color.a; + int i = 0; + for(const auto& light : m_lights) { + if(!light.directional && !light.positional) { + lightData->ambientLight[0] = light.color.r; + lightData->ambientLight[1] = light.color.g; + lightData->ambientLight[2] = light.color.b; + continue; + } + if(i == 2) { + sceClibPrintf("light overflow\n"); + continue; + } - lightData->lights[i].position[0] = src.position.x; - lightData->lights[i].position[1] = src.position.y; - lightData->lights[i].position[2] = src.position.z; - lightData->lights[i].position[3] = src.positional; + lightData->lights[i].color[0] = light.color.r; + lightData->lights[i].color[1] = light.color.g; + lightData->lights[i].color[2] = light.color.b; + lightData->lights[i].color[3] = light.color.a; - lightData->lights[i].direction[0] = src.direction.x; - lightData->lights[i].direction[1] = src.direction.y; - lightData->lights[i].direction[2] = src.direction.z; - lightData->lights[i].direction[3] = src.directional; + 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; + i++; } - lightData->lightCount = lightCount; sceGxmSetFragmentUniformBuffer(this->context, 0, lightData); return DD_OK; @@ -1100,21 +1264,19 @@ void GXMRenderer::SubmitDraw( sceGxmPushUserMarker(this->context, marker); sceGxmSetVertexProgram(this->context, this->mainVertexProgram); - if (this->transparencyEnabled) { - sceGxmSetFragmentProgram(this->context, this->transparentFragmentProgram); - } - else { - sceGxmSetFragmentProgram(this->context, this->opaqueFragmentProgram); - } - void* vertUniforms; - void* fragUniforms; - sceGxmReserveVertexDefaultUniformBuffer(this->context, &vertUniforms); - sceGxmReserveFragmentDefaultUniformBuffer(this->context, &fragUniforms); + bool textured = appearance.textureId != NO_TEXTURE_ID; - SET_UNIFORM(vertUniforms, this->uModelViewMatrix, modelViewMatrix); - SET_UNIFORM(vertUniforms, this->uProjectionMatrix, m_projection); - sceGxmSetUniformDataF(vertUniforms, this->uNormalMatrix, 0, 9, static_cast(normalMatrix[0])); + const SceGxmFragmentProgram *fragmentProgram; + if(this->transparencyEnabled) { + fragmentProgram = textured ? this->blendedTextureFragmentProgram : this->blendedColorFragmentProgram; + } else { + fragmentProgram = textured ? this->opaqueTextureFragmentProgram : this->opaqueColorFragmentProgram; + } + sceGxmSetFragmentProgram(this->context, fragmentProgram); + + const SceGxmProgramParameter* uColor = textured ? this->texture_uColor : this->color_uColor; + const SceGxmProgramParameter* uShininess = textured ? this->texture_uShininess : this->color_uShininess; float color[4] = { appearance.color.r / 255.0f, @@ -1122,19 +1284,39 @@ void GXMRenderer::SubmitDraw( appearance.color.b / 255.0f, appearance.color.a / 255.0f }; - SET_UNIFORM(fragUniforms, this->uColor, color); - SET_UNIFORM(fragUniforms, this->uShininess, appearance.shininess); - int useTexture = appearance.textureId != NO_TEXTURE_ID ? 1 : 0; - SET_UNIFORM(fragUniforms, this->uUseTexture, useTexture); - if (useTexture) { + void* vertUniforms; + void* fragUniforms; +#ifdef GXM_PRECOMPUTE + sceGxmSetPrecomputedVertexState(this->context, &mesh.vertexState[this->currentVertexBufferIndex]); + sceGxmSetPrecomputedFragmentState(this->context, &mesh.fragmentState[this->currentFragmentBufferIndex]); + vertUniforms = sceGxmPrecomputedVertexStateGetDefaultUniformBuffer(&mesh.vertexState[this->currentVertexBufferIndex]); + fragUniforms = sceGxmPrecomputedFragmentStateGetDefaultUniformBuffer(&mesh.fragmentState[this->currentFragmentBufferIndex]); +#else + sceGxmReserveVertexDefaultUniformBuffer(this->context, &vertUniforms); + sceGxmReserveFragmentDefaultUniformBuffer(this->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); + + if (textured) { auto& texture = m_textures[appearance.textureId]; sceGxmSetFragmentTexture(this->context, 0, &texture.gxmTexture); } +#ifdef GXM_PRECOMPUTE + sceGxmDrawPrecomputed(this->context, &mesh.drawState); + sceGxmSetPrecomputedVertexState(this->context, NULL); + sceGxmSetPrecomputedFragmentState(this->context, NULL); +#else sceGxmSetVertexStream(this->context, 0, mesh.vertexBuffer); sceGxmDraw(this->context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, mesh.indexBuffer, mesh.indexCount); - +#endif sceGxmPopUserMarker(this->context); } diff --git a/miniwin/src/d3drm/backends/gxm/shaders/.gitignore b/miniwin/src/d3drm/backends/gxm/shaders/.gitignore index 21ce5a1f..04193dc2 100644 --- a/miniwin/src/d3drm/backends/gxm/shaders/.gitignore +++ b/miniwin/src/d3drm/backends/gxm/shaders/.gitignore @@ -1,2 +1,3 @@ *.exe -cache/ \ No newline at end of file +cache/ +*.perf.txt \ No newline at end of file diff --git a/miniwin/src/d3drm/backends/gxm/shaders/Makefile b/miniwin/src/d3drm/backends/gxm/shaders/Makefile index 56241c42..6837ca78 100644 --- a/miniwin/src/d3drm/backends/gxm/shaders/Makefile +++ b/miniwin/src/d3drm/backends/gxm/shaders/Makefile @@ -1,9 +1,13 @@ -shaders += main.frag.gxp main.vert.gxp +shaders += main.vert.gxp shaders += color.frag.gxp image.frag.gxp +shaders += main.color.frag.gxp main.texture.frag.gxp + +PERFS = $(shaders:.gxp=.perf.txt) all: $(shaders) +perfs: $(PERFS) -CGCFLAGS = -Wperf -cache -cachedir cache +CGCFLAGS = -Wperf -cache -cachedir cache -W4 -Wsuppress=5206,5203 cache: mkdir -p cache @@ -13,3 +17,12 @@ cache: %.frag.gxp: %.frag.cg | cache ./psp2cgc.exe $(CGCFLAGS) -profile sce_fp_psp2 $< -o $@ + +main.color.frag.gxp: main.frag.cg | cache + ./psp2cgc.exe $(CGCFLAGS) -profile sce_fp_psp2 $< -o $@ + +main.texture.frag.gxp: main.frag.cg | cache + ./psp2cgc.exe $(CGCFLAGS) -DTEXTURED=1 -profile sce_fp_psp2 $< -o $@ + +%.perf.txt: %.gxp + ./psp2shaderperf.exe -disasm $< > $@ diff --git a/miniwin/src/d3drm/backends/gxm/shaders/color.frag.gxp b/miniwin/src/d3drm/backends/gxm/shaders/color.frag.gxp index 4814e137..854275fb 100644 Binary files a/miniwin/src/d3drm/backends/gxm/shaders/color.frag.gxp and b/miniwin/src/d3drm/backends/gxm/shaders/color.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 new file mode 100644 index 00000000..bc881a9e Binary files /dev/null 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 f7b162b5..5867df1a 100644 --- a/miniwin/src/d3drm/backends/gxm/shaders/main.frag.cg +++ b/miniwin/src/d3drm/backends/gxm/shaders/main.frag.cg @@ -10,11 +10,10 @@ void main( float3 vNormal : TEXCOORD2, float2 vTexCoord : TEXCOORD3, - uniform __nostrip SceneLight uLights[3] : BUFFER[0], - uniform __nostrip int uLightCount : BUFFER[0], + uniform __nostrip SceneLight uLights[2] : BUFFER[0], + uniform __nostrip float3 uAmbientLight : BUFFER[0], uniform __nostrip float uShininess, uniform __nostrip float4 uColor, - uniform __nostrip int uUseTexture, uniform __nostrip sampler2D uTexture, out float4 outColor : COLOR @@ -22,46 +21,38 @@ void main( float3 diffuse = float3(0.0, 0.0, 0.0); float3 specular = float3(0.0, 0.0, 0.0); - for (int i = 0; i < uLightCount; ++i) { - float3 lightColor = uLights[i].color.rgb; + float3 viewVec = normalize(-vViewPos); // Assuming camera at origin - // ambient - if (uLights[i].position.w == 0.0 && uLights[i].direction.w == 0.0) { - diffuse += lightColor; - continue; - } + diffuse += uAmbientLight; + + 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; // directional - float3 lightVec; - if (uLights[i].direction.w == 1.0) { - lightVec = -normalize(uLights[i].direction.xyz); - } else { // point - lightVec = normalize(uLights[i].position.xyz - vViewPos); - } + float3 pointLightVec = uLights[i].position.xyz - vViewPos; + float3 directionalLightVec = -uLights[i].direction.xyz; + float3 lightVec = normalize(lerp(pointLightVec, directionalLightVec, isDirectional)); + // Diffuse contribution float dotNL = max(dot(vNormal, lightVec), 0.0); - if (dotNL > 0.0) { - // Diffuse contribution - diffuse += dotNL * lightColor; + diffuse += dotNL * lightColor; - // Specular - if (uShininess > 0.0) { - float3 viewVec = normalize(-vViewPos); // Assuming camera at origin - float3 halfVec = normalize(lightVec + viewVec); - float dotNH = max(dot(vNormal, halfVec), 0.0); - float spec = pow(dotNH, uShininess); - specular += spec * 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; } } - outColor = uColor; outColor.rgb = clamp(diffuse * uColor.rgb + specular, 0.0, 1.0); - if (uUseTexture != 0) { - float4 texel = tex2D(uTexture, vTexCoord); - outColor.rgb *= texel.rgb; - outColor.rgb = clamp(outColor.rgb, 0.0, 1.0); - } - - //outColor = float4(vNormal, 1.0); -} \ No newline at end of file + outColor.a = uColor.a; +#if TEXTURED + float4 texel = tex2D(uTexture, vTexCoord); + outColor.rgb *= texel.rgb; +#endif +} diff --git a/miniwin/src/d3drm/backends/gxm/shaders/main.frag.gxp b/miniwin/src/d3drm/backends/gxm/shaders/main.frag.gxp deleted file mode 100644 index d5861ad8..00000000 Binary files a/miniwin/src/d3drm/backends/gxm/shaders/main.frag.gxp and /dev/null differ diff --git a/miniwin/src/d3drm/backends/gxm/shaders/main.texture.frag.gxp b/miniwin/src/d3drm/backends/gxm/shaders/main.texture.frag.gxp new file mode 100644 index 00000000..08717777 Binary files /dev/null and b/miniwin/src/d3drm/backends/gxm/shaders/main.texture.frag.gxp differ diff --git a/miniwin/src/internal/d3drmrenderer_gxm.h b/miniwin/src/internal/d3drmrenderer_gxm.h index 354d1524..0e604527 100644 --- a/miniwin/src/internal/d3drmrenderer_gxm.h +++ b/miniwin/src/internal/d3drmrenderer_gxm.h @@ -20,6 +20,8 @@ DEFINE_GUID(GXM_GUID, 0x682656F3, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, #define GXM_VERTEX_BUFFER_COUNT 2 #define GXM_FRAGMENT_BUFFER_COUNT 3 +//#define GXM_PRECOMPUTE + struct GXMTextureCacheEntry { IDirect3DRMTexture* texture; Uint32 version; @@ -35,6 +37,14 @@ struct GXMMeshCacheEntry { void* vertexBuffer; void* indexBuffer; uint16_t indexCount; + +#ifdef GXM_PRECOMPUTE + void* precomputeData; + void* uniformBuffers; + SceGxmPrecomputedVertexState vertexState[GXM_VERTEX_BUFFER_COUNT]; + SceGxmPrecomputedFragmentState fragmentState[GXM_FRAGMENT_BUFFER_COUNT]; + SceGxmPrecomputedDraw drawState; +#endif }; typedef struct GXMDisplayData { @@ -50,8 +60,8 @@ struct SceneLightGXM { static_assert(sizeof(SceneLightGXM) == 4*4*3); struct GXMSceneLightUniform { - SceneLightGXM lights[3]; - int lightCount; + SceneLightGXM lights[2]; + float ambientLight[3]; }; @@ -175,15 +185,20 @@ class GXMRenderer : public Direct3DRMRenderer { // shader SceGxmShaderPatcherId mainVertexProgramId; - SceGxmShaderPatcherId mainFragmentProgramId; + SceGxmShaderPatcherId mainColorFragmentProgramId; + SceGxmShaderPatcherId mainTextureFragmentProgramId; SceGxmShaderPatcherId imageFragmentProgramId; SceGxmShaderPatcherId colorFragmentProgramId; - SceGxmVertexProgram* mainVertexProgram; // 3d vert - SceGxmFragmentProgram* opaqueFragmentProgram; // 3d with no transparency - SceGxmFragmentProgram* transparentFragmentProgram; // 3d with transparency - SceGxmFragmentProgram* imageFragmentProgram; // 2d images, no lighting - SceGxmFragmentProgram* colorFragmentProgram; // 2d color, no lighting + SceGxmVertexProgram* mainVertexProgram; + // with lighting + SceGxmFragmentProgram* opaqueColorFragmentProgram; + SceGxmFragmentProgram* blendedColorFragmentProgram; + SceGxmFragmentProgram* opaqueTextureFragmentProgram; + SceGxmFragmentProgram* blendedTextureFragmentProgram; + // no lighting + SceGxmFragmentProgram* imageFragmentProgram; + SceGxmFragmentProgram* colorFragmentProgram; // main shader vertex uniforms const SceGxmProgramParameter* uModelViewMatrix; @@ -191,11 +206,14 @@ class GXMRenderer : public Direct3DRMRenderer { const SceGxmProgramParameter* uProjectionMatrix; // main shader fragment uniforms - const SceGxmProgramParameter* uLights; - const SceGxmProgramParameter* uLightCount; - const SceGxmProgramParameter* uShininess; - const SceGxmProgramParameter* uColor; - const SceGxmProgramParameter* uUseTexture; + 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; // color shader frament uniforms const SceGxmProgramParameter* colorShader_uColor;