Add drawstate cache
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c
index dc76d4f..925df80 100644
--- a/src/render/vitagxm/SDL_render_vita_gxm.c
+++ b/src/render/vitagxm/SDL_render_vita_gxm.c
@@ -126,6 +126,12 @@ StartDrawing(SDL_Renderer *renderer)
return;
}
+ data->drawstate.texture = NULL;
+ data->drawstate.vertex_program = NULL;
+ data->drawstate.fragment_program = NULL;
+ data->drawstate.last_command = -1;
+ data->drawstate.texture_color = 0xFFFFFFFF;
+
// reset blend mode
// data->currentBlendMode = SDL_BLENDMODE_BLEND;
// fragment_programs *in = &data->blendFragmentPrograms.blend_mode_blend;
@@ -676,6 +682,8 @@ VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
clear_color[3] = (cmd->data.color.a)/255.0f;
// set clear shaders
+ data->drawstate.fragment_program = data->clearFragmentProgram;
+ data->drawstate.vertex_program = data->clearVertexProgram;
sceGxmSetVertexProgram(data->gxm_context, data->clearVertexProgram);
sceGxmSetFragmentProgram(data->gxm_context, data->clearFragmentProgram);
@@ -697,12 +705,19 @@ VITA_GXM_RenderDrawPoints(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
{
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
- sceGxmSetVertexProgram(data->gxm_context, data->colorVertexProgram);
- sceGxmSetFragmentProgram(data->gxm_context, data->colorFragmentProgram);
+ if (data->drawstate.fragment_program != data->colorFragmentProgram || data->drawstate.vertex_program != data->colorVertexProgram) {
+ data->drawstate.fragment_program = data->colorFragmentProgram;
+ data->drawstate.vertex_program = data->colorVertexProgram;
+
+ sceGxmSetVertexProgram(data->gxm_context, data->colorVertexProgram);
+ sceGxmSetFragmentProgram(data->gxm_context, data->colorFragmentProgram);
+
+
+ void *vertexDefaultBuffer;
+ sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertexDefaultBuffer);
+ sceGxmSetUniformDataF(vertexDefaultBuffer, data->colorWvpParam, 0, 16, data->ortho_matrix);
+ }
- void *vertexDefaultBuffer;
- sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertexDefaultBuffer);
- sceGxmSetUniformDataF(vertexDefaultBuffer, data->colorWvpParam, 0, 16, data->ortho_matrix);
sceGxmSetVertexStream(data->gxm_context, 0, (const void*)cmd->data.draw.first);
@@ -718,16 +733,18 @@ VITA_GXM_RenderDrawLines(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
{
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
- sceGxmSetVertexProgram(data->gxm_context, data->colorVertexProgram);
- sceGxmSetFragmentProgram(data->gxm_context, data->colorFragmentProgram);
+ if (data->drawstate.fragment_program != data->colorFragmentProgram || data->drawstate.vertex_program != data->colorVertexProgram) {
+ data->drawstate.fragment_program = data->colorFragmentProgram;
+ data->drawstate.vertex_program = data->colorVertexProgram;
- void *vertexDefaultBuffer;
+ sceGxmSetVertexProgram(data->gxm_context, data->colorVertexProgram);
+ sceGxmSetFragmentProgram(data->gxm_context, data->colorFragmentProgram);
- sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertexDefaultBuffer);
- sceGxmSetUniformDataF(vertexDefaultBuffer, data->colorWvpParam, 0, 16, data->ortho_matrix);
-
- sceGxmSetVertexStream(data->gxm_context, 0, (const void*)cmd->data.draw.first);
+ void *vertexDefaultBuffer;
+ sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertexDefaultBuffer);
+ sceGxmSetUniformDataF(vertexDefaultBuffer, data->colorWvpParam, 0, 16, data->ortho_matrix);
+ }
sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_LINE);
sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_LINES, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, cmd->data.draw.count);
@@ -741,12 +758,18 @@ VITA_GXM_RenderFillRects(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
{
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
- sceGxmSetVertexProgram(data->gxm_context, data->colorVertexProgram);
- sceGxmSetFragmentProgram(data->gxm_context, data->colorFragmentProgram);
+ if (data->drawstate.fragment_program != data->colorFragmentProgram || data->drawstate.vertex_program != data->colorVertexProgram) {
+ data->drawstate.fragment_program = data->colorFragmentProgram;
+ data->drawstate.vertex_program = data->colorVertexProgram;
+
+ sceGxmSetVertexProgram(data->gxm_context, data->colorVertexProgram);
+ sceGxmSetFragmentProgram(data->gxm_context, data->colorFragmentProgram);
- void *vertexDefaultBuffer;
- sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertexDefaultBuffer);
- sceGxmSetUniformDataF(vertexDefaultBuffer, data->colorWvpParam, 0, 16, data->ortho_matrix);
+
+ void *vertexDefaultBuffer;
+ sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertexDefaultBuffer);
+ sceGxmSetUniformDataF(vertexDefaultBuffer, data->colorWvpParam, 0, 16, data->ortho_matrix);
+ }
sceGxmSetVertexStream(data->gxm_context, 0, (const void*)cmd->data.draw.first);
sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, 4 * cmd->data.draw.count);
@@ -821,40 +844,65 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
b = cmd->data.draw.b;
a = cmd->data.draw.a;
- sceGxmSetVertexProgram(data->gxm_context, data->textureVertexProgram);
+ if (data->drawstate.vertex_program != data->textureVertexProgram) {
+ data->drawstate.vertex_program = data->textureVertexProgram;
+ sceGxmSetVertexProgram(data->gxm_context, data->textureVertexProgram);
+ }
if(r == 255 && g == 255 && b == 255 && a == 255)
{
- sceGxmSetFragmentProgram(data->gxm_context, data->textureFragmentProgram);
+ if (data->drawstate.fragment_program != data->textureFragmentProgram) {
+ data->drawstate.fragment_program = data->textureFragmentProgram;
+ sceGxmSetFragmentProgram(data->gxm_context, data->textureFragmentProgram);
+ }
}
else
{
- sceGxmSetFragmentProgram(data->gxm_context, data->textureTintFragmentProgram);
- void *texture_tint_color_buffer;
- sceGxmReserveFragmentDefaultUniformBuffer(data->gxm_context, &texture_tint_color_buffer);
-
- float *tint_color = pool_memalign(
- data,
- 4 * sizeof(float), // RGBA
- sizeof(float)
- );
+ if (data->drawstate.fragment_program != data->textureTintFragmentProgram) {
+ data->drawstate.fragment_program = data->textureTintFragmentProgram;
+ sceGxmSetFragmentProgram(data->gxm_context, data->textureTintFragmentProgram);
+ }
+
+ Uint32 texture_color = ((a << 24) | (b << 16) | (g << 8) | r);
+
+ if (
+ (data->drawstate.last_command != SDL_RENDERCMD_COPY && data->drawstate.last_command != SDL_RENDERCMD_COPY_EX)
+ || data->drawstate.texture_color != texture_color
+ ) {
+ data->drawstate.texture_color = texture_color;
+ void *texture_tint_color_buffer;
+ sceGxmReserveFragmentDefaultUniformBuffer(data->gxm_context, &texture_tint_color_buffer);
+
+ float *tint_color = pool_memalign(
+ data,
+ 4 * sizeof(float), // RGBA
+ sizeof(float)
+ );
+
+ tint_color[0] = r / 255.0f;
+ tint_color[1] = g / 255.0f;
+ tint_color[2] = b / 255.0f;
+ tint_color[3] = a / 255.0f;
+
+ sceGxmSetUniformDataF(texture_tint_color_buffer, data->textureTintColorParam, 0, 4, tint_color);
+ }
- tint_color[0] = r / 255.0f;
- tint_color[1] = g / 255.0f;
- tint_color[2] = b / 255.0f;
- tint_color[3] = a / 255.0f;
-
- sceGxmSetUniformDataF(texture_tint_color_buffer, data->textureTintColorParam, 0, 4, tint_color);
+ }
+ if (data->drawstate.last_command != SDL_RENDERCMD_COPY && data->drawstate.last_command != SDL_RENDERCMD_COPY_EX) {
+ void *vertex_wvp_buffer;
+ sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertex_wvp_buffer);
+ sceGxmSetUniformDataF(vertex_wvp_buffer, data->textureWvpParam, 0, 16, data->ortho_matrix);
}
- void *vertex_wvp_buffer;
- sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertex_wvp_buffer);
- sceGxmSetUniformDataF(vertex_wvp_buffer, data->textureWvpParam, 0, 16, data->ortho_matrix);
+ if (data->drawstate.texture != cmd->data.draw.texture) {
+ data->drawstate.texture = cmd->data.draw.texture;
+ // TODO: check if texture changed
+ VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) cmd->data.draw.texture->driverdata;
- VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) cmd->data.draw.texture->driverdata;
+ sceGxmSetFragmentTexture(data->gxm_context, 0, &vita_texture->tex->gxm_tex);
+ }
- sceGxmSetFragmentTexture(data->gxm_context, 0, &vita_texture->tex->gxm_tex);
sceGxmSetVertexStream(data->gxm_context, 0, (const void*)cmd->data.draw.first);
sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, 4 * cmd->data.draw.count);
@@ -865,7 +913,7 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
case SDL_RENDERCMD_NO_OP:
break;
}
-
+ data->drawstate.last_command = cmd->command;
cmd = cmd->next;
}
diff --git a/src/render/vitagxm/SDL_render_vita_gxm_tools.c b/src/render/vitagxm/SDL_render_vita_gxm_tools.c
index 26967aa..757f1f4 100644
--- a/src/render/vitagxm/SDL_render_vita_gxm_tools.c
+++ b/src/render/vitagxm/SDL_render_vita_gxm_tools.c
@@ -249,6 +249,8 @@ set_stencil_mask(VITA_GXM_RenderData *data, float x, float y, float w, float h)
vertices[3].z = +0.5f;
vertices[3].color = 0;
+ data->drawstate.fragment_program = data->colorFragmentProgram;
+ data->drawstate.vertex_program = data->colorVertexProgram;
sceGxmSetVertexProgram(data->gxm_context, data->colorVertexProgram);
sceGxmSetFragmentProgram(data->gxm_context, data->colorFragmentProgram);
diff --git a/src/render/vitagxm/SDL_render_vita_gxm_types.h b/src/render/vitagxm/SDL_render_vita_gxm_types.h
index cc4e5f2..af4c331 100644
--- a/src/render/vitagxm/SDL_render_vita_gxm_types.h
+++ b/src/render/vitagxm/SDL_render_vita_gxm_types.h
@@ -104,6 +104,10 @@ typedef struct
SDL_Texture *texture;
SDL_Texture *target;
Uint32 color;
+ Uint32 texture_color;
+ SceGxmFragmentProgram *fragment_program;
+ SceGxmVertexProgram *vertex_program;
+ int last_command;
} gxm_drawstate_cache;
typedef struct