Module: Mesa
Branch: master
Commit: af8d488ea5e13219c67c132a3edfa2e7a698746d
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=af8d488ea5e13219c67c132a3edfa2e7a698746d

Author: James Park <jpar...@lagfreegames.com>
Date:   Tue Aug  4 10:58:11 2020 -0700

util,ac,aco,radv: Cross-platform memstream API

POSIX memstream is not available on Windows.

Reviewed-by: Samuel Pitoiset <samuel.pitoi...@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7143>

---

 src/amd/common/ac_debug.c                      |  7 ++-
 src/amd/compiler/aco_assembler.cpp             |  7 ++-
 src/amd/compiler/aco_instruction_selection.cpp |  7 ++-
 src/amd/compiler/aco_interface.cpp             | 12 ++--
 src/amd/compiler/aco_optimizer.cpp             |  7 ++-
 src/amd/compiler/aco_validate.cpp              | 14 +++--
 src/amd/vulkan/radv_shader.c                   | 16 +++--
 src/util/memstream.c                           | 81 ++++++++++++++++++++++++++
 src/util/memstream.h                           | 67 +++++++++++++++++++++
 src/util/meson.build                           |  2 +
 10 files changed, 197 insertions(+), 23 deletions(-)

diff --git a/src/amd/common/ac_debug.c b/src/amd/common/ac_debug.c
index 246a89ee86a..5acf4928d0b 100644
--- a/src/amd/common/ac_debug.c
+++ b/src/amd/common/ac_debug.c
@@ -33,6 +33,7 @@
 
 #include "sid.h"
 #include "sid_tables.h"
+#include "util/memstream.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "util/u_string.h"
@@ -584,10 +585,12 @@ void ac_parse_ib_chunk(FILE *f, uint32_t *ib_ptr, int 
num_dw, const int *trace_i
 
    char *out;
    size_t outsize;
-   FILE *memf = open_memstream(&out, &outsize);
+   struct u_memstream mem;
+   u_memstream_open(&mem, &out, &outsize);
+   FILE *const memf = u_memstream_get(&mem);
    ib.f = memf;
    ac_do_parse_ib(memf, &ib);
-   fclose(memf);
+   u_memstream_close(&mem);
 
    if (out) {
       format_ib_output(f, out);
diff --git a/src/amd/compiler/aco_assembler.cpp 
b/src/amd/compiler/aco_assembler.cpp
index ac9339c99eb..755bed09e1a 100644
--- a/src/amd/compiler/aco_assembler.cpp
+++ b/src/amd/compiler/aco_assembler.cpp
@@ -5,6 +5,7 @@
 #include "aco_builder.h"
 #include "common/sid.h"
 #include "ac_shader_util.h"
+#include "util/memstream.h"
 #include "util/u_math.h"
 
 namespace aco {
@@ -83,11 +84,13 @@ void emit_instruction(asm_context& ctx, 
std::vector<uint32_t>& out, Instruction*
    if (opcode == (uint32_t)-1) {
       char *out;
       size_t outsize;
-      FILE *memf = open_memstream(&out, &outsize);
+      struct u_memstream mem;
+      u_memstream_open(&mem, &out, &outsize);
+      FILE *const memf = u_memstream_get(&mem);
 
       fprintf(memf, "Unsupported opcode: ");
       aco_print_instr(instr, memf);
-      fclose(memf);
+      u_memstream_close(&mem);
 
       aco_err(ctx.program, out);
       free(out);
diff --git a/src/amd/compiler/aco_instruction_selection.cpp 
b/src/amd/compiler/aco_instruction_selection.cpp
index 1da9ea41d98..c57b6709ac6 100644
--- a/src/amd/compiler/aco_instruction_selection.cpp
+++ b/src/amd/compiler/aco_instruction_selection.cpp
@@ -34,6 +34,7 @@
 #include "aco_interface.h"
 #include "aco_instruction_selection.h"
 #include "util/fast_idiv_by_const.h"
+#include "util/memstream.h"
 
 #include "ac_exp_param.h"
 #include "sid.h"
@@ -50,11 +51,13 @@ static void _isel_err(isel_context *ctx, const char *file, 
unsigned line,
 {
    char *out;
    size_t outsize;
-   FILE *memf = open_memstream(&out, &outsize);
+   struct u_memstream mem;
+   u_memstream_open(&mem, &out, &outsize);
+   FILE *const memf = u_memstream_get(&mem);
 
    fprintf(memf, "%s: ", msg);
    nir_print_instr(instr, memf);
-   fclose(memf);
+   u_memstream_close(&mem);
 
    _aco_err(ctx->program, file, line, out);
    free(out);
diff --git a/src/amd/compiler/aco_interface.cpp 
b/src/amd/compiler/aco_interface.cpp
index 9b3f88e8a26..55ddd19b638 100644
--- a/src/amd/compiler/aco_interface.cpp
+++ b/src/amd/compiler/aco_interface.cpp
@@ -23,6 +23,7 @@
 
 #include "aco_interface.h"
 #include "aco_ir.h"
+#include "util/memstream.h"
 #include "vulkan/radv_shader.h"
 #include "vulkan/radv_shader_args.h"
 
@@ -110,11 +111,12 @@ void aco_compile_shader(unsigned shader_count,
    if (args->options->record_ir) {
       char *data = NULL;
       size_t size = 0;
-      FILE *f = open_memstream(&data, &size);
-      if (f) {
-         aco_print_program(program.get(), f);
-         fputc(0, f);
-         fclose(f);
+      u_memstream mem;
+      if (u_memstream_open(&mem, &data, &size)) {
+         FILE *const memf = u_memstream_get(&mem);
+         aco_print_program(program.get(), memf);
+         fputc(0, memf);
+         u_memstream_close(&mem);
       }
 
       llvm_ir = std::string(data, data + size);
diff --git a/src/amd/compiler/aco_optimizer.cpp 
b/src/amd/compiler/aco_optimizer.cpp
index a21fb21d1fa..22497a10452 100644
--- a/src/amd/compiler/aco_optimizer.cpp
+++ b/src/amd/compiler/aco_optimizer.cpp
@@ -30,6 +30,7 @@
 
 #include "aco_ir.h"
 #include "util/half_float.h"
+#include "util/memstream.h"
 #include "util/u_math.h"
 
 namespace aco {
@@ -40,11 +41,13 @@ void perfwarn(Program *program, bool cond, const char *msg, 
Instruction *instr)
    if (cond) {
       char *out;
       size_t outsize;
-      FILE *memf = open_memstream(&out, &outsize);
+      struct u_memstream mem;
+      u_memstream_open(&mem, &out, &outsize);
+      FILE *const memf = u_memstream_get(&mem);
 
       fprintf(memf, "%s: ", msg);
       aco_print_instr(instr, memf);
-      fclose(memf);
+      u_memstream_close(&mem);
 
       aco_perfwarn(program, out);
       free(out);
diff --git a/src/amd/compiler/aco_validate.cpp 
b/src/amd/compiler/aco_validate.cpp
index d8886cd31b7..ef3b4c78cba 100644
--- a/src/amd/compiler/aco_validate.cpp
+++ b/src/amd/compiler/aco_validate.cpp
@@ -27,6 +27,8 @@
 #include <array>
 #include <map>
 
+#include "util/memstream.h"
+
 namespace aco {
 
 static void aco_log(Program *program, enum radv_compiler_debug_level level,
@@ -78,11 +80,13 @@ bool validate_ir(Program* program)
       if (!check) {
          char *out;
          size_t outsize;
-         FILE *memf = open_memstream(&out, &outsize);
+         struct u_memstream mem;
+         u_memstream_open(&mem, &out, &outsize);
+         FILE *const memf = u_memstream_get(&mem);
 
          fprintf(memf, "%s: ", msg);
          aco_print_instr(instr, memf);
-         fclose(memf);
+         u_memstream_close(&mem);
 
          aco_err(program, out);
          free(out);
@@ -520,7 +524,9 @@ bool ra_fail(Program *program, Location loc, Location loc2, 
const char *fmt, ...
 
    char *out;
    size_t outsize;
-   FILE *memf = open_memstream(&out, &outsize);
+   struct u_memstream mem;
+   u_memstream_open(&mem, &out, &outsize);
+   FILE *const memf = u_memstream_get(&mem);
 
    fprintf(memf, "RA error found at instruction in BB%d:\n", loc.block->index);
    if (loc.instr) {
@@ -534,7 +540,7 @@ bool ra_fail(Program *program, Location loc, Location loc2, 
const char *fmt, ...
       aco_print_instr(loc2.instr, memf);
    }
    fprintf(memf, "\n\n");
-   fclose(memf);
+   u_memstream_close(&mem);
 
    aco_err(program, out);
    free(out);
diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c
index 9d25b4f0b89..118c0bbeb08 100644
--- a/src/amd/vulkan/radv_shader.c
+++ b/src/amd/vulkan/radv_shader.c
@@ -25,6 +25,7 @@
  * IN THE SOFTWARE.
  */
 
+#include "util/memstream.h"
 #include "util/mesa-sha1.h"
 #include "util/u_atomic.h"
 #include "radv_debug.h"
@@ -1224,11 +1225,12 @@ radv_dump_nir_shaders(struct nir_shader * const 
*shaders,
        char *data = NULL;
        char *ret = NULL;
        size_t size = 0;
-       FILE *f = open_memstream(&data, &size);
-       if (f) {
+       struct u_memstream mem;
+       if (u_memstream_open(&mem, &data, &size)) {
+               FILE *const memf = u_memstream_get(&mem);
                for (int i = 0; i < shader_count; ++i)
-                       nir_print_shader(shaders[i], f);
-               fclose(f);
+                       nir_print_shader(shaders[i], memf);
+               u_memstream_close(&mem);
        }
 
        ret = malloc(size + 1);
@@ -1601,13 +1603,15 @@ radv_GetShaderInfoAMD(VkDevice _device,
        case VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD: {
                char *out;
                size_t outsize;
-               FILE *memf = open_memstream(&out, &outsize);
+               struct u_memstream mem;
+               u_memstream_open(&mem, &out, &outsize);
+               FILE *const memf = u_memstream_get(&mem);
 
                fprintf(memf, "%s:\n", radv_get_shader_name(&variant->info, 
stage));
                fprintf(memf, "%s\n\n", variant->ir_string);
                fprintf(memf, "%s\n\n", variant->disasm_string);
                radv_dump_shader_stats(device, pipeline, stage, memf);
-               fclose(memf);
+               u_memstream_close(&mem);
 
                /* Need to include the null terminator. */
                size_t length = outsize + 1;
diff --git a/src/util/memstream.c b/src/util/memstream.c
new file mode 100644
index 00000000000..f133a527341
--- /dev/null
+++ b/src/util/memstream.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2020 Lag Free Games, LLC
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "memstream.h"
+
+#include <stdlib.h>
+
+bool
+u_memstream_open(struct u_memstream *mem, char **bufp, size_t *sizep)
+{
+#ifdef _WIN32
+   bool success = false;
+
+   char path[MAX_PATH];
+   DWORD dwResult = GetTempPath(MAX_PATH, path);
+   if ((dwResult > 0) && (dwResult < MAX_PATH)) {
+      char *temp = mem->temp;
+      UINT uResult = GetTempFileName(path, "MEMSTREAM", 0, temp);
+      if (uResult != 0) {
+         FILE *f = fopen(temp, "w+b");
+         success = f != NULL;
+         if (success)
+         {
+            mem->f = f;
+            mem->bufp = bufp;
+            mem->sizep = sizep;
+         }
+      }
+   }
+
+   return success;
+#else
+   FILE *const f = open_memstream(bufp, sizep);
+   mem->f = f;
+   return f != NULL;
+#endif
+}
+
+void
+u_memstream_close(struct u_memstream *mem)
+{
+   FILE *const f = mem->f;
+
+#ifdef _WIN32
+   long size = ftell(f);
+   if (size > 0) {
+      char *buf = malloc(size);
+      fseek(f, 0, SEEK_SET);
+      fread(buf, 1, size, f);
+
+      *mem->bufp = buf;
+      *mem->sizep = size;
+   }
+
+   remove(mem->temp);
+#endif
+
+   fclose(f);
+}
diff --git a/src/util/memstream.h b/src/util/memstream.h
new file mode 100644
index 00000000000..2d4be8257c1
--- /dev/null
+++ b/src/util/memstream.h
@@ -0,0 +1,67 @@
+/**************************************************************************
+ *
+ * Copyright 2020 Lag Free Games, LLC
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef MEMSTREAM_H
+#define MEMSTREAM_H
+
+#include <stdbool.h>
+#include <stdio.h>
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct u_memstream
+{
+   FILE *f;
+#ifdef _WIN32
+   char **bufp;
+   size_t *sizep;
+   char temp[MAX_PATH];
+#endif
+};
+
+extern bool
+u_memstream_open(struct u_memstream *mem, char **bufp, size_t *sizep);
+
+extern void
+u_memstream_close(struct u_memstream *mem);
+
+static inline FILE *
+u_memstream_get(const struct u_memstream *mem)
+{
+   return mem->f;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/util/meson.build b/src/util/meson.build
index 7c0e37cf1ed..f38b725f251 100644
--- a/src/util/meson.build
+++ b/src/util/meson.build
@@ -61,6 +61,8 @@ files_mesa_util = files(
   'list.h',
   'log.c',
   'macros.h',
+  'memstream.c',
+  'memstream.h',
   'mesa-sha1.c',
   'mesa-sha1.h',
   'os_time.c',

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to