Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/r300/compiler/radeon_inline_literals.c
4574 views
1
/*
2
* Copyright 2012 Advanced Micro Devices, Inc.
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* on the rights to use, copy, modify, merge, publish, distribute, sub
8
* license, and/or sell copies of the Software, and to permit persons to whom
9
* the Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21
* USE OR OTHER DEALINGS IN THE SOFTWARE.
22
*
23
* Author: Tom Stellard <[email protected]>
24
*/
25
26
#include "radeon_compiler.h"
27
#include "radeon_compiler_util.h"
28
#include "radeon_dataflow.h"
29
#include "radeon_program.h"
30
#include "radeon_program_constants.h"
31
#include "util/u_bitcast.h"
32
#include <stdio.h>
33
34
#define VERBOSE 0
35
36
#define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0)
37
38
/* IEEE-754:
39
* 22:0 mantissa
40
* 30:23 exponent
41
* 31 sign
42
*
43
* R300:
44
* 0:2 mantissa
45
* 3:6 exponent (bias 7)
46
*/
47
static int ieee_754_to_r300_float(float f, unsigned char *r300_float_out)
48
{
49
unsigned float_bits = u_bitcast_f2u(f);
50
/* XXX: Handle big-endian */
51
unsigned mantissa = float_bits & 0x007fffff;
52
unsigned biased_exponent = (float_bits & 0x7f800000) >> 23;
53
unsigned negate = !!(float_bits & 0x80000000);
54
int exponent = biased_exponent - 127;
55
unsigned mantissa_mask = 0xff8fffff;
56
unsigned r300_exponent, r300_mantissa;
57
58
DBG("Converting %f (0x%x) to 7-bit:\n", f, float_bits);
59
DBG("Raw exponent = %d\n", exponent);
60
61
if (exponent < -7 || exponent > 8) {
62
DBG("Failed exponent out of range\n\n");
63
return 0;
64
}
65
66
if (mantissa & mantissa_mask) {
67
DBG("Failed mantissa has too many bits:\n"
68
"mantissa=0x%x mantissa_mask=0x%x, and=0x%x\n\n",
69
mantissa, mantissa_mask,
70
mantissa & mantissa_mask);
71
return 0;
72
}
73
74
r300_exponent = exponent + 7;
75
r300_mantissa = (mantissa & ~mantissa_mask) >> 20;
76
*r300_float_out = r300_mantissa | (r300_exponent << 3);
77
78
DBG("Success! r300_float = 0x%x\n\n", *r300_float_out);
79
80
if (negate)
81
return -1;
82
else
83
return 1;
84
}
85
86
void rc_inline_literals(struct radeon_compiler *c, void *user)
87
{
88
struct rc_instruction * inst;
89
90
for(inst = c->Program.Instructions.Next;
91
inst != &c->Program.Instructions;
92
inst = inst->Next) {
93
const struct rc_opcode_info * info =
94
rc_get_opcode_info(inst->U.I.Opcode);
95
96
unsigned src_idx;
97
struct rc_constant * constant;
98
float float_value;
99
unsigned char r300_float = 0;
100
int ret;
101
102
/* XXX: Handle presub */
103
104
/* We aren't using rc_for_all_reads_src here, because presub
105
* sources need to be handled differently. */
106
for (src_idx = 0; src_idx < info->NumSrcRegs; src_idx++) {
107
unsigned new_swizzle;
108
unsigned use_literal = 0;
109
unsigned negate_mask = 0;
110
unsigned swz, chan;
111
struct rc_src_register * src_reg =
112
&inst->U.I.SrcReg[src_idx];
113
swz = RC_SWIZZLE_UNUSED;
114
if (src_reg->File != RC_FILE_CONSTANT) {
115
continue;
116
}
117
constant =
118
&c->Program.Constants.Constants[src_reg->Index];
119
if (constant->Type != RC_CONSTANT_IMMEDIATE) {
120
continue;
121
}
122
new_swizzle = rc_init_swizzle(RC_SWIZZLE_UNUSED, 0);
123
for (chan = 0; chan < 4; chan++) {
124
unsigned char r300_float_tmp;
125
swz = GET_SWZ(src_reg->Swizzle, chan);
126
if (swz == RC_SWIZZLE_UNUSED) {
127
continue;
128
}
129
float_value = constant->u.Immediate[swz];
130
ret = ieee_754_to_r300_float(float_value,
131
&r300_float_tmp);
132
if (!ret || (use_literal &&
133
r300_float != r300_float_tmp)) {
134
use_literal = 0;
135
break;
136
}
137
138
if (ret == -1 && src_reg->Abs) {
139
use_literal = 0;
140
break;
141
}
142
143
if (!use_literal) {
144
r300_float = r300_float_tmp;
145
use_literal = 1;
146
}
147
148
/* Use RC_SWIZZLE_W for the inline constant, so
149
* it will become one of the alpha sources. */
150
SET_SWZ(new_swizzle, chan, RC_SWIZZLE_W);
151
if (ret == -1) {
152
negate_mask |= (1 << chan);
153
}
154
}
155
156
if (!use_literal) {
157
continue;
158
}
159
src_reg->File = RC_FILE_INLINE;
160
src_reg->Index = r300_float;
161
src_reg->Swizzle = new_swizzle;
162
src_reg->Negate = src_reg->Negate ^ negate_mask;
163
}
164
}
165
}
166
167