[PATCH 3/5] wined3d: Introduce a scratch string buffers framework. (v2)

Matteo Bruni mbruni at codeweavers.com
Fri Apr 24 15:25:43 CDT 2015


---
 dlls/wined3d/glsl_shader.c     | 98 ++++++++++++++++++++++++------------------
 dlls/wined3d/shader.c          | 65 ++++++++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h | 12 ++++++
 3 files changed, 132 insertions(+), 43 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 2e0be37..6f3a73a 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -92,6 +92,7 @@ struct constant_heap
 /* GLSL shader private data */
 struct shader_glsl_priv {
     struct wined3d_string_buffer shader_buffer;
+    struct wined3d_string_buffer_list string_buffers;
     struct wine_rb_tree program_lookup;
     struct constant_heap vconst_heap;
     struct constant_heap pconst_heap;
@@ -435,10 +436,10 @@ static void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLu
 
 /* Context activation is done by the caller. */
 static void shader_glsl_load_samplers(const struct wined3d_gl_info *gl_info,
-        const DWORD *tex_unit_map, GLuint program_id)
+        struct shader_glsl_priv *priv, const DWORD *tex_unit_map, GLuint program_id)
 {
     unsigned int mapped_unit;
-    char sampler_name[20];
+    struct wined3d_string_buffer *sampler_name = string_buffer_get(&priv->string_buffers);
     const char *prefix;
     unsigned int i, j;
     GLint name_loc;
@@ -461,23 +462,24 @@ static void shader_glsl_load_samplers(const struct wined3d_gl_info *gl_info,
 
         for (j = 0; j < sampler_info[i].count; ++j)
         {
-            snprintf(sampler_name, sizeof(sampler_name), "%s_sampler%u", prefix, j);
-            name_loc = GL_EXTCALL(glGetUniformLocation(program_id, sampler_name));
+            string_buffer_sprintf(sampler_name, "%s_sampler%u", prefix, j);
+            name_loc = GL_EXTCALL(glGetUniformLocation(program_id, sampler_name->buffer));
             if (name_loc == -1)
                 continue;
 
             mapped_unit = tex_unit_map[sampler_info[i].base_idx + j];
             if (mapped_unit == WINED3D_UNMAPPED_STAGE || mapped_unit >= gl_info->limits.combined_samplers)
             {
-                ERR("Trying to load sampler %s on unsupported unit %u.\n", sampler_name, mapped_unit);
+                ERR("Trying to load sampler %s on unsupported unit %u.\n", sampler_name->buffer, mapped_unit);
                 continue;
             }
 
-            TRACE("Loading sampler %s on unit %u.\n", sampler_name, mapped_unit);
+            TRACE("Loading sampler %s on unit %u.\n", sampler_name->buffer, mapped_unit);
             GL_EXTCALL(glUniform1i(name_loc, mapped_unit));
         }
     }
     checkGLcall("glUniform1i");
+    string_buffer_release(&priv->string_buffers, sampler_name);
 }
 
 /* Context activation is done by the caller. */
@@ -6113,31 +6115,31 @@ static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(str
 
 
 static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *gl_info,
-        GLuint program_id, struct glsl_vs_program *vs, unsigned int vs_c_count)
+        struct shader_glsl_priv *priv, GLuint program_id, struct glsl_vs_program *vs, unsigned int vs_c_count)
 {
     unsigned int i;
-    char name[32];
+    struct wined3d_string_buffer *name = string_buffer_get(&priv->string_buffers);
 
     vs->uniform_f_locations = HeapAlloc(GetProcessHeap(), 0,
             sizeof(GLuint) * gl_info->limits.glsl_vs_float_constants);
     for (i = 0; i < vs_c_count; ++i)
     {
-        snprintf(name, sizeof(name), "vs_c[%u]", i);
-        vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
+        string_buffer_sprintf(name, "vs_c[%u]", i);
+        vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
     }
     memset(&vs->uniform_f_locations[vs_c_count], 0xff,
             (gl_info->limits.glsl_vs_float_constants - vs_c_count) * sizeof(GLuint));
 
     for (i = 0; i < MAX_CONST_I; ++i)
     {
-        snprintf(name, sizeof(name), "vs_i[%u]", i);
-        vs->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
+        string_buffer_sprintf(name, "vs_i[%u]", i);
+        vs->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
     }
 
     for (i = 0; i < MAX_CONST_B; ++i)
     {
-        snprintf(name, sizeof(name), "vs_b[%u]", i);
-        vs->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
+        string_buffer_sprintf(name, "vs_b[%u]", i);
+        vs->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
     }
 
     vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "posFixup"));
@@ -6145,46 +6147,48 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *
     vs->modelview_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_modelview_matrix"));
     vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix"));
     vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_normal_matrix"));
+
+    string_buffer_release(&priv->string_buffers, name);
 }
 
 static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *gl_info,
-        GLuint program_id, struct glsl_ps_program *ps, unsigned int ps_c_count)
+        struct shader_glsl_priv *priv, GLuint program_id, struct glsl_ps_program *ps, unsigned int ps_c_count)
 {
     unsigned int i;
-    char name[32];
+    struct wined3d_string_buffer *name = string_buffer_get(&priv->string_buffers);
 
     ps->uniform_f_locations = HeapAlloc(GetProcessHeap(), 0,
             sizeof(GLuint) * gl_info->limits.glsl_ps_float_constants);
     for (i = 0; i < ps_c_count; ++i)
     {
-        snprintf(name, sizeof(name), "ps_c[%u]", i);
-        ps->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
+        string_buffer_sprintf(name, "ps_c[%u]", i);
+        ps->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
     }
     memset(&ps->uniform_f_locations[ps_c_count], 0xff,
             (gl_info->limits.glsl_ps_float_constants - ps_c_count) * sizeof(GLuint));
 
     for (i = 0; i < MAX_CONST_I; ++i)
     {
-        snprintf(name, sizeof(name), "ps_i[%u]", i);
-        ps->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
+        string_buffer_sprintf(name, "ps_i[%u]", i);
+        ps->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
     }
 
     for (i = 0; i < MAX_CONST_B; ++i)
     {
-        snprintf(name, sizeof(name), "ps_b[%u]", i);
-        ps->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
+        string_buffer_sprintf(name, "ps_b[%u]", i);
+        ps->uniform_b_locations[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
     }
 
     for (i = 0; i < MAX_TEXTURES; ++i)
     {
-        snprintf(name, sizeof(name), "bumpenv_mat%u", i);
-        ps->bumpenv_mat_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
-        snprintf(name, sizeof(name), "bumpenv_lum_scale%u", i);
-        ps->bumpenv_lum_scale_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
-        snprintf(name, sizeof(name), "bumpenv_lum_offset%u", i);
-        ps->bumpenv_lum_offset_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
-        snprintf(name, sizeof(name), "tss_const%u", i);
-        ps->tss_constant_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name));
+        string_buffer_sprintf(name, "bumpenv_mat%u", i);
+        ps->bumpenv_mat_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
+        string_buffer_sprintf(name, "bumpenv_lum_scale%u", i);
+        ps->bumpenv_lum_scale_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
+        string_buffer_sprintf(name, "bumpenv_lum_offset%u", i);
+        ps->bumpenv_lum_offset_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
+        string_buffer_sprintf(name, "tss_const%u", i);
+        ps->tss_constant_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
     }
 
     ps->tex_factor_location = GL_EXTCALL(glGetUniformLocation(program_id, "tex_factor"));
@@ -6192,26 +6196,30 @@ static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *
     ps->np2_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "ps_samplerNP2Fixup"));
     ps->ycorrection_location = GL_EXTCALL(glGetUniformLocation(program_id, "ycorrection"));
     ps->color_key_location = GL_EXTCALL(glGetUniformLocation(program_id, "color_key"));
+
+    string_buffer_release(&priv->string_buffers, name);
 }
 
-static void shader_glsl_init_uniform_block_bindings(const struct wined3d_gl_info *gl_info, GLuint program_id,
+static void shader_glsl_init_uniform_block_bindings(const struct wined3d_gl_info *gl_info,
+        struct shader_glsl_priv *priv, GLuint program_id,
         const struct wined3d_shader_reg_maps *reg_maps, unsigned int base, unsigned int count)
 {
     const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type);
     GLuint block_idx;
     unsigned int i;
-    char name[16];
+    struct wined3d_string_buffer *name = string_buffer_get(&priv->string_buffers);
 
     for (i = 0; i < count; ++i)
     {
         if (!reg_maps->cb_sizes[i])
             continue;
 
-        snprintf(name, sizeof(name), "block_%s_cb%u", prefix, i);
-        block_idx = GL_EXTCALL(glGetUniformBlockIndex(program_id, name));
+        string_buffer_sprintf(name, "block_%s_cb%u", prefix, i);
+        block_idx = GL_EXTCALL(glGetUniformBlockIndex(program_id, name->buffer));
         GL_EXTCALL(glUniformBlockBinding(program_id, block_idx, base + i));
     }
     checkGLcall("glUniformBlockBinding");
+    string_buffer_release(&priv->string_buffers, name);
 }
 
 /* Context activation is done by the caller. */
@@ -6337,7 +6345,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
     if (vshader)
     {
         WORD map = vshader->reg_maps.input_registers;
-        char tmp_name[10];
+        struct wined3d_string_buffer *tmp_name = string_buffer_get(&priv->string_buffers);
 
         reorder_shader_id = generate_param_reorder_function(&priv->shader_buffer, vshader, pshader, gl_info);
         TRACE("Attaching GLSL shader object %u to program %u.\n", reorder_shader_id, program_id);
@@ -6361,10 +6369,11 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
         {
             if (!(map & 1)) continue;
 
-            snprintf(tmp_name, sizeof(tmp_name), "vs_in%u", i);
-            GL_EXTCALL(glBindAttribLocation(program_id, i, tmp_name));
+            string_buffer_sprintf(tmp_name, "vs_in%u", i);
+            GL_EXTCALL(glBindAttribLocation(program_id, i, tmp_name->buffer));
         }
         checkGLcall("glBindAttribLocation");
+        string_buffer_release(&priv->string_buffers, tmp_name);
     }
 
     if (gshader)
@@ -6403,9 +6412,9 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
     GL_EXTCALL(glLinkProgram(program_id));
     shader_glsl_validate_link(gl_info, program_id);
 
-    shader_glsl_init_vs_uniform_locations(gl_info, program_id, &entry->vs,
+    shader_glsl_init_vs_uniform_locations(gl_info, priv, program_id, &entry->vs,
             vshader ? min(vshader->limits->constant_float, gl_info->limits.glsl_vs_float_constants) : 0);
-    shader_glsl_init_ps_uniform_locations(gl_info, program_id, &entry->ps,
+    shader_glsl_init_ps_uniform_locations(gl_info, priv, program_id, &entry->ps,
             pshader ? min(pshader->limits->constant_float, gl_info->limits.glsl_ps_float_constants) : 0);
     checkGLcall("Find glsl program uniform locations");
 
@@ -6431,7 +6440,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
      * supports enough samplers to allow the max number of vertex samplers with all possible
      * fixed function fragment processing setups. So once the program is linked these samplers
      * won't change. */
-    shader_glsl_load_samplers(gl_info, context->tex_unit_map, program_id);
+    shader_glsl_load_samplers(gl_info, priv, context->tex_unit_map, program_id);
 
     entry->constant_update_mask = 0;
     if (vshader)
@@ -6443,7 +6452,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
             entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_B;
         entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP;
 
-        shader_glsl_init_uniform_block_bindings(gl_info, program_id, &vshader->reg_maps,
+        shader_glsl_init_uniform_block_bindings(gl_info, priv, program_id, &vshader->reg_maps,
                 0, gl_info->limits.vertex_uniform_blocks);
     }
     else
@@ -6453,7 +6462,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
     }
 
     if (gshader)
-        shader_glsl_init_uniform_block_bindings(gl_info, program_id, &gshader->reg_maps,
+        shader_glsl_init_uniform_block_bindings(gl_info, priv, program_id, &gshader->reg_maps,
                 gl_info->limits.vertex_uniform_blocks, gl_info->limits.geometry_uniform_blocks);
 
     if (ps_id)
@@ -6468,7 +6477,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
             if (entry->ps.ycorrection_location != -1)
                 entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_Y_CORR;
 
-            shader_glsl_init_uniform_block_bindings(gl_info, program_id, &pshader->reg_maps,
+            shader_glsl_init_uniform_block_bindings(gl_info, priv, program_id, &pshader->reg_maps,
                     gl_info->limits.vertex_uniform_blocks + gl_info->limits.geometry_uniform_blocks,
                     gl_info->limits.fragment_uniform_blocks);
         }
@@ -6926,6 +6935,8 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win
     struct fragment_caps fragment_caps;
     void *vertex_priv, *fragment_priv;
 
+    string_buffer_list_init(&priv->string_buffers);
+
     if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv)))
     {
         ERR("Failed to initialize vertex pipe.\n");
@@ -7018,6 +7029,7 @@ static void shader_glsl_free(struct wined3d_device *device)
     constant_heap_free(&priv->pconst_heap);
     constant_heap_free(&priv->vconst_heap);
     HeapFree(GetProcessHeap(), 0, priv->stack);
+    string_buffer_list_cleanup(&priv->string_buffers);
     string_buffer_free(&priv->shader_buffer);
     priv->fragment_pipe->free_private(device);
     priv->vertex_pipe->vp_free(device);
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 2d50ced..2a2cf3a 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -313,6 +313,71 @@ int shader_addline(struct wined3d_string_buffer *buffer, const char *format, ...
     return ret;
 }
 
+struct wined3d_string_buffer *string_buffer_get(struct wined3d_string_buffer_list *list)
+{
+    struct wined3d_string_buffer *buffer;
+
+    if (list_empty(&list->list))
+    {
+        buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer));
+        if (!buffer || !string_buffer_init(buffer))
+        {
+            ERR("Couldn't allocate buffer for temporary string.\n");
+            if (buffer)
+                HeapFree(GetProcessHeap(), 0, buffer);
+            return NULL;
+        }
+    }
+    else
+    {
+        buffer = LIST_ENTRY(list_head(&list->list), struct wined3d_string_buffer, entry);
+        list_remove(&buffer->entry);
+    }
+    string_buffer_clear(buffer);
+    return buffer;
+}
+
+static void string_buffer_vsprintf(struct wined3d_string_buffer *buffer, const char *format, va_list args)
+{
+    if (!buffer)
+        return;
+    string_buffer_clear(buffer);
+    shader_vaddline(buffer, format, args);
+}
+
+void string_buffer_sprintf(struct wined3d_string_buffer *buffer, const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+    string_buffer_vsprintf(buffer, format, args);
+    va_end(args);
+}
+
+void string_buffer_release(struct wined3d_string_buffer_list *list, struct wined3d_string_buffer *buffer)
+{
+    if (!buffer)
+        return;
+    list_add_head(&list->list, &buffer->entry);
+}
+
+void string_buffer_list_init(struct wined3d_string_buffer_list *list)
+{
+    list_init(&list->list);
+}
+
+void string_buffer_list_cleanup(struct wined3d_string_buffer_list *list)
+{
+    struct wined3d_string_buffer *buffer, *buffer_next;
+
+    LIST_FOR_EACH_ENTRY_SAFE(buffer, buffer_next, &list->list, struct wined3d_string_buffer, entry)
+    {
+        string_buffer_free(buffer);
+        HeapFree(GetProcessHeap(), 0, buffer);
+    }
+    list_init(&list->list);
+}
+
 /* Convert floating point offset relative to a register file to an absolute
  * offset for float constants. */
 static unsigned int shader_get_float_offset(enum wined3d_shader_register_type register_type, UINT register_idx)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index c840c10..deca62b 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -437,6 +437,7 @@ enum wined3d_shader_rel_op
 
 struct wined3d_string_buffer
 {
+    struct list entry;
     char *buffer;
     unsigned int buffer_size;
     unsigned int content_size;
@@ -2894,6 +2895,17 @@ struct wined3d_shader_limits
 #define PRINTF_ATTR(fmt,args)
 #endif
 
+struct wined3d_string_buffer_list
+{
+    struct list list;
+};
+
+struct wined3d_string_buffer *string_buffer_get(struct wined3d_string_buffer_list *list) DECLSPEC_HIDDEN;
+void string_buffer_sprintf(struct wined3d_string_buffer *buffer, const char *format, ...) PRINTF_ATTR(2, 3) DECLSPEC_HIDDEN;
+void string_buffer_release(struct wined3d_string_buffer_list *list, struct wined3d_string_buffer *buffer) DECLSPEC_HIDDEN;
+void string_buffer_list_init(struct wined3d_string_buffer_list *list) DECLSPEC_HIDDEN;
+void string_buffer_list_cleanup(struct wined3d_string_buffer_list *list) DECLSPEC_HIDDEN;
+
 int shader_addline(struct wined3d_string_buffer *buffer, const char *fmt, ...) PRINTF_ATTR(2,3) DECLSPEC_HIDDEN;
 int shader_vaddline(struct wined3d_string_buffer *buffer, const char *fmt, va_list args) DECLSPEC_HIDDEN;
 
-- 
2.0.5




More information about the wine-patches mailing list