mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 00:10:10 +01:00
util,ac,aco,radv: Cross-platform memstream API
POSIX memstream is not available on Windows. Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7143>
This commit is contained in:
parent
4c2e7b0893
commit
af8d488ea5
10 changed files with 197 additions and 23 deletions
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "sid.h"
|
#include "sid.h"
|
||||||
#include "sid_tables.h"
|
#include "sid_tables.h"
|
||||||
|
#include "util/memstream.h"
|
||||||
#include "util/u_math.h"
|
#include "util/u_math.h"
|
||||||
#include "util/u_memory.h"
|
#include "util/u_memory.h"
|
||||||
#include "util/u_string.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;
|
char *out;
|
||||||
size_t outsize;
|
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;
|
ib.f = memf;
|
||||||
ac_do_parse_ib(memf, &ib);
|
ac_do_parse_ib(memf, &ib);
|
||||||
fclose(memf);
|
u_memstream_close(&mem);
|
||||||
|
|
||||||
if (out) {
|
if (out) {
|
||||||
format_ib_output(f, out);
|
format_ib_output(f, out);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include "aco_builder.h"
|
#include "aco_builder.h"
|
||||||
#include "common/sid.h"
|
#include "common/sid.h"
|
||||||
#include "ac_shader_util.h"
|
#include "ac_shader_util.h"
|
||||||
|
#include "util/memstream.h"
|
||||||
#include "util/u_math.h"
|
#include "util/u_math.h"
|
||||||
|
|
||||||
namespace aco {
|
namespace aco {
|
||||||
|
|
@ -83,11 +84,13 @@ void emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction*
|
||||||
if (opcode == (uint32_t)-1) {
|
if (opcode == (uint32_t)-1) {
|
||||||
char *out;
|
char *out;
|
||||||
size_t outsize;
|
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: ");
|
fprintf(memf, "Unsupported opcode: ");
|
||||||
aco_print_instr(instr, memf);
|
aco_print_instr(instr, memf);
|
||||||
fclose(memf);
|
u_memstream_close(&mem);
|
||||||
|
|
||||||
aco_err(ctx.program, out);
|
aco_err(ctx.program, out);
|
||||||
free(out);
|
free(out);
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
#include "aco_interface.h"
|
#include "aco_interface.h"
|
||||||
#include "aco_instruction_selection.h"
|
#include "aco_instruction_selection.h"
|
||||||
#include "util/fast_idiv_by_const.h"
|
#include "util/fast_idiv_by_const.h"
|
||||||
|
#include "util/memstream.h"
|
||||||
|
|
||||||
#include "ac_exp_param.h"
|
#include "ac_exp_param.h"
|
||||||
#include "sid.h"
|
#include "sid.h"
|
||||||
|
|
@ -50,11 +51,13 @@ static void _isel_err(isel_context *ctx, const char *file, unsigned line,
|
||||||
{
|
{
|
||||||
char *out;
|
char *out;
|
||||||
size_t outsize;
|
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);
|
fprintf(memf, "%s: ", msg);
|
||||||
nir_print_instr(instr, memf);
|
nir_print_instr(instr, memf);
|
||||||
fclose(memf);
|
u_memstream_close(&mem);
|
||||||
|
|
||||||
_aco_err(ctx->program, file, line, out);
|
_aco_err(ctx->program, file, line, out);
|
||||||
free(out);
|
free(out);
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "aco_interface.h"
|
#include "aco_interface.h"
|
||||||
#include "aco_ir.h"
|
#include "aco_ir.h"
|
||||||
|
#include "util/memstream.h"
|
||||||
#include "vulkan/radv_shader.h"
|
#include "vulkan/radv_shader.h"
|
||||||
#include "vulkan/radv_shader_args.h"
|
#include "vulkan/radv_shader_args.h"
|
||||||
|
|
||||||
|
|
@ -110,11 +111,12 @@ void aco_compile_shader(unsigned shader_count,
|
||||||
if (args->options->record_ir) {
|
if (args->options->record_ir) {
|
||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
FILE *f = open_memstream(&data, &size);
|
u_memstream mem;
|
||||||
if (f) {
|
if (u_memstream_open(&mem, &data, &size)) {
|
||||||
aco_print_program(program.get(), f);
|
FILE *const memf = u_memstream_get(&mem);
|
||||||
fputc(0, f);
|
aco_print_program(program.get(), memf);
|
||||||
fclose(f);
|
fputc(0, memf);
|
||||||
|
u_memstream_close(&mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm_ir = std::string(data, data + size);
|
llvm_ir = std::string(data, data + size);
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "aco_ir.h"
|
#include "aco_ir.h"
|
||||||
#include "util/half_float.h"
|
#include "util/half_float.h"
|
||||||
|
#include "util/memstream.h"
|
||||||
#include "util/u_math.h"
|
#include "util/u_math.h"
|
||||||
|
|
||||||
namespace aco {
|
namespace aco {
|
||||||
|
|
@ -40,11 +41,13 @@ void perfwarn(Program *program, bool cond, const char *msg, Instruction *instr)
|
||||||
if (cond) {
|
if (cond) {
|
||||||
char *out;
|
char *out;
|
||||||
size_t outsize;
|
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);
|
fprintf(memf, "%s: ", msg);
|
||||||
aco_print_instr(instr, memf);
|
aco_print_instr(instr, memf);
|
||||||
fclose(memf);
|
u_memstream_close(&mem);
|
||||||
|
|
||||||
aco_perfwarn(program, out);
|
aco_perfwarn(program, out);
|
||||||
free(out);
|
free(out);
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include "util/memstream.h"
|
||||||
|
|
||||||
namespace aco {
|
namespace aco {
|
||||||
|
|
||||||
static void aco_log(Program *program, enum radv_compiler_debug_level level,
|
static void aco_log(Program *program, enum radv_compiler_debug_level level,
|
||||||
|
|
@ -78,11 +80,13 @@ bool validate_ir(Program* program)
|
||||||
if (!check) {
|
if (!check) {
|
||||||
char *out;
|
char *out;
|
||||||
size_t outsize;
|
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);
|
fprintf(memf, "%s: ", msg);
|
||||||
aco_print_instr(instr, memf);
|
aco_print_instr(instr, memf);
|
||||||
fclose(memf);
|
u_memstream_close(&mem);
|
||||||
|
|
||||||
aco_err(program, out);
|
aco_err(program, out);
|
||||||
free(out);
|
free(out);
|
||||||
|
|
@ -520,7 +524,9 @@ bool ra_fail(Program *program, Location loc, Location loc2, const char *fmt, ...
|
||||||
|
|
||||||
char *out;
|
char *out;
|
||||||
size_t outsize;
|
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);
|
fprintf(memf, "RA error found at instruction in BB%d:\n", loc.block->index);
|
||||||
if (loc.instr) {
|
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);
|
aco_print_instr(loc2.instr, memf);
|
||||||
}
|
}
|
||||||
fprintf(memf, "\n\n");
|
fprintf(memf, "\n\n");
|
||||||
fclose(memf);
|
u_memstream_close(&mem);
|
||||||
|
|
||||||
aco_err(program, out);
|
aco_err(program, out);
|
||||||
free(out);
|
free(out);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "util/memstream.h"
|
||||||
#include "util/mesa-sha1.h"
|
#include "util/mesa-sha1.h"
|
||||||
#include "util/u_atomic.h"
|
#include "util/u_atomic.h"
|
||||||
#include "radv_debug.h"
|
#include "radv_debug.h"
|
||||||
|
|
@ -1224,11 +1225,12 @@ radv_dump_nir_shaders(struct nir_shader * const *shaders,
|
||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
char *ret = NULL;
|
char *ret = NULL;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
FILE *f = open_memstream(&data, &size);
|
struct u_memstream mem;
|
||||||
if (f) {
|
if (u_memstream_open(&mem, &data, &size)) {
|
||||||
|
FILE *const memf = u_memstream_get(&mem);
|
||||||
for (int i = 0; i < shader_count; ++i)
|
for (int i = 0; i < shader_count; ++i)
|
||||||
nir_print_shader(shaders[i], f);
|
nir_print_shader(shaders[i], memf);
|
||||||
fclose(f);
|
u_memstream_close(&mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = malloc(size + 1);
|
ret = malloc(size + 1);
|
||||||
|
|
@ -1601,13 +1603,15 @@ radv_GetShaderInfoAMD(VkDevice _device,
|
||||||
case VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD: {
|
case VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD: {
|
||||||
char *out;
|
char *out;
|
||||||
size_t outsize;
|
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", radv_get_shader_name(&variant->info, stage));
|
||||||
fprintf(memf, "%s\n\n", variant->ir_string);
|
fprintf(memf, "%s\n\n", variant->ir_string);
|
||||||
fprintf(memf, "%s\n\n", variant->disasm_string);
|
fprintf(memf, "%s\n\n", variant->disasm_string);
|
||||||
radv_dump_shader_stats(device, pipeline, stage, memf);
|
radv_dump_shader_stats(device, pipeline, stage, memf);
|
||||||
fclose(memf);
|
u_memstream_close(&mem);
|
||||||
|
|
||||||
/* Need to include the null terminator. */
|
/* Need to include the null terminator. */
|
||||||
size_t length = outsize + 1;
|
size_t length = outsize + 1;
|
||||||
|
|
|
||||||
81
src/util/memstream.c
Normal file
81
src/util/memstream.c
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
67
src/util/memstream.h
Normal file
67
src/util/memstream.h
Normal file
|
|
@ -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
|
||||||
|
|
@ -61,6 +61,8 @@ files_mesa_util = files(
|
||||||
'list.h',
|
'list.h',
|
||||||
'log.c',
|
'log.c',
|
||||||
'macros.h',
|
'macros.h',
|
||||||
|
'memstream.c',
|
||||||
|
'memstream.h',
|
||||||
'mesa-sha1.c',
|
'mesa-sha1.c',
|
||||||
'mesa-sha1.h',
|
'mesa-sha1.h',
|
||||||
'os_time.c',
|
'os_time.c',
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue