Parcourir la source

r300/compiler: implement elimination of unused constants

Wine likes to create a *lot* of constants, exceeding the size of the constant
file in hw.
tags/mesa-7.9-rc1
Marek Olšák il y a 16 ans
Parent
révision
574ba4b5f5

+ 1
- 0
src/mesa/drivers/dri/r300/compiler/Makefile Voir le fichier

@@ -23,6 +23,7 @@ C_SOURCES = \
radeon_dataflow_deadcode.c \
radeon_dataflow_swizzles.c \
radeon_optimize.c \
radeon_remove_constants.c \
radeon_rename_regs.c \
r3xx_fragprog.c \
r300_fragprog.c \

+ 1
- 0
src/mesa/drivers/dri/r300/compiler/SConscript Voir le fichier

@@ -22,6 +22,7 @@ r300compiler = env.ConvenienceLibrary(
'radeon_pair_schedule.c',
'radeon_pair_regalloc.c',
'radeon_optimize.c',
'radeon_remove_constants.c'
'radeon_rename_regs.c',
'radeon_emulate_branches.c',
'radeon_emulate_loops.c',

+ 8
- 0
src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c Voir le fichier

@@ -30,6 +30,7 @@
#include "radeon_program_alu.h"
#include "radeon_program_tex.h"
#include "radeon_rename_regs.h"
#include "radeon_remove_constants.h"
#include "r300_fragprog.h"
#include "r300_fragprog_swizzle.h"
#include "r500_fragprog.h"
@@ -180,6 +181,13 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)

debug_program_log(c, "after dataflow passes");

if (c->Base.remove_unused_constants) {
rc_remove_unused_constants(&c->Base,
&c->code->constants_remap_table);

debug_program_log(c, "after constants cleanup");
}

if(!c->Base.is_r500) {
/* This pass makes it easier for the scheduler to group TEX
* instructions and reduces the chances of creating too

+ 9
- 0
src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c Voir le fichier

@@ -31,6 +31,7 @@
#include "radeon_swizzle.h"
#include "radeon_emulate_branches.h"
#include "radeon_emulate_loops.h"
#include "radeon_remove_constants.h"

struct loop {
int BgnLoop;
@@ -993,6 +994,14 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler *c)

debug_program_log(c, "after register allocation");

if (c->Base.remove_unused_constants) {
rc_remove_unused_constants(&c->Base,
&c->code->constants_remap_table);
if (c->Base.Error)
return;

debug_program_log(c, "after constants cleanup");
}

translate_vertex_program(c);
if (c->Base.Error)

+ 2
- 0
src/mesa/drivers/dri/r300/compiler/radeon_code.h Voir le fichier

@@ -235,6 +235,7 @@ struct rX00_fragment_program_code {
unsigned writes_depth:1;

struct rc_constant_list constants;
unsigned *constants_remap_table;
};


@@ -266,6 +267,7 @@ struct r300_vertex_program_code {
int outputs[VSF_MAX_OUTPUTS];

struct rc_constant_list constants;
unsigned *constants_remap_table;

uint32_t InputsRead;
uint32_t OutputsWritten;

+ 4
- 1
src/mesa/drivers/dri/r300/compiler/radeon_compiler.h Voir le fichier

@@ -39,9 +39,12 @@ struct radeon_compiler {
char * ErrorMsg;

/* Hardware specification. */
unsigned is_r500;
unsigned is_r500:1;
unsigned max_temp_regs;

/* Whether to remove unused constants and empty holes in constant space. */
unsigned remove_unused_constants:1;

/**
* Variables used internally, not be touched by callers
* of the compiler

+ 128
- 0
src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.c Voir le fichier

@@ -0,0 +1,128 @@
/*
* Copyright (C) 2010 Marek Olšák <maraeo@gmail.com>
*
* 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, sublicense, 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 NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "radeon_remove_constants.h"

void rc_remove_unused_constants(struct radeon_compiler *c,
unsigned **out_remap_table)
{
unsigned char *const_used;
unsigned *remap_table;
unsigned *inv_remap_table;
unsigned has_rel_addr = 0;
unsigned is_identity = 1;
unsigned are_externals_remapped = 0;
struct rc_constant *constants = c->Program.Constants.Constants;

if (!c->Program.Constants.Count) {
*out_remap_table = NULL;
return;
}

const_used = malloc(c->Program.Constants.Count);
memset(const_used, 0, c->Program.Constants.Count);

/* Pass 1: Mark used constants. */
for (struct rc_instruction *inst = c->Program.Instructions.Next;
inst != &c->Program.Instructions; inst = inst->Next) {
const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->U.I.Opcode);

for (unsigned i = 0; i < opcode->NumSrcRegs; i++) {
if (inst->U.I.SrcReg[i].File == RC_FILE_CONSTANT) {
if (inst->U.I.SrcReg[i].RelAddr) {
has_rel_addr = 1;
} else {
const_used[inst->U.I.SrcReg[i].Index] = 1;
}
}
}
}

/* Pass 2: If there is relative addressing, mark all externals as used. */
if (has_rel_addr) {
for (unsigned i = 0; i < c->Program.Constants.Count; i++)
if (constants[i].Type == RC_CONSTANT_EXTERNAL)
const_used[i] = 1;
}

/* Pass 3: Make the remapping table and remap constants.
* This pass removes unused constants simply by overwriting them by other constants. */
remap_table = malloc(c->Program.Constants.Count * sizeof(unsigned));
inv_remap_table = malloc(c->Program.Constants.Count * sizeof(unsigned));
unsigned new_count = 0;

for (unsigned i = 0; i < c->Program.Constants.Count; i++) {
if (const_used[i]) {
remap_table[new_count] = i;
inv_remap_table[i] = new_count;

if (i != new_count) {
if (constants[i].Type == RC_CONSTANT_EXTERNAL)
are_externals_remapped = 1;

constants[new_count] = constants[i];
is_identity = 0;
}
new_count++;
}
}

/* is_identity ==> new_count == old_count
* !is_identity ==> new_count < old_count */
assert( is_identity || new_count < c->Program.Constants.Count);
assert(!(has_rel_addr && are_externals_remapped));

/* Pass 4: Redirect reads of all constants to their new locations. */
if (!is_identity) {
for (struct rc_instruction *inst = c->Program.Instructions.Next;
inst != &c->Program.Instructions; inst = inst->Next) {
const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->U.I.Opcode);

for (unsigned i = 0; i < opcode->NumSrcRegs; i++) {
if (inst->U.I.SrcReg[i].File == RC_FILE_CONSTANT) {
inst->U.I.SrcReg[i].Index = inv_remap_table[inst->U.I.SrcReg[i].Index];
}
}
}

}

/* Set the new constant count. Note that new_count may be less than
* Count even though the remapping function is identity. In that case,
* the constants have been removed at the end of the array. */
c->Program.Constants.Count = new_count;

if (are_externals_remapped) {
*out_remap_table = remap_table;
} else {
*out_remap_table = NULL;
free(remap_table);
}

free(const_used);
free(inv_remap_table);
}

+ 36
- 0
src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.h Voir le fichier

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2010 Marek Olšák <maraeo@gmail.com>
*
* 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, sublicense, 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 NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 RADEON_REMOVE_CONSTANTS_H
#define RADEON_REMOVE_CONSTANTS_H

#include "radeon_compiler.h"

void rc_remove_unused_constants(struct radeon_compiler *c,
unsigned **out_remap_table);

#endif

Chargement…
Annuler
Enregistrer