mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-02-27 21:37:37 +00:00
improve fragment shader performance
This commit is contained in:
parent
fca27bf78d
commit
450ce40b01
@ -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);
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
#define INCBIN_PREFIX _inc_
|
||||
#include "incbin.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
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<int>(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;
|
||||
|
||||
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].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;
|
||||
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].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].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<const float*>(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<const float*>(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);
|
||||
}
|
||||
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
*.exe
|
||||
cache/
|
||||
*.perf.txt
|
||||
@ -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 $< > $@
|
||||
|
||||
Binary file not shown.
BIN
miniwin/src/d3drm/backends/gxm/shaders/main.color.frag.gxp
Normal file
BIN
miniwin/src/d3drm/backends/gxm/shaders/main.color.frag.gxp
Normal file
Binary file not shown.
@ -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));
|
||||
|
||||
float dotNL = max(dot(vNormal, lightVec), 0.0);
|
||||
if (dotNL > 0.0) {
|
||||
// Diffuse contribution
|
||||
float dotNL = max(dot(vNormal, lightVec), 0.0);
|
||||
diffuse += dotNL * lightColor;
|
||||
|
||||
// Specular
|
||||
if (uShininess > 0.0) {
|
||||
float3 viewVec = normalize(-vViewPos); // Assuming camera at origin
|
||||
//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) {
|
||||
outColor.a = uColor.a;
|
||||
#if TEXTURED
|
||||
float4 texel = tex2D(uTexture, vTexCoord);
|
||||
outColor.rgb *= texel.rgb;
|
||||
outColor.rgb = clamp(outColor.rgb, 0.0, 1.0);
|
||||
}
|
||||
|
||||
//outColor = float4(vNormal, 1.0);
|
||||
#endif
|
||||
}
|
||||
Binary file not shown.
BIN
miniwin/src/d3drm/backends/gxm/shaders/main.texture.frag.gxp
Normal file
BIN
miniwin/src/d3drm/backends/gxm/shaders/main.texture.frag.gxp
Normal file
Binary file not shown.
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user