diff options
Diffstat (limited to 'src/gallium/drivers/r300')
41 files changed, 2319 insertions, 2291 deletions
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index e44f9b9dfc..d7a2c8c462 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -4,21 +4,38 @@ include $(TOP)/configs/current  LIBNAME = r300  C_SOURCES = \ +	r3xx_fs.c \ +	r5xx_fs.c \  	r300_chipset.c \  	r300_clear.c \  	r300_context.c \ -	r300_debug.c \  	r300_emit.c \  	r300_flush.c \ +	r300_fs.c \  	r300_query.c \  	r300_render.c \  	r300_screen.c \  	r300_state.c \  	r300_state_derived.c \  	r300_state_invariant.c \ -	r300_state_shader.c \ -	r300_state_tcl.c \ +	r300_vs.c \  	r300_surface.c \ -	r300_texture.c +	r300_texture.c \ +	r300_tgsi_to_rc.c + +LIBRARY_INCLUDES = \ +	-I$(TOP)/src/mesa/drivers/dri/r300/compiler \ +	-I$(TOP)/src/mesa \ +	-I$(TOP)/include + +COMPILER_ARCHIVE = $(TOP)/src/mesa/drivers/dri/r300/compiler/libr300compiler.a + +EXTRA_OBJECTS = \ +	$(COMPILER_ARCHIVE)  include ../../Makefile.template + +.PHONY : $(COMPILER_ARCHIVE) + +$(COMPILER_ARCHIVE): +	cd $(TOP)/src/mesa/drivers/dri/r300/compiler; make diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript index 182ed2d459..493d7b28bc 100644 --- a/src/gallium/drivers/r300/SConscript +++ b/src/gallium/drivers/r300/SConscript @@ -5,20 +5,22 @@ env = env.Clone()  r300 = env.ConvenienceLibrary(      target = 'r300',      source = [ +        'r3xx_fs.c', +        'r5xx_fs.c',          'r300_chipset.c',          'r300_clear.c',          'r300_context.c',          'r300_debug.c',          'r300_emit.c',          'r300_flush.c', +        'r300_fs.c',          'r300_query.c',          'r300_render.c',          'r300_screen.c',          'r300_state.c',          'r300_state_derived.c',          'r300_state_invariant.c', -        'r300_state_shader.c', -        'r300_state_tcl.c', +        'r300_vs.c',          'r300_surface.c',          'r300_texture.c',      ]) diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c index 9d95ad918c..d138866d33 100644 --- a/src/gallium/drivers/r300/r300_chipset.c +++ b/src/gallium/drivers/r300/r300_chipset.c @@ -30,9 +30,10 @@  void r300_parse_chipset(struct r300_capabilities* caps)  {      /* Reasonable defaults */ +    caps->num_vert_fpus = 4;      caps->has_tcl = getenv("RADEON_NO_TCL") ? FALSE : TRUE;      caps->is_r500 = FALSE; -    caps->num_vert_fpus = 4; +    caps->high_second_pipe = FALSE;      /* Note: These are not ordered by PCI ID. I leave that task to GCC, @@ -41,6 +42,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)      switch (caps->pci_id) {          case 0x4144:              caps->family = CHIP_FAMILY_R300; +            caps->high_second_pipe = TRUE;              break;          case 0x4145: @@ -51,6 +53,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)          case 0x4E46:          case 0x4E47:              caps->family = CHIP_FAMILY_R300; +            caps->high_second_pipe = TRUE;              break;          case 0x4150: @@ -67,6 +70,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)          case 0x4E54:          case 0x4E56:              caps->family = CHIP_FAMILY_RV350; +            caps->high_second_pipe = TRUE;              break;          case 0x4148: @@ -77,10 +81,12 @@ void r300_parse_chipset(struct r300_capabilities* caps)          case 0x4E49:          case 0x4E4B:              caps->family = CHIP_FAMILY_R350; +            caps->high_second_pipe = TRUE;              break;          case 0x4E4A:              caps->family = CHIP_FAMILY_R360; +            caps->high_second_pipe = TRUE;              break;          case 0x5460: @@ -92,6 +98,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)          case 0x5B64:          case 0x5B65:              caps->family = CHIP_FAMILY_RV370; +            caps->high_second_pipe = TRUE;              break;          case 0x3150: @@ -100,6 +107,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)          case 0x3E50:          case 0x3E54:              caps->family = CHIP_FAMILY_RV380; +            caps->high_second_pipe = TRUE;              break;          case 0x4A48: @@ -150,6 +158,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)              caps->num_vert_fpus = 6;              break; +        case 0x4B48:          case 0x4B49:          case 0x4B4A:          case 0x4B4B: @@ -349,7 +358,4 @@ void r300_parse_chipset(struct r300_capabilities* caps)                  caps->pci_id);              break;      } - -    /* XXX SW TCL is broken so no forcing it off right now -    caps->has_tcl = FALSE; */  } diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h index 21eebeae60..322d4a57e4 100644 --- a/src/gallium/drivers/r300/r300_chipset.h +++ b/src/gallium/drivers/r300/r300_chipset.h @@ -44,6 +44,8 @@ struct r300_capabilities {       * - Blend color is split across two registers       * - Universal Shader (US) block used for fragment shaders */      boolean is_r500; +    /* Whether or not the second pixel pipe is accessed with the high bit */ +    boolean high_second_pipe;  };  /* Enumerations for legibility and telling which card we're running on. */ diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 6bdf544a05..da67bc29b8 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -34,10 +34,6 @@ static boolean r300_draw_range_elements(struct pipe_context* pipe,      struct r300_context* r300 = r300_context(pipe);      int i; -    if (r300->dirty_state) { -        r300_emit_dirty_state(r300); -    } -      for (i = 0; i < r300->vertex_buffer_count; i++) {          void* buf = pipe_buffer_map(pipe->screen,                                      r300->vertex_buffers[i].buffer, @@ -56,7 +52,7 @@ static boolean r300_draw_range_elements(struct pipe_context* pipe,      draw_set_mapped_constant_buffer(r300->draw,              r300->shader_constants[PIPE_SHADER_VERTEX].constants, -            r300->shader_constants[PIPE_SHADER_VERTEX].user_count * +            r300->shader_constants[PIPE_SHADER_VERTEX].count *                  (sizeof(float) * 4));      draw_arrays(r300->draw, mode, start, count); @@ -92,9 +88,21 @@ static boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,  static void r300_destroy_context(struct pipe_context* context) {      struct r300_context* r300 = r300_context(context); +    struct r300_query* query, * temp;      draw_destroy(r300->draw); +    /* Free the OQ BO. */ +    context->screen->buffer_destroy(r300->oqbo); + +    /* If there are any queries pending or not destroyed, remove them now. */ +    if (r300->query_list) { +        foreach_s(query, temp, r300->query_list) { +            remove_from_list(query); +            FREE(query); +        } +    } +      FREE(r300->blend_color_state);      FREE(r300->rs_block);      FREE(r300->scissor_state); @@ -133,7 +141,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,      if (!r300)          return NULL; -    /* XXX this could be refactored now? */      r300->winsys = r300_winsys;      r300->context.winsys = (struct pipe_winsys*)r300_winsys; @@ -150,14 +157,25 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,      r300->context.is_texture_referenced = r300_is_texture_referenced;      r300->context.is_buffer_referenced = r300_is_buffer_referenced; -    r300->draw = draw_create(); -    draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300)); -      r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state);      r300->rs_block = CALLOC_STRUCT(r300_rs_block);      r300->scissor_state = CALLOC_STRUCT(r300_scissor_state);      r300->viewport_state = CALLOC_STRUCT(r300_viewport_state); +    /* Create a Draw. This is used for vert collation and SW TCL. */ +    r300->draw = draw_create(); +    /* Enable our renderer. */ +    draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300)); +    /* Disable Draw's clipping if TCL is present. */ +    draw_set_driver_clipping(r300->draw, r300_screen(screen)->caps->has_tcl); +    /* Force Draw to never do viewport transform, since (again) we can do +     * transform in hardware, always. */ +    draw_set_viewport_state(r300->draw, &r300_viewport_identity); + +    /* Open up the OQ BO. */ +    r300->oqbo = screen->buffer_create(screen, 4096, +            PIPE_BUFFER_USAGE_VERTEX, 4096); +      r300_init_flush_functions(r300);      r300_init_query_functions(r300); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 6f62998b35..f78492d4aa 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -25,15 +25,22 @@  #include "draw/draw_context.h"  #include "draw/draw_vertex.h" +  #include "pipe/p_context.h" +  #include "tgsi/tgsi_scan.h" +  #include "util/u_memory.h" +#include "util/u_simple_list.h"  #include "r300_clear.h"  #include "r300_query.h"  #include "r300_screen.h"  #include "r300_winsys.h" +struct r300_fragment_shader; +struct r300_vertex_shader; +  struct r300_blend_state {      uint32_t blend_control;       /* R300_RB3D_CBLEND: 0x4e04 */      uint32_t alpha_blend_control; /* R300_RB3D_ABLEND: 0x4e08 */ @@ -63,6 +70,11 @@ struct r300_rs_state {      /* Draw-specific rasterizer state */      struct pipe_rasterizer_state rs; +    /* Whether or not to enable the VTE. This is referenced at the very +     * last moment during emission of VTE state, to decide whether or not +     * the VTE should be used for transformation. */ +    boolean enable_vte; +      uint32_t vap_control_status;    /* R300_VAP_CNTL_STATUS: 0x2140 */      uint32_t point_size;            /* R300_GA_POINT_SIZE: 0x421c */      uint32_t point_minmax;          /* R300_GA_POINT_MINMAX: 0x4230 */ @@ -112,23 +124,24 @@ struct r300_viewport_state {      uint32_t vte_control; /* R300_VAP_VTE_CNTL:      0x20b0 */  }; -#define R300_NEW_BLEND           0x0000001 -#define R300_NEW_BLEND_COLOR     0x0000002 -#define R300_NEW_CONSTANTS       0x0000004 -#define R300_NEW_DSA             0x0000008 -#define R300_NEW_FRAMEBUFFERS    0x0000010 -#define R300_NEW_FRAGMENT_SHADER 0x0000020 -#define R300_NEW_RASTERIZER      0x0000040 -#define R300_NEW_RS_BLOCK        0x0000080 -#define R300_NEW_SAMPLER         0x0000100 -#define R300_ANY_NEW_SAMPLERS    0x000ff00 -#define R300_NEW_SCISSOR         0x0010000 -#define R300_NEW_TEXTURE         0x0020000 -#define R300_ANY_NEW_TEXTURES    0x1fe0000 -#define R300_NEW_VERTEX_FORMAT   0x2000000 -#define R300_NEW_VERTEX_SHADER   0x4000000 -#define R300_NEW_VIEWPORT        0x8000000 -#define R300_NEW_KITCHEN_SINK    0xfffffff +#define R300_NEW_BLEND           0x00000001 +#define R300_NEW_BLEND_COLOR     0x00000002 +#define R300_NEW_CLIP            0x00000004 +#define R300_NEW_CONSTANTS       0x00000008 +#define R300_NEW_DSA             0x00000010 +#define R300_NEW_FRAMEBUFFERS    0x00000020 +#define R300_NEW_FRAGMENT_SHADER 0x00000040 +#define R300_NEW_RASTERIZER      0x00000080 +#define R300_NEW_RS_BLOCK        0x00000100 +#define R300_NEW_SAMPLER         0x00000200 +#define R300_ANY_NEW_SAMPLERS    0x0001fe00 +#define R300_NEW_SCISSOR         0x00020000 +#define R300_NEW_TEXTURE         0x00040000 +#define R300_ANY_NEW_TEXTURES    0x03fc0000 +#define R300_NEW_VERTEX_FORMAT   0x04000000 +#define R300_NEW_VERTEX_SHADER   0x08000000 +#define R300_NEW_VIEWPORT        0x10000000 +#define R300_NEW_KITCHEN_SINK    0x1fffffff  /* The next several objects are not pure Radeon state; they inherit from   * various Gallium classes. */ @@ -136,66 +149,32 @@ struct r300_viewport_state {  struct r300_constant_buffer {      /* Buffer of constants */      /* XXX first number should be raised */ -    float constants[8][4]; -    /* Number of user-defined constants */ -    int user_count; +    float constants[32][4];      /* Total number of constants */ -    int count; -}; - -struct r3xx_fragment_shader { -    /* Parent class */ -    struct pipe_shader_state state; -    struct tgsi_shader_info info; - -    /* Has this shader been translated yet? */ -    boolean translated; - -    /* Pixel stack size */ -    int stack_size; -}; - -struct r300_fragment_shader { -    /* Parent class */ -    struct r3xx_fragment_shader shader; - -    /* Number of ALU instructions */ -    int alu_instruction_count; - -    /* Number of texture instructions */ -    int tex_instruction_count; - -    /* Number of texture indirections */ -    int indirections; - -    /* Indirection node offsets */ -    int alu_offset[4]; - -    /* Machine instructions */ -    struct { -        uint32_t alu_rgb_inst; -        uint32_t alu_rgb_addr; -        uint32_t alu_alpha_inst; -        uint32_t alu_alpha_addr; -    } instructions[64]; /* XXX magic num */ +    unsigned count;  }; -struct r500_fragment_shader { -    /* Parent class */ -    struct r3xx_fragment_shader shader; - -    /* Number of used instructions */ -    int instruction_count; - -    /* Machine instructions */ -    struct { -        uint32_t inst0; -        uint32_t inst1; -        uint32_t inst2; -        uint32_t inst3; -        uint32_t inst4; -        uint32_t inst5; -    } instructions[256]; /*< XXX magic number */ +/* Query object. + * + * This is not a subclass of pipe_query because pipe_query is never + * actually fully defined. So, rather than have it as a member, and do + * subclass-style casting, we treat pipe_query as an opaque, and just + * trust that our state tracker does not ever mess up query objects. + */ +struct r300_query { +    /* The kind of query. Currently only OQ is supported. */ +    unsigned type; +    /* Whether this query is currently active. Only active queries will +     * get emitted into the command stream, and only active queries get +     * tallied. */ +    boolean active; +    /* The current count of this query. Required to be at least 32 bits. */ +    unsigned int count; +    /* The offset of this query into the query buffer, in bytes. */ +    unsigned offset; +    /* Linked list members. */ +    struct r300_query* prev; +    struct r300_query* next;  };  struct r300_texture { @@ -207,7 +186,7 @@ struct r300_texture {      /* Stride (pitch?) of this texture in bytes */      unsigned stride; -     +      /* Total size of this texture, in bytes. */      unsigned size; @@ -232,27 +211,9 @@ struct r300_vertex_format {      int fs_tab[16];  }; -struct r300_vertex_shader { -    /* Parent class */ -    struct pipe_shader_state state; -    struct tgsi_shader_info info; - -    /* Fallback shader, because Draw has issues */ -    struct draw_vertex_shader* draw; - -    /* Has this shader been translated yet? */ -    boolean translated; - -    /* Number of used instructions */ -    int instruction_count; - -    /* Machine instructions */ -    struct { -        uint32_t inst0; -        uint32_t inst1; -        uint32_t inst2; -        uint32_t inst3; -    } instructions[128]; /*< XXX magic number */ +static struct pipe_viewport_state r300_viewport_identity = { +    .scale = {1.0, 1.0, 1.0, 1.0}, +    .translate = {0.0, 0.0, 0.0, 0.0},  };  struct r300_context { @@ -264,17 +225,29 @@ struct r300_context {      /* Draw module. Used mostly for SW TCL. */      struct draw_context* draw; +    /* Vertex buffer for rendering. */ +    struct pipe_buffer* vbo; +    /* Offset into the VBO. */ +    size_t vbo_offset; + +    /* Occlusion query buffer. */ +    struct pipe_buffer* oqbo; +    /* Query list. */ +    struct r300_query* query_list; +      /* Various CSO state objects. */      /* Blend state. */      struct r300_blend_state* blend_state;      /* Blend color state. */      struct r300_blend_color_state* blend_color_state; +    /* User clip planes. */ +    struct pipe_clip_state clip_state;      /* Shader constants. */      struct r300_constant_buffer shader_constants[PIPE_SHADER_TYPES];      /* Depth, stencil, and alpha state. */      struct r300_dsa_state* dsa_state;      /* Fragment shader. */ -    struct r3xx_fragment_shader* fs; +    struct r300_fragment_shader* fs;      /* Framebuffer state. We currently don't need our own version of this. */      struct pipe_framebuffer_state framebuffer_state;      /* Rasterizer state. */ @@ -289,7 +262,7 @@ struct r300_context {      /* Texture states. */      struct r300_texture* textures[8];      int texture_count; -    /* Vertex buffers. */ +    /* Vertex buffers for Gallium. */      struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];      int vertex_buffer_count;      /* Vertex information. */ @@ -305,7 +278,8 @@ struct r300_context {  };  /* Convenience cast wrapper. */ -static struct r300_context* r300_context(struct pipe_context* context) { +static INLINE struct r300_context* r300_context(struct pipe_context* context) +{      return (struct r300_context*)context;  } diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index 82a3942248..71b142c0db 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -34,6 +34,7 @@  #define MAX_CS_SIZE 64 * 1024 / 4 +#define VERY_VERBOSE_CS 0  #define VERY_VERBOSE_REGISTERS 0  /* XXX stolen from radeon_drm.h */ @@ -56,8 +57,10 @@  #define BEGIN_CS(size) do { \      CHECK_CS(size); \ -    debug_printf("r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \ -        size, __FUNCTION__, __FILE__, __LINE__); \ +    if (VERY_VERBOSE_CS) { \ +        debug_printf("r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \ +                size, __FUNCTION__, __FILE__, __LINE__); \ +    } \      cs_winsys->begin_cs(cs_winsys, (size), \              __FILE__, __FUNCTION__, __LINE__); \      cs_count = size; \ @@ -93,8 +96,9 @@  } 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); \ +    debug_printf("r300: writing relocation for buffer %p, offset %d, " \ +            "domains (%d, %d, %d)\n", \ +        bo, offset, rd, wd, flags); \      assert(bo); \      OUT_CS(offset); \      cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ @@ -102,16 +106,20 @@  } while (0)  #define END_CS do { \ -    debug_printf("r300: END_CS in %s (%s:%d)\n", __FUNCTION__, __FILE__, \ -        __LINE__); \ +    if (VERY_VERBOSE_CS) { \ +        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_winsys, __FILE__, __FUNCTION__, __LINE__); \  } while (0)  #define FLUSH_CS do { \ -    debug_printf("r300: FLUSH_CS in %s (%s:%d)\n\n", __FUNCTION__, __FILE__, \ -        __LINE__); \ +    if (VERY_VERBOSE_CS) { \ +        debug_printf("r300: FLUSH_CS in %s (%s:%d)\n\n", __FUNCTION__, \ +                __FILE__, __LINE__); \ +    } \      cs_winsys->flush_cs(cs_winsys); \  } while (0) diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c deleted file mode 100644 index dd63136c9d..0000000000 --- a/src/gallium/drivers/r300/r300_debug.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2009 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_debug.h" - -static void r300_dump_fs(struct r300_fragment_shader* fs) -{ -    int i; - -    for (i = 0; i < fs->alu_instruction_count; i++) { -    } -} - -static char* r500_fs_swiz[] = { -    " R", -    " G", -    " B", -    " A", -    " 0", -    ".5", -    " 1", -    " U", -}; - -static char* r500_fs_op_rgb[] = { -    "MAD", -    "DP3", -    "DP4", -    "D2A", -    "MIN", -    "MAX", -    "---", -    "CND", -    "CMP", -    "FRC", -    "SOP", -    "MDH", -    "MDV", -}; - -static char* r500_fs_op_alpha[] = { -    "MAD", -    " DP", -    "MIN", -    "MAX", -    "---", -    "CND", -    "CMP", -    "FRC", -    "EX2", -    "LN2", -    "RCP", -    "RSQ", -    "SIN", -    "COS", -    "MDH", -    "MDV", -}; - -static char* r500_fs_mask[] = { -    "NONE", -    "R   ", -    " G  ", -    "RG  ", -    "  B ", -    "R B ", -    " GB ", -    "RGB ", -    "   A", -    "R  A", -    " G A", -    "RG A", -    "  BA", -    "R BA", -    " GBA", -    "RGBA", -}; - -static char* r500_fs_tex[] = { -    "    NOP", -    "     LD", -    "TEXKILL", -    "   PROJ", -    "LODBIAS", -    "    LOD", -    "   DXDY", -}; - -void r500_fs_dump(struct r500_fragment_shader* fs) -{ -    int i; -    uint32_t inst; - -    for (i = 0; i < fs->instruction_count; i++) { -        inst = fs->instructions[i].inst0; -        debug_printf("%d:  0: CMN_INST   0x%08x:", i, inst); -        switch (inst & 0x3) { -            case R500_INST_TYPE_ALU: -                debug_printf("ALU "); -                break; -            case R500_INST_TYPE_OUT: -                debug_printf("OUT "); -                break; -            case R500_INST_TYPE_FC: -                debug_printf("FC  "); -                break; -            case R500_INST_TYPE_TEX: -                debug_printf("TEX "); -                break; -        } -        debug_printf("%s %s %s %s ", -                inst & R500_INST_TEX_SEM_WAIT ? "TEX_WAIT" : "", -                inst & R500_INST_LAST ? "LAST" : "", -                inst & R500_INST_NOP ? "NOP" : "", -                inst & R500_INST_ALU_WAIT ? "ALU_WAIT" : ""); -        debug_printf("wmask: %s omask: %s\n", -                r500_fs_mask[(inst >> 11) & 0xf], -                r500_fs_mask[(inst >> 15) & 0xf]); -        switch (inst & 0x3) { -            case R500_INST_TYPE_ALU: -            case R500_INST_TYPE_OUT: -                inst = fs->instructions[i].inst1; -                debug_printf("    1: RGB_ADDR   0x%08x:", inst); -                debug_printf("Addr0: %d%c, Addr1: %d%c, " -                        "Addr2: %d%c, srcp:%d\n", -                        inst & 0xff, (inst & (1 << 8)) ? 'c' : 't', -                        (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't', -                        (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't', -                        (inst >> 30)); - -                inst = fs->instructions[i].inst2; -                debug_printf("    2: ALPHA_ADDR 0x%08x:", inst); -                debug_printf("Addr0: %d%c, Addr1: %d%c, " -                        "Addr2: %d%c, srcp:%d\n", -                        inst & 0xff, (inst & (1 << 8)) ? 'c' : 't', -                        (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't', -                        (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't', -                        (inst >> 30)); - -                inst = fs->instructions[i].inst3; -                debug_printf("    3: RGB_INST   0x%08x:", inst); -                debug_printf("rgb_A_src:%d %s/%s/%s %d " -                        "rgb_B_src:%d %s/%s/%s %d\n", -                        inst & 0x3, r500_fs_swiz[(inst >> 2) & 0x7], -                        r500_fs_swiz[(inst >> 5) & 0x7], -                        r500_fs_swiz[(inst >> 8) & 0x7], -                        (inst >> 11) & 0x3, (inst >> 13) & 0x3, -                        r500_fs_swiz[(inst >> 15) & 0x7], -                        r500_fs_swiz[(inst >> 18) & 0x7], -                        r500_fs_swiz[(inst >> 21) & 0x7], -                        (inst >> 24) & 0x3); - -                inst = fs->instructions[i].inst4; -                debug_printf("    4: ALPHA_INST 0x%08x:", inst); -                debug_printf("%s dest:%d%s alp_A_src:%d %s %d " -                        "alp_B_src:%d %s %d w:%d\n", -                        r500_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f, -                        inst & (1<<11) ? "(rel)":"", (inst >> 12) & 0x3, -                        r500_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3, -                        (inst >> 19) & 0x3, r500_fs_swiz[(inst >> 21) & 0x7], -                        (inst >> 24) & 0x3, (inst >> 31) & 0x1); - -                inst = fs->instructions[i].inst5; -                debug_printf("    5: RGBA_INST  0x%08x:", inst); -                debug_printf("%s dest:%d%s rgb_C_src:%d %s/%s/%s %d " -                        "alp_C_src:%d %s %d\n", -                        r500_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f, -                        inst & (1 << 11) ? "(rel)":"", (inst >> 12) & 0x3, -                        r500_fs_swiz[(inst >> 14) & 0x7], -                        r500_fs_swiz[(inst >> 17) & 0x7], -                        r500_fs_swiz[(inst >> 20) & 0x7], -                        (inst >> 23) & 0x3, (inst >> 25) & 0x3, -                        r500_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3); -                break; -            case R500_INST_TYPE_FC: -                /* XXX don't even bother yet */ -                break; -            case R500_INST_TYPE_TEX: -                inst = fs->instructions[i].inst1; -                debug_printf("    1: TEX_INST   0x%08x: id: %d " -                        "op:%s, %s, %s %s\n", -                        inst, (inst >> 16) & 0xf, -                        r500_fs_tex[(inst >> 22) & 0x7], -                        (inst & (1 << 25)) ? "ACQ" : "", -                        (inst & (1 << 26)) ? "IGNUNC" : "", -                        (inst & (1 << 27)) ? "UNSCALED" : "SCALED"); - -                inst = fs->instructions[i].inst2; -                debug_printf("    2: TEX_ADDR   0x%08x: " -                        "src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n", -                        inst, inst & 0x7f, inst & (1 << 7) ? "(rel)" : "", -                        r500_fs_swiz[(inst >> 8) & 0x3], -                        r500_fs_swiz[(inst >> 10) & 0x3], -                        r500_fs_swiz[(inst >> 12) & 0x3], -                        r500_fs_swiz[(inst >> 14) & 0x3], -                        (inst >> 16) & 0x7f, inst & (1 << 23) ? "(rel)" : "", -                        r500_fs_swiz[(inst >> 24) & 0x3], -                        r500_fs_swiz[(inst >> 26) & 0x3], -                        r500_fs_swiz[(inst >> 28) & 0x3], -                        r500_fs_swiz[(inst >> 30) & 0x3]); -                 -                inst = fs->instructions[i].inst3; -                debug_printf("    3: TEX_DXDY   0x%08x\n", inst); -                break; -        } -    } -} - -void r300_vs_dump(struct r300_vertex_shader* vs) -{ -    int i; - -    for (i = 0; i < vs->instruction_count; i++) { -        debug_printf("inst0: 0x%x\n", vs->instructions[i].inst0); -        debug_printf("inst1: 0x%x\n", vs->instructions[i].inst1); -        debug_printf("inst2: 0x%x\n", vs->instructions[i].inst2); -        debug_printf("inst3: 0x%x\n", vs->instructions[i].inst3); -    } -} diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 01bac5f759..bd4d59e6f1 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -24,6 +24,9 @@  #include "r300_emit.h" +#include "r300_fs.h" +#include "r300_vs.h" +  void r300_emit_blend_state(struct r300_context* r300,                             struct r300_blend_state* blend)  { @@ -56,6 +59,36 @@ void r300_emit_blend_color_state(struct r300_context* r300,      }  } +void r300_emit_clip_state(struct r300_context* r300, +                          struct pipe_clip_state* clip) +{ +    int i; +    struct r300_screen* r300screen = r300_screen(r300->context.screen); +    CS_LOCALS(r300); + +    if (r300screen->caps->has_tcl) { +        BEGIN_CS(5 + (6 * 4)); +        OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, +                (r300screen->caps->is_r500 ? +                 R500_PVS_UCP_START : R300_PVS_UCP_START)); +        OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, 6 * 4); +        for (i = 0; i < 6; i++) { +            OUT_CS_32F(clip->ucp[i][0]); +            OUT_CS_32F(clip->ucp[i][1]); +            OUT_CS_32F(clip->ucp[i][2]); +            OUT_CS_32F(clip->ucp[i][3]); +        } +        OUT_CS_REG(R300_VAP_CLIP_CNTL, ((1 << clip->nr) - 1) | +                R300_PS_UCP_MODE_CLIP_AS_TRIFAN); +        END_CS; +    } else { +        BEGIN_CS(2); +        OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE); +        END_CS; +    } + +} +  void r300_emit_dsa_state(struct r300_context* r300,                             struct r300_dsa_state* dsa)  { @@ -79,73 +112,158 @@ void r300_emit_dsa_state(struct r300_context* r300,      END_CS;  } -void r300_emit_fragment_shader(struct r300_context* r300, -                               struct r300_fragment_shader* fs) +static const float * get_shader_constant( +    struct r300_context * r300, +    struct rc_constant * constant, +    struct r300_constant_buffer * externals) +{ +    static const float zero[4] = { 0.0, 0.0, 0.0, 0.0 }; +    switch(constant->Type) { +        case RC_CONSTANT_EXTERNAL: +            return externals->constants[constant->u.External]; + +        case RC_CONSTANT_IMMEDIATE: +            return constant->u.Immediate; + +        default: +            debug_printf("r300: Implementation error: Unhandled constant type %i\n", +                constant->Type); +            return zero; +    } +} + +/* Convert a normal single-precision float into the 7.16 format + * used by the R300 fragment shader. + */ +static uint32_t pack_float24(float f) +{ +    union { +        float fl; +        uint32_t u; +    } u; +    float mantissa; +    int exponent; +    uint32_t float24 = 0; + +    if (f == 0.0) +        return 0; + +    u.fl = f; + +    mantissa = frexpf(f, &exponent); + +    /* Handle -ve */ +    if (mantissa < 0) { +        float24 |= (1 << 23); +        mantissa = mantissa * -1.0; +    } +    /* Handle exponent, bias of 63 */ +    exponent += 62; +    float24 |= (exponent << 16); +    /* Kill 7 LSB of mantissa */ +    float24 |= (u.u & 0x7FFFFF) >> 7; + +    return float24; +} + +void r300_emit_fragment_program_code(struct r300_context* r300, +                                     struct rX00_fragment_program_code* generic_code, +                                     struct r300_constant_buffer* externals)  { +    struct r300_fragment_program_code * code = &generic_code->code.r300; +    struct rc_constant_list * constants = &generic_code->constants;      int i;      CS_LOCALS(r300); -    BEGIN_CS(22); +    BEGIN_CS(15 + +             code->alu.length * 4 + +             (code->tex.length ? (1 + code->tex.length) : 0) + +             (constants->Count ? (1 + constants->Count * 4) : 0)); + +    OUT_CS_REG(R300_US_CONFIG, code->config); +    OUT_CS_REG(R300_US_PIXSIZE, code->pixsize); +    OUT_CS_REG(R300_US_CODE_OFFSET, code->code_offset); + +    OUT_CS_REG_SEQ(R300_US_CODE_ADDR_0, 4); +    for(i = 0; i < 4; ++i) +        OUT_CS(code->code_addr[i]); + +    OUT_CS_REG_SEQ(R300_US_ALU_RGB_INST_0, code->alu.length); +    for (i = 0; i < code->alu.length; i++) +        OUT_CS(code->alu.inst[i].rgb_inst); + +    OUT_CS_REG_SEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length); +    for (i = 0; i < code->alu.length; i++) +        OUT_CS(code->alu.inst[i].rgb_addr); + +    OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length); +    for (i = 0; i < code->alu.length; i++) +        OUT_CS(code->alu.inst[i].alpha_inst); -    OUT_CS_REG(R300_US_CONFIG, fs->indirections); -    OUT_CS_REG(R300_US_PIXSIZE, fs->shader.stack_size); -    /* XXX figure out exactly how big the sizes are on this reg */ -    OUT_CS_REG(R300_US_CODE_OFFSET, 0x40); -    /* XXX figure these ones out a bit better kthnx */ -    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, 0x40 | R300_RGBA_OUT); +    OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length); +    for (i = 0; i < code->alu.length; i++) +        OUT_CS(code->alu.inst[i].alpha_addr); -    for (i = 0; i < fs->alu_instruction_count; i++) { -        OUT_CS_REG(R300_US_ALU_RGB_INST_0 + (4 * i), -            fs->instructions[i].alu_rgb_inst); -        OUT_CS_REG(R300_US_ALU_RGB_ADDR_0 + (4 * i), -            fs->instructions[i].alu_rgb_addr); -        OUT_CS_REG(R300_US_ALU_ALPHA_INST_0 + (4 * i), -            fs->instructions[i].alu_alpha_inst); -        OUT_CS_REG(R300_US_ALU_ALPHA_ADDR_0 + (4 * i), -            fs->instructions[i].alu_alpha_addr); +    if (code->tex.length) { +        OUT_CS_REG_SEQ(R300_US_TEX_INST_0, code->tex.length); +        for(i = 0; i < code->tex.length; ++i) +            OUT_CS(code->tex.inst[i]); +    } + +    if (constants->Count) { +        OUT_CS_ONE_REG(R300_PFS_PARAM_0_X, constants->Count * 4); +        for(i = 0; i < constants->Count; ++i) { +            const float * data = get_shader_constant(r300, &constants->Constants[i], externals); +            OUT_CS(pack_float24(data[0])); +            OUT_CS(pack_float24(data[1])); +            OUT_CS(pack_float24(data[2])); +            OUT_CS(pack_float24(data[3])); +        }      }      END_CS;  } -void r500_emit_fragment_shader(struct r300_context* r300, -                               struct r500_fragment_shader* fs) +void r500_emit_fragment_program_code(struct r300_context* r300, +                                     struct rX00_fragment_program_code* generic_code, +                                     struct r300_constant_buffer* externals)  { +    struct r500_fragment_program_code * code = &generic_code->code.r500; +    struct rc_constant_list * constants = &generic_code->constants;      int i; -    struct r300_constant_buffer* constants = -        &r300->shader_constants[PIPE_SHADER_FRAGMENT];      CS_LOCALS(r300); -    BEGIN_CS(9 + (fs->instruction_count * 6) + (constants->count ? 3 : 0) + -            (constants->count * 4)); -    OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); -    OUT_CS_REG(R500_US_PIXSIZE, fs->shader.stack_size); -    OUT_CS_REG(R500_US_CODE_ADDR, R500_US_CODE_START_ADDR(0) | -            R500_US_CODE_END_ADDR(fs->instruction_count)); +    BEGIN_CS(13 + +             ((code->inst_end + 1) * 6) + +             (constants->Count ? (3 + (constants->Count * 4)) : 0)); +    OUT_CS_REG(R500_US_CONFIG, 0); +    OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx); +    OUT_CS_REG(R500_US_CODE_RANGE, +               R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end)); +    OUT_CS_REG(R500_US_CODE_OFFSET, 0); +    OUT_CS_REG(R500_US_CODE_ADDR, +               R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(code->inst_end));      OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_INSTR); -    OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, fs->instruction_count * 6); -    for (i = 0; i < fs->instruction_count; i++) { -        OUT_CS(fs->instructions[i].inst0); -        OUT_CS(fs->instructions[i].inst1); -        OUT_CS(fs->instructions[i].inst2); -        OUT_CS(fs->instructions[i].inst3); -        OUT_CS(fs->instructions[i].inst4); -        OUT_CS(fs->instructions[i].inst5); +    OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, (code->inst_end + 1) * 6); +    for (i = 0; i <= code->inst_end; i++) { +        OUT_CS(code->inst[i].inst0); +        OUT_CS(code->inst[i].inst1); +        OUT_CS(code->inst[i].inst2); +        OUT_CS(code->inst[i].inst3); +        OUT_CS(code->inst[i].inst4); +        OUT_CS(code->inst[i].inst5);      } -    if (constants->count) { -        OUT_CS_REG(R500_GA_US_VECTOR_INDEX, -                R500_GA_US_VECTOR_INDEX_TYPE_CONST); -        OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->count * 4); -        for (i = 0; i < constants->count; i++) { -            OUT_CS_32F(constants->constants[i][0]); -            OUT_CS_32F(constants->constants[i][1]); -            OUT_CS_32F(constants->constants[i][2]); -            OUT_CS_32F(constants->constants[i][3]); +    if (constants->Count) { +        OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST); +        OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4); +        for (i = 0; i < constants->Count; i++) { +            const float * data = get_shader_constant(r300, &constants->Constants[i], externals); +            OUT_CS_32F(data[0]); +            OUT_CS_32F(data[1]); +            OUT_CS_32F(data[2]); +            OUT_CS_32F(data[3]);          }      } @@ -160,16 +278,19 @@ void r300_emit_fb_state(struct r300_context* r300,      int i;      CS_LOCALS(r300); -    BEGIN_CS((8 * fb->nr_cbufs) + (fb->zsbuf ? 8 : 0) + 4); +    BEGIN_CS((10 * fb->nr_cbufs) + (fb->zsbuf ? 10 : 0) + 4);      for (i = 0; i < fb->nr_cbufs; i++) {          tex = (struct r300_texture*)fb->cbufs[i]->texture; +        assert(tex && tex->buffer && "cbuf is marked, but NULL!");          pixpitch = tex->stride / tex->tex.block.size;          OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);          OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); -        OUT_CS_REG(R300_RB3D_COLORPITCH0 + (4 * i), pixpitch | -            r300_translate_colorformat(tex->tex.format)); +        OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1); +        OUT_CS_RELOC(tex->buffer, pixpitch | +                     r300_translate_colorformat(tex->tex.format), 0, +                     RADEON_GEM_DOMAIN_VRAM, 0);          OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i),              r300_translate_out_fmt(fb->cbufs[i]->format)); @@ -177,14 +298,16 @@ void r300_emit_fb_state(struct r300_context* r300,      if (fb->zsbuf) {          tex = (struct r300_texture*)fb->zsbuf->texture; -        pixpitch = (tex->stride / tex->tex.block.size); +        assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); +        pixpitch = tex->stride / tex->tex.block.size;          OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);          OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);          OUT_CS_REG(R300_ZB_FORMAT, r300_translate_zsformat(tex->tex.format)); -        OUT_CS_REG(R300_ZB_DEPTHPITCH, pixpitch); +        OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); +        OUT_CS_RELOC(tex->buffer, pixpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);      }      OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, @@ -196,6 +319,79 @@ void r300_emit_fb_state(struct r300_context* r300,      END_CS;  } +void r300_emit_query_begin(struct r300_context* r300, +                           struct r300_query* query) +{ +    CS_LOCALS(r300); + +    /* XXX This will almost certainly not return good results +     * for overlapping queries. */ +    BEGIN_CS(2); +    OUT_CS_REG(R300_ZB_ZPASS_DATA, 0); +    END_CS; +} + +void r300_emit_query_end(struct r300_context* r300, +                         struct r300_query* query) +{ +    struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps; +    CS_LOCALS(r300); + +    if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo, +                0, RADEON_GEM_DOMAIN_GTT)) { +        debug_printf("r300: There wasn't room for the OQ buffer!?" +                " Oh noes!\n"); +    } + +    assert(caps->num_frag_pipes); +    BEGIN_CS(6 * caps->num_frag_pipes + 2); +    /* I'm not so sure I like this switch, but it's hard to be elegant +     * when there's so many special cases... +     * +     * So here's the basic idea. For each pipe, enable writes to it only, +     * then put out the relocation for ZPASS_ADDR, taking into account a +     * 4-byte offset for each pipe. RV380 and older are special; they have +     * only two pipes, and the second pipe's enable is on bit 3, not bit 1, +     * so there's a chipset cap for that. */ +    switch (caps->num_frag_pipes) { +        case 4: +            /* pipe 3 only */ +            OUT_CS_REG(R300_SU_REG_DEST, 1 << 3); +            OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); +            OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3), +                    0, RADEON_GEM_DOMAIN_GTT, 0); +        case 3: +            /* pipe 2 only */ +            OUT_CS_REG(R300_SU_REG_DEST, 1 << 2); +            OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); +            OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2), +                    0, RADEON_GEM_DOMAIN_GTT, 0); +        case 2: +            /* pipe 1 only */ +            /* As mentioned above, accomodate RV380 and older. */ +            OUT_CS_REG(R300_SU_REG_DEST, +                    1 << (caps->high_second_pipe ? 3 : 1)); +            OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); +            OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1), +                    0, RADEON_GEM_DOMAIN_GTT, 0); +        case 1: +            /* pipe 0 only */ +            OUT_CS_REG(R300_SU_REG_DEST, 1 << 0); +            OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); +            OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0), +                    0, RADEON_GEM_DOMAIN_GTT, 0); +        default: +            debug_printf("r300: Implementation error: Chipset reports %d" +                    " pixel pipes!\n", caps->num_frag_pipes); +            assert(0); +    } + +    /* And, finally, reset it to normal... */ +    OUT_CS_REG(R300_SU_REG_DEST, 0xF); +    END_CS; + +} +  void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs)  {      CS_LOCALS(r300); @@ -234,7 +430,7 @@ void r300_emit_rs_block_state(struct r300_context* r300,      }      for (i = 0; i < 8; i++) {          OUT_CS(rs->ip[i]); -        debug_printf("ip %d: 0x%08x\n", i, rs->ip[i]); +        /* debug_printf("ip %d: 0x%08x\n", i, rs->ip[i]); */      }      OUT_CS_REG_SEQ(R300_RS_COUNT, 2); @@ -248,27 +444,15 @@ void r300_emit_rs_block_state(struct r300_context* r300,      }      for (i = 0; i < 8; i++) {          OUT_CS(rs->inst[i]); -        debug_printf("inst %d: 0x%08x\n", i, rs->inst[i]); +        /* debug_printf("inst %d: 0x%08x\n", i, rs->inst[i]); */      } -    debug_printf("count: 0x%08x inst_count: 0x%08x\n", rs->count, -            rs->inst_count); +    /* debug_printf("count: 0x%08x inst_count: 0x%08x\n", rs->count, +     *        rs->inst_count); */      END_CS;  } -void r300_emit_sampler(struct r300_context* r300, -                       struct r300_sampler_state* sampler, unsigned offset) -{ -    CS_LOCALS(r300); - -    BEGIN_CS(6); -    OUT_CS_REG(R300_TX_FILTER0_0 + (offset * 4), sampler->filter0); -    OUT_CS_REG(R300_TX_FILTER1_0 + (offset * 4), sampler->filter1); -    OUT_CS_REG(R300_TX_BORDER_COLOR_0 + (offset * 4), sampler->border_color); -    END_CS; -} -  void r300_emit_scissor_state(struct r300_context* r300,                               struct r300_scissor_state* scissor)  { @@ -282,11 +466,17 @@ void r300_emit_scissor_state(struct r300_context* r300,  }  void r300_emit_texture(struct r300_context* r300, -                       struct r300_texture* tex, unsigned offset) +                       struct r300_sampler_state* sampler, +                       struct r300_texture* tex, +                       unsigned offset)  {      CS_LOCALS(r300); -    BEGIN_CS(10); +    BEGIN_CS(16); +    OUT_CS_REG(R300_TX_FILTER0_0 + (offset * 4), sampler->filter0); +    OUT_CS_REG(R300_TX_FILTER1_0 + (offset * 4), sampler->filter1); +    OUT_CS_REG(R300_TX_BORDER_COLOR_0 + (offset * 4), sampler->border_color); +      OUT_CS_REG(R300_TX_FORMAT0_0 + (offset * 4), tex->state.format0);      OUT_CS_REG(R300_TX_FORMAT1_0 + (offset * 4), tex->state.format1);      OUT_CS_REG(R300_TX_FORMAT2_0 + (offset * 4), tex->state.format2); @@ -296,6 +486,30 @@ void r300_emit_texture(struct r300_context* r300,      END_CS;  } +void r300_emit_vertex_buffer(struct r300_context* r300) +{ +    CS_LOCALS(r300); + +    debug_printf("r300: Preparing vertex buffer %p for render, " +            "vertex size %d\n", r300->vbo, +            r300->vertex_info.vinfo.size); +    /* Set the pointer to our vertex buffer. The emitted values are this: +     * PACKET3 [3D_LOAD_VBPNTR] +     * COUNT   [1] +     * FORMAT  [size | stride << 8] +     * OFFSET  [offset into BO] +     * VBPNTR  [relocated BO] +     */ +    BEGIN_CS(7); +    OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3); +    OUT_CS(1); +    OUT_CS(r300->vertex_info.vinfo.size | +            (r300->vertex_info.vinfo.size << 8)); +    OUT_CS(r300->vbo_offset); +    OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); +    END_CS; +} +  void r300_emit_vertex_format_state(struct r300_context* r300)  {      int i; @@ -310,33 +524,33 @@ void r300_emit_vertex_format_state(struct r300_context* r300)      OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);      OUT_CS(r300->vertex_info.vinfo.hwfmt[2]);      OUT_CS(r300->vertex_info.vinfo.hwfmt[3]); -    for (i = 0; i < 4; i++) { -        debug_printf("hwfmt%d: 0x%08x\n", i, -                r300->vertex_info.vinfo.hwfmt[i]); -    } +    /* for (i = 0; i < 4; i++) { +     *    debug_printf("hwfmt%d: 0x%08x\n", i, +     *            r300->vertex_info.vinfo.hwfmt[i]); +     * } */      OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8);      for (i = 0; i < 8; i++) {          OUT_CS(r300->vertex_info.vap_prog_stream_cntl[i]); -        debug_printf("prog_stream_cntl%d: 0x%08x\n", i, -                r300->vertex_info.vap_prog_stream_cntl[i]); +        /* debug_printf("prog_stream_cntl%d: 0x%08x\n", i, +         *        r300->vertex_info.vap_prog_stream_cntl[i]); */      }      OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8);      for (i = 0; i < 8; i++) {          OUT_CS(r300->vertex_info.vap_prog_stream_cntl_ext[i]); -        debug_printf("prog_stream_cntl_ext%d: 0x%08x\n", i, -                r300->vertex_info.vap_prog_stream_cntl_ext[i]); +        /* debug_printf("prog_stream_cntl_ext%d: 0x%08x\n", i, +         *        r300->vertex_info.vap_prog_stream_cntl_ext[i]); */      }      END_CS;  } -void r300_emit_vertex_shader(struct r300_context* r300, -                             struct r300_vertex_shader* vs) +void r300_emit_vertex_program_code(struct r300_context* r300, +                                   struct r300_vertex_program_code* code, +                                   struct r300_constant_buffer* constants)  {      int i;      struct r300_screen* r300screen = r300_screen(r300->context.screen); -    struct r300_constant_buffer* constants = -        &r300->shader_constants[PIPE_SHADER_VERTEX]; +    unsigned instruction_count = code->length / 4;      CS_LOCALS(r300);      if (!r300screen->caps->has_tcl) { @@ -345,38 +559,40 @@ void r300_emit_vertex_shader(struct r300_context* r300,          return;      } -    if (constants->count) { -        BEGIN_CS(16 + (vs->instruction_count * 4) + (constants->count * 4)); +    if (code->constants.Count) { +        BEGIN_CS(14 + code->length + (code->constants.Count * 4));      } else { -        BEGIN_CS(13 + (vs->instruction_count * 4) + (constants->count * 4)); +        BEGIN_CS(11 + code->length);      } -    OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, R300_PVS_FIRST_INST(0) | -            R300_PVS_LAST_INST(vs->instruction_count - 1)); -    OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, vs->instruction_count - 1); - -    /* XXX */ -    OUT_CS_REG(R300_VAP_PVS_CONST_CNTL, 0x0); +    /* R300_VAP_PVS_CODE_CNTL_0 +     * R300_VAP_PVS_CONST_CNTL +     * R300_VAP_PVS_CODE_CNTL_1 +     * See the r5xx docs for instructions on how to use these. +     * XXX these could be optimized to select better values... */ +    OUT_CS_REG_SEQ(R300_VAP_PVS_CODE_CNTL_0, 3); +    OUT_CS(R300_PVS_FIRST_INST(0) | +            R300_PVS_XYZW_VALID_INST(instruction_count - 1) | +            R300_PVS_LAST_INST(instruction_count - 1)); +    OUT_CS(R300_PVS_MAX_CONST_ADDR(code->constants.Count - 1)); +    OUT_CS(instruction_count - 1);      OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0); -    OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, vs->instruction_count * 4); -    for (i = 0; i < vs->instruction_count; i++) { -        OUT_CS(vs->instructions[i].inst0); -        OUT_CS(vs->instructions[i].inst1); -        OUT_CS(vs->instructions[i].inst2); -        OUT_CS(vs->instructions[i].inst3); -    } +    OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->length); +    for (i = 0; i < code->length; i++) +        OUT_CS(code->body.d[i]); -    if (constants->count) { +    if (code->constants.Count) {          OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,                  (r300screen->caps->is_r500 ?                   R500_PVS_CONST_START : R300_PVS_CONST_START)); -        OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->count * 4); -        for (i = 0; i < constants->count; i++) { -            OUT_CS_32F(constants->constants[i][0]); -            OUT_CS_32F(constants->constants[i][1]); -            OUT_CS_32F(constants->constants[i][2]); -            OUT_CS_32F(constants->constants[i][3]); +        OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->constants.Count * 4); +        for (i = 0; i < code->constants.Count; i++) { +            const float * data = get_shader_constant(r300, &code->constants.Constants[i], constants); +            OUT_CS_32F(data[0]); +            OUT_CS_32F(data[1]); +            OUT_CS_32F(data[2]); +            OUT_CS_32F(data[3]);          }      } @@ -386,7 +602,12 @@ void r300_emit_vertex_shader(struct r300_context* r300,              R300_PVS_VF_MAX_VTX_NUM(12));      OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);      END_CS; +} +void r300_emit_vertex_shader(struct r300_context* r300, +                             struct r300_vertex_shader* vs) +{ +    r300_emit_vertex_program_code(r300, &vs->code, &r300->shader_constants[PIPE_SHADER_VERTEX]);  }  void r300_emit_viewport_state(struct r300_context* r300, @@ -403,7 +624,11 @@ void r300_emit_viewport_state(struct r300_context* r300,      OUT_CS_32F(viewport->zscale);      OUT_CS_32F(viewport->zoffset); -    OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control); +    if (r300->rs_state->enable_vte) { +        OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control); +    } else { +        OUT_CS_REG(R300_VAP_VTE_CNTL, 0); +    }      END_CS;  } @@ -421,23 +646,73 @@ void r300_flush_textures(struct r300_context* r300)  void r300_emit_dirty_state(struct r300_context* r300)  {      struct r300_screen* r300screen = r300_screen(r300->context.screen); -    int i; -    int dirty_tex = 0; +    struct r300_texture* tex; +    int i, dirty_tex = 0; +    boolean invalid = FALSE; -    if (!(r300->dirty_hw)) { +    if (!(r300->dirty_state)) {          return;      }      r300_update_derived_state(r300);      /* XXX check size */ -    struct r300_texture* fb_tex = -        (struct r300_texture*)r300->framebuffer_state.cbufs[0]; -    r300->winsys->add_buffer(r300->winsys, fb_tex->buffer, -            0, RADEON_GEM_DOMAIN_VRAM); -    if (r300->winsys->validate(r300->winsys)) { -        /* XXX */ +validate: +    /* Color buffers... */ +    for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) { +        tex = (struct r300_texture*)r300->framebuffer_state.cbufs[i]->texture; +        assert(tex && tex->buffer && "cbuf is marked, but NULL!"); +        if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, +                    0, RADEON_GEM_DOMAIN_VRAM)) { +            r300->context.flush(&r300->context, 0, NULL); +            goto validate; +        } +    } +    /* ...depth buffer... */ +    if (r300->framebuffer_state.zsbuf) { +        tex = (struct r300_texture*)r300->framebuffer_state.zsbuf->texture; +        assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); +        if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, +                    0, RADEON_GEM_DOMAIN_VRAM)) { +            r300->context.flush(&r300->context, 0, NULL); +            goto validate; +        } +    } +    /* ...textures... */ +    for (i = 0; i < r300->texture_count; i++) { +        tex = r300->textures[i]; +        assert(tex && tex->buffer && "texture is marked, but NULL!"); +        if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, +                    RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { +            r300->context.flush(&r300->context, 0, NULL); +            goto validate; +        } +    } +    /* ...occlusion query buffer... */ +    if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo, +                0, RADEON_GEM_DOMAIN_GTT)) { +        r300->context.flush(&r300->context, 0, NULL); +        goto validate; +    } +    /* ...and vertex buffer. */ +    if (r300->vbo) { +        if (!r300->winsys->add_buffer(r300->winsys, r300->vbo, +                    RADEON_GEM_DOMAIN_GTT, 0)) { +            r300->context.flush(&r300->context, 0, NULL); +            goto validate; +        } +    } else { +        debug_printf("No VBO while emitting dirty state!\n"); +    } +    if (!r300->winsys->validate(r300->winsys)) {          r300->context.flush(&r300->context, 0, NULL); +        if (invalid) { +            /* Well, hell. */ +            debug_printf("r300: Stuck in validation loop, gonna quit now."); +            exit(1); +        } +        invalid = TRUE; +        goto validate;      }      if (r300->dirty_state & R300_NEW_BLEND) { @@ -450,6 +725,11 @@ void r300_emit_dirty_state(struct r300_context* r300)          r300->dirty_state &= ~R300_NEW_BLEND_COLOR;      } +    if (r300->dirty_state & R300_NEW_CLIP) { +        r300_emit_clip_state(r300, &r300->clip_state); +        r300->dirty_state &= ~R300_NEW_CLIP; +    } +      if (r300->dirty_state & R300_NEW_DSA) {          r300_emit_dsa_state(r300, r300->dsa_state);          r300->dirty_state &= ~R300_NEW_DSA; @@ -457,11 +737,9 @@ void r300_emit_dirty_state(struct r300_context* r300)      if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {          if (r300screen->caps->is_r500) { -            r500_emit_fragment_shader(r300, -                (struct r500_fragment_shader*)r300->fs); +            r500_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);          } else { -            r300_emit_fragment_shader(r300, -                (struct r300_fragment_shader*)r300->fs); +            r300_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);          }          r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;      } @@ -481,29 +759,27 @@ void r300_emit_dirty_state(struct r300_context* r300)          r300->dirty_state &= ~R300_NEW_RS_BLOCK;      } -    if (r300->dirty_state & R300_ANY_NEW_SAMPLERS) { -        for (i = 0; i < r300->sampler_count; i++) { -            if (r300->dirty_state & (R300_NEW_SAMPLER << i)) { -                r300_emit_sampler(r300, r300->sampler_states[i], i); -                r300->dirty_state &= ~(R300_NEW_SAMPLER << i); -                dirty_tex++; -            } -        } -    } -      if (r300->dirty_state & R300_NEW_SCISSOR) {          r300_emit_scissor_state(r300, r300->scissor_state);          r300->dirty_state &= ~R300_NEW_SCISSOR;      } -    if (r300->dirty_state & R300_ANY_NEW_TEXTURES) { -        for (i = 0; i < r300->texture_count; i++) { -            if (r300->dirty_state & (R300_NEW_TEXTURE << i)) { -                r300_emit_texture(r300, r300->textures[i], i); -                r300->dirty_state &= ~(R300_NEW_TEXTURE << i); +    /* Samplers and textures are tracked separately but emitted together. */ +    if (r300->dirty_state & +            (R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES)) { +        for (i = 0; i < MIN2(r300->sampler_count, r300->texture_count); i++) { +            if (r300->dirty_state & +                    ((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i))) { +                r300_emit_texture(r300, +                        r300->sampler_states[i], +                        r300->textures[i], +                        i); +                r300->dirty_state &= +                    ~((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i));                  dirty_tex++;              }          } +        r300->dirty_state &= ~(R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES);      }      if (r300->dirty_state & R300_NEW_VIEWPORT) { @@ -519,4 +795,18 @@ void r300_emit_dirty_state(struct r300_context* r300)          r300_emit_vertex_format_state(r300);          r300->dirty_state &= ~R300_NEW_VERTEX_FORMAT;      } + +    if (r300->dirty_state & R300_NEW_VERTEX_SHADER) { +        r300_emit_vertex_shader(r300, r300->vs); +        r300->dirty_state &= ~R300_NEW_VERTEX_SHADER; +    } + +    /* XXX +    assert(r300->dirty_state == 0); +    */ + +    /* Finally, emit the VBO. */ +    r300_emit_vertex_buffer(r300); + +    r300->dirty_hw++;  } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 31dbc7ab85..350691d592 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -30,20 +30,28 @@  #include "r300_screen.h"  #include "r300_state_inlines.h" +struct rX00_fragment_program_code; +struct r300_vertex_program_code; +  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_clip_state(struct r300_context* r300, +                          struct pipe_clip_state* clip); +  void r300_emit_dsa_state(struct r300_context* r300,                           struct r300_dsa_state* dsa); -void r300_emit_fragment_shader(struct r300_context* r300, -                               struct r300_fragment_shader* fs); +void r300_emit_fragment_program_code(struct r300_context* r300, +                                     struct rX00_fragment_program_code* generic_code, +                                     struct r300_constant_buffer* externals); -void r500_emit_fragment_shader(struct r300_context* r300, -                               struct r500_fragment_shader* fs); +void r500_emit_fragment_program_code(struct r300_context* r300, +                                     struct rX00_fragment_program_code* generic_code, +                                     struct r300_constant_buffer* externals);  void r300_emit_fb_state(struct r300_context* r300,                          struct pipe_framebuffer_state* fb); @@ -53,17 +61,22 @@ void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs);  void r300_emit_rs_block_state(struct r300_context* r300,                                struct r300_rs_block* rs); -void r300_emit_sampler(struct r300_context* r300, -                       struct r300_sampler_state* sampler, unsigned offset); -  void r300_emit_scissor_state(struct r300_context* r300,                               struct r300_scissor_state* scissor);  void r300_emit_texture(struct r300_context* r300, -                       struct r300_texture* tex, unsigned offset); +                       struct r300_sampler_state* sampler, +                       struct r300_texture* tex, +                       unsigned offset); + +void r300_emit_vertex_buffer(struct r300_context* r300);  void r300_emit_vertex_format_state(struct r300_context* r300); +void r300_emit_vertex_program_code(struct r300_context* r300, +                                   struct r300_vertex_program_code* code, +                                   struct r300_constant_buffer* constants); +  void r300_emit_vertex_shader(struct r300_context* r300,                               struct r300_vertex_shader* vs); diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c index 89a5f2b20c..0dff1c6f4f 100644 --- a/src/gallium/drivers/r300/r300_flush.c +++ b/src/gallium/drivers/r300/r300_flush.c @@ -29,7 +29,11 @@ static void r300_flush(struct pipe_context* pipe,      struct r300_context* r300 = r300_context(pipe);      CS_LOCALS(r300); -    draw_flush(r300->draw); +    /* We probably need to flush Draw, but we may have been called from +     * within Draw. This feels kludgy, but it might be the best thing. */ +    if (!r300->draw->flushing) { +        draw_flush(r300->draw); +    }      if (r300->dirty_hw) {          FLUSH_CS; diff --git a/src/gallium/drivers/r300/r300_flush.h b/src/gallium/drivers/r300/r300_flush.h index a1b224b39c..9a83d89daa 100644 --- a/src/gallium/drivers/r300/r300_flush.h +++ b/src/gallium/drivers/r300/r300_flush.h @@ -23,6 +23,8 @@  #ifndef R300_FLUSH_H  #define R300_FLUSH_H +#include "draw/draw_private.h" +  #include "pipe/p_context.h"  #include "r300_context.h" diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c new file mode 100644 index 0000000000..36463b9a2e --- /dev/null +++ b/src/gallium/drivers/r300/r300_fs.c @@ -0,0 +1,137 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.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_fs.h" + +#include "r300_tgsi_to_rc.h" + +#include "radeon_compiler.h" + +static void find_output_registers(struct r300_fragment_program_compiler * compiler, +                                  struct r300_fragment_shader * fs) +{ +    unsigned i; + +    /* Mark the outputs as not present initially */ +    compiler->OutputColor = fs->info.num_outputs; +    compiler->OutputDepth = fs->info.num_outputs; + +    /* Now see where they really are. */ +    for(i = 0; i < fs->info.num_outputs; ++i) { +        switch(fs->info.output_semantic_name[i]) { +            case TGSI_SEMANTIC_COLOR: +                compiler->OutputColor = i; +                break; +            case TGSI_SEMANTIC_POSITION: +                compiler->OutputDepth = i; +                break; +        } +    } +} + +static void allocate_hardware_inputs( +    struct r300_fragment_program_compiler * c, +    void (*allocate)(void * data, unsigned input, unsigned hwreg), +    void * mydata) +{ +    struct tgsi_shader_info* info = &((struct r300_fragment_shader*)c->UserData)->info; +    int total_colors = 0; +    int colors = 0; +    int total_generic = 0; +    int generic = 0; +    int i; + +    for (i = 0; i < info->num_inputs; i++) { +        switch (info->input_semantic_name[i]) { +            case TGSI_SEMANTIC_COLOR: +                total_colors++; +                break; +            case TGSI_SEMANTIC_FOG: +            case TGSI_SEMANTIC_GENERIC: +                total_generic++; +                break; +        } +    } + +    for(i = 0; i < info->num_inputs; i++) { +        switch (info->input_semantic_name[i]) { +            case TGSI_SEMANTIC_COLOR: +                allocate(mydata, i, colors); +                colors++; +                break; +            case TGSI_SEMANTIC_FOG: +            case TGSI_SEMANTIC_GENERIC: +                allocate(mydata, i, total_colors + generic); +                generic++; +                break; +        } +    } +} + +void r300_translate_fragment_shader(struct r300_context* r300, +                                    struct r300_fragment_shader* fs) +{ +    struct r300_fragment_program_compiler compiler; +    struct tgsi_to_rc ttr; + +    memset(&compiler, 0, sizeof(compiler)); +    rc_init(&compiler.Base); +    compiler.Base.Debug = 1; + +    compiler.code = &fs->code; +    compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500; +    compiler.AllocateHwInputs = &allocate_hardware_inputs; +    compiler.UserData = fs; + +    /* TODO: Program compilation depends on texture compare modes, +     * which are sampler state. Therefore, programs need to be recompiled +     * depending on this state as in the classic Mesa driver. +     * +     * This is not yet handled correctly. +     */ + +    find_output_registers(&compiler, fs); + +    if (compiler.Base.Debug) { +        debug_printf("r300: Initial fragment program\n"); +        tgsi_dump(fs->state.tokens, 0); +    } + +    /* Translate TGSI to our internal representation */ +    ttr.compiler = &compiler.Base; +    ttr.info = &fs->info; + +    r300_tgsi_to_rc(&ttr, fs->state.tokens); + +    /* Invoke the compiler */ +    r3xx_compile_fragment_program(&compiler); +    if (compiler.Base.Error) { +        /* Todo: Fail gracefully */ +        fprintf(stderr, "r300 FP: Compiler error\n"); +        abort(); +    } + +    /* And, finally... */ +    rc_destroy(&compiler.Base); +    fs->translated = TRUE; +} diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h new file mode 100644 index 0000000000..9fab789402 --- /dev/null +++ b/src/gallium/drivers/r300/r300_fs.h @@ -0,0 +1,51 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.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_FS_H +#define R300_FS_H + +#include "tgsi/tgsi_dump.h" + +#include "r300_context.h" +#include "r3xx_fs.h" +#include "r5xx_fs.h" + +#include "radeon_code.h" + +struct r300_fragment_shader { +    /* Parent class */ +    struct pipe_shader_state state; +    struct tgsi_shader_info info; + +    /* Has this shader been translated yet? */ +    boolean translated; + +    /* Compiled code */ +    struct rX00_fragment_program_code code; +}; + + +void r300_translate_fragment_shader(struct r300_context* r300, +                                    struct r300_fragment_shader* fs); + +    #endif /* R300_FS_H */ diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c index 8fc61c2dec..1d5185b417 100644 --- a/src/gallium/drivers/r300/r300_query.c +++ b/src/gallium/drivers/r300/r300_query.c @@ -25,14 +25,30 @@  static struct pipe_query* r300_create_query(struct pipe_context* pipe,                                              unsigned query_type)  { -    struct r300_query* q = CALLOC_STRUCT(r300_query); +    struct r300_context* r300 = r300_context(pipe); +    struct r300_screen* r300screen = r300_screen(r300->context.screen); +    unsigned query_size = r300screen->caps->num_frag_pipes * 4; +    struct r300_query* q, * qptr; + +    q = CALLOC_STRUCT(r300_query);      q->type = query_type;      assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER); -    /* XXX this is to force winsys to give us a GTT buffer */ -    q->buf = pipe->screen->buffer_create(pipe->screen, 64, -            PIPE_BUFFER_USAGE_VERTEX, 64); +    q->active = FALSE; + +    if (!r300->query_list) { +        r300->query_list = q; +    } else if (!is_empty_list(r300->query_list)) { +        qptr = last_elem(r300->query_list); +        q->offset = qptr->offset + query_size; +        insert_at_tail(r300->query_list, q); +    } + +    /* XXX */ +    if (q->offset >= 4096) { +        q->offset = 0; +    }      return (struct pipe_query*)q;  } @@ -40,6 +56,9 @@ static struct pipe_query* r300_create_query(struct pipe_context* pipe,  static void r300_destroy_query(struct pipe_context* pipe,                                 struct pipe_query* query)  { +    struct r300_query* q = (struct r300_query*)query; + +    remove_from_list(q);      FREE(query);  } @@ -49,15 +68,15 @@ static void r300_begin_query(struct pipe_context* pipe,      uint32_t* map;      struct r300_context* r300 = r300_context(pipe);      struct r300_query* q = (struct r300_query*)query; -    CS_LOCALS(r300); -    map = pipe_buffer_map(pipe->screen, q->buf, PIPE_BUFFER_USAGE_CPU_WRITE); +    map = pipe->screen->buffer_map(pipe->screen, r300->oqbo, +            PIPE_BUFFER_USAGE_CPU_WRITE); +    map += q->offset / 4;      *map = ~0; -    pipe_buffer_unmap(pipe->screen, q->buf); +    pipe->screen->buffer_unmap(pipe->screen, r300->oqbo); -    BEGIN_CS(2); -    OUT_CS_REG(R300_ZB_ZPASS_DATA, 0); -    END_CS; +    r300_emit_dirty_state(r300); +    r300_emit_query_begin(r300, q);  }  static void r300_end_query(struct pipe_context* pipe, @@ -65,12 +84,9 @@ static void r300_end_query(struct pipe_context* pipe,  {      struct r300_context* r300 = r300_context(pipe);      struct r300_query* q = (struct r300_query*)query; -    CS_LOCALS(r300); -    BEGIN_CS(4); -    OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); -    OUT_CS_RELOC(q->buf, 0, 0, RADEON_GEM_DOMAIN_GTT, 0); -    END_CS; +    r300_emit_dirty_state(r300); +    r300_emit_query_end(r300, q);  }  static boolean r300_get_query_result(struct pipe_context* pipe, @@ -78,22 +94,38 @@ static boolean r300_get_query_result(struct pipe_context* pipe,                                       boolean wait,                                       uint64_t* result)  { +    struct r300_context* r300 = r300_context(pipe); +    struct r300_screen* r300screen = r300_screen(r300->context.screen);      struct r300_query* q = (struct r300_query*)query; +    unsigned flags = PIPE_BUFFER_USAGE_CPU_READ;      uint32_t* map;      uint32_t temp; +    unsigned i;      if (wait) { -        /* Well, we're expected to just sit here and spin, so let's go ahead -         * and flush so we can be sure that the card's spinning... */ -        /* XXX double-check these params */          pipe->flush(pipe, 0, NULL); +    } else { +        flags |= PIPE_BUFFER_USAGE_DONTBLOCK;      } -    map = pipe_buffer_map(pipe->screen, q->buf, PIPE_BUFFER_USAGE_CPU_READ); -    temp = *map; -    pipe_buffer_unmap(pipe->screen, q->buf); +    map = pipe->screen->buffer_map(pipe->screen, r300->oqbo, flags); +    map += q->offset / 4; +    for (i = 0; i < r300screen->caps->num_frag_pipes; i++) { +        if (*map == ~0) { +            /* Looks like our results aren't ready yet. */ +            if (wait) { +                debug_printf("r300: Despite waiting, OQ results haven't" +                        " come in yet.\n"); +            } +            temp = ~0; +            break; +        } +        temp += *map; +        map++; +    } +    pipe->screen->buffer_unmap(pipe->screen, r300->oqbo); -    if (temp < 0) { +    if (temp == ~0) {          /* Our results haven't been written yet... */          return FALSE;      } diff --git a/src/gallium/drivers/r300/r300_query.h b/src/gallium/drivers/r300/r300_query.h index 4f447ea45b..4f50e8f844 100644 --- a/src/gallium/drivers/r300/r300_query.h +++ b/src/gallium/drivers/r300/r300_query.h @@ -27,12 +27,7 @@  #include "r300_cs.h"  #include "r300_reg.h" -struct r300_query { -    /* The kind of query. Currently only OQ is supported. */ -    unsigned type; -    /* Buffer object where we want our results to reside. */ -    struct pipe_buffer* buf; -}; +struct r300_context;  static INLINE struct r300_query* r300_query(struct pipe_query* q)  { diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 660816e1da..03cd219cde 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -511,11 +511,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #       define R300_PVS_XYZW_VALID_INST_SHIFT    10  #       define R300_PVS_LAST_INST_SHIFT          20  #       define R300_PVS_FIRST_INST(x)            ((x) << 0) +#       define R300_PVS_XYZW_VALID_INST(x)       ((x) << 10)  #       define R300_PVS_LAST_INST(x)             ((x) << 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_PVS_MAX_CONST_ADDR(x)        ((x) << 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 @@ -1062,8 +1064,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.          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_FLAT | \ -        R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST ) +        R300_GA_COLOR_CONTROL_ALPHA3_SHADING_FLAT )  #       define R300_SHADE_MODEL_SMOOTH ( \          R300_GA_COLOR_CONTROL_RGB0_SHADING_GOURAUD | \ @@ -1073,8 +1074,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.          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 ) +        R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD )  /* Specifies red & green components of fill color -- S312 format -- Backwards comp. */  #define R300_GA_SOLID_RG                         0x427c @@ -1478,6 +1478,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #       define R300_TX_PITCH_EN                  (1 << 31)  #       define R300_TX_WIDTH(x)                  ((x) << 0)  #       define R300_TX_HEIGHT(x)                 ((x) << 11) +#       define R300_TX_NUM_LEVELS(x)             ((x) << 26)  #define R300_TX_FORMAT1_0                   0x44C0  	/* The interpretation of the format word by Wladimir van der Laan */ @@ -1485,9 +1486,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  	   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 @@ -1504,31 +1503,29 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #	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 */ +#	define R300_TX_FORMAT_Y8           	    0x12 +#	define R300_TX_FORMAT_AVYU444 	    	    0x13 +#	define R300_TX_FORMAT_VYUY422  	    	    0x14 +#	define R300_TX_FORMAT_YVYU422  	    	    0x15 +#	define R300_TX_FORMAT_16_MPEG  	    	    0x16 +#	define R300_TX_FORMAT_16_16_MPEG    	    0x17 +#	define R300_TX_FORMAT_16F     	    	    0x18 +#	define R300_TX_FORMAT_16F_16F 	    	    0x19 +#	define R300_TX_FORMAT_16F_16F_16F_16F  	    0x1A +#	define R300_TX_FORMAT_32F     	    	    0x1B +#	define R300_TX_FORMAT_32F_32F 	    	    0x1C +#	define R300_TX_FORMAT_32F_32F_32F_32F  	    0x1D +#       define R300_TX_FORMAT_W24_FP                0x1E -	/* 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 +#       define R300_TX_FORMAT_SIGNED_W             (1 << 5) +#       define R300_TX_FORMAT_SIGNED_Z             (1 << 6) +#       define R300_TX_FORMAT_SIGNED_Y             (1 << 7) +#       define R300_TX_FORMAT_SIGNED_X             (1 << 8) +#       define R300_TX_FORMAT_SIGNED               (0xf << 5) -	/* 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 */ @@ -1569,7 +1566,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #	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_FORMAT_GAMMA               (1 << 21) +#       define R300_TX_FORMAT_YUV_TO_RGB          (1 << 22)  #define R300_TX_FORMAT2_0		    0x4500 /* obvious missing in gap */  #       define R300_TX_PITCHMASK_SHIFT           0 @@ -3040,6 +3038,7 @@ enum {  #   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_RGB_WMASK_RGB			(7 << 11)  #   define R500_INST_ALPHA_WMASK			(1 << 14)  #   define R500_INST_RGB_OMASK_R			(1 << 15)  #   define R500_INST_RGB_OMASK_G			(1 << 16) @@ -3313,6 +3312,10 @@ enum {  #define R200_3D_DRAW_IMMD_2      0xC0003500 +/* XXX Oh look, stuff not brought over from docs yet */ + +#define R300_SU_REG_DEST                    0x42C8 +  #endif /* _R300_REG_H */  /* *INDENT-ON* */ diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index cbd84d7c56..cd458d019a 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -45,11 +45,7 @@ struct r300_render {      /* VBO */      struct pipe_buffer* vbo; -    size_t vbo_size; -    size_t vbo_offset; -    void* vbo_map;      size_t vbo_alloc_size; -    size_t vbo_max_used;  };  static INLINE struct r300_render* @@ -78,24 +74,21 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render,      struct pipe_screen* screen = r300->context.screen;      size_t size = (size_t)vertex_size * (size_t)count; -    if (r300render->vbo) { +    if (r300render->vbo && (size > r300render->vbo_alloc_size)) {          pipe_buffer_reference(&r300render->vbo, NULL);      } +     +    if (!r300render->vbo) { +        r300render->vbo = pipe_buffer_create(screen, +                                             64, +                                             PIPE_BUFFER_USAGE_VERTEX, +                                             size); +    } -    r300render->vbo_size = MAX2(size, r300render->vbo_alloc_size); -    r300render->vbo_offset = 0; -    r300render->vbo = pipe_buffer_create(screen, -                                         64, -                                         PIPE_BUFFER_USAGE_VERTEX, -                                         r300render->vbo_size); - +    r300render->vbo_alloc_size = MAX2(size, r300render->vbo_alloc_size);      r300render->vertex_size = vertex_size; -    if (r300render->vbo) { -        return TRUE; -    } else { -        return FALSE; -    } +    return (r300render->vbo) ? TRUE : FALSE;  }  static void* r300_render_map_vertices(struct vbuf_render* render) @@ -103,10 +96,8 @@ static void* r300_render_map_vertices(struct vbuf_render* render)      struct r300_render* r300render = r300_render(render);      struct pipe_screen* screen = r300render->r300->context.screen; -    r300render->vbo_map = pipe_buffer_map(screen, r300render->vbo, -                                          PIPE_BUFFER_USAGE_CPU_WRITE); - -    return (unsigned char*)r300render->vbo_map + r300render->vbo_offset; +    return (unsigned char*)pipe_buffer_map(screen, r300render->vbo, +                                           PIPE_BUFFER_USAGE_CPU_WRITE);  }  static void r300_render_unmap_vertices(struct vbuf_render* render, @@ -116,9 +107,6 @@ static void r300_render_unmap_vertices(struct vbuf_render* render,      struct r300_render* r300render = r300_render(render);      struct pipe_screen* screen = r300render->r300->context.screen; -    r300render->vbo_max_used = MAX2(r300render->vbo_max_used, -             r300render->vertex_size * (max + 1)); -      pipe_buffer_unmap(screen, r300render->vbo);  } @@ -180,27 +168,9 @@ static void prepare_render(struct r300_render* render, unsigned count)      CS_LOCALS(r300); -    /* Make sure that all possible state is emitted. */ -    r300_emit_dirty_state(r300); +    r300->vbo = render->vbo; -    debug_printf("r300: Preparing vertex buffer %p for render, " -            "vertex size %d, vertex count %d\n", render->vbo, -            r300->vertex_info.vinfo.size, count); -    /* Set the pointer to our vertex buffer. The emitted values are this: -     * PACKET3 [3D_LOAD_VBPNTR] -     * COUNT   [1] -     * FORMAT  [size | stride << 8] -     * OFFSET  [0] -     * VBPNTR  [relocated BO] -     */ -    BEGIN_CS(7); -    OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3); -    OUT_CS(1); -    OUT_CS(r300->vertex_info.vinfo.size | -            (r300->vertex_info.vinfo.size << 8)); -    OUT_CS(render->vbo_offset); -    OUT_CS_RELOC(render->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); -    END_CS; +    r300_emit_dirty_state(r300);  }  static void r300_render_draw_arrays(struct vbuf_render* render, @@ -212,8 +182,6 @@ static void r300_render_draw_arrays(struct vbuf_render* render,      CS_LOCALS(r300); -    r300render->vbo_offset = start; -      prepare_render(r300render, count);      debug_printf("r300: Doing vbuf render, count %d\n", count); @@ -248,13 +216,14 @@ static void r300_render_draw(struct vbuf_render* render,          return;      } +/*      index_map = pipe_buffer_map(screen, index_buffer,                                  PIPE_BUFFER_USAGE_CPU_WRITE);      memcpy(index_map, indices, count);      pipe_buffer_unmap(screen, index_buffer);      debug_printf("r300: Doing indexbuf render, count %d\n", count); -/* +      BEGIN_CS(8);      OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);      OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | @@ -264,13 +233,15 @@ static void r300_render_draw(struct vbuf_render* render,      OUT_CS_INDEX_RELOC(index_buffer, 0, count, RADEON_GEM_DOMAIN_GTT, 0, 0);      END_CS; */ -    BEGIN_CS(2 + count); -    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, count); +    BEGIN_CS(2 + (count+1)/2); +    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2);      OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | -           r300render->hwprim | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); -    for (i = 0; i < count; i++) { -        index = indices[i]; -        OUT_CS(index); +           r300render->hwprim); +    for (i = 0; i < count-1; i += 2) { +        OUT_CS(indices[i+1] << 16 | indices[i]); +    } +    if (count % 2) { +        OUT_CS(indices[count-1]);      }      END_CS;  } diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index d2c5998c26..15740f6125 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -87,23 +87,24 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)              } else {                  return 0;              } -            return 0;          case PIPE_CAP_GLSL: -            /* IN THEORY */ -            return 0; +            if (r300screen->caps->is_r500) { +                return 1; +            } else { +                return 0; +            }          case PIPE_CAP_S3TC: -            /* IN THEORY */ -            return 0; +            return 1;          case PIPE_CAP_ANISOTROPIC_FILTER: -            /* IN THEORY */ -            return 0; +            return 1;          case PIPE_CAP_POINT_SPRITE:              /* IN THEORY */              return 0;          case PIPE_CAP_MAX_RENDER_TARGETS:              return 4;          case PIPE_CAP_OCCLUSION_QUERY: -            return 1; +            /* IN THEORY */ +            return 0;          case PIPE_CAP_TEXTURE_SHADOW_MAP:              /* IN THEORY */              return 0; @@ -143,6 +144,11 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)          case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:              /* XXX guessing (what a terrible guess) */              return 2; +        case PIPE_CAP_TGSI_CONT_SUPPORTED: +            /* XXX */ +            return 0; +        case PIPE_CAP_BLEND_EQUATION_SEPARATE: +            return 1;          default:              debug_printf("r300: Implementation error: Bad param %d\n",                  param); @@ -152,17 +158,20 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)  static float r300_get_paramf(struct pipe_screen* pscreen, int param)  { +    struct r300_screen* r300screen = r300_screen(pscreen); +      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; +            /* The maximum dimensions of the colorbuffer are our practical +             * rendering limits. 2048 pixels should be enough for anybody. */ +            if (r300screen->caps->is_r500) { +                return 4096.0f; +            } else { +                return 2048.0f; +            }          case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:              return 16.0f;          case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: @@ -174,21 +183,58 @@ static float r300_get_paramf(struct pipe_screen* pscreen, int param)      }  } -static boolean check_tex_2d_format(enum pipe_format format, boolean is_r500) +static boolean check_tex_2d_format(enum pipe_format format, uint32_t usage, +                                   boolean is_r500)  {      switch (format) { +        /* Supported formats. */          /* Colorbuffer */          case PIPE_FORMAT_A4R4G4B4_UNORM:          case PIPE_FORMAT_R5G6B5_UNORM:          case PIPE_FORMAT_A1R5G5B5_UNORM: -        case PIPE_FORMAT_A8R8G8B8_UNORM: +            return usage & +                (PIPE_TEXTURE_USAGE_RENDER_TARGET | +                 PIPE_TEXTURE_USAGE_DISPLAY_TARGET | +                 PIPE_TEXTURE_USAGE_PRIMARY); + +        /* Texture */ +        case PIPE_FORMAT_A8R8G8B8_SRGB: +        case PIPE_FORMAT_R8G8B8A8_SRGB: +        case PIPE_FORMAT_DXT1_RGB: +        case PIPE_FORMAT_DXT1_RGBA: +        case PIPE_FORMAT_DXT3_RGBA: +        case PIPE_FORMAT_DXT5_RGBA: +        case PIPE_FORMAT_YCBCR: +            return usage & PIPE_TEXTURE_USAGE_SAMPLER; +          /* Colorbuffer or texture */ +        case PIPE_FORMAT_A8R8G8B8_UNORM: +        case PIPE_FORMAT_R8G8B8A8_UNORM:          case PIPE_FORMAT_I8_UNORM: +            return usage & +                (PIPE_TEXTURE_USAGE_RENDER_TARGET | +                 PIPE_TEXTURE_USAGE_DISPLAY_TARGET | +                 PIPE_TEXTURE_USAGE_PRIMARY | +                 PIPE_TEXTURE_USAGE_SAMPLER); +          /* Z buffer */          case PIPE_FORMAT_Z16_UNORM: -        /* Z buffer with stencil */ +            return usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL; + +        /* Z buffer with stencil or texture */          case PIPE_FORMAT_Z24S8_UNORM: -            return TRUE; +            return usage & +                (PIPE_TEXTURE_USAGE_DEPTH_STENCIL | +                 PIPE_TEXTURE_USAGE_SAMPLER); + +        /* Definitely unsupported formats. */ +        /* Non-usable Z buffer/stencil formats. */ +        case PIPE_FORMAT_Z24X8_UNORM: +        case PIPE_FORMAT_S8Z24_UNORM: +        case PIPE_FORMAT_X8Z24_UNORM: +            debug_printf("r300: Note: Got unsupported format: %s in %s\n", +                pf_name(format), __FUNCTION__); +            return FALSE;          /* XXX These don't even exist          case PIPE_FORMAT_A32R32G32B32: @@ -211,7 +257,8 @@ static boolean check_tex_2d_format(enum pipe_format format, boolean is_r500)              return FALSE; */          default: -            debug_printf("r300: Warning: Got unsupported format: %s in %s\n", +            /* Unknown format... */ +            debug_printf("r300: Warning: Got unknown format: %s in %s\n",                  pf_name(format), __FUNCTION__);              break;      } @@ -228,11 +275,18 @@ static boolean r300_is_format_supported(struct pipe_screen* pscreen,  {      switch (target) {          case PIPE_TEXTURE_2D: -            return check_tex_2d_format(format, +            return check_tex_2d_format(format, tex_usage,                  r300_screen(pscreen)->caps->is_r500); +        case PIPE_TEXTURE_1D: +        case PIPE_TEXTURE_3D: +        case PIPE_TEXTURE_CUBE: +            debug_printf("r300: Implementation error: Unsupported format " +                    "target: %d\n", target); +            break;          default: -            debug_printf("r300: Warning: Got unknown format target: %d\n", -                format); +            debug_printf("r300: Fatal: This is not a format target: %d\n", +                target); +            assert(0);              break;      } @@ -268,13 +322,14 @@ r300_get_tex_transfer(struct pipe_screen *screen,      trans = CALLOC_STRUCT(r300_transfer);      if (trans) {          pipe_texture_reference(&trans->transfer.texture, texture); -        trans->transfer.format = trans->transfer.format; +        trans->transfer.format = texture->format;          trans->transfer.width = w;          trans->transfer.height = h;          trans->transfer.block = texture->block;          trans->transfer.nblocksx = texture->nblocksx[level];          trans->transfer.nblocksy = texture->nblocksy[level]; -        trans->transfer.stride = tex->stride; +        trans->transfer.stride = align(pf_get_stride(&trans->transfer.block, +                                                     texture->width[level]), 32);          trans->transfer.usage = usage;          trans->offset = offset;      } diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 3f52dbc3be..2a0e41fbc3 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -49,7 +49,7 @@ struct r300_transfer {  };  /* Convenience cast wrapper. */ -static struct r300_screen* r300_screen(struct pipe_screen* screen) { +static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) {      return (struct r300_screen*)screen;  } diff --git a/src/gallium/drivers/r300/r300_shader_inlines.h b/src/gallium/drivers/r300/r300_shader_inlines.h new file mode 100644 index 0000000000..a04f45b03e --- /dev/null +++ b/src/gallium/drivers/r300/r300_shader_inlines.h @@ -0,0 +1,47 @@ +/* + * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.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_SHADER_INLINES_H +#define R300_SHADER_INLINES_H + +/* TGSI constants. TGSI is like XML: If it can't solve your problems, you're + * not using enough of it. */ +static const struct tgsi_full_src_register r300_constant_zero = { +    .SrcRegister.Extended = TRUE, +    .SrcRegister.File = TGSI_FILE_NULL, +    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO, +    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO, +    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO, +    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO, +}; + +static const struct tgsi_full_src_register r300_constant_one = { +    .SrcRegister.Extended = TRUE, +    .SrcRegister.File = TGSI_FILE_NULL, +    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ONE, +    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ONE, +    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ONE, +    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ONE, +}; + +#endif /* R300_SHADER_INLINES_H */ diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 184a23c9e6..c16cadd040 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -24,12 +24,15 @@  #include "util/u_pack_color.h"  #include "util/u_debug.h" + +#include "pipe/p_config.h"  #include "pipe/internal/p_winsys_screen.h"  #include "r300_context.h"  #include "r300_reg.h"  #include "r300_state_inlines.h" -#include "r300_state_shader.h" +#include "r300_fs.h" +#include "r300_vs.h"  /* r300_state: Functions used to intialize state context by translating   * Gallium state objects into semi-native r300 state objects. */ @@ -62,8 +65,6 @@ static void* r300_create_blend_state(struct pipe_context* pipe,      }      /* 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; @@ -121,9 +122,14 @@ 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); + +    if (r300_screen(pipe->screen)->caps->has_tcl) { +        r300->clip_state = *state; +        r300->dirty_state |= R300_NEW_CLIP; +    } else { +        draw_flush(r300->draw); +        draw_set_clip_state(r300->draw, state); +    }  }  static void @@ -132,7 +138,6 @@ static void                               const struct pipe_constant_buffer* buffer)  {      struct r300_context* r300 = r300_context(pipe); -    int i = r300->shader_constants[shader].user_count;      /* This entire chunk of code seems ever-so-slightly baked.       * It's as if I've got pipe_buffer* matryoshkas... */ @@ -143,24 +148,13 @@ static void              map, buffer->buffer->size);          pipe->winsys->buffer_unmap(pipe->winsys, buffer->buffer); -        r300->shader_constants[shader].user_count = +        r300->shader_constants[shader].count =              buffer->buffer->size / (sizeof(float) * 4);      } else { -        r300->shader_constants[shader].user_count = 0; +        r300->shader_constants[shader].count = 0;      }      r300->dirty_state |= R300_NEW_CONSTANTS; - -    /* If the number of constants have changed, invalidate the shader. */ -    if (r300->shader_constants[shader].user_count != i) { -        if (shader == PIPE_SHADER_FRAGMENT && r300->fs) { -            r300->fs->translated = FALSE; -            r300_translate_fragment_shader(r300, r300->fs); -        } else if (shader == PIPE_SHADER_VERTEX && r300->vs) { -            r300->vs->translated = FALSE; -            r300_translate_vertex_shader(r300, r300->vs); -        } -    }  }  /* Create a new depth, stencil, and alpha state based on the CSO dsa state. @@ -230,7 +224,8 @@ static void*          dsa->alpha_reference = CLAMP(state->alpha.ref_value * 1023.0f,                                       0, 1023);      } else { -        dsa->z_buffer_top = R300_ZTOP_ENABLE; +        /* XXX need to fix this to be dynamically set +        dsa->z_buffer_top = R300_ZTOP_ENABLE; */      }      return (void*)dsa; @@ -257,6 +252,7 @@ static void r300_set_edgeflags(struct pipe_context* pipe,                                 const unsigned* bitfield)  {      /* XXX you know it's bad when i915 has this blank too */ +    /* XXX and even worse, I have no idea WTF the bitfield is */  }  static void @@ -276,19 +272,13 @@ static void  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; +    struct r300_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); -    } +    fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader);      /* Copy state directly into shader. */      fs->state = *shader; +    fs->state.tokens = tgsi_dup_tokens(shader->tokens);      tgsi_scan_shader(shader->tokens, &fs->info); @@ -299,7 +289,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe,  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; +    struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;      if (fs == NULL) {          r300->fs = NULL; @@ -308,7 +298,6 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)          r300_translate_fragment_shader(r300, fs);      } -    fs->translated = TRUE;      r300->fs = fs;      r300->dirty_state |= R300_NEW_FRAGMENT_SHADER; @@ -317,13 +306,16 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)  /* Delete fragment shader state. */  static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)  { +    struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; +    rc_constants_destroy(&fs->code.constants); +    FREE(fs->state.tokens);      FREE(shader);  }  static void r300_set_polygon_stipple(struct pipe_context* pipe,                                       const struct pipe_poly_stipple* state)  { -    /* XXX */ +    /* XXX no idea how to set this up, but not terribly important */  }  /* Create a new rasterizer state based on the CSO rasterizer state. @@ -341,14 +333,21 @@ static void* r300_create_rs_state(struct pipe_context* pipe,      /* Copy rasterizer state for Draw. */      rs->rs = *state; +    rs->enable_vte = !state->bypass_vs_clip_and_viewport; + +#ifdef PIPE_ARCH_LITTLE_ENDIAN +    rs->vap_control_status = R300_VC_NO_SWAP; +#else +    rs->vap_control_status = R300_VC_32BIT_SWAP; +#endif +      /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL.       * Else, enable HW TCL and force Draw's TCL off. */      if (state->bypass_vs_clip_and_viewport ||              !r300_screen(pipe->screen)->caps->has_tcl) { -        rs->vap_control_status = R300_VAP_TCL_BYPASS; +        rs->vap_control_status |= R300_VAP_TCL_BYPASS;      } else {          rs->rs.bypass_vs_clip_and_viewport = TRUE; -        rs->vap_control_status = 0;      }      rs->point_size = pack_float_16_6x(state->point_size) | @@ -412,6 +411,10 @@ static void* r300_create_rs_state(struct pipe_context* pipe,          rs->color_control = R300_SHADE_MODEL_SMOOTH;      } +    if (!state->flatshade_first) { +        rs->color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST; +    } +      return (void*)rs;  } @@ -535,16 +538,16 @@ static void r300_set_scissor_state(struct pipe_context* pipe,              (state->minx << R300_SCISSORS_X_SHIFT) |              (state->miny << R300_SCISSORS_Y_SHIFT);          r300->scissor_state->scissor_bottom_right = -            (state->maxx << R300_SCISSORS_X_SHIFT) | -            (state->maxy << R300_SCISSORS_Y_SHIFT); +            ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) | +            ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT);      } else {          /* Offset of 1440 in non-R500 chipsets. */          r300->scissor_state->scissor_top_left =              ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) |              ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT);          r300->scissor_state->scissor_bottom_right = -            ((state->maxx + 1440) << R300_SCISSORS_X_SHIFT) | -            ((state->maxy + 1440) << R300_SCISSORS_Y_SHIFT); +            (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) | +            (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);      }      r300->dirty_state |= R300_NEW_SCISSOR; @@ -555,40 +558,35 @@ static void r300_set_viewport_state(struct pipe_context* pipe,  {      struct r300_context* r300 = r300_context(pipe); -    draw_flush(r300->draw); - -    if (r300_screen(r300->context.screen)->caps->has_tcl) { -        /* Do the transform in HW. */ -        r300->viewport_state->vte_control = R300_VTX_W0_FMT; +    /* Do the transform in HW. */ +    r300->viewport_state->vte_control = R300_VTX_W0_FMT; -        if (state->scale[0] != 1.0f) { -            r300->viewport_state->xscale = state->scale[0]; -            r300->viewport_state->vte_control |= R300_VPORT_X_SCALE_ENA; -        } -        if (state->scale[1] != 1.0f) { -            r300->viewport_state->yscale = state->scale[1]; -            r300->viewport_state->vte_control |= R300_VPORT_Y_SCALE_ENA; -        } -        if (state->scale[2] != 1.0f) { -            r300->viewport_state->zscale = state->scale[2]; -            r300->viewport_state->vte_control |= R300_VPORT_Z_SCALE_ENA; -        } -        if (state->translate[0] != 0.0f) { -            r300->viewport_state->xoffset = state->translate[0]; -            r300->viewport_state->vte_control |= R300_VPORT_X_OFFSET_ENA; -        } -        if (state->translate[1] != 0.0f) { -            r300->viewport_state->yoffset = state->translate[1]; -            r300->viewport_state->vte_control |= R300_VPORT_Y_OFFSET_ENA; -        } -        if (state->translate[2] != 0.0f) { -            r300->viewport_state->zoffset = state->translate[2]; -            r300->viewport_state->vte_control |= R300_VPORT_Z_OFFSET_ENA; -        } -    } else { -        r300->viewport_state->vte_control = 0; -        /* Have Draw do the actual transform. */ -        draw_set_viewport_state(r300->draw, state); +    if (state->scale[0] != 1.0f) { +        assert(state->scale[0] != 0.0f); +        r300->viewport_state->xscale = state->scale[0]; +        r300->viewport_state->vte_control |= R300_VPORT_X_SCALE_ENA; +    } +    if (state->scale[1] != 1.0f) { +        assert(state->scale[1] != 0.0f); +        r300->viewport_state->yscale = state->scale[1]; +        r300->viewport_state->vte_control |= R300_VPORT_Y_SCALE_ENA; +    } +    if (state->scale[2] != 1.0f) { +        assert(state->scale[2] != 0.0f); +        r300->viewport_state->zscale = state->scale[2]; +        r300->viewport_state->vte_control |= R300_VPORT_Z_SCALE_ENA; +    } +    if (state->translate[0] != 0.0f) { +        r300->viewport_state->xoffset = state->translate[0]; +        r300->viewport_state->vte_control |= R300_VPORT_X_OFFSET_ENA; +    } +    if (state->translate[1] != 0.0f) { +        r300->viewport_state->yoffset = state->translate[1]; +        r300->viewport_state->vte_control |= R300_VPORT_Y_OFFSET_ENA; +    } +    if (state->translate[2] != 0.0f) { +        r300->viewport_state->zoffset = state->translate[2]; +        r300->viewport_state->vte_control |= R300_VPORT_Z_OFFSET_ENA;      }      r300->dirty_state |= R300_NEW_VIEWPORT; @@ -628,6 +626,7 @@ static void* r300_create_vs_state(struct pipe_context* pipe,          struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);          /* Copy state directly into shader. */          vs->state = *shader; +        vs->state.tokens = tgsi_dup_tokens(shader->tokens);          tgsi_scan_shader(shader->tokens, &vs->info); @@ -672,7 +671,9 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)      if (r300_screen(pipe->screen)->caps->has_tcl) {          struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; +        rc_constants_destroy(&vs->code.constants);          draw_delete_vertex_shader(r300->draw, vs->draw); +        FREE(vs->state.tokens);          FREE(shader);      } else {          draw_delete_vertex_shader(r300->draw, diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index c4c9784a00..c01e61a9b1 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -22,6 +22,9 @@  #include "r300_state_derived.h" +#include "r300_fs.h" +#include "r300_vs.h" +  /* r300_state_derived: Various bits of state which are dependent upon   * currently bound CSO data. */ @@ -46,63 +49,71 @@ static void r300_vs_tab_routes(struct r300_context* r300,      assert(info->num_inputs <= 16); -    if (r300screen->caps->has_tcl) { -        /* Just copy vert attribs over as-is. */ +    if (!r300screen->caps->has_tcl || !r300->rs_state->enable_vte) +    {          for (i = 0; i < info->num_inputs; i++) { -            tab[i] = i; -        } -        for (i = 0; i < info->num_outputs; i++) { -            switch (info->output_semantic_name[i]) { +            switch (info->input_semantic_name[i]) {                  case TGSI_SEMANTIC_POSITION:                      pos = TRUE; +                    tab[i] = 0;                      break;                  case TGSI_SEMANTIC_COLOR: +                    tab[i] = 2 + cols;                      cols++;                      break;                  case TGSI_SEMANTIC_PSIZE:                      psize = TRUE; +                    tab[i] = 15;                      break;                  case TGSI_SEMANTIC_FOG:                      fog = TRUE; +                    /* Fall through */                  case TGSI_SEMANTIC_GENERIC: +                    tab[i] = 6 + texs;                      texs++;                      break;                  default: -                    debug_printf("r300: Unknown vertex output %d\n", -                        info->output_semantic_name[i]); +                    debug_printf("r300: Unknown vertex input %d\n", +                        info->input_semantic_name[i]);                      break;              }          } -    } else { +    } +    else +    { +        /* Just copy vert attribs over as-is. */          for (i = 0; i < info->num_inputs; i++) { -            switch (info->input_semantic_name[i]) { +            tab[i] = i; +        } + +        for (i = 0; i < info->num_outputs; i++) { +            switch (info->output_semantic_name[i]) {                  case TGSI_SEMANTIC_POSITION:                      pos = TRUE; -                    tab[i] = 0;                      break;                  case TGSI_SEMANTIC_COLOR: -                    tab[i] = 2 + cols;                      cols++;                      break;                  case TGSI_SEMANTIC_PSIZE:                      psize = TRUE; -                    tab[i] = 15;                      break;                  case TGSI_SEMANTIC_FOG:                      fog = TRUE;                      /* Fall through */                  case TGSI_SEMANTIC_GENERIC: -                    tab[i] = 6 + texs;                      texs++;                      break;                  default: -                    debug_printf("r300: Unknown vertex input %d\n", -                        info->input_semantic_name[i]); +                    debug_printf("r300: Unknown vertex output %d\n", +                        info->output_semantic_name[i]);                      break;              }          }      } +    /* XXX magic */ +    assert(texs <= 8); +      /* Do the actual vertex_info setup.       *       * vertex_info has four uints of hardware-specific data in it. @@ -140,21 +151,32 @@ static void r300_vs_tab_routes(struct r300_context* r300,          vinfo->hwfmt[2] |= (R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i);      } -    for (i = 0; i < texs; i++) { +    /* Init i right here, increment it if fog is enabled. +     * This gets around a double-increment problem. */ +    i = 0; + +    if (fog) { +        i++;          draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, -            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i)); +            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_FOG, 0));          vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);          vinfo->hwfmt[3] |= (4 << (3 * i));      } -    if (fog) { -        i++; +    for (i; i < texs; i++) {          draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, -            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_FOG, 0)); +            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i));          vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);          vinfo->hwfmt[3] |= (4 << (3 * i));      } +    /* Handle the case where the vertex shader will be generating some of +     * the attribs based on its inputs. */ +    if (r300screen->caps->has_tcl && +            info->num_inputs < info->num_outputs) { +        vinfo->num_attribs = info->num_inputs; +    } +      draw_compute_vertex_size(vinfo);  } @@ -162,26 +184,40 @@ static void r300_vs_tab_routes(struct r300_context* r300,  static void r300_vertex_psc(struct r300_context* r300,                              struct r300_vertex_format* vformat)  { +    struct r300_screen* r300screen = r300_screen(r300->context.screen);      struct vertex_info* vinfo = &vformat->vinfo;      int* tab = vformat->vs_tab;      uint32_t temp; -    int i; +    int i, attrib_count; -    debug_printf("r300: attrib count: %d\n", vinfo->num_attribs); -    for (i = 0; i < vinfo->num_attribs; i++) { -        debug_printf("r300: attrib: offset %d, interp %d, size %d," -               " tab %d\n", vinfo->attrib[i].src_index, -               vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, -               tab[i]); +    /* Vertex shaders have no semantics on their inputs, +     * so PSC should just route stuff based on their info, +     * and not on attrib information. */ +    if (r300screen->caps->has_tcl) { +        attrib_count = r300->vs->info.num_inputs; +        debug_printf("r300: routing %d attribs in psc for vs\n", +                attrib_count); +    } else { +        attrib_count = vinfo->num_attribs; +        debug_printf("r300: attrib count: %d\n", attrib_count); +        for (i = 0; i < attrib_count; i++) { +            debug_printf("r300: attrib: offset %d, interp %d, size %d," +                   " tab %d\n", vinfo->attrib[i].src_index, +                   vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, +                   tab[i]); +        }      } -    for (i = 0; i < vinfo->num_attribs; i++) { +    for (i = 0; i < attrib_count; i++) {          /* Make sure we have a proper destination for our attribute */          assert(tab[i] != -1);          /* Add the attribute to the PSC table. */ -        temp = translate_vertex_data_type(vinfo->attrib[i].emit) | -            (tab[i] << R300_DST_VEC_LOC_SHIFT); +        temp = r300screen->caps->has_tcl ? +            R300_DATA_TYPE_FLOAT_4 : +            translate_vertex_data_type(vinfo->attrib[i].emit); +        temp |= tab[i] << R300_DST_VEC_LOC_SHIFT; +          if (i & 1) {              vformat->vap_prog_stream_cntl[i >> 1] &= 0x0000ffff;              vformat->vap_prog_stream_cntl[i >> 1] |= temp << 16; @@ -206,7 +242,6 @@ static void r300_vertex_psc(struct r300_context* r300,  /* Update the vertex format. */  static void r300_update_vertex_format(struct r300_context* r300)  { -    struct r300_screen* r300screen = r300_screen(r300->context.screen);      struct r300_vertex_format vformat;      int i; diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index 8bd9b41bd7..7d822fec48 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -34,42 +34,31 @@ void r300_emit_invariant_state(struct r300_context* r300)      struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;      CS_LOCALS(r300); -    BEGIN_CS(30 + (caps->has_tcl ? 2: 0)); +    BEGIN_CS(24 + (caps->has_tcl ? 2: 0));      /*** Graphics Backend (GB) ***/      /* Various GB enables */ -    OUT_CS_REG(R300_GB_ENABLE, 0x0); -    /* Subpixel multisampling for AA */ -    OUT_CS_REG(R300_GB_MSPOS0, 0x66666666); -    OUT_CS_REG(R300_GB_MSPOS1, 0x66666666); -    /* GB tile config and pipe setup */ -    OUT_CS_REG(R300_GB_TILE_CONFIG, R300_GB_TILE_DISABLE | -        r300_translate_gb_pipes(caps->num_frag_pipes)); +    OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE | +                               R300_GB_LINE_STUFF_ENABLE  | +                               R300_GB_TRIANGLE_STUFF_ENABLE); +    /* Subpixel multisampling for AA +     * These are commented out because glisse's CS checker doesn't like them. +     * I presume these will be re-enabled later. +     * OUT_CS_REG(R300_GB_MSPOS0, 0x66666666); +     * OUT_CS_REG(R300_GB_MSPOS1, 0x6666666); +     */      /* Source of fog depth */      OUT_CS_REG(R300_GB_SELECT, R300_GB_FOG_SELECT_1_1_W);      /* AA enable */      OUT_CS_REG(R300_GB_AA_CONFIG, 0x0); -    /*** Geometry Assembly (GA) ***/ -    /* GA errata fixes. */ -    if (caps->is_r500) { -        OUT_CS_REG(R300_GA_ENHANCE, -                R300_GA_ENHANCE_DEADLOCK_CNTL_PREVENT_TCL | -                R300_GA_ENHANCE_FASTSYNC_CNTL_ENABLE | -                R500_GA_ENHANCE_REG_READWRITE_ENABLE | -                R500_GA_ENHANCE_REG_NOSTALL_ENABLE); -    } else { -        OUT_CS_REG(R300_GA_ENHANCE, -                R300_GA_ENHANCE_DEADLOCK_CNTL_PREVENT_TCL | -                R300_GA_ENHANCE_FASTSYNC_CNTL_ENABLE); -    } -      /*** Fog (FG) ***/      OUT_CS_REG(R300_FG_FOG_BLEND, 0x0);      OUT_CS_REG(R300_FG_FOG_COLOR_R, 0x0);      OUT_CS_REG(R300_FG_FOG_COLOR_G, 0x0);      OUT_CS_REG(R300_FG_FOG_COLOR_B, 0x0);      OUT_CS_REG(R300_FG_DEPTH_SRC, 0x0); +    OUT_CS_REG(R300_US_W_FMT, 0x0);      /*** VAP ***/      /* Max and min vertex index clamp. */ @@ -86,7 +75,7 @@ void r300_emit_invariant_state(struct r300_context* r300)      END_CS;      /* XXX unsorted stuff from surface_fill */ -    BEGIN_CS(79 + (caps->has_tcl ? 7 : 0)); +    BEGIN_CS(64 + (caps->has_tcl ? 5 : 0) + (caps->is_r500 ? 4 : 0));      /* Flush PVS. */      OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); @@ -94,30 +83,26 @@ void r300_emit_invariant_state(struct r300_context* r300)          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); -    /* XXX endian */      if (caps->has_tcl) { -        OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VC_NO_SWAP); -        OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE | -            R300_PS_UCP_MODE_CLIP_AS_TRIFAN);          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); -    } else { -        OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VC_NO_SWAP | -                R300_VAP_TCL_BYPASS);      }      /* 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); +    /* XXX line tex stuffing */ +    OUT_CS_REG_SEQ(R300_GA_LINE_S0, 1); +    OUT_CS_32F(0.0); +    OUT_CS_REG_SEQ(R300_GA_LINE_S1, 1); +    OUT_CS_32F(1.0);      OUT_CS_REG(R300_GA_TRIANGLE_STIPPLE, 0x5 |          (0x5 << R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_SHIFT));      /* XXX this big chunk should be refactored into rs_state */ -    OUT_CS_REG(R300_GA_LINE_S0, 0x00000000); -    OUT_CS_REG(R300_GA_LINE_S1, 0x3F800000);      OUT_CS_REG(R300_GA_SOLID_RG, 0x00000000);      OUT_CS_REG(R300_GA_SOLID_BA, 0x00000000);      OUT_CS_REG(R300_GA_POLY_MODE, 0x00000000); @@ -133,8 +118,10 @@ void r300_emit_invariant_state(struct r300_context* r300)      OUT_CS_REG(R300_RB3D_CCTL, 0x00000000);      OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0x0000000F);      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); +    if (caps->is_r500) { +        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); @@ -144,17 +131,9 @@ void r300_emit_invariant_state(struct r300_context* r300)      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); -    /* Vertex size. */ -    OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8);      /* XXX */      OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa); -    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);      END_CS;  } diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c deleted file mode 100644 index 1b02239ee7..0000000000 --- a/src/gallium/drivers/r300/r300_state_shader.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * 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" - -static void r300_copy_passthrough_shader(struct r300_fragment_shader* fs) -{ -    struct r300_fragment_shader* pt = &r300_passthrough_fragment_shader; -    fs->shader.stack_size = pt->shader.stack_size; -    fs->alu_instruction_count = pt->alu_instruction_count; -    fs->tex_instruction_count = pt->tex_instruction_count; -    fs->indirections = pt->indirections; -    fs->instructions[0] = pt->instructions[0]; -} - -static void r500_copy_passthrough_shader(struct r500_fragment_shader* fs) -{ -    struct r500_fragment_shader* pt = &r500_passthrough_fragment_shader; -    fs->shader.stack_size = pt->shader.stack_size; -    fs->instruction_count = pt->instruction_count; -    fs->instructions[0] = pt->instructions[0]; -} - -static void r300_fs_declare(struct r300_fs_asm* assembler, -                            struct tgsi_full_declaration* decl) -{ -    switch (decl->Declaration.File) { -        case TGSI_FILE_INPUT: -            switch (decl->Semantic.SemanticName) { -                case TGSI_SEMANTIC_COLOR: -                    assembler->color_count++; -                    break; -                case TGSI_SEMANTIC_GENERIC: -                    assembler->tex_count++; -                    break; -                default: -                    debug_printf("r300: fs: Bad semantic declaration %d\n", -                        decl->Semantic.SemanticName); -                    break; -            } -            break; -        case TGSI_FILE_OUTPUT: -        case TGSI_FILE_CONSTANT: -            break; -        case TGSI_FILE_TEMPORARY: -            assembler->temp_count++; -            break; -        default: -            debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File); -            break; -    } - -    assembler->temp_offset = assembler->color_count + assembler->tex_count; -} - -static INLINE unsigned r300_fs_src(struct r300_fs_asm* assembler, -                                   struct tgsi_src_register* src) -{ -    switch (src->File) { -        case TGSI_FILE_NULL: -            return 0; -        case TGSI_FILE_INPUT: -            /* XXX may be wrong */ -            return src->Index; -            break; -        case TGSI_FILE_TEMPORARY: -            return src->Index + assembler->temp_offset; -            break; -        case TGSI_FILE_IMMEDIATE: -            return (src->Index + assembler->imm_offset) | (1 << 8); -            break; -        case TGSI_FILE_CONSTANT: -            /* XXX magic */ -            return src->Index | (1 << 8); -            break; -        default: -            debug_printf("r300: fs: Unimplemented src %d\n", src->File); -            break; -    } -    return 0; -} - -static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler, -                                   struct tgsi_dst_register* dst) -{ -    switch (dst->File) { -        case TGSI_FILE_NULL: -            /* This happens during KIL instructions. */ -            return 0; -            break; -        case TGSI_FILE_OUTPUT: -            return 0; -            break; -        case TGSI_FILE_TEMPORARY: -            return dst->Index + assembler->temp_offset; -            break; -        default: -            debug_printf("r300: fs: Unimplemented dst %d\n", dst->File); -            break; -    } -    return 0; -} - -static INLINE unsigned r500_fix_swiz(unsigned s) -{ -    /* For historical reasons, the swizzle values x, y, z, w, and 0 are -     * equivalent to the actual machine code, but 1 is not. Thus, we just -     * adjust it a bit... */ -    if (s == TGSI_EXTSWIZZLE_ONE) { -        return R500_SWIZZLE_ONE; -    } else { -        return s; -    } -} - -static uint32_t r500_rgba_swiz(struct tgsi_full_src_register* reg) -{ -    if (reg->SrcRegister.Extended) { -        return r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) | -            (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) | -            (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) | -            (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9); -    } else { -        return reg->SrcRegister.SwizzleX | -            (reg->SrcRegister.SwizzleY << 3) | -            (reg->SrcRegister.SwizzleZ << 6) | -            (reg->SrcRegister.SwizzleW << 9); -    } -} - -static uint32_t r500_strq_swiz(struct tgsi_full_src_register* reg) -{ -    return reg->SrcRegister.SwizzleX | -        (reg->SrcRegister.SwizzleY << 2) | -        (reg->SrcRegister.SwizzleZ << 4) | -        (reg->SrcRegister.SwizzleW << 6); -} - -static INLINE uint32_t r500_rgb_swiz(struct tgsi_full_src_register* reg) -{ -    /* Only the first 9 bits... */ -    return (r500_rgba_swiz(reg) & 0x1ff) | -        (reg->SrcRegister.Negate ? (1 << 9) : 0) | -        (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0); -} - -static INLINE uint32_t r500_alpha_swiz(struct tgsi_full_src_register* reg) -{ -    /* Only the last 3 bits... */ -    return (r500_rgba_swiz(reg) >> 9) | -        (reg->SrcRegister.Negate ? (1 << 9) : 0) | -        (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0); -} - -static INLINE uint32_t r300_rgb_op(unsigned op) -{ -    switch (op) { -        case TGSI_OPCODE_MOV: -            return R300_ALU_OUTC_CMP; -        default: -            return 0; -    } -} - -static INLINE uint32_t r300_alpha_op(unsigned op) -{ -    switch (op) { -        case TGSI_OPCODE_MOV: -            return R300_ALU_OUTA_CMP; -        default: -            return 0; -    } -} - -static INLINE uint32_t r500_rgba_op(unsigned op) -{ -    switch (op) { -        case TGSI_OPCODE_EX2: -        case TGSI_OPCODE_LG2: -        case TGSI_OPCODE_RCP: -        case TGSI_OPCODE_RSQ: -            return R500_ALU_RGBA_OP_SOP; -        case TGSI_OPCODE_FRC: -            return R500_ALU_RGBA_OP_FRC; -        case TGSI_OPCODE_DP3: -            return R500_ALU_RGBA_OP_DP3; -        case TGSI_OPCODE_DP4: -        case TGSI_OPCODE_DPH: -            return R500_ALU_RGBA_OP_DP4; -        case TGSI_OPCODE_ABS: -        case TGSI_OPCODE_CMP: -        case TGSI_OPCODE_MOV: -        case TGSI_OPCODE_SWZ: -            return R500_ALU_RGBA_OP_CMP; -        case TGSI_OPCODE_ADD: -        case TGSI_OPCODE_MAD: -        case TGSI_OPCODE_MUL: -        case TGSI_OPCODE_SUB: -            return R500_ALU_RGBA_OP_MAD; -        default: -            return 0; -    } -} - -static INLINE uint32_t r500_alpha_op(unsigned op) -{ -    switch (op) { -        case TGSI_OPCODE_EX2: -            return R500_ALPHA_OP_EX2; -        case TGSI_OPCODE_LG2: -            return R500_ALPHA_OP_LN2; -        case TGSI_OPCODE_RCP: -            return R500_ALPHA_OP_RCP; -        case TGSI_OPCODE_RSQ: -            return R500_ALPHA_OP_RSQ; -        case TGSI_OPCODE_FRC: -            return R500_ALPHA_OP_FRC; -        case TGSI_OPCODE_DP3: -        case TGSI_OPCODE_DP4: -        case TGSI_OPCODE_DPH: -            return R500_ALPHA_OP_DP; -        case TGSI_OPCODE_ABS: -        case TGSI_OPCODE_CMP: -        case TGSI_OPCODE_MOV: -        case TGSI_OPCODE_SWZ: -            return R500_ALPHA_OP_CMP; -        case TGSI_OPCODE_ADD: -        case TGSI_OPCODE_MAD: -        case TGSI_OPCODE_MUL: -        case TGSI_OPCODE_SUB: -            return R500_ALPHA_OP_MAD; -        default: -            return 0; -    } -} - -static INLINE uint32_t r500_tex_op(unsigned op) -{ -    switch (op) { -        case TGSI_OPCODE_KIL: -            return R500_TEX_INST_TEXKILL; -        case TGSI_OPCODE_TEX: -            return R500_TEX_INST_LD; -        case TGSI_OPCODE_TXB: -            return R500_TEX_INST_LODBIAS; -        case TGSI_OPCODE_TXP: -            return R500_TEX_INST_PROJ; -        default: -            return 0; -    } -} - -static INLINE void r300_emit_maths(struct r300_fragment_shader* fs, -                                   struct r300_fs_asm* assembler, -                                   struct tgsi_full_src_register* src, -                                   struct tgsi_full_dst_register* dst, -                                   unsigned op, -                                   unsigned count) -{ -    int i = fs->alu_instruction_count; - -    fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | -        r300_rgb_op(op); -    fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | -        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ; -    fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | -        r300_alpha_op(op); -    fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) | -        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT; - -    fs->alu_instruction_count++; -} - -/* Setup an ALU operation. */ -static INLINE void r500_emit_alu(struct r500_fragment_shader* fs, -                                 struct r300_fs_asm* assembler, -                                 struct tgsi_full_dst_register* dst) -{ -    int i = fs->instruction_count; - -    if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { -        fs->instructions[i].inst0 = R500_INST_TYPE_OUT | -        R500_ALU_OMASK(dst->DstRegister.WriteMask); -    } else { -        fs->instructions[i].inst0 = R500_INST_TYPE_ALU | -        R500_ALU_WMASK(dst->DstRegister.WriteMask); -    } - -    fs->instructions[i].inst0 |= R500_INST_TEX_SEM_WAIT; - -    fs->instructions[i].inst4 = -        R500_ALPHA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister)); -    fs->instructions[i].inst5 = -        R500_ALU_RGBA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister)); -} - -static INLINE void r500_emit_maths(struct r500_fragment_shader* fs, -                                   struct r300_fs_asm* assembler, -                                   struct tgsi_full_src_register* src, -                                   struct tgsi_full_dst_register* dst, -                                   unsigned op, -                                   unsigned count) -{ -    int i = fs->instruction_count; - -    r500_emit_alu(fs, assembler, dst); - -    switch (count) { -        case 3: -            fs->instructions[i].inst1 = -                R500_RGB_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister)); -            fs->instructions[i].inst2 = -                R500_ALPHA_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister)); -            fs->instructions[i].inst5 |= -                R500_ALU_RGBA_SEL_C_SRC2 | -                R500_SWIZ_RGBA_C(r500_rgb_swiz(&src[2])) | -                R500_ALU_RGBA_ALPHA_SEL_C_SRC2 | -                R500_SWIZ_ALPHA_C(r500_alpha_swiz(&src[2])); -        case 2: -            fs->instructions[i].inst1 |= -                R500_RGB_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister)); -            fs->instructions[i].inst2 |= -                R500_ALPHA_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister)); -            fs->instructions[i].inst3 = -                R500_ALU_RGB_SEL_B_SRC1 | -                R500_SWIZ_RGB_B(r500_rgb_swiz(&src[1])); -            fs->instructions[i].inst4 |= -                R500_SWIZ_ALPHA_B(r500_alpha_swiz(&src[1])) | -                R500_ALPHA_SEL_B_SRC1; -        case 1: -        case 0: -        default: -            fs->instructions[i].inst1 |= -                R500_RGB_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister)); -            fs->instructions[i].inst2 |= -                R500_ALPHA_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister)); -            fs->instructions[i].inst3 |= -                R500_ALU_RGB_SEL_A_SRC0 | -                R500_SWIZ_RGB_A(r500_rgb_swiz(&src[0])); -            fs->instructions[i].inst4 |= -                R500_SWIZ_ALPHA_A(r500_alpha_swiz(&src[0])) | -                R500_ALPHA_SEL_A_SRC0; -            break; -    } - -    fs->instructions[i].inst4 |= r500_alpha_op(op); -    fs->instructions[i].inst5 |= r500_rgba_op(op); - -    fs->instruction_count++; -} - -static INLINE void r500_emit_tex(struct r500_fragment_shader* fs, -                                 struct r300_fs_asm* assembler, -                                 struct tgsi_full_src_register* src, -                                 struct tgsi_full_dst_register* dst, -                                 uint32_t op) -{ -    int i = fs->instruction_count; - -    fs->instructions[i].inst0 = R500_INST_TYPE_TEX | -        R500_TEX_WMASK(dst->DstRegister.WriteMask) | -        R500_INST_TEX_SEM_WAIT; -    fs->instructions[i].inst1 = R500_TEX_ID(0) | -        R500_TEX_SEM_ACQUIRE | //R500_TEX_IGNORE_UNCOVERED | -        r500_tex_op(op); -    fs->instructions[i].inst2 = -        R500_TEX_SRC_ADDR(r300_fs_src(assembler, &src->SrcRegister)) | -        R500_SWIZ_TEX_STRQ(r500_strq_swiz(src)) | -        R500_TEX_DST_ADDR(r300_fs_dst(assembler, &dst->DstRegister)) | -        R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | -        R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A; - -    if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { -        fs->instructions[i].inst2 |= -            R500_TEX_DST_ADDR(assembler->temp_count + -                    assembler->temp_offset); - -        fs->instruction_count++; - -        /* Setup and emit a MOV. */ -        src[0].SrcRegister.Index = assembler->temp_count; -        src[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - -        src[1] = src[0]; -        src[2] = r500_constant_zero; -        r500_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3); -    } else { -        fs->instruction_count++; -    } -} - -static void r300_fs_instruction(struct r300_fragment_shader* fs, -                                struct r300_fs_asm* assembler, -                                struct tgsi_full_instruction* inst) -{ -    switch (inst->Instruction.Opcode) { -        case TGSI_OPCODE_MOV: -            /* src0 -> src1 and src2 forced to zero */ -            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; -            inst->FullSrcRegisters[2] = r500_constant_zero; -            r300_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; -        case TGSI_OPCODE_END: -            break; -        default: -            debug_printf("r300: fs: Bad opcode %d\n", -                    inst->Instruction.Opcode); -            break; -    } -} - -static void r500_fs_instruction(struct r500_fragment_shader* fs, -                                struct r300_fs_asm* assembler, -                                struct tgsi_full_instruction* inst) -{ -    /* Switch between opcodes. When possible, prefer using the official -     * AMD/ATI names for opcodes, please, as it facilitates using the -     * documentation. */ -    switch (inst->Instruction.Opcode) { -        /* The simple scalar ops. */ -        case TGSI_OPCODE_EX2: -        case TGSI_OPCODE_LG2: -        case TGSI_OPCODE_RCP: -        case TGSI_OPCODE_RSQ: -            /* Copy red swizzle to alpha for src0 */ -            inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW = -                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX; -            inst->FullSrcRegisters[0].SrcRegister.SwizzleW = -                inst->FullSrcRegisters[0].SrcRegister.SwizzleX; -            /* Fall through */ -        case TGSI_OPCODE_FRC: -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 1); -            break; - -        /* The dot products. */ -        case TGSI_OPCODE_DPH: -            /* Set alpha swizzle to one for src0 */ -            if (!inst->FullSrcRegisters[0].SrcRegister.Extended) { -                inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE; -                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX = -                    inst->FullSrcRegisters[0].SrcRegister.SwizzleX; -                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY = -                    inst->FullSrcRegisters[0].SrcRegister.SwizzleY; -                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ = -                    inst->FullSrcRegisters[0].SrcRegister.SwizzleZ; -            } -            inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW = -                TGSI_EXTSWIZZLE_ONE; -            /* Fall through */ -        case TGSI_OPCODE_DP3: -        case TGSI_OPCODE_DP4: -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 2); -            break; - -        /* Simple three-source operations. */ -        case TGSI_OPCODE_CMP: -            /* Swap src0 and src2 */ -            inst->FullSrcRegisters[3] = inst->FullSrcRegisters[2]; -            inst->FullSrcRegisters[2] = inst->FullSrcRegisters[0]; -            inst->FullSrcRegisters[0] = inst->FullSrcRegisters[3]; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; - -        /* The MAD variants. */ -        case TGSI_OPCODE_SUB: -            /* Just like ADD, but flip the negation on src1 first */ -            inst->FullSrcRegisters[1].SrcRegister.Negate = -                !inst->FullSrcRegisters[1].SrcRegister.Negate; -            /* Fall through */ -        case TGSI_OPCODE_ADD: -            /* Force src0 to one, move all registers over */ -            inst->FullSrcRegisters[2] = inst->FullSrcRegisters[1]; -            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; -            inst->FullSrcRegisters[0] = r500_constant_one; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; -        case TGSI_OPCODE_MUL: -            /* Force our src2 to zero */ -            inst->FullSrcRegisters[2] = r500_constant_zero; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; -        case TGSI_OPCODE_MAD: -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; - -        /* The MOV variants. */ -        case TGSI_OPCODE_ABS: -            /* Set absolute value modifiers. */ -            inst->FullSrcRegisters[0].SrcRegisterExtMod.Absolute = TRUE; -            /* Fall through */ -        case TGSI_OPCODE_MOV: -        case TGSI_OPCODE_SWZ: -            /* src0 -> src1 and src2 forced to zero */ -            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; -            inst->FullSrcRegisters[2] = r500_constant_zero; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; - -        /* The texture instruction set. */ -        case TGSI_OPCODE_KIL: -        case TGSI_OPCODE_TEX: -        case TGSI_OPCODE_TXB: -        case TGSI_OPCODE_TXP: -            r500_emit_tex(fs, assembler, &inst->FullSrcRegisters[0], -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode); -            break; - -        /* This is the end. My only friend, the end. */ -        case TGSI_OPCODE_END: -            break; -        default: -            debug_printf("r300: fs: Bad opcode %d\n", -                    inst->Instruction.Opcode); -            break; -    } - -    /* Clamp, if saturation flags are set. */ -    if (inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE) { -        fs->instructions[fs->instruction_count - 1].inst0 |= -            R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP; -    } -} - -static void r300_fs_finalize(struct r3xx_fragment_shader* fs, -                             struct r300_fs_asm* assembler) -{ -    fs->stack_size = assembler->temp_count + assembler->temp_offset; -} - -static void r500_fs_finalize(struct r500_fragment_shader* fs, -                             struct r300_fs_asm* assembler) -{ -    /* XXX should this just go with OPCODE_END? */ -    fs->instructions[fs->instruction_count - 1].inst0 |= -        R500_INST_LAST; -} - -void r300_translate_fragment_shader(struct r300_context* r300, -                                    struct r3xx_fragment_shader* fs) -{ -    struct tgsi_parse_context parser; -    int i; -    boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500; -    struct r300_constant_buffer* consts = -        &r300->shader_constants[PIPE_SHADER_FRAGMENT]; - -    struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm); -    if (assembler == NULL) { -        return; -    } -    /* Setup starting offset for immediates. */ -    assembler->imm_offset = consts->user_count; - -    /* Make sure we start at the beginning of the shader. */ -    if (is_r500) { -        ((struct r500_fragment_shader*)fs)->instruction_count = 0; -    } - -    tgsi_parse_init(&parser, fs->state.tokens); - -    while (!tgsi_parse_end_of_tokens(&parser)) { -        tgsi_parse_token(&parser); - -        /* This is seriously the lamest way to create fragment programs ever. -         * I blame TGSI. */ -        switch (parser.FullToken.Token.Type) { -            case TGSI_TOKEN_TYPE_DECLARATION: -                /* Allocated registers sitting at the beginning -                 * of the program. */ -                r300_fs_declare(assembler, &parser.FullToken.FullDeclaration); -                break; -            case TGSI_TOKEN_TYPE_IMMEDIATE: -                debug_printf("r300: Emitting immediate to constant buffer, " -                        "position %d\n", -                        assembler->imm_offset + assembler->imm_count); -                /* I am not amused by the length of these. */ -                for (i = 0; i < 4; i++) { -                    consts->constants[assembler->imm_offset + -                        assembler->imm_count][i] = -                        parser.FullToken.FullImmediate.u.ImmediateFloat32[i] -                        .Float; -                } -                assembler->imm_count++; -                break; -            case TGSI_TOKEN_TYPE_INSTRUCTION: -                if (is_r500) { -                    r500_fs_instruction((struct r500_fragment_shader*)fs, -                            assembler, &parser.FullToken.FullInstruction); -                } else { -                    r300_fs_instruction((struct r300_fragment_shader*)fs, -                            assembler, &parser.FullToken.FullInstruction); -                } -                break; -        } -    } - -    debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n", -            assembler->tex_count, assembler->color_count, -            assembler->tex_count + assembler->color_count); - -    consts->count = consts->user_count + assembler->imm_count; -    debug_printf("r300: fs: %d total constants, " -            "%d from user and %d from immediates\n", consts->count, -            consts->user_count, assembler->imm_count); -    r300_fs_finalize(fs, assembler); -    if (is_r500) { -        r500_fs_finalize((struct r500_fragment_shader*)fs, assembler); -    } - -    tgsi_dump(fs->state.tokens); -    /* XXX finish r300 dumper too */ -    if (is_r500) { -        r500_fs_dump((struct r500_fragment_shader*)fs); -    } - -    tgsi_parse_free(&parser); -    FREE(assembler); -} diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h deleted file mode 100644 index 185fdd90f0..0000000000 --- a/src/gallium/drivers/r300/r300_state_shader.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * 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 "tgsi/tgsi_parse.h" - -#include "r300_context.h" -#include "r300_debug.h" -#include "r300_reg.h" -#include "r300_screen.h" - -/* XXX this all should find its way back to r300_reg */ -/* Swizzle tools */ -#define R500_SWIZZLE_ZERO 4 -#define R500_SWIZZLE_HALF 5 -#define R500_SWIZZLE_ONE 6 -#define R500_SWIZ_RGB_ZERO ((4 << 0) | (4 << 3) | (4 << 6)) -#define R500_SWIZ_RGB_ONE ((6 << 0) | (6 << 3) | (6 << 6)) -#define R500_SWIZ_RGB_RGB ((0 << 0) | (1 << 3) | (2 << 6)) -#define R500_SWIZ_MOD_NEG 1 -#define R500_SWIZ_MOD_ABS 2 -#define R500_SWIZ_MOD_NEG_ABS 3 -/* Swizzles for inst2 */ -#define R500_SWIZ_TEX_STRQ(x) ((x) << 8) -#define R500_SWIZ_TEX_RGBA(x) ((x) << 24) -/* Swizzles for inst3 */ -#define R500_SWIZ_RGB_A(x) ((x) << 2) -#define R500_SWIZ_RGB_B(x) ((x) << 15) -/* Swizzles for inst4 */ -#define R500_SWIZ_ALPHA_A(x) ((x) << 14) -#define R500_SWIZ_ALPHA_B(x) ((x) << 21) -/* Swizzle for inst5 */ -#define R500_SWIZ_RGBA_C(x) ((x) << 14) -#define R500_SWIZ_ALPHA_C(x) ((x) << 27) -/* Writemasks */ -#define R500_TEX_WMASK(x) ((x) << 11) -#define R500_ALU_WMASK(x) ((x) << 11) -#define R500_ALU_OMASK(x) ((x) << 15) - -/* TGSI constants. TGSI is like XML: If it can't solve your problems, you're - * not using enough of it. */ -static const struct tgsi_full_src_register r500_constant_zero = { -    .SrcRegister.Extended = TRUE, -    .SrcRegister.File = TGSI_FILE_NULL, -    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO, -    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO, -    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO, -    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO, -}; - -static const struct tgsi_full_src_register r500_constant_one = { -    .SrcRegister.Extended = TRUE, -    .SrcRegister.File = TGSI_FILE_NULL, -    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ONE, -    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ONE, -    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ONE, -    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ONE, -}; - -/* Temporary struct used to hold assembly state while putting together - * fragment programs. */ -struct r300_fs_asm { -    /* Pipe context. */ -    struct r300_context* r300; -    /* Number of colors. */ -    unsigned color_count; -    /* Number of texcoords. */ -    unsigned tex_count; -    /* Offset for temporary registers. Inputs and temporaries have no -     * distinguishing markings, so inputs start at 0 and the first usable -     * temporary register is after all inputs. */ -    unsigned temp_offset; -    /* Number of requested temporary registers. */ -    unsigned temp_count; -    /* Offset for immediate constants. Neither R300 nor R500 can do four -     * inline constants per source, so instead we copy immediates into the -     * constant buffer. */ -    unsigned imm_offset; -    /* Number of immediate constants. */ -    unsigned imm_count; -}; - -void r300_translate_fragment_shader(struct r300_context* r300, -                           struct r3xx_fragment_shader* fs); - -static struct r300_fragment_shader r300_passthrough_fragment_shader = { -    /* XXX This is the emission code. TODO: decode -    OUT_CS_REG(R300_US_CONFIG, 0); -    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); -*/ -    .alu_instruction_count = 1, -    .tex_instruction_count = 0, -    .indirections = 0, -    .shader.stack_size = 1, - -    .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | -        R300_ALU_OUTC_CMP, -    .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | -        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, -    .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | -        R300_ALU_OUTA_CMP, -    .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | -        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, -}; - -static struct r500_fragment_shader r500_passthrough_fragment_shader = { -    .shader.stack_size = 0, -    .instruction_count = 1, -    .instructions[0].inst0 = R500_INST_TYPE_OUT | -        R500_INST_TEX_SEM_WAIT | R500_INST_LAST | -        R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | -        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, -    .instructions[0].inst1 = -        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | -        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, -    .instructions[0].inst2 = -        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | -        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, -    .instructions[0].inst3 = -        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, -    .instructions[0].inst4 = -        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, -    .instructions[0].inst5 = -        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, -}; - -static struct r300_fragment_shader r300_texture_fragment_shader = { -    /* XXX This is the emission code. TODO: decode -    OUT_CS_REG(R300_US_CONFIG, 0); -    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); -*/ -    .alu_instruction_count = 1, -    .tex_instruction_count = 0, -    .indirections = 0, -    .shader.stack_size = 1, - -    .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | -        R300_ALU_OUTC_CMP, -    .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | -        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, -    .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | -        R300_ALU_OUTA_CMP, -    .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | -        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, -}; - -static struct r500_fragment_shader r500_texture_fragment_shader = { -    .shader.stack_size = 1, -    .instruction_count = 2, -    .instructions[0].inst0 = R500_INST_TYPE_TEX | -        R500_INST_TEX_SEM_WAIT | -        R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | -        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, -    .instructions[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD | -        R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED, -    .instructions[0].inst2 = R500_TEX_SRC_ADDR(0) | -        R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G | -        R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A | -        R500_TEX_DST_ADDR(0) | -        R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | -        R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A, -    .instructions[0].inst3 = 0x0, -    .instructions[0].inst4 = 0x0, -    .instructions[0].inst5 = 0x0, -    .instructions[1].inst0 = R500_INST_TYPE_OUT | -        R500_INST_TEX_SEM_WAIT | R500_INST_LAST | -        R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | -        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, -    .instructions[1].inst1 = -        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | -        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, -    .instructions[1].inst2 = -        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | -        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, -    .instructions[1].inst3 = -        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, -    .instructions[1].inst4 = -        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, -    .instructions[1].inst5 = -        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, -}; - -#endif /* R300_STATE_SHADER_H */ diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_state_tcl.c deleted file mode 100644 index d84912de48..0000000000 --- a/src/gallium/drivers/r300/r300_state_tcl.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright 2009 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_tcl.h" - -static void r300_vs_declare(struct r300_vs_asm* assembler, -                            struct tgsi_full_declaration* decl) -{ -    switch (decl->Declaration.File) { -        case TGSI_FILE_INPUT: -            break; -        case TGSI_FILE_OUTPUT: -            switch (decl->Semantic.SemanticName) { -                case TGSI_SEMANTIC_POSITION: -                    assembler->tab[decl->DeclarationRange.First] = 0; -                    break; -                case TGSI_SEMANTIC_COLOR: -                    assembler->tab[decl->DeclarationRange.First] = -                        (assembler->point_size ? 1 : 0) + -                        assembler->out_colors; -                    break; -                case TGSI_SEMANTIC_FOG: -                case TGSI_SEMANTIC_GENERIC: -                    /* XXX multiple? */ -                    assembler->tab[decl->DeclarationRange.First] = -                        (assembler->point_size ? 1 : 0) + -                        assembler->out_colors + -                        assembler->out_texcoords; -                    break; -                case TGSI_SEMANTIC_PSIZE: -                    assembler->tab[decl->DeclarationRange.First] = 1; -                    break; -                default: -                    debug_printf("r300: vs: Bad semantic declaration %d\n", -                        decl->Semantic.SemanticName); -                    break; -            } -            break; -        case TGSI_FILE_CONSTANT: -            break; -        case TGSI_FILE_TEMPORARY: -            assembler->temp_count++; -            break; -        default: -            debug_printf("r300: vs: Bad file %d\n", decl->Declaration.File); -            break; -    } -} - -static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler, -                                        struct tgsi_src_register* src) -{ -    switch (src->File) { -        case TGSI_FILE_NULL: -            /* Probably a zero or one swizzle */ -            return R300_PVS_SRC_REG_INPUT; -            break; -        case TGSI_FILE_INPUT: -            return R300_PVS_SRC_REG_INPUT; -            break; -        case TGSI_FILE_TEMPORARY: -            return R300_PVS_SRC_REG_TEMPORARY; -            break; -        case TGSI_FILE_CONSTANT: -            return R300_PVS_SRC_REG_CONSTANT; -        default: -            debug_printf("r300: vs: Unimplemented src type %d\n", src->File); -            break; -    } -    return 0; -} - -static INLINE unsigned r300_vs_dst_type(struct r300_vs_asm* assembler, -                                        struct tgsi_dst_register* dst) -{ -    switch (dst->File) { -        case TGSI_FILE_TEMPORARY: -            return R300_PVS_DST_REG_TEMPORARY; -            break; -        case TGSI_FILE_OUTPUT: -            return R300_PVS_DST_REG_OUT; -            break; -        default: -            debug_printf("r300: vs: Unimplemented dst type %d\n", dst->File); -            break; -    } -    return 0; -} - -static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler, -                                   struct tgsi_dst_register* dst) -{ -    switch (dst->File) { -        case TGSI_FILE_TEMPORARY: -            return dst->Index; -            break; -        case TGSI_FILE_OUTPUT: -            return assembler->tab[dst->Index]; -            break; -        default: -            debug_printf("r300: vs: Unimplemented dst %d\n", dst->File); -            break; -    } -    return 0; -} - -static uint32_t r300_vs_op(unsigned op) -{ -    switch (op) { -        case TGSI_OPCODE_DP3: -        case TGSI_OPCODE_DP4: -            return R300_VE_DOT_PRODUCT; -        case TGSI_OPCODE_MUL: -            return R300_VE_MULTIPLY; -        case TGSI_OPCODE_ADD: -        case TGSI_OPCODE_MOV: -        case TGSI_OPCODE_SWZ: -            return R300_VE_ADD; -        case TGSI_OPCODE_MAD: -            return R300_PVS_DST_MACRO_INST | R300_PVS_MACRO_OP_2CLK_MADD; -        default: -            break; -    } -    return 0; -} - -static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg) -{ -    if (reg->SrcRegister.Extended) { -        return reg->SrcRegisterExtSwz.ExtSwizzleX | -            (reg->SrcRegisterExtSwz.ExtSwizzleY << 3) | -            (reg->SrcRegisterExtSwz.ExtSwizzleZ << 6) | -            (reg->SrcRegisterExtSwz.ExtSwizzleW << 9); -    } else { -        return reg->SrcRegister.SwizzleX | -            (reg->SrcRegister.SwizzleY << 3) | -            (reg->SrcRegister.SwizzleZ << 6) | -            (reg->SrcRegister.SwizzleW << 9); -    } -} - -static void r300_vs_emit_inst(struct r300_vertex_shader* vs, -                              struct r300_vs_asm* assembler, -                              struct tgsi_full_src_register* src, -                              struct tgsi_full_dst_register* dst, -                              unsigned op, -                              unsigned count) -{ -    int i = vs->instruction_count; -    vs->instructions[i].inst0 = R300_PVS_DST_OPCODE(r300_vs_op(op)) | -        R300_PVS_DST_REG_TYPE(r300_vs_dst_type(assembler, &dst->DstRegister)) | -        R300_PVS_DST_OFFSET(r300_vs_dst(assembler, &dst->DstRegister)) | -        R300_PVS_DST_WE_XYZW; -    switch (count) { -        case 3: -            vs->instructions[i].inst3 = -                R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, -                            &src[2].SrcRegister)) | -                R300_PVS_SRC_OFFSET(src[2].SrcRegister.Index) | -                R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[2])); -            /* Fall through */ -        case 2: -            vs->instructions[i].inst2 = -                R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, -                            &src[1].SrcRegister)) | -                R300_PVS_SRC_OFFSET(src[1].SrcRegister.Index) | -                R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[1])); -            /* Fall through */ -        case 1: -            vs->instructions[i].inst1 = -                R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, -                            &src[0].SrcRegister)) | -                R300_PVS_SRC_OFFSET(src[0].SrcRegister.Index) | -                R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[0])); -            break; -    } -    vs->instruction_count++; -} - -static void r300_vs_instruction(struct r300_vertex_shader* vs, -                                struct r300_vs_asm* assembler, -                                struct tgsi_full_instruction* inst) -{ -    switch (inst->Instruction.Opcode) { -        case TGSI_OPCODE_ADD: -        case TGSI_OPCODE_MUL: -            r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, -                    2); -            break; -        case TGSI_OPCODE_DP3: -            /* Set alpha swizzle to zero for src0 and src1 */ -            if (!inst->FullSrcRegisters[0].SrcRegister.Extended) { -                inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE; -                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX = -                    inst->FullSrcRegisters[0].SrcRegister.SwizzleX; -                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY = -                    inst->FullSrcRegisters[0].SrcRegister.SwizzleY; -                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ = -                    inst->FullSrcRegisters[0].SrcRegister.SwizzleZ; -            } -            inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW = -                TGSI_EXTSWIZZLE_ZERO; -            if (!inst->FullSrcRegisters[1].SrcRegister.Extended) { -                inst->FullSrcRegisters[1].SrcRegister.Extended = TRUE; -                inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleX = -                    inst->FullSrcRegisters[1].SrcRegister.SwizzleX; -                inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleY = -                    inst->FullSrcRegisters[1].SrcRegister.SwizzleY; -                inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleZ = -                    inst->FullSrcRegisters[1].SrcRegister.SwizzleZ; -            } -            inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleW = -                TGSI_EXTSWIZZLE_ZERO; -            /* Fall through */ -        case TGSI_OPCODE_DP4: -            r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, -                    2); -            break; -        case TGSI_OPCODE_MOV: -        case TGSI_OPCODE_SWZ: -            inst->FullSrcRegisters[1] = r300_constant_zero; -            r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, -                    2); -            break; -        case TGSI_OPCODE_MAD: -            r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, -                    3); -            break; -        case TGSI_OPCODE_END: -            break; -        default: -            debug_printf("r300: vs: Bad opcode %d\n", -                    inst->Instruction.Opcode); -            break; -    } -} - -static void r300_vs_init(struct r300_vertex_shader* vs, -                         struct r300_vs_asm* assembler) -{ -    struct tgsi_shader_info* info = &vs->info; -    int i; - -    for (i = 0; i < info->num_outputs; i++) { -        switch (info->output_semantic_name[i]) { -            case TGSI_SEMANTIC_PSIZE: -                assembler->point_size = TRUE; -                break; -            case TGSI_SEMANTIC_COLOR: -                assembler->out_colors++; -                break; -            case TGSI_SEMANTIC_FOG: -            case TGSI_SEMANTIC_GENERIC: -                assembler->out_texcoords++; -                break; -        } -    } -} - -void r300_translate_vertex_shader(struct r300_context* r300, -                                  struct r300_vertex_shader* vs) -{ -    struct tgsi_parse_context parser; -    int i; -    struct r300_constant_buffer* consts = -        &r300->shader_constants[PIPE_SHADER_VERTEX]; - -    struct r300_vs_asm* assembler = CALLOC_STRUCT(r300_vs_asm); -    if (assembler == NULL) { -        return; -    } - -    /* Init assembler. */ -    r300_vs_init(vs, assembler); - -    /* Setup starting offset for immediates. */ -    assembler->imm_offset = consts->user_count; - -    tgsi_parse_init(&parser, vs->state.tokens); - -    while (!tgsi_parse_end_of_tokens(&parser)) { -        tgsi_parse_token(&parser); - -        /* This is seriously the lamest way to create fragment programs ever. -         * I blame TGSI. */ -        switch (parser.FullToken.Token.Type) { -            case TGSI_TOKEN_TYPE_DECLARATION: -                /* Allocated registers sitting at the beginning -                 * of the program. */ -                r300_vs_declare(assembler, &parser.FullToken.FullDeclaration); -                break; -            case TGSI_TOKEN_TYPE_IMMEDIATE: -                debug_printf("r300: Emitting immediate to constant buffer, " -                        "position %d\n", -                        assembler->imm_offset + assembler->imm_count); -                /* I am not amused by the length of these. */ -                for (i = 0; i < 4; i++) { -                    consts->constants[assembler->imm_offset + -                        assembler->imm_count][i] = -                        parser.FullToken.FullImmediate.u.ImmediateFloat32[i] -                        .Float; -                } -                assembler->imm_count++; -                break; -            case TGSI_TOKEN_TYPE_INSTRUCTION: -                r300_vs_instruction(vs, assembler, -                        &parser.FullToken.FullInstruction); -                break; -        } -    } - -    debug_printf("r300: vs: %d texs and %d colors, first free reg is %d\n", -            assembler->tex_count, assembler->color_count, -            assembler->tex_count + assembler->color_count); - -    consts->count = consts->user_count + assembler->imm_count; -    debug_printf("r300: vs: %d total constants, " -            "%d from user and %d from immediates\n", consts->count, -            consts->user_count, assembler->imm_count); - -    debug_printf("r300: vs: tab: %d %d %d %d\n", assembler->tab[0], -            assembler->tab[1], assembler->tab[2], assembler->tab[3]); - -    tgsi_dump(vs->state.tokens); -    /* XXX finish r300 vertex shader dumper */ -    r300_vs_dump(vs); - -    tgsi_parse_free(&parser); -    FREE(assembler); -} diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_state_tcl.h deleted file mode 100644 index e2e1357d43..0000000000 --- a/src/gallium/drivers/r300/r300_state_tcl.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2009 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_TCL_H -#define R300_STATE_TCL_H - -#include "tgsi/tgsi_parse.h" - -#include "r300_context.h" -#include "r300_debug.h" -#include "r300_reg.h" -#include "r300_screen.h" - -/* XXX get these to r300_reg */ -#define R300_PVS_DST_OPCODE(x)   ((x) << 0) -#   define R300_VE_DOT_PRODUCT            1 -#   define R300_VE_MULTIPLY               2 -#   define R300_VE_ADD                    3 -#define R300_PVS_DST_MACRO_INST    (1 << 7) -#   define R300_PVS_MACRO_OP_2CLK_MADD    0 -#define R300_PVS_DST_REG_TYPE(x) ((x) << 8) -#   define R300_PVS_DST_REG_TEMPORARY     0 -#   define R300_PVS_DST_REG_A0            1 -#   define R300_PVS_DST_REG_OUT           2 -#   define R300_PVS_DST_REG_OUT_REPL_X    3 -#   define R300_PVS_DST_REG_ALT_TEMPORARY 4 -#   define R300_PVS_DST_REG_INPUT         5 -#define R300_PVS_DST_OFFSET(x)   ((x) << 13) -#define R300_PVS_DST_WE(x)       ((x) << 20) -#define R300_PVS_DST_WE_XYZW     (0xf << 20) - -#define R300_PVS_SRC_REG_TYPE(x) ((x) << 0) -#   define R300_PVS_SRC_REG_TEMPORARY     0 -#   define R300_PVS_SRC_REG_INPUT         1 -#   define R300_PVS_SRC_REG_CONSTANT      2 -#   define R300_PVS_SRC_REG_ALT_TEMPORARY 3 -#define R300_PVS_SRC_OFFSET(x)   ((x) << 5) -#define R300_PVS_SRC_SWIZZLE(x)  ((x) << 13) -#   define R300_PVS_SRC_SELECT_X          0 -#   define R300_PVS_SRC_SELECT_Y          1 -#   define R300_PVS_SRC_SELECT_Z          2 -#   define R300_PVS_SRC_SELECT_W          3 -#   define R300_PVS_SRC_SELECT_FORCE_0    4 -#   define R300_PVS_SRC_SELECT_FORCE_1    5 -#   define R300_PVS_SRC_SWIZZLE_XYZW \ -    ((R300_PVS_SRC_SELECT_X | (R300_PVS_SRC_SELECT_Y << 3) | \ -     (R300_PVS_SRC_SELECT_Z << 6) | (R300_PVS_SRC_SELECT_W << 9)) << 13) -#   define R300_PVS_SRC_SWIZZLE_ZERO \ -    ((R300_PVS_SRC_SELECT_FORCE_0 | (R300_PVS_SRC_SELECT_FORCE_0 << 3) | \ -     (R300_PVS_SRC_SELECT_FORCE_0 << 6) | \ -      (R300_PVS_SRC_SELECT_FORCE_0 << 9)) << 13) -#   define R300_PVS_SRC_SWIZZLE_ONE \ -    ((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \ -     (R300_PVS_SRC_SELECT_FORCE_1 << 6) | \ -      (R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13) - -static const struct tgsi_full_src_register r300_constant_zero = { -    .SrcRegister.Extended = TRUE, -    .SrcRegister.File = TGSI_FILE_NULL, -    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO, -    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO, -    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO, -    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO, -}; - -/* Temporary struct used to hold assembly state while putting together - * fragment programs. */ -struct r300_vs_asm { -    /* Pipe context. */ -    struct r300_context* r300; -    /* Number of colors. */ -    unsigned color_count; -    /* Number of texcoords. */ -    unsigned tex_count; -    /* Number of requested temporary registers. */ -    unsigned temp_count; -    /* Offset for immediate constants. Neither R300 nor R500 can do four -     * inline constants per source, so instead we copy immediates into the -     * constant buffer. */ -    unsigned imm_offset; -    /* Number of immediate constants. */ -    unsigned imm_count; -    /* Number of colors to write. */ -    unsigned out_colors; -    /* Number of texcoords to write. */ -    unsigned out_texcoords; -    /* Whether to emit point size. */ -    boolean point_size; -    /* Tab of declared outputs to OVM outputs. */ -    unsigned tab[16]; -}; - -static struct r300_vertex_shader r300_passthrough_vertex_shader = { -        /* XXX translate these back into normal instructions */ -    .instruction_count = 2, -    .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | -        R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | -        R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW, -    .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | -        R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW, -    .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, -    .instructions[0].inst3 = 0x0, -    .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | -        R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | -        R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW, -    .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | -        R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW, -    .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, -    .instructions[1].inst3 = 0x0, -}; - -static struct r300_vertex_shader r300_texture_vertex_shader = { -        /* XXX translate these back into normal instructions */ -    .instruction_count = 2, -    .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | -        R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | -        R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW, -    .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | -        R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW, -    .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, -    .instructions[0].inst3 = 0x0, -    .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) | -        R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | -        R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW, -    .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | -        R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW, -    .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO, -    .instructions[1].inst3 = 0x0, -}; - -void r300_translate_vertex_shader(struct r300_context* r300, -                                  struct r300_vertex_shader* vs); - -#endif /* R300_STATE_TCL_H */ diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c index 4dd5b8af99..96e6e4a77d 100644 --- a/src/gallium/drivers/r300/r300_surface.c +++ b/src/gallium/drivers/r300/r300_surface.c @@ -23,42 +23,48 @@  #include "r300_surface.h" -static void r300_surface_setup(struct pipe_context* pipe, -                               struct pipe_surface* dest, +static void r300_surface_setup(struct r300_context* r300, +                               struct r300_texture* dest,                                 unsigned x, unsigned y,                                 unsigned w, unsigned h)  { -    struct r300_context* r300 = r300_context(pipe); -    struct r300_capabilities* caps = r300_screen(pipe->screen)->caps; -    struct r300_texture* tex = (struct r300_texture*)dest->texture; -    unsigned pixpitch = tex->stride / tex->tex.block.size; +    struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps; +    unsigned pixpitch = dest->stride / dest->tex.block.size;      CS_LOCALS(r300); -    /* Make sure our target BO is okay. */ -    r300->winsys->add_buffer(r300->winsys, tex->buffer, -            0, RADEON_GEM_DOMAIN_VRAM); -    if (r300->winsys->validate(r300->winsys)) { -        r300->context.flush(&r300->context, 0, NULL); -    } -      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);      r300_emit_rs_state(r300, &rs_clear_state); -    BEGIN_CS(15); +    BEGIN_CS(26); + +    /* Viewport setup */ +    OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); +    OUT_CS_32F((float)w); +    OUT_CS_32F((float)x); +    OUT_CS_32F((float)h); +    OUT_CS_32F((float)y); +    OUT_CS_32F(1.0); +    OUT_CS_32F(0.0); + +    OUT_CS_REG(R300_VAP_VTE_CNTL, R300_VPORT_X_SCALE_ENA | +            R300_VPORT_X_OFFSET_ENA | +            R300_VPORT_Y_SCALE_ENA | +            R300_VPORT_Y_OFFSET_ENA | +            R300_VTX_XY_FMT | R300_VTX_Z_FMT);      /* Pixel scissors. */      OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);      if (caps->is_r500) {          OUT_CS((x << R300_SCISSORS_X_SHIFT) | (y << R300_SCISSORS_Y_SHIFT)); -        OUT_CS((w << R300_SCISSORS_X_SHIFT) | (h << R300_SCISSORS_Y_SHIFT)); +        OUT_CS(((w - 1) << R300_SCISSORS_X_SHIFT) | ((h - 1) << R300_SCISSORS_Y_SHIFT));      } else {          /* Non-R500 chipsets have an offset of 1440 in their scissors. */          OUT_CS(((x + 1440) << R300_SCISSORS_X_SHIFT) |                  ((y + 1440) << R300_SCISSORS_Y_SHIFT)); -        OUT_CS(((w + 1440) << R300_SCISSORS_X_SHIFT) | -                ((h + 1440) << R300_SCISSORS_Y_SHIFT)); +        OUT_CS((((w - 1) + 1440) << R300_SCISSORS_X_SHIFT) | +                (((h - 1) + 1440) << R300_SCISSORS_Y_SHIFT));      }      /* Flush colorbuffer and blend caches. */ @@ -71,9 +77,11 @@ static void r300_surface_setup(struct pipe_context* pipe,      /* Setup colorbuffer. */      OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1); -    OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); -    OUT_CS_REG(R300_RB3D_COLORPITCH0, pixpitch | -        r300_translate_colorformat(tex->tex.format)); +    OUT_CS_RELOC(dest->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); +    OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0, 1); +    OUT_CS_RELOC(dest->buffer, pixpitch | +                 r300_translate_colorformat(dest->tex.format), 0, +                 RADEON_GEM_DOMAIN_VRAM, 0);      OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0xf);      END_CS; @@ -93,6 +101,7 @@ static void r300_surface_fill(struct pipe_context* pipe,      struct r300_capabilities* caps = r300_screen(pipe->screen)->caps;      struct r300_texture* tex = (struct r300_texture*)dest->texture;      unsigned pixpitch = tex->stride / tex->tex.block.size; +    boolean invalid = FALSE;      CS_LOCALS(r300);      a = (float)((color >> 24) & 0xff) / 255.0f; @@ -105,19 +114,41 @@ static void r300_surface_fill(struct pipe_context* pipe,      /* Fallback? */      if (FALSE) { +fallback:          debug_printf("r300: Falling back on surface clear...");          util_surface_fill(pipe, dest, x, y, w, h, color);          return;      } -    r300_surface_setup(r300, dest, x, y, w, h); +    /* Make sure our target BO is okay. */ +validate: +    if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, +                0, RADEON_GEM_DOMAIN_VRAM)) { +        r300->context.flush(&r300->context, 0, NULL); +        goto validate; +    } +    if (!r300->winsys->validate(r300->winsys)) { +        r300->context.flush(&r300->context, 0, NULL); +        if (invalid) { +            debug_printf("r300: Stuck in validation loop, gonna fallback."); +            goto fallback; +        } +        invalid = TRUE; +        goto validate; +    } + +    r300_surface_setup(r300, tex, x, y, w, h);      /* Vertex shader setup */      if (caps->has_tcl) { -        r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader); +        r300_emit_vertex_program_code(r300, &r300_passthrough_vertex_shader, 0);      } else {          BEGIN_CS(4); -        OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS); +        OUT_CS_REG(R300_VAP_CNTL_STATUS, +#ifdef PIPE_ARCH_BIG_ENDIAN +                   R300_VC_32BIT_SWAP | +#endif +                   R300_VAP_TCL_BYPASS);          OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) |                  R300_PVS_NUM_CNTLRS(5) |                  R300_PVS_NUM_FPUS(caps->num_vert_fpus) | @@ -127,14 +158,14 @@ static void r300_surface_fill(struct pipe_context* pipe,      /* Fragment shader setup */      if (caps->is_r500) { -        r500_emit_fragment_shader(r300, &r500_passthrough_fragment_shader); -        r300_emit_rs_block_state(r300, &r500_rs_block_clear_state); +        r500_emit_fragment_program_code(r300, &r5xx_passthrough_fragment_shader, 0); +        r300_emit_rs_block_state(r300, &r5xx_rs_block_clear_state);      } else { -        r300_emit_fragment_shader(r300, &r300_passthrough_fragment_shader); -        r300_emit_rs_block_state(r300, &r300_rs_block_clear_state); +        r300_emit_fragment_program_code(r300, &r3xx_passthrough_fragment_shader, 0); +        r300_emit_rs_block_state(r300, &r3xx_rs_block_clear_state);      } -    BEGIN_CS(31); +    BEGIN_CS(26);      /* VAP stream control, mapping from input memory to PVS/RS memory */      if (caps->has_tcl) { @@ -161,27 +192,21 @@ static void r300_surface_fill(struct pipe_context* pipe,      /* Disable textures */      OUT_CS_REG(R300_TX_ENABLE, 0x0); -    /* 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); -      /* The size of the point we're about to draw, in sixths of pixels */      OUT_CS_REG(R300_GA_POINT_SIZE, -        ((h * 6) & R300_POINTSIZE_Y_MASK) | +        ((h * 6)  & R300_POINTSIZE_Y_MASK) |          ((w * 6) << R300_POINTSIZE_X_SHIFT)); +    /* Vertex size. */ +    OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8); +      /* Packet3 with our point vertex */      OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8);      OUT_CS(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |              (1 << R300_PRIM_NUM_VERTICES_SHIFT));      /* Position */ -    OUT_CS_32F(w / 2.0); -    OUT_CS_32F(h / 2.0); +    OUT_CS_32F(0.5); +    OUT_CS_32F(0.5);      OUT_CS_32F(1.0);      OUT_CS_32F(1.0);      /* Color */ @@ -190,11 +215,7 @@ static void r300_surface_fill(struct pipe_context* pipe,      OUT_CS_32F(b);      OUT_CS_32F(a); -    /* 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); */      END_CS; @@ -213,30 +234,63 @@ static void r300_surface_copy(struct pipe_context* pipe,      struct r300_texture* srctex = (struct r300_texture*)src->texture;      struct r300_texture* desttex = (struct r300_texture*)dest->texture;      unsigned pixpitch = srctex->stride / srctex->tex.block.size; +    boolean invalid = FALSE; +    float fsrcx = srcx, fsrcy = srcy, fdestx = destx, fdesty = desty;      CS_LOCALS(r300);      debug_printf("r300: Copying surface %p at (%d,%d) to %p at (%d, %d),"          " dimensions %dx%d (pixel pitch %d)\n",          src, srcx, srcy, dest, destx, desty, w, h, pixpitch); -    if ((srctex == desttex) && +    if ((srctex->buffer == desttex->buffer) &&              ((destx < srcx + w) || (srcx < destx + w)) &&              ((desty < srcy + h) || (srcy < desty + h))) { +fallback:          debug_printf("r300: Falling back on surface_copy\n");          util_surface_copy(pipe, FALSE, dest, destx, desty, src,                  srcx, srcy, w, h);      } -    r300_emit_sampler(r300, &r300_sampler_copy_state, 0); -    r300_emit_texture(r300, srctex, 0); +    /* Add our target BOs to the list. */ +validate: +    if (!r300->winsys->add_buffer(r300->winsys, srctex->buffer, +                RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { +        r300->context.flush(&r300->context, 0, NULL); +        goto validate; +    } +    if (!r300->winsys->add_buffer(r300->winsys, desttex->buffer, +                0, RADEON_GEM_DOMAIN_VRAM)) { +        r300->context.flush(&r300->context, 0, NULL); +        goto validate; +    } +    if (!r300->winsys->validate(r300->winsys)) { +        r300->context.flush(&r300->context, 0, NULL); +        if (invalid) { +            debug_printf("r300: Stuck in validation loop, gonna fallback."); +            goto fallback; +        } +        invalid = TRUE; +        goto validate; +    } + +    r300_surface_setup(r300, desttex, destx, desty, w, h); + +    /* Setup the texture. */ +    r300_emit_texture(r300, &r300_sampler_copy_state, srctex, 0); + +    /* Flush and enable. */      r300_flush_textures(r300);      /* Vertex shader setup */      if (caps->has_tcl) { -        r300_emit_vertex_shader(r300, &r300_texture_vertex_shader); +        r300_emit_vertex_program_code(r300, &r300_passthrough_vertex_shader, 0);      } else {          BEGIN_CS(4); -        OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS); +        OUT_CS_REG(R300_VAP_CNTL_STATUS, +#ifdef PIPE_ARCH_BIG_ENDIAN +                   R300_VC_32BIT_SWAP | +#endif +                   R300_VAP_TCL_BYPASS);          OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) |                  R300_PVS_NUM_CNTLRS(5) |                  R300_PVS_NUM_FPUS(caps->num_vert_fpus) | @@ -246,13 +300,14 @@ static void r300_surface_copy(struct pipe_context* pipe,      /* Fragment shader setup */      if (caps->is_r500) { -        r500_emit_fragment_shader(r300, &r500_texture_fragment_shader); -        r300_emit_rs_block_state(r300, &r500_rs_block_copy_state); +        r500_emit_fragment_program_code(r300, &r5xx_texture_fragment_shader, 0); +        r300_emit_rs_block_state(r300, &r5xx_rs_block_copy_state);      } else { -        r300_emit_fragment_shader(r300, &r300_texture_fragment_shader); -        r300_emit_rs_block_state(r300, &r300_rs_block_copy_state); +        r300_emit_fragment_program_code(r300, &r3xx_texture_fragment_shader, 0); +        r300_emit_rs_block_state(r300, &r3xx_rs_block_copy_state);      } +    BEGIN_CS(30);      /* VAP stream control, mapping from input memory to PVS/RS memory */      if (caps->has_tcl) {          OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, @@ -275,33 +330,38 @@ static void r300_surface_copy(struct pipe_context* pipe,      /* Two components of texture 0 */      OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x2); +    /* Vertex size. */ +    OUT_CS_REG(R300_VAP_VTX_SIZE, 0x4); +      /* Packet3 with our texcoords */ -    OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8); +    OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 16);      OUT_CS(R300_PRIM_TYPE_QUADS | R300_PRIM_WALK_RING |              (4 << R300_PRIM_NUM_VERTICES_SHIFT));      /* (x    , y    ) */ -    OUT_CS_32F((float)destx); -    OUT_CS_32F((float)desty); -    OUT_CS_32F((float)srcx); -    OUT_CS_32F((float)srcy); +    OUT_CS_32F(fdestx / dest->width); +    OUT_CS_32F(fdesty / dest->height); +    OUT_CS_32F(fsrcx  / src->width); +    OUT_CS_32F(fsrcy  / src->height);      /* (x    , y + h) */ -    OUT_CS_32F((float)destx); -    OUT_CS_32F((float)(desty + h)); -    OUT_CS_32F((float)srcx); -    OUT_CS_32F((float)(srcy + h)); +    OUT_CS_32F(fdestx / dest->width); +    OUT_CS_32F((fdesty + h) / dest->height); +    OUT_CS_32F(fsrcx  / src->width); +    OUT_CS_32F((fsrcy  + h) / src->height);      /* (x + w, y + h) */ -    OUT_CS_32F((float)(destx + w)); -    OUT_CS_32F((float)(desty + h)); -    OUT_CS_32F((float)(srcx + w)); -    OUT_CS_32F((float)(srcy + h)); +    OUT_CS_32F((fdestx + w) / dest->width); +    OUT_CS_32F((fdesty + h) / dest->height); +    OUT_CS_32F((fsrcx  + w) / src->width); +    OUT_CS_32F((fsrcy  + h) / src->height);      /* (x + w, y    ) */ -    OUT_CS_32F((float)(destx + w)); -    OUT_CS_32F((float)desty); -    OUT_CS_32F((float)(srcx + w)); -    OUT_CS_32F((float)srcy); +    OUT_CS_32F((fdestx + w) / dest->width); +    OUT_CS_32F(fdesty / dest->height); +    OUT_CS_32F((fsrcx  + w) / src->width); +    OUT_CS_32F(fsrcy  / src->height);      OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA); +    END_CS; +      r300->dirty_hw++;  } diff --git a/src/gallium/drivers/r300/r300_surface.h b/src/gallium/drivers/r300/r300_surface.h index 894def07aa..f9e98b2ec9 100644 --- a/src/gallium/drivers/r300/r300_surface.h +++ b/src/gallium/drivers/r300/r300_surface.h @@ -31,8 +31,8 @@  #include "r300_context.h"  #include "r300_cs.h"  #include "r300_emit.h" -#include "r300_state_shader.h" -#include "r300_state_tcl.h" +#include "r300_fs.h" +#include "r300_vs.h"  #include "r300_state_inlines.h"  static struct r300_blend_state blend_clear_state = { @@ -72,17 +72,17 @@ static struct r300_rs_state rs_clear_state = {      .color_control = R300_SHADE_MODEL_FLAT,  }; -static struct r300_rs_block r300_rs_block_clear_state = { -    .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) | -        R500_RS_SEL_T(R300_RS_SEL_K0) | -        R500_RS_SEL_R(R300_RS_SEL_K0) | +static struct r300_rs_block r3xx_rs_block_clear_state = { +    .ip[0] = R500_RS_SEL_S(R300_RS_SEL_C0) | +        R500_RS_SEL_T(R300_RS_SEL_C0) | +        R500_RS_SEL_R(R300_RS_SEL_C0) |          R500_RS_SEL_Q(R300_RS_SEL_K1),      .inst[0] = R300_RS_INST_COL_CN_WRITE,      .count = R300_IT_COUNT(0) | R300_IC_COUNT(1) | R300_HIRES_EN,      .inst_count = 0,  }; -static struct r300_rs_block r500_rs_block_clear_state = { +static struct r300_rs_block r5xx_rs_block_clear_state = {      .ip[0] = R500_RS_SEL_S(R500_RS_IP_PTR_K0) |          R500_RS_SEL_T(R500_RS_IP_PTR_K0) |          R500_RS_SEL_R(R500_RS_IP_PTR_K0) | @@ -94,24 +94,24 @@ static struct r300_rs_block r500_rs_block_clear_state = {  /* The following state is used for surface_copy only. */ -static struct r300_rs_block r300_rs_block_copy_state = { +static struct r300_rs_block r3xx_rs_block_copy_state = {      .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) |          R500_RS_SEL_T(R300_RS_SEL_K0) |          R500_RS_SEL_R(R300_RS_SEL_K0) |          R500_RS_SEL_Q(R300_RS_SEL_K1),      .inst[0] = R300_RS_INST_COL_CN_WRITE,      .count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN, -    .inst_count = R300_RS_TX_OFFSET(6), +    .inst_count = R300_RS_TX_OFFSET(0),  }; -static struct r300_rs_block r500_rs_block_copy_state = { +static struct r300_rs_block r5xx_rs_block_copy_state = {      .ip[0] = R500_RS_SEL_S(0) |          R500_RS_SEL_T(1) |          R500_RS_SEL_R(R500_RS_IP_PTR_K0) |          R500_RS_SEL_Q(R500_RS_IP_PTR_K1),      .inst[0] = R500_RS_INST_TEX_CN_WRITE,      .count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN, -    .inst_count = R300_RS_TX_OFFSET(6), +    .inst_count = R300_RS_TX_OFFSET(0),  };  static struct r300_sampler_state r300_sampler_copy_state = { diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index fe91f4e184..590052509c 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -22,33 +22,35 @@  #include "r300_texture.h" -static int minify(int i) -{ -    return MAX2(1, i >> 1); -} -  static void r300_setup_texture_state(struct r300_texture* tex,                                       unsigned width,                                       unsigned height, -                                     unsigned pitch) +                                     unsigned pitch, +                                     unsigned levels)  {      struct r300_texture_state* state = &tex->state;      state->format0 = R300_TX_WIDTH((width - 1) & 0x7ff) | -        R300_TX_HEIGHT((height - 1) & 0x7ff) | R300_TX_PITCH_EN; +        R300_TX_HEIGHT((height - 1) & 0x7ff) | +        R300_TX_NUM_LEVELS(levels) | +        R300_TX_PITCH_EN;      /* XXX */ -    state->format1 = R300_TX_FORMAT_A8R8G8B8; +    state->format1 = r300_translate_texformat(tex->tex.format);      state->format2 = pitch - 1; -    /* XXX +    /* Assume (somewhat foolishly) that oversized textures will +     * not be permitted by the state tracker. */      if (width > 2048) { -        state->pitch |= R300_TXWIDTH_11; +        state->format2 |= R500_TXWIDTH_BIT11;      }      if (height > 2048) { -        state->pitch |= R300_TXHEIGHT_11; -    } */ +        state->format2 |= R500_TXHEIGHT_BIT11; +    } + +    debug_printf("r300: Set texture state (%dx%d, pitch %d, %d levels)\n", +            width, height, pitch, levels);  }  static void r300_setup_miptree(struct r300_texture* tex) @@ -65,16 +67,24 @@ static void r300_setup_miptree(struct r300_texture* tex)          }          base->nblocksx[i] = pf_get_nblocksx(&base->block, base->width[i]); -        base->nblocksy[i] = pf_get_nblocksy(&base->block, base->width[i]); +        base->nblocksy[i] = pf_get_nblocksy(&base->block, base->height[i]); -        /* Radeons enjoy things in multiples of 32. */ -        /* XXX this can be 32 when POT */ -        stride = (base->nblocksx[i] * base->block.size + 63) & ~63; +        /* Radeons enjoy things in multiples of 64. +         * +         * XXX +         * POT, uncompressed, unmippmapped textures can be aligned to 32, +         * instead of 64. */ +        stride = align(pf_get_stride(&base->block, base->width[i]), 32);          size = stride * base->nblocksy[i] * base->depth[i]; -        tex->offset[i] = (tex->size + 63) & ~63; +        tex->offset[i] = align(tex->size, 32);          tex->size = tex->offset[i] + size; +        debug_printf("r300: Texture miptree: Level %d " +                "(%dx%dx%d px, pitch %d bytes)\n", +                i, base->width[i], base->height[i], base->depth[i], +                stride); +        /* Save stride of first level to the texture. */          if (i == 0) {              tex->stride = stride;          } @@ -86,8 +96,6 @@ 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) { @@ -100,11 +108,10 @@ static struct pipe_texture*      r300_setup_miptree(tex); -    /* XXX */ -    r300_setup_texture_state(tex, tex->tex.width[0], tex->tex.height[0], -            tex->tex.width[0]); +    r300_setup_texture_state(tex, template->width[0], template->height[0], +            template->width[0], template->last_level); -    tex->buffer = screen->buffer_create(screen, 64, +    tex->buffer = screen->buffer_create(screen, 1024,                                          PIPE_BUFFER_USAGE_PIXEL,                                          tex->size); @@ -166,6 +173,7 @@ static struct pipe_texture*  {      struct r300_texture* tex; +    /* XXX we should start doing mips now... */      if (base->target != PIPE_TEXTURE_2D ||          base->last_level != 0 ||          base->depth[0] != 1) { @@ -183,8 +191,9 @@ static struct pipe_texture*      tex->stride = *stride; +    /* XXX */      r300_setup_texture_state(tex, tex->tex.width[0], tex->tex.height[0], -            tex->stride); +            tex->stride, 0);      pipe_buffer_reference(&tex->buffer, buffer); diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 98fb5c9a08..3b56f0307c 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -32,6 +32,52 @@  void r300_init_screen_texture_functions(struct pipe_screen* screen); +/* Note the signature of R300_EASY_TX_FORMAT(A, R, G, B, FORMAT)... */ +static INLINE uint32_t r300_translate_texformat(enum pipe_format format) +{ +    switch (format) { +        /* X8 */ +        case PIPE_FORMAT_I8_UNORM: +            return R300_EASY_TX_FORMAT(X, X, X, X, X8); +        /* W8Z8Y8X8 */ +        case PIPE_FORMAT_A8R8G8B8_UNORM: +            return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); +        case PIPE_FORMAT_R8G8B8A8_UNORM: +            return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8); +        case PIPE_FORMAT_A8R8G8B8_SRGB: +            return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8) | +                R300_TX_FORMAT_GAMMA; +        case PIPE_FORMAT_R8G8B8A8_SRGB: +            return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8) | +                R300_TX_FORMAT_GAMMA; +        /* DXT1 */ +        case PIPE_FORMAT_DXT1_RGB: +            return R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1); +        case PIPE_FORMAT_DXT1_RGBA: +            return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1); +        /* DXT3 */ +        case PIPE_FORMAT_DXT3_RGBA: +            return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3); +        /* DXT5 */ +        case PIPE_FORMAT_DXT5_RGBA: +            return R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5); +        /* YVYU422 */ +        case PIPE_FORMAT_YCBCR: +            return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | +                R300_TX_FORMAT_YUV_TO_RGB; +        /* W24_FP */ +        case PIPE_FORMAT_Z24S8_UNORM: +            return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP); +        default: +            debug_printf("r300: Implementation error: " +                "Got unsupported texture format %s in %s\n", +                pf_name(format), __FUNCTION__); +            assert(0); +            break; +    } +    return 0; +} +  #ifndef R300_WINSYS_H  boolean r300_get_texture_buffer(struct pipe_texture* texture, diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c new file mode 100644 index 0000000000..d68a104106 --- /dev/null +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -0,0 +1,336 @@ +/* + * Copyright 2009 Nicolai Hähnle <nhaehnle@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 COPYRIGHT HOLDER(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_tgsi_to_rc.h" + +#include "radeon_compiler.h" +#include "radeon_program.h" + +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_scan.h" +#include "tgsi/tgsi_util.h" + + +static unsigned translate_opcode(unsigned opcode) +{ +    switch(opcode) { +        case TGSI_OPCODE_ARL: return OPCODE_ARL; +        case TGSI_OPCODE_MOV: return OPCODE_MOV; +        case TGSI_OPCODE_LIT: return OPCODE_LIT; +        case TGSI_OPCODE_RCP: return OPCODE_RCP; +        case TGSI_OPCODE_RSQ: return OPCODE_RSQ; +        case TGSI_OPCODE_EXP: return OPCODE_EXP; +        case TGSI_OPCODE_LOG: return OPCODE_LOG; +        case TGSI_OPCODE_MUL: return OPCODE_MUL; +        case TGSI_OPCODE_ADD: return OPCODE_ADD; +        case TGSI_OPCODE_DP3: return OPCODE_DP3; +        case TGSI_OPCODE_DP4: return OPCODE_DP4; +        case TGSI_OPCODE_DST: return OPCODE_DST; +        case TGSI_OPCODE_MIN: return OPCODE_MIN; +        case TGSI_OPCODE_MAX: return OPCODE_MAX; +        case TGSI_OPCODE_SLT: return OPCODE_SLT; +        case TGSI_OPCODE_SGE: return OPCODE_SGE; +        case TGSI_OPCODE_MAD: return OPCODE_MAD; +        case TGSI_OPCODE_SUB: return OPCODE_SUB; +        case TGSI_OPCODE_LRP: return OPCODE_LRP; +     /* case TGSI_OPCODE_CND: return OPCODE_CND; */ +        case TGSI_OPCODE_DP2A: return OPCODE_DP2A; +                                        /* gap */ +        case TGSI_OPCODE_FRC: return OPCODE_FRC; +     /* case TGSI_OPCODE_CLAMP: return OPCODE_CLAMP; */ +        case TGSI_OPCODE_FLR: return OPCODE_FLR; +     /* case TGSI_OPCODE_ROUND: return OPCODE_ROUND; */ +        case TGSI_OPCODE_EX2: return OPCODE_EX2; +        case TGSI_OPCODE_LG2: return OPCODE_LG2; +        case TGSI_OPCODE_POW: return OPCODE_POW; +        case TGSI_OPCODE_XPD: return OPCODE_XPD; +                                        /* gap */ +        case TGSI_OPCODE_ABS: return OPCODE_ABS; +        case TGSI_OPCODE_RCC: return OPCODE_RCC; +        case TGSI_OPCODE_DPH: return OPCODE_DPH; +        case TGSI_OPCODE_COS: return OPCODE_COS; +        case TGSI_OPCODE_DDX: return OPCODE_DDX; +        case TGSI_OPCODE_DDY: return OPCODE_DDY; +     /* case TGSI_OPCODE_KILP: return OPCODE_KILP; */ +        case TGSI_OPCODE_PK2H: return OPCODE_PK2H; +        case TGSI_OPCODE_PK2US: return OPCODE_PK2US; +        case TGSI_OPCODE_PK4B: return OPCODE_PK4B; +        case TGSI_OPCODE_PK4UB: return OPCODE_PK4UB; +        case TGSI_OPCODE_RFL: return OPCODE_RFL; +        case TGSI_OPCODE_SEQ: return OPCODE_SEQ; +        case TGSI_OPCODE_SFL: return OPCODE_SFL; +        case TGSI_OPCODE_SGT: return OPCODE_SGT; +        case TGSI_OPCODE_SIN: return OPCODE_SIN; +        case TGSI_OPCODE_SLE: return OPCODE_SLE; +        case TGSI_OPCODE_SNE: return OPCODE_SNE; +        case TGSI_OPCODE_STR: return OPCODE_STR; +        case TGSI_OPCODE_TEX: return OPCODE_TEX; +        case TGSI_OPCODE_TXD: return OPCODE_TXD; +        case TGSI_OPCODE_TXP: return OPCODE_TXP; +        case TGSI_OPCODE_UP2H: return OPCODE_UP2H; +        case TGSI_OPCODE_UP2US: return OPCODE_UP2US; +        case TGSI_OPCODE_UP4B: return OPCODE_UP4B; +        case TGSI_OPCODE_UP4UB: return OPCODE_UP4UB; +        case TGSI_OPCODE_X2D: return OPCODE_X2D; +        case TGSI_OPCODE_ARA: return OPCODE_ARA; +        case TGSI_OPCODE_ARR: return OPCODE_ARR; +        case TGSI_OPCODE_BRA: return OPCODE_BRA; +        case TGSI_OPCODE_CAL: return OPCODE_CAL; +        case TGSI_OPCODE_RET: return OPCODE_RET; +        case TGSI_OPCODE_SSG: return OPCODE_SSG; +        case TGSI_OPCODE_CMP: return OPCODE_CMP; +        case TGSI_OPCODE_SCS: return OPCODE_SCS; +        case TGSI_OPCODE_TXB: return OPCODE_TXB; +     /* case TGSI_OPCODE_NRM: return OPCODE_NRM; */ +     /* case TGSI_OPCODE_DIV: return OPCODE_DIV; */ +        case TGSI_OPCODE_DP2: return OPCODE_DP2; +        case TGSI_OPCODE_TXL: return OPCODE_TXL; +        case TGSI_OPCODE_BRK: return OPCODE_BRK; +        case TGSI_OPCODE_IF: return OPCODE_IF; +     /* case TGSI_OPCODE_LOOP: return OPCODE_LOOP; */ +     /* case TGSI_OPCODE_REP: return OPCODE_REP; */ +        case TGSI_OPCODE_ELSE: return OPCODE_ELSE; +        case TGSI_OPCODE_ENDIF: return OPCODE_ENDIF; +        case TGSI_OPCODE_ENDLOOP: return OPCODE_ENDLOOP; +     /* case TGSI_OPCODE_ENDREP: return OPCODE_ENDREP; */ +        case TGSI_OPCODE_PUSHA: return OPCODE_PUSHA; +        case TGSI_OPCODE_POPA: return OPCODE_POPA; +     /* case TGSI_OPCODE_CEIL: return OPCODE_CEIL; */ +     /* case TGSI_OPCODE_I2F: return OPCODE_I2F; */ +        case TGSI_OPCODE_NOT: return OPCODE_NOT; +        case TGSI_OPCODE_TRUNC: return OPCODE_TRUNC; +     /* case TGSI_OPCODE_SHL: return OPCODE_SHL; */ +     /* case TGSI_OPCODE_SHR: return OPCODE_SHR; */ +        case TGSI_OPCODE_AND: return OPCODE_AND; +        case TGSI_OPCODE_OR: return OPCODE_OR; +     /* case TGSI_OPCODE_MOD: return OPCODE_MOD; */ +        case TGSI_OPCODE_XOR: return OPCODE_XOR; +     /* case TGSI_OPCODE_SAD: return OPCODE_SAD; */ +     /* case TGSI_OPCODE_TXF: return OPCODE_TXF; */ +     /* case TGSI_OPCODE_TXQ: return OPCODE_TXQ; */ +        case TGSI_OPCODE_CONT: return OPCODE_CONT; +     /* case TGSI_OPCODE_EMIT: return OPCODE_EMIT; */ +     /* case TGSI_OPCODE_ENDPRIM: return OPCODE_ENDPRIM; */ +     /* case TGSI_OPCODE_BGNLOOP2: return OPCODE_BGNLOOP2; */ +        case TGSI_OPCODE_BGNSUB: return OPCODE_BGNSUB; +     /* case TGSI_OPCODE_ENDLOOP2: return OPCODE_ENDLOOP2; */ +        case TGSI_OPCODE_ENDSUB: return OPCODE_ENDSUB; +        case TGSI_OPCODE_NOISE1: return OPCODE_NOISE1; +        case TGSI_OPCODE_NOISE2: return OPCODE_NOISE2; +        case TGSI_OPCODE_NOISE3: return OPCODE_NOISE3; +        case TGSI_OPCODE_NOISE4: return OPCODE_NOISE4; +        case TGSI_OPCODE_NOP: return OPCODE_NOP; +                                        /* gap */ +        case TGSI_OPCODE_NRM4: return OPCODE_NRM4; +     /* case TGSI_OPCODE_CALLNZ: return OPCODE_CALLNZ; */ +     /* case TGSI_OPCODE_IFC: return OPCODE_IFC; */ +     /* case TGSI_OPCODE_BREAKC: return OPCODE_BREAKC; */ +        case TGSI_OPCODE_KIL: return OPCODE_KIL; +        case TGSI_OPCODE_END: return OPCODE_END; +        case TGSI_OPCODE_SWZ: return OPCODE_SWZ; +    } + +    fprintf(stderr, "Unknown opcode: %i\n", opcode); +    abort(); +} + +static unsigned translate_saturate(unsigned saturate) +{ +    switch(saturate) { +        case TGSI_SAT_NONE: return SATURATE_OFF; +        case TGSI_SAT_ZERO_ONE: return SATURATE_ZERO_ONE; +        case TGSI_SAT_MINUS_PLUS_ONE: return SATURATE_PLUS_MINUS_ONE; +    } + +    fprintf(stderr, "Unknown saturate mode: %i\n", saturate); +    abort(); +} + +static unsigned translate_register_file(unsigned file) +{ +    switch(file) { +        case TGSI_FILE_CONSTANT: return PROGRAM_CONSTANT; +        case TGSI_FILE_IMMEDIATE: return PROGRAM_CONSTANT; +        case TGSI_FILE_INPUT: return PROGRAM_INPUT; +        case TGSI_FILE_OUTPUT: return PROGRAM_OUTPUT; +        case TGSI_FILE_TEMPORARY: return PROGRAM_TEMPORARY; +        case TGSI_FILE_ADDRESS: return PROGRAM_ADDRESS; +    } + +    fprintf(stderr, "Unhandled register file: %i\n", file); +    abort(); +} + +static int translate_register_index( +    struct tgsi_to_rc * ttr, +    unsigned file, +    int index) +{ +    if (file == TGSI_FILE_IMMEDIATE) +        return ttr->immediate_offset + index; + +    return index; +} + +static void transform_dstreg( +    struct tgsi_to_rc * ttr, +    struct prog_dst_register * dst, +    struct tgsi_full_dst_register * src) +{ +    dst->File = translate_register_file(src->DstRegister.File); +    dst->Index = translate_register_index(ttr, src->DstRegister.File, src->DstRegister.Index); +    dst->WriteMask = src->DstRegister.WriteMask; +    dst->RelAddr = src->DstRegister.Indirect; +} + +static void transform_srcreg( +    struct tgsi_to_rc * ttr, +    struct prog_src_register * dst, +    struct tgsi_full_src_register * src) +{ +    dst->File = translate_register_file(src->SrcRegister.File); +    dst->Index = translate_register_index(ttr, src->SrcRegister.File, src->SrcRegister.Index); +    dst->RelAddr = src->SrcRegister.Indirect; +    dst->Swizzle = tgsi_util_get_full_src_register_extswizzle(src, 0); +    dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 1) << 3; +    dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 2) << 6; +    dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 3) << 9; +    dst->Abs = src->SrcRegisterExtMod.Absolute; +    dst->Negate = +        src->SrcRegisterExtSwz.NegateX | +        (src->SrcRegisterExtSwz.NegateY << 1) | +        (src->SrcRegisterExtSwz.NegateZ << 2) | +        (src->SrcRegisterExtSwz.NegateW << 3); +    dst->Negate ^= src->SrcRegister.Negate ? NEGATE_XYZW : 0; +} + +static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_ext_texture src) +{ +    switch(src.Texture) { +        case TGSI_TEXTURE_1D: +            dst->I.TexSrcTarget = TEXTURE_1D_INDEX; +            break; +        case TGSI_TEXTURE_2D: +            dst->I.TexSrcTarget = TEXTURE_2D_INDEX; +            break; +        case TGSI_TEXTURE_3D: +            dst->I.TexSrcTarget = TEXTURE_3D_INDEX; +            break; +        case TGSI_TEXTURE_CUBE: +            dst->I.TexSrcTarget = TEXTURE_CUBE_INDEX; +            break; +        case TGSI_TEXTURE_RECT: +            dst->I.TexSrcTarget = TEXTURE_RECT_INDEX; +            break; +        case TGSI_TEXTURE_SHADOW1D: +            dst->I.TexSrcTarget = TEXTURE_1D_INDEX; +            dst->I.TexShadow = 1; +            break; +        case TGSI_TEXTURE_SHADOW2D: +            dst->I.TexSrcTarget = TEXTURE_2D_INDEX; +            dst->I.TexShadow = 1; +            break; +        case TGSI_TEXTURE_SHADOWRECT: +            dst->I.TexSrcTarget = TEXTURE_RECT_INDEX; +            dst->I.TexShadow = 1; +            break; +    } +} + +static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_instruction * src) +{ +    if (src->Instruction.Opcode == TGSI_OPCODE_END) +        return; + +    struct rc_instruction * dst = rc_insert_new_instruction(ttr->compiler, ttr->compiler->Program.Instructions.Prev); +    int i; + +    dst->I.Opcode = translate_opcode(src->Instruction.Opcode); +    dst->I.SaturateMode = translate_saturate(src->Instruction.Saturate); + +    if (src->Instruction.NumDstRegs) +        transform_dstreg(ttr, &dst->I.DstReg, &src->FullDstRegisters[0]); + +    for(i = 0; i < src->Instruction.NumSrcRegs; ++i) { +        if (src->FullSrcRegisters[i].SrcRegister.File == TGSI_FILE_SAMPLER) +            dst->I.TexSrcUnit = src->FullSrcRegisters[i].SrcRegister.Index; +        else +            transform_srcreg(ttr, &dst->I.SrcReg[i], &src->FullSrcRegisters[i]); +    } + +    /* Texturing. */ +    transform_texture(dst, src->InstructionExtTexture); +} + +static void handle_immediate(struct tgsi_to_rc * ttr, struct tgsi_full_immediate * imm) +{ +    struct rc_constant constant; +    int i; + +    constant.Type = RC_CONSTANT_IMMEDIATE; +    constant.Size = 4; +    for(i = 0; i < 4; ++i) +        constant.u.Immediate[i] = imm->u[i].Float; +    rc_constants_add(&ttr->compiler->Program.Constants, &constant); +} + +void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens) +{ +    struct tgsi_parse_context parser; +    int i; + +    /* Allocate constants placeholders. +     * +     * Note: What if declared constants are not contiguous? */ +    for(i = 0; i <= ttr->info->file_max[TGSI_FILE_CONSTANT]; ++i) { +        struct rc_constant constant; +        memset(&constant, 0, sizeof(constant)); +        constant.Type = RC_CONSTANT_EXTERNAL; +        constant.Size = 4; +        constant.u.External = i; +        rc_constants_add(&ttr->compiler->Program.Constants, &constant); +    } + +    ttr->immediate_offset = ttr->compiler->Program.Constants.Count; + +    tgsi_parse_init(&parser, tokens); + +    while (!tgsi_parse_end_of_tokens(&parser)) { +        tgsi_parse_token(&parser); + +        switch (parser.FullToken.Token.Type) { +            case TGSI_TOKEN_TYPE_DECLARATION: +                break; +            case TGSI_TOKEN_TYPE_IMMEDIATE: +                handle_immediate(ttr, &parser.FullToken.FullImmediate); +                break; +            case TGSI_TOKEN_TYPE_INSTRUCTION: +                transform_instruction(ttr, &parser.FullToken.FullInstruction); +                break; +        } +    } + +    tgsi_parse_free(&parser); + +    rc_calculate_inputs_outputs(ttr->compiler); +} + diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.h b/src/gallium/drivers/r300/r300_tgsi_to_rc.h new file mode 100644 index 0000000000..93e90ec6d2 --- /dev/null +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.h @@ -0,0 +1,41 @@ +/* + * Copyright 2009 Nicolai Hähnle <nhaehnle@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 COPYRIGHT HOLDER(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_TGSI_TO_RC_H +#define R300_TGSI_TO_RC_H + +struct radeon_compiler; + +struct tgsi_full_declaration; +struct tgsi_shader_info; +struct tgsi_token; + +struct tgsi_to_rc { +    struct radeon_compiler * compiler; +    const struct tgsi_shader_info * info; + +    int immediate_offset; +}; + +void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens); + +#endif /* R300_TGSI_TO_RC_H */ diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c new file mode 100644 index 0000000000..2cb903bba2 --- /dev/null +++ b/src/gallium/drivers/r300/r300_vs.c @@ -0,0 +1,234 @@ +/* + * Copyright 2009 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_vs.h" + +#include "r300_context.h" +#include "r300_tgsi_to_rc.h" + +#include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_parse.h" + +#include "radeon_compiler.h" + + +static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c) +{ +    struct r300_vertex_shader * vs = c->UserData; +    struct tgsi_shader_info* info = &vs->info; +    boolean pointsize = false; +    int out_colors = 0; +    int colors = 0; +    int out_generic = 0; +    int generic = 0; +    int i; + +    /* Fill in the input mapping */ +    for (i = 0; i < info->num_inputs; i++) +        c->code->inputs[i] = i; + +    /* Fill in the output mapping */ +    for (i = 0; i < info->num_outputs; i++) { +        switch (info->output_semantic_name[i]) { +            case TGSI_SEMANTIC_PSIZE: +                pointsize = true; +                break; +            case TGSI_SEMANTIC_COLOR: +                out_colors++; +                break; +            case TGSI_SEMANTIC_FOG: +            case TGSI_SEMANTIC_GENERIC: +                out_generic++; +                break; +        } +    } + +    struct tgsi_parse_context parser; + +    tgsi_parse_init(&parser, vs->state.tokens); + +    while (!tgsi_parse_end_of_tokens(&parser)) { +        tgsi_parse_token(&parser); + +        if (parser.FullToken.Token.Type != TGSI_TOKEN_TYPE_DECLARATION) +            continue; + +        struct tgsi_full_declaration * decl = &parser.FullToken.FullDeclaration; + +        if (decl->Declaration.File != TGSI_FILE_OUTPUT) +            continue; + +        switch (decl->Semantic.SemanticName) { +            case TGSI_SEMANTIC_POSITION: +                c->code->outputs[decl->DeclarationRange.First] = 0; +                break; +            case TGSI_SEMANTIC_PSIZE: +                c->code->outputs[decl->DeclarationRange.First] = 1; +                break; +            case TGSI_SEMANTIC_COLOR: +                c->code->outputs[decl->DeclarationRange.First] = 1 + +                    (pointsize ? 1 : 0) + +                    colors++; +                break; +            case TGSI_SEMANTIC_FOG: +            case TGSI_SEMANTIC_GENERIC: +                c->code->outputs[decl->DeclarationRange.First] = 1 + +                    (pointsize ? 1 : 0) + +                    out_colors + +                    generic++; +                break; +            default: +                debug_printf("r300: vs: Bad semantic declaration %d\n", +                    decl->Semantic.SemanticName); +                break; +        } +    } + +    tgsi_parse_free(&parser); +} + + +void r300_translate_vertex_shader(struct r300_context* r300, +                                  struct r300_vertex_shader* vs) +{ +    struct r300_vertex_program_compiler compiler; +    struct tgsi_to_rc ttr; + +    /* Setup the compiler */ +    rc_init(&compiler.Base); + +    compiler.Base.Debug = 1; +    compiler.code = &vs->code; +    compiler.UserData = vs; + +    if (compiler.Base.Debug) { +        debug_printf("r300: Initial vertex program\n"); +        tgsi_dump(vs->state.tokens, 0); +    } + +    /* Translate TGSI to our internal representation */ +    ttr.compiler = &compiler.Base; +    ttr.info = &vs->info; + +    r300_tgsi_to_rc(&ttr, vs->state.tokens); + +    compiler.RequiredOutputs = ~(~0 << vs->info.num_outputs); +    compiler.SetHwInputOutput = &set_vertex_inputs_outputs; + +    /* Invoke the compiler */ +    r3xx_compile_vertex_program(&compiler); +    if (compiler.Base.Error) { +        /* Todo: Fail gracefully */ +        fprintf(stderr, "r300 VP: Compiler error\n"); +        abort(); +    } + +    /* And, finally... */ +    rc_destroy(&compiler.Base); +    vs->translated = TRUE; +} + + +/* XXX get these to r300_reg */ +#define R300_PVS_DST_OPCODE(x)   ((x) << 0) +#   define R300_VE_DOT_PRODUCT            1 +#   define R300_VE_MULTIPLY               2 +#   define R300_VE_ADD                    3 +#   define R300_VE_MAXIMUM                7 +#   define R300_VE_SET_LESS_THAN          10 +#define R300_PVS_DST_MATH_INST     (1 << 6) +#   define R300_ME_RECIP_DX               6 +#define R300_PVS_DST_MACRO_INST    (1 << 7) +#   define R300_PVS_MACRO_OP_2CLK_MADD    0 +#define R300_PVS_DST_REG_TYPE(x) ((x) << 8) +#   define R300_PVS_DST_REG_TEMPORARY     0 +#   define R300_PVS_DST_REG_A0            1 +#   define R300_PVS_DST_REG_OUT           2 +#   define R300_PVS_DST_REG_OUT_REPL_X    3 +#   define R300_PVS_DST_REG_ALT_TEMPORARY 4 +#   define R300_PVS_DST_REG_INPUT         5 +#define R300_PVS_DST_OFFSET(x)   ((x) << 13) +#define R300_PVS_DST_WE(x)       ((x) << 20) +#define R300_PVS_DST_WE_XYZW     (0xf << 20) + +#define R300_PVS_SRC_REG_TYPE(x) ((x) << 0) +#   define R300_PVS_SRC_REG_TEMPORARY     0 +#   define R300_PVS_SRC_REG_INPUT         1 +#   define R300_PVS_SRC_REG_CONSTANT      2 +#   define R300_PVS_SRC_REG_ALT_TEMPORARY 3 +#define R300_PVS_SRC_OFFSET(x)   ((x) << 5) +#define R300_PVS_SRC_SWIZZLE(x)  ((x) << 13) +#   define R300_PVS_SRC_SELECT_X          0 +#   define R300_PVS_SRC_SELECT_Y          1 +#   define R300_PVS_SRC_SELECT_Z          2 +#   define R300_PVS_SRC_SELECT_W          3 +#   define R300_PVS_SRC_SELECT_FORCE_0    4 +#   define R300_PVS_SRC_SELECT_FORCE_1    5 +#   define R300_PVS_SRC_SWIZZLE_XYZW \ +    ((R300_PVS_SRC_SELECT_X | (R300_PVS_SRC_SELECT_Y << 3) | \ +     (R300_PVS_SRC_SELECT_Z << 6) | (R300_PVS_SRC_SELECT_W << 9)) << 13) +#   define R300_PVS_SRC_SWIZZLE_ZERO \ +    ((R300_PVS_SRC_SELECT_FORCE_0 | (R300_PVS_SRC_SELECT_FORCE_0 << 3) | \ +     (R300_PVS_SRC_SELECT_FORCE_0 << 6) | \ +      (R300_PVS_SRC_SELECT_FORCE_0 << 9)) << 13) +#   define R300_PVS_SRC_SWIZZLE_ONE \ +    ((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \ +     (R300_PVS_SRC_SELECT_FORCE_1 << 6) | \ +      (R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13) +#define R300_PVS_MODIFIER_X        (1 << 25) +#define R300_PVS_MODIFIER_Y        (1 << 26) +#define R300_PVS_MODIFIER_Z        (1 << 27) +#define R300_PVS_MODIFIER_W        (1 << 28) +#define R300_PVS_NEGATE_XYZW \ +    (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \ +     R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W) + +struct r300_vertex_program_code r300_passthrough_vertex_shader = { +    .length = 8, /* two instructions */ + +    /* MOV out[0], in[0] */ +    .body.d[0] = R300_PVS_DST_OPCODE(R300_VE_ADD) | +        R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | +        R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW, +    .body.d[1] = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | +        R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW, +    .body.d[2] = R300_PVS_SRC_SWIZZLE_ZERO, +    .body.d[3] = 0x0, + +    /* MOV out[1], in[1] */ +    .body.d[4] = R300_PVS_DST_OPCODE(R300_VE_ADD) | +        R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) | +        R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW, +    .body.d[5] = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) | +        R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW, +    .body.d[6] = R300_PVS_SRC_SWIZZLE_ZERO, +    .body.d[7] = 0x0, + +    .inputs[0] = 0, +    .inputs[1] = 1, +    .outputs[0] = 0, +    .outputs[1] = 1, + +    .InputsRead = 3, +    .OutputsWritten = 3 +}; + diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h new file mode 100644 index 0000000000..2a4ce315e3 --- /dev/null +++ b/src/gallium/drivers/r300/r300_vs.h @@ -0,0 +1,54 @@ +/* + * Copyright 2009 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_VS_H +#define R300_VS_H + +#include "pipe/p_state.h" +#include "tgsi/tgsi_scan.h" + +#include "radeon_code.h" + +struct r300_context; + +struct r300_vertex_shader { +    /* Parent class */ +    struct pipe_shader_state state; +    struct tgsi_shader_info info; + +    /* Fallback shader, because Draw has issues */ +    struct draw_vertex_shader* draw; + +    /* Has this shader been translated yet? */ +    boolean translated; + +    /* Machine code (if translated) */ +    struct r300_vertex_program_code code; +}; + + +extern struct r300_vertex_program_code r300_passthrough_vertex_shader; + +void r300_translate_vertex_shader(struct r300_context* r300, +                                  struct r300_vertex_shader* vs); + +#endif /* R300_VS_H */ diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index a833bb0399..f18ad75a47 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -55,10 +55,10 @@ struct r300_winsys {      uint32_t vram_size;      /* Add a pipe_buffer to the list of buffer objects to validate. */ -    void (*add_buffer)(struct r300_winsys* winsys, -                       struct pipe_buffer* pbuffer, -                       uint32_t rd, -                       uint32_t wd); +    boolean (*add_buffer)(struct r300_winsys* winsys, +                          struct pipe_buffer* pbuffer, +                          uint32_t rd, +                          uint32_t wd);      /* Revalidate all currently setup pipe_buffers.       * Returns TRUE if a flush is required. */ diff --git a/src/gallium/drivers/r300/r3xx_fs.c b/src/gallium/drivers/r300/r3xx_fs.c new file mode 100644 index 0000000000..c1c1194d58 --- /dev/null +++ b/src/gallium/drivers/r300/r3xx_fs.c @@ -0,0 +1,74 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.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 "r3xx_fs.h" + +#include "r300_reg.h" + +struct rX00_fragment_program_code r3xx_passthrough_fragment_shader = { +    .code.r300.alu.length = 1, +    .code.r300.tex.length = 0, + +    .code.r300.config = 0, +    .code.r300.pixsize = 0, +    .code.r300.code_offset = 0, +    .code.r300.code_addr[3] = R300_RGBA_OUT, + +    .code.r300.alu.inst[0].rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | +        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | +        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | +        R300_ALU_OUTC_CMP, +    .code.r300.alu.inst[0].rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | +        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, +    .code.r300.alu.inst[0].alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | +        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | +        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | +        R300_ALU_OUTA_CMP, +    .code.r300.alu.inst[0].alpha_addr = R300_ALPHA_ADDR0(0) | +        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, +}; + +struct rX00_fragment_program_code r3xx_texture_fragment_shader = { +    .code.r300.alu.length = 1, +    .code.r300.tex.length = 1, + +    .code.r300.config = R300_PFS_CNTL_FIRST_NODE_HAS_TEX, +    .code.r300.pixsize = 0, +    .code.r300.code_offset = 0, +    .code.r300.code_addr[3] = R300_RGBA_OUT, + +    .code.r300.tex.inst[0] = R300_TEX_OP_LD << R300_TEX_INST_SHIFT, + +    .code.r300.alu.inst[0].rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | +        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | +        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | +        R300_ALU_OUTC_CMP, +    .code.r300.alu.inst[0].rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | +        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, +    .code.r300.alu.inst[0].alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | +        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | +        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | +        R300_ALU_OUTA_CMP, +    .code.r300.alu.inst[0].alpha_addr = R300_ALPHA_ADDR0(0) | +        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, +}; diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r3xx_fs.h index a1f873656d..51cd245724 100644 --- a/src/gallium/drivers/r300/r300_debug.h +++ b/src/gallium/drivers/r300/r3xx_fs.h @@ -1,5 +1,6 @@  /* - * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com> + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.com>   *   * Permission is hereby granted, free of charge, to any person obtaining a   * copy of this software and associated documentation files (the "Software"), @@ -20,15 +21,12 @@   * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE   * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef R300_DEBUG_H -#define R300_DEBUG_H +#ifndef R3XX_FS_H +#define R3XX_FS_H -#include "r300_reg.h" -#include "r300_state_shader.h" -#include "r300_state_tcl.h" +#include "radeon_code.h" -void r500_fs_dump(struct r500_fragment_shader* fs); +struct rX00_fragment_program_code r3xx_passthrough_fragment_shader; +struct rX00_fragment_program_code r3xx_texture_fragment_shader; -void r300_vs_dump(struct r300_vertex_shader* vs); - -#endif /* R300_DEBUG_H */ +#endif /* R3XX_FS_H */ diff --git a/src/gallium/drivers/r300/r5xx_fs.c b/src/gallium/drivers/r300/r5xx_fs.c new file mode 100644 index 0000000000..f072deab0d --- /dev/null +++ b/src/gallium/drivers/r300/r5xx_fs.c @@ -0,0 +1,125 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.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 "r5xx_fs.h" + +#include "r300_reg.h" + +/* XXX this all should find its way back to r300_reg */ +/* Swizzle tools */ +#define R500_SWIZZLE_ZERO 4 +#define R500_SWIZZLE_HALF 5 +#define R500_SWIZZLE_ONE 6 +#define R500_SWIZ_RGB_ZERO ((4 << 0) | (4 << 3) | (4 << 6)) +#define R500_SWIZ_RGB_ONE ((6 << 0) | (6 << 3) | (6 << 6)) +#define R500_SWIZ_RGB_RGB ((0 << 0) | (1 << 3) | (2 << 6)) +#define R500_SWIZ_MOD_NEG 1 +#define R500_SWIZ_MOD_ABS 2 +#define R500_SWIZ_MOD_NEG_ABS 3 +/* Swizzles for inst2 */ +#define R500_SWIZ_TEX_STRQ(x) ((x) << 8) +#define R500_SWIZ_TEX_RGBA(x) ((x) << 24) +/* Swizzles for inst3 */ +#define R500_SWIZ_RGB_A(x) ((x) << 2) +#define R500_SWIZ_RGB_B(x) ((x) << 15) +/* Swizzles for inst4 */ +#define R500_SWIZ_ALPHA_A(x) ((x) << 14) +#define R500_SWIZ_ALPHA_B(x) ((x) << 21) +/* Swizzle for inst5 */ +#define R500_SWIZ_RGBA_C(x) ((x) << 14) +#define R500_SWIZ_ALPHA_C(x) ((x) << 27) +/* Writemasks */ +#define R500_TEX_WMASK(x) ((x) << 11) +#define R500_ALU_WMASK(x) ((x) << 11) +#define R500_ALU_OMASK(x) ((x) << 15) +#define R500_W_OMASK (1 << 31) + +struct rX00_fragment_program_code r5xx_passthrough_fragment_shader = { +    .code.r500.max_temp_idx = 0, +    .code.r500.inst_end = 0, + +    .code.r500.inst[0].inst0 = R500_INST_TYPE_OUT | +        R500_INST_TEX_SEM_WAIT | R500_INST_LAST | +        R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | +        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, +    .code.r500.inst[0].inst1 = +        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | +        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, +    .code.r500.inst[0].inst2 = +        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | +        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, +    .code.r500.inst[0].inst3 = +        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, +    .code.r500.inst[0].inst4 = +        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, +    .code.r500.inst[0].inst5 = +        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, +}; + +struct rX00_fragment_program_code r5xx_texture_fragment_shader = { +    .code.r500.max_temp_idx = 0, +    .code.r500.inst_end = 1, + +    .code.r500.inst[0].inst0 = R500_INST_TYPE_TEX | +        R500_INST_TEX_SEM_WAIT | +        R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK | +        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, +    .code.r500.inst[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD | +        R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED, +    .code.r500.inst[0].inst2 = R500_TEX_SRC_ADDR(0) | +        R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G | +        R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A | +        R500_TEX_DST_ADDR(0) | +        R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | +        R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A, +    .code.r500.inst[0].inst3 = 0x0, +    .code.r500.inst[0].inst4 = 0x0, +    .code.r500.inst[0].inst5 = 0x0, + +    .code.r500.inst[1].inst0 = R500_INST_TYPE_OUT | +        R500_INST_TEX_SEM_WAIT | R500_INST_LAST | +        R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | +        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, +    .code.r500.inst[1].inst1 = +        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | +        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, +    .code.r500.inst[1].inst2 = +        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | +        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, +    .code.r500.inst[1].inst3 = +        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, +    .code.r500.inst[1].inst4 = +        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, +    .code.r500.inst[1].inst5 = +        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, +}; diff --git a/src/gallium/drivers/r300/r5xx_fs.h b/src/gallium/drivers/r300/r5xx_fs.h new file mode 100644 index 0000000000..a4addde32b --- /dev/null +++ b/src/gallium/drivers/r300/r5xx_fs.h @@ -0,0 +1,32 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.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 R5XX_FS_H +#define R5XX_FS_H + +#include "radeon_code.h" + +struct rX00_fragment_program_code r5xx_passthrough_fragment_shader; +struct rX00_fragment_program_code r5xx_texture_fragment_shader; + +#endif /* R5XX_FS_H */  | 
