diff options
author | Corbin Simpson <MostAwesomeDude@gmail.com> | 2009-02-06 13:34:04 -0800 |
---|---|---|
committer | Corbin Simpson <MostAwesomeDude@gmail.com> | 2009-02-06 13:34:04 -0800 |
commit | 4683fc94f5e03f596fc8e5c12e9dd54a83deaeb9 (patch) | |
tree | bf78732b3bc9b7b22d3e1074d1447ea5be77656f /src | |
parent | e6372853c221a5d64494ce75a6a323c479c55a86 (diff) | |
parent | 80026428e3aa8f71ccd42d8d3b5e0a15c150dda2 (diff) |
Merge branch 'gallium-0.2-radeon' into gallium-0.2
Diffstat (limited to 'src')
38 files changed, 7855 insertions, 0 deletions
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile new file mode 100644 index 0000000000..e83d943cd8 --- /dev/null +++ b/src/gallium/drivers/r300/Makefile @@ -0,0 +1,21 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = r300 + +C_SOURCES = \ + r300_chipset.c \ + r300_clear.c \ + r300_context.c \ + r300_emit.c \ + r300_flush.c \ + r300_screen.c \ + r300_state.c \ + r300_state_shader.c \ + r300_surface.c \ + r300_swtcl_emit.c \ + r300_texture.c + +include ../../Makefile.template + +symlinks: diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript new file mode 100644 index 0000000000..18684c3e7f --- /dev/null +++ b/src/gallium/drivers/r300/SConscript @@ -0,0 +1,17 @@ +Import('*') + +env = env.Clone() + +r300 = env.ConvenienceLibrary( + target = 'r300', + source = [ + 'r300_blit.c', + 'r300_clear.c', + 'r300_context.c', + 'r300_screen.c', + 'r300_state.c', + 'r300_surface.c', + ]) + +Export('r300') + diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c new file mode 100644 index 0000000000..7def62422a --- /dev/null +++ b/src/gallium/drivers/r300/r300_chipset.c @@ -0,0 +1,348 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "r300_chipset.h" +#include "pipe/p_debug.h" + +/* r300_chipset: A file all to itself for deducing the various properties of + * Radeons. */ + +/* Parse a PCI ID and fill an r300_capabilities struct with information. */ +void r300_parse_chipset(struct r300_capabilities* caps) +{ + /* Reasonable defaults */ + caps->has_tcl = TRUE; + caps->is_r500 = FALSE; + caps->num_vert_fpus = 4; + + + /* Note: These are not ordered by PCI ID. I leave that task to GCC, + * which will perform the ordering while collating jump tables. Instead, + * I've tried to group them according to capabilities and age. */ + switch (caps->pci_id) { + case 0x4144: + caps->family = CHIP_FAMILY_R300; + break; + + case 0x4145: + case 0x4146: + case 0x4147: + case 0x4E44: + case 0x4E45: + case 0x4E46: + case 0x4E47: + caps->family = CHIP_FAMILY_R300; + break; + + case 0x4150: + case 0x4151: + case 0x4152: + case 0x4153: + case 0x4154: + case 0x4155: + case 0x4156: + case 0x4E50: + case 0x4E51: + case 0x4E52: + case 0x4E53: + case 0x4E54: + case 0x4E56: + caps->family = CHIP_FAMILY_RV350; + break; + + case 0x4148: + case 0x4149: + case 0x414A: + case 0x414B: + case 0x4E48: + case 0x4E49: + case 0x4E4B: + caps->family = CHIP_FAMILY_R350; + break; + + case 0x4E4A: + caps->family = CHIP_FAMILY_R360; + break; + + case 0x5460: + case 0x5462: + case 0x5464: + case 0x5B60: + case 0x5B62: + case 0x5B63: + case 0x5B64: + case 0x5B65: + caps->family = CHIP_FAMILY_RV370; + break; + + case 0x3150: + case 0x3152: + case 0x3154: + case 0x3E50: + case 0x3E54: + caps->family = CHIP_FAMILY_RV380; + break; + + case 0x4A48: + case 0x4A49: + case 0x4A4A: + case 0x4A4B: + case 0x4A4C: + case 0x4A4D: + case 0x4A4E: + case 0x4A4F: + case 0x4A50: + case 0x4A54: + caps->family = CHIP_FAMILY_R420; + caps->num_vert_fpus = 6; + break; + + case 0x5548: + case 0x5549: + case 0x554A: + case 0x554B: + case 0x5550: + case 0x5551: + case 0x5552: + case 0x5554: + case 0x5D57: + caps->family = CHIP_FAMILY_R423; + caps->num_vert_fpus = 6; + break; + + case 0x554C: + case 0x554D: + case 0x554E: + case 0x554F: + case 0x5D48: + case 0x5D49: + case 0x5D4A: + caps->family = CHIP_FAMILY_R430; + caps->num_vert_fpus = 6; + break; + + case 0x5D4C: + case 0x5D4D: + case 0x5D4E: + case 0x5D4F: + case 0x5D50: + case 0x5D52: + caps->family = CHIP_FAMILY_R480; + caps->num_vert_fpus = 6; + break; + + case 0x4B49: + case 0x4B4A: + case 0x4B4B: + case 0x4B4C: + caps->family = CHIP_FAMILY_R481; + caps->num_vert_fpus = 6; + break; + + case 0x5E4C: + case 0x5E4F: + case 0x564A: + case 0x564B: + case 0x564F: + case 0x5652: + case 0x5653: + case 0x5657: + case 0x5E48: + case 0x5E4A: + case 0x5E4B: + case 0x5E4D: + caps->family = CHIP_FAMILY_RV410; + caps->num_vert_fpus = 6; + break; + + case 0x5954: + case 0x5955: + caps->family = CHIP_FAMILY_RS480; + caps->has_tcl = FALSE; + break; + + case 0x5974: + case 0x5975: + caps->family = CHIP_FAMILY_RS482; + caps->has_tcl = FALSE; + break; + + case 0x5A41: + case 0x5A42: + caps->family = CHIP_FAMILY_RS400; + caps->has_tcl = FALSE; + break; + + case 0x5A61: + case 0x5A62: + caps->family = CHIP_FAMILY_RC410; + caps->has_tcl = FALSE; + break; + + case 0x791E: + case 0x791F: + caps->family = CHIP_FAMILY_RS690; + caps->has_tcl = FALSE; + break; + + case 0x796C: + case 0x796D: + case 0x796E: + case 0x796F: + caps->family = CHIP_FAMILY_RS740; + caps->has_tcl = FALSE; + break; + + case 0x7100: + case 0x7101: + case 0x7102: + case 0x7103: + case 0x7104: + case 0x7105: + case 0x7106: + case 0x7108: + case 0x7109: + case 0x710A: + case 0x710B: + case 0x710C: + case 0x710E: + case 0x710F: + caps->family = CHIP_FAMILY_R520; + caps->num_vert_fpus = 8; + caps->is_r500 = TRUE; + break; + + case 0x7140: + case 0x7141: + case 0x7142: + case 0x7143: + case 0x7144: + case 0x7145: + case 0x7146: + case 0x7147: + case 0x7149: + case 0x714A: + case 0x714B: + case 0x714C: + case 0x714D: + case 0x714E: + case 0x714F: + case 0x7151: + case 0x7152: + case 0x7153: + case 0x715E: + case 0x715F: + case 0x7180: + case 0x7181: + case 0x7183: + case 0x7186: + case 0x7187: + case 0x7188: + case 0x718A: + case 0x718B: + case 0x718C: + case 0x718D: + case 0x718F: + case 0x7193: + case 0x7196: + case 0x719B: + case 0x719F: + case 0x7200: + case 0x7210: + case 0x7211: + caps->family = CHIP_FAMILY_RV515; + caps->num_vert_fpus = 2; + caps->is_r500 = TRUE; + break; + + case 0x71C0: + case 0x71C1: + case 0x71C2: + case 0x71C3: + case 0x71C4: + case 0x71C5: + case 0x71C6: + case 0x71C7: + case 0x71CD: + case 0x71CE: + case 0x71D2: + case 0x71D4: + case 0x71D5: + case 0x71D6: + case 0x71DA: + case 0x71DE: + caps->family = CHIP_FAMILY_RV530; + caps->num_vert_fpus = 5; + caps->is_r500 = TRUE; + break; + + case 0x7240: + case 0x7243: + case 0x7244: + case 0x7245: + case 0x7246: + case 0x7247: + case 0x7248: + case 0x7249: + case 0x724A: + case 0x724B: + case 0x724C: + case 0x724D: + case 0x724E: + case 0x724F: + case 0x7284: + caps->family = CHIP_FAMILY_R580; + caps->num_vert_fpus = 8; + caps->is_r500 = TRUE; + break; + + case 0x7280: + caps->family = CHIP_FAMILY_RV570; + caps->num_vert_fpus = 5; + caps->is_r500 = TRUE; + break; + + case 0x7281: + case 0x7283: + case 0x7287: + case 0x7288: + case 0x7289: + case 0x728B: + case 0x728C: + case 0x7290: + case 0x7291: + case 0x7293: + case 0x7297: + caps->family = CHIP_FAMILY_RV560; + caps->num_vert_fpus = 5; + caps->is_r500 = TRUE; + break; + + default: + debug_printf("r300: Warning: Unknown chipset 0x%x\n", + caps->pci_id); + break; + } + + /* Force off TCL for now */ + caps->has_tcl = FALSE; +} diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h new file mode 100644 index 0000000000..a9cd372ec5 --- /dev/null +++ b/src/gallium/drivers/r300/r300_chipset.h @@ -0,0 +1,79 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 R300_CHIPSET_H +#define R300_CHIPSET_H + +#include "pipe/p_compiler.h" + +/* Structure containing all the possible information about a specific Radeon + * in the R3xx, R4xx, and R5xx families. */ +struct r300_capabilities { + /* PCI ID */ + uint32_t pci_id; + /* Chipset family */ + int family; + /* The number of vertex floating-point units */ + int num_vert_fpus; + /* The number of fragment pipes */ + int num_frag_pipes; + /* Whether or not TCL is physically present */ + boolean has_tcl; + /* Whether or not this is an RV515 or newer; R500s have many differences + * that require extra consideration, compared to their R3xx cousins: + * - Extra bit of width and height on texture sizes + * - Blend color is split across two registers + * - Universal Shader (US) block used for fragment shaders */ + boolean is_r500; +}; + +/* Enumerations for legibility and telling which card we're running on. */ +enum { + CHIP_FAMILY_R300 = 0, + CHIP_FAMILY_R350, + CHIP_FAMILY_R360, + CHIP_FAMILY_RV350, + CHIP_FAMILY_RV370, + CHIP_FAMILY_RV380, + CHIP_FAMILY_R420, + CHIP_FAMILY_R423, + CHIP_FAMILY_R430, + CHIP_FAMILY_R480, + CHIP_FAMILY_R481, + CHIP_FAMILY_RV410, + CHIP_FAMILY_RS400, + CHIP_FAMILY_RC410, + CHIP_FAMILY_RS480, + CHIP_FAMILY_RS482, + CHIP_FAMILY_RS690, + CHIP_FAMILY_RS740, + CHIP_FAMILY_RV515, + CHIP_FAMILY_R520, + CHIP_FAMILY_RV530, + CHIP_FAMILY_R580, + CHIP_FAMILY_RV560, + CHIP_FAMILY_RV570 +}; + +void r300_parse_chipset(struct r300_capabilities* caps); + +#endif /* R300_CHIPSET_H */ diff --git a/src/gallium/drivers/r300/r300_clear.c b/src/gallium/drivers/r300/r300_clear.c new file mode 100644 index 0000000000..fd28437aaa --- /dev/null +++ b/src/gallium/drivers/r300/r300_clear.c @@ -0,0 +1,33 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "r300_clear.h" + +/* This gets its own file because Intel's is in its own file. + * I assume there's a good reason. */ +void r300_clear(struct pipe_context* pipe, + struct pipe_surface* ps, + unsigned color) +{ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color); + ps->status = PIPE_SURFACE_STATUS_DEFINED; +}
\ No newline at end of file diff --git a/src/gallium/drivers/r300/r300_clear.h b/src/gallium/drivers/r300/r300_clear.h new file mode 100644 index 0000000000..e24a0690c9 --- /dev/null +++ b/src/gallium/drivers/r300/r300_clear.h @@ -0,0 +1,27 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "pipe/p_context.h" + +void r300_clear(struct pipe_context* pipe, + struct pipe_surface* ps, + unsigned color); diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c new file mode 100644 index 0000000000..7b605ae87a --- /dev/null +++ b/src/gallium/drivers/r300/r300_context.c @@ -0,0 +1,68 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "r300_context.h" + +static void r300_destroy_context(struct pipe_context* context) { + struct r300_context* r300 = r300_context(context); + + draw_destroy(r300->draw); + + FREE(r300->blend_color_state); + FREE(r300->scissor_state); + FREE(r300); +} + +struct pipe_context* r300_create_context(struct pipe_screen* screen, + struct pipe_winsys* winsys, + struct r300_winsys* r300_winsys) +{ + struct r300_context* r300 = CALLOC_STRUCT(r300_context); + + if (!r300) + return NULL; + + r300->winsys = r300_winsys; + r300->context.winsys = winsys; + r300->context.screen = r300_create_screen(winsys, r300_winsys); + + r300->context.destroy = r300_destroy_context; + + r300->context.clear = r300_clear; + + r300->draw = draw_create(); + /*XXX draw_set_rasterize_stage(r300->draw, r300_draw_swtcl_stage(r300));*/ + + r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state); + r300->scissor_state = CALLOC_STRUCT(r300_scissor_state); + + r300_init_flush_functions(r300); + + r300_init_surface_functions(r300); + + r300_init_state_functions(r300); + + r300->dirty_state = R300_NEW_KITCHEN_SINK; + r300->dirty_hw++; + + return &r300->context; +} diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h new file mode 100644 index 0000000000..fb91c172f4 --- /dev/null +++ b/src/gallium/drivers/r300/r300_context.h @@ -0,0 +1,186 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 R300_CONTEXT_H +#define R300_CONTEXT_H + +#include "draw/draw_context.h" +#include "pipe/p_context.h" +#include "tgsi/tgsi_scan.h" +#include "util/u_memory.h" + +#include "r300_clear.h" +#include "r300_screen.h" +#include "r300_winsys.h" + +struct r300_blend_state { + uint32_t blend_control; /* R300_RB3D_CBLEND: 0x4e04 */ + uint32_t alpha_blend_control; /* R300_RB3D_ABLEND: 0x4e08 */ + uint32_t rop; /* R300_RB3D_ROPCNTL: 0x4e18 */ + uint32_t dither; /* R300_RB3D_DITHER_CTL: 0x4e50 */ +}; + +struct r300_blend_color_state { + /* RV515 and earlier */ + uint32_t blend_color; /* R300_RB3D_BLEND_COLOR: 0x4e10 */ + /* R520 and newer */ + uint32_t blend_color_red_alpha; /* R500_RB3D_CONSTANT_COLOR_AR: 0x4ef8 */ + uint32_t blend_color_green_blue; /* R500_RB3D_CONSTANT_COLOR_GB: 0x4efc */ +}; + +struct r300_dsa_state { + uint32_t alpha_function; /* R300_FG_ALPHA_FUNC: 0x4bd4 */ + uint32_t alpha_reference; /* R500_FG_ALPHA_VALUE: 0x4be0 */ + uint32_t z_buffer_control; /* R300_ZB_CNTL: 0x4f00 */ + uint32_t z_stencil_control; /* R300_ZB_ZSTENCILCNTL: 0x4f04 */ + uint32_t stencil_ref_mask; /* R300_ZB_STENCILREFMASK: 0x4f08 */ + uint32_t z_buffer_top; /* R300_ZB_ZTOP: 0x4f14 */ + uint32_t stencil_ref_bf; /* R500_ZB_STENCILREFMASK_BF: 0x4fd4 */ +}; + +struct r300_rs_state { + uint32_t vap_control_status; /* R300_VAP_CNTL_STATUS: 0x2140 */ + uint32_t point_size; /* R300_GA_POINT_SIZE: 0x421c */ + uint32_t line_control; /* R300_GA_LINE_CNTL: 0x4234 */ + uint32_t depth_scale_front; /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */ + uint32_t depth_offset_front;/* R300_SU_POLY_OFFSET_FRONT_OFFSET: 0x42a8 */ + uint32_t depth_scale_back; /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */ + uint32_t depth_offset_back; /* R300_SU_POLY_OFFSET_BACK_OFFSET: 0x42b0 */ + uint32_t polygon_offset_enable; /* R300_SU_POLY_OFFSET_ENABLE: 0x42b4 */ + uint32_t cull_mode; /* R300_SU_CULL_MODE: 0x42b8 */ + uint32_t line_stipple_config; /* R300_GA_LINE_STIPPLE_CONFIG: 0x4328 */ + uint32_t line_stipple_value; /* R300_GA_LINE_STIPPLE_VALUE: 0x4260 */ +}; + +struct r300_sampler_state { + uint32_t filter0; /* R300_TX_FILTER0: 0x4400 */ + uint32_t filter1; /* R300_TX_FILTER1: 0x4440 */ + uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */ +}; + +struct r300_scissor_state { + uint32_t scissor_top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */ + uint32_t scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */ +}; + +struct r300_texture_state { +}; + +#define R300_NEW_BLEND 0x000001 +#define R300_NEW_BLEND_COLOR 0x000002 +#define R300_NEW_DSA 0x000004 +#define R300_NEW_FRAMEBUFFERS 0x000008 +#define R300_NEW_FRAGMENT_SHADER 0x000010 +#define R300_NEW_RASTERIZER 0x000020 +#define R300_NEW_SAMPLER 0x000040 +#define R300_NEW_SCISSOR 0x004000 +#define R300_NEW_TEXTURE 0x008000 +#define R300_NEW_VERTEX_SHADER 0x800000 +#define R300_NEW_KITCHEN_SINK 0xffffff + +/* The next several objects are not pure Radeon state; they inherit from + * various Gallium classes. */ + +struct r3xx_fragment_shader { + /* Parent class */ + struct pipe_shader_state state; + struct tgsi_shader_info info; + + /* Has this shader been translated yet? */ + boolean translated; +}; + +struct r300_fragment_shader { + /* Parent class */ + struct r3xx_fragment_shader shader; +}; + +struct r500_fragment_shader { + /* Parent class */ + struct r3xx_fragment_shader shader; +}; + +struct r300_texture { + /* Parent class */ + struct pipe_texture tex; + + /* Offsets into the buffer. */ + unsigned offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* Total size of this texture, in bytes. */ + unsigned size; + + /* Pipe buffer backing this texture. */ + struct pipe_buffer* buffer; +}; + +struct r300_context { + /* Parent class */ + struct pipe_context context; + + /* The interface to the windowing system, etc. */ + struct r300_winsys* winsys; + /* Draw module. Used mostly for SW TCL. */ + struct draw_context* draw; + + /* Various CSO state objects. */ + /* Blend state. */ + struct r300_blend_state* blend_state; + /* Blend color state. */ + struct r300_blend_color_state* blend_color_state; + /* Depth, stencil, and alpha state. */ + struct r300_dsa_state* dsa_state; + /* Fragment shader. */ + struct r3xx_fragment_shader* fs; + /* Framebuffer state. We currently don't need our own version of this. */ + struct pipe_framebuffer_state framebuffer_state; + /* Rasterizer state. */ + struct r300_rs_state* rs_state; + /* Sampler states. */ + struct r300_sampler_state* sampler_states[8]; + int sampler_count; + /* Scissor state. */ + struct r300_scissor_state* scissor_state; + /* Texture states. */ + struct r300_texture* textures[8]; + struct r300_texture_state* texture_states[8]; + int texture_count; + /* Bitmask of dirty state objects. */ + uint32_t dirty_state; + /* Flag indicating whether or not the HW is dirty. */ + uint32_t dirty_hw; +}; + +/* Convenience cast wrapper. */ +static struct r300_context* r300_context(struct pipe_context* context) { + return (struct r300_context*)context; +} + +/* Context initialization. */ +void r300_init_state_functions(struct r300_context* r300); +void r300_init_surface_functions(struct r300_context* r300); + +struct pipe_context* r300_create_context(struct pipe_screen* screen, + struct pipe_winsys* winsys, + struct r300_winsys* r300_winsys); + +#endif /* R300_CONTEXT_H */ diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h new file mode 100644 index 0000000000..385b61a096 --- /dev/null +++ b/src/gallium/drivers/r300/r300_cs.h @@ -0,0 +1,129 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 R300_CS_H +#define R300_CS_H + +#include "r300_reg.h" +#include "r300_winsys.h" + +/* Pack a 32-bit float into a dword. */ +static uint32_t pack_float_32(float f) +{ + union { + float f; + uint32_t u; + } u; + + u.f = f; + return u.u; +} + +/* Yes, I know macros are ugly. However, they are much prettier than the code + * that they neatly hide away, and don't have the cost of function setup,so + * we're going to use them. */ + +#define MAX_CS_SIZE 64 * 1024 / 4 + +/* XXX stolen from radeon_drm.h */ +#define RADEON_GEM_DOMAIN_CPU 0x1 +#define RADEON_GEM_DOMAIN_GTT 0x2 +#define RADEON_GEM_DOMAIN_VRAM 0x4 + +/* XXX stolen from radeon_reg.h */ +#define RADEON_CP_PACKET0 0x0 + +#define CP_PACKET0(register, count) \ + (RADEON_CP_PACKET0 | ((count) << 16) | ((register) >> 2)) + +#define CP_PACKET3(op, count) \ + (RADEON_CP_PACKET3 | (op) | ((count) << 16)) + +#define CS_LOCALS(context) \ + struct r300_winsys* cs_winsys = context->winsys; \ + struct radeon_cs* cs = cs_winsys->cs; \ + int cs_count = 0; + +#define CHECK_CS(size) \ + cs_winsys->check_cs(cs, (size)) + +#define BEGIN_CS(size) do { \ + CHECK_CS(size); \ + debug_printf("r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \ + size, __FUNCTION__, __FILE__, __LINE__); \ + cs_winsys->begin_cs(cs, (size), __FILE__, __FUNCTION__, __LINE__); \ + cs_count = size; \ +} while (0) + +#define OUT_CS(value) do { \ + cs_winsys->write_cs_dword(cs, (value)); \ + cs_count--; \ +} while (0) + +#define OUT_CS_32F(value) do { \ + cs_winsys->write_cs_dword(cs, pack_float_32(value)); \ + cs_count--; \ +} while (0) + +#define OUT_CS_REG(register, value) do { \ + debug_printf("r300: writing 0x%08X to register 0x%04X\n", \ + value, register); \ + assert(register); \ + OUT_CS(CP_PACKET0(register, 0)); \ + OUT_CS(value); \ +} while (0) + +/* Note: This expects count to be the number of registers, + * not the actual packet0 count! */ +#define OUT_CS_REG_SEQ(register, count) do { \ + debug_printf("r300: writing register sequence of %d to 0x%04X\n", \ + count, register); \ + assert(register); \ + OUT_CS(CP_PACKET0(register, ((count) - 1))); \ +} while (0) + +#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \ + debug_printf("r300: writing relocation for buffer %p, offset %d\n", \ + bo, offset); \ + assert(bo); \ + OUT_CS(offset); \ + cs_winsys->write_cs_reloc(cs, bo, rd, wd, flags); \ + cs_count -= 2; \ +} while (0) + +#define END_CS do { \ + debug_printf("r300: END_CS in %s (%s:%d)\n", __FUNCTION__, __FILE__, \ + __LINE__); \ + if (cs_count != 0) \ + debug_printf("r300: Warning: cs_count off by %d\n", cs_count); \ + cs_winsys->end_cs(cs, __FILE__, __FUNCTION__, __LINE__); \ +} while (0) + +#define FLUSH_CS do { \ + debug_printf("r300: FLUSH_CS in %s (%s:%d)\n", __FUNCTION__, __FILE__, \ + __LINE__); \ + cs_winsys->flush_cs(cs); \ +} while (0) + +#include "r300_cs_inlines.h" + +#endif /* R300_CS_H */ diff --git a/src/gallium/drivers/r300/r300_cs_inlines.h b/src/gallium/drivers/r300/r300_cs_inlines.h new file mode 100644 index 0000000000..71e6623699 --- /dev/null +++ b/src/gallium/drivers/r300/r300_cs_inlines.h @@ -0,0 +1,37 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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. */ + +/* r300_cs_inlines: This is just a handful of useful inlines for sending + * (very) common instructions to the CS buffer. Should only be included from + * r300_cs.h, probably. */ + +#ifdef R300_CS_H + +#define R300_PACIFY do { \ + OUT_CS_REG(R300_SC_SCREENDOOR, 0x0); \ + OUT_CS_REG(RADEON_WAIT_UNTIL, (1 << 15) | (1 << 17) | \ + (1 << 18) | (1 << 31)); \ + OUT_CS_REG(R300_SC_SCREENDOOR, 0xffffff); \ +} while (0) + + +#endif /* R300_CS_H */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c new file mode 100644 index 0000000000..c71b8d0b02 --- /dev/null +++ b/src/gallium/drivers/r300/r300_emit.c @@ -0,0 +1,153 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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. */ + +/* r300_emit: Functions for emitting state. */ + +#include "r300_emit.h" + +void r300_emit_blend_state(struct r300_context* r300, + struct r300_blend_state* blend) +{ + CS_LOCALS(r300); + BEGIN_CS(7); + OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 2); + OUT_CS(blend->blend_control); + OUT_CS(blend->alpha_blend_control); + OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop); + OUT_CS_REG(R300_RB3D_DITHER_CTL, blend->dither); + END_CS; +} + +void r300_emit_blend_color_state(struct r300_context* r300, + struct r300_blend_color_state* bc) +{ + struct r300_screen* r300screen = + (struct r300_screen*)r300->context.screen; + CS_LOCALS(r300); + if (r300screen->caps->is_r500) { + BEGIN_CS(3); + OUT_CS_REG_SEQ(R500_RB3D_CONSTANT_COLOR_AR, 2); + OUT_CS(bc->blend_color_red_alpha); + OUT_CS(bc->blend_color_green_blue); + END_CS; + } else { + BEGIN_CS(2); + OUT_CS_REG(R300_RB3D_BLEND_COLOR, bc->blend_color); + END_CS; + } +} + +void r300_emit_dsa_state(struct r300_context* r300, + struct r300_dsa_state* dsa) +{ + struct r300_screen* r300screen = + (struct r300_screen*)r300->context.screen; + CS_LOCALS(r300); + BEGIN_CS(r300screen->caps->is_r500 ? 8 : 8); + OUT_CS_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function); + /* XXX figure out the r300 counterpart for this */ + if (r300screen->caps->is_r500) { + /* OUT_CS_REG(R500_FG_ALPHA_VALUE, dsa->alpha_reference); */ + } + OUT_CS_REG_SEQ(R300_ZB_CNTL, 3); + OUT_CS(dsa->z_buffer_control); + OUT_CS(dsa->z_stencil_control); + OUT_CS(dsa->stencil_ref_mask); + OUT_CS_REG(R300_ZB_ZTOP, dsa->z_buffer_top); + if (r300screen->caps->is_r500) { + /* OUT_CS_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf); */ + } + END_CS; +} + +/* XXX add pitch, stride, z/stencil buf */ +void r300_emit_fb_state(struct r300_context* r300, + struct pipe_framebuffer_state* fb) +{ + CS_LOCALS(r300); + int i; + + BEGIN_CS((3 * fb->nr_cbufs) + 6); + for (i = 0; i < fb->nr_cbufs; i++) { + OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1); + OUT_CS_RELOC(fb->cbufs[i]->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); + } + R300_PACIFY; + END_CS; +} + +void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs) +{ + struct r300_screen* r300screen = + (struct r300_screen*)r300->context.screen; + CS_LOCALS(r300); + BEGIN_CS(14); + OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status); + OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 6); + OUT_CS(rs->depth_scale_front); + OUT_CS(rs->depth_offset_front); + OUT_CS(rs->depth_scale_back); + OUT_CS(rs->depth_offset_back); + OUT_CS(rs->polygon_offset_enable); + OUT_CS(rs->cull_mode); + OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, rs->line_stipple_config); + OUT_CS_REG(R300_GA_LINE_STIPPLE_VALUE, rs->line_stipple_value); + END_CS; +} + +static void r300_emit_dirty_state(struct r300_context* r300) +{ + struct r300_screen* r300screen = + (struct r300_screen*)r300->context.screen; + CS_LOCALS(r300); + + if (!(r300->dirty_state) && !(r300->dirty_hw)) { + return; + } + + /* XXX check size */ + + if (r300->dirty_state & R300_NEW_BLEND) { + r300_emit_blend_state(r300, r300->blend_state); + } + + if (r300->dirty_state & R300_NEW_BLEND_COLOR) { + r300_emit_blend_color_state(r300, r300->blend_color_state); + } + + if (r300->dirty_state & R300_NEW_DSA) { + r300_emit_dsa_state(r300, r300->dsa_state); + } + + if (r300->dirty_state & R300_NEW_RASTERIZER) { + r300_emit_rs_state(r300, r300->rs_state); + } + + if (r300->dirty_state & R300_NEW_SCISSOR) { + struct r300_scissor_state* scissor = r300->scissor_state; + /* XXX next two are contiguous regs */ + OUT_CS_REG(R300_SC_SCISSORS_TL, scissor->scissor_top_left); + OUT_CS_REG(R300_SC_SCISSORS_BR, scissor->scissor_bottom_right); + } + + r300->dirty_state = 0; +} diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h new file mode 100644 index 0000000000..b6e69386f9 --- /dev/null +++ b/src/gallium/drivers/r300/r300_emit.h @@ -0,0 +1,36 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "r300_context.h" +#include "r300_cs.h" +#include "r300_screen.h" + +void r300_emit_blend_state(struct r300_context* r300, + struct r300_blend_state* blend); + +void r300_emit_blend_color_state(struct r300_context* r300, + struct r300_blend_color_state* bc); + +void r300_emit_dsa_state(struct r300_context* r300, + struct r300_dsa_state* dsa); + +void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs); diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c new file mode 100644 index 0000000000..3766f0a0a7 --- /dev/null +++ b/src/gallium/drivers/r300/r300_flush.c @@ -0,0 +1,42 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "r300_flush.h" + +static void r300_flush(struct pipe_context* pipe, + unsigned flags, + struct pipe_fence_handle** fence) +{ + struct r300_context* r300 = r300_context(pipe); + CS_LOCALS(r300); + + if (r300->dirty_hw) { + FLUSH_CS; + r300->dirty_state = R300_NEW_KITCHEN_SINK; + r300->dirty_hw = 0; + } +} + +void r300_init_flush_functions(struct r300_context* r300) +{ + r300->context.flush = r300_flush; +} diff --git a/src/gallium/drivers/r300/r300_flush.h b/src/gallium/drivers/r300/r300_flush.h new file mode 100644 index 0000000000..a1b224b39c --- /dev/null +++ b/src/gallium/drivers/r300/r300_flush.h @@ -0,0 +1,33 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 R300_FLUSH_H +#define R300_FLUSH_H + +#include "pipe/p_context.h" + +#include "r300_context.h" +#include "r300_cs.h" + +void r300_init_flush_functions(struct r300_context* r300); + +#endif /* R300_FLUSH_H */ diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h new file mode 100644 index 0000000000..dbd0cc28e2 --- /dev/null +++ b/src/gallium/drivers/r300/r300_reg.h @@ -0,0 +1,3290 @@ +/************************************************************************** + +Copyright (C) 2004-2005 Nicolai Haehnle et al. + +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 +on 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 +THE AUTHOR(S) AND/OR THEIR 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. + +**************************************************************************/ + +/* *INDENT-OFF* */ + +#ifndef _R300_REG_H +#define _R300_REG_H + +#define R300_MC_INIT_MISC_LAT_TIMER 0x180 +# define R300_MC_MISC__MC_CPR_INIT_LAT_SHIFT 0 +# define R300_MC_MISC__MC_VF_INIT_LAT_SHIFT 4 +# define R300_MC_MISC__MC_DISP0R_INIT_LAT_SHIFT 8 +# define R300_MC_MISC__MC_DISP1R_INIT_LAT_SHIFT 12 +# define R300_MC_MISC__MC_FIXED_INIT_LAT_SHIFT 16 +# define R300_MC_MISC__MC_E2R_INIT_LAT_SHIFT 20 +# define R300_MC_MISC__MC_SAME_PAGE_PRIO_SHIFT 24 +# define R300_MC_MISC__MC_GLOBW_INIT_LAT_SHIFT 28 + + +#define R300_MC_INIT_GFX_LAT_TIMER 0x154 +# define R300_MC_MISC__MC_G3D0R_INIT_LAT_SHIFT 0 +# define R300_MC_MISC__MC_G3D1R_INIT_LAT_SHIFT 4 +# define R300_MC_MISC__MC_G3D2R_INIT_LAT_SHIFT 8 +# define R300_MC_MISC__MC_G3D3R_INIT_LAT_SHIFT 12 +# define R300_MC_MISC__MC_TX0R_INIT_LAT_SHIFT 16 +# define R300_MC_MISC__MC_TX1R_INIT_LAT_SHIFT 20 +# define R300_MC_MISC__MC_GLOBR_INIT_LAT_SHIFT 24 +# define R300_MC_MISC__MC_GLOBW_FULL_LAT_SHIFT 28 + +/* + * This file contains registers and constants for the R300. They have been + * found mostly by examining command buffers captured using glxtest, as well + * as by extrapolating some known registers and constants from the R200. + * I am fairly certain that they are correct unless stated otherwise + * in comments. + */ + +#define R300_SE_VPORT_XSCALE 0x1D98 +#define R300_SE_VPORT_XOFFSET 0x1D9C +#define R300_SE_VPORT_YSCALE 0x1DA0 +#define R300_SE_VPORT_YOFFSET 0x1DA4 +#define R300_SE_VPORT_ZSCALE 0x1DA8 +#define R300_SE_VPORT_ZOFFSET 0x1DAC + + +/* + * Vertex Array Processing (VAP) Control + */ +#define R300_VAP_CNTL 0x2080 +# define R300_PVS_NUM_SLOTS_SHIFT 0 +# define R300_PVS_NUM_CNTLRS_SHIFT 4 +# define R300_PVS_NUM_FPUS_SHIFT 8 +# define R300_VF_MAX_VTX_NUM_SHIFT 18 +# define R300_GL_CLIP_SPACE_DEF (0 << 22) +# define R300_DX_CLIP_SPACE_DEF (1 << 22) +# define R500_TCL_STATE_OPTIMIZATION (1 << 23) + +/* This register is written directly and also starts data section + * in many 3d CP_PACKET3's + */ +#define R300_VAP_VF_CNTL 0x2084 +# define R300_VAP_VF_CNTL__PRIM_TYPE__SHIFT 0 +# define R300_VAP_VF_CNTL__PRIM_NONE (0<<0) +# define R300_VAP_VF_CNTL__PRIM_POINTS (1<<0) +# define R300_VAP_VF_CNTL__PRIM_LINES (2<<0) +# define R300_VAP_VF_CNTL__PRIM_LINE_STRIP (3<<0) +# define R300_VAP_VF_CNTL__PRIM_TRIANGLES (4<<0) +# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN (5<<0) +# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP (6<<0) +# define R300_VAP_VF_CNTL__PRIM_LINE_LOOP (12<<0) +# define R300_VAP_VF_CNTL__PRIM_QUADS (13<<0) +# define R300_VAP_VF_CNTL__PRIM_QUAD_STRIP (14<<0) +# define R300_VAP_VF_CNTL__PRIM_POLYGON (15<<0) + +# define R300_VAP_VF_CNTL__PRIM_WALK__SHIFT 4 + /* State based - direct writes to registers trigger vertex + generation */ +# define R300_VAP_VF_CNTL__PRIM_WALK_STATE_BASED (0<<4) +# define R300_VAP_VF_CNTL__PRIM_WALK_INDICES (1<<4) +# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST (2<<4) +# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED (3<<4) + + /* I don't think I saw these three used.. */ +# define R300_VAP_VF_CNTL__COLOR_ORDER__SHIFT 6 +# define R300_VAP_VF_CNTL__TCL_OUTPUT_CTL_ENA__SHIFT 9 +# define R300_VAP_VF_CNTL__PROG_STREAM_ENA__SHIFT 10 + + /* index size - when not set the indices are assumed to be 16 bit */ +# define R300_VAP_VF_CNTL__INDEX_SIZE_32bit (1<<11) + /* number of vertices */ +# define R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT 16 + +#define R500_VAP_INDEX_OFFSET 0x208c + +#define R300_VAP_OUTPUT_VTX_FMT_0 0x2090 +# define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0) +# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT (1<<1) +# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) +# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) +# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) +# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) + +#define R300_VAP_OUTPUT_VTX_FMT_1 0x2094 + /* each of the following is 3 bits wide, specifies number + of components */ +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18 +# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21 +# define R300_VAP_OUTPUT_VTX_FMT_1__NOT_PRESENT 0 +# define R300_VAP_OUTPUT_VTX_FMT_1__1_COMPONENT 1 +# define R300_VAP_OUTPUT_VTX_FMT_1__2_COMPONENTS 2 +# define R300_VAP_OUTPUT_VTX_FMT_1__3_COMPONENTS 3 +# define R300_VAP_OUTPUT_VTX_FMT_1__4_COMPONENTS 4 + +#define R300_SE_VTE_CNTL 0x20b0 +# define R300_VPORT_X_SCALE_ENA (1 << 0) +# define R300_VPORT_X_OFFSET_ENA (1 << 1) +# define R300_VPORT_Y_SCALE_ENA (1 << 2) +# define R300_VPORT_Y_OFFSET_ENA (1 << 3) +# define R300_VPORT_Z_SCALE_ENA (1 << 4) +# define R300_VPORT_Z_OFFSET_ENA (1 << 5) +# define R300_VTX_XY_FMT (1 << 8) +# define R300_VTX_Z_FMT (1 << 9) +# define R300_VTX_W0_FMT (1 << 10) +# define R300_SERIAL_PROC_ENA (1 << 11) + +#define R300_VAP_VTX_SIZE 0x20b4 + +/* BEGIN: Vertex data assembly - lots of uncertainties */ + +/* gap */ + +/* Maximum Vertex Indx Clamp */ +#define R300_VAP_VF_MAX_VTX_INDX 0x2134 +/* Minimum Vertex Indx Clamp */ +#define R300_VAP_VF_MIN_VTX_INDX 0x2138 + +/** Vertex assembler/processor control status */ +#define R300_VAP_CNTL_STATUS 0x2140 +/* No swap at all (default) */ +# define R300_VC_NO_SWAP (0 << 0) +/* 16-bit swap: 0xAABBCCDD becomes 0xBBAADDCC */ +# define R300_VC_16BIT_SWAP (1 << 0) +/* 32-bit swap: 0xAABBCCDD becomes 0xDDCCBBAA */ +# define R300_VC_32BIT_SWAP (2 << 0) +/* Half-dword swap: 0xAABBCCDD becomes 0xCCDDAABB */ +# define R300_VC_HALF_DWORD_SWAP (3 << 0) +/* The TCL engine will not be used (as it is logically or even physically removed) */ +# define R300_VAP_TCL_BYPASS (1 << 8) +/* Read only flag if TCL engine is busy. */ +# define R300_VAP_PVS_BUSY (1 << 11) +/* TODO: gap for MAX_MPS */ +/* Read only flag if the vertex store is busy. */ +# define R300_VAP_VS_BUSY (1 << 24) +/* Read only flag if the reciprocal engine is busy. */ +# define R300_VAP_RCP_BUSY (1 << 25) +/* Read only flag if the viewport transform engine is busy. */ +# define R300_VAP_VTE_BUSY (1 << 26) +/* Read only flag if the memory interface unit is busy. */ +# define R300_VAP_MUI_BUSY (1 << 27) +/* Read only flag if the vertex cache is busy. */ +# define R300_VAP_VC_BUSY (1 << 28) +/* Read only flag if the vertex fetcher is busy. */ +# define R300_VAP_VF_BUSY (1 << 29) +/* Read only flag if the register pipeline is busy. */ +# define R300_VAP_REGPIPE_BUSY (1 << 30) +/* Read only flag if the VAP engine is busy. */ +# define R300_VAP_VAP_BUSY (1 << 31) + +/* gap */ + +/* Where do we get our vertex data? + * + * Vertex data either comes either from immediate mode registers or from + * vertex arrays. + * There appears to be no mixed mode (though we can force the pitch of + * vertex arrays to 0, effectively reusing the same element over and over + * again). + * + * Immediate mode is controlled by the INPUT_CNTL registers. I am not sure + * if these registers influence vertex array processing. + * + * Vertex arrays are controlled via the 3D_LOAD_VBPNTR packet3. + * + * In both cases, vertex attributes are then passed through INPUT_ROUTE. + * + * Beginning with INPUT_ROUTE_0_0 is a list of WORDs that route vertex data + * into the vertex processor's input registers. + * The first word routes the first input, the second word the second, etc. + * The corresponding input is routed into the register with the given index. + * The list is ended by a word with INPUT_ROUTE_END set. + * + * Always set COMPONENTS_4 in immediate mode. + */ + +#define R300_VAP_PROG_STREAM_CNTL_0 0x2150 +# define R300_DATA_TYPE_0_SHIFT 0 +# define R300_DATA_TYPE_FLOAT_1 0 +# define R300_DATA_TYPE_FLOAT_2 1 +# define R300_DATA_TYPE_FLOAT_3 2 +# define R300_DATA_TYPE_FLOAT_4 3 +# define R300_DATA_TYPE_BYTE 4 +# define R300_DATA_TYPE_D3DCOLOR 5 +# define R300_DATA_TYPE_SHORT_2 6 +# define R300_DATA_TYPE_SHORT_4 7 +# define R300_DATA_TYPE_VECTOR_3_TTT 8 +# define R300_DATA_TYPE_VECTOR_3_EET 9 +# define R300_SKIP_DWORDS_SHIFT 4 +# define R300_DST_VEC_LOC_SHIFT 8 +# define R300_LAST_VEC (1 << 13) +# define R300_SIGNED (1 << 14) +# define R300_NORMALIZE (1 << 15) +# define R300_DATA_TYPE_1_SHIFT 16 +#define R300_VAP_PROG_STREAM_CNTL_1 0x2154 +#define R300_VAP_PROG_STREAM_CNTL_2 0x2158 +#define R300_VAP_PROG_STREAM_CNTL_3 0x215C +#define R300_VAP_PROG_STREAM_CNTL_4 0x2160 +#define R300_VAP_PROG_STREAM_CNTL_5 0x2164 +#define R300_VAP_PROG_STREAM_CNTL_6 0x2168 +#define R300_VAP_PROG_STREAM_CNTL_7 0x216C +/* gap */ + +/* Notes: + * - always set up to produce at least two attributes: + * if vertex program uses only position, fglrx will set normal, too + * - INPUT_CNTL_0_COLOR and INPUT_CNTL_COLOR bits are always equal. + */ +#define R300_VAP_VTX_STATE_CNTL 0x2180 +# define R300_COLOR_0_ASSEMBLY_SHIFT 0 +# define R300_SEL_COLOR 0 +# define R300_SEL_USER_COLOR_0 1 +# define R300_SEL_USER_COLOR_1 2 +# define R300_COLOR_1_ASSEMBLY_SHIFT 2 +# define R300_COLOR_2_ASSEMBLY_SHIFT 4 +# define R300_COLOR_3_ASSEMBLY_SHIFT 6 +# define R300_COLOR_4_ASSEMBLY_SHIFT 8 +# define R300_COLOR_5_ASSEMBLY_SHIFT 10 +# define R300_COLOR_6_ASSEMBLY_SHIFT 12 +# define R300_COLOR_7_ASSEMBLY_SHIFT 14 +# define R300_UPDATE_USER_COLOR_0_ENA (1 << 16) + +/* + * Each bit in this field applies to the corresponding vector in the VSM + * memory (i.e. Bit 0 applies to VECTOR_0 (POSITION), etc.). If the bit + * is set, then the corresponding 4-Dword Vector is output into the Vertex Stream. + */ +#define R300_VAP_VSM_VTX_ASSM 0x2184 +# define R300_INPUT_CNTL_POS 0x00000001 +# define R300_INPUT_CNTL_NORMAL 0x00000002 +# define R300_INPUT_CNTL_COLOR 0x00000004 +# define R300_INPUT_CNTL_TC0 0x00000400 +# define R300_INPUT_CNTL_TC1 0x00000800 +# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */ +# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */ +# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */ +# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */ +# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */ +# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */ + +/* Programmable Stream Control Signed Normalize Control */ +#define R300_VAP_PSC_SGN_NORM_CNTL 0x21dc +# define SGN_NORM_ZERO 0 +# define SGN_NORM_ZERO_CLAMP_MINUS_ONE 1 +# define SGN_NORM_NO_ZERO 2 + +/* gap */ + +/* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0 + * are set to a swizzling bit pattern, other words are 0. + * + * In immediate mode, the pattern is always set to xyzw. In vertex array + * mode, the swizzling pattern is e.g. used to set zw components in texture + * coordinates with only tweo components. + */ +#define R300_VAP_PROG_STREAM_CNTL_EXT_0 0x21e0 +# define R300_SWIZZLE0_SHIFT 0 +# define R300_SWIZZLE_SELECT_X_SHIFT 0 +# define R300_SWIZZLE_SELECT_Y_SHIFT 3 +# define R300_SWIZZLE_SELECT_Z_SHIFT 6 +# define R300_SWIZZLE_SELECT_W_SHIFT 9 + +# define R300_SWIZZLE_SELECT_X 0 +# define R300_SWIZZLE_SELECT_Y 1 +# define R300_SWIZZLE_SELECT_Z 2 +# define R300_SWIZZLE_SELECT_W 3 +# define R300_SWIZZLE_SELECT_FP_ZERO 4 +# define R300_SWIZZLE_SELECT_FP_ONE 5 +/* alternate forms for r300_emit.c */ +# define R300_INPUT_ROUTE_SELECT_X 0 +# define R300_INPUT_ROUTE_SELECT_Y 1 +# define R300_INPUT_ROUTE_SELECT_Z 2 +# define R300_INPUT_ROUTE_SELECT_W 3 +# define R300_INPUT_ROUTE_SELECT_ZERO 4 +# define R300_INPUT_ROUTE_SELECT_ONE 5 + +# define R300_WRITE_ENA_SHIFT 12 +# define R300_WRITE_ENA_X 1 +# define R300_WRITE_ENA_Y 2 +# define R300_WRITE_ENA_Z 4 +# define R300_WRITE_ENA_W 8 +# define R300_SWIZZLE1_SHIFT 16 +#define R300_VAP_PROG_STREAM_CNTL_EXT_1 0x21e4 +#define R300_VAP_PROG_STREAM_CNTL_EXT_2 0x21e8 +#define R300_VAP_PROG_STREAM_CNTL_EXT_3 0x21ec +#define R300_VAP_PROG_STREAM_CNTL_EXT_4 0x21f0 +#define R300_VAP_PROG_STREAM_CNTL_EXT_5 0x21f4 +#define R300_VAP_PROG_STREAM_CNTL_EXT_6 0x21f8 +#define R300_VAP_PROG_STREAM_CNTL_EXT_7 0x21fc + +/* END: Vertex data assembly */ + +/* gap */ + +/* BEGIN: Upload vertex program and data */ + +/* + * The programmable vertex shader unit has a memory bank of unknown size + * that can be written to in 16 byte units by writing the address into + * UPLOAD_ADDRESS, followed by data in UPLOAD_DATA (multiples of 4 DWORDs). + * + * Pointers into the memory bank are always in multiples of 16 bytes. + * + * The memory bank is divided into areas with fixed meaning. + * + * Starting at address UPLOAD_PROGRAM: Vertex program instructions. + * Native limits reported by drivers from ATI suggest size 256 (i.e. 4KB), + * whereas the difference between known addresses suggests size 512. + * + * Starting at address UPLOAD_PARAMETERS: Vertex program parameters. + * Native reported limits and the VPI layout suggest size 256, whereas + * difference between known addresses suggests size 512. + * + * At address UPLOAD_POINTSIZE is a vector (0, 0, ps, 0), where ps is the + * floating point pointsize. The exact purpose of this state is uncertain, + * as there is also the R300_RE_POINTSIZE register. + * + * Multiple vertex programs and parameter sets can be loaded at once, + * which could explain the size discrepancy. + */ +#define R300_VAP_PVS_VECTOR_INDX_REG 0x2200 +# define R300_PVS_CODE_START 0 +# define R300_MAX_PVS_CODE_LINES 256 +# define R500_MAX_PVS_CODE_LINES 1024 +# define R300_PVS_CONST_START 512 +# define R500_PVS_CONST_START 1024 +# define R300_MAX_PVS_CONST_VECS 256 +# define R500_MAX_PVS_CONST_VECS 1024 +# define R300_PVS_UCP_START 1024 +# define R500_PVS_UCP_START 1536 +# define R300_POINT_VPORT_SCALE_OFFSET 1030 +# define R500_POINT_VPORT_SCALE_OFFSET 1542 +# define R300_POINT_GEN_TEX_OFFSET 1031 +# define R500_POINT_GEN_TEX_OFFSET 1543 + +/* + * These are obsolete defines form r300_context.h, but they might give some + * clues when investigating the addresses further... + */ +#if 0 +#define VSF_DEST_PROGRAM 0x0 +#define VSF_DEST_MATRIX0 0x200 +#define VSF_DEST_MATRIX1 0x204 +#define VSF_DEST_MATRIX2 0x208 +#define VSF_DEST_VECTOR0 0x20c +#define VSF_DEST_VECTOR1 0x20d +#define VSF_DEST_UNKNOWN1 0x400 +#define VSF_DEST_UNKNOWN2 0x406 +#endif + +/* gap */ + +#define R300_VAP_PVS_UPLOAD_DATA 0x2208 + +/* END: Upload vertex program and data */ + +/* gap */ + +/* I do not know the purpose of this register. However, I do know that + * it is set to 221C_CLEAR for clear operations and to 221C_NORMAL + * for normal rendering. + * + * 2007-11-05: This register is the user clip plane control register, but there + * also seems to be a rendering mode control; the NORMAL/CLEAR defines. + * + * See bug #9871. http://bugs.freedesktop.org/attachment.cgi?id=10672&action=view + */ +#define R300_VAP_CLIP_CNTL 0x221C +# define R300_VAP_UCP_ENABLE_0 (1 << 0) +# define R300_VAP_UCP_ENABLE_1 (1 << 1) +# define R300_VAP_UCP_ENABLE_2 (1 << 2) +# define R300_VAP_UCP_ENABLE_3 (1 << 3) +# define R300_VAP_UCP_ENABLE_4 (1 << 4) +# define R300_VAP_UCP_ENABLE_5 (1 << 5) +# define R300_PS_UCP_MODE_DIST_COP (0 << 14) +# define R300_PS_UCP_MODE_RADIUS_COP (1 << 14) +# define R300_PS_UCP_MODE_RADIUS_COP_CLIP (2 << 14) +# define R300_PS_UCP_MODE_CLIP_AS_TRIFAN (3 << 14) +# define R300_CLIP_DISABLE (1 << 16) +# define R300_UCP_CULL_ONLY_ENABLE (1 << 17) +# define R300_BOUNDARY_EDGE_FLAG_ENABLE (1 << 18) +# define R500_COLOR2_IS_TEXTURE (1 << 20) +# define R500_COLOR3_IS_TEXTURE (1 << 21) + +/* These seem to be per-pixel and per-vertex X and Y clipping planes. The first + * plane is per-pixel and the second plane is per-vertex. + * + * This was determined by experimentation alone but I believe it is correct. + * + * These registers are called X_QUAD0_1_FL to X_QUAD0_4_FL by glxtest. + */ +#define R300_VAP_GB_VERT_CLIP_ADJ 0x2220 +#define R300_VAP_GB_VERT_DISC_ADJ 0x2224 +#define R300_VAP_GB_HORZ_CLIP_ADJ 0x2228 +#define R300_VAP_GB_HORZ_DISC_ADJ 0x222c + +/* gap */ + +/* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between + * rendering commands and overwriting vertex program parameters. + * Therefore, I suspect writing zero to 0x2284 synchronizes the engine and + * avoids bugs caused by still running shaders reading bad data from memory. + */ +#define R300_VAP_PVS_STATE_FLUSH_REG 0x2284 + +/* This register is used to define the number of core clocks to wait for a + * vertex to be received by the VAP input controller (while the primitive + * path is backed up) before forcing any accumulated vertices to be submitted + * to the vertex processing path. + */ +#define VAP_PVS_VTX_TIMEOUT_REG 0x2288 +# define R300_2288_R300 0x00750000 /* -- nh */ +# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */ + +/* gap */ + +/* Addresses are relative to the vertex program instruction area of the + * memory bank. PROGRAM_END points to the last instruction of the active + * program + * + * The meaning of the two UNKNOWN fields is obviously not known. However, + * experiments so far have shown that both *must* point to an instruction + * inside the vertex program, otherwise the GPU locks up. + * + * fglrx usually sets CNTL_3_UNKNOWN to the end of the program and + * R300_PVS_CNTL_1_POS_END_SHIFT points to instruction where last write to + * position takes place. + * + * Most likely this is used to ignore rest of the program in cases + * where group of verts arent visible. For some reason this "section" + * is sometimes accepted other instruction that have no relationship with + * position calculations. + */ +#define R300_VAP_PVS_CODE_CNTL_0 0x22D0 +# define R300_PVS_FIRST_INST_SHIFT 0 +# define R300_PVS_XYZW_VALID_INST_SHIFT 10 +# define R300_PVS_LAST_INST_SHIFT 20 +/* Addresses are relative the the vertex program parameters area. */ +#define R300_VAP_PVS_CONST_CNTL 0x22D4 +# define R300_PVS_CONST_BASE_OFFSET_SHIFT 0 +# define R300_PVS_MAX_CONST_ADDR_SHIFT 16 +#define R300_VAP_PVS_CODE_CNTL_1 0x22D8 +# define R300_PVS_LAST_VTX_SRC_INST_SHIFT 0 +#define R300_VAP_PVS_FLOW_CNTL_OPC 0x22DC + +/* The entire range from 0x2300 to 0x2AC inclusive seems to be used for + * immediate vertices + */ +#define R300_VAP_VTX_COLOR_R 0x2464 +#define R300_VAP_VTX_COLOR_G 0x2468 +#define R300_VAP_VTX_COLOR_B 0x246C +#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */ +#define R300_VAP_VTX_POS_0_Y_1 0x2494 +#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */ +#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */ +#define R300_VAP_VTX_POS_0_Y_2 0x24A4 +#define R300_VAP_VTX_POS_0_Z_2 0x24A8 +/* write 0 to indicate end of packet? */ +#define R300_VAP_VTX_END_OF_PKT 0x24AC + +/* gap */ + +/* These are values from r300_reg/r300_reg.h - they are known to be correct + * and are here so we can use one register file instead of several + * - Vladimir + */ +#define R300_GB_VAP_RASTER_VTX_FMT_0 0x4000 +# define R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT (1<<0) +# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_0_PRESENT (1<<1) +# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_1_PRESENT (1<<2) +# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_2_PRESENT (1<<3) +# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_3_PRESENT (1<<4) +# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_SPACE (0xf<<5) +# define R300_GB_VAP_RASTER_VTX_FMT_0__PT_SIZE_PRESENT (0x1<<16) + +#define R300_GB_VAP_RASTER_VTX_FMT_1 0x4004 + /* each of the following is 3 bits wide, specifies number + of components */ +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18 +# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21 + +/* UNK30 seems to enables point to quad transformation on textures + * (or something closely related to that). + * This bit is rather fatal at the time being due to lackings at pixel + * shader side + * Specifies top of Raster pipe specific enable controls. + */ +#define R300_GB_ENABLE 0x4008 +# define R300_GB_POINT_STUFF_DISABLE (0 << 0) +# define R300_GB_POINT_STUFF_ENABLE (1 << 0) /* Specifies if points will have stuffed texture coordinates. */ +# define R300_GB_LINE_STUFF_DISABLE (0 << 1) +# define R300_GB_LINE_STUFF_ENABLE (1 << 1) /* Specifies if lines will have stuffed texture coordinates. */ +# define R300_GB_TRIANGLE_STUFF_DISABLE (0 << 2) +# define R300_GB_TRIANGLE_STUFF_ENABLE (1 << 2) /* Specifies if triangles will have stuffed texture coordinates. */ +# define R300_GB_STENCIL_AUTO_DISABLE (0 << 4) +# define R300_GB_STENCIL_AUTO_ENABLE (1 << 4) /* Enable stencil auto inc/dec based on triangle cw/ccw, force into dzy low bit. */ +# define R300_GB_STENCIL_AUTO_FORCE (2 << 4) /* Force 0 into dzy low bit. */ + + /* each of the following is 2 bits wide */ +#define R300_GB_TEX_REPLICATE 0 /* Replicate VAP source texture coordinates (S,T,[R,Q]). */ +#define R300_GB_TEX_ST 1 /* Stuff with source texture coordinates (S,T). */ +#define R300_GB_TEX_STR 2 /* Stuff with source texture coordinates (S,T,R). */ +# define R300_GB_TEX0_SOURCE_SHIFT 16 +# define R300_GB_TEX1_SOURCE_SHIFT 18 +# define R300_GB_TEX2_SOURCE_SHIFT 20 +# define R300_GB_TEX3_SOURCE_SHIFT 22 +# define R300_GB_TEX4_SOURCE_SHIFT 24 +# define R300_GB_TEX5_SOURCE_SHIFT 26 +# define R300_GB_TEX6_SOURCE_SHIFT 28 +# define R300_GB_TEX7_SOURCE_SHIFT 30 + +/* MSPOS - positions for multisample antialiasing (?) */ +#define R300_GB_MSPOS0 0x4010 + /* shifts - each of the fields is 4 bits */ +# define R300_GB_MSPOS0__MS_X0_SHIFT 0 +# define R300_GB_MSPOS0__MS_Y0_SHIFT 4 +# define R300_GB_MSPOS0__MS_X1_SHIFT 8 +# define R300_GB_MSPOS0__MS_Y1_SHIFT 12 +# define R300_GB_MSPOS0__MS_X2_SHIFT 16 +# define R300_GB_MSPOS0__MS_Y2_SHIFT 20 +# define R300_GB_MSPOS0__MSBD0_Y 24 +# define R300_GB_MSPOS0__MSBD0_X 28 + +#define R300_GB_MSPOS1 0x4014 +# define R300_GB_MSPOS1__MS_X3_SHIFT 0 +# define R300_GB_MSPOS1__MS_Y3_SHIFT 4 +# define R300_GB_MSPOS1__MS_X4_SHIFT 8 +# define R300_GB_MSPOS1__MS_Y4_SHIFT 12 +# define R300_GB_MSPOS1__MS_X5_SHIFT 16 +# define R300_GB_MSPOS1__MS_Y5_SHIFT 20 +# define R300_GB_MSPOS1__MSBD1 24 + +/* Specifies the graphics pipeline configuration for rasterization. */ +#define R300_GB_TILE_CONFIG 0x4018 +# define R300_GB_TILE_DISABLE (0 << 0) +# define R300_GB_TILE_ENABLE (1 << 0) +# define R300_GB_TILE_PIPE_COUNT_RV300 (0 << 1) /* RV350 (1 pipe, 1 ctx) */ +# define R300_GB_TILE_PIPE_COUNT_R300 (3 << 1) /* R300 (2 pipes, 1 ctx) */ +# define R300_GB_TILE_PIPE_COUNT_R420_3P (6 << 1) /* R420-3P (3 pipes, 1 ctx) */ +# define R300_GB_TILE_PIPE_COUNT_R420 (7 << 1) /* R420 (4 pipes, 1 ctx) */ +# define R300_GB_TILE_SIZE_8 (0 << 4) +# define R300_GB_TILE_SIZE_16 (1 << 4) +# define R300_GB_TILE_SIZE_32 (2 << 4) +# define R300_GB_SUPER_SIZE_1 (0 << 6) +# define R300_GB_SUPER_SIZE_2 (1 << 6) +# define R300_GB_SUPER_SIZE_4 (2 << 6) +# define R300_GB_SUPER_SIZE_8 (3 << 6) +# define R300_GB_SUPER_SIZE_16 (4 << 6) +# define R300_GB_SUPER_SIZE_32 (5 << 6) +# define R300_GB_SUPER_SIZE_64 (6 << 6) +# define R300_GB_SUPER_SIZE_128 (7 << 6) +# define R300_GB_SUPER_X_SHIFT 9 /* 3 bits wide */ +# define R300_GB_SUPER_Y_SHIFT 12 /* 3 bits wide */ +# define R300_GB_SUPER_TILE_A (0 << 15) +# define R300_GB_SUPER_TILE_B (1 << 15) +# define R300_GB_SUBPIXEL_1_12 (0 << 16) +# define R300_GB_SUBPIXEL_1_16 (1 << 16) +# define GB_TILE_CONFIG_QUADS_PER_RAS_4 (0 << 17) +# define GB_TILE_CONFIG_QUADS_PER_RAS_8 (1 << 17) +# define GB_TILE_CONFIG_QUADS_PER_RAS_16 (2 << 17) +# define GB_TILE_CONFIG_QUADS_PER_RAS_32 (3 << 17) +# define GB_TILE_CONFIG_BB_SCAN_INTERCEPT (0 << 19) +# define GB_TILE_CONFIG_BB_SCAN_BOUND_BOX (1 << 19) +# define GB_TILE_CONFIG_ALT_SCAN_EN_LR (0 << 20) +# define GB_TILE_CONFIG_ALT_SCAN_EN_LRL (1 << 20) +# define GB_TILE_CONFIG_ALT_OFFSET (0 << 21) +# define GB_TILE_CONFIG_SUBPRECISION (0 << 22) +# define GB_TILE_CONFIG_ALT_TILING_DEF (0 << 23) +# define GB_TILE_CONFIG_ALT_TILING_3_2 (1 << 23) +# define GB_TILE_CONFIG_Z_EXTENDED_24_1 (0 << 24) +# define GB_TILE_CONFIG_Z_EXTENDED_S25_1 (1 << 24) + +/* Specifies the sizes of the various FIFO`s in the sc/rs/us. This register must be the first one written */ +#define R300_GB_FIFO_SIZE 0x4024 + /* each of the following is 2 bits wide */ +#define R300_GB_FIFO_SIZE_32 0 +#define R300_GB_FIFO_SIZE_64 1 +#define R300_GB_FIFO_SIZE_128 2 +#define R300_GB_FIFO_SIZE_256 3 +# define R300_SC_IFIFO_SIZE_SHIFT 0 +# define R300_SC_TZFIFO_SIZE_SHIFT 2 +# define R300_SC_BFIFO_SIZE_SHIFT 4 + +# define R300_US_OFIFO_SIZE_SHIFT 12 +# define R300_US_WFIFO_SIZE_SHIFT 14 + /* the following use the same constants as above, but meaning is + is times 2 (i.e. instead of 32 words it means 64 */ +# define R300_RS_TFIFO_SIZE_SHIFT 6 +# define R300_RS_CFIFO_SIZE_SHIFT 8 +# define R300_US_RAM_SIZE_SHIFT 10 + /* watermarks, 3 bits wide */ +# define R300_RS_HIGHWATER_COL_SHIFT 16 +# define R300_RS_HIGHWATER_TEX_SHIFT 19 +# define R300_OFIFO_HIGHWATER_SHIFT 22 /* two bits only */ +# define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT 24 + +#define GB_Z_PEQ_CONFIG 0x4028 +# define GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_4_4 (0 << 0) +# define GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8 (1 << 0) + +/* Specifies various polygon specific selects (fog, depth, perspective). */ +#define R300_GB_SELECT 0x401c +# define R300_GB_FOG_SELECT_C0A (0 << 0) +# define R300_GB_FOG_SELECT_C1A (1 << 0) +# define R300_GB_FOG_SELECT_C2A (2 << 0) +# define R300_GB_FOG_SELECT_C3A (3 << 0) +# define R300_GB_FOG_SELECT_1_1_W (4 << 0) +# define R300_GB_FOG_SELECT_Z (5 << 0) +# define R300_GB_DEPTH_SELECT_Z (0 << 3) +# define R300_GB_DEPTH_SELECT_1_1_W (1 << 3) +# define R300_GB_W_SELECT_1_W (0 << 4) +# define R300_GB_W_SELECT_1 (1 << 4) +# define R300_GB_FOG_STUFF_DISABLE (0 << 5) +# define R300_GB_FOG_STUFF_ENABLE (1 << 5) +# define R300_GB_FOG_STUFF_TEX_SHIFT 6 +# define R300_GB_FOG_STUFF_TEX_MASK 0x000003c0 +# define R300_GB_FOG_STUFF_COMP_SHIFT 10 +# define R300_GB_FOG_STUFF_COMP_MASK 0x00000c00 + +/* Specifies the graphics pipeline configuration for antialiasing. */ +#define R300_GB_AA_CONFIG 0x4020 +# define GB_AA_CONFIG_AA_DISABLE (0 << 0) +# define GB_AA_CONFIG_AA_ENABLE (1 << 0) +# define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_2 (0 << 1) +# define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_3 (1 << 1) +# define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_4 (2 << 1) +# define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_6 (3 << 1) + +/* Selects which of 4 pipes are active. */ +#define GB_PIPE_SELECT 0x402c +# define GB_PIPE_SELECT_PIPE0_ID_SHIFT 0 +# define GB_PIPE_SELECT_PIPE1_ID_SHIFT 2 +# define GB_PIPE_SELECT_PIPE2_ID_SHIFT 4 +# define GB_PIPE_SELECT_PIPE3_ID_SHIFT 6 +# define GB_PIPE_SELECT_PIPE_MASK_SHIFT 8 +# define GB_PIPE_SELECT_MAX_PIPE 12 +# define GB_PIPE_SELECT_BAD_PIPES 14 +# define GB_PIPE_SELECT_CONFIG_PIPES 18 + + +/* Specifies the sizes of the various FIFO`s in the sc/rs. */ +#define GB_FIFO_SIZE1 0x4070 +/* High water mark for SC input fifo */ +# define GB_FIFO_SIZE1_SC_HIGHWATER_IFIFO_SHIFT 0 +# define GB_FIFO_SIZE1_SC_HIGHWATER_IFIFO_MASK 0x0000003f +/* High water mark for SC input fifo (B) */ +# define GB_FIFO_SIZE1_SC_HIGHWATER_BFIFO_SHIFT 6 +# define GB_FIFO_SIZE1_SC_HIGHWATER_BFIFO_MASK 0x00000fc0 +/* High water mark for RS colors' fifo */ +# define GB_FIFO_SIZE1_SC_HIGHWATER_COL_SHIFT 12 +# define GB_FIFO_SIZE1_SC_HIGHWATER_COL_MASK 0x0003f000 +/* High water mark for RS textures' fifo */ +# define GB_FIFO_SIZE1_SC_HIGHWATER_TEX_SHIFT 18 +# define GB_FIFO_SIZE1_SC_HIGHWATER_TEX_MASK 0x00fc0000 + +/* This table specifies the source location and format for up to 16 texture + * addresses (i[0]:i[15]) and four colors (c[0]:c[3]) + */ +#define R500_RS_IP_0 0x4074 +#define R500_RS_IP_1 0x4078 +#define R500_RS_IP_2 0x407C +#define R500_RS_IP_3 0x4080 +#define R500_RS_IP_4 0x4084 +#define R500_RS_IP_5 0x4088 +#define R500_RS_IP_6 0x408C +#define R500_RS_IP_7 0x4090 +#define R500_RS_IP_8 0x4094 +#define R500_RS_IP_9 0x4098 +#define R500_RS_IP_10 0x409C +#define R500_RS_IP_11 0x40A0 +#define R500_RS_IP_12 0x40A4 +#define R500_RS_IP_13 0x40A8 +#define R500_RS_IP_14 0x40AC +#define R500_RS_IP_15 0x40B0 +#define R500_RS_IP_PTR_K0 62 +#define R500_RS_IP_PTR_K1 63 +#define R500_RS_IP_TEX_PTR_S_SHIFT 0 +#define R500_RS_IP_TEX_PTR_T_SHIFT 6 +#define R500_RS_IP_TEX_PTR_R_SHIFT 12 +#define R500_RS_IP_TEX_PTR_Q_SHIFT 18 +#define R500_RS_IP_COL_PTR_SHIFT 24 +#define R500_RS_IP_COL_FMT_SHIFT 27 +# define R500_RS_COL_PTR(x) (x << 24) +# define R500_RS_COL_FMT(x) (x << 27) +/* gap */ +#define R500_RS_IP_OFFSET_DIS (0 << 31) +#define R500_RS_IP_OFFSET_EN (1 << 31) + +/* gap */ + +/* Zero to flush caches. */ +#define R300_TX_INVALTAGS 0x4100 +#define R300_TX_FLUSH 0x0 + +/* The upper enable bits are guessed, based on fglrx reported limits. */ +#define R300_TX_ENABLE 0x4104 +# define R300_TX_ENABLE_0 (1 << 0) +# define R300_TX_ENABLE_1 (1 << 1) +# define R300_TX_ENABLE_2 (1 << 2) +# define R300_TX_ENABLE_3 (1 << 3) +# define R300_TX_ENABLE_4 (1 << 4) +# define R300_TX_ENABLE_5 (1 << 5) +# define R300_TX_ENABLE_6 (1 << 6) +# define R300_TX_ENABLE_7 (1 << 7) +# define R300_TX_ENABLE_8 (1 << 8) +# define R300_TX_ENABLE_9 (1 << 9) +# define R300_TX_ENABLE_10 (1 << 10) +# define R300_TX_ENABLE_11 (1 << 11) +# define R300_TX_ENABLE_12 (1 << 12) +# define R300_TX_ENABLE_13 (1 << 13) +# define R300_TX_ENABLE_14 (1 << 14) +# define R300_TX_ENABLE_15 (1 << 15) + +#define R500_TX_FILTER_4 0x4110 +# define R500_TX_WEIGHT_1_SHIFT (0) +# define R500_TX_WEIGHT_0_SHIFT (11) +# define R500_TX_WEIGHT_PAIR (1<<22) +# define R500_TX_PHASE_SHIFT (23) +# define R500_TX_DIRECTION_HORIZONTAL (0<<27) +# define R500_TX_DIRECTION_VERITCAL (1<<27) + +/* S Texture Coordinate of Vertex 0 for Point texture stuffing (LLC) */ +#define R300_GA_POINT_S0 0x4200 + +/* T Texture Coordinate of Vertex 0 for Point texture stuffing (LLC) */ +#define R300_GA_POINT_T0 0x4204 + +/* S Texture Coordinate of Vertex 2 for Point texture stuffing (URC) */ +#define R300_GA_POINT_S1 0x4208 + +/* T Texture Coordinate of Vertex 2 for Point texture stuffing (URC) */ +#define R300_GA_POINT_T1 0x420c + +/* Specifies amount to shift integer position of vertex (screen space) before + * converting to float for triangle stipple. + */ +#define R300_GA_TRIANGLE_STIPPLE 0x4214 +# define R300_GA_TRIANGLE_STIPPLE_X_SHIFT_SHIFT 0 +# define R300_GA_TRIANGLE_STIPPLE_X_SHIFT_MASK 0x0000000f +# define R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_SHIFT 16 +# define R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_MASK 0x000f0000 + +/* The pointsize is given in multiples of 6. The pointsize can be enormous: + * Clear() renders a single point that fills the entire framebuffer. + * 1/2 Height of point; fixed (16.0), subpixel format (1/12 or 1/16, even if in + * 8b precision). + */ +#define R300_GA_POINT_SIZE 0x421C +# define R300_POINTSIZE_Y_SHIFT 0 +# define R300_POINTSIZE_Y_MASK 0x0000ffff +# define R300_POINTSIZE_X_SHIFT 16 +# define R300_POINTSIZE_X_MASK 0xffff0000 +# define R300_POINTSIZE_MAX (R300_POINTSIZE_Y_MASK / 6) + +/* Blue fill color */ +#define R500_GA_FILL_R 0x4220 + +/* Blue fill color */ +#define R500_GA_FILL_G 0x4224 + +/* Blue fill color */ +#define R500_GA_FILL_B 0x4228 + +/* Alpha fill color */ +#define R500_GA_FILL_A 0x422c + + +/* Specifies maximum and minimum point & sprite sizes for per vertex size + * specification. The lower part (15:0) is MIN and (31:16) is max. + */ +#define R300_GA_POINT_MINMAX 0x4230 +# define R300_GA_POINT_MINMAX_MIN_SHIFT 0 +# define R300_GA_POINT_MINMAX_MIN_MASK (0xFFFF << 0) +# define R300_GA_POINT_MINMAX_MAX_SHIFT 16 +# define R300_GA_POINT_MINMAX_MAX_MASK (0xFFFF << 16) + +/* 1/2 width of line, in subpixels (1/12 or 1/16 only, even in 8b + * subprecision); (16.0) fixed format. + * + * The line width is given in multiples of 6. + * In default mode lines are classified as vertical lines. + * HO: horizontal + * VE: vertical or horizontal + * HO & VE: no classification + */ +#define R300_GA_LINE_CNTL 0x4234 +# define R300_GA_LINE_CNTL_WIDTH_SHIFT 0 +# define R300_GA_LINE_CNTL_WIDTH_MASK 0x0000ffff +# define R300_GA_LINE_CNTL_END_TYPE_HOR (0 << 16) +# define R300_GA_LINE_CNTL_END_TYPE_VER (1 << 16) +# define R300_GA_LINE_CNTL_END_TYPE_SQR (2 << 16) /* horizontal or vertical depending upon slope */ +# define R300_GA_LINE_CNTL_END_TYPE_COMP (3 << 16) /* Computed (perpendicular to slope) */ +# define R500_GA_LINE_CNTL_SORT_NO (0 << 18) +# define R500_GA_LINE_CNTL_SORT_MINX_MINY (1 << 18) +/** TODO: looks wrong */ +# define R300_LINESIZE_MAX (R300_GA_LINE_CNTL_WIDTH_MASK / 6) +/** TODO: looks wrong */ +# define R300_LINE_CNT_HO (1 << 16) +/** TODO: looks wrong */ +# define R300_LINE_CNT_VE (1 << 17) + +/* Line Stipple configuration information. */ +#define R300_GA_LINE_STIPPLE_CONFIG 0x4238 +# define R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_NO (0 << 0) +# define R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE (1 << 0) +# define R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_PACKET (2 << 0) +# define R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_SHIFT 2 +# define R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK 0xfffffffc + +/* Used to load US instructions and constants */ +#define R500_GA_US_VECTOR_INDEX 0x4250 +# define R500_GA_US_VECTOR_INDEX_SHIFT 0 +# define R500_GA_US_VECTOR_INDEX_MASK 0x000000ff +# define R500_GA_US_VECTOR_INDEX_TYPE_INSTR (0 << 16) +# define R500_GA_US_VECTOR_INDEX_TYPE_CONST (1 << 16) +# define R500_GA_US_VECTOR_INDEX_CLAMP_NO (0 << 17) +# define R500_GA_US_VECTOR_INDEX_CLAMP_CONST (1 << 17) + +/* Data register for loading US instructions and constants */ +#define R500_GA_US_VECTOR_DATA 0x4254 + +/* Specifies color properties and mappings of textures. */ +#define R500_GA_COLOR_CONTROL_PS3 0x4258 +# define R500_TEX0_SHADING_PS3_SOLID (0 << 0) +# define R500_TEX0_SHADING_PS3_FLAT (1 << 0) +# define R500_TEX0_SHADING_PS3_GOURAUD (2 << 0) +# define R500_TEX1_SHADING_PS3_SOLID (0 << 2) +# define R500_TEX1_SHADING_PS3_FLAT (1 << 2) +# define R500_TEX1_SHADING_PS3_GOURAUD (2 << 2) +# define R500_TEX2_SHADING_PS3_SOLID (0 << 4) +# define R500_TEX2_SHADING_PS3_FLAT (1 << 4) +# define R500_TEX2_SHADING_PS3_GOURAUD (2 << 4) +# define R500_TEX3_SHADING_PS3_SOLID (0 << 6) +# define R500_TEX3_SHADING_PS3_FLAT (1 << 6) +# define R500_TEX3_SHADING_PS3_GOURAUD (2 << 6) +# define R500_TEX4_SHADING_PS3_SOLID (0 << 8) +# define R500_TEX4_SHADING_PS3_FLAT (1 << 8) +# define R500_TEX4_SHADING_PS3_GOURAUD (2 << 8) +# define R500_TEX5_SHADING_PS3_SOLID (0 << 10) +# define R500_TEX5_SHADING_PS3_FLAT (1 << 10) +# define R500_TEX5_SHADING_PS3_GOURAUD (2 << 10) +# define R500_TEX6_SHADING_PS3_SOLID (0 << 12) +# define R500_TEX6_SHADING_PS3_FLAT (1 << 12) +# define R500_TEX6_SHADING_PS3_GOURAUD (2 << 12) +# define R500_TEX7_SHADING_PS3_SOLID (0 << 14) +# define R500_TEX7_SHADING_PS3_FLAT (1 << 14) +# define R500_TEX7_SHADING_PS3_GOURAUD (2 << 14) +# define R500_TEX8_SHADING_PS3_SOLID (0 << 16) +# define R500_TEX8_SHADING_PS3_FLAT (1 << 16) +# define R500_TEX8_SHADING_PS3_GOURAUD (2 << 16) +# define R500_TEX9_SHADING_PS3_SOLID (0 << 18) +# define R500_TEX9_SHADING_PS3_FLAT (1 << 18) +# define R500_TEX9_SHADING_PS3_GOURAUD (2 << 18) +# define R500_TEX10_SHADING_PS3_SOLID (0 << 20) +# define R500_TEX10_SHADING_PS3_FLAT (1 << 20) +# define R500_TEX10_SHADING_PS3_GOURAUD (2 << 20) +# define R500_COLOR0_TEX_OVERRIDE_NO (0 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_0 (1 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_1 (2 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_2 (3 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_3 (4 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_4 (5 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_5 (6 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_6 (7 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_7 (8 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_8_C2 (9 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_9_C3 (10 << 22) +# define R500_COLOR1_TEX_OVERRIDE_NO (0 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_0 (1 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_1 (2 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_2 (3 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_3 (4 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_4 (5 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_5 (6 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_6 (7 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_7 (8 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_8_C2 (9 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_9_C3 (10 << 26) + +/* Returns idle status of various G3D block, captured when GA_IDLE written or + * when hard or soft reset asserted. + */ +#define R500_GA_IDLE 0x425c +# define R500_GA_IDLE_PIPE3_Z_IDLE (0 << 0) +# define R500_GA_IDLE_PIPE2_Z_IDLE (0 << 1) +# define R500_GA_IDLE_PIPE3_CD_IDLE (0 << 2) +# define R500_GA_IDLE_PIPE2_CD_IDLE (0 << 3) +# define R500_GA_IDLE_PIPE3_FG_IDLE (0 << 4) +# define R500_GA_IDLE_PIPE2_FG_IDLE (0 << 5) +# define R500_GA_IDLE_PIPE3_US_IDLE (0 << 6) +# define R500_GA_IDLE_PIPE2_US_IDLE (0 << 7) +# define R500_GA_IDLE_PIPE3_SC_IDLE (0 << 8) +# define R500_GA_IDLE_PIPE2_SC_IDLE (0 << 9) +# define R500_GA_IDLE_PIPE3_RS_IDLE (0 << 10) +# define R500_GA_IDLE_PIPE2_RS_IDLE (0 << 11) +# define R500_GA_IDLE_PIPE1_Z_IDLE (0 << 12) +# define R500_GA_IDLE_PIPE0_Z_IDLE (0 << 13) +# define R500_GA_IDLE_PIPE1_CD_IDLE (0 << 14) +# define R500_GA_IDLE_PIPE0_CD_IDLE (0 << 15) +# define R500_GA_IDLE_PIPE1_FG_IDLE (0 << 16) +# define R500_GA_IDLE_PIPE0_FG_IDLE (0 << 17) +# define R500_GA_IDLE_PIPE1_US_IDLE (0 << 18) +# define R500_GA_IDLE_PIPE0_US_IDLE (0 << 19) +# define R500_GA_IDLE_PIPE1_SC_IDLE (0 << 20) +# define R500_GA_IDLE_PIPE0_SC_IDLE (0 << 21) +# define R500_GA_IDLE_PIPE1_RS_IDLE (0 << 22) +# define R500_GA_IDLE_PIPE0_RS_IDLE (0 << 23) +# define R500_GA_IDLE_SU_IDLE (0 << 24) +# define R500_GA_IDLE_GA_IDLE (0 << 25) +# define R500_GA_IDLE_GA_UNIT2_IDLE (0 << 26) + +/* Current value of stipple accumulator. */ +#define R300_GA_LINE_STIPPLE_VALUE 0x4260 + +/* S Texture Coordinate Value for Vertex 0 of Line (stuff textures -- i.e. AA) */ +#define R300_GA_LINE_S0 0x4264 +/* S Texture Coordinate Value for Vertex 1 of Lines (V2 of parallelogram -- stuff textures -- i.e. AA) */ +#define R300_GA_LINE_S1 0x4268 + +/* GA Input fifo high water marks */ +#define R500_GA_FIFO_CNTL 0x4270 +# define R500_GA_FIFO_CNTL_VERTEX_FIFO_MASK 0x00000007 +# define R500_GA_FIFO_CNTL_VERTEX_FIFO_SHIFT 0 +# define R500_GA_FIFO_CNTL_VERTEX_INDEX_MASK 0x00000038 +# define R500_GA_FIFO_CNTL_VERTEX_INDEX_SHIFT 3 +# define R500_GA_FIFO_CNTL_VERTEX_REG_MASK 0x00003fc0 +# define R500_GA_FIFO_CNTL_VERTEX_REG_SHIFT 6 + +/* GA enhance/tweaks */ +#define R300_GA_ENHANCE 0x4274 +# define R300_GA_ENHANCE_DEADLOCK_CNTL_NO_EFFECT (0 << 0) +# define R300_GA_ENHANCE_DEADLOCK_CNTL_PREVENT_TCL (1 << 0) /* Prevents TCL interface from deadlocking on GA side. */ +# define R300_GA_ENHANCE_FASTSYNC_CNTL_NO_EFFECT (0 << 1) +# define R300_GA_ENHANCE_FASTSYNC_CNTL_ENABLE (1 << 1) /* Enables high-performance register/primitive switching. */ +# define R500_GA_ENHANCE_REG_READWRITE_NO_EFFECT (0 << 2) /* R520+ only */ +# define R500_GA_ENHANCE_REG_READWRITE_ENABLE (1 << 2) /* R520+ only, Enables GA support of simultaneous register reads and writes. */ +# define R500_GA_ENHANCE_REG_NOSTALL_NO_EFFECT (0 << 3) +# define R500_GA_ENHANCE_REG_NOSTALL_ENABLE (1 << 3) /* Enables GA support of no-stall reads for register read back. */ + +#define R300_GA_COLOR_CONTROL 0x4278 +# define R300_GA_COLOR_CONTROL_RGB0_SHADING_SOLID (0 << 0) +# define R300_GA_COLOR_CONTROL_RGB0_SHADING_FLAT (1 << 0) +# define R300_GA_COLOR_CONTROL_RGB0_SHADING_GOURAUD (2 << 0) +# define R300_GA_COLOR_CONTROL_ALPHA0_SHADING_SOLID (0 << 2) +# define R300_GA_COLOR_CONTROL_ALPHA0_SHADING_FLAT (1 << 2) +# define R300_GA_COLOR_CONTROL_ALPHA0_SHADING_GOURAUD (2 << 2) +# define R300_GA_COLOR_CONTROL_RGB1_SHADING_SOLID (0 << 4) +# define R300_GA_COLOR_CONTROL_RGB1_SHADING_FLAT (1 << 4) +# define R300_GA_COLOR_CONTROL_RGB1_SHADING_GOURAUD (2 << 4) +# define R300_GA_COLOR_CONTROL_ALPHA1_SHADING_SOLID (0 << 6) +# define R300_GA_COLOR_CONTROL_ALPHA1_SHADING_FLAT (1 << 6) +# define R300_GA_COLOR_CONTROL_ALPHA1_SHADING_GOURAUD (2 << 6) +# define R300_GA_COLOR_CONTROL_RGB2_SHADING_SOLID (0 << 8) +# define R300_GA_COLOR_CONTROL_RGB2_SHADING_FLAT (1 << 8) +# define R300_GA_COLOR_CONTROL_RGB2_SHADING_GOURAUD (2 << 8) +# define R300_GA_COLOR_CONTROL_ALPHA2_SHADING_SOLID (0 << 10) +# define R300_GA_COLOR_CONTROL_ALPHA2_SHADING_FLAT (1 << 10) +# define R300_GA_COLOR_CONTROL_ALPHA2_SHADING_GOURAUD (2 << 10) +# define R300_GA_COLOR_CONTROL_RGB3_SHADING_SOLID (0 << 12) +# define R300_GA_COLOR_CONTROL_RGB3_SHADING_FLAT (1 << 12) +# define R300_GA_COLOR_CONTROL_RGB3_SHADING_GOURAUD (2 << 12) +# define R300_GA_COLOR_CONTROL_ALPHA3_SHADING_SOLID (0 << 14) +# define R300_GA_COLOR_CONTROL_ALPHA3_SHADING_FLAT (1 << 14) +# define R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD (2 << 14) +# define R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_FIRST (0 << 16) +# define R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_SECOND (1 << 16) +# define R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_THIRD (2 << 16) +# define R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST (3 << 16) + +/** TODO: might be candidate for removal */ +# define R300_RE_SHADE_MODEL_SMOOTH ( \ + R300_GA_COLOR_CONTROL_RGB0_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA0_SHADING_GOURAUD | \ + R300_GA_COLOR_CONTROL_RGB1_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA1_SHADING_GOURAUD | \ + R300_GA_COLOR_CONTROL_RGB2_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA2_SHADING_GOURAUD | \ + R300_GA_COLOR_CONTROL_RGB3_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD | \ + R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST ) +/** TODO: might be candidate for removal, the GOURAUD stuff also looks buggy to me */ +# define R300_RE_SHADE_MODEL_FLAT ( \ + R300_GA_COLOR_CONTROL_RGB0_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA0_SHADING_FLAT | \ + R300_GA_COLOR_CONTROL_RGB1_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA1_SHADING_GOURAUD | \ + R300_GA_COLOR_CONTROL_RGB2_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA2_SHADING_FLAT | \ + R300_GA_COLOR_CONTROL_RGB3_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD | \ + R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST ) + +/* Specifies red & green components of fill color -- S312 format -- Backwards comp. */ +#define R300_GA_SOLID_RG 0x427c +# define GA_SOLID_RG_COLOR_GREEN_SHIFT 0 +# define GA_SOLID_RG_COLOR_GREEN_MASK 0x0000ffff +# define GA_SOLID_RG_COLOR_RED_SHIFT 16 +# define GA_SOLID_RG_COLOR_RED_MASK 0xffff0000 +/* Specifies blue & alpha components of fill color -- S312 format -- Backwards comp. */ +#define R300_GA_SOLID_BA 0x4280 +# define GA_SOLID_BA_COLOR_ALPHA_SHIFT 0 +# define GA_SOLID_BA_COLOR_ALPHA_MASK 0x0000ffff +# define GA_SOLID_BA_COLOR_BLUE_SHIFT 16 +# define GA_SOLID_BA_COLOR_BLUE_MASK 0xffff0000 + +/* Polygon Mode + * Dangerous + */ +#define R300_GA_POLY_MODE 0x4288 +# define R300_GA_POLY_MODE_DISABLE (0 << 0) +# define R300_GA_POLY_MODE_DUAL (1 << 0) /* send 2 sets of 3 polys with specified poly type */ +/* reserved */ +# define R300_GA_POLY_MODE_FRONT_PTYPE_POINT (0 << 4) +# define R300_GA_POLY_MODE_FRONT_PTYPE_LINE (1 << 4) +# define R300_GA_POLY_MODE_FRONT_PTYPE_TRI (2 << 4) +/* reserved */ +# define R300_GA_POLY_MODE_BACK_PTYPE_POINT (0 << 7) +# define R300_GA_POLY_MODE_BACK_PTYPE_LINE (1 << 7) +# define R300_GA_POLY_MODE_BACK_PTYPE_TRI (2 << 7) +/* reserved */ + +/* Specifies the rouding mode for geometry & color SPFP to FP conversions. */ +#define R300_GA_ROUND_MODE 0x428c +# define R300_GA_ROUND_MODE_GEOMETRY_ROUND_TRUNC (0 << 0) +# define R300_GA_ROUND_MODE_GEOMETRY_ROUND_NEAREST (1 << 0) +# define R300_GA_ROUND_MODE_COLOR_ROUND_TRUNC (0 << 2) +# define R300_GA_ROUND_MODE_COLOR_ROUND_NEAREST (1 << 2) +# define R300_GA_ROUND_MODE_RGB_CLAMP_RGB (0 << 4) +# define R300_GA_ROUND_MODE_RGB_CLAMP_FP20 (1 << 4) +# define R300_GA_ROUND_MODE_ALPHA_CLAMP_RGB (0 << 5) +# define R300_GA_ROUND_MODE_ALPHA_CLAMP_FP20 (1 << 5) +# define R500_GA_ROUND_MODE_GEOMETRY_MASK_SHIFT 6 +# define R500_GA_ROUND_MODE_GEOMETRY_MASK_MASK 0x000003c0 + +/* Specifies x & y offsets for vertex data after conversion to FP. + * Offsets are in S15 format (subpixels -- 1/12 or 1/16, even in 8b + * subprecision). + */ +#define R300_GA_OFFSET 0x4290 +# define R300_GA_OFFSET_X_OFFSET_SHIFT 0 +# define R300_GA_OFFSET_X_OFFSET_MASK 0x0000ffff +# define R300_GA_OFFSET_Y_OFFSET_SHIFT 16 +# define R300_GA_OFFSET_Y_OFFSET_MASK 0xffff0000 + +/* Specifies the scale to apply to fog. */ +#define R300_GA_FOG_SCALE 0x4294 +/* Specifies the offset to apply to fog. */ +#define R300_GA_FOG_OFFSET 0x4298 +/* Specifies number of cycles to assert reset, and also causes RB3D soft reset to assert. */ +#define R300_GA_SOFT_RESET 0x429c + +/* Not sure why there are duplicate of factor and constant values. + * My best guess so far is that there are seperate zbiases for test and write. + * Ordering might be wrong. + * Some of the tests indicate that fgl has a fallback implementation of zbias + * via pixel shaders. + */ +#define R300_SU_TEX_WRAP 0x42A0 +#define R300_SU_POLY_OFFSET_FRONT_SCALE 0x42A4 +#define R300_SU_POLY_OFFSET_FRONT_OFFSET 0x42A8 +#define R300_SU_POLY_OFFSET_BACK_SCALE 0x42AC +#define R300_SU_POLY_OFFSET_BACK_OFFSET 0x42B0 + +/* This register needs to be set to (1<<1) for RV350 to correctly + * perform depth test (see --vb-triangles in r300_demo) + * Don't know about other chips. - Vladimir + * This is set to 3 when GL_POLYGON_OFFSET_FILL is on. + * My guess is that there are two bits for each zbias primitive + * (FILL, LINE, POINT). + * One to enable depth test and one for depth write. + * Yet this doesnt explain why depth writes work ... + */ +#define R300_SU_POLY_OFFSET_ENABLE 0x42B4 +# define R300_FRONT_ENABLE (1 << 0) +# define R300_BACK_ENABLE (1 << 1) +# define R300_PARA_ENABLE (1 << 2) + +#define R300_SU_CULL_MODE 0x42B8 +# define R300_CULL_FRONT (1 << 0) +# define R300_CULL_BACK (1 << 1) +# define R300_FRONT_FACE_CCW (0 << 2) +# define R300_FRONT_FACE_CW (1 << 2) + +/* SU Depth Scale value */ +#define R300_SU_DEPTH_SCALE 0x42c0 +/* SU Depth Offset value */ +#define R300_SU_DEPTH_OFFSET 0x42c4 + + +/* BEGIN: Rasterization / Interpolators - many guesses */ + +/* + * TC_CNT is the number of incoming texture coordinate sets (i.e. it depends + * on the vertex program, *not* the fragment program) + */ +#define R300_RS_COUNT 0x4300 +# define R300_IT_COUNT_SHIFT 0 +# define R300_IT_COUNT_MASK 0x0000007f +# define R300_IC_COUNT_SHIFT 7 +# define R300_IC_COUNT_MASK 0x00000780 +# define R300_W_ADDR_SHIFT 12 +# define R300_W_ADDR_MASK 0x0003f000 +# define R300_HIRES_DIS (0 << 18) +# define R300_HIRES_EN (1 << 18) + +#define R300_RS_INST_COUNT 0x4304 +# define R300_RS_INST_COUNT_SHIFT 0 +# define R300_RS_INST_COUNT_MASK 0x0000000f +# define R300_RS_TX_OFFSET_SHIFT 5 +# define R300_RS_TX_OFFSET_MASK 0x000000e0 + +/* gap */ + +/* Only used for texture coordinates. + * Use the source field to route texture coordinate input from the + * vertex program to the desired interpolator. Note that the source + * field is relative to the outputs the vertex program *actually* + * writes. If a vertex program only writes texcoord[1], this will + * be source index 0. + * Set INTERP_USED on all interpolators that produce data used by + * the fragment program. INTERP_USED looks like a swizzling mask, + * but I haven't seen it used that way. + * + * Note: The _UNKNOWN constants are always set in their respective + * register. I don't know if this is necessary. + */ +#define R300_RS_IP_0 0x4310 +#define R300_RS_IP_1 0x4314 +#define R300_RS_IP_2 0x4318 +#define R300_RS_IP_3 0x431C +# define R300_RS_INTERP_SRC_SHIFT 2 /* TODO: check for removal */ +# define R300_RS_INTERP_SRC_MASK (7 << 2) /* TODO: check for removal */ +# define R300_RS_TEX_PTR(x) (x << 0) +# define R300_RS_COL_PTR(x) (x << 6) +# define R300_RS_COL_FMT(x) (x << 9) +# define R300_RS_COL_FMT_RGBA 0 +# define R300_RS_COL_FMT_RGB0 1 +# define R300_RS_COL_FMT_RGB1 2 +# define R300_RS_COL_FMT_000A 4 +# define R300_RS_COL_FMT_0000 5 +# define R300_RS_COL_FMT_0001 6 +# define R300_RS_COL_FMT_111A 8 +# define R300_RS_COL_FMT_1110 9 +# define R300_RS_COL_FMT_1111 10 +# define R300_RS_SEL_S(x) (x << 13) +# define R300_RS_SEL_T(x) (x << 16) +# define R300_RS_SEL_R(x) (x << 19) +# define R300_RS_SEL_Q(x) (x << 22) +# define R300_RS_SEL_C0 0 +# define R300_RS_SEL_C1 1 +# define R300_RS_SEL_C2 2 +# define R300_RS_SEL_C3 3 +# define R300_RS_SEL_K0 4 +# define R300_RS_SEL_K1 5 + + +/* */ +#define R500_RS_INST_0 0x4320 +#define R500_RS_INST_1 0x4324 +#define R500_RS_INST_2 0x4328 +#define R500_RS_INST_3 0x432c +#define R500_RS_INST_4 0x4330 +#define R500_RS_INST_5 0x4334 +#define R500_RS_INST_6 0x4338 +#define R500_RS_INST_7 0x433c +#define R500_RS_INST_8 0x4340 +#define R500_RS_INST_9 0x4344 +#define R500_RS_INST_10 0x4348 +#define R500_RS_INST_11 0x434c +#define R500_RS_INST_12 0x4350 +#define R500_RS_INST_13 0x4354 +#define R500_RS_INST_14 0x4358 +#define R500_RS_INST_15 0x435c +#define R500_RS_INST_TEX_ID_SHIFT 0 +#define R500_RS_INST_TEX_CN_WRITE (1 << 4) +#define R500_RS_INST_TEX_ADDR_SHIFT 5 +#define R500_RS_INST_COL_ID_SHIFT 12 +#define R500_RS_INST_COL_CN_NO_WRITE (0 << 16) +#define R500_RS_INST_COL_CN_WRITE (1 << 16) +#define R500_RS_INST_COL_CN_WRITE_FBUFFER (2 << 16) +#define R500_RS_INST_COL_CN_WRITE_BACKFACE (3 << 16) +#define R500_RS_INST_COL_ADDR_SHIFT 18 +#define R500_RS_INST_TEX_ADJ (1 << 25) +#define R500_RS_INST_W_CN (1 << 26) + +/* These DWORDs control how vertex data is routed into fragment program + * registers, after interpolators. + */ +#define R300_RS_INST_0 0x4330 +#define R300_RS_INST_1 0x4334 +#define R300_RS_INST_2 0x4338 +#define R300_RS_INST_3 0x433C +#define R300_RS_INST_4 0x4340 +#define R300_RS_INST_5 0x4344 +#define R300_RS_INST_6 0x4348 +#define R300_RS_INST_7 0x434C +# define R300_RS_INST_TEX_ID(x) ((x) << 0) +# define R300_RS_INST_TEX_CN_WRITE (1 << 3) +# define R300_RS_INST_TEX_ADDR_SHIFT 6 +# define R300_RS_INST_COL_ID(x) ((x) << 11) +# define R300_RS_INST_COL_CN_WRITE (1 << 14) +# define R300_RS_INST_COL_ADDR_SHIFT 17 +# define R300_RS_INST_TEX_ADJ (1 << 22) +# define R300_RS_COL_BIAS_UNUSED_SHIFT 23 + +/* END: Rasterization / Interpolators - many guesses */ + +/* Hierarchical Z Enable */ +#define R300_SC_HYPERZ 0x43a4 +# define R300_SC_HYPERZ_DISABLE (0 << 0) +# define R300_SC_HYPERZ_ENABLE (1 << 0) +# define R300_SC_HYPERZ_MIN (0 << 1) +# define R300_SC_HYPERZ_MAX (1 << 1) +# define R300_SC_HYPERZ_ADJ_256 (0 << 2) +# define R300_SC_HYPERZ_ADJ_128 (1 << 2) +# define R300_SC_HYPERZ_ADJ_64 (2 << 2) +# define R300_SC_HYPERZ_ADJ_32 (3 << 2) +# define R300_SC_HYPERZ_ADJ_16 (4 << 2) +# define R300_SC_HYPERZ_ADJ_8 (5 << 2) +# define R300_SC_HYPERZ_ADJ_4 (6 << 2) +# define R300_SC_HYPERZ_ADJ_2 (7 << 2) +# define R300_SC_HYPERZ_HZ_Z0MIN_NO (0 << 5) +# define R300_SC_HYPERZ_HZ_Z0MIN (1 << 5) +# define R300_SC_HYPERZ_HZ_Z0MAX_NO (0 << 6) +# define R300_SC_HYPERZ_HZ_Z0MAX (1 << 6) + +#define R300_SC_EDGERULE 0x43a8 + +/* BEGIN: Scissors and cliprects */ + +/* There are four clipping rectangles. Their corner coordinates are inclusive. + * Every pixel is assigned a number from 0 and 15 by setting bits 0-3 depending + * on whether the pixel is inside cliprects 0-3, respectively. For example, + * if a pixel is inside cliprects 0 and 1, but outside 2 and 3, it is assigned + * the number 3 (binary 0011). + * Iff the bit corresponding to the pixel's number in RE_CLIPRECT_CNTL is set, + * the pixel is rasterized. + * + * In addition to this, there is a scissors rectangle. Only pixels inside the + * scissors rectangle are drawn. (coordinates are inclusive) + * + * For some reason, the top-left corner of the framebuffer is at (1440, 1440) + * for the purpose of clipping and scissors. + */ +#define R300_SC_CLIPRECT_TL_0 0x43B0 +#define R300_SC_CLIPRECT_BR_0 0x43B4 +#define R300_SC_CLIPRECT_TL_1 0x43B8 +#define R300_SC_CLIPRECT_BR_1 0x43BC +#define R300_SC_CLIPRECT_TL_2 0x43C0 +#define R300_SC_CLIPRECT_BR_2 0x43C4 +#define R300_SC_CLIPRECT_TL_3 0x43C8 +#define R300_SC_CLIPRECT_BR_3 0x43CC +# define R300_CLIPRECT_OFFSET 1440 +# define R300_CLIPRECT_MASK 0x1FFF +# define R300_CLIPRECT_X_SHIFT 0 +# define R300_CLIPRECT_X_MASK (0x1FFF << 0) +# define R300_CLIPRECT_Y_SHIFT 13 +# define R300_CLIPRECT_Y_MASK (0x1FFF << 13) +#define R300_SC_CLIP_RULE 0x43D0 +# define R300_CLIP_OUT (1 << 0) +# define R300_CLIP_0 (1 << 1) +# define R300_CLIP_1 (1 << 2) +# define R300_CLIP_10 (1 << 3) +# define R300_CLIP_2 (1 << 4) +# define R300_CLIP_20 (1 << 5) +# define R300_CLIP_21 (1 << 6) +# define R300_CLIP_210 (1 << 7) +# define R300_CLIP_3 (1 << 8) +# define R300_CLIP_30 (1 << 9) +# define R300_CLIP_31 (1 << 10) +# define R300_CLIP_310 (1 << 11) +# define R300_CLIP_32 (1 << 12) +# define R300_CLIP_320 (1 << 13) +# define R300_CLIP_321 (1 << 14) +# define R300_CLIP_3210 (1 << 15) + +/* gap */ + +#define R300_SC_SCISSORS_TL 0x43E0 +#define R300_SC_SCISSORS_BR 0x43E4 +# define R300_SCISSORS_OFFSET 1440 +# define R300_SCISSORS_X_SHIFT 0 +# define R300_SCISSORS_X_MASK (0x1FFF << 0) +# define R300_SCISSORS_Y_SHIFT 13 +# define R300_SCISSORS_Y_MASK (0x1FFF << 13) + +/* Screen door sample mask */ +#define R300_SC_SCREENDOOR 0x43e8 + +/* END: Scissors and cliprects */ + +/* BEGIN: Texture specification */ + +/* + * The texture specification dwords are grouped by meaning and not by texture + * unit. This means that e.g. the offset for texture image unit N is found in + * register TX_OFFSET_0 + (4*N) + */ +#define R300_TX_FILTER0_0 0x4400 +#define R300_TX_FILTER0_1 0x4404 +#define R300_TX_FILTER0_2 0x4408 +#define R300_TX_FILTER0_3 0x440c +#define R300_TX_FILTER0_4 0x4410 +#define R300_TX_FILTER0_5 0x4414 +#define R300_TX_FILTER0_6 0x4418 +#define R300_TX_FILTER0_7 0x441c +#define R300_TX_FILTER0_8 0x4420 +#define R300_TX_FILTER0_9 0x4424 +#define R300_TX_FILTER0_10 0x4428 +#define R300_TX_FILTER0_11 0x442c +#define R300_TX_FILTER0_12 0x4430 +#define R300_TX_FILTER0_13 0x4434 +#define R300_TX_FILTER0_14 0x4438 +#define R300_TX_FILTER0_15 0x443c +# define R300_TX_REPEAT 0 +# define R300_TX_MIRRORED 1 +# define R300_TX_CLAMP_TO_EDGE 2 +# define R300_TX_MIRROR_ONCE_TO_EDGE 3 +# define R300_TX_CLAMP 4 +# define R300_TX_MIRROR_ONCE 5 +# define R300_TX_CLAMP_TO_BORDER 6 +# define R300_TX_MIRROR_ONCE_TO_BORDER 7 +# define R300_TX_WRAP_S_SHIFT 0 +# define R300_TX_WRAP_S_MASK (7 << 0) +# define R300_TX_WRAP_T_SHIFT 3 +# define R300_TX_WRAP_T_MASK (7 << 3) +# define R300_TX_WRAP_R_SHIFT 6 +# define R300_TX_WRAP_R_MASK (7 << 6) +# define R300_TX_MAG_FILTER_4 (0 << 9) +# define R300_TX_MAG_FILTER_NEAREST (1 << 9) +# define R300_TX_MAG_FILTER_LINEAR (2 << 9) +# define R300_TX_MAG_FILTER_ANISO (3 << 9) +# define R300_TX_MAG_FILTER_MASK (3 << 9) +# define R300_TX_MIN_FILTER_NEAREST (1 << 11) +# define R300_TX_MIN_FILTER_LINEAR (2 << 11) +# define R300_TX_MIN_FILTER_ANISO (3 << 11) +# define R300_TX_MIN_FILTER_MASK (3 << 11) +# define R300_TX_MIN_FILTER_MIP_NONE (0 << 13) +# define R300_TX_MIN_FILTER_MIP_NEAREST (1 << 13) +# define R300_TX_MIN_FILTER_MIP_LINEAR (2 << 13) +# define R300_TX_MIN_FILTER_MIP_MASK (3 << 13) +# define R300_TX_MAX_ANISO_1_TO_1 (0 << 21) +# define R300_TX_MAX_ANISO_2_TO_1 (1 << 21) +# define R300_TX_MAX_ANISO_4_TO_1 (2 << 21) +# define R300_TX_MAX_ANISO_8_TO_1 (3 << 21) +# define R300_TX_MAX_ANISO_16_TO_1 (4 << 21) +# define R300_TX_MAX_ANISO_MASK (7 << 21) + +#define R300_TX_FILTER1_0 0x4440 +# define R300_CHROMA_KEY_MODE_DISABLE 0 +# define R300_CHROMA_KEY_FORCE 1 +# define R300_CHROMA_KEY_BLEND 2 +# define R300_MC_ROUND_NORMAL (0<<2) +# define R300_MC_ROUND_MPEG4 (1<<2) +# define R300_LOD_BIAS_SHIFT 3 +# define R300_LOD_BIAS_MASK 0x1ff8 +# define R300_EDGE_ANISO_EDGE_DIAG (0<<13) +# define R300_EDGE_ANISO_EDGE_ONLY (1<<13) +# define R300_MC_COORD_TRUNCATE_DISABLE (0<<14) +# define R300_MC_COORD_TRUNCATE_MPEG (1<<14) +# define R300_TX_TRI_PERF_0_8 (0<<15) +# define R300_TX_TRI_PERF_1_8 (1<<15) +# define R300_TX_TRI_PERF_1_4 (2<<15) +# define R300_TX_TRI_PERF_3_8 (3<<15) +# define R300_ANISO_THRESHOLD_MASK (7<<17) + +# define R500_MACRO_SWITCH (1<<22) +# define R500_BORDER_FIX (1<<31) + +#define R300_TX_SIZE_0 0x4480 +# define R300_TX_WIDTHMASK_SHIFT 0 +# define R300_TX_WIDTHMASK_MASK (2047 << 0) +# define R300_TX_HEIGHTMASK_SHIFT 11 +# define R300_TX_HEIGHTMASK_MASK (2047 << 11) +# define R300_TX_DEPTHMASK_SHIFT 22 +# define R300_TX_DEPTHMASK_MASK (0xf << 22) +# define R300_TX_MAX_MIP_LEVEL_SHIFT 26 +# define R300_TX_MAX_MIP_LEVEL_MASK (0xf << 26) +# define R300_TX_SIZE_PROJECTED (1<<30) +# define R300_TX_SIZE_TXPITCH_EN (1<<31) +#define R300_TX_FORMAT_0 0x44C0 + /* The interpretation of the format word by Wladimir van der Laan */ + /* The X, Y, Z and W refer to the layout of the components. + They are given meanings as R, G, B and Alpha by the swizzle + specification */ +# define R300_TX_FORMAT_X8 0x0 +# define R500_TX_FORMAT_X1 0x0 // bit set in format 2 +# define R300_TX_FORMAT_X16 0x1 +# define R500_TX_FORMAT_X1_REV 0x0 // bit set in format 2 +# define R300_TX_FORMAT_Y4X4 0x2 +# define R300_TX_FORMAT_Y8X8 0x3 +# define R300_TX_FORMAT_Y16X16 0x4 +# define R300_TX_FORMAT_Z3Y3X2 0x5 +# define R300_TX_FORMAT_Z5Y6X5 0x6 +# define R300_TX_FORMAT_Z6Y5X5 0x7 +# define R300_TX_FORMAT_Z11Y11X10 0x8 +# define R300_TX_FORMAT_Z10Y11X11 0x9 +# define R300_TX_FORMAT_W4Z4Y4X4 0xA +# define R300_TX_FORMAT_W1Z5Y5X5 0xB +# define R300_TX_FORMAT_W8Z8Y8X8 0xC +# define R300_TX_FORMAT_W2Z10Y10X10 0xD +# define R300_TX_FORMAT_W16Z16Y16X16 0xE +# define R300_TX_FORMAT_DXT1 0xF +# define R300_TX_FORMAT_DXT3 0x10 +# define R300_TX_FORMAT_DXT5 0x11 +# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */ +# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */ +# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ +# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ + + /* These two values are wrong, but they're the only values that + * produce any even vaguely correct results. Can r300 only do 16-bit + * depth textures? + */ +# define R300_TX_FORMAT_X24_Y8 0x1e +# define R300_TX_FORMAT_X32 0x1e + + /* 0x16 - some 16 bit green format.. ?? */ +# define R300_TX_FORMAT_3D (1 << 25) +# define R300_TX_FORMAT_CUBIC_MAP (2 << 25) + + /* gap */ + /* Floating point formats */ + /* Note - hardware supports both 16 and 32 bit floating point */ +# define R300_TX_FORMAT_FL_I16 0x18 +# define R300_TX_FORMAT_FL_I16A16 0x19 +# define R300_TX_FORMAT_FL_R16G16B16A16 0x1A +# define R300_TX_FORMAT_FL_I32 0x1B +# define R300_TX_FORMAT_FL_I32A32 0x1C +# define R300_TX_FORMAT_FL_R32G32B32A32 0x1D + /* alpha modes, convenience mostly */ + /* if you have alpha, pick constant appropriate to the + number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */ +# define R300_TX_FORMAT_ALPHA_1CH 0x000 +# define R300_TX_FORMAT_ALPHA_2CH 0x200 +# define R300_TX_FORMAT_ALPHA_4CH 0x600 +# define R300_TX_FORMAT_ALPHA_NONE 0xA00 + /* Swizzling */ + /* constants */ +# define R300_TX_FORMAT_X 0 +# define R300_TX_FORMAT_Y 1 +# define R300_TX_FORMAT_Z 2 +# define R300_TX_FORMAT_W 3 +# define R300_TX_FORMAT_ZERO 4 +# define R300_TX_FORMAT_ONE 5 + /* 2.0*Z, everything above 1.0 is set to 0.0 */ +# define R300_TX_FORMAT_CUT_Z 6 + /* 2.0*W, everything above 1.0 is set to 0.0 */ +# define R300_TX_FORMAT_CUT_W 7 + +# define R300_TX_FORMAT_B_SHIFT 18 +# define R300_TX_FORMAT_G_SHIFT 15 +# define R300_TX_FORMAT_R_SHIFT 12 +# define R300_TX_FORMAT_A_SHIFT 9 + /* Convenience macro to take care of layout and swizzling */ +# define R300_EASY_TX_FORMAT(B, G, R, A, FMT) ( \ + ((R300_TX_FORMAT_##B)<<R300_TX_FORMAT_B_SHIFT) \ + | ((R300_TX_FORMAT_##G)<<R300_TX_FORMAT_G_SHIFT) \ + | ((R300_TX_FORMAT_##R)<<R300_TX_FORMAT_R_SHIFT) \ + | ((R300_TX_FORMAT_##A)<<R300_TX_FORMAT_A_SHIFT) \ + | (R300_TX_FORMAT_##FMT) \ + ) + /* These can be ORed with result of R300_EASY_TX_FORMAT() + We don't really know what they do. Take values from a + constant color ? */ +# define R300_TX_FORMAT_CONST_X (1<<5) +# define R300_TX_FORMAT_CONST_Y (2<<5) +# define R300_TX_FORMAT_CONST_Z (4<<5) +# define R300_TX_FORMAT_CONST_W (8<<5) + +# define R300_TX_FORMAT_YUV_MODE 0x00800000 + +#define R300_TX_FORMAT2_0 0x4500 /* obvious missing in gap */ +# define R300_TX_PITCHMASK_SHIFT 0 +# define R300_TX_PITCHMASK_MASK (2047 << 0) +# define R500_TXFORMAT_MSB (1 << 14) +# define R500_TXWIDTH_BIT11 (1 << 15) +# define R500_TXHEIGHT_BIT11 (1 << 16) +# define R500_POW2FIX2FLT (1 << 17) +# define R500_SEL_FILTER4_TC0 (0 << 18) +# define R500_SEL_FILTER4_TC1 (1 << 18) +# define R500_SEL_FILTER4_TC2 (2 << 18) +# define R500_SEL_FILTER4_TC3 (3 << 18) + +#define R300_TX_OFFSET_0 0x4540 +#define R300_TX_OFFSET_1 0x4544 +#define R300_TX_OFFSET_2 0x4548 +#define R300_TX_OFFSET_3 0x454C +#define R300_TX_OFFSET_4 0x4550 +#define R300_TX_OFFSET_5 0x4554 +#define R300_TX_OFFSET_6 0x4558 +#define R300_TX_OFFSET_7 0x455C + /* BEGIN: Guess from R200 */ +# define R300_TXO_ENDIAN_NO_SWAP (0 << 0) +# define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0) +# define R300_TXO_ENDIAN_WORD_SWAP (2 << 0) +# define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0) +# define R300_TXO_MACRO_TILE (1 << 2) +# define R300_TXO_MICRO_TILE_LINEAR (0 << 3) +# define R300_TXO_MICRO_TILE (1 << 3) +# define R300_TXO_MICRO_TILE_SQUARE (2 << 3) +# define R300_TXO_OFFSET_MASK 0xffffffe0 +# define R300_TXO_OFFSET_SHIFT 5 + /* END: Guess from R200 */ + +/* 32 bit chroma key */ +#define R300_TX_CHROMA_KEY_0 0x4580 +#define R300_TX_CHROMA_KEY_1 0x4584 +#define R300_TX_CHROMA_KEY_2 0x4588 +#define R300_TX_CHROMA_KEY_3 0x458c +#define R300_TX_CHROMA_KEY_4 0x4590 +#define R300_TX_CHROMA_KEY_5 0x4594 +#define R300_TX_CHROMA_KEY_6 0x4598 +#define R300_TX_CHROMA_KEY_7 0x459c +#define R300_TX_CHROMA_KEY_8 0x45a0 +#define R300_TX_CHROMA_KEY_9 0x45a4 +#define R300_TX_CHROMA_KEY_10 0x45a8 +#define R300_TX_CHROMA_KEY_11 0x45ac +#define R300_TX_CHROMA_KEY_12 0x45b0 +#define R300_TX_CHROMA_KEY_13 0x45b4 +#define R300_TX_CHROMA_KEY_14 0x45b8 +#define R300_TX_CHROMA_KEY_15 0x45bc +/* ff00ff00 == { 0, 1.0, 0, 1.0 } */ + +/* Border Color */ +#define R300_TX_BORDER_COLOR_0 0x45c0 +#define R300_TX_BORDER_COLOR_1 0x45c4 +#define R300_TX_BORDER_COLOR_2 0x45c8 +#define R300_TX_BORDER_COLOR_3 0x45cc +#define R300_TX_BORDER_COLOR_4 0x45d0 +#define R300_TX_BORDER_COLOR_5 0x45d4 +#define R300_TX_BORDER_COLOR_6 0x45d8 +#define R300_TX_BORDER_COLOR_7 0x45dc +#define R300_TX_BORDER_COLOR_8 0x45e0 +#define R300_TX_BORDER_COLOR_9 0x45e4 +#define R300_TX_BORDER_COLOR_10 0x45e8 +#define R300_TX_BORDER_COLOR_11 0x45ec +#define R300_TX_BORDER_COLOR_12 0x45f0 +#define R300_TX_BORDER_COLOR_13 0x45f4 +#define R300_TX_BORDER_COLOR_14 0x45f8 +#define R300_TX_BORDER_COLOR_15 0x45fc + + +/* END: Texture specification */ + +/* BEGIN: Fragment program instruction set */ + +/* Fragment programs are written directly into register space. + * There are separate instruction streams for texture instructions and ALU + * instructions. + * In order to synchronize these streams, the program is divided into up + * to 4 nodes. Each node begins with a number of TEX operations, followed + * by a number of ALU operations. + * The first node can have zero TEX ops, all subsequent nodes must have at + * least + * one TEX ops. + * All nodes must have at least one ALU op. + * + * The index of the last node is stored in PFS_CNTL_0: A value of 0 means + * 1 node, a value of 3 means 4 nodes. + * The total amount of instructions is defined in PFS_CNTL_2. The offsets are + * offsets into the respective instruction streams, while *_END points to the + * last instruction relative to this offset. + */ +#define R300_US_CONFIG 0x4600 +# define R300_PFS_CNTL_LAST_NODES_SHIFT 0 +# define R300_PFS_CNTL_LAST_NODES_MASK (3 << 0) +# define R300_PFS_CNTL_FIRST_NODE_HAS_TEX (1 << 3) +#define R300_US_PIXSIZE 0x4604 +/* There is an unshifted value here which has so far always been equal to the + * index of the highest used temporary register. + */ +#define R300_US_CODE_OFFSET 0x4608 +# define R300_PFS_CNTL_ALU_OFFSET_SHIFT 0 +# define R300_PFS_CNTL_ALU_OFFSET_MASK (63 << 0) +# define R300_PFS_CNTL_ALU_END_SHIFT 6 +# define R300_PFS_CNTL_ALU_END_MASK (63 << 6) +# define R300_PFS_CNTL_TEX_OFFSET_SHIFT 13 +# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 13) +# define R300_PFS_CNTL_TEX_END_SHIFT 18 +# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) + +/* gap */ + +/* Nodes are stored backwards. The last active node is always stored in + * PFS_NODE_3. + * Example: In a 2-node program, NODE_0 and NODE_1 are set to 0. The + * first node is stored in NODE_2, the second node is stored in NODE_3. + * + * Offsets are relative to the master offset from PFS_CNTL_2. + */ +#define R300_US_CODE_ADDR_0 0x4610 +#define R300_US_CODE_ADDR_1 0x4614 +#define R300_US_CODE_ADDR_2 0x4618 +#define R300_US_CODE_ADDR_3 0x461C +# define R300_ALU_START_SHIFT 0 +# define R300_ALU_START_MASK (63 << 0) +# define R300_ALU_SIZE_SHIFT 6 +# define R300_ALU_SIZE_MASK (63 << 6) +# define R300_TEX_START_SHIFT 12 +# define R300_TEX_START_MASK (31 << 12) +# define R300_TEX_SIZE_SHIFT 17 +# define R300_TEX_SIZE_MASK (31 << 17) +# define R300_RGBA_OUT (1 << 22) +# define R300_W_OUT (1 << 23) + +/* TEX + * As far as I can tell, texture instructions cannot write into output + * registers directly. A subsequent ALU instruction is always necessary, + * even if it's just MAD o0, r0, 1, 0 + */ +#define R300_US_TEX_INST_0 0x4620 +# define R300_SRC_ADDR_SHIFT 0 +# define R300_SRC_ADDR_MASK (31 << 0) +# define R300_DST_ADDR_SHIFT 6 +# define R300_DST_ADDR_MASK (31 << 6) +# define R300_TEX_ID_SHIFT 11 +# define R300_TEX_ID_MASK (15 << 11) +# define R300_TEX_INST_SHIFT 15 +# define R300_TEX_OP_NOP 0 +# define R300_TEX_OP_LD 1 +# define R300_TEX_OP_KIL 2 +# define R300_TEX_OP_TXP 3 +# define R300_TEX_OP_TXB 4 +# define R300_TEX_INST_MASK (7 << 15) + +/* Output format from the unfied shader */ +#define R300_US_OUT_FMT_0 0x46A4 +# define R300_US_OUT_FMT_C4_8 (0 << 0) +# define R300_US_OUT_FMT_C4_10 (1 << 0) +# define R300_US_OUT_FMT_C4_10_GAMMA (2 << 0) +# define R300_US_OUT_FMT_C_16 (3 << 0) +# define R300_US_OUT_FMT_C2_16 (4 << 0) +# define R300_US_OUT_FMT_C4_16 (5 << 0) +# define R300_US_OUT_FMT_C_16_MPEG (6 << 0) +# define R300_US_OUT_FMT_C2_16_MPEG (7 << 0) +# define R300_US_OUT_FMT_C2_4 (8 << 0) +# define R300_US_OUT_FMT_C_3_3_2 (9 << 0) +# define R300_US_OUT_FMT_C_6_5_6 (10 << 0) +# define R300_US_OUT_FMT_C_11_11_10 (11 << 0) +# define R300_US_OUT_FMT_C_10_11_11 (12 << 0) +# define R300_US_OUT_FMT_C_2_10_10_10 (13 << 0) +/* reserved */ +# define R300_US_OUT_FMT_UNUSED (15 << 0) +# define R300_US_OUT_FMT_C_16_FP (16 << 0) +# define R300_US_OUT_FMT_C2_16_FP (17 << 0) +# define R300_US_OUT_FMT_C4_16_FP (18 << 0) +# define R300_US_OUT_FMT_C_32_FP (19 << 0) +# define R300_US_OUT_FMT_C2_32_FP (20 << 0) +# define R300_US_OUT_FMT_C4_32_FP (21 << 0) +# define R300_C0_SEL_A (0 << 8) +# define R300_C0_SEL_R (1 << 8) +# define R300_C0_SEL_G (2 << 8) +# define R300_C0_SEL_B (3 << 8) +# define R300_C1_SEL_A (0 << 10) +# define R300_C1_SEL_R (1 << 10) +# define R300_C1_SEL_G (2 << 10) +# define R300_C1_SEL_B (3 << 10) +# define R300_C2_SEL_A (0 << 12) +# define R300_C2_SEL_R (1 << 12) +# define R300_C2_SEL_G (2 << 12) +# define R300_C2_SEL_B (3 << 12) +# define R300_C3_SEL_A (0 << 14) +# define R300_C3_SEL_R (1 << 14) +# define R300_C3_SEL_G (2 << 14) +# define R300_C3_SEL_B (3 << 14) +# define R300_OUT_SIGN(x) (x << 16) + +/* ALU + * The ALU instructions register blocks are enumerated according to the order + * in which fglrx. I assume there is space for 64 instructions, since + * each block has space for a maximum of 64 DWORDs, and this matches reported + * native limits. + * + * The basic functional block seems to be one MAD for each color and alpha, + * and an adder that adds all components after the MUL. + * - ADD, MUL, MAD etc.: use MAD with appropriate neutral operands + * - DP4: Use OUTC_DP4, OUTA_DP4 + * - DP3: Use OUTC_DP3, OUTA_DP4, appropriate alpha operands + * - DPH: Use OUTC_DP4, OUTA_DP4, appropriate alpha operands + * - CMPH: If ARG2 > 0.5, return ARG0, else return ARG1 + * - CMP: If ARG2 < 0, return ARG1, else return ARG0 + * - FLR: use FRC+MAD + * - XPD: use MAD+MAD + * - SGE, SLT: use MAD+CMP + * - RSQ: use ABS modifier for argument + * - Use OUTC_REPL_ALPHA to write results of an alpha-only operation + * (e.g. RCP) into color register + * - apparently, there's no quick DST operation + * - fglrx set FPI2_UNKNOWN_31 on a "MAD fragment.color, tmp0, tmp1, tmp2" + * - fglrx set FPI2_UNKNOWN_31 on a "MAX r2, r1, c0" + * - fglrx once set FPI0_UNKNOWN_31 on a "FRC r1, r1" + * + * Operand selection + * First stage selects three sources from the available registers and + * constant parameters. This is defined in INSTR1 (color) and INSTR3 (alpha). + * fglrx sorts the three source fields: Registers before constants, + * lower indices before higher indices; I do not know whether this is + * necessary. + * + * fglrx fills unused sources with "read constant 0" + * According to specs, you cannot select more than two different constants. + * + * Second stage selects the operands from the sources. This is defined in + * INSTR0 (color) and INSTR2 (alpha). You can also select the special constants + * zero and one. + * Swizzling and negation happens in this stage, as well. + * + * Important: Color and alpha seem to be mostly separate, i.e. their sources + * selection appears to be fully independent (the register storage is probably + * physically split into a color and an alpha section). + * However (because of the apparent physical split), there is some interaction + * WRT swizzling. If, for example, you want to load an R component into an + * Alpha operand, this R component is taken from a *color* source, not from + * an alpha source. The corresponding register doesn't even have to appear in + * the alpha sources list. (I hope this all makes sense to you) + * + * Destination selection + * The destination register index is in FPI1 (color) and FPI3 (alpha) + * together with enable bits. + * There are separate enable bits for writing into temporary registers + * (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_* + * /DSTA_OUTPUT). You can write to both at once, or not write at all (the + * same index must be used for both). + * + * Note: There is a special form for LRP + * - Argument order is the same as in ARB_fragment_program. + * - Operation is MAD + * - ARG1 is set to ARGC_SRC1C_LRP/ARGC_SRC1A_LRP + * - Set FPI0/FPI2_SPECIAL_LRP + * Arbitrary LRP (including support for swizzling) requires vanilla MAD+MAD + */ +#define R300_US_ALU_RGB_ADDR_0 0x46C0 +# define R300_ALU_SRC0C_SHIFT 0 +# define R300_ALU_SRC0C_MASK (31 << 0) +# define R300_ALU_SRC0C_CONST (1 << 5) +# define R300_ALU_SRC1C_SHIFT 6 +# define R300_ALU_SRC1C_MASK (31 << 6) +# define R300_ALU_SRC1C_CONST (1 << 11) +# define R300_ALU_SRC2C_SHIFT 12 +# define R300_ALU_SRC2C_MASK (31 << 12) +# define R300_ALU_SRC2C_CONST (1 << 17) +# define R300_ALU_SRC_MASK 0x0003ffff +# define R300_ALU_DSTC_SHIFT 18 +# define R300_ALU_DSTC_MASK (31 << 18) +# define R300_ALU_DSTC_REG_MASK_SHIFT 23 +# define R300_ALU_DSTC_REG_X (1 << 23) +# define R300_ALU_DSTC_REG_Y (1 << 24) +# define R300_ALU_DSTC_REG_Z (1 << 25) +# define R300_ALU_DSTC_OUTPUT_MASK_SHIFT 26 +# define R300_ALU_DSTC_OUTPUT_X (1 << 26) +# define R300_ALU_DSTC_OUTPUT_Y (1 << 27) +# define R300_ALU_DSTC_OUTPUT_Z (1 << 28) + +#define R300_US_ALU_ALPHA_ADDR_0 0x47C0 +# define R300_ALU_SRC0A_SHIFT 0 +# define R300_ALU_SRC0A_MASK (31 << 0) +# define R300_ALU_SRC0A_CONST (1 << 5) +# define R300_ALU_SRC1A_SHIFT 6 +# define R300_ALU_SRC1A_MASK (31 << 6) +# define R300_ALU_SRC1A_CONST (1 << 11) +# define R300_ALU_SRC2A_SHIFT 12 +# define R300_ALU_SRC2A_MASK (31 << 12) +# define R300_ALU_SRC2A_CONST (1 << 17) +# define R300_ALU_SRC_MASK 0x0003ffff +# define R300_ALU_DSTA_SHIFT 18 +# define R300_ALU_DSTA_MASK (31 << 18) +# define R300_ALU_DSTA_REG (1 << 23) +# define R300_ALU_DSTA_OUTPUT (1 << 24) +# define R300_ALU_DSTA_DEPTH (1 << 27) + +#define R300_US_ALU_RGB_INST_0 0x48C0 +# define R300_ALU_ARGC_SRC0C_XYZ 0 +# define R300_ALU_ARGC_SRC0C_XXX 1 +# define R300_ALU_ARGC_SRC0C_YYY 2 +# define R300_ALU_ARGC_SRC0C_ZZZ 3 +# define R300_ALU_ARGC_SRC1C_XYZ 4 +# define R300_ALU_ARGC_SRC1C_XXX 5 +# define R300_ALU_ARGC_SRC1C_YYY 6 +# define R300_ALU_ARGC_SRC1C_ZZZ 7 +# define R300_ALU_ARGC_SRC2C_XYZ 8 +# define R300_ALU_ARGC_SRC2C_XXX 9 +# define R300_ALU_ARGC_SRC2C_YYY 10 +# define R300_ALU_ARGC_SRC2C_ZZZ 11 +# define R300_ALU_ARGC_SRC0A 12 +# define R300_ALU_ARGC_SRC1A 13 +# define R300_ALU_ARGC_SRC2A 14 +# define R300_ALU_ARGC_SRCP_XYZ 15 +# define R300_ALU_ARGC_SRCP_XXX 16 +# define R300_ALU_ARGC_SRCP_YYY 17 +# define R300_ALU_ARGC_SRCP_ZZZ 18 +# define R300_ALU_ARGC_SRCP_WWW 19 +# define R300_ALU_ARGC_ZERO 20 +# define R300_ALU_ARGC_ONE 21 +# define R300_ALU_ARGC_HALF 22 +# define R300_ALU_ARGC_SRC0C_YZX 23 +# define R300_ALU_ARGC_SRC1C_YZX 24 +# define R300_ALU_ARGC_SRC2C_YZX 25 +# define R300_ALU_ARGC_SRC0C_ZXY 26 +# define R300_ALU_ARGC_SRC1C_ZXY 27 +# define R300_ALU_ARGC_SRC2C_ZXY 28 +# define R300_ALU_ARGC_SRC0CA_WZY 29 +# define R300_ALU_ARGC_SRC1CA_WZY 30 +# define R300_ALU_ARGC_SRC2CA_WZY 31 + +# define R300_ALU_ARG0C_SHIFT 0 +# define R300_ALU_ARG0C_MASK (31 << 0) +# define R300_ALU_ARG0C_NOP (0 << 5) +# define R300_ALU_ARG0C_NEG (1 << 5) +# define R300_ALU_ARG0C_ABS (2 << 5) +# define R300_ALU_ARG0C_NAB (3 << 5) +# define R300_ALU_ARG1C_SHIFT 7 +# define R300_ALU_ARG1C_MASK (31 << 7) +# define R300_ALU_ARG1C_NOP (0 << 12) +# define R300_ALU_ARG1C_NEG (1 << 12) +# define R300_ALU_ARG1C_ABS (2 << 12) +# define R300_ALU_ARG1C_NAB (3 << 12) +# define R300_ALU_ARG2C_SHIFT 14 +# define R300_ALU_ARG2C_MASK (31 << 14) +# define R300_ALU_ARG2C_NOP (0 << 19) +# define R300_ALU_ARG2C_NEG (1 << 19) +# define R300_ALU_ARG2C_ABS (2 << 19) +# define R300_ALU_ARG2C_NAB (3 << 19) +# define R300_ALU_SRCP_1_MINUS_2_SRC0 (0 << 21) +# define R300_ALU_SRCP_SRC1_MINUS_SRC0 (1 << 21) +# define R300_ALU_SRCP_SRC1_PLUS_SRC0 (2 << 21) +# define R300_ALU_SRCP_1_MINUS_SRC0 (3 << 21) + +# define R300_ALU_OUTC_MAD (0 << 23) +# define R300_ALU_OUTC_DP3 (1 << 23) +# define R300_ALU_OUTC_DP4 (2 << 23) +# define R300_ALU_OUTC_D2A (3 << 23) +# define R300_ALU_OUTC_MIN (4 << 23) +# define R300_ALU_OUTC_MAX (5 << 23) +# define R300_ALU_OUTC_CMPH (7 << 23) +# define R300_ALU_OUTC_CMP (8 << 23) +# define R300_ALU_OUTC_FRC (9 << 23) +# define R300_ALU_OUTC_REPL_ALPHA (10 << 23) + +# define R300_ALU_OUTC_MOD_NOP (0 << 27) +# define R300_ALU_OUTC_MOD_MUL2 (1 << 27) +# define R300_ALU_OUTC_MOD_MUL4 (2 << 27) +# define R300_ALU_OUTC_MOD_MUL8 (3 << 27) +# define R300_ALU_OUTC_MOD_DIV2 (4 << 27) +# define R300_ALU_OUTC_MOD_DIV4 (5 << 27) +# define R300_ALU_OUTC_MOD_DIV8 (6 << 27) + +# define R300_ALU_OUTC_CLAMP (1 << 30) +# define R300_ALU_INSERT_NOP (1 << 31) + +#define R300_US_ALU_ALPHA_INST_0 0x49C0 +# define R300_ALU_ARGA_SRC0C_X 0 +# define R300_ALU_ARGA_SRC0C_Y 1 +# define R300_ALU_ARGA_SRC0C_Z 2 +# define R300_ALU_ARGA_SRC1C_X 3 +# define R300_ALU_ARGA_SRC1C_Y 4 +# define R300_ALU_ARGA_SRC1C_Z 5 +# define R300_ALU_ARGA_SRC2C_X 6 +# define R300_ALU_ARGA_SRC2C_Y 7 +# define R300_ALU_ARGA_SRC2C_Z 8 +# define R300_ALU_ARGA_SRC0A 9 +# define R300_ALU_ARGA_SRC1A 10 +# define R300_ALU_ARGA_SRC2A 11 +# define R300_ALU_ARGA_SRCP_X 12 +# define R300_ALU_ARGA_SRCP_Y 13 +# define R300_ALU_ARGA_SRCP_Z 14 +# define R300_ALU_ARGA_SRCP_W 15 + +# define R300_ALU_ARGA_ZERO 16 +# define R300_ALU_ARGA_ONE 17 +# define R300_ALU_ARGA_HALF 18 +# define R300_ALU_ARG0A_SHIFT 0 +# define R300_ALU_ARG0A_MASK (31 << 0) +# define R300_ALU_ARG0A_NOP (0 << 5) +# define R300_ALU_ARG0A_NEG (1 << 5) +# define R300_ALU_ARG0A_ABS (2 << 5) +# define R300_ALU_ARG0A_NAB (3 << 5) +# define R300_ALU_ARG1A_SHIFT 7 +# define R300_ALU_ARG1A_MASK (31 << 7) +# define R300_ALU_ARG1A_NOP (0 << 12) +# define R300_ALU_ARG1A_NEG (1 << 12) +# define R300_ALU_ARG1A_ABS (2 << 12) +# define R300_ALU_ARG1A_NAB (3 << 12) +# define R300_ALU_ARG2A_SHIFT 14 +# define R300_ALU_ARG2A_MASK (31 << 14) +# define R300_ALU_ARG2A_NOP (0 << 19) +# define R300_ALU_ARG2A_NEG (1 << 19) +# define R300_ALU_ARG2A_ABS (2 << 19) +# define R300_ALU_ARG2A_NAB (3 << 19) +# define R300_ALU_SRCP_1_MINUS_2_SRC0 (0 << 21) +# define R300_ALU_SRCP_SRC1_MINUS_SRC0 (1 << 21) +# define R300_ALU_SRCP_SRC1_PLUS_SRC0 (2 << 21) +# define R300_ALU_SRCP_1_MINUS_SRC0 (3 << 21) + +# define R300_ALU_OUTA_MAD (0 << 23) +# define R300_ALU_OUTA_DP4 (1 << 23) +# define R300_ALU_OUTA_MIN (2 << 23) +# define R300_ALU_OUTA_MAX (3 << 23) +# define R300_ALU_OUTA_CND (5 << 23) +# define R300_ALU_OUTA_CMP (6 << 23) +# define R300_ALU_OUTA_FRC (7 << 23) +# define R300_ALU_OUTA_EX2 (8 << 23) +# define R300_ALU_OUTA_LG2 (9 << 23) +# define R300_ALU_OUTA_RCP (10 << 23) +# define R300_ALU_OUTA_RSQ (11 << 23) + +# define R300_ALU_OUTA_MOD_NOP (0 << 27) +# define R300_ALU_OUTA_MOD_MUL2 (1 << 27) +# define R300_ALU_OUTA_MOD_MUL4 (2 << 27) +# define R300_ALU_OUTA_MOD_MUL8 (3 << 27) +# define R300_ALU_OUTA_MOD_DIV2 (4 << 27) +# define R300_ALU_OUTA_MOD_DIV4 (5 << 27) +# define R300_ALU_OUTA_MOD_DIV8 (6 << 27) + +# define R300_ALU_OUTA_CLAMP (1 << 30) +/* END: Fragment program instruction set */ + +/* Fog: Fog Blending Enable */ +#define R300_FG_FOG_BLEND 0x4bc0 +# define R300_FG_FOG_BLEND_DISABLE (0 << 0) +# define R300_FG_FOG_BLEND_ENABLE (1 << 0) +# define R300_FG_FOG_BLEND_FN_LINEAR (0 << 1) +# define R300_FG_FOG_BLEND_FN_EXP (1 << 1) +# define R300_FG_FOG_BLEND_FN_EXP2 (2 << 1) +# define R300_FG_FOG_BLEND_FN_CONSTANT (3 << 1) +# define R300_FG_FOG_BLEND_FN_MASK (3 << 1) + +/* Fog: Red Component of Fog Color */ +#define R300_FG_FOG_COLOR_R 0x4bc8 +/* Fog: Green Component of Fog Color */ +#define R300_FG_FOG_COLOR_G 0x4bcc +/* Fog: Blue Component of Fog Color */ +#define R300_FG_FOG_COLOR_B 0x4bd0 +# define R300_FG_FOG_COLOR_MASK 0x000003ff + +/* Fog: Constant Factor for Fog Blending */ +#define R300_FG_FOG_FACTOR 0x4bc4 +# define FG_FOG_FACTOR_MASK 0x000003ff + +/* Fog: Alpha function */ +#define R300_FG_ALPHA_FUNC 0x4bd4 +# define R300_FG_ALPHA_FUNC_VAL_MASK 0x000000ff +# define R300_FG_ALPHA_FUNC_NEVER (0 << 8) +# define R300_FG_ALPHA_FUNC_LESS (1 << 8) +# define R300_FG_ALPHA_FUNC_EQUAL (2 << 8) +# define R300_FG_ALPHA_FUNC_LE (3 << 8) +# define R300_FG_ALPHA_FUNC_GREATER (4 << 8) +# define R300_FG_ALPHA_FUNC_NOTEQUAL (5 << 8) +# define R300_FG_ALPHA_FUNC_GE (6 << 8) +# define R300_FG_ALPHA_FUNC_ALWAYS (7 << 8) +# define R300_ALPHA_TEST_OP_MASK (7 << 8) +# define R300_FG_ALPHA_FUNC_DISABLE (0 << 11) +# define R300_FG_ALPHA_FUNC_ENABLE (1 << 11) + +# define R500_FG_ALPHA_FUNC_10BIT (0 << 12) +# define R500_FG_ALPHA_FUNC_8BIT (1 << 12) + +# define R300_FG_ALPHA_FUNC_MASK_DISABLE (0 << 16) +# define R300_FG_ALPHA_FUNC_MASK_ENABLE (1 << 16) +# define R300_FG_ALPHA_FUNC_CFG_2_OF_4 (0 << 17) +# define R300_FG_ALPHA_FUNC_CFG_3_OF_6 (1 << 17) + +# define R300_FG_ALPHA_FUNC_DITH_DISABLE (0 << 20) +# define R300_FG_ALPHA_FUNC_DITH_ENABLE (1 << 20) + +# define R500_FG_ALPHA_FUNC_OFFSET_DISABLE (0 << 24) +# define R500_FG_ALPHA_FUNC_OFFSET_ENABLE (1 << 24) /* Not supported in R520 */ +# define R500_FG_ALPHA_FUNC_DISC_ZERO_MASK_DISABLE (0 << 25) +# define R500_FG_ALPHA_FUNC_DISC_ZERO_MASK_ENABLE (1 << 25) + +# define R500_FG_ALPHA_FUNC_FP16_DISABLE (0 << 28) +# define R500_FG_ALPHA_FUNC_FP16_ENABLE (1 << 28) + + +/* Fog: Where does the depth come from? */ +#define R300_FG_DEPTH_SRC 0x4bd8 +# define R300_FG_DEPTH_SRC_SCAN (0 << 0) +# define R300_FG_DEPTH_SRC_SHADER (1 << 0) + +/* Fog: Alpha Compare Value */ +#define R500_FG_ALPHA_VALUE 0x4be0 +# define R500_FG_ALPHA_VALUE_MASK 0x0000ffff + +/* gap */ + +/* Fragment program parameters in 7.16 floating point */ +#define R300_PFS_PARAM_0_X 0x4C00 +#define R300_PFS_PARAM_0_Y 0x4C04 +#define R300_PFS_PARAM_0_Z 0x4C08 +#define R300_PFS_PARAM_0_W 0x4C0C +/* last consts */ +#define R300_PFS_PARAM_31_X 0x4DF0 +#define R300_PFS_PARAM_31_Y 0x4DF4 +#define R300_PFS_PARAM_31_Z 0x4DF8 +#define R300_PFS_PARAM_31_W 0x4DFC + +/* Unpipelined. */ +#define R300_RB3D_CCTL 0x4e00 +# define R300_RB3D_CCTL_NUM_MULTIWRITES_1_BUFFER (0 << 5) +# define R300_RB3D_CCTL_NUM_MULTIWRITES_2_BUFFERS (1 << 5) +# define R300_RB3D_CCTL_NUM_MULTIWRITES_3_BUFFERS (2 << 5) +# define R300_RB3D_CCTL_NUM_MULTIWRITES_4_BUFFERS (3 << 5) +# define R300_RB3D_CCTL_CLRCMP_FLIPE_DISABLE (0 << 7) +# define R300_RB3D_CCTL_CLRCMP_FLIPE_ENABLE (1 << 7) +# define R300_RB3D_CCTL_AA_COMPRESSION_DISABLE (0 << 9) +# define R300_RB3D_CCTL_AA_COMPRESSION_ENABLE (1 << 9) +# define R300_RB3D_CCTL_CMASK_DISABLE (0 << 10) +# define R300_RB3D_CCTL_CMASK_ENABLE (1 << 10) +/* reserved */ +# define R300_RB3D_CCTL_INDEPENDENT_COLOR_CHANNEL_MASK_DISABLE (0 << 12) +# define R300_RB3D_CCTL_INDEPENDENT_COLOR_CHANNEL_MASK_ENABLE (1 << 12) +# define R300_RB3D_CCTL_WRITE_COMPRESSION_ENABLE (0 << 13) +# define R300_RB3D_CCTL_WRITE_COMPRESSION_DISABLE (1 << 13) +# define R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_DISABLE (0 << 14) +# define R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE (1 << 14) + + +/* Notes: + * - AFAIK fglrx always sets BLEND_UNKNOWN when blending is used in + * the application + * - AFAIK fglrx always sets BLEND_NO_SEPARATE when CBLEND and ABLEND + * are set to the same + * function (both registers are always set up completely in any case) + * - Most blend flags are simply copied from R200 and not tested yet + */ +#define R300_RB3D_CBLEND 0x4E04 +#define R300_RB3D_ABLEND 0x4E08 +/* the following only appear in CBLEND */ +# define R300_ALPHA_BLEND_ENABLE (1 << 0) +# define R300_SEPARATE_ALPHA_ENABLE (1 << 1) +# define R300_READ_ENABLE (1 << 2) +# define R300_DISCARD_SRC_PIXELS_DIS (0 << 3) +# define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_0 (1 << 3) +# define R300_DISCARD_SRC_PIXELS_SRC_COLOR_0 (2 << 3) +# define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_COLOR_0 (3 << 3) +# define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_1 (4 << 3) +# define R300_DISCARD_SRC_PIXELS_SRC_COLOR_1 (5 << 3) +# define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_COLOR_1 (6 << 3) + +/* the following are shared between CBLEND and ABLEND */ +# define R300_FCN_MASK (3 << 12) +# define R300_COMB_FCN_ADD_CLAMP (0 << 12) +# define R300_COMB_FCN_ADD_NOCLAMP (1 << 12) +# define R300_COMB_FCN_SUB_CLAMP (2 << 12) +# define R300_COMB_FCN_SUB_NOCLAMP (3 << 12) +# define R300_COMB_FCN_MIN (4 << 12) +# define R300_COMB_FCN_MAX (5 << 12) +# define R300_COMB_FCN_RSUB_CLAMP (6 << 12) +# define R300_COMB_FCN_RSUB_NOCLAMP (7 << 12) +# define R300_BLEND_GL_ZERO (32) +# define R300_BLEND_GL_ONE (33) +# define R300_BLEND_GL_SRC_COLOR (34) +# define R300_BLEND_GL_ONE_MINUS_SRC_COLOR (35) +# define R300_BLEND_GL_DST_COLOR (36) +# define R300_BLEND_GL_ONE_MINUS_DST_COLOR (37) +# define R300_BLEND_GL_SRC_ALPHA (38) +# define R300_BLEND_GL_ONE_MINUS_SRC_ALPHA (39) +# define R300_BLEND_GL_DST_ALPHA (40) +# define R300_BLEND_GL_ONE_MINUS_DST_ALPHA (41) +# define R300_BLEND_GL_SRC_ALPHA_SATURATE (42) +# define R300_BLEND_GL_CONST_COLOR (43) +# define R300_BLEND_GL_ONE_MINUS_CONST_COLOR (44) +# define R300_BLEND_GL_CONST_ALPHA (45) +# define R300_BLEND_GL_ONE_MINUS_CONST_ALPHA (46) +# define R300_BLEND_MASK (63) +# define R300_SRC_BLEND_SHIFT (16) +# define R300_DST_BLEND_SHIFT (24) + +/* Constant color used by the blender. Pipelined through the blender. + * Note: For R520, this field is ignored, use RB3D_CONSTANT_COLOR_GB__BLUE, + * RB3D_CONSTANT_COLOR_GB__GREEN, etc. instead. + */ +#define R300_RB3D_BLEND_COLOR 0x4E10 + + +/* 3D Color Channel Mask. If all the channels used in the current color format + * are disabled, then the cb will discard all the incoming quads. Pipelined + * through the blender. + */ +#define RB3D_COLOR_CHANNEL_MASK 0x4E0C +# define RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0 (1 << 0) +# define RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 (1 << 1) +# define RB3D_COLOR_CHANNEL_MASK_RED_MASK0 (1 << 2) +# define RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0 (1 << 3) +# define RB3D_COLOR_CHANNEL_MASK_BLUE_MASK1 (1 << 4) +# define RB3D_COLOR_CHANNEL_MASK_GREEN_MASK1 (1 << 5) +# define RB3D_COLOR_CHANNEL_MASK_RED_MASK1 (1 << 6) +# define RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK1 (1 << 7) +# define RB3D_COLOR_CHANNEL_MASK_BLUE_MASK2 (1 << 8) +# define RB3D_COLOR_CHANNEL_MASK_GREEN_MASK2 (1 << 9) +# define RB3D_COLOR_CHANNEL_MASK_RED_MASK2 (1 << 10) +# define RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK2 (1 << 11) +# define RB3D_COLOR_CHANNEL_MASK_BLUE_MASK3 (1 << 12) +# define RB3D_COLOR_CHANNEL_MASK_GREEN_MASK3 (1 << 13) +# define RB3D_COLOR_CHANNEL_MASK_RED_MASK3 (1 << 14) +# define RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK3 (1 << 15) + +/* Clear color that is used when the color mask is set to 00. Unpipelined. + * Program this register with a 32-bit value in ARGB8888 or ARGB2101010 + * formats, ignoring the fields. + */ +#define RB3D_COLOR_CLEAR_VALUE 0x4e14 + +/* gap */ + +/* Color Compare Color. Stalls the 2d/3d datapath until it is idle. */ +#define RB3D_CLRCMP_CLR 0x4e20 + +/* Color Compare Mask. Stalls the 2d/3d datapath until it is idle. */ +#define RB3D_CLRCMP_MSK 0x4e24 + +/* Color Buffer Address Offset of multibuffer 0. Unpipelined. */ +#define R300_RB3D_COLOROFFSET0 0x4E28 +# define R300_COLOROFFSET_MASK 0xFFFFFFE0 +/* Color Buffer Address Offset of multibuffer 1. Unpipelined. */ +#define R300_RB3D_COLOROFFSET1 0x4E2C +/* Color Buffer Address Offset of multibuffer 2. Unpipelined. */ +#define R300_RB3D_COLOROFFSET2 0x4E30 +/* Color Buffer Address Offset of multibuffer 3. Unpipelined. */ +#define R300_RB3D_COLOROFFSET3 0x4E34 + +/* Color buffer format and tiling control for all the multibuffers and the + * pitch of multibuffer 0 to 3. Unpipelined. The cache must be empty before any + * of the registers are changed. + * + * Bit 16: Larger tiles + * Bit 17: 4x2 tiles + * Bit 18: Extremely weird tile like, but some pixels duplicated? + */ +#define R300_RB3D_COLORPITCH0 0x4E38 +# define R300_COLORPITCH_MASK 0x00003FFE +# define R300_COLOR_TILE_DISABLE (0 << 16) +# define R300_COLOR_TILE_ENABLE (1 << 16) +# define R300_COLOR_MICROTILE_DISABLE (0 << 17) +# define R300_COLOR_MICROTILE_ENABLE (1 << 17) +# define R300_COLOR_MICROTILE_ENABLE_SQUARE (2 << 17) /* Only available in 16-bit */ +# define R300_COLOR_ENDIAN_NO_SWAP (0 << 19) +# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 19) +# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 19) +# define R300_COLOR_ENDIAN_HALF_DWORD_SWAP (3 << 19) +# define R500_COLOR_FORMAT_ARGB10101010 (0 << 21) +# define R500_COLOR_FORMAT_UV1010 (1 << 21) +# define R500_COLOR_FORMAT_CI8 (2 << 21) /* 2D only */ +# define R300_COLOR_FORMAT_ARGB1555 (3 << 21) +# define R300_COLOR_FORMAT_RGB565 (4 << 21) +# define R500_COLOR_FORMAT_ARGB2101010 (5 << 21) +# define R300_COLOR_FORMAT_ARGB8888 (6 << 21) +# define R300_COLOR_FORMAT_ARGB32323232 (7 << 21) +/* reserved */ +# define R300_COLOR_FORMAT_I8 (9 << 21) +# define R300_COLOR_FORMAT_ARGB16161616 (10 << 21) +# define R300_COLOR_FORMAT_VYUY (11 << 21) +# define R300_COLOR_FORMAT_YVYU (12 << 21) +# define R300_COLOR_FORMAT_UV88 (13 << 21) +# define R500_COLOR_FORMAT_I10 (14 << 21) +# define R300_COLOR_FORMAT_ARGB4444 (15 << 21) +#define R300_RB3D_COLORPITCH1 0x4E3C +#define R300_RB3D_COLORPITCH2 0x4E40 +#define R300_RB3D_COLORPITCH3 0x4E44 + +/* gap */ + +/* Destination Color Buffer Cache Control/Status. If the cb is in e2 mode, then + * a flush or free will not occur upon a write to this register, but a sync + * will be immediately sent if one is requested. If both DC_FLUSH and DC_FREE + * are zero but DC_FINISH is one, then a sync will be sent immediately -- the + * cb will not wait for all the previous operations to complete before sending + * the sync. Unpipelined except when DC_FINISH and DC_FREE are both set to + * zero. + * + * Set to 0A before 3D operations, set to 02 afterwards. + */ +#define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_NO_EFFECT (0 << 0) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_NO_EFFECT_1 (1 << 0) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D (2 << 0) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D_1 (3 << 0) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_NO_EFFECT (0 << 2) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_NO_EFFECT_1 (1 << 2) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS (2 << 2) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS_1 (3 << 2) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FINISH_NO_SIGNAL (0 << 4) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FINISH_SIGNAL (1 << 4) + +#define R300_RB3D_DITHER_CTL 0x4E50 +# define R300_RB3D_DITHER_CTL_DITHER_MODE_TRUNCATE (0 << 0) +# define R300_RB3D_DITHER_CTL_DITHER_MODE_ROUND (1 << 0) +# define R300_RB3D_DITHER_CTL_DITHER_MODE_LUT (2 << 0) +/* reserved */ +# define R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_TRUNCATE (0 << 2) +# define R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_ROUND (1 << 2) +# define R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT (2 << 2) +/* reserved */ + +/* Resolve buffer destination address. The cache must be empty before changing + * this register if the cb is in resolve mode. Unpipelined + */ +#define R300_RB3D_AARESOLVE_OFFSET 0x4e80 +# define R300_RB3D_AARESOLVE_OFFSET_SHIFT 5 +# define R300_RB3D_AARESOLVE_OFFSET_MASK 0xffffffe0 /* At least according to the calculations of Christoph Brill */ + +/* Resolve Buffer Pitch and Tiling Control. The cache must be empty before + * changing this register if the cb is in resolve mode. Unpipelined + */ +#define R300_RB3D_AARESOLVE_PITCH 0x4e84 +# define R300_RB3D_AARESOLVE_PITCH_SHIFT 1 +# define R300_RB3D_AARESOLVE_PITCH_MASK 0x00003ffe /* At least according to the calculations of Christoph Brill */ + +/* Resolve Buffer Control. Unpipelined */ +#define R300_RB3D_AARESOLVE_CTL 0x4e88 +# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_NORMAL (0 << 0) +# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_RESOLVE (1 << 0) +# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_GAMMA_10 (0 << 1) +# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_GAMMA_22 (1 << 1) +# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_SAMPLE0 (0 << 2) +# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE (1 << 2) + + +/* Discard src pixels less than or equal to threshold. */ +#define R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4ea0 +/* Discard src pixels greater than or equal to threshold. */ +#define R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4ea4 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_BLUE_SHIFT 0 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_BLUE_MASK 0x000000ff +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_GREEN_SHIFT 8 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_GREEN_MASK 0x0000ff00 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_RED_SHIFT 16 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_RED_MASK 0x00ff0000 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_ALPHA_SHIFT 24 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_ALPHA_MASK 0xff000000 + +/* 3D ROP Control. Stalls the 2d/3d datapath until it is idle. */ +#define R300_RB3D_ROPCNTL 0x4e18 +# define R300_RB3D_ROPCNTL_ROP_ENABLE 0x00000004 +# define R300_RB3D_ROPCNTL_ROP_MASK (15 << 8) +# define R300_RB3D_ROPCNTL_ROP_SHIFT 8 + +/* Color Compare Flip. Stalls the 2d/3d datapath until it is idle. */ +#define R300_RB3D_CLRCMP_FLIPE 0x4e1c + +/* Sets the fifo sizes */ +#define R500_RB3D_FIFO_SIZE 0x4ef4 +# define R500_RB3D_FIFO_SIZE_OP_FIFO_SIZE_FULL (0 << 0) +# define R500_RB3D_FIFO_SIZE_OP_FIFO_SIZE_HALF (1 << 0) +# define R500_RB3D_FIFO_SIZE_OP_FIFO_SIZE_QUATER (2 << 0) +# define R500_RB3D_FIFO_SIZE_OP_FIFO_SIZE_EIGTHS (3 << 0) + +/* Constant color used by the blender. Pipelined through the blender. */ +#define R500_RB3D_CONSTANT_COLOR_AR 0x4ef8 +# define R500_RB3D_CONSTANT_COLOR_AR_RED_MASK 0x0000ffff +# define R500_RB3D_CONSTANT_COLOR_AR_RED_SHIFT 0 +# define R500_RB3D_CONSTANT_COLOR_AR_ALPHA_MASK 0xffff0000 +# define R500_RB3D_CONSTANT_COLOR_AR_ALPHA_SHIFT 16 + +/* Constant color used by the blender. Pipelined through the blender. */ +#define R500_RB3D_CONSTANT_COLOR_GB 0x4efc +# define R500_RB3D_CONSTANT_COLOR_AR_BLUE_MASK 0x0000ffff +# define R500_RB3D_CONSTANT_COLOR_AR_BLUE_SHIFT 0 +# define R500_RB3D_CONSTANT_COLOR_AR_GREEN_MASK 0xffff0000 +# define R500_RB3D_CONSTANT_COLOR_AR_GREEN_SHIFT 16 + +/* gap */ +/* There seems to be no "write only" setting, so use Z-test = ALWAYS + * for this. + * Bit (1<<8) is the "test" bit. so plain write is 6 - vd + */ +#define R300_ZB_CNTL 0x4F00 +# define R300_STENCIL_ENABLE (1 << 0) +# define R300_Z_ENABLE (1 << 1) +# define R300_Z_WRITE_ENABLE (1 << 2) +# define R300_Z_SIGNED_COMPARE (1 << 3) +# define R300_STENCIL_FRONT_BACK (1 << 4) + +#define R300_ZB_ZSTENCILCNTL 0x4f04 + /* functions */ +# define R300_ZS_NEVER 0 +# define R300_ZS_LESS 1 +# define R300_ZS_LEQUAL 2 +# define R300_ZS_EQUAL 3 +# define R300_ZS_GEQUAL 4 +# define R300_ZS_GREATER 5 +# define R300_ZS_NOTEQUAL 6 +# define R300_ZS_ALWAYS 7 +# define R300_ZS_MASK 7 + /* operations */ +# define R300_ZS_KEEP 0 +# define R300_ZS_ZERO 1 +# define R300_ZS_REPLACE 2 +# define R300_ZS_INCR 3 +# define R300_ZS_DECR 4 +# define R300_ZS_INVERT 5 +# define R300_ZS_INCR_WRAP 6 +# define R300_ZS_DECR_WRAP 7 +# define R300_Z_FUNC_SHIFT 0 + /* front and back refer to operations done for front + and back faces, i.e. separate stencil function support */ +# define R300_S_FRONT_FUNC_SHIFT 3 +# define R300_S_FRONT_SFAIL_OP_SHIFT 6 +# define R300_S_FRONT_ZPASS_OP_SHIFT 9 +# define R300_S_FRONT_ZFAIL_OP_SHIFT 12 +# define R300_S_BACK_FUNC_SHIFT 15 +# define R300_S_BACK_SFAIL_OP_SHIFT 18 +# define R300_S_BACK_ZPASS_OP_SHIFT 21 +# define R300_S_BACK_ZFAIL_OP_SHIFT 24 + +#define R300_ZB_STENCILREFMASK 0x4f08 +# define R300_STENCILREF_SHIFT 0 +# define R300_STENCILREF_MASK 0x000000ff +# define R300_STENCILMASK_SHIFT 8 +# define R300_STENCILMASK_MASK 0x0000ff00 +# define R300_STENCILWRITEMASK_SHIFT 16 +# define R300_STENCILWRITEMASK_MASK 0x00ff0000 + +/* gap */ + +#define R300_ZB_FORMAT 0x4f10 +# define R300_DEPTHFORMAT_16BIT_INT_Z (0 << 0) +# define R300_DEPTHFORMAT_16BIT_13E3 (1 << 0) +# define R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL (2 << 0) +/* reserved up to (15 << 0) */ +# define R300_INVERT_13E3_LEADING_ONES (0 << 4) +# define R300_INVERT_13E3_LEADING_ZEROS (1 << 4) + +#define R300_ZB_ZTOP 0x4F14 +# define R300_ZTOP_DISABLE (0 << 0) +# define R300_ZTOP_ENABLE (1 << 0) + +/* gap */ + +#define R300_ZB_ZCACHE_CTLSTAT 0x4f18 +# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_NO_EFFECT (0 << 0) +# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE (1 << 0) +# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_NO_EFFECT (0 << 1) +# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE (1 << 1) +# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE (0 << 31) +# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY (1 << 31) + +#define R300_ZB_BW_CNTL 0x4f1c +# define R300_HIZ_DISABLE (0 << 0) +# define R300_HIZ_ENABLE (1 << 0) +# define R300_HIZ_MIN (0 << 1) +# define R300_HIZ_MAX (1 << 1) +# define R300_FAST_FILL_DISABLE (0 << 2) +# define R300_FAST_FILL_ENABLE (1 << 2) +# define R300_RD_COMP_DISABLE (0 << 3) +# define R300_RD_COMP_ENABLE (1 << 3) +# define R300_WR_COMP_DISABLE (0 << 4) +# define R300_WR_COMP_ENABLE (1 << 4) +# define R300_ZB_CB_CLEAR_RMW (0 << 5) +# define R300_ZB_CB_CLEAR_CACHE_LINEAR (1 << 5) +# define R300_FORCE_COMPRESSED_STENCIL_VALUE_DISABLE (0 << 6) +# define R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE (1 << 6) + +# define R500_ZEQUAL_OPTIMIZE_ENABLE (0 << 7) +# define R500_ZEQUAL_OPTIMIZE_DISABLE (1 << 7) +# define R500_SEQUAL_OPTIMIZE_ENABLE (0 << 8) +# define R500_SEQUAL_OPTIMIZE_DISABLE (1 << 8) + +# define R500_BMASK_ENABLE (0 << 10) +# define R500_BMASK_DISABLE (1 << 10) +# define R500_HIZ_EQUAL_REJECT_DISABLE (0 << 11) +# define R500_HIZ_EQUAL_REJECT_ENABLE (1 << 11) +# define R500_HIZ_FP_EXP_BITS_DISABLE (0 << 12) +# define R500_HIZ_FP_EXP_BITS_1 (1 << 12) +# define R500_HIZ_FP_EXP_BITS_2 (2 << 12) +# define R500_HIZ_FP_EXP_BITS_3 (3 << 12) +# define R500_HIZ_FP_EXP_BITS_4 (4 << 12) +# define R500_HIZ_FP_EXP_BITS_5 (5 << 12) +# define R500_HIZ_FP_INVERT_LEADING_ONES (0 << 15) +# define R500_HIZ_FP_INVERT_LEADING_ZEROS (1 << 15) +# define R500_TILE_OVERWRITE_RECOMPRESSION_ENABLE (0 << 16) +# define R500_TILE_OVERWRITE_RECOMPRESSION_DISABLE (1 << 16) +# define R500_CONTIGUOUS_6XAA_SAMPLES_ENABLE (0 << 17) +# define R500_CONTIGUOUS_6XAA_SAMPLES_DISABLE (1 << 17) +# define R500_PEQ_PACKING_DISABLE (0 << 18) +# define R500_PEQ_PACKING_ENABLE (1 << 18) +# define R500_COVERED_PTR_MASKING_DISABLE (0 << 18) +# define R500_COVERED_PTR_MASKING_ENABLE (1 << 18) + + +/* gap */ + +/* Z Buffer Address Offset. + * Bits 31 to 5 are used for aligned Z buffer address offset for macro tiles. + */ +#define R300_ZB_DEPTHOFFSET 0x4f20 + +/* Z Buffer Pitch and Endian Control */ +#define R300_ZB_DEPTHPITCH 0x4f24 +# define R300_DEPTHPITCH_MASK 0x00003FFC +# define R300_DEPTHMACROTILE_DISABLE (0 << 16) +# define R300_DEPTHMACROTILE_ENABLE (1 << 16) +# define R300_DEPTHMICROTILE_LINEAR (0 << 17) +# define R300_DEPTHMICROTILE_TILED (1 << 17) +# define R300_DEPTHMICROTILE_TILED_SQUARE (2 << 17) +# define R300_DEPTHENDIAN_NO_SWAP (0 << 18) +# define R300_DEPTHENDIAN_WORD_SWAP (1 << 18) +# define R300_DEPTHENDIAN_DWORD_SWAP (2 << 18) +# define R300_DEPTHENDIAN_HALF_DWORD_SWAP (3 << 18) + +/* Z Buffer Clear Value */ +#define R300_ZB_DEPTHCLEARVALUE 0x4f28 + +/* Hierarchical Z Memory Offset */ +#define R300_ZB_HIZ_OFFSET 0x4f44 + +/* Hierarchical Z Write Index */ +#define R300_ZB_HIZ_WRINDEX 0x4f48 + +/* Hierarchical Z Data */ +#define R300_ZB_HIZ_DWORD 0x4f4c + +/* Hierarchical Z Read Index */ +#define R300_ZB_HIZ_RDINDEX 0x4f50 + +/* Hierarchical Z Pitch */ +#define R300_ZB_HIZ_PITCH 0x4f54 + +/* Z Buffer Z Pass Counter Data */ +#define R300_ZB_ZPASS_DATA 0x4f58 + +/* Z Buffer Z Pass Counter Address */ +#define R300_ZB_ZPASS_ADDR 0x4f5c + +/* Depth buffer X and Y coordinate offset */ +#define R300_ZB_DEPTHXY_OFFSET 0x4f60 +# define R300_DEPTHX_OFFSET_SHIFT 1 +# define R300_DEPTHX_OFFSET_MASK 0x000007FE +# define R300_DEPTHY_OFFSET_SHIFT 17 +# define R300_DEPTHY_OFFSET_MASK 0x07FE0000 + +/* Sets the fifo sizes */ +#define R500_ZB_FIFO_SIZE 0x4fd0 +# define R500_OP_FIFO_SIZE_FULL (0 << 0) +# define R500_OP_FIFO_SIZE_HALF (1 << 0) +# define R500_OP_FIFO_SIZE_QUATER (2 << 0) +# define R500_OP_FIFO_SIZE_EIGTHS (4 << 0) + +/* Stencil Reference Value and Mask for backfacing quads */ +/* R300_ZB_STENCILREFMASK handles front face */ +#define R500_ZB_STENCILREFMASK_BF 0x4fd4 +# define R500_STENCILREF_SHIFT 0 +# define R500_STENCILREF_MASK 0x000000ff +# define R500_STENCILMASK_SHIFT 8 +# define R500_STENCILMASK_MASK 0x0000ff00 +# define R500_STENCILWRITEMASK_SHIFT 16 +# define R500_STENCILWRITEMASK_MASK 0x00ff0000 + +/** + * \defgroup R3XX_R5XX_PROGRAMMABLE_VERTEX_SHADER_DESCRIPTION R3XX-R5XX PROGRAMMABLE VERTEX SHADER DESCRIPTION + * + * The PVS_DST_MATH_INST is used to identify whether the instruction is a Vector + * Engine instruction or a Math Engine instruction. + */ + +/*\{*/ + +enum { + /* R3XX */ + VECTOR_NO_OP = 0, + VE_DOT_PRODUCT = 1, + VE_MULTIPLY = 2, + VE_ADD = 3, + VE_MULTIPLY_ADD = 4, + VE_DISTANCE_VECTOR = 5, + VE_FRACTION = 6, + VE_MAXIMUM = 7, + VE_MINIMUM = 8, + VE_SET_GREATER_THAN_EQUAL = 9, + VE_SET_LESS_THAN = 10, + VE_MULTIPLYX2_ADD = 11, + VE_MULTIPLY_CLAMP = 12, + VE_FLT2FIX_DX = 13, + VE_FLT2FIX_DX_RND = 14, + /* R5XX */ + VE_PRED_SET_EQ_PUSH = 15, + VE_PRED_SET_GT_PUSH = 16, + VE_PRED_SET_GTE_PUSH = 17, + VE_PRED_SET_NEQ_PUSH = 18, + VE_COND_WRITE_EQ = 19, + VE_COND_WRITE_GT = 20, + VE_COND_WRITE_GTE = 21, + VE_COND_WRITE_NEQ = 22, + VE_COND_MUX_EQ = 23, + VE_COND_MUX_GT = 24, + VE_COND_MUX_GTE = 25, + VE_SET_GREATER_THAN = 26, + VE_SET_EQUAL = 27, + VE_SET_NOT_EQUAL = 28, +}; + +enum { + /* R3XX */ + MATH_NO_OP = 0, + ME_EXP_BASE2_DX = 1, + ME_LOG_BASE2_DX = 2, + ME_EXP_BASEE_FF = 3, + ME_LIGHT_COEFF_DX = 4, + ME_POWER_FUNC_FF = 5, + ME_RECIP_DX = 6, + ME_RECIP_FF = 7, + ME_RECIP_SQRT_DX = 8, + ME_RECIP_SQRT_FF = 9, + ME_MULTIPLY = 10, + ME_EXP_BASE2_FULL_DX = 11, + ME_LOG_BASE2_FULL_DX = 12, + ME_POWER_FUNC_FF_CLAMP_B = 13, + ME_POWER_FUNC_FF_CLAMP_B1 = 14, + ME_POWER_FUNC_FF_CLAMP_01 = 15, + ME_SIN = 16, + ME_COS = 17, + /* R5XX */ + ME_LOG_BASE2_IEEE = 18, + ME_RECIP_IEEE = 19, + ME_RECIP_SQRT_IEEE = 20, + ME_PRED_SET_EQ = 21, + ME_PRED_SET_GT = 22, + ME_PRED_SET_GTE = 23, + ME_PRED_SET_NEQ = 24, + ME_PRED_SET_CLR = 25, + ME_PRED_SET_INV = 26, + ME_PRED_SET_POP = 27, + ME_PRED_SET_RESTORE = 28, +}; + +enum { + /* R3XX */ + PVS_MACRO_OP_2CLK_MADD = 0, + PVS_MACRO_OP_2CLK_M2X_ADD = 1, +}; + +enum { + PVS_SRC_REG_TEMPORARY = 0, /* Intermediate Storage */ + PVS_SRC_REG_INPUT = 1, /* Input Vertex Storage */ + PVS_SRC_REG_CONSTANT = 2, /* Constant State Storage */ + PVS_SRC_REG_ALT_TEMPORARY = 3, /* Alternate Intermediate Storage */ +}; + +enum { + PVS_DST_REG_TEMPORARY = 0, /* Intermediate Storage */ + PVS_DST_REG_A0 = 1, /* Address Register Storage */ + PVS_DST_REG_OUT = 2, /* Output Memory. Used for all outputs */ + PVS_DST_REG_OUT_REPL_X = 3, /* Output Memory & Replicate X to all channels */ + PVS_DST_REG_ALT_TEMPORARY = 4, /* Alternate Intermediate Storage */ + PVS_DST_REG_INPUT = 5, /* Output Memory & Replicate X to all channels */ +}; + +enum { + PVS_SRC_SELECT_X = 0, /* Select X Component */ + PVS_SRC_SELECT_Y = 1, /* Select Y Component */ + PVS_SRC_SELECT_Z = 2, /* Select Z Component */ + PVS_SRC_SELECT_W = 3, /* Select W Component */ + PVS_SRC_SELECT_FORCE_0 = 4, /* Force Component to 0.0 */ + PVS_SRC_SELECT_FORCE_1 = 5, /* Force Component to 1.0 */ +}; + +/* PVS Opcode & Destination Operand Description */ + +enum { + PVS_DST_OPCODE_MASK = 0x3f, + PVS_DST_OPCODE_SHIFT = 0, + PVS_DST_MATH_INST_MASK = 0x1, + PVS_DST_MATH_INST_SHIFT = 6, + PVS_DST_MACRO_INST_MASK = 0x1, + PVS_DST_MACRO_INST_SHIFT = 7, + PVS_DST_REG_TYPE_MASK = 0xf, + PVS_DST_REG_TYPE_SHIFT = 8, + PVS_DST_ADDR_MODE_1_MASK = 0x1, + PVS_DST_ADDR_MODE_1_SHIFT = 12, + PVS_DST_OFFSET_MASK = 0x7f, + PVS_DST_OFFSET_SHIFT = 13, + PVS_DST_WE_X_MASK = 0x1, + PVS_DST_WE_X_SHIFT = 20, + PVS_DST_WE_Y_MASK = 0x1, + PVS_DST_WE_Y_SHIFT = 21, + PVS_DST_WE_Z_MASK = 0x1, + PVS_DST_WE_Z_SHIFT = 22, + PVS_DST_WE_W_MASK = 0x1, + PVS_DST_WE_W_SHIFT = 23, + PVS_DST_VE_SAT_MASK = 0x1, + PVS_DST_VE_SAT_SHIFT = 24, + PVS_DST_ME_SAT_MASK = 0x1, + PVS_DST_ME_SAT_SHIFT = 25, + PVS_DST_PRED_ENABLE_MASK = 0x1, + PVS_DST_PRED_ENABLE_SHIFT = 26, + PVS_DST_PRED_SENSE_MASK = 0x1, + PVS_DST_PRED_SENSE_SHIFT = 27, + PVS_DST_DUAL_MATH_OP_MASK = 0x3, + PVS_DST_DUAL_MATH_OP_SHIFT = 27, + PVS_DST_ADDR_SEL_MASK = 0x3, + PVS_DST_ADDR_SEL_SHIFT = 29, + PVS_DST_ADDR_MODE_0_MASK = 0x1, + PVS_DST_ADDR_MODE_0_SHIFT = 31, +}; + +/* PVS Source Operand Description */ + +enum { + PVS_SRC_REG_TYPE_MASK = 0x3, + PVS_SRC_REG_TYPE_SHIFT = 0, + SPARE_0_MASK = 0x1, + SPARE_0_SHIFT = 2, + PVS_SRC_ABS_XYZW_MASK = 0x1, + PVS_SRC_ABS_XYZW_SHIFT = 3, + PVS_SRC_ADDR_MODE_0_MASK = 0x1, + PVS_SRC_ADDR_MODE_0_SHIFT = 4, + PVS_SRC_OFFSET_MASK = 0xff, + PVS_SRC_OFFSET_SHIFT = 5, + PVS_SRC_SWIZZLE_X_MASK = 0x7, + PVS_SRC_SWIZZLE_X_SHIFT = 13, + PVS_SRC_SWIZZLE_Y_MASK = 0x7, + PVS_SRC_SWIZZLE_Y_SHIFT = 16, + PVS_SRC_SWIZZLE_Z_MASK = 0x7, + PVS_SRC_SWIZZLE_Z_SHIFT = 19, + PVS_SRC_SWIZZLE_W_MASK = 0x7, + PVS_SRC_SWIZZLE_W_SHIFT = 22, + PVS_SRC_MODIFIER_X_MASK = 0x1, + PVS_SRC_MODIFIER_X_SHIFT = 25, + PVS_SRC_MODIFIER_Y_MASK = 0x1, + PVS_SRC_MODIFIER_Y_SHIFT = 26, + PVS_SRC_MODIFIER_Z_MASK = 0x1, + PVS_SRC_MODIFIER_Z_SHIFT = 27, + PVS_SRC_MODIFIER_W_MASK = 0x1, + PVS_SRC_MODIFIER_W_SHIFT = 28, + PVS_SRC_ADDR_SEL_MASK = 0x3, + PVS_SRC_ADDR_SEL_SHIFT = 29, + PVS_SRC_ADDR_MODE_1_MASK = 0x0, + PVS_SRC_ADDR_MODE_1_SHIFT = 32, +}; + +/*\}*/ + +/* BEGIN: Packet 3 commands */ + +/* A primitive emission dword. */ +#define R300_PRIM_TYPE_NONE (0 << 0) +#define R300_PRIM_TYPE_POINT (1 << 0) +#define R300_PRIM_TYPE_LINE (2 << 0) +#define R300_PRIM_TYPE_LINE_STRIP (3 << 0) +#define R300_PRIM_TYPE_TRI_LIST (4 << 0) +#define R300_PRIM_TYPE_TRI_FAN (5 << 0) +#define R300_PRIM_TYPE_TRI_STRIP (6 << 0) +#define R300_PRIM_TYPE_TRI_TYPE2 (7 << 0) +#define R300_PRIM_TYPE_RECT_LIST (8 << 0) +#define R300_PRIM_TYPE_3VRT_POINT_LIST (9 << 0) +#define R300_PRIM_TYPE_3VRT_LINE_LIST (10 << 0) + /* GUESS (based on r200) */ +#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0) +#define R300_PRIM_TYPE_LINE_LOOP (12 << 0) +#define R300_PRIM_TYPE_QUADS (13 << 0) +#define R300_PRIM_TYPE_QUAD_STRIP (14 << 0) +#define R300_PRIM_TYPE_POLYGON (15 << 0) +#define R300_PRIM_TYPE_MASK 0xF +#define R300_PRIM_WALK_IND (1 << 4) +#define R300_PRIM_WALK_LIST (2 << 4) +#define R300_PRIM_WALK_RING (3 << 4) +#define R300_PRIM_WALK_MASK (3 << 4) + /* GUESS (based on r200) */ +#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6) +#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6) +#define R300_PRIM_NUM_VERTICES_SHIFT 16 +#define R300_PRIM_NUM_VERTICES_MASK 0xffff + + + +/* + * The R500 unified shader (US) registers come in banks of 512 each, one + * for each instruction slot in the shader. You can't touch them directly. + * R500_US_VECTOR_INDEX() sets the base instruction to modify; successive + * writes to R500_GA_US_VECTOR_DATA autoincrement the index after the + * instruction is fully specified. + */ +#define R500_US_ALU_ALPHA_INST_0 0xa800 +# define R500_ALPHA_OP_MAD 0 +# define R500_ALPHA_OP_DP 1 +# define R500_ALPHA_OP_MIN 2 +# define R500_ALPHA_OP_MAX 3 +/* #define R500_ALPHA_OP_RESERVED 4 */ +# define R500_ALPHA_OP_CND 5 +# define R500_ALPHA_OP_CMP 6 +# define R500_ALPHA_OP_FRC 7 +# define R500_ALPHA_OP_EX2 8 +# define R500_ALPHA_OP_LN2 9 +# define R500_ALPHA_OP_RCP 10 +# define R500_ALPHA_OP_RSQ 11 +# define R500_ALPHA_OP_SIN 12 +# define R500_ALPHA_OP_COS 13 +# define R500_ALPHA_OP_MDH 14 +# define R500_ALPHA_OP_MDV 15 +# define R500_ALPHA_ADDRD(x) (x << 4) +# define R500_ALPHA_ADDRD_REL (1 << 11) +# define R500_ALPHA_SEL_A_SHIFT 12 +# define R500_ALPHA_SEL_A_SRC0 (0 << 12) +# define R500_ALPHA_SEL_A_SRC1 (1 << 12) +# define R500_ALPHA_SEL_A_SRC2 (2 << 12) +# define R500_ALPHA_SEL_A_SRCP (3 << 12) +# define R500_ALPHA_SWIZ_A_R (0 << 14) +# define R500_ALPHA_SWIZ_A_G (1 << 14) +# define R500_ALPHA_SWIZ_A_B (2 << 14) +# define R500_ALPHA_SWIZ_A_A (3 << 14) +# define R500_ALPHA_SWIZ_A_0 (4 << 14) +# define R500_ALPHA_SWIZ_A_HALF (5 << 14) +# define R500_ALPHA_SWIZ_A_1 (6 << 14) +/* #define R500_ALPHA_SWIZ_A_UNUSED (7 << 14) */ +# define R500_ALPHA_MOD_A_NOP (0 << 17) +# define R500_ALPHA_MOD_A_NEG (1 << 17) +# define R500_ALPHA_MOD_A_ABS (2 << 17) +# define R500_ALPHA_MOD_A_NAB (3 << 17) +# define R500_ALPHA_SEL_B_SHIFT 19 +# define R500_ALPHA_SEL_B_SRC0 (0 << 19) +# define R500_ALPHA_SEL_B_SRC1 (1 << 19) +# define R500_ALPHA_SEL_B_SRC2 (2 << 19) +# define R500_ALPHA_SEL_B_SRCP (3 << 19) +# define R500_ALPHA_SWIZ_B_R (0 << 21) +# define R500_ALPHA_SWIZ_B_G (1 << 21) +# define R500_ALPHA_SWIZ_B_B (2 << 21) +# define R500_ALPHA_SWIZ_B_A (3 << 21) +# define R500_ALPHA_SWIZ_B_0 (4 << 21) +# define R500_ALPHA_SWIZ_B_HALF (5 << 21) +# define R500_ALPHA_SWIZ_B_1 (6 << 21) +/* #define R500_ALPHA_SWIZ_B_UNUSED (7 << 21) */ +# define R500_ALPHA_MOD_B_NOP (0 << 24) +# define R500_ALPHA_MOD_B_NEG (1 << 24) +# define R500_ALPHA_MOD_B_ABS (2 << 24) +# define R500_ALPHA_MOD_B_NAB (3 << 24) +# define R500_ALPHA_OMOD_IDENTITY (0 << 26) +# define R500_ALPHA_OMOD_MUL_2 (1 << 26) +# define R500_ALPHA_OMOD_MUL_4 (2 << 26) +# define R500_ALPHA_OMOD_MUL_8 (3 << 26) +# define R500_ALPHA_OMOD_DIV_2 (4 << 26) +# define R500_ALPHA_OMOD_DIV_4 (5 << 26) +# define R500_ALPHA_OMOD_DIV_8 (6 << 26) +# define R500_ALPHA_OMOD_DISABLE (7 << 26) +# define R500_ALPHA_TARGET(x) (x << 29) +# define R500_ALPHA_W_OMASK (1 << 31) +#define R500_US_ALU_ALPHA_ADDR_0 0x9800 +# define R500_ALPHA_ADDR0(x) (x << 0) +# define R500_ALPHA_ADDR0_CONST (1 << 8) +# define R500_ALPHA_ADDR0_REL (1 << 9) +# define R500_ALPHA_ADDR1(x) (x << 10) +# define R500_ALPHA_ADDR1_CONST (1 << 18) +# define R500_ALPHA_ADDR1_REL (1 << 19) +# define R500_ALPHA_ADDR2(x) (x << 20) +# define R500_ALPHA_ADDR2_CONST (1 << 28) +# define R500_ALPHA_ADDR2_REL (1 << 29) +# define R500_ALPHA_SRCP_OP_1_MINUS_2A0 (0 << 30) +# define R500_ALPHA_SRCP_OP_A1_MINUS_A0 (1 << 30) +# define R500_ALPHA_SRCP_OP_A1_PLUS_A0 (2 << 30) +# define R500_ALPHA_SRCP_OP_1_MINUS_A0 (3 << 30) +#define R500_US_ALU_RGBA_INST_0 0xb000 +# define R500_ALU_RGBA_OP_MAD (0 << 0) +# define R500_ALU_RGBA_OP_DP3 (1 << 0) +# define R500_ALU_RGBA_OP_DP4 (2 << 0) +# define R500_ALU_RGBA_OP_D2A (3 << 0) +# define R500_ALU_RGBA_OP_MIN (4 << 0) +# define R500_ALU_RGBA_OP_MAX (5 << 0) +/* #define R500_ALU_RGBA_OP_RESERVED (6 << 0) */ +# define R500_ALU_RGBA_OP_CND (7 << 0) +# define R500_ALU_RGBA_OP_CMP (8 << 0) +# define R500_ALU_RGBA_OP_FRC (9 << 0) +# define R500_ALU_RGBA_OP_SOP (10 << 0) +# define R500_ALU_RGBA_OP_MDH (11 << 0) +# define R500_ALU_RGBA_OP_MDV (12 << 0) +# define R500_ALU_RGBA_ADDRD(x) (x << 4) +# define R500_ALU_RGBA_ADDRD_REL (1 << 11) +# define R500_ALU_RGBA_SEL_C_SHIFT 12 +# define R500_ALU_RGBA_SEL_C_SRC0 (0 << 12) +# define R500_ALU_RGBA_SEL_C_SRC1 (1 << 12) +# define R500_ALU_RGBA_SEL_C_SRC2 (2 << 12) +# define R500_ALU_RGBA_SEL_C_SRCP (3 << 12) +# define R500_ALU_RGBA_R_SWIZ_R (0 << 14) +# define R500_ALU_RGBA_R_SWIZ_G (1 << 14) +# define R500_ALU_RGBA_R_SWIZ_B (2 << 14) +# define R500_ALU_RGBA_R_SWIZ_A (3 << 14) +# define R500_ALU_RGBA_R_SWIZ_0 (4 << 14) +# define R500_ALU_RGBA_R_SWIZ_HALF (5 << 14) +# define R500_ALU_RGBA_R_SWIZ_1 (6 << 14) +/* #define R500_ALU_RGBA_R_SWIZ_UNUSED (7 << 14) */ +# define R500_ALU_RGBA_G_SWIZ_R (0 << 17) +# define R500_ALU_RGBA_G_SWIZ_G (1 << 17) +# define R500_ALU_RGBA_G_SWIZ_B (2 << 17) +# define R500_ALU_RGBA_G_SWIZ_A (3 << 17) +# define R500_ALU_RGBA_G_SWIZ_0 (4 << 17) +# define R500_ALU_RGBA_G_SWIZ_HALF (5 << 17) +# define R500_ALU_RGBA_G_SWIZ_1 (6 << 17) +/* #define R500_ALU_RGBA_G_SWIZ_UNUSED (7 << 17) */ +# define R500_ALU_RGBA_B_SWIZ_R (0 << 20) +# define R500_ALU_RGBA_B_SWIZ_G (1 << 20) +# define R500_ALU_RGBA_B_SWIZ_B (2 << 20) +# define R500_ALU_RGBA_B_SWIZ_A (3 << 20) +# define R500_ALU_RGBA_B_SWIZ_0 (4 << 20) +# define R500_ALU_RGBA_B_SWIZ_HALF (5 << 20) +# define R500_ALU_RGBA_B_SWIZ_1 (6 << 20) +/* #define R500_ALU_RGBA_B_SWIZ_UNUSED (7 << 20) */ +# define R500_ALU_RGBA_MOD_C_NOP (0 << 23) +# define R500_ALU_RGBA_MOD_C_NEG (1 << 23) +# define R500_ALU_RGBA_MOD_C_ABS (2 << 23) +# define R500_ALU_RGBA_MOD_C_NAB (3 << 23) +# define R500_ALU_RGBA_ALPHA_SEL_C_SHIFT 25 +# define R500_ALU_RGBA_ALPHA_SEL_C_SRC0 (0 << 25) +# define R500_ALU_RGBA_ALPHA_SEL_C_SRC1 (1 << 25) +# define R500_ALU_RGBA_ALPHA_SEL_C_SRC2 (2 << 25) +# define R500_ALU_RGBA_ALPHA_SEL_C_SRCP (3 << 25) +# define R500_ALU_RGBA_A_SWIZ_R (0 << 27) +# define R500_ALU_RGBA_A_SWIZ_G (1 << 27) +# define R500_ALU_RGBA_A_SWIZ_B (2 << 27) +# define R500_ALU_RGBA_A_SWIZ_A (3 << 27) +# define R500_ALU_RGBA_A_SWIZ_0 (4 << 27) +# define R500_ALU_RGBA_A_SWIZ_HALF (5 << 27) +# define R500_ALU_RGBA_A_SWIZ_1 (6 << 27) +/* #define R500_ALU_RGBA_A_SWIZ_UNUSED (7 << 27) */ +# define R500_ALU_RGBA_ALPHA_MOD_C_NOP (0 << 30) +# define R500_ALU_RGBA_ALPHA_MOD_C_NEG (1 << 30) +# define R500_ALU_RGBA_ALPHA_MOD_C_ABS (2 << 30) +# define R500_ALU_RGBA_ALPHA_MOD_C_NAB (3 << 30) +#define R500_US_ALU_RGB_INST_0 0xa000 +# define R500_ALU_RGB_SEL_A_SHIFT 0 +# define R500_ALU_RGB_SEL_A_SRC0 (0 << 0) +# define R500_ALU_RGB_SEL_A_SRC1 (1 << 0) +# define R500_ALU_RGB_SEL_A_SRC2 (2 << 0) +# define R500_ALU_RGB_SEL_A_SRCP (3 << 0) +# define R500_ALU_RGB_R_SWIZ_A_R (0 << 2) +# define R500_ALU_RGB_R_SWIZ_A_G (1 << 2) +# define R500_ALU_RGB_R_SWIZ_A_B (2 << 2) +# define R500_ALU_RGB_R_SWIZ_A_A (3 << 2) +# define R500_ALU_RGB_R_SWIZ_A_0 (4 << 2) +# define R500_ALU_RGB_R_SWIZ_A_HALF (5 << 2) +# define R500_ALU_RGB_R_SWIZ_A_1 (6 << 2) +/* #define R500_ALU_RGB_R_SWIZ_A_UNUSED (7 << 2) */ +# define R500_ALU_RGB_G_SWIZ_A_R (0 << 5) +# define R500_ALU_RGB_G_SWIZ_A_G (1 << 5) +# define R500_ALU_RGB_G_SWIZ_A_B (2 << 5) +# define R500_ALU_RGB_G_SWIZ_A_A (3 << 5) +# define R500_ALU_RGB_G_SWIZ_A_0 (4 << 5) +# define R500_ALU_RGB_G_SWIZ_A_HALF (5 << 5) +# define R500_ALU_RGB_G_SWIZ_A_1 (6 << 5) +/* #define R500_ALU_RGB_G_SWIZ_A_UNUSED (7 << 5) */ +# define R500_ALU_RGB_B_SWIZ_A_R (0 << 8) +# define R500_ALU_RGB_B_SWIZ_A_G (1 << 8) +# define R500_ALU_RGB_B_SWIZ_A_B (2 << 8) +# define R500_ALU_RGB_B_SWIZ_A_A (3 << 8) +# define R500_ALU_RGB_B_SWIZ_A_0 (4 << 8) +# define R500_ALU_RGB_B_SWIZ_A_HALF (5 << 8) +# define R500_ALU_RGB_B_SWIZ_A_1 (6 << 8) +/* #define R500_ALU_RGB_B_SWIZ_A_UNUSED (7 << 8) */ +# define R500_ALU_RGB_MOD_A_NOP (0 << 11) +# define R500_ALU_RGB_MOD_A_NEG (1 << 11) +# define R500_ALU_RGB_MOD_A_ABS (2 << 11) +# define R500_ALU_RGB_MOD_A_NAB (3 << 11) +# define R500_ALU_RGB_SEL_B_SHIFT 13 +# define R500_ALU_RGB_SEL_B_SRC0 (0 << 13) +# define R500_ALU_RGB_SEL_B_SRC1 (1 << 13) +# define R500_ALU_RGB_SEL_B_SRC2 (2 << 13) +# define R500_ALU_RGB_SEL_B_SRCP (3 << 13) +# define R500_ALU_RGB_R_SWIZ_B_R (0 << 15) +# define R500_ALU_RGB_R_SWIZ_B_G (1 << 15) +# define R500_ALU_RGB_R_SWIZ_B_B (2 << 15) +# define R500_ALU_RGB_R_SWIZ_B_A (3 << 15) +# define R500_ALU_RGB_R_SWIZ_B_0 (4 << 15) +# define R500_ALU_RGB_R_SWIZ_B_HALF (5 << 15) +# define R500_ALU_RGB_R_SWIZ_B_1 (6 << 15) +/* #define R500_ALU_RGB_R_SWIZ_B_UNUSED (7 << 15) */ +# define R500_ALU_RGB_G_SWIZ_B_R (0 << 18) +# define R500_ALU_RGB_G_SWIZ_B_G (1 << 18) +# define R500_ALU_RGB_G_SWIZ_B_B (2 << 18) +# define R500_ALU_RGB_G_SWIZ_B_A (3 << 18) +# define R500_ALU_RGB_G_SWIZ_B_0 (4 << 18) +# define R500_ALU_RGB_G_SWIZ_B_HALF (5 << 18) +# define R500_ALU_RGB_G_SWIZ_B_1 (6 << 18) +/* #define R500_ALU_RGB_G_SWIZ_B_UNUSED (7 << 18) */ +# define R500_ALU_RGB_B_SWIZ_B_R (0 << 21) +# define R500_ALU_RGB_B_SWIZ_B_G (1 << 21) +# define R500_ALU_RGB_B_SWIZ_B_B (2 << 21) +# define R500_ALU_RGB_B_SWIZ_B_A (3 << 21) +# define R500_ALU_RGB_B_SWIZ_B_0 (4 << 21) +# define R500_ALU_RGB_B_SWIZ_B_HALF (5 << 21) +# define R500_ALU_RGB_B_SWIZ_B_1 (6 << 21) +/* #define R500_ALU_RGB_B_SWIZ_B_UNUSED (7 << 21) */ +# define R500_ALU_RGB_MOD_B_NOP (0 << 24) +# define R500_ALU_RGB_MOD_B_NEG (1 << 24) +# define R500_ALU_RGB_MOD_B_ABS (2 << 24) +# define R500_ALU_RGB_MOD_B_NAB (3 << 24) +# define R500_ALU_RGB_OMOD_IDENTITY (0 << 26) +# define R500_ALU_RGB_OMOD_MUL_2 (1 << 26) +# define R500_ALU_RGB_OMOD_MUL_4 (2 << 26) +# define R500_ALU_RGB_OMOD_MUL_8 (3 << 26) +# define R500_ALU_RGB_OMOD_DIV_2 (4 << 26) +# define R500_ALU_RGB_OMOD_DIV_4 (5 << 26) +# define R500_ALU_RGB_OMOD_DIV_8 (6 << 26) +# define R500_ALU_RGB_OMOD_DISABLE (7 << 26) +# define R500_ALU_RGB_TARGET(x) (x << 29) +# define R500_ALU_RGB_WMASK (1 << 31) +#define R500_US_ALU_RGB_ADDR_0 0x9000 +# define R500_RGB_ADDR0(x) (x << 0) +# define R500_RGB_ADDR0_CONST (1 << 8) +# define R500_RGB_ADDR0_REL (1 << 9) +# define R500_RGB_ADDR1(x) (x << 10) +# define R500_RGB_ADDR1_CONST (1 << 18) +# define R500_RGB_ADDR1_REL (1 << 19) +# define R500_RGB_ADDR2(x) (x << 20) +# define R500_RGB_ADDR2_CONST (1 << 28) +# define R500_RGB_ADDR2_REL (1 << 29) +# define R500_RGB_SRCP_OP_1_MINUS_2RGB0 (0 << 30) +# define R500_RGB_SRCP_OP_RGB1_MINUS_RGB0 (1 << 30) +# define R500_RGB_SRCP_OP_RGB1_PLUS_RGB0 (2 << 30) +# define R500_RGB_SRCP_OP_1_MINUS_RGB0 (3 << 30) +#define R500_US_CMN_INST_0 0xb800 +# define R500_INST_TYPE_MASK (3 << 0) +# define R500_INST_TYPE_ALU (0 << 0) +# define R500_INST_TYPE_OUT (1 << 0) +# define R500_INST_TYPE_FC (2 << 0) +# define R500_INST_TYPE_TEX (3 << 0) +# define R500_INST_TEX_SEM_WAIT (1 << 2) +# define R500_INST_RGB_PRED_SEL_NONE (0 << 3) +# define R500_INST_RGB_PRED_SEL_RGBA (1 << 3) +# define R500_INST_RGB_PRED_SEL_RRRR (2 << 3) +# define R500_INST_RGB_PRED_SEL_GGGG (3 << 3) +# define R500_INST_RGB_PRED_SEL_BBBB (4 << 3) +# define R500_INST_RGB_PRED_SEL_AAAA (5 << 3) +# define R500_INST_RGB_PRED_INV (1 << 6) +# define R500_INST_WRITE_INACTIVE (1 << 7) +# define R500_INST_LAST (1 << 8) +# define R500_INST_NOP (1 << 9) +# define R500_INST_ALU_WAIT (1 << 10) +# define R500_INST_RGB_WMASK_R (1 << 11) +# define R500_INST_RGB_WMASK_G (1 << 12) +# define R500_INST_RGB_WMASK_B (1 << 13) +# define R500_INST_ALPHA_WMASK (1 << 14) +# define R500_INST_RGB_OMASK_R (1 << 15) +# define R500_INST_RGB_OMASK_G (1 << 16) +# define R500_INST_RGB_OMASK_B (1 << 17) +# define R500_INST_ALPHA_OMASK (1 << 18) +# define R500_INST_RGB_CLAMP (1 << 19) +# define R500_INST_ALPHA_CLAMP (1 << 20) +# define R500_INST_ALU_RESULT_SEL (1 << 21) +# define R500_INST_ALPHA_PRED_INV (1 << 22) +# define R500_INST_ALU_RESULT_OP_EQ (0 << 23) +# define R500_INST_ALU_RESULT_OP_LT (1 << 23) +# define R500_INST_ALU_RESULT_OP_GE (2 << 23) +# define R500_INST_ALU_RESULT_OP_NE (3 << 23) +# define R500_INST_ALPHA_PRED_SEL_NONE (0 << 25) +# define R500_INST_ALPHA_PRED_SEL_RGBA (1 << 25) +# define R500_INST_ALPHA_PRED_SEL_RRRR (2 << 25) +# define R500_INST_ALPHA_PRED_SEL_GGGG (3 << 25) +# define R500_INST_ALPHA_PRED_SEL_BBBB (4 << 25) +# define R500_INST_ALPHA_PRED_SEL_AAAA (5 << 25) +/* XXX next four are kind of guessed */ +# define R500_INST_STAT_WE_R (1 << 28) +# define R500_INST_STAT_WE_G (1 << 29) +# define R500_INST_STAT_WE_B (1 << 30) +# define R500_INST_STAT_WE_A (1 << 31) + +/* note that these are 8 bit lengths, despite the offsets, at least for R500 */ +#define R500_US_CODE_ADDR 0x4630 +# define R500_US_CODE_START_ADDR(x) (x << 0) +# define R500_US_CODE_END_ADDR(x) (x << 16) +#define R500_US_CODE_OFFSET 0x4638 +# define R500_US_CODE_OFFSET_ADDR(x) (x << 0) +#define R500_US_CODE_RANGE 0x4634 +# define R500_US_CODE_RANGE_ADDR(x) (x << 0) +# define R500_US_CODE_RANGE_SIZE(x) (x << 16) +#define R500_US_CONFIG 0x4600 +# define R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO (1 << 1) +#define R500_US_FC_ADDR_0 0xa000 +# define R500_FC_BOOL_ADDR(x) (x << 0) +# define R500_FC_INT_ADDR(x) (x << 8) +# define R500_FC_JUMP_ADDR(x) (x << 16) +# define R500_FC_JUMP_GLOBAL (1 << 31) +#define R500_US_FC_BOOL_CONST 0x4620 +# define R500_FC_KBOOL(x) (x) +#define R500_US_FC_CTRL 0x4624 +# define R500_FC_TEST_EN (1 << 30) +# define R500_FC_FULL_FC_EN (1 << 31) +#define R500_US_FC_INST_0 0x9800 +# define R500_FC_OP_JUMP (0 << 0) +# define R500_FC_OP_LOOP (1 << 0) +# define R500_FC_OP_ENDLOOP (2 << 0) +# define R500_FC_OP_REP (3 << 0) +# define R500_FC_OP_ENDREP (4 << 0) +# define R500_FC_OP_BREAKLOOP (5 << 0) +# define R500_FC_OP_BREAKREP (6 << 0) +# define R500_FC_OP_CONTINUE (7 << 0) +# define R500_FC_B_ELSE (1 << 4) +# define R500_FC_JUMP_ANY (1 << 5) +# define R500_FC_A_OP_NONE (0 << 6) +# define R500_FC_A_OP_POP (1 << 6) +# define R500_FC_A_OP_PUSH (2 << 6) +# define R500_FC_JUMP_FUNC(x) (x << 8) +# define R500_FC_B_POP_CNT(x) (x << 16) +# define R500_FC_B_OP0_NONE (0 << 24) +# define R500_FC_B_OP0_DECR (1 << 24) +# define R500_FC_B_OP0_INCR (2 << 24) +# define R500_FC_B_OP1_DECR (0 << 26) +# define R500_FC_B_OP1_NONE (1 << 26) +# define R500_FC_B_OP1_INCR (2 << 26) +# define R500_FC_IGNORE_UNCOVERED (1 << 28) +#define R500_US_FC_INT_CONST_0 0x4c00 +# define R500_FC_INT_CONST_KR(x) (x << 0) +# define R500_FC_INT_CONST_KG(x) (x << 8) +# define R500_FC_INT_CONST_KB(x) (x << 16) +/* _0 through _15 */ +#define R500_US_FORMAT0_0 0x4640 +# define R500_FORMAT_TXWIDTH(x) (x << 0) +# define R500_FORMAT_TXHEIGHT(x) (x << 11) +# define R500_FORMAT_TXDEPTH(x) (x << 22) +/* _0 through _3 */ +#define R500_US_OUT_FMT_0 0x46A4 +# define R500_OUT_FMT_C4_8 (0 << 0) +# define R500_OUT_FMT_C4_10 (1 << 0) +# define R500_OUT_FMT_C4_10_GAMMA (2 << 0) +# define R500_OUT_FMT_C_16 (3 << 0) +# define R500_OUT_FMT_C2_16 (4 << 0) +# define R500_OUT_FMT_C4_16 (5 << 0) +# define R500_OUT_FMT_C_16_MPEG (6 << 0) +# define R500_OUT_FMT_C2_16_MPEG (7 << 0) +# define R500_OUT_FMT_C2_4 (8 << 0) +# define R500_OUT_FMT_C_3_3_2 (9 << 0) +# define R500_OUT_FMT_C_6_5_6 (10 << 0) +# define R500_OUT_FMT_C_11_11_10 (11 << 0) +# define R500_OUT_FMT_C_10_11_11 (12 << 0) +# define R500_OUT_FMT_C_2_10_10_10 (13 << 0) +/* #define R500_OUT_FMT_RESERVED (14 << 0) */ +# define R500_OUT_FMT_UNUSED (15 << 0) +# define R500_OUT_FMT_C_16_FP (16 << 0) +# define R500_OUT_FMT_C2_16_FP (17 << 0) +# define R500_OUT_FMT_C4_16_FP (18 << 0) +# define R500_OUT_FMT_C_32_FP (19 << 0) +# define R500_OUT_FMT_C2_32_FP (20 << 0) +# define R500_OUT_FMT_C4_32_FP (21 << 0) +# define R500_C0_SEL_A (0 << 8) +# define R500_C0_SEL_R (1 << 8) +# define R500_C0_SEL_G (2 << 8) +# define R500_C0_SEL_B (3 << 8) +# define R500_C1_SEL_A (0 << 10) +# define R500_C1_SEL_R (1 << 10) +# define R500_C1_SEL_G (2 << 10) +# define R500_C1_SEL_B (3 << 10) +# define R500_C2_SEL_A (0 << 12) +# define R500_C2_SEL_R (1 << 12) +# define R500_C2_SEL_G (2 << 12) +# define R500_C2_SEL_B (3 << 12) +# define R500_C3_SEL_A (0 << 14) +# define R500_C3_SEL_R (1 << 14) +# define R500_C3_SEL_G (2 << 14) +# define R500_C3_SEL_B (3 << 14) +# define R500_OUT_SIGN(x) (x << 16) +# define R500_ROUND_ADJ (1 << 20) +#define R500_US_PIXSIZE 0x4604 +# define R500_PIX_SIZE(x) (x) +#define R500_US_TEX_ADDR_0 0x9800 +# define R500_TEX_SRC_ADDR(x) (x << 0) +# define R500_TEX_SRC_ADDR_REL (1 << 7) +# define R500_TEX_SRC_S_SWIZ_R (0 << 8) +# define R500_TEX_SRC_S_SWIZ_G (1 << 8) +# define R500_TEX_SRC_S_SWIZ_B (2 << 8) +# define R500_TEX_SRC_S_SWIZ_A (3 << 8) +# define R500_TEX_SRC_T_SWIZ_R (0 << 10) +# define R500_TEX_SRC_T_SWIZ_G (1 << 10) +# define R500_TEX_SRC_T_SWIZ_B (2 << 10) +# define R500_TEX_SRC_T_SWIZ_A (3 << 10) +# define R500_TEX_SRC_R_SWIZ_R (0 << 12) +# define R500_TEX_SRC_R_SWIZ_G (1 << 12) +# define R500_TEX_SRC_R_SWIZ_B (2 << 12) +# define R500_TEX_SRC_R_SWIZ_A (3 << 12) +# define R500_TEX_SRC_Q_SWIZ_R (0 << 14) +# define R500_TEX_SRC_Q_SWIZ_G (1 << 14) +# define R500_TEX_SRC_Q_SWIZ_B (2 << 14) +# define R500_TEX_SRC_Q_SWIZ_A (3 << 14) +# define R500_TEX_DST_ADDR(x) (x << 16) +# define R500_TEX_DST_ADDR_REL (1 << 23) +# define R500_TEX_DST_R_SWIZ_R (0 << 24) +# define R500_TEX_DST_R_SWIZ_G (1 << 24) +# define R500_TEX_DST_R_SWIZ_B (2 << 24) +# define R500_TEX_DST_R_SWIZ_A (3 << 24) +# define R500_TEX_DST_G_SWIZ_R (0 << 26) +# define R500_TEX_DST_G_SWIZ_G (1 << 26) +# define R500_TEX_DST_G_SWIZ_B (2 << 26) +# define R500_TEX_DST_G_SWIZ_A (3 << 26) +# define R500_TEX_DST_B_SWIZ_R (0 << 28) +# define R500_TEX_DST_B_SWIZ_G (1 << 28) +# define R500_TEX_DST_B_SWIZ_B (2 << 28) +# define R500_TEX_DST_B_SWIZ_A (3 << 28) +# define R500_TEX_DST_A_SWIZ_R (0 << 30) +# define R500_TEX_DST_A_SWIZ_G (1 << 30) +# define R500_TEX_DST_A_SWIZ_B (2 << 30) +# define R500_TEX_DST_A_SWIZ_A (3 << 30) +#define R500_US_TEX_ADDR_DXDY_0 0xa000 +# define R500_DX_ADDR(x) (x << 0) +# define R500_DX_ADDR_REL (1 << 7) +# define R500_DX_S_SWIZ_R (0 << 8) +# define R500_DX_S_SWIZ_G (1 << 8) +# define R500_DX_S_SWIZ_B (2 << 8) +# define R500_DX_S_SWIZ_A (3 << 8) +# define R500_DX_T_SWIZ_R (0 << 10) +# define R500_DX_T_SWIZ_G (1 << 10) +# define R500_DX_T_SWIZ_B (2 << 10) +# define R500_DX_T_SWIZ_A (3 << 10) +# define R500_DX_R_SWIZ_R (0 << 12) +# define R500_DX_R_SWIZ_G (1 << 12) +# define R500_DX_R_SWIZ_B (2 << 12) +# define R500_DX_R_SWIZ_A (3 << 12) +# define R500_DX_Q_SWIZ_R (0 << 14) +# define R500_DX_Q_SWIZ_G (1 << 14) +# define R500_DX_Q_SWIZ_B (2 << 14) +# define R500_DX_Q_SWIZ_A (3 << 14) +# define R500_DY_ADDR(x) (x << 16) +# define R500_DY_ADDR_REL (1 << 17) +# define R500_DY_S_SWIZ_R (0 << 24) +# define R500_DY_S_SWIZ_G (1 << 24) +# define R500_DY_S_SWIZ_B (2 << 24) +# define R500_DY_S_SWIZ_A (3 << 24) +# define R500_DY_T_SWIZ_R (0 << 26) +# define R500_DY_T_SWIZ_G (1 << 26) +# define R500_DY_T_SWIZ_B (2 << 26) +# define R500_DY_T_SWIZ_A (3 << 26) +# define R500_DY_R_SWIZ_R (0 << 28) +# define R500_DY_R_SWIZ_G (1 << 28) +# define R500_DY_R_SWIZ_B (2 << 28) +# define R500_DY_R_SWIZ_A (3 << 28) +# define R500_DY_Q_SWIZ_R (0 << 30) +# define R500_DY_Q_SWIZ_G (1 << 30) +# define R500_DY_Q_SWIZ_B (2 << 30) +# define R500_DY_Q_SWIZ_A (3 << 30) +#define R500_US_TEX_INST_0 0x9000 +# define R500_TEX_ID(x) (x << 16) +# define R500_TEX_INST_NOP (0 << 22) +# define R500_TEX_INST_LD (1 << 22) +# define R500_TEX_INST_TEXKILL (2 << 22) +# define R500_TEX_INST_PROJ (3 << 22) +# define R500_TEX_INST_LODBIAS (4 << 22) +# define R500_TEX_INST_LOD (5 << 22) +# define R500_TEX_INST_DXDY (6 << 22) +# define R500_TEX_SEM_ACQUIRE (1 << 25) +# define R500_TEX_IGNORE_UNCOVERED (1 << 26) +# define R500_TEX_UNSCALED (1 << 27) +#define R300_US_W_FMT 0x46b4 +# define R300_W_FMT_W0 (0 << 0) +# define R300_W_FMT_W24 (1 << 0) +# define R300_W_FMT_W24FP (2 << 0) +# define R300_W_SRC_US (0 << 2) +# define R300_W_SRC_RAS (1 << 2) + + +/* Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR. + * Two parameter dwords: + * 0. VAP_VTX_FMT: The first parameter is not written to hardware + * 1. VAP_VF_CTL: The second parameter is a standard primitive emission dword. + */ +#define R300_PACKET3_3D_DRAW_VBUF 0x00002800 + +/* Draw a primitive from immediate vertices in this packet + * Up to 16382 dwords: + * 0. VAP_VTX_FMT: The first parameter is not written to hardware + * 1. VAP_VF_CTL: The second parameter is a standard primitive emission dword. + * 2 to end: Up to 16380 dwords of vertex data. + */ +#define R300_PACKET3_3D_DRAW_IMMD 0x00002900 + +/* Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR and + * immediate vertices in this packet + * Up to 16382 dwords: + * 0. VAP_VTX_FMT: The first parameter is not written to hardware + * 1. VAP_VF_CTL: The second parameter is a standard primitive emission dword. + * 2 to end: Up to 16380 dwords of vertex data. + */ +#define R300_PACKET3_3D_DRAW_INDX 0x00002A00 + + +/* Specify the full set of vertex arrays as (address, stride). + * The first parameter is the number of vertex arrays specified. + * The rest of the command is a variable length list of blocks, where + * each block is three dwords long and specifies two arrays. + * The first dword of a block is split into two words, the lower significant + * word refers to the first array, the more significant word to the second + * array in the block. + * The low byte of each word contains the size of an array entry in dwords, + * the high byte contains the stride of the array. + * The second dword of a block contains the pointer to the first array, + * the third dword of a block contains the pointer to the second array. + * Note that if the total number of arrays is odd, the third dword of + * the last block is omitted. + */ +#define R300_PACKET3_3D_LOAD_VBPNTR 0x00002F00 + +#define R300_PACKET3_INDX_BUFFER 0x00003300 +# define R300_EB_UNK1_SHIFT 24 +# define R300_EB_UNK1 (0x80<<24) +# define R300_EB_UNK2 0x0810 + +/* Same as R300_PACKET3_3D_DRAW_VBUF but without VAP_VTX_FMT */ +#define R300_PACKET3_3D_DRAW_VBUF_2 0x00003400 +/* Same as R300_PACKET3_3D_DRAW_IMMD but without VAP_VTX_FMT */ +#define R300_PACKET3_3D_DRAW_IMMD_2 0x00003500 +/* Same as R300_PACKET3_3D_DRAW_INDX but without VAP_VTX_FMT */ +#define R300_PACKET3_3D_DRAW_INDX_2 0x00003600 + +/* Clears a portion of hierachical Z RAM + * 3 dword parameters + * 0. START + * 1. COUNT: 13:0 (max is 0x3FFF) + * 2. CLEAR_VALUE: Value to write into HIZ RAM. + */ +#define R300_PACKET3_3D_CLEAR_HIZ 0x00003700 + +/* Draws a set of primitives using vertex buffers pointed by the state data. + * At least 2 Parameters: + * 0. VAP_VF_CNTL: The first parameter is a standard primitive emission dword. + * 2 to end: Data or indices (see other 3D_DRAW_* packets for details) + */ +#define R300_PACKET3_3D_DRAW_128 0x00003900 + +/* END: Packet 3 commands */ + + +/* Color formats for 2d packets + */ +#define R300_CP_COLOR_FORMAT_CI8 2 +#define R300_CP_COLOR_FORMAT_ARGB1555 3 +#define R300_CP_COLOR_FORMAT_RGB565 4 +#define R300_CP_COLOR_FORMAT_ARGB8888 6 +#define R300_CP_COLOR_FORMAT_RGB332 7 +#define R300_CP_COLOR_FORMAT_RGB8 9 +#define R300_CP_COLOR_FORMAT_ARGB4444 15 + +/* + * CP type-3 packets + */ +#define R300_CP_CMD_BITBLT_MULTI 0xC0009B00 + +/* XXX Corbin's stuff from radeon and r200 */ + +#define RADEON_WAIT_UNTIL 0x1720 +# define RADEON_WAIT_CRTC_PFLIP (1 << 0) +# define RADEON_WAIT_2D_IDLECLEAN (1 << 16) +# define RADEON_WAIT_3D_IDLECLEAN (1 << 17) +# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) + +#define RADEON_CP_PACKET3 0xC0000000 + +#define R200_3D_DRAW_IMMD_2 0xC0003500 + +#endif /* _R300_REG_H */ + +/* *INDENT-ON* */ + +/* vim: set foldenable foldmarker=\\{,\\} foldmethod=marker : */ diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c new file mode 100644 index 0000000000..fd916fadbe --- /dev/null +++ b/src/gallium/drivers/r300/r300_screen.c @@ -0,0 +1,269 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "r300_screen.h" + +/* Return the identifier behind whom the brave coders responsible for this + * amalgamation of code, sweat, and duct tape, routinely obscure their names. + * + * ...I should have just put "Corbin Simpson", but I'm not that cool. + * + * (Or egotistical. Yet.) */ +static const char* r300_get_vendor(struct pipe_screen* pscreen) +{ + return "X.Org R300 Project"; +} + +static const char* chip_families[] = { + "R300", + "R350", + "R360", + "RV350", + "RV370", + "RV380", + "R420", + "R423", + "R430", + "R480", + "R481", + "RV410", + "RS400", + "RC410", + "RS480", + "RS482", + "RS690", + "RS740", + "RV515", + "R520", + "RV530", + "R580", + "RV560", + "RV570" +}; + +static const char* r300_get_name(struct pipe_screen* pscreen) +{ + struct r300_screen* r300screen = r300_screen(pscreen); + + return chip_families[r300screen->caps->family]; +} + +static int r300_get_param(struct pipe_screen* pscreen, int param) +{ + struct r300_screen* r300screen = r300_screen(pscreen); + + switch (param) { + /* XXX cases marked "IN THEORY" are possible on the hardware, + * but haven't been implemented yet. */ + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + /* XXX I'm told this goes up to 16 */ + return 8; + case PIPE_CAP_NPOT_TEXTURES: + /* IN THEORY */ + return 0; + case PIPE_CAP_TWO_SIDED_STENCIL: + if (r300screen->caps->is_r500) { + return 1; + } else { + return 0; + } + return 0; + case PIPE_CAP_GLSL: + /* IN THEORY */ + return 0; + case PIPE_CAP_S3TC: + /* IN THEORY */ + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + /* IN THEORY */ + return 0; + case PIPE_CAP_POINT_SPRITE: + /* IN THEORY */ + return 0; + case PIPE_CAP_MAX_RENDER_TARGETS: + /* XXX 4 eventually */ + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + /* IN THEORY */ + return 0; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + /* IN THEORY */ + return 0; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + if (r300screen->caps->is_r500) { + /* 13 == 4096x4096 */ + return 13; + } else { + /* 12 == 2048x2048 */ + return 12; + } + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + /* So, technically, the limit is the same as above, but some math + * shows why this is silly. Assuming RGBA, 4cpp, we can see that + * 4096*4096*4096 = 64.0 GiB exactly, so it's not exactly + * practical. However, if at some point a game really wants this, + * then we can remove this limit. */ + if (r300screen->caps->is_r500) { + /* 9 == 256x256x256 */ + return 9; + } else { + /* 8 == 128*128*128 */ + return 8; + } + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + if (r300screen->caps->is_r500) { + /* 13 == 4096x4096 */ + return 13; + } else { + /* 12 == 2048x2048 */ + return 12; + } + case PIPE_CAP_TEXTURE_MIRROR_CLAMP: + return 1; + case PIPE_CAP_TEXTURE_MIRROR_REPEAT: + return 1; + case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: + /* XXX guessing */ + return 2; + default: + debug_printf("r300: Implementation error: Bad param %d\n", + param); + return 0; + } +} + +static float r300_get_paramf(struct pipe_screen* pscreen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + case PIPE_CAP_MAX_LINE_WIDTH_AA: + /* XXX this is the biggest thing that will fit in that register. + * Perhaps the actual rendering limits are less? */ + return 10922.0f; + case PIPE_CAP_MAX_POINT_WIDTH: + case PIPE_CAP_MAX_POINT_WIDTH_AA: + /* XXX this is the biggest thing that will fit in that register. + * Perhaps the actual rendering limits are less? */ + return 10922.0f; + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 16.0f; + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 16.0f; + default: + debug_printf("r300: Implementation error: Bad paramf %d\n", + param); + return 0.0f; + } +} + +/* XXX moar formats */ +static boolean check_tex_2d_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_I8_UNORM: + return TRUE; + default: + debug_printf("r300: Warning: Got unknown format: %s, in %s\n", + pf_name(format), __FUNCTION__); + break; + } + + return FALSE; +} + +/* XXX moar targets */ +static boolean r300_is_format_supported(struct pipe_screen* pscreen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags) +{ + switch (target) { + case PIPE_TEXTURE_2D: + return check_tex_2d_format(format); + default: + debug_printf("r300: Warning: Got unknown format target: %d\n", + format); + break; + } + + return FALSE; +} + +static void* r300_surface_map(struct pipe_screen* screen, + struct pipe_surface* surface, + unsigned flags) +{ + char* map = pipe_buffer_map(screen, surface->buffer, flags); + + if (!map) { + return NULL; + } + + return map + surface->offset; +} + +static void r300_surface_unmap(struct pipe_screen* screen, + struct pipe_surface* surface) +{ + pipe_buffer_unmap(screen, surface->buffer); +} + +static void r300_destroy_screen(struct pipe_screen* pscreen) +{ + struct r300_screen* r300screen = r300_screen(pscreen); + + FREE(r300screen->caps); + FREE(r300screen); +} + +struct pipe_screen* r300_create_screen(struct pipe_winsys* winsys, + struct r300_winsys* r300_winsys) +{ + struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen); + struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities); + + if (!r300screen || !caps) + return NULL; + + caps->pci_id = r300_winsys->pci_id; + caps->num_frag_pipes = r300_winsys->gb_pipes; + + r300_parse_chipset(caps); + + r300screen->caps = caps; + r300screen->screen.winsys = winsys; + r300screen->screen.destroy = r300_destroy_screen; + r300screen->screen.get_name = r300_get_name; + r300screen->screen.get_vendor = r300_get_vendor; + r300screen->screen.get_param = r300_get_param; + r300screen->screen.get_paramf = r300_get_paramf; + r300screen->screen.is_format_supported = r300_is_format_supported; + r300screen->screen.surface_map = r300_surface_map; + r300screen->screen.surface_unmap = r300_surface_unmap; + + r300_init_screen_texture_functions(&r300screen->screen); + u_simple_screen_init(&r300screen->screen); + + return &r300screen->screen; +} diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h new file mode 100644 index 0000000000..2e25f61dbf --- /dev/null +++ b/src/gallium/drivers/r300/r300_screen.h @@ -0,0 +1,52 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 R300_SCREEN_H +#define R300_SCREEN_H + +#include "pipe/p_inlines.h" +#include "pipe/p_screen.h" +#include "util/u_memory.h" +#include "util/u_simple_screen.h" + +#include "r300_chipset.h" +#include "r300_texture.h" +#include "r300_winsys.h" + +struct r300_screen { + /* Parent class */ + struct pipe_screen screen; + + /* Chipset capabilities */ + struct r300_capabilities* caps; +}; + +/* Convenience cast wrapper. */ +static struct r300_screen* r300_screen(struct pipe_screen* screen) { + return (struct r300_screen*)screen; +} + +/* Creates a new r300 screen. */ +struct pipe_screen* r300_create_screen(struct pipe_winsys* winsys, + struct r300_winsys* r300_winsys); + +#endif /* R300_SCREEN_H */ diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c new file mode 100644 index 0000000000..9392d72342 --- /dev/null +++ b/src/gallium/drivers/r300/r300_state.c @@ -0,0 +1,826 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "util/u_math.h" +#include "util/u_pack_color.h" +#include "pipe/p_debug.h" + +#include "r300_context.h" +#include "r300_reg.h" + +/* r300_state: Functions used to intialize state context by translating + * Gallium state objects into semi-native r300 state objects. + * + * XXX break this file up into pieces if it gets too big! */ + +/* Pack a float into a dword. */ +static uint32_t pack_float_32(float f) +{ + union { + float f; + uint32_t u; + } u; + + u.f = f; + return u.u; +} + +static uint32_t translate_blend_function(int blend_func) { + switch (blend_func) { + case PIPE_BLEND_ADD: + return R300_COMB_FCN_ADD_CLAMP; + case PIPE_BLEND_SUBTRACT: + return R300_COMB_FCN_SUB_CLAMP; + case PIPE_BLEND_REVERSE_SUBTRACT: + return R300_COMB_FCN_RSUB_CLAMP; + case PIPE_BLEND_MIN: + return R300_COMB_FCN_MIN; + case PIPE_BLEND_MAX: + return R300_COMB_FCN_MAX; + default: + debug_printf("r300: Unknown blend function %d\n", blend_func); + break; + } + return 0; +} + +/* XXX we can also offer the D3D versions of some of these... */ +static uint32_t translate_blend_factor(int blend_fact) { + switch (blend_fact) { + case PIPE_BLENDFACTOR_ONE: + return R300_BLEND_GL_ONE; + case PIPE_BLENDFACTOR_SRC_COLOR: + return R300_BLEND_GL_SRC_COLOR; + case PIPE_BLENDFACTOR_SRC_ALPHA: + return R300_BLEND_GL_SRC_ALPHA; + case PIPE_BLENDFACTOR_DST_ALPHA: + return R300_BLEND_GL_DST_ALPHA; + case PIPE_BLENDFACTOR_DST_COLOR: + return R300_BLEND_GL_DST_COLOR; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + return R300_BLEND_GL_SRC_ALPHA_SATURATE; + case PIPE_BLENDFACTOR_CONST_COLOR: + return R300_BLEND_GL_CONST_COLOR; + case PIPE_BLENDFACTOR_CONST_ALPHA: + return R300_BLEND_GL_CONST_ALPHA; + /* XXX WTF are these? + case PIPE_BLENDFACTOR_SRC1_COLOR: + case PIPE_BLENDFACTOR_SRC1_ALPHA: */ + case PIPE_BLENDFACTOR_ZERO: + return R300_BLEND_GL_ZERO; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + return R300_BLEND_GL_ONE_MINUS_SRC_COLOR; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + return R300_BLEND_GL_ONE_MINUS_DST_ALPHA; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + return R300_BLEND_GL_ONE_MINUS_DST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + return R300_BLEND_GL_ONE_MINUS_CONST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA; + /* XXX see above + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */ + default: + debug_printf("r300: Unknown blend factor %d\n", blend_fact); + break; + } + return 0; +} + +/* Create a new blend state based on the CSO blend state. + * + * This encompasses alpha blending, logic/raster ops, and blend dithering. */ +static void* r300_create_blend_state(struct pipe_context* pipe, + const struct pipe_blend_state* state) +{ + struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state); + + if (state->blend_enable) { + /* XXX for now, always do separate alpha... + * is it faster to do it with one reg? */ + blend->blend_control = R300_ALPHA_BLEND_ENABLE | + R300_SEPARATE_ALPHA_ENABLE | + R300_READ_ENABLE | + translate_blend_function(state->rgb_func) | + (translate_blend_factor(state->rgb_src_factor) << + R300_SRC_BLEND_SHIFT) | + (translate_blend_factor(state->rgb_dst_factor) << + R300_DST_BLEND_SHIFT); + blend->alpha_blend_control = + translate_blend_function(state->alpha_func) | + (translate_blend_factor(state->alpha_src_factor) << + R300_SRC_BLEND_SHIFT) | + (translate_blend_factor(state->alpha_dst_factor) << + R300_DST_BLEND_SHIFT); + } + + /* PIPE_LOGICOP_* don't need to be translated, fortunately. */ + /* XXX are logicops still allowed if blending's disabled? + * Does Gallium take care of it for us? */ + if (state->logicop_enable) { + blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE | + (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT; + } + + if (state->dither) { + blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT | + R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT; + } + + return (void*)blend; +} + +/* Bind blend state. */ +static void r300_bind_blend_state(struct pipe_context* pipe, + void* state) +{ + struct r300_context* r300 = r300_context(pipe); + + r300->blend_state = (struct r300_blend_state*)state; + r300->dirty_state |= R300_NEW_BLEND; +} + +/* Free blend state. */ +static void r300_delete_blend_state(struct pipe_context* pipe, + void* state) +{ + FREE(state); +} + +/* Set blend color. + * Setup both R300 and R500 registers, figure out later which one to write. */ +static void r300_set_blend_color(struct pipe_context* pipe, + const struct pipe_blend_color* color) +{ + struct r300_context* r300 = r300_context(pipe); + uint32_t r, g, b, a; + ubyte ur, ug, ub, ua; + + r = util_iround(color->color[0] * 1023.0f); + g = util_iround(color->color[1] * 1023.0f); + b = util_iround(color->color[2] * 1023.0f); + a = util_iround(color->color[3] * 1023.0f); + + ur = float_to_ubyte(color->color[0]); + ug = float_to_ubyte(color->color[1]); + ub = float_to_ubyte(color->color[2]); + ua = float_to_ubyte(color->color[3]); + + r300->blend_color_state->blend_color = (a << 24) | (r << 16) | (g << 8) | b; + + r300->blend_color_state->blend_color_red_alpha = ur | (ua << 16); + r300->blend_color_state->blend_color_green_blue = ub | (ug << 16); + + r300->dirty_state |= R300_NEW_BLEND_COLOR; +} + +static void r300_set_clip_state(struct pipe_context* pipe, + const struct pipe_clip_state* state) +{ + struct r300_context* r300 = r300_context(pipe); + /* XXX Draw */ + draw_flush(r300->draw); + draw_set_clip_state(r300->draw, state); +} + +static void + r300_set_constant_buffer(struct pipe_context* pipe, + uint shader, uint index, + const struct pipe_constant_buffer* buffer) +{ + /* XXX */ +} + +static uint32_t translate_depth_stencil_function(int zs_func) { + switch (zs_func) { + case PIPE_FUNC_NEVER: + return R300_ZS_NEVER; + case PIPE_FUNC_LESS: + return R300_ZS_LESS; + case PIPE_FUNC_EQUAL: + return R300_ZS_EQUAL; + case PIPE_FUNC_LEQUAL: + return R300_ZS_LEQUAL; + case PIPE_FUNC_GREATER: + return R300_ZS_GREATER; + case PIPE_FUNC_NOTEQUAL: + return R300_ZS_NOTEQUAL; + case PIPE_FUNC_GEQUAL: + return R300_ZS_GEQUAL; + case PIPE_FUNC_ALWAYS: + return R300_ZS_ALWAYS; + default: + debug_printf("r300: Unknown depth/stencil function %d\n", + zs_func); + break; + } + return 0; +} + +static uint32_t translate_stencil_op(int s_op) { + switch (s_op) { + case PIPE_STENCIL_OP_KEEP: + return R300_ZS_KEEP; + case PIPE_STENCIL_OP_ZERO: + return R300_ZS_ZERO; + case PIPE_STENCIL_OP_REPLACE: + return R300_ZS_REPLACE; + case PIPE_STENCIL_OP_INCR: + return R300_ZS_INCR; + case PIPE_STENCIL_OP_DECR: + return R300_ZS_DECR; + case PIPE_STENCIL_OP_INCR_WRAP: + return R300_ZS_INCR_WRAP; + case PIPE_STENCIL_OP_DECR_WRAP: + return R300_ZS_DECR_WRAP; + case PIPE_STENCIL_OP_INVERT: + return R300_ZS_INVERT; + default: + debug_printf("r300: Unknown stencil op %d", s_op); + break; + } + return 0; +} + +static uint32_t translate_alpha_function(int alpha_func) { + switch (alpha_func) { + case PIPE_FUNC_NEVER: + return R300_FG_ALPHA_FUNC_NEVER; + case PIPE_FUNC_LESS: + return R300_FG_ALPHA_FUNC_LESS; + case PIPE_FUNC_EQUAL: + return R300_FG_ALPHA_FUNC_EQUAL; + case PIPE_FUNC_LEQUAL: + return R300_FG_ALPHA_FUNC_LE; + case PIPE_FUNC_GREATER: + return R300_FG_ALPHA_FUNC_GREATER; + case PIPE_FUNC_NOTEQUAL: + return R300_FG_ALPHA_FUNC_NOTEQUAL; + case PIPE_FUNC_GEQUAL: + return R300_FG_ALPHA_FUNC_GE; + case PIPE_FUNC_ALWAYS: + return R300_FG_ALPHA_FUNC_ALWAYS; + default: + debug_printf("r300: Unknown alpha function %d", alpha_func); + break; + } + return 0; +} + +/* Create a new depth, stencil, and alpha state based on the CSO dsa state. + * + * This contains the depth buffer, stencil buffer, alpha test, and such. + * On the Radeon, depth and stencil buffer setup are intertwined, which is + * the reason for some of the strange-looking assignments across registers. */ +static void* + r300_create_dsa_state(struct pipe_context* pipe, + const struct pipe_depth_stencil_alpha_state* state) +{ + struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state); + + /* Depth test setup. */ + if (state->depth.enabled) { + dsa->z_buffer_control |= R300_Z_ENABLE; + + if (state->depth.writemask) { + dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; + } + + dsa->z_stencil_control |= + (translate_depth_stencil_function(state->depth.func) << + R300_Z_FUNC_SHIFT); + } + + /* Stencil buffer setup. */ + if (state->stencil[0].enabled) { + dsa->z_buffer_control |= R300_STENCIL_ENABLE; + dsa->z_stencil_control |= + (translate_depth_stencil_function(state->stencil[0].func) << + R300_S_FRONT_FUNC_SHIFT) | + (translate_stencil_op(state->stencil[0].fail_op) << + R300_S_FRONT_SFAIL_OP_SHIFT) | + (translate_stencil_op(state->stencil[0].zpass_op) << + R300_S_FRONT_ZPASS_OP_SHIFT) | + (translate_stencil_op(state->stencil[0].zfail_op) << + R300_S_FRONT_ZFAIL_OP_SHIFT); + + dsa->stencil_ref_mask = (state->stencil[0].ref_value) | + (state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) | + (state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT); + + if (state->stencil[1].enabled) { + dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK; + dsa->z_stencil_control |= + (translate_depth_stencil_function(state->stencil[1].func) << + R300_S_BACK_FUNC_SHIFT) | + (translate_stencil_op(state->stencil[1].fail_op) << + R300_S_BACK_SFAIL_OP_SHIFT) | + (translate_stencil_op(state->stencil[1].zpass_op) << + R300_S_BACK_ZPASS_OP_SHIFT) | + (translate_stencil_op(state->stencil[1].zfail_op) << + R300_S_BACK_ZFAIL_OP_SHIFT); + + dsa->stencil_ref_bf = (state->stencil[1].ref_value) | + (state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) | + (state->stencil[1].writemask << R300_STENCILWRITEMASK_SHIFT); + } + } + + /* Alpha test setup. */ + if (state->alpha.enabled) { + dsa->alpha_function = translate_alpha_function(state->alpha.func) | + R300_FG_ALPHA_FUNC_ENABLE; + dsa->alpha_reference = CLAMP(state->alpha.ref_value * 1023.0f, + 0, 1023); + } else { + dsa->z_buffer_top = R300_ZTOP_ENABLE; + } + + return (void*)dsa; +} + +/* Bind DSA state. */ +static void r300_bind_dsa_state(struct pipe_context* pipe, + void* state) +{ + struct r300_context* r300 = r300_context(pipe); + + r300->dsa_state = (struct r300_dsa_state*)state; + r300->dirty_state |= R300_NEW_DSA; +} + +/* Free DSA state. */ +static void r300_delete_dsa_state(struct pipe_context* pipe, + void* state) +{ + FREE(state); +} + +static void r300_set_edgeflags(struct pipe_context* pipe, + const unsigned* bitfield) +{ + /* XXX you know it's bad when i915 has this blank too */ +} + +static void + r300_set_framebuffer_state(struct pipe_context* pipe, + const struct pipe_framebuffer_state* state) +{ + struct r300_context* r300 = r300_context(pipe); + + draw_flush(r300->draw); + + r300->framebuffer_state = *state; + + r300->dirty_state |= R300_NEW_FRAMEBUFFERS; +} + +/* Create fragment shader state. */ +static void* r300_create_fs_state(struct pipe_context* pipe, + const struct pipe_shader_state* shader) +{ + struct r300_context* r300 = r300_context(pipe); + struct r3xx_fragment_shader* fs = NULL; + + if (r300_screen(r300->context.screen)->caps->is_r500) { + fs = + (struct r3xx_fragment_shader*)CALLOC_STRUCT(r500_fragment_shader); + } else { + fs = + (struct r3xx_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader); + } + + /* Copy state directly into shader. */ + fs->state = *shader; + + return (void*)fs; +} + +/* Bind fragment shader state. */ +static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) +{ + struct r300_context* r300 = r300_context(pipe); + struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader; + + if (!fs->translated) { + if (r300_screen(r300->context.screen)->caps->is_r500) { + r500_translate_shader(r300, fs); + } else { + r300_translate_shader(r300, fs); + } + } + + r300->fs = fs; + + r300->dirty_state |= R300_NEW_FRAGMENT_SHADER; +} + +/* Delete fragment shader state. */ +static void r300_delete_fs_state(struct pipe_context* pipe, void* shader) +{ + FREE(shader); +} + +static void r300_set_polygon_stipple(struct pipe_context* pipe, + const struct pipe_poly_stipple* state) +{ + /* XXX */ +} + +static INLINE int pack_float_16_6x(float f) { + return ((int)(f * 6.0) & 0xffff); +} + +/* Create a new rasterizer state based on the CSO rasterizer state. + * + * This is a very large chunk of state, and covers most of the graphics + * backend (GB), geometry assembly (GA), and setup unit (SU) blocks. + * + * In a not entirely unironic sidenote, this state has nearly nothing to do + * with the actual block on the Radeon called the rasterizer (RS). */ +static void* r300_create_rs_state(struct pipe_context* pipe, + const struct pipe_rasterizer_state* state) +{ + struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); + + /* XXX this is part of HW TCL */ + /* XXX endian control */ + rs->vap_control_status = R300_VAP_TCL_BYPASS; + + rs->point_size = pack_float_16_6x(state->point_size) | + (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT); + + rs->line_control = pack_float_16_6x(state->line_width) | + R300_GA_LINE_CNTL_END_TYPE_COMP; + + /* Radeons don't think in "CW/CCW", they think in "front/back". */ + if (state->front_winding == PIPE_WINDING_CW) { + rs->cull_mode = R300_FRONT_FACE_CW; + + if (state->offset_cw) { + rs->polygon_offset_enable |= R300_FRONT_ENABLE; + } + if (state->offset_ccw) { + rs->polygon_offset_enable |= R300_BACK_ENABLE; + } + } else { + rs->cull_mode = R300_FRONT_FACE_CCW; + + if (state->offset_ccw) { + rs->polygon_offset_enable |= R300_FRONT_ENABLE; + } + if (state->offset_cw) { + rs->polygon_offset_enable |= R300_BACK_ENABLE; + } + } + if (state->front_winding & state->cull_mode) { + rs->cull_mode |= R300_CULL_FRONT; + } + if (~(state->front_winding) & state->cull_mode) { + rs->cull_mode |= R300_CULL_BACK; + } + + if (rs->polygon_offset_enable) { + rs->depth_offset_front = rs->depth_offset_back = + pack_float_32(state->offset_units); + rs->depth_scale_front = rs->depth_scale_back = + pack_float_32(state->offset_scale); + } + + if (state->line_stipple_enable) { + rs->line_stipple_config = + R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE | + (pack_float_32((float)state->line_stipple_factor) & + R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK); + /* XXX this might need to be scaled up */ + rs->line_stipple_value = state->line_stipple_pattern; + } + + return (void*)rs; +} + +/* Bind rasterizer state. */ +static void r300_bind_rs_state(struct pipe_context* pipe, void* state) +{ + struct r300_context* r300 = r300_context(pipe); + + r300->rs_state = (struct r300_rs_state*)state; + r300->dirty_state |= R300_NEW_RASTERIZER; +} + +/* Free rasterizer state. */ +static void r300_delete_rs_state(struct pipe_context* pipe, void* state) +{ + FREE(state); +} + +static uint32_t translate_wrap(int wrap) { + switch (wrap) { + case PIPE_TEX_WRAP_REPEAT: + return R300_TX_REPEAT; + case PIPE_TEX_WRAP_CLAMP: + return R300_TX_CLAMP; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return R300_TX_CLAMP_TO_EDGE; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return R300_TX_CLAMP_TO_BORDER; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + return R300_TX_REPEAT | R300_TX_MIRRORED; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + return R300_TX_CLAMP | R300_TX_MIRRORED; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED; + default: + debug_printf("r300: Unknown texture wrap %d", wrap); + return 0; + } +} + +static uint32_t translate_tex_filters(int min, int mag, int mip) { + uint32_t retval = 0; + switch (min) { + case PIPE_TEX_FILTER_NEAREST: + retval |= R300_TX_MIN_FILTER_NEAREST; + case PIPE_TEX_FILTER_LINEAR: + retval |= R300_TX_MIN_FILTER_LINEAR; + case PIPE_TEX_FILTER_ANISO: + retval |= R300_TX_MIN_FILTER_ANISO; + default: + debug_printf("r300: Unknown texture filter %d", min); + break; + } + switch (mag) { + case PIPE_TEX_FILTER_NEAREST: + retval |= R300_TX_MAG_FILTER_NEAREST; + case PIPE_TEX_FILTER_LINEAR: + retval |= R300_TX_MAG_FILTER_LINEAR; + case PIPE_TEX_FILTER_ANISO: + retval |= R300_TX_MAG_FILTER_ANISO; + default: + debug_printf("r300: Unknown texture filter %d", mag); + break; + } + switch (mip) { + case PIPE_TEX_MIPFILTER_NONE: + retval |= R300_TX_MIN_FILTER_MIP_NONE; + case PIPE_TEX_MIPFILTER_NEAREST: + retval |= R300_TX_MIN_FILTER_MIP_NEAREST; + case PIPE_TEX_MIPFILTER_LINEAR: + retval |= R300_TX_MIN_FILTER_MIP_LINEAR; + default: + debug_printf("r300: Unknown texture filter %d", mip); + break; + } + + return retval; +} + +static uint32_t anisotropy(float max_aniso) { + if (max_aniso >= 16.0f) { + return R300_TX_MAX_ANISO_16_TO_1; + } else if (max_aniso >= 8.0f) { + return R300_TX_MAX_ANISO_8_TO_1; + } else if (max_aniso >= 4.0f) { + return R300_TX_MAX_ANISO_4_TO_1; + } else if (max_aniso >= 2.0f) { + return R300_TX_MAX_ANISO_2_TO_1; + } else { + return R300_TX_MAX_ANISO_1_TO_1; + } +} + +static void* + r300_create_sampler_state(struct pipe_context* pipe, + const struct pipe_sampler_state* state) +{ + struct r300_context* r300 = r300_context(pipe); + struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state); + int lod_bias; + + sampler->filter0 |= + (translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) | + (translate_wrap(state->wrap_t) << R300_TX_WRAP_T_SHIFT) | + (translate_wrap(state->wrap_r) << R300_TX_WRAP_R_SHIFT); + + sampler->filter0 |= translate_tex_filters(state->min_img_filter, + state->mag_img_filter, + state->min_mip_filter); + + lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1); + + sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT; + + sampler->filter1 |= anisotropy(state->max_anisotropy); + + util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, + &sampler->border_color); + + /* R500-specific fixups and optimizations */ + if (r300_screen(r300->context.screen)->caps->is_r500) { + sampler->filter1 |= R500_BORDER_FIX; + } + + return (void*)sampler; +} + +static void r300_bind_sampler_states(struct pipe_context* pipe, + unsigned count, + void** states) +{ + struct r300_context* r300 = r300_context(pipe); + int i; + + if (count > 8) { + return; + } + + for (i = 0; i < count; i++) { + if (r300->sampler_states[i] != states[i]) { + r300->sampler_states[i] = (struct r300_sampler_state*)states[i]; + r300->dirty_state |= (R300_NEW_SAMPLER << i); + } + } + + r300->sampler_count = count; +} + +static void r300_delete_sampler_state(struct pipe_context* pipe, void* state) +{ + FREE(state); +} + +static void r300_set_sampler_textures(struct pipe_context* pipe, + unsigned count, + struct pipe_texture** texture) +{ + struct r300_context* r300 = r300_context(pipe); + int i; + + /* XXX magic num */ + if (count > 8) { + return; + } + + for (i = 0; i < count; i++) { + if (r300->textures[i] != (struct r300_texture*)texture[i]) { + pipe_texture_reference((struct pipe_texture**)&r300->textures[i], + texture[i]); + r300->dirty_state |= (R300_NEW_TEXTURE << i); + } + } + + for (i = count; i < 8; i++) { + if (r300->textures[i]) { + pipe_texture_reference((struct pipe_texture**)&r300->textures[i], + NULL); + r300->dirty_state |= (R300_NEW_TEXTURE << i); + } + } + + r300->texture_count = count; +} + +static void r300_set_scissor_state(struct pipe_context* pipe, + const struct pipe_scissor_state* state) +{ + struct r300_context* r300 = r300_context(pipe); + draw_flush(r300->draw); + + uint32_t left, top, right, bottom; + + /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in + * both directions for all values, and can only be 13 bits wide. Why? + * We may never know. */ + left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff; + top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff; + right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff; + bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff; + + r300->scissor_state->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) | + (top << R300_SCISSORS_Y_SHIFT); + r300->scissor_state->scissor_bottom_right = + (right << R300_SCISSORS_X_SHIFT) | (bottom << R300_SCISSORS_Y_SHIFT); + + r300->dirty_state |= R300_NEW_SCISSOR; +} + +static void r300_set_viewport_state(struct pipe_context* pipe, + const struct pipe_viewport_state* state) +{ + struct r300_context* r300 = r300_context(pipe); + /* XXX handing this off to Draw for now */ + draw_set_viewport_state(r300->draw, state); +} + +static void r300_set_vertex_buffers(struct pipe_context* pipe, + unsigned count, + const struct pipe_vertex_buffer* buffers) +{ + struct r300_context* r300 = r300_context(pipe); + /* XXX Draw */ + draw_flush(r300->draw); + draw_set_vertex_buffers(r300->draw, count, buffers); +} + +static void r300_set_vertex_elements(struct pipe_context* pipe, + unsigned count, + const struct pipe_vertex_element* elements) +{ + struct r300_context* r300 = r300_context(pipe); + /* XXX Draw */ + draw_flush(r300->draw); + draw_set_vertex_elements(r300->draw, count, elements); +} + +static void* r300_create_vs_state(struct pipe_context* pipe, + const struct pipe_shader_state* state) +{ + struct r300_context* context = r300_context(pipe); + /* XXX handing this off to Draw for now */ + return draw_create_vertex_shader(context->draw, state); +} + +static void r300_bind_vs_state(struct pipe_context* pipe, void* state) { + struct r300_context* context = r300_context(pipe); + /* XXX handing this off to Draw for now */ + draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state); +} + +static void r300_delete_vs_state(struct pipe_context* pipe, void* state) +{ + struct r300_context* context = r300_context(pipe); + /* XXX handing this off to Draw for now */ + draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state); +} + +void r300_init_state_functions(struct r300_context* r300) +{ + r300->context.create_blend_state = r300_create_blend_state; + r300->context.bind_blend_state = r300_bind_blend_state; + r300->context.delete_blend_state = r300_delete_blend_state; + + r300->context.set_blend_color = r300_set_blend_color; + + r300->context.set_clip_state = r300_set_clip_state; + + r300->context.set_constant_buffer = r300_set_constant_buffer; + + r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state; + r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state; + r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state; + + r300->context.set_edgeflags = r300_set_edgeflags; + + r300->context.set_framebuffer_state = r300_set_framebuffer_state; + + r300->context.create_fs_state = r300_create_fs_state; + r300->context.bind_fs_state = r300_bind_fs_state; + r300->context.delete_fs_state = r300_delete_fs_state; + + r300->context.set_polygon_stipple = r300_set_polygon_stipple; + + r300->context.create_rasterizer_state = r300_create_rs_state; + r300->context.bind_rasterizer_state = r300_bind_rs_state; + r300->context.delete_rasterizer_state = r300_delete_rs_state; + + r300->context.create_sampler_state = r300_create_sampler_state; + r300->context.bind_sampler_states = r300_bind_sampler_states; + r300->context.delete_sampler_state = r300_delete_sampler_state; + + r300->context.set_sampler_textures = r300_set_sampler_textures; + + r300->context.set_scissor_state = r300_set_scissor_state; + + r300->context.set_viewport_state = r300_set_viewport_state; + + r300->context.set_vertex_buffers = r300_set_vertex_buffers; + r300->context.set_vertex_elements = r300_set_vertex_elements; + + r300->context.create_vs_state = r300_create_vs_state; + r300->context.bind_vs_state = r300_bind_vs_state; + r300->context.delete_vs_state = r300_delete_vs_state; +} diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c new file mode 100644 index 0000000000..e87172128f --- /dev/null +++ b/src/gallium/drivers/r300/r300_state_shader.c @@ -0,0 +1,33 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "r300_state_shader.h" + +void r300_translate_shader(struct r300_context* r300, + struct r300_fragment_shader* fs) +{ +} + +void r500_translate_shader(struct r300_context* r300, + struct r500_fragment_shader* fs) +{ +} diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h new file mode 100644 index 0000000000..a20bd4276c --- /dev/null +++ b/src/gallium/drivers/r300/r300_state_shader.h @@ -0,0 +1,35 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 R300_STATE_SHADER_H +#define R300_STATE_SHADER_H + +#include "r300_context.h" +#include "r300_screen.h" + +void r300_translate_shader(struct r300_context* r300, + struct r300_fragment_shader* fs); + +void r500_translate_shader(struct r300_context* r300, + struct r500_fragment_shader* fs); + +#endif /* R300_STATE_SHADER_H */ diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c new file mode 100644 index 0000000000..1ed4a4e3bc --- /dev/null +++ b/src/gallium/drivers/r300/r300_surface.c @@ -0,0 +1,328 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "r300_surface.h" + +/* Provides pipe_context's "surface_fill". Commonly used for clearing + * buffers. */ +static void r300_surface_fill(struct pipe_context* pipe, + struct pipe_surface* dest, + unsigned x, unsigned y, + unsigned w, unsigned h, + unsigned color) +{ + struct r300_context* r300 = r300_context(pipe); + CS_LOCALS(r300); + struct r300_capabilities* caps = ((struct r300_screen*)pipe->screen)->caps; + int i; + float r, g, b, a; + r = (float)((color >> 16) & 0xff) / 255.0f; + g = (float)((color >> 8) & 0xff) / 255.0f; + b = (float)((color >> 0) & 0xff) / 255.0f; + debug_printf("r300: Filling surface %p at (%d,%d)," + " dimensions %dx%d (stride %d), color 0x%x\n", + dest, x, y, w, h, dest->stride, color); + + /* Fallback? */ + if (0) { + debug_printf("r300: Falling back on surface clear..."); + void* map = pipe->screen->surface_map(pipe->screen, dest, + PIPE_BUFFER_USAGE_CPU_WRITE); + pipe_fill_rect(map, &dest->block, &dest->stride, x, y, w, h, color); + pipe->screen->surface_unmap(pipe->screen, dest); + return; + } + +BEGIN_CS((caps->is_r500) ? 309 : 280); +R300_PACIFY; +OUT_CS_REG(R300_TX_INVALTAGS, 0x0); +R300_PACIFY; +/* Flush PVS. */ +OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); + +OUT_CS_REG(R300_SE_VTE_CNTL, R300_VPORT_X_SCALE_ENA | + R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA | + R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA | + R300_VPORT_Z_OFFSET_ENA | R300_VTX_W0_FMT); +/* Vertex size. */ +OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8); +/* Max and min vertex index clamp. */ +OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, 0xFFFFFF); +OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0x0); +/* XXX endian */ +OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VC_NO_SWAP); +OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, 0x0); +/* XXX magic number not in r300_reg */ +OUT_CS_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0xAAAAAAAA); +OUT_CS_REG(R300_VAP_CLIP_CNTL, 0x0); +OUT_CS_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4); +OUT_CS_32F(1.0); +OUT_CS_32F(1.0); +OUT_CS_32F(1.0); +OUT_CS_32F(1.0); +/* XXX is this too long? */ +OUT_CS_REG(VAP_PVS_VTX_TIMEOUT_REG, 0xFFFF); +OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE | + R300_GB_LINE_STUFF_ENABLE | R300_GB_TRIANGLE_STUFF_ENABLE); +/* XXX more magic numbers */ +OUT_CS_REG(R300_GB_MSPOS0, 0x66666666); +OUT_CS_REG(R300_GB_MSPOS1, 0x66666666); +/* XXX why doesn't classic Mesa write the number of pipes, too? */ +OUT_CS_REG(R300_GB_TILE_CONFIG, R300_GB_TILE_ENABLE | R300_GB_TILE_SIZE_16); +OUT_CS_REG(R300_GB_SELECT, R300_GB_FOG_SELECT_1_1_W); +OUT_CS_REG(R300_GB_AA_CONFIG, 0x0); +/* XXX point tex stuffing */ +OUT_CS_REG_SEQ(R300_GA_POINT_S0, 1); +OUT_CS_32F(0.0); +OUT_CS_REG_SEQ(R300_GA_POINT_S1, 1); +OUT_CS_32F(1.0); +OUT_CS_REG(R300_GA_TRIANGLE_STIPPLE, 0x5 | + (0x5 << R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_SHIFT)); +/* XXX should this be related to the actual point size? */ +OUT_CS_REG(R300_GA_POINT_MINMAX, 0x6 | + (0x1800 << R300_GA_POINT_MINMAX_MAX_SHIFT)); +/* XXX this big chunk should be refactored into rs_state */ +OUT_CS_REG(R300_GA_LINE_CNTL, 0x00030006); +OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, 0x3BAAAAAB); +OUT_CS_REG(R300_GA_LINE_STIPPLE_VALUE, 0x00000000); +OUT_CS_REG(R300_GA_LINE_S0, 0x00000000); +OUT_CS_REG(R300_GA_LINE_S1, 0x3F800000); +OUT_CS_REG(R300_GA_ENHANCE, 0x00000002); +OUT_CS_REG(R300_GA_COLOR_CONTROL, 0x0003AAAA); +OUT_CS_REG(R300_GA_SOLID_RG, 0x00000000); +OUT_CS_REG(R300_GA_SOLID_BA, 0x00000000); +OUT_CS_REG(R300_GA_POLY_MODE, 0x00000000); +OUT_CS_REG(R300_GA_ROUND_MODE, 0x00000001); +OUT_CS_REG(R300_GA_OFFSET, 0x00000000); +OUT_CS_REG(R300_GA_FOG_SCALE, 0x3DBF1412); +OUT_CS_REG(R300_GA_FOG_OFFSET, 0x00000000); +OUT_CS_REG(R300_SU_TEX_WRAP, 0x00000000); +OUT_CS_REG(R300_SU_POLY_OFFSET_FRONT_SCALE, 0x00000000); +OUT_CS_REG(R300_SU_POLY_OFFSET_FRONT_OFFSET, 0x00000000); +OUT_CS_REG(R300_SU_POLY_OFFSET_BACK_SCALE, 0x00000000); +OUT_CS_REG(R300_SU_POLY_OFFSET_BACK_OFFSET, 0x00000000); +OUT_CS_REG(R300_SU_POLY_OFFSET_ENABLE, 0x00000000); +OUT_CS_REG(R300_SU_CULL_MODE, 0x00000000); +OUT_CS_REG(R300_SU_DEPTH_SCALE, 0x4B7FFFFF); +OUT_CS_REG(R300_SU_DEPTH_OFFSET, 0x00000000); +OUT_CS_REG(R300_SC_HYPERZ, 0x0000001C); +OUT_CS_REG(R300_SC_EDGERULE, 0x2DA49525); +OUT_CS_REG(R300_SC_SCREENDOOR, 0x00FFFFFF); +OUT_CS_REG(R300_FG_FOG_BLEND, 0x00000002); +OUT_CS_REG(R300_FG_FOG_COLOR_R, 0x00000000); +OUT_CS_REG(R300_FG_FOG_COLOR_G, 0x00000000); +OUT_CS_REG(R300_FG_FOG_COLOR_B, 0x00000000); +OUT_CS_REG(R300_FG_DEPTH_SRC, 0x00000000); +OUT_CS_REG(R300_FG_DEPTH_SRC, 0x00000000); +OUT_CS_REG(R300_RB3D_CCTL, 0x00000000); +OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0x0000000F); + +/* XXX: Oh the wonderful unknown */ +OUT_CS_REG_SEQ(0x4E54, 8); +for (i = 0; i < 8; i++) + OUT_CS(0x00000000); +OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, 0x00000000); +OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x00000000); +OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFFFFFFFF); +OUT_CS_REG(R300_ZB_FORMAT, 0x00000002); +OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, 0x00000003); +OUT_CS_REG(R300_ZB_BW_CNTL, 0x00000000); +OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0x00000000); +OUT_CS_REG(0x4F30, 0x00000000); +OUT_CS_REG(0x4F34, 0x00000000); +OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0x00000000); +OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000); +R300_PACIFY; +OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, 0x21030003); +OUT_CS_REG(R300_FG_FOG_BLEND, 0x00000000); +OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0, 0xF688F688); +OUT_CS_REG(R300_VAP_VTX_STATE_CNTL, 0x1); +OUT_CS_REG(R300_VAP_VSM_VTX_ASSM, 0x405); +OUT_CS_REG(R300_SE_VTE_CNTL, 0x0000043F); +OUT_CS_REG(R300_VAP_VTX_SIZE, 0x00000008); +OUT_CS_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0xAAAAAAAA); +OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0, 0x00000003); +OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x00000000); +OUT_CS_REG(R300_TX_ENABLE, 0x0); +/* XXX viewport setup */ +OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); +OUT_CS_32F(1.0); +OUT_CS_32F((float)x); +OUT_CS_32F(1.0); +OUT_CS_32F((float)y); +OUT_CS_32F(1.0); +OUT_CS_32F(0.0); + +OUT_CS_REG(R300_VAP_CLIP_CNTL, 0x0001C000); +OUT_CS_REG(R300_GA_POINT_SIZE, ((h * 6) & R300_POINTSIZE_Y_MASK) | + ((w * 6) << R300_POINTSIZE_X_SHIFT)); + +/* XXX RS block and fp setup */ +if (caps->is_r500) { + OUT_CS_REG_SEQ(R500_RS_IP_0, 8); + for (i = 0; i < 8; i++) { + /* I like the operator macros more than the shift macros... */ + OUT_CS((R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) | + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) | + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | + (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)); + } + /* XXX */ + OUT_CS_REG_SEQ(R300_RS_COUNT, 2); + OUT_CS((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN); + OUT_CS(0x0); + OUT_CS_REG(R500_RS_INST_0, R500_RS_INST_COL_CN_WRITE); + + OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); + OUT_CS_REG(R500_US_PIXSIZE, 0x00000000); + OUT_CS_REG(R500_US_CODE_ADDR, R500_US_CODE_START_ADDR(0) | + R500_US_CODE_END_ADDR(1)); + OUT_CS_REG(R500_US_CODE_RANGE, R500_US_CODE_RANGE_ADDR(0) | + R500_US_CODE_RANGE_SIZE(1)); + OUT_CS_REG(R500_US_CODE_OFFSET, R500_US_CODE_OFFSET_ADDR(0)); + R300_PACIFY; + OUT_CS_REG(R500_GA_US_VECTOR_INDEX, + 0 | R500_GA_US_VECTOR_INDEX_TYPE_INSTR); + OUT_CS_REG(R500_GA_US_VECTOR_DATA, + R500_INST_TYPE_OUT | R500_INST_TEX_SEM_WAIT | R500_INST_LAST | + R500_INST_RGB_OMASK_R | R500_INST_RGB_OMASK_G | R500_INST_RGB_OMASK_B | + R500_INST_ALPHA_OMASK | R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP); + OUT_CS_REG(R500_GA_US_VECTOR_DATA, + R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | + R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST); + OUT_CS_REG(R500_GA_US_VECTOR_DATA, + R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | + R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST); + OUT_CS_REG(R500_GA_US_VECTOR_DATA, + R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R | + R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B | + R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R | + R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B); + OUT_CS_REG(R500_GA_US_VECTOR_DATA, + R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A); + OUT_CS_REG(R500_GA_US_VECTOR_DATA, + R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 | + R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | + R500_ALU_RGBA_A_SWIZ_0); +} else { + OUT_CS_REG_SEQ(R300_RS_IP_0, 8); + for (i = 0; i < 8; i++) { + OUT_CS(R300_RS_SEL_T(R300_RS_SEL_K0) | + R300_RS_SEL_R(R300_RS_SEL_K0) | R300_RS_SEL_Q(R300_RS_SEL_K1)); + } + /* XXX */ + OUT_CS_REG_SEQ(R300_RS_COUNT, 2); + OUT_CS((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN); + OUT_CS(1); + OUT_CS_REG(R300_RS_INST_0, R300_RS_INST_COL_CN_WRITE); + + /* XXX magic numbers */ + OUT_CS_REG(R300_US_CONFIG, 0); + OUT_CS_REG(R300_US_PIXSIZE, 2); + OUT_CS_REG(R300_US_CODE_OFFSET, 0x0); + OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0); + OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0); + OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0); + OUT_CS_REG(R300_US_CODE_ADDR_3, 0x400000); + OUT_CS_REG(R300_US_ALU_RGB_INST_0, 0x50A80); + OUT_CS_REG(R300_US_ALU_RGB_ADDR_0, 0x1C000000); + OUT_CS_REG(R300_US_ALU_ALPHA_INST_0, 0x40889); + OUT_CS_REG(R300_US_ALU_ALPHA_ADDR_0, 0x1000000); + OUT_CS_REG_SEQ(R300_US_OUT_FMT_0, 4); + OUT_CS(R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A); + OUT_CS(R300_US_OUT_FMT_UNUSED); + OUT_CS(R300_US_OUT_FMT_UNUSED); + OUT_CS(R300_US_OUT_FMT_UNUSED); + OUT_CS_REG(R300_US_W_FMT, R300_W_FMT_W0); +} +/* XXX these magic numbers should be explained when + * this becomes a cached state object */ +OUT_CS_REG(R300_VAP_CNTL, 0xA | (0x5 << R300_PVS_NUM_CNTLRS_SHIFT) | + (caps->num_vert_fpus << R300_PVS_NUM_FPUS_SHIFT)); +OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, 0x00100000); +OUT_CS_REG(R300_VAP_PVS_CONST_CNTL, 0x00000000); +OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, 0x00000001); +R300_PACIFY; +/* XXX translate these back into normal instructions */ +OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x1); +OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0x0); +OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0xF00203); +OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0xD10001); +OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0x1248001); +OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0x0); +OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0xF02203); +OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0xD10021); +OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0x1248021); +OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0x0); +R300_PACIFY; +END_CS; + +r300_emit_blend_state(r300, &blend_clear_state); +r300_emit_blend_color_state(r300, &blend_color_clear_state); +r300_emit_dsa_state(r300, &dsa_clear_state); + +BEGIN_CS(36); +R300_PACIFY; +/* Flush colorbuffer and blend caches. */ +OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, + R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D | + R300_RB3D_DSTCACHE_CTLSTAT_DC_FINISH_SIGNAL); +OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, + R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | + R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); + +OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1); +OUT_CS_RELOC(dest->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); +/* XXX this should not be so rigid and it still doesn't work right */ +OUT_CS_REG(R300_RB3D_COLORPITCH0, (dest->stride >> 2) | R300_COLOR_FORMAT_ARGB8888); +OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0x0000000F); +/* XXX Packet3 */ +OUT_CS(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8)); +OUT_CS(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING | +(1 << R300_PRIM_NUM_VERTICES_SHIFT)); +OUT_CS_32F(w / 2.0); +OUT_CS_32F(h / 2.0); +/* XXX this should be the depth value to clear to */ +OUT_CS_32F(1.0); +OUT_CS_32F(1.0); +OUT_CS_32F(r); +OUT_CS_32F(g); +OUT_CS_32F(b); +OUT_CS_32F(1.0); + +/* XXX figure out why this is 0xA and not 0x2 */ +OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA); +/* XXX OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, + R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | + R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); */ +R300_PACIFY; + +END_CS; +FLUSH_CS; + + r300->dirty_state = R300_NEW_KITCHEN_SINK; +} + +void r300_init_surface_functions(struct r300_context* r300) +{ + r300->context.surface_fill = r300_surface_fill; +} diff --git a/src/gallium/drivers/r300/r300_surface.h b/src/gallium/drivers/r300/r300_surface.h new file mode 100644 index 0000000000..e1d53116a1 --- /dev/null +++ b/src/gallium/drivers/r300/r300_surface.h @@ -0,0 +1,58 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 R300_SURFACE_H +#define R300_SURFACE_H + +#include "pipe/p_context.h" +#include "pipe/p_screen.h" + +#include "util/u_rect.h" + +#include "r300_context.h" +#include "r300_cs.h" +#include "r300_emit.h" + +const struct r300_blend_state blend_clear_state = { + .blend_control = 0x0, + .alpha_blend_control = 0x0, + .rop = 0x0, + .dither = 0x0, +}; + +const struct r300_blend_color_state blend_color_clear_state = { + .blend_color = 0x0, + .blend_color_red_alpha = 0x0, + .blend_color_green_blue = 0x0, +}; + +const struct r300_dsa_state dsa_clear_state = { + .alpha_function = 0x0, + .alpha_reference = 0x0, + .z_buffer_control = 0x0, + .z_stencil_control = 0x0, + .stencil_ref_mask = R300_STENCILWRITEMASK_MASK, + .z_buffer_top = R300_ZTOP_ENABLE, + .stencil_ref_bf = 0x0, +}; + +#endif /* R300_SURFACE_H */ diff --git a/src/gallium/drivers/r300/r300_swtcl_emit.c b/src/gallium/drivers/r300/r300_swtcl_emit.c new file mode 100644 index 0000000000..f6e98d23e9 --- /dev/null +++ b/src/gallium/drivers/r300/r300_swtcl_emit.c @@ -0,0 +1,129 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "draw/draw_pipe.h" +#include "util/u_memory.h" + +#include "r300_cs.h" +#include "r300_context.h" +#include "r300_reg.h" + +/* r300_swtcl_emit: Primitive vertex emission using an immediate + * vertex buffer and no HW TCL. */ + +struct swtcl_stage { + /* Parent class */ + struct draw_stage draw; + + struct r300_context* r300; +}; + +static INLINE struct swtcl_stage* swtcl_stage(struct draw_stage* draw) { + return (struct swtcl_stage*)draw; +} + +static void r300_emit_vertex(struct r300_context* r300, + const struct vertex_header* vertex) +{ + /* XXX */ +} + +static INLINE void r300_emit_prim(struct draw_stage* draw, + struct prim_header* prim, + unsigned hwprim, + unsigned count) +{ + struct r300_context* r300 = swtcl_stage(draw)->r300; + CS_LOCALS(r300); + int i; + + r300_emit_dirty_state(r300); + + /* XXX should be count * vtx size */ + BEGIN_CS(2 + count + 6); + OUT_CS(CP_PACKET3(R200_3D_DRAW_IMMD_2, count)); + OUT_CS(hwprim | R300_PRIM_WALK_RING | + (count << R300_PRIM_NUM_VERTICES_SHIFT)); + + for (i = 0; i < count; i++) { + r300_emit_vertex(r300, prim->v[i]); + } + R300_PACIFY; + END_CS; +} + +/* Just as an aside... + * + * Radeons can do many more primitives: + * - Line strip + * - Triangle fan + * - Triangle strip + * - Line loop + * - Quads + * - Quad strip + * - Polygons + * + * The following were just the only ones in Draw. */ + +static void r300_emit_point(struct draw_stage* draw, struct prim_header* prim) +{ + r300_emit_prim(draw, prim, R300_PRIM_TYPE_POINT, 1); +} + +static void r300_emit_line(struct draw_stage* draw, struct prim_header* prim) +{ + r300_emit_prim(draw, prim, R300_PRIM_TYPE_LINE, 2); +} + +static void r300_emit_tri(struct draw_stage* draw, struct prim_header* prim) +{ + r300_emit_prim(draw, prim, R300_PRIM_TYPE_TRI_LIST, 3); +} + +static void r300_swtcl_flush(struct draw_stage* draw, unsigned flags) +{ +} + +static void r300_reset_stipple(struct draw_stage* draw) +{ + /* XXX */ +} + +static void r300_swtcl_destroy(struct draw_stage* draw) +{ + FREE(draw); +} + +struct draw_stage* r300_draw_swtcl_stage(struct r300_context* r300) +{ + struct swtcl_stage* swtcl = CALLOC_STRUCT(swtcl_stage); + + swtcl->r300 = r300; + swtcl->draw.point = r300_emit_point; + swtcl->draw.line = r300_emit_line; + swtcl->draw.tri = r300_emit_tri; + swtcl->draw.flush = r300_swtcl_flush; + swtcl->draw.reset_stipple_counter = r300_reset_stipple; + swtcl->draw.destroy = r300_swtcl_destroy; + + return &swtcl->draw; +} diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c new file mode 100644 index 0000000000..f9ad14f12b --- /dev/null +++ b/src/gallium/drivers/r300/r300_texture.c @@ -0,0 +1,195 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 "r300_texture.h" + +static int minify(int i) +{ + return MAX2(1, i >> 1); +} + +static void r300_setup_miptree(struct r300_texture* tex) +{ + struct pipe_texture* base = &tex->tex; + int stride, size, offset; + + for (int i = 0; i <= base->last_level; i++) { + if (i > 0) { + base->width[i] = minify(base->width[i-1]); + base->height[i] = minify(base->height[i-1]); + base->depth[i] = minify(base->depth[i-1]); + } + + base->nblocksx[i] = pf_get_nblocksx(&base->block, base->width[i]); + base->nblocksy[i] = pf_get_nblocksy(&base->block, base->width[i]); + + /* Radeons enjoy things in multiples of 32. */ + /* XXX NPOT -> 64, not 32 */ + stride = (base->nblocksx[i] * base->block.size + 63) & ~63; + size = stride * base->nblocksy[i] * base->depth[i]; + + /* XXX 64 for NPOT */ + tex->offset[i] = (tex->size + 63) & ~63; + tex->size = tex->offset[i] + size; + } +} + +/* Create a new texture. */ +static struct pipe_texture* + r300_texture_create(struct pipe_screen* screen, + const struct pipe_texture* template) +{ + /* XXX struct r300_screen* r300screen = r300_screen(screen); */ + + struct r300_texture* tex = CALLOC_STRUCT(r300_texture); + + if (!tex) { + return NULL; + } + + tex->tex = *template; + tex->tex.refcount = 1; + tex->tex.screen = screen; + + r300_setup_miptree(tex); + + tex->buffer = screen->buffer_create(screen, 63, + PIPE_BUFFER_USAGE_PIXEL, + tex->size); + + if (!tex->buffer) { + FREE(tex); + return NULL; + } + + return (struct pipe_texture*)tex; +} + +static void r300_texture_release(struct pipe_screen* screen, + struct pipe_texture** texture) +{ + if (!*texture) { + return; + } + + (*texture)->refcount--; + + if ((*texture)->refcount <= 0) { + struct r300_texture* tex = (struct r300_texture*)*texture; + + pipe_buffer_reference(screen, &tex->buffer, NULL); + + FREE(tex); + } + + *texture = NULL; +} + +static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, + struct pipe_texture* texture, + unsigned face, + unsigned level, + unsigned zslice, + unsigned flags) +{ + struct r300_texture* tex = (struct r300_texture*)texture; + struct pipe_surface* surface = CALLOC_STRUCT(pipe_surface); + unsigned offset; + + /* XXX this is certainly dependent on tex target */ + offset = tex->offset[level]; + + if (surface) { + surface->refcount = 1; + pipe_texture_reference(&surface->texture, texture); + pipe_buffer_reference(screen, &surface->buffer, tex->buffer); + surface->format = texture->format; + surface->width = texture->width[level]; + surface->height = texture->height[level]; + surface->block = texture->block; + surface->nblocksx = texture->nblocksx[level]; + surface->nblocksy = texture->nblocksy[level]; + /* XXX save the actual stride instead plz kthnxbai */ + surface->stride = + (texture->nblocksx[level] * texture->block.size + 63) & ~63; + surface->offset = offset; + surface->usage = flags; + surface->status = PIPE_SURFACE_STATUS_DEFINED; + } + + return surface; +} + +static void r300_tex_surface_release(struct pipe_screen* screen, + struct pipe_surface** surface) +{ + struct pipe_surface* s = *surface; + + s->refcount--; + + if (s->refcount <= 0) { + pipe_texture_reference(&s->texture, NULL); + pipe_buffer_reference(screen, &s->buffer, NULL); + FREE(s); + } + + *surface = NULL; +} + +static struct pipe_texture* + r300_texture_blanket(struct pipe_screen* screen, + const struct pipe_texture* base, + const unsigned* stride, + struct pipe_buffer* buffer) +{ + struct r300_texture* tex; + + if (base->target != PIPE_TEXTURE_2D || + base->last_level != 0 || + base->depth[0] != 1) { + return NULL; + } + + tex = CALLOC_STRUCT(r300_texture); + if (!tex) { + return NULL; + } + + tex->tex = *base; + tex->tex.refcount = 1; + tex->tex.screen = screen; + + /* XXX tex->stride = *stride; */ + + pipe_buffer_reference(screen, &tex->buffer, buffer); + + return (struct pipe_texture*)tex; +} + +void r300_init_screen_texture_functions(struct pipe_screen* screen) +{ + screen->texture_create = r300_texture_create; + screen->texture_release = r300_texture_release; + screen->get_tex_surface = r300_get_tex_surface; + screen->tex_surface_release = r300_tex_surface_release; + screen->texture_blanket = r300_texture_blanket; +} diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h new file mode 100644 index 0000000000..7964229a94 --- /dev/null +++ b/src/gallium/drivers/r300/r300_texture.h @@ -0,0 +1,34 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 R300_TEXTURE_H +#define R300_TEXTURE_H + +#include "pipe/p_screen.h" + +#include "util/u_math.h" + +#include "r300_context.h" + +void r300_init_screen_texture_functions(struct pipe_screen* screen); + +#endif /* R300_TEXTURE_H */ diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h new file mode 100644 index 0000000000..5a3a212892 --- /dev/null +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -0,0 +1,94 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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 R300_WINSYS_H +#define R300_WINSYS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* The public interface header for the r300 pipe driver. + * Any winsys hosting this pipe needs to implement r300_winsys and then + * call r300_create_context to start things. */ + +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +struct radeon_cs; + +struct r300_winsys { + + /* PCI ID */ + uint32_t pci_id; + + /* GB pipe count */ + uint32_t gb_pipes; + + /* CS object. This is very much like Intel's batchbuffer. + * Fill it full of dwords and relocs and then submit. + * Repeat as needed. */ + /* Note: Unlike Mesa's version of this, we don't keep a copy of the CSM + * that was used to create this CS. Is this a good idea? */ + /* Note: The pipe driver doesn't know how to use this. This is purely + * for the winsys. */ + struct radeon_cs* cs; + + /* Check to see if there's room for commands. */ + boolean (*check_cs)(struct radeon_cs* cs, int size); + + /* Start a command emit. */ + void (*begin_cs)(struct radeon_cs* cs, + int size, + const char* file, + const char* function, + int line); + + /* Write a dword to the command buffer. */ + void (*write_cs_dword)(struct radeon_cs* cs, uint32_t dword); + + /* Write a relocated dword to the command buffer. */ + void (*write_cs_reloc)(struct radeon_cs* cs, + struct pipe_buffer* bo, + uint32_t rd, + uint32_t wd, + uint32_t flags); + + /* Finish a command emit. */ + void (*end_cs)(struct radeon_cs* cs, + const char* file, + const char* function, + int line); + + /* Flush the CS. */ + void (*flush_cs)(struct radeon_cs* cs); +}; + +struct pipe_context* r300_create_context(struct pipe_screen* screen, + struct pipe_winsys* winsys, + struct r300_winsys* r300_winsys); + +#ifdef __cplusplus +} +#endif + +#endif /* R300_WINSYS_H */ diff --git a/src/gallium/winsys/drm/radeon/Makefile b/src/gallium/winsys/drm/radeon/Makefile new file mode 100644 index 0000000000..dca1e3233a --- /dev/null +++ b/src/gallium/winsys/drm/radeon/Makefile @@ -0,0 +1,32 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = radeon_dri.so + +MINIGLX_SOURCES = + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/r300/libr300.a + +DRIVER_SOURCES = \ + radeon_buffer.c \ + radeon_context.c \ + radeon_r300.c \ + radeon_screen.c \ + radeon_winsys_softpipe.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +DRIVER_DEFINES = -I../../../drivers/r300 + +include ../Makefile.template + +DRI_LIB_DEPS += -ldrm_radeon + +symlinks: diff --git a/src/gallium/winsys/drm/radeon/SConscript b/src/gallium/winsys/drm/radeon/SConscript new file mode 100644 index 0000000000..2435211a32 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/SConscript @@ -0,0 +1,29 @@ +Import('*') + +if 'mesa' in env['statetrackers']: + + env = drienv.Clone() + + DRIVER_SOURCES = [ + 'radeon_buffer.c', + 'radeon_context.c', + 'radeon_screen.c', + 'radeon_winsys_softpipe.c', + ] + + sources = \ + COMMON_GALLIUM_SOURCES + \ + DRIVER_SOURCES + + drivers = [ + softpipe, + r300 + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='radeon_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], + ) + diff --git a/src/gallium/winsys/drm/radeon/radeon_buffer.c b/src/gallium/winsys/drm/radeon/radeon_buffer.c new file mode 100644 index 0000000000..259a505c0a --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_buffer.c @@ -0,0 +1,239 @@ +/* + * Copyright © 2008 Jérôme Glisse + * 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 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 THE COPYRIGHT HOLDERS, AUTHORS + * 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Jérôme Glisse <glisse@freedesktop.org> + */ +#include <stdio.h> +#include "dri_util.h" +#include "state_tracker/st_public.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "radeon_buffer.h" +#include "radeon_screen.h" +#include "radeon_context.h" +#include "radeon_bo.h" +#include "radeon_drm.h" + +static const char *radeon_get_name(struct pipe_winsys *ws) +{ + return "RADEON/DRI2"; +} + +static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct radeon_pipe_winsys *radeon_ws = (struct radeon_pipe_winsys *)ws; + struct radeon_pipe_buffer *radeon_buffer; + uint32_t domain; + + radeon_buffer = calloc(1, sizeof(*radeon_buffer)); + if (radeon_buffer == NULL) { + return NULL; + } + radeon_buffer->base.refcount = 1; + radeon_buffer->base.alignment = alignment; + radeon_buffer->base.usage = usage; + radeon_buffer->base.size = size; + + domain = 0; + + if (usage & PIPE_BUFFER_USAGE_PIXEL) { + domain |= RADEON_GEM_DOMAIN_VRAM; + } + if (usage & PIPE_BUFFER_USAGE_VERTEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + + if (usage & PIPE_BUFFER_USAGE_INDEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + radeon_buffer->bo = radeon_bo_open(radeon_ws->radeon_screen->bom, 0, + size, alignment, domain, 0); + if (radeon_buffer->bo == NULL) { + free(radeon_buffer); + } + return &radeon_buffer->base; +} + +static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws, + void *ptr, + unsigned bytes) +{ + struct radeon_pipe_buffer *radeon_buffer; + + radeon_buffer = (struct radeon_pipe_buffer*)radeon_buffer_create(ws, 0, 0, bytes); + if (radeon_buffer == NULL) { + return NULL; + } + radeon_bo_map(radeon_buffer->bo, 1); + memcpy(radeon_buffer->bo->ptr, ptr, bytes); + radeon_bo_unmap(radeon_buffer->bo); + return &radeon_buffer->base; +} + +static void radeon_buffer_del(struct pipe_winsys *ws, struct pipe_buffer *buffer) +{ + struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; + + radeon_bo_unref(radeon_buffer->bo); + free(radeon_buffer); +} + +static void *radeon_buffer_map(struct pipe_winsys *ws, + struct pipe_buffer *buffer, + unsigned flags) +{ + struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; + int write = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) { + write = 1; + } + if (radeon_bo_map(radeon_buffer->bo, write)) + return NULL; + return radeon_buffer->bo->ptr; +} + +static void radeon_buffer_unmap(struct pipe_winsys *ws, struct pipe_buffer *buffer) +{ + struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; + + radeon_bo_unmap(radeon_buffer->bo); +} + +static void radeon_fence_reference(struct pipe_winsys *ws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *pfence) +{ +} + +static int radeon_fence_signalled(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, + unsigned flag) +{ + return 1; +} + +static int radeon_fence_finish(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, + unsigned flag) +{ + return 0; +} + +static void radeon_flush_frontbuffer(struct pipe_winsys *pipe_winsys, + struct pipe_surface *pipe_surface, + void *context_private) +{ + /* TODO: call dri2CopyRegion */ +} + +struct pipe_winsys *radeon_pipe_winsys(struct radeon_screen *radeon_screen) +{ + struct radeon_pipe_winsys *radeon_ws; + + radeon_ws = calloc(1, sizeof(struct radeon_pipe_winsys)); + if (radeon_ws == NULL) { + return NULL; + } + radeon_ws->radeon_screen = radeon_screen; + + radeon_ws->winsys.flush_frontbuffer = radeon_flush_frontbuffer; + + radeon_ws->winsys.buffer_create = radeon_buffer_create; + radeon_ws->winsys.buffer_destroy = radeon_buffer_del; + radeon_ws->winsys.user_buffer_create = radeon_buffer_user_create; + radeon_ws->winsys.buffer_map = radeon_buffer_map; + radeon_ws->winsys.buffer_unmap = radeon_buffer_unmap; + + radeon_ws->winsys.fence_reference = radeon_fence_reference; + radeon_ws->winsys.fence_signalled = radeon_fence_signalled; + radeon_ws->winsys.fence_finish = radeon_fence_finish; + + radeon_ws->winsys.get_name = radeon_get_name; + + return &radeon_ws->winsys; +} + +static struct pipe_buffer *radeon_buffer_from_handle(struct radeon_screen *radeon_screen, + uint32_t handle) +{ + struct radeon_pipe_buffer *radeon_buffer; + struct radeon_bo *bo = NULL; + + bo = radeon_bo_open(radeon_screen->bom, handle, 0, 0, 0, 0); + if (bo == NULL) { + return NULL; + } + radeon_buffer = calloc(1, sizeof(struct radeon_pipe_buffer)); + if (radeon_buffer == NULL) { + radeon_bo_unref(bo); + return NULL; + } + radeon_buffer->base.refcount = 1; + radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL; + radeon_buffer->bo = bo; + return &radeon_buffer->base; +} + +struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, + uint32_t handle, + enum pipe_format format, + int w, int h, int pitch) +{ + struct pipe_screen *pipe_screen = radeon_context->pipe_screen; + struct pipe_winsys *pipe_winsys = radeon_context->pipe_winsys; + struct pipe_texture tmpl; + struct pipe_surface *ps; + struct pipe_texture *pt; + struct pipe_buffer *pb; + + pb = radeon_buffer_from_handle(radeon_context->radeon_screen, handle); + if (pb == NULL) { + return NULL; + } + memset(&tmpl, 0, sizeof(tmpl)); + tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + tmpl.target = PIPE_TEXTURE_2D; + tmpl.width[0] = w; + tmpl.height[0] = h; + tmpl.depth[0] = 1; + tmpl.format = format; + pf_get_block(tmpl.format, &tmpl.block); + tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w); + tmpl.nblocksy[0] = pf_get_nblocksy(&tmpl.block, h); + + pt = pipe_screen->texture_blanket(pipe_screen, &tmpl, &pitch, pb); + if (pt == NULL) { + pipe_buffer_reference(pipe_screen, &pb, NULL); + } + ps = pipe_screen->get_tex_surface(pipe_screen, pt, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + return ps; +} diff --git a/src/gallium/winsys/drm/radeon/radeon_buffer.h b/src/gallium/winsys/drm/radeon/radeon_buffer.h new file mode 100644 index 0000000000..c626c20229 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_buffer.h @@ -0,0 +1,54 @@ +/* + * Copyright © 2008 Jérôme Glisse + * 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 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 THE COPYRIGHT HOLDERS, AUTHORS + * 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Jérôme Glisse <glisse@freedesktop.org> + */ +#ifndef RADEON_BUFFER_H +#define RADEON_BUFFER_H + +#include "pipe/internal/p_winsys_screen.h" +#include "radeon_screen.h" +#include "radeon_context.h" +#include "radeon_bo.h" + +struct radeon_pipe_buffer { + struct pipe_buffer base; + struct radeon_bo *bo; +}; + +struct radeon_pipe_winsys { + struct pipe_winsys winsys; + struct radeon_screen *radeon_screen; +}; + +struct pipe_winsys *radeon_pipe_winsys(struct radeon_screen *radeon_screen); +struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, + uint32_t handle, + enum pipe_format format, + int w, int h, int pitch); + +#endif diff --git a/src/gallium/winsys/drm/radeon/radeon_context.c b/src/gallium/winsys/drm/radeon/radeon_context.c new file mode 100644 index 0000000000..a9d1577634 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_context.c @@ -0,0 +1,306 @@ +/* + * Copyright © 2008 Jérôme Glisse + * 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 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 THE COPYRIGHT HOLDERS, AUTHORS + * 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Jérôme Glisse <glisse@freedesktop.org> + */ +#include <stdio.h> +#include "dri_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "radeon_screen.h" +#include "radeon_context.h" +#include "radeon_buffer.h" +#include "radeon_winsys_softpipe.h" + +#define need_GL_ARB_fragment_program +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_shader_objects +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_vertex_shader +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_compiled_vertex_array +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_VERSION_2_0 +#define need_GL_VERSION_2_1 +#include "extension_helper.h" + +/** + * Extension strings exported by the radeon driver. + */ +const struct dri_extension radeon_card_extensions[] = { + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_shader_objects", GL_ARB_shader_objects_functions}, + {"GL_ARB_shading_language_100", GL_VERSION_2_0_functions}, + {"GL_ARB_shading_language_120", GL_VERSION_2_1_functions}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {NULL, NULL} +}; + +static void radeon_update_renderbuffers(__DRIcontext *dri_context, + __DRIdrawable *dri_drawable) +{ + struct radeon_framebuffer *radeon_fb; + struct radeon_context *radeon_context; + unsigned attachments[10]; + __DRIbuffer *buffers; + __DRIscreen *screen; + int i, count; + + radeon_context = dri_context->driverPrivate; + screen = dri_drawable->driScreenPriv; + radeon_fb = dri_drawable->driverPrivate; + for (count = 0, i = 0; count < 6; count++) { + if (radeon_fb->attachments & (1 << count)) { + attachments[i++] = count; + } + } + + buffers = (*screen->dri2.loader->getBuffers)(dri_drawable, + &dri_drawable->w, + &dri_drawable->h, + attachments, + i, + &count, + dri_drawable->loaderPrivate); + if (buffers == NULL) { + return; + } + + /* set one cliprect to cover the whole dri_drawable */ + dri_drawable->x = 0; + dri_drawable->y = 0; + dri_drawable->backX = 0; + dri_drawable->backY = 0; + dri_drawable->numClipRects = 1; + dri_drawable->pClipRects[0].x1 = 0; + dri_drawable->pClipRects[0].y1 = 0; + dri_drawable->pClipRects[0].x2 = dri_drawable->w; + dri_drawable->pClipRects[0].y2 = dri_drawable->h; + dri_drawable->numBackClipRects = 1; + dri_drawable->pBackClipRects[0].x1 = 0; + dri_drawable->pBackClipRects[0].y1 = 0; + dri_drawable->pBackClipRects[0].x2 = dri_drawable->w; + dri_drawable->pBackClipRects[0].y2 = dri_drawable->h; + + for (i = 0; i < count; i++) { + struct pipe_surface *ps; + enum pipe_format format = 0; + int index = 0; + + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + index = ST_SURFACE_FRONT_LEFT; + switch (buffers[i].cpp) { + case 4: + format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case 2: + format = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + /* FIXME: error */ + return; + } + break; + case __DRI_BUFFER_BACK_LEFT: + index = ST_SURFACE_BACK_LEFT; + switch (buffers[i].cpp) { + case 4: + format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case 2: + format = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + /* FIXME: error */ + return; + } + break; + case __DRI_BUFFER_STENCIL: + case __DRI_BUFFER_DEPTH: + index = ST_SURFACE_DEPTH; + switch (buffers[i].cpp) { + case 4: + format = PIPE_FORMAT_Z24S8_UNORM; + break; + case 2: + format = PIPE_FORMAT_Z16_UNORM; + break; + default: + /* FIXME: error */ + return; + } + break; + case __DRI_BUFFER_ACCUM: + default: + fprintf(stderr, + "unhandled buffer attach event, attacment type %d\n", + buffers[i].attachment); + return; + } + + ps = radeon_surface_from_handle(radeon_context, + buffers[i].name, + format, + dri_drawable->w, + dri_drawable->h, + buffers[i].pitch); + assert(ps); + st_set_framebuffer_surface(radeon_fb->st_framebuffer, index, ps); + } + st_resize_framebuffer(radeon_fb->st_framebuffer, + dri_drawable->w, + dri_drawable->h); +} + +GLboolean radeon_context_create(const __GLcontextModes *visual, + __DRIcontextPrivate *dri_context, + void *shared_context) +{ + __DRIscreenPrivate *dri_screen; + struct radeon_context *radeon_context; + struct radeon_screen *radeon_screen; + struct pipe_context *pipe; + struct st_context *shared_st_context = NULL; + + dri_context->driverPrivate = NULL; + radeon_context = calloc(1, sizeof(struct radeon_context)); + if (radeon_context == NULL) { + return GL_FALSE; + } + + if (shared_context) { + shared_st_context = ((struct radeon_context*)shared_context)->st_context; + } + + dri_screen = dri_context->driScreenPriv; + radeon_screen = dri_screen->private; + radeon_context->dri_screen = dri_screen; + radeon_context->radeon_screen = radeon_screen; + radeon_context->drm_fd = dri_screen->fd; + + radeon_context->pipe_winsys = radeon_pipe_winsys(radeon_screen); + if (radeon_context->pipe_winsys == NULL) { + free(radeon_context); + return GL_FALSE; + } + + if (!getenv("RADEON_SOFTPIPE")) { + fprintf(stderr, "Creating r300 context...\n"); + pipe = + r300_create_context(NULL, + radeon_context->pipe_winsys, + radeon_create_r300_winsys(radeon_context->drm_fd)); + radeon_context->pipe_screen = pipe->screen; + } else { + pipe = radeon_create_softpipe(radeon_context); + } + radeon_context->st_context = st_create_context(pipe, visual, + shared_st_context); + driInitExtensions(radeon_context->st_context->ctx, + radeon_card_extensions, GL_TRUE); + dri_context->driverPrivate = radeon_context; + return GL_TRUE; +} + +void radeon_context_destroy(__DRIcontextPrivate *dri_context) +{ + struct radeon_context *radeon_context; + + radeon_context = dri_context->driverPrivate; + st_finish(radeon_context->st_context); + st_destroy_context(radeon_context->st_context); + free(radeon_context); +} + +GLboolean radeon_context_bind(__DRIcontextPrivate *dri_context, + __DRIdrawablePrivate *dri_drawable, + __DRIdrawablePrivate *dri_readable) +{ + struct radeon_framebuffer *drawable; + struct radeon_framebuffer *readable; + struct radeon_context *radeon_context; + + if (dri_context == NULL) { + st_make_current(NULL, NULL, NULL); + return GL_TRUE; + } + + radeon_context = dri_context->driverPrivate; + drawable = dri_drawable->driverPrivate; + readable = dri_readable->driverPrivate; + st_make_current(radeon_context->st_context, + drawable->st_framebuffer, + readable->st_framebuffer); + + radeon_update_renderbuffers(dri_context, dri_drawable); + if (dri_drawable != dri_readable) { + radeon_update_renderbuffers(dri_context, dri_readable); + } + return GL_TRUE; +} + +GLboolean radeon_context_unbind(__DRIcontextPrivate *dri_context) +{ + struct radeon_context *radeon_context; + + radeon_context = dri_context->driverPrivate; + st_flush(radeon_context->st_context, PIPE_FLUSH_RENDER_CACHE, NULL); + return GL_TRUE; +} diff --git a/src/gallium/winsys/drm/radeon/radeon_context.h b/src/gallium/winsys/drm/radeon/radeon_context.h new file mode 100644 index 0000000000..d7222b4469 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_context.h @@ -0,0 +1,70 @@ +/* + * Copyright © 2008 Jérôme Glisse + * 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 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 THE COPYRIGHT HOLDERS, AUTHORS + * 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Jérôme Glisse <glisse@freedesktop.org> + */ +#ifndef RADEON_CONTEXT_H +#define RADEON_CONTEXT_H + +#include "dri_util.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "radeon_screen.h" + +#include "radeon_r300.h" + +struct radeon_framebuffer { + struct st_framebuffer *st_framebuffer; + unsigned attachments; +}; + +struct radeon_context { + /* st */ + struct st_context *st_context; + /* pipe */ + struct pipe_screen *pipe_screen; + struct pipe_winsys *pipe_winsys; + /* DRI */ + __DRIscreenPrivate *dri_screen; + __DRIdrawablePrivate *dri_drawable; + __DRIdrawablePrivate *dri_readable; + /* DRM */ + int drm_fd; + /* RADEON */ + struct radeon_screen *radeon_screen; +}; + +GLboolean radeon_context_create(const __GLcontextModes*, + __DRIcontextPrivate*, + void*); +void radeon_context_destroy(__DRIcontextPrivate*); +GLboolean radeon_context_bind(__DRIcontextPrivate*, + __DRIdrawablePrivate*, + __DRIdrawablePrivate*); +GLboolean radeon_context_unbind(__DRIcontextPrivate*); + +#endif diff --git a/src/gallium/winsys/drm/radeon/radeon_r300.c b/src/gallium/winsys/drm/radeon/radeon_r300.c new file mode 100644 index 0000000000..8fe2375e34 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_r300.c @@ -0,0 +1,96 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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_r300.h" + +static boolean radeon_r300_check_cs(struct radeon_cs* cs, int size) +{ + /* XXX check size here, lazy ass! */ + return TRUE; +} + +static void radeon_r300_write_cs_reloc(struct radeon_cs* cs, + struct pipe_buffer* pbuffer, + uint32_t rd, + uint32_t wd, + uint32_t flags) +{ + radeon_cs_write_reloc(cs, ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags); +} + +static void radeon_r300_flush_cs(struct radeon_cs* cs) +{ + radeon_cs_emit(cs); + radeon_cs_erase(cs); +} + +/* Helper function to do the ioctls needed for setup and init. */ +static void do_ioctls(struct r300_winsys* winsys, int fd) +{ + drm_radeon_getparam_t gp; + uint32_t target; + int retval; + + /* XXX is this cast safe? */ + gp.value = (int*)⌖ + + /* First, get PCI ID */ + gp.param = RADEON_PARAM_DEVICE_ID; + retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); + if (retval) { + fprintf(stderr, "%s: Failed to get PCI ID, error number %d", + __FUNCTION__, retval); + exit(1); + } + winsys->pci_id = target; + + /* Then, get the number of pixel pipes */ + gp.param = RADEON_PARAM_NUM_GB_PIPES; + retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); + if (retval) { + fprintf(stderr, "%s: Failed to get GB pipe count, error number %d", + __FUNCTION__, retval); + exit(1); + } + winsys->gb_pipes = target; + +} + +struct r300_winsys* radeon_create_r300_winsys(int fd) +{ + struct r300_winsys* winsys = calloc(1, sizeof(struct r300_winsys)); + + do_ioctls(winsys, fd); + + struct radeon_cs_manager* csm = radeon_cs_manager_gem_ctor(fd); + + winsys->cs = radeon_cs_create(csm, 1024 * 64 / 4); + + winsys->check_cs = radeon_r300_check_cs; + winsys->begin_cs = radeon_cs_begin; + winsys->write_cs_dword = radeon_cs_write_dword; + winsys->write_cs_reloc = radeon_r300_write_cs_reloc; + winsys->end_cs = radeon_cs_end; + winsys->flush_cs = radeon_r300_flush_cs; + + return winsys; +} diff --git a/src/gallium/winsys/drm/radeon/radeon_r300.h b/src/gallium/winsys/drm/radeon/radeon_r300.h new file mode 100644 index 0000000000..8ed95a3a9b --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_r300.h @@ -0,0 +1,34 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * + * 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 + * on 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 + * THE AUTHOR(S) AND/OR THEIR 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. */ + +/* XXX WTF is this! I shouldn't have to include those first three! FUCK! */ +#include <stdint.h> +#include <stdlib.h> +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_cs.h" + +#include "r300_winsys.h" + +#include "radeon_buffer.h" + +struct r300_winsys* radeon_create_r300_winsys(int fd); diff --git a/src/gallium/winsys/drm/radeon/radeon_screen.c b/src/gallium/winsys/drm/radeon/radeon_screen.c new file mode 100644 index 0000000000..e31caff0bf --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_screen.c @@ -0,0 +1,288 @@ +/* + * Copyright © 2008 Jérôme Glisse + * 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 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 THE COPYRIGHT HOLDERS, AUTHORS + * 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Jérôme Glisse <glisse@freedesktop.org> + */ +#include <stdio.h> +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "utils.h" +#include "xf86drm.h" +#include "drm.h" +#include "dri_util.h" +#include "radeon_screen.h" +#include "radeon_context.h" +#include "radeon_buffer.h" +#include "radeon_bo.h" +#include "radeon_bo_gem.h" +#include "radeon_drm.h" + +extern const struct dri_extension radeon_card_extensions[]; + +static const __DRIextension *radeon_screen_extensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + NULL +}; + +static __DRIconfig **radeon_fill_in_modes(unsigned pixel_bits, + unsigned depth_bits, + GLboolean have_back_buffer) +{ + __DRIconfig **configs; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + unsigned num_modes; + GLenum fb_format; + GLenum fb_type; + uint8_t depth_bits_array[3]; + uint8_t stencil_bits_array[3]; + uint8_t msaa_samples_array[1]; + /* TODO: pageflipping ? */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + stencil_bits_array[0] = 0; + stencil_bits_array[1] = 0; + if (depth_bits == 24) { + stencil_bits_array[2] = 8; + num_modes = 3; + } + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + depth_bits_array[2] = depth_bits; + depth_buffer_factor = (depth_bits == 24) ? 3 : 2; + + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + msaa_samples_array[0] = 0; + + if (pixel_bits == 16) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } else { + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + configs = (__DRIconfig **)driCreateConfigs(fb_format, + fb_type, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + msaa_samples_array, + 1); + if (configs == NULL) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", + __FILE__, __LINE__); + return NULL; + } + return configs; +} + +static void radeon_screen_destroy(__DRIscreenPrivate *dri_screen) +{ + struct radeon_screen *radeon_screen = (struct radeon_screen*)dri_screen->private; + + radeon_bo_manager_gem_dtor(radeon_screen->bom); + dri_screen = NULL; + free(radeon_screen); +} + +static const __DRIconfig **radeon_screen_init(__DRIscreenPrivate *dri_screen) +{ + struct radeon_screen *radeon_screen; + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, radeon_card_extensions, GL_FALSE); + + radeon_screen = calloc(1, sizeof(struct radeon_screen)); + if (radeon_screen == NULL) { + fprintf(stderr, "\nERROR! Allocating private area failed\n"); + return NULL; + } + dri_screen->private = (void*)radeon_screen; + dri_screen->extensions = radeon_screen_extensions; + radeon_screen->dri_screen = dri_screen; + + radeon_screen->bom = radeon_bo_manager_gem_ctor(dri_screen->fd); + if (radeon_screen->bom == NULL) { + radeon_screen_destroy(dri_screen); + return NULL; + } + + return driConcatConfigs(radeon_fill_in_modes(16, 16, 1), + radeon_fill_in_modes(32, 24, 1)); +} + +static boolean radeon_buffer_create(__DRIscreenPrivate *dri_screen, + __DRIdrawablePrivate *dri_drawable, + const __GLcontextModes *visual, + boolean is_pixmap) +{ + if (is_pixmap) { + /* TODO: implement ? */ + return GL_FALSE; + } else { + enum pipe_format color_format, depth_format, stencil_format; + struct radeon_framebuffer *radeon_fb; + + radeon_fb = calloc(1, sizeof(struct radeon_framebuffer)); + if (radeon_fb == NULL) { + return GL_FALSE; + } + + switch (visual->redBits) { + case 5: + color_format = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + color_format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + } + + switch (visual->depthBits) { + case 24: + depth_format = PIPE_FORMAT_S8Z24_UNORM; + break; + case 16: + depth_format = PIPE_FORMAT_Z16_UNORM; + break; + default: + depth_format = PIPE_FORMAT_NONE; + break; + } + + switch (visual->stencilBits) { + case 8: + /* force depth format */ + depth_format = PIPE_FORMAT_S8Z24_UNORM; + stencil_format = PIPE_FORMAT_S8Z24_UNORM; + break; + default: + stencil_format = PIPE_FORMAT_NONE; + break; + } + + radeon_fb->st_framebuffer = st_create_framebuffer(visual, + color_format, + depth_format, + stencil_format, + dri_drawable->w, + dri_drawable->h, + (void*)radeon_fb); + if (radeon_fb->st_framebuffer == NULL) { + free(radeon_fb); + return GL_FALSE; + } + dri_drawable->driverPrivate = (void *) radeon_fb; + + radeon_fb->attachments = (1 << __DRI_BUFFER_FRONT_LEFT); + if (visual->doubleBufferMode) { + radeon_fb->attachments |= (1 << __DRI_BUFFER_BACK_LEFT); + } + if (visual->depthBits || visual->stencilBits) { + radeon_fb->attachments |= (1 << __DRI_BUFFER_DEPTH); + } + + return GL_TRUE; + } +} + +static void radeon_buffer_destroy(__DRIdrawablePrivate * dri_drawable) +{ + struct radeon_framebuffer *radeon_fb; + + radeon_fb = dri_drawable->driverPrivate; + assert(radeon_fb->st_framebuffer); + st_unreference_framebuffer(radeon_fb->st_framebuffer); + free(radeon_fb); +} + +static void radeon_swap_buffers(__DRIdrawablePrivate *dri_drawable) +{ + struct radeon_framebuffer *radeon_fb; + struct pipe_surface *back_surf = NULL; + + radeon_fb = dri_drawable->driverPrivate; + assert(radeon_fb); + assert(radeon_fb->st_framebuffer); + + st_get_framebuffer_surface(radeon_fb->st_framebuffer, + ST_SURFACE_BACK_LEFT, + &back_surf); + if (back_surf) { + st_notify_swapbuffers(radeon_fb->st_framebuffer); + /* TODO: do we want to do anythings ? */ + st_notify_swapbuffers_complete(radeon_fb->st_framebuffer); + } +} + +/** + * Called via glXCopySubBufferMESA() to copy a subrect of the back + * buffer to the front buffer/screen. + */ +static void radeon_copy_sub_buffer(__DRIdrawablePrivate *dri_drawable, + int x, int y, int w, int h) +{ + /* TODO: ... */ +} + +const struct __DriverAPIRec driDriverAPI = { + .InitScreen = NULL, + .DestroyScreen = radeon_screen_destroy, + .CreateContext = radeon_context_create, + .DestroyContext = radeon_context_destroy, + .CreateBuffer = radeon_buffer_create, + .DestroyBuffer = radeon_buffer_destroy, + .SwapBuffers = radeon_swap_buffers, + .MakeCurrent = radeon_context_bind, + .UnbindContext = radeon_context_unbind, + .CopySubBuffer = radeon_copy_sub_buffer, + .InitScreen2 = radeon_screen_init, +}; diff --git a/src/gallium/winsys/drm/radeon/radeon_screen.h b/src/gallium/winsys/drm/radeon/radeon_screen.h new file mode 100644 index 0000000000..01b7fa6531 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_screen.h @@ -0,0 +1,41 @@ +/* + * Copyright © 2008 Jérôme Glisse + * 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 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 THE COPYRIGHT HOLDERS, AUTHORS + * 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Jérôme Glisse <glisse@freedesktop.org> + */ +#ifndef RADEON_SCREEN_H +#define RADEON_SCREEN_H + +#include "dri_util.h" +#include "radeon_bo.h" + +struct radeon_screen { + __DRIscreenPrivate *dri_screen; + struct radeon_bo_manager *bom; +}; + +#endif diff --git a/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.c b/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.c new file mode 100644 index 0000000000..8402e1fa5a --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.c @@ -0,0 +1,77 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com> + */ +#include <stdio.h> +#include "imports.h" +#include "pipe/p_defines.h" +#include "pipe/p_format.h" +#include "softpipe/sp_winsys.h" +#include "radeon_context.h" +#include "radeon_winsys_softpipe.h" + +struct radeon_softpipe_winsys { + struct softpipe_winsys sp_winsys; + struct radeon_context *radeon_context; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean radeon_is_format_supported(struct softpipe_winsys *sws, uint format) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + }; + return FALSE; +} + +struct pipe_context *radeon_create_softpipe(struct radeon_context *radeon_context) +{ + struct radeon_softpipe_winsys *radeon_sp_ws; + struct pipe_screen *pipe_screen; + + pipe_screen = softpipe_create_screen(radeon_context->pipe_winsys); + + radeon_sp_ws = CALLOC_STRUCT(radeon_softpipe_winsys); + if (radeon_sp_ws == NULL) { + return NULL; + } + radeon_context->pipe_screen = pipe_screen; + radeon_sp_ws->radeon_context = radeon_context; + radeon_sp_ws->sp_winsys.is_format_supported = radeon_is_format_supported; + return softpipe_create(pipe_screen, + radeon_context->pipe_winsys, + &radeon_sp_ws->sp_winsys); +} diff --git a/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.h b/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.h new file mode 100644 index 0000000000..519eab769c --- /dev/null +++ b/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.h @@ -0,0 +1,37 @@ +/* + * Copyright © 2008 Jérôme Glisse + * 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 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 THE COPYRIGHT HOLDERS, AUTHORS + * 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Jérôme Glisse <glisse@freedesktop.org> + */ +#ifndef RADEON_WINSYS_SOFTPIPE_H +#define RADEON_WINSYS_SOFTPIPE_H + +#include "radeon_context.h" + +struct pipe_context *radeon_create_softpipe(struct radeon_context *radeon_context); + +#endif |