~ubuntu-branches/ubuntu/precise/mesa/precise-updates

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/r300/r300_blit.c

  • Committer: Package Import Robot
  • Author(s): Robert Hooker
  • Date: 2012-02-02 12:05:48 UTC
  • mfrom: (1.7.1) (3.3.27 sid)
  • Revision ID: package-import@ubuntu.com-20120202120548-nvkma85jq0h4coix
Tags: 8.0~rc2-0ubuntu4
Drop drisearchdir handling, it is no longer needed with multiarch
and dri-alternates being removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com>
3
 
 *
4
 
 * All Rights Reserved.
5
 
 *
6
 
 * Permission is hereby granted, free of charge, to any person obtaining
7
 
 * a copy of this software and associated documentation files (the
8
 
 * "Software"), to deal in the Software without restriction, including
9
 
 * without limitation the rights to use, copy, modify, merge, publish,
10
 
 * distribute, sublicense, and/or sell copies of the Software, and to
11
 
 * permit persons to whom the Software is furnished to do so, subject to
12
 
 * the following conditions:
13
 
 *
14
 
 * The above copyright notice and this permission notice (including the
15
 
 * next paragraph) shall be included in all copies or substantial
16
 
 * portions of the Software.
17
 
 *
18
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21
 
 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22
 
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
 
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
 
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 
 *
26
 
 */
27
 
 
28
 
#include "radeon_common.h"
29
 
#include "r300_context.h"
30
 
 
31
 
#include "r300_blit.h"
32
 
#include "r300_cmdbuf.h"
33
 
#include "r300_emit.h"
34
 
#include "r300_tex.h"
35
 
#include "compiler/radeon_compiler.h"
36
 
#include "compiler/radeon_opcodes.h"
37
 
 
38
 
static void vp_ins_outs(struct r300_vertex_program_compiler *c)
39
 
{
40
 
    c->code->inputs[VERT_ATTRIB_POS] = 0;
41
 
    c->code->inputs[VERT_ATTRIB_TEX0] = 1;
42
 
    c->code->outputs[VERT_RESULT_HPOS] = 0;
43
 
    c->code->outputs[VERT_RESULT_TEX0] = 1;
44
 
}
45
 
 
46
 
static void fp_allocate_hw_inputs(
47
 
    struct r300_fragment_program_compiler * c,
48
 
    void (*allocate)(void * data, unsigned input, unsigned hwreg),
49
 
    void * mydata)
50
 
{
51
 
    allocate(mydata, FRAG_ATTRIB_TEX0, 0);
52
 
}
53
 
 
54
 
static void create_vertex_program(struct r300_context *r300)
55
 
{
56
 
    struct r300_vertex_program_compiler compiler;
57
 
    struct rc_instruction *inst;
58
 
 
59
 
    memset(&compiler, 0, sizeof(compiler));
60
 
    rc_init(&compiler.Base);
61
 
 
62
 
    inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
63
 
    inst->U.I.Opcode = RC_OPCODE_MOV;
64
 
    inst->U.I.DstReg.File = RC_FILE_OUTPUT;
65
 
    inst->U.I.DstReg.Index = VERT_RESULT_HPOS;
66
 
    inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
67
 
    inst->U.I.SrcReg[0].Abs = 0;
68
 
    inst->U.I.SrcReg[0].File = RC_FILE_INPUT;
69
 
    inst->U.I.SrcReg[0].Index = VERT_ATTRIB_POS;
70
 
    inst->U.I.SrcReg[0].Negate = 0;
71
 
    inst->U.I.SrcReg[0].RelAddr = 0;
72
 
    inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
73
 
 
74
 
    inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
75
 
    inst->U.I.Opcode = RC_OPCODE_MOV;
76
 
    inst->U.I.DstReg.File = RC_FILE_OUTPUT;
77
 
    inst->U.I.DstReg.Index = VERT_RESULT_TEX0;
78
 
    inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
79
 
    inst->U.I.SrcReg[0].Abs = 0;
80
 
    inst->U.I.SrcReg[0].File = RC_FILE_INPUT;
81
 
    inst->U.I.SrcReg[0].Index = VERT_ATTRIB_TEX0;
82
 
    inst->U.I.SrcReg[0].Negate = 0;
83
 
    inst->U.I.SrcReg[0].RelAddr = 0;
84
 
    inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
85
 
 
86
 
    compiler.Base.Program.InputsRead = (1 << VERT_ATTRIB_POS) | (1 << VERT_ATTRIB_TEX0);
87
 
    compiler.RequiredOutputs = compiler.Base.Program.OutputsWritten = (1 << VERT_RESULT_HPOS) | (1 << VERT_RESULT_TEX0);
88
 
    compiler.SetHwInputOutput = vp_ins_outs;
89
 
    compiler.code = &r300->blit.vp_code;
90
 
    compiler.Base.is_r500 = r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515;
91
 
    compiler.Base.disable_optimizations = 0;
92
 
    compiler.Base.has_half_swizzles = 0;
93
 
    compiler.Base.max_temp_regs = 32;
94
 
    compiler.Base.max_constants = 256;
95
 
    compiler.Base.max_alu_insts = compiler.Base.is_r500 ? 1024 : 256;
96
 
 
97
 
    r3xx_compile_vertex_program(&compiler);
98
 
}
99
 
 
100
 
static void create_fragment_program(struct r300_context *r300)
101
 
{
102
 
    struct r300_fragment_program_compiler compiler;
103
 
    struct rc_instruction *inst;
104
 
 
105
 
    memset(&compiler, 0, sizeof(struct r300_fragment_program_compiler));
106
 
    rc_init(&compiler.Base);
107
 
 
108
 
    inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
109
 
    inst->U.I.Opcode = RC_OPCODE_TEX;
110
 
    inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
111
 
    inst->U.I.TexSrcUnit = 0;
112
 
    inst->U.I.DstReg.File = RC_FILE_OUTPUT;
113
 
    inst->U.I.DstReg.Index = FRAG_RESULT_COLOR;
114
 
    inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
115
 
    inst->U.I.SrcReg[0].Abs = 0;
116
 
    inst->U.I.SrcReg[0].File = RC_FILE_INPUT;
117
 
    inst->U.I.SrcReg[0].Index = FRAG_ATTRIB_TEX0;
118
 
    inst->U.I.SrcReg[0].Negate = 0;
119
 
    inst->U.I.SrcReg[0].RelAddr = 0;
120
 
    inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
121
 
    inst->U.I.TexSwizzle = RC_SWIZZLE_XYZW;
122
 
 
123
 
    compiler.Base.Program.InputsRead = (1 << FRAG_ATTRIB_TEX0);
124
 
    compiler.OutputColor[0] = FRAG_RESULT_COLOR;
125
 
    compiler.OutputDepth = FRAG_RESULT_DEPTH;
126
 
    compiler.enable_shadow_ambient = GL_TRUE;
127
 
    compiler.Base.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515);
128
 
    compiler.Base.disable_optimizations = 0;
129
 
    compiler.Base.has_half_swizzles = 1;
130
 
    compiler.Base.max_temp_regs = (compiler.Base.is_r500) ? 128 : 32;
131
 
    compiler.Base.max_constants = compiler.Base.is_r500 ? 256 : 32;
132
 
    compiler.Base.max_alu_insts = compiler.Base.is_r500 ? 512 : 64;
133
 
    compiler.Base.max_tex_insts = compiler.Base.is_r500 ? 512 : 32;
134
 
    compiler.code = &r300->blit.fp_code;
135
 
    compiler.AllocateHwInputs = fp_allocate_hw_inputs;
136
 
 
137
 
    r3xx_compile_fragment_program(&compiler);
138
 
}
139
 
 
140
 
void r300_blit_init(struct r300_context *r300)
141
 
{
142
 
    if (r300->options.hw_tcl_enabled)
143
 
        create_vertex_program(r300);
144
 
    create_fragment_program(r300);
145
 
}
146
 
 
147
 
static void r300_emit_tx_setup(struct r300_context *r300,
148
 
                               gl_format mesa_format,
149
 
                               struct radeon_bo *bo,
150
 
                               intptr_t offset,
151
 
                               unsigned width,
152
 
                               unsigned height,
153
 
                               unsigned pitch)
154
 
{
155
 
    int is_r500 = r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515;
156
 
    BATCH_LOCALS(&r300->radeon);
157
 
 
158
 
    assert(is_r500 ? width  <= 4096 : width  <= 2048);
159
 
    assert(is_r500 ? height <= 4096 : height <= 2048);
160
 
    assert(r300TranslateTexFormat(mesa_format) >= 0);
161
 
    assert(offset % 32 == 0);
162
 
 
163
 
    BEGIN_BATCH(17);
164
 
    OUT_BATCH_REGVAL(R300_TX_FILTER0_0,
165
 
                     (R300_TX_CLAMP_TO_EDGE  << R300_TX_WRAP_S_SHIFT) |
166
 
                     (R300_TX_CLAMP_TO_EDGE  << R300_TX_WRAP_T_SHIFT) |
167
 
                     (R300_TX_CLAMP_TO_EDGE  << R300_TX_WRAP_R_SHIFT) |
168
 
                     R300_TX_MIN_FILTER_MIP_NONE |
169
 
                     R300_TX_MIN_FILTER_NEAREST |
170
 
                     R300_TX_MAG_FILTER_NEAREST |
171
 
                     (0 << 28));
172
 
    OUT_BATCH_REGVAL(R300_TX_FILTER1_0, 0);
173
 
    OUT_BATCH_REGVAL(R300_TX_SIZE_0,
174
 
                     (((width  - 1) & 0x7ff) << R300_TX_WIDTHMASK_SHIFT) |
175
 
                     (((height - 1) & 0x7ff) << R300_TX_HEIGHTMASK_SHIFT) |
176
 
                     (0 << R300_TX_DEPTHMASK_SHIFT) |
177
 
                     (0 << R300_TX_MAX_MIP_LEVEL_SHIFT) |
178
 
                     R300_TX_SIZE_TXPITCH_EN);
179
 
 
180
 
    OUT_BATCH_REGVAL(R300_TX_FORMAT_0, r300TranslateTexFormat(mesa_format));
181
 
    OUT_BATCH_REGVAL(R300_TX_FORMAT2_0,
182
 
                     (pitch - 1) |
183
 
                     (is_r500 && width  > 2048 ? R500_TXWIDTH_BIT11  : 0) |
184
 
                     (is_r500 && height > 2048 ? R500_TXHEIGHT_BIT11 : 0));
185
 
    OUT_BATCH_REGSEQ(R300_TX_OFFSET_0, 1);
186
 
    OUT_BATCH_RELOC(0, bo, offset, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
187
 
 
188
 
    OUT_BATCH_REGSEQ(R300_TX_INVALTAGS, 2);
189
 
    OUT_BATCH(0);
190
 
    OUT_BATCH(1);
191
 
 
192
 
    END_BATCH();
193
 
}
194
 
 
195
 
#define EASY_US_FORMAT(FMT, C0, C1, C2, C3, SIGN) \
196
 
    (FMT  | R500_C0_SEL_##C0 | R500_C1_SEL_##C1 | \
197
 
    R500_C2_SEL_##C2 | R500_C3_SEL_##C3 | R500_OUT_SIGN(SIGN))
198
 
 
199
 
static uint32_t mesa_format_to_us_format(gl_format mesa_format)
200
 
{
201
 
    switch(mesa_format)
202
 
    {
203
 
        case MESA_FORMAT_RGBA8888: // x
204
 
            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, B, G, R, 0);
205
 
        case MESA_FORMAT_RGB565: // x
206
 
        case MESA_FORMAT_ARGB1555: // x
207
 
        case MESA_FORMAT_RGBA8888_REV: // x
208
 
            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, R, G, B, A, 0);
209
 
        case MESA_FORMAT_ARGB8888: // x
210
 
            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, B, G, R, A, 0);
211
 
        case MESA_FORMAT_ARGB8888_REV:
212
 
            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, R, G, B, 0);
213
 
        case MESA_FORMAT_XRGB8888:
214
 
            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, R, G, B, 0);
215
 
 
216
 
        case MESA_FORMAT_RGB332:
217
 
            return EASY_US_FORMAT(R500_OUT_FMT_C_3_3_2, A, R, G, B, 0);
218
 
 
219
 
        case MESA_FORMAT_RGBA_FLOAT32:
220
 
            return EASY_US_FORMAT(R500_OUT_FMT_C4_32_FP, R, G, B, A, 0);
221
 
        case MESA_FORMAT_RGBA_FLOAT16:
222
 
            return EASY_US_FORMAT(R500_OUT_FMT_C4_16_FP, R, G, B, A, 0);
223
 
        case MESA_FORMAT_ALPHA_FLOAT32:
224
 
            return EASY_US_FORMAT(R500_OUT_FMT_C_32_FP, A, A, A, A, 0);
225
 
        case MESA_FORMAT_ALPHA_FLOAT16:
226
 
            return EASY_US_FORMAT(R500_OUT_FMT_C_16_FP, A, A, A, A, 0);
227
 
 
228
 
        case MESA_FORMAT_SIGNED_RGBA8888:
229
 
            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, R, G, B, A, 0xf);
230
 
        case MESA_FORMAT_SIGNED_RGBA8888_REV:
231
 
            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, B, G, R, 0xf);
232
 
        case MESA_FORMAT_SIGNED_RGBA_16:
233
 
            return EASY_US_FORMAT(R500_OUT_FMT_C4_16, R, G, B, A, 0xf);
234
 
 
235
 
        default:
236
 
            fprintf(stderr, "Unsupported format %s for US output\n", _mesa_get_format_name(mesa_format));
237
 
            assert(0);
238
 
            return 0;
239
 
    }
240
 
}
241
 
#undef EASY_US_FORMAT
242
 
 
243
 
static void r500_emit_fp_setup(struct r300_context *r300,
244
 
                               struct r500_fragment_program_code *fp,
245
 
                               gl_format dst_format)
246
 
{
247
 
    r500_emit_fp(r300, (uint32_t *)fp->inst, (fp->inst_end + 1) * 6, 0, 0, 0);
248
 
    BATCH_LOCALS(&r300->radeon);
249
 
 
250
 
    BEGIN_BATCH(10);
251
 
    OUT_BATCH_REGSEQ(R500_US_CODE_ADDR, 3);
252
 
    OUT_BATCH(R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(fp->inst_end));
253
 
    OUT_BATCH(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(fp->inst_end));
254
 
    OUT_BATCH(0);
255
 
    OUT_BATCH_REGVAL(R500_US_CONFIG, 0);
256
 
    OUT_BATCH_REGVAL(R500_US_OUT_FMT_0, mesa_format_to_us_format(dst_format));
257
 
    OUT_BATCH_REGVAL(R500_US_PIXSIZE, fp->max_temp_idx);
258
 
    END_BATCH();
259
 
}
260
 
 
261
 
static void r500_emit_rs_setup(struct r300_context *r300)
262
 
{
263
 
    BATCH_LOCALS(&r300->radeon);
264
 
 
265
 
    BEGIN_BATCH(7);
266
 
    OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
267
 
    OUT_BATCH((4 << R300_IT_COUNT_SHIFT) | R300_HIRES_EN);
268
 
    OUT_BATCH(0);
269
 
    OUT_BATCH_REGVAL(R500_RS_INST_0,
270
 
                     (0 << R500_RS_INST_TEX_ID_SHIFT) |
271
 
                     (0 << R500_RS_INST_TEX_ADDR_SHIFT) |
272
 
                     R500_RS_INST_TEX_CN_WRITE |
273
 
                     R500_RS_INST_COL_CN_NO_WRITE);
274
 
    OUT_BATCH_REGVAL(R500_RS_IP_0,
275
 
                     (0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
276
 
                     (1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
277
 
                     (2 << R500_RS_IP_TEX_PTR_R_SHIFT) |
278
 
                     (3 << R500_RS_IP_TEX_PTR_Q_SHIFT));
279
 
    END_BATCH();
280
 
}
281
 
 
282
 
static void r300_emit_fp_setup(struct r300_context *r300,
283
 
                               struct r300_fragment_program_code *code,
284
 
                               gl_format dst_format)
285
 
{
286
 
    unsigned i;
287
 
    BATCH_LOCALS(&r300->radeon);
288
 
 
289
 
    BEGIN_BATCH((code->alu.length + 1) * 4 + code->tex.length + 1 + 11);
290
 
 
291
 
    OUT_BATCH_REGSEQ(R300_US_ALU_RGB_INST_0, code->alu.length);
292
 
    for (i = 0; i < code->alu.length; i++) {
293
 
        OUT_BATCH(code->alu.inst[i].rgb_inst);
294
 
    }
295
 
    OUT_BATCH_REGSEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length);
296
 
    for (i = 0; i < code->alu.length; i++) {
297
 
        OUT_BATCH(code->alu.inst[i].rgb_addr);
298
 
    }
299
 
    OUT_BATCH_REGSEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length);
300
 
    for (i = 0; i < code->alu.length; i++) {
301
 
        OUT_BATCH(code->alu.inst[i].alpha_inst);
302
 
    }
303
 
    OUT_BATCH_REGSEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length);
304
 
    for (i = 0; i < code->alu.length; i++) {
305
 
        OUT_BATCH(code->alu.inst[i].alpha_addr);
306
 
    }
307
 
 
308
 
    OUT_BATCH_REGSEQ(R300_US_TEX_INST_0, code->tex.length);
309
 
    OUT_BATCH_TABLE(code->tex.inst, code->tex.length);
310
 
 
311
 
    OUT_BATCH_REGSEQ(R300_US_CONFIG, 3);
312
 
    OUT_BATCH(R300_PFS_CNTL_FIRST_NODE_HAS_TEX);
313
 
    OUT_BATCH(code->pixsize);
314
 
    OUT_BATCH(code->code_offset);
315
 
    OUT_BATCH_REGSEQ(R300_US_CODE_ADDR_0, 4);
316
 
    OUT_BATCH_TABLE(code->code_addr, 4);
317
 
    OUT_BATCH_REGVAL(R500_US_OUT_FMT_0, mesa_format_to_us_format(dst_format));
318
 
    END_BATCH();
319
 
}
320
 
 
321
 
static void r300_emit_rs_setup(struct r300_context *r300)
322
 
{
323
 
    BATCH_LOCALS(&r300->radeon);
324
 
 
325
 
    BEGIN_BATCH(7);
326
 
    OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
327
 
    OUT_BATCH((4 << R300_IT_COUNT_SHIFT) | R300_HIRES_EN);
328
 
    OUT_BATCH(0);
329
 
    OUT_BATCH_REGVAL(R300_RS_INST_0,
330
 
                     R300_RS_INST_TEX_ID(0) |
331
 
                     R300_RS_INST_TEX_ADDR(0) |
332
 
                     R300_RS_INST_TEX_CN_WRITE);
333
 
    OUT_BATCH_REGVAL(R300_RS_IP_0,
334
 
                     R300_RS_TEX_PTR(0) |
335
 
                     R300_RS_SEL_S(R300_RS_SEL_C0) |
336
 
                     R300_RS_SEL_T(R300_RS_SEL_C1) |
337
 
                     R300_RS_SEL_R(R300_RS_SEL_K0) |
338
 
                     R300_RS_SEL_Q(R300_RS_SEL_K1));
339
 
    END_BATCH();
340
 
}
341
 
 
342
 
static void emit_pvs_setup(struct r300_context *r300,
343
 
                           uint32_t *vp_code,
344
 
                           unsigned vp_len)
345
 
{
346
 
    BATCH_LOCALS(&r300->radeon);
347
 
 
348
 
    r300_emit_vpu(r300, vp_code, vp_len * 4, R300_PVS_CODE_START);
349
 
 
350
 
    BEGIN_BATCH(4);
351
 
    OUT_BATCH_REGSEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
352
 
    OUT_BATCH((0 << R300_PVS_FIRST_INST_SHIFT) |
353
 
              ((vp_len - 1)  << R300_PVS_XYZW_VALID_INST_SHIFT) |
354
 
              ((vp_len - 1)<< R300_PVS_LAST_INST_SHIFT));
355
 
    OUT_BATCH(0);
356
 
    OUT_BATCH((vp_len - 1) << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
357
 
    END_BATCH();
358
 
}
359
 
 
360
 
static void emit_vap_setup(struct r300_context *r300)
361
 
{
362
 
    int tex_offset;
363
 
    BATCH_LOCALS(&r300->radeon);
364
 
 
365
 
    if (r300->options.hw_tcl_enabled)
366
 
        tex_offset = 1;
367
 
    else
368
 
        tex_offset = 6;
369
 
 
370
 
    BEGIN_BATCH(12);
371
 
    OUT_BATCH_REGSEQ(R300_SE_VTE_CNTL, 2);
372
 
    OUT_BATCH(R300_VTX_XY_FMT | R300_VTX_Z_FMT);
373
 
    OUT_BATCH(4);
374
 
 
375
 
    OUT_BATCH_REGVAL(R300_VAP_PSC_SGN_NORM_CNTL, 0xaaaaaaaa);
376
 
    OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_0,
377
 
                     ((R300_DATA_TYPE_FLOAT_2 | (0 << R300_DST_VEC_LOC_SHIFT)) << 0) |
378
 
                     (((tex_offset << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_2 | R300_LAST_VEC) << 16));
379
 
    OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_EXT_0,
380
 
                    ((((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
381
 
                       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
382
 
                       (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |
383
 
                       (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT) | 
384
 
                       (0xf << R300_WRITE_ENA_SHIFT) ) << 0) |
385
 
                     (((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
386
 
                       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
387
 
                       (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |
388
 
                       (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT) |
389
 
                       (0xf << R300_WRITE_ENA_SHIFT) ) << 16) ) );
390
 
    OUT_BATCH_REGSEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
391
 
    OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT);
392
 
    OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_1__4_COMPONENTS);
393
 
    END_BATCH();
394
 
}
395
 
 
396
 
static GLboolean validate_buffers(struct r300_context *r300,
397
 
                                  struct radeon_bo *src_bo,
398
 
                                  struct radeon_bo *dst_bo)
399
 
{
400
 
    int ret;
401
 
 
402
 
    radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs);
403
 
 
404
 
    ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs,
405
 
                                        src_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
406
 
    if (ret)
407
 
        return GL_FALSE;
408
 
 
409
 
    ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs,
410
 
                                        dst_bo, 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT);
411
 
    if (ret)
412
 
        return GL_FALSE;
413
 
 
414
 
    return GL_TRUE;
415
 
}
416
 
 
417
 
/**
418
 
 * Calculate texcoords for given image region.
419
 
 * Output values are [minx, maxx, miny, maxy]
420
 
 */
421
 
static void calc_tex_coords(float img_width, float img_height,
422
 
                            float x, float y,
423
 
                            float reg_width, float reg_height,
424
 
                            unsigned flip_y, float *buf)
425
 
{
426
 
    buf[0] = x / img_width;
427
 
    buf[1] = buf[0] + reg_width / img_width;
428
 
    buf[2] = y / img_height;
429
 
    buf[3] = buf[2] + reg_height / img_height;
430
 
    if (flip_y)
431
 
    {
432
 
        buf[2] = 1.0 - buf[2];
433
 
        buf[3] = 1.0 - buf[3];
434
 
    }
435
 
}
436
 
 
437
 
static void emit_draw_packet(struct r300_context *r300,
438
 
                             unsigned src_width, unsigned src_height,
439
 
                             unsigned src_x_offset, unsigned src_y_offset,
440
 
                             unsigned dst_x_offset, unsigned dst_y_offset,
441
 
                             unsigned reg_width, unsigned reg_height,
442
 
                             unsigned flip_y)
443
 
{
444
 
    float texcoords[4];
445
 
 
446
 
    calc_tex_coords(src_width, src_height,
447
 
                    src_x_offset, src_y_offset,
448
 
                    reg_width, reg_height,
449
 
                    flip_y, texcoords);
450
 
 
451
 
    float verts[] = { dst_x_offset, dst_y_offset,
452
 
                      texcoords[0], texcoords[2],
453
 
                      dst_x_offset, dst_y_offset + reg_height,
454
 
                      texcoords[0], texcoords[3],
455
 
                      dst_x_offset + reg_width, dst_y_offset + reg_height,
456
 
                      texcoords[1], texcoords[3],
457
 
                      dst_x_offset + reg_width, dst_y_offset,
458
 
                      texcoords[1], texcoords[2] };
459
 
 
460
 
    BATCH_LOCALS(&r300->radeon);
461
 
 
462
 
    BEGIN_BATCH(19);
463
 
    OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_IMMD_2, 16);
464
 
    OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED |
465
 
              (4 << 16) | R300_VAP_VF_CNTL__PRIM_QUADS);
466
 
    OUT_BATCH_TABLE(verts, 16);
467
 
    END_BATCH();
468
 
}
469
 
 
470
 
static void other_stuff(struct r300_context *r300)
471
 
{
472
 
    BATCH_LOCALS(&r300->radeon);
473
 
 
474
 
    BEGIN_BATCH(13);
475
 
    OUT_BATCH_REGVAL(R300_GA_POLY_MODE,
476
 
                     R300_GA_POLY_MODE_FRONT_PTYPE_TRI | R300_GA_POLY_MODE_BACK_PTYPE_TRI);
477
 
    OUT_BATCH_REGVAL(R300_SU_CULL_MODE, R300_FRONT_FACE_CCW);
478
 
    OUT_BATCH_REGVAL(R300_FG_FOG_BLEND, 0);
479
 
    OUT_BATCH_REGVAL(R300_FG_ALPHA_FUNC, 0);
480
 
    OUT_BATCH_REGSEQ(R300_RB3D_CBLEND, 2);
481
 
    OUT_BATCH(0x0);
482
 
    OUT_BATCH(0x0);
483
 
    OUT_BATCH_REGVAL(R300_ZB_CNTL, 0);
484
 
    END_BATCH();
485
 
    if (r300->options.hw_tcl_enabled) {
486
 
        BEGIN_BATCH(2);
487
 
        OUT_BATCH_REGVAL(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
488
 
        END_BATCH();
489
 
    }
490
 
}
491
 
 
492
 
static void emit_cb_setup(struct r300_context *r300,
493
 
                          struct radeon_bo *bo,
494
 
                          intptr_t offset,
495
 
                          gl_format mesa_format,
496
 
                          unsigned pitch,
497
 
                          unsigned width,
498
 
                          unsigned height)
499
 
{
500
 
    BATCH_LOCALS(&r300->radeon);
501
 
 
502
 
    unsigned x1, y1, x2, y2;
503
 
    x1 = 0;
504
 
    y1 = 0;
505
 
    x2 = width - 1;
506
 
    y2 = height - 1;
507
 
 
508
 
    if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
509
 
        x1 += R300_SCISSORS_OFFSET;
510
 
        y1 += R300_SCISSORS_OFFSET;
511
 
        x2 += R300_SCISSORS_OFFSET;
512
 
        y2 += R300_SCISSORS_OFFSET;
513
 
    }
514
 
 
515
 
    r300_emit_cb_setup(r300, bo, offset, mesa_format,
516
 
                       _mesa_get_format_bytes(mesa_format),
517
 
                       _mesa_format_row_stride(mesa_format, pitch));
518
 
 
519
 
    BEGIN_BATCH_NO_AUTOSTATE(5);
520
 
    OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2);
521
 
    OUT_BATCH((x1 << R300_SCISSORS_X_SHIFT)|(y1 << R300_SCISSORS_Y_SHIFT));
522
 
    OUT_BATCH((x2 << R300_SCISSORS_X_SHIFT)|(y2 << R300_SCISSORS_Y_SHIFT));
523
 
    OUT_BATCH_REGVAL(R300_RB3D_CCTL, 0);
524
 
    END_BATCH();
525
 
}
526
 
 
527
 
unsigned r300_check_blit(gl_format dst_format)
528
 
{
529
 
    switch (dst_format) {
530
 
        case MESA_FORMAT_RGB565:
531
 
        case MESA_FORMAT_ARGB1555:
532
 
        case MESA_FORMAT_RGBA8888:
533
 
        case MESA_FORMAT_RGBA8888_REV:
534
 
        case MESA_FORMAT_ARGB8888:
535
 
        case MESA_FORMAT_ARGB8888_REV:
536
 
        case MESA_FORMAT_XRGB8888:
537
 
            break;
538
 
        default:
539
 
            return 0;
540
 
    }
541
 
 
542
 
    if (_mesa_get_format_bits(dst_format, GL_DEPTH_BITS) > 0)
543
 
        return 0;
544
 
 
545
 
    return 1;
546
 
}
547
 
 
548
 
/**
549
 
 * Copy a region of [@a width x @a height] pixels from source buffer
550
 
 * to destination buffer.
551
 
 * @param[in] r300 r300 context
552
 
 * @param[in] src_bo source radeon buffer object
553
 
 * @param[in] src_offset offset of the source image in the @a src_bo
554
 
 * @param[in] src_mesaformat source image format
555
 
 * @param[in] src_pitch aligned source image width
556
 
 * @param[in] src_width source image width
557
 
 * @param[in] src_height source image height
558
 
 * @param[in] src_x_offset x offset in the source image
559
 
 * @param[in] src_y_offset y offset in the source image
560
 
 * @param[in] dst_bo destination radeon buffer object
561
 
 * @param[in] dst_offset offset of the destination image in the @a dst_bo
562
 
 * @param[in] dst_mesaformat destination image format
563
 
 * @param[in] dst_pitch aligned destination image width
564
 
 * @param[in] dst_width destination image width
565
 
 * @param[in] dst_height destination image height
566
 
 * @param[in] dst_x_offset x offset in the destination image
567
 
 * @param[in] dst_y_offset y offset in the destination image
568
 
 * @param[in] width region width
569
 
 * @param[in] height region height
570
 
 * @param[in] flip_y set if y coords of the source image need to be flipped
571
 
 */
572
 
unsigned r300_blit(struct gl_context *ctx,
573
 
                   struct radeon_bo *src_bo,
574
 
                   intptr_t src_offset,
575
 
                   gl_format src_mesaformat,
576
 
                   unsigned src_pitch,
577
 
                   unsigned src_width,
578
 
                   unsigned src_height,
579
 
                   unsigned src_x_offset,
580
 
                   unsigned src_y_offset,
581
 
                   struct radeon_bo *dst_bo,
582
 
                   intptr_t dst_offset,
583
 
                   gl_format dst_mesaformat,
584
 
                   unsigned dst_pitch,
585
 
                   unsigned dst_width,
586
 
                   unsigned dst_height,
587
 
                   unsigned dst_x_offset,
588
 
                   unsigned dst_y_offset,
589
 
                   unsigned reg_width,
590
 
                   unsigned reg_height,
591
 
                   unsigned flip_y)
592
 
{
593
 
    r300ContextPtr r300 = R300_CONTEXT(ctx);
594
 
 
595
 
    if (!r300_check_blit(dst_mesaformat))
596
 
        return 0;
597
 
 
598
 
    /* Make sure that colorbuffer has even width - hw limitation */
599
 
    if (dst_pitch % 2 > 0)
600
 
        ++dst_pitch;
601
 
 
602
 
    /* Need to clamp the region size to make sure
603
 
     * we don't read outside of the source buffer
604
 
     * or write outside of the destination buffer.
605
 
     */
606
 
    if (reg_width + src_x_offset > src_width)
607
 
        reg_width = src_width - src_x_offset;
608
 
    if (reg_height + src_y_offset > src_height)
609
 
        reg_height = src_height - src_y_offset;
610
 
    if (reg_width + dst_x_offset > dst_width)
611
 
        reg_width = dst_width - dst_x_offset;
612
 
    if (reg_height + dst_y_offset > dst_height)
613
 
        reg_height = dst_height - dst_y_offset;
614
 
 
615
 
    if (src_bo == dst_bo) {
616
 
        return 0;
617
 
    }
618
 
 
619
 
    if (src_offset % 32 || dst_offset % 32) {
620
 
        return GL_FALSE;
621
 
    }
622
 
 
623
 
    if (0) {
624
 
        fprintf(stderr, "src: size [%d x %d], pitch %d, "
625
 
                "offset [%d x %d], format %s, bo %p\n",
626
 
                src_width, src_height, src_pitch,
627
 
                src_x_offset, src_y_offset,
628
 
                _mesa_get_format_name(src_mesaformat),
629
 
                src_bo);
630
 
        fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n",
631
 
                dst_pitch, dst_x_offset, dst_y_offset,
632
 
                _mesa_get_format_name(dst_mesaformat), dst_bo);
633
 
        fprintf(stderr, "region: %d x %d\n", reg_width, reg_height);
634
 
    }
635
 
 
636
 
    /* Flush is needed to make sure that source buffer has correct data */
637
 
    radeonFlush(r300->radeon.glCtx);
638
 
 
639
 
    if (!validate_buffers(r300, src_bo, dst_bo))
640
 
        return 0;
641
 
 
642
 
    rcommonEnsureCmdBufSpace(&r300->radeon, 200, __FUNCTION__);
643
 
 
644
 
    other_stuff(r300);
645
 
 
646
 
    r300_emit_tx_setup(r300, src_mesaformat, src_bo, src_offset, src_width, src_height, src_pitch);
647
 
 
648
 
    if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
649
 
        r500_emit_fp_setup(r300, &r300->blit.fp_code.code.r500, dst_mesaformat);
650
 
        r500_emit_rs_setup(r300);
651
 
    } else {
652
 
        r300_emit_fp_setup(r300, &r300->blit.fp_code.code.r300, dst_mesaformat);
653
 
        r300_emit_rs_setup(r300);
654
 
    }
655
 
 
656
 
    if (r300->options.hw_tcl_enabled)
657
 
        emit_pvs_setup(r300, r300->blit.vp_code.body.d, 2);
658
 
 
659
 
    emit_vap_setup(r300);
660
 
 
661
 
    emit_cb_setup(r300, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height);
662
 
 
663
 
    emit_draw_packet(r300, src_width, src_height,
664
 
                     src_x_offset, src_y_offset,
665
 
                     dst_x_offset, dst_y_offset,
666
 
                     reg_width, reg_height,
667
 
                     flip_y);
668
 
 
669
 
    r300EmitCacheFlush(r300);
670
 
 
671
 
    radeonFlush(r300->radeon.glCtx);
672
 
 
673
 
    return 1;
674
 
}