Drop GLcontext typedef and use struct gl_context instead
[mesa.git] / src / mesa / drivers / dri / r300 / r300_blit.c
index ea626d942dcb6d25d25c7b052d212c405f09fc1a..9fd8e8fde5fbd6ce4088012a5017b4ed9d2f54da 100644 (file)
@@ -56,6 +56,7 @@ static void create_vertex_program(struct r300_context *r300)
     struct r300_vertex_program_compiler compiler;
     struct rc_instruction *inst;
 
+    memset(&compiler, 0, sizeof(compiler));
     rc_init(&compiler.Base);
 
     inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
@@ -88,6 +89,12 @@ static void create_vertex_program(struct r300_context *r300)
     compiler.RequiredOutputs = compiler.Base.Program.OutputsWritten = (1 << VERT_RESULT_HPOS) | (1 << VERT_RESULT_TEX0);
     compiler.SetHwInputOutput = vp_ins_outs;
     compiler.code = &r300->blit.vp_code;
+    compiler.Base.is_r500 = r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515;
+    compiler.Base.disable_optimizations = 0;
+    compiler.Base.has_half_swizzles = 0;
+    compiler.Base.max_temp_regs = 32;
+    compiler.Base.max_constants = 256;
+    compiler.Base.max_alu_insts = compiler.Base.is_r500 ? 1024 : 256;
 
     r3xx_compile_vertex_program(&compiler);
 }
@@ -97,6 +104,7 @@ static void create_fragment_program(struct r300_context *r300)
     struct r300_fragment_program_compiler compiler;
     struct rc_instruction *inst;
 
+    memset(&compiler, 0, sizeof(struct r300_fragment_program_compiler));
     rc_init(&compiler.Base);
 
     inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
@@ -114,9 +122,15 @@ static void create_fragment_program(struct r300_context *r300)
     inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
 
     compiler.Base.Program.InputsRead = (1 << FRAG_ATTRIB_TEX0);
-    compiler.OutputColor = FRAG_RESULT_COLOR;
+    compiler.OutputColor[0] = FRAG_RESULT_COLOR;
     compiler.OutputDepth = FRAG_RESULT_DEPTH;
-    compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515);
+    compiler.enable_shadow_ambient = GL_TRUE;
+    compiler.Base.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515);
+    compiler.Base.disable_optimizations = 0;
+    compiler.Base.has_half_swizzles = 1;
+    compiler.Base.max_temp_regs = (compiler.Base.is_r500) ? 128 : 32;
+    compiler.Base.max_constants = compiler.Base.is_r500 ? 256 : 32;
+    compiler.Base.max_alu_insts = compiler.Base.is_r500 ? 512 : 64;
     compiler.code = &r300->blit.fp_code;
     compiler.AllocateHwInputs = fp_allocate_hw_inputs;
 
@@ -125,7 +139,8 @@ static void create_fragment_program(struct r300_context *r300)
 
 void r300_blit_init(struct r300_context *r300)
 {
-    create_vertex_program(r300);
+    if (r300->options.hw_tcl_enabled)
+       create_vertex_program(r300);
     create_fragment_program(r300);
 }
 
@@ -137,10 +152,11 @@ static void r300_emit_tx_setup(struct r300_context *r300,
                                unsigned height,
                                unsigned pitch)
 {
+    int is_r500 = r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515;
     BATCH_LOCALS(&r300->radeon);
 
-    assert(width <= 2048);
-    assert(height <= 2048);
+    assert(is_r500 ? width  <= 4096 : width  <= 2048);
+    assert(is_r500 ? height <= 4096 : height <= 2048);
     assert(r300TranslateTexFormat(mesa_format) >= 0);
     assert(offset % 32 == 0);
 
@@ -150,19 +166,22 @@ static void r300_emit_tx_setup(struct r300_context *r300,
                      (R300_TX_CLAMP_TO_EDGE  << R300_TX_WRAP_T_SHIFT) |
                      (R300_TX_CLAMP_TO_EDGE  << R300_TX_WRAP_R_SHIFT) |
                      R300_TX_MIN_FILTER_MIP_NONE |
-                     R300_TX_MIN_FILTER_LINEAR |
-                     R300_TX_MAG_FILTER_LINEAR |
+                     R300_TX_MIN_FILTER_NEAREST |
+                     R300_TX_MAG_FILTER_NEAREST |
                      (0 << 28));
     OUT_BATCH_REGVAL(R300_TX_FILTER1_0, 0);
     OUT_BATCH_REGVAL(R300_TX_SIZE_0,
-                     ((width-1) << R300_TX_WIDTHMASK_SHIFT) |
-                     ((height-1) << R300_TX_HEIGHTMASK_SHIFT) |
+                     (((width  - 1) & 0x7ff) << R300_TX_WIDTHMASK_SHIFT) |
+                     (((height - 1) & 0x7ff) << R300_TX_HEIGHTMASK_SHIFT) |
                      (0 << R300_TX_DEPTHMASK_SHIFT) |
                      (0 << R300_TX_MAX_MIP_LEVEL_SHIFT) |
                      R300_TX_SIZE_TXPITCH_EN);
 
     OUT_BATCH_REGVAL(R300_TX_FORMAT_0, r300TranslateTexFormat(mesa_format));
-    OUT_BATCH_REGVAL(R300_TX_FORMAT2_0, pitch - 1);
+    OUT_BATCH_REGVAL(R300_TX_FORMAT2_0,
+                     (pitch - 1) |
+                     (is_r500 && width  > 2048 ? R500_TXWIDTH_BIT11  : 0) |
+                     (is_r500 && height > 2048 ? R500_TXHEIGHT_BIT11 : 0));
     OUT_BATCH_REGSEQ(R300_TX_OFFSET_0, 1);
     OUT_BATCH_RELOC(0, bo, offset, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
 
@@ -181,8 +200,6 @@ static uint32_t mesa_format_to_us_format(gl_format mesa_format)
 {
     switch(mesa_format)
     {
-        case MESA_FORMAT_S8_Z24:
-        case MESA_FORMAT_X8_Z24:
         case MESA_FORMAT_RGBA8888: // x
             return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, B, G, R, 0);
         case MESA_FORMAT_RGB565: // x
@@ -216,7 +233,8 @@ static uint32_t mesa_format_to_us_format(gl_format mesa_format)
             return EASY_US_FORMAT(R500_OUT_FMT_C4_16, R, G, B, A, 0xf);
 
         default:
-            assert(!"Invalid format for US output\n");
+            fprintf(stderr, "Unsupported format %s for US output\n", _mesa_get_format_name(mesa_format));
+            assert(0);
             return 0;
     }
 }
@@ -341,8 +359,14 @@ static void emit_pvs_setup(struct r300_context *r300,
 
 static void emit_vap_setup(struct r300_context *r300)
 {
+    int tex_offset;
     BATCH_LOCALS(&r300->radeon);
 
+    if (r300->options.hw_tcl_enabled)
+       tex_offset = 1;
+    else
+       tex_offset = 6;
+
     BEGIN_BATCH(12);
     OUT_BATCH_REGSEQ(R300_SE_VTE_CNTL, 2);
     OUT_BATCH(R300_VTX_XY_FMT | R300_VTX_Z_FMT);
@@ -351,7 +375,7 @@ static void emit_vap_setup(struct r300_context *r300)
     OUT_BATCH_REGVAL(R300_VAP_PSC_SGN_NORM_CNTL, 0xaaaaaaaa);
     OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_0,
                      ((R300_DATA_TYPE_FLOAT_2 | (0 << R300_DST_VEC_LOC_SHIFT)) << 0) |
-                     (((1 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_2 | R300_LAST_VEC) << 16));
+                     (((tex_offset << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_2 | R300_LAST_VEC) << 16));
     OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_EXT_0,
                     ((((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
                        (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
@@ -374,15 +398,16 @@ static GLboolean validate_buffers(struct r300_context *r300,
                                   struct radeon_bo *dst_bo)
 {
     int ret;
-    radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
-                                      src_bo, RADEON_GEM_DOMAIN_VRAM, 0);
 
-    radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
-                                      dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
+    radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs);
+
+    ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs,
+                                        src_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
+    if (ret)
+        return GL_FALSE;
 
     ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs,
-                                        first_elem(&r300->radeon.dma.reserved)->bo,
-                                        RADEON_GEM_DOMAIN_GTT, 0);
+                                        dst_bo, 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT);
     if (ret)
         return GL_FALSE;
 
@@ -404,9 +429,8 @@ static void calc_tex_coords(float img_width, float img_height,
     buf[3] = buf[2] + reg_height / img_height;
     if (flip_y)
     {
-        float tmp = buf[2];
-        buf[2] = 1.0 - buf[3];
-        buf[3] = 1.0 - tmp;
+        buf[2] = 1.0 - buf[2];
+        buf[3] = 1.0 - buf[3];
     }
 }
 
@@ -425,13 +449,13 @@ static void emit_draw_packet(struct r300_context *r300,
                     flip_y, texcoords);
 
     float verts[] = { dst_x_offset, dst_y_offset,
-                      texcoords[0], texcoords[3],
-                      dst_x_offset, dst_y_offset + reg_height,
                       texcoords[0], texcoords[2],
+                      dst_x_offset, dst_y_offset + reg_height,
+                      texcoords[0], texcoords[3],
                       dst_x_offset + reg_width, dst_y_offset + reg_height,
-                      texcoords[1], texcoords[2],
+                      texcoords[1], texcoords[3],
                       dst_x_offset + reg_width, dst_y_offset,
-                      texcoords[1], texcoords[3] };
+                      texcoords[1], texcoords[2] };
 
     BATCH_LOCALS(&r300->radeon);
 
@@ -447,7 +471,7 @@ static void other_stuff(struct r300_context *r300)
 {
     BATCH_LOCALS(&r300->radeon);
 
-    BEGIN_BATCH(15);
+    BEGIN_BATCH(13);
     OUT_BATCH_REGVAL(R300_GA_POLY_MODE,
                      R300_GA_POLY_MODE_FRONT_PTYPE_TRI | R300_GA_POLY_MODE_BACK_PTYPE_TRI);
     OUT_BATCH_REGVAL(R300_SU_CULL_MODE, R300_FRONT_FACE_CCW);
@@ -456,9 +480,13 @@ static void other_stuff(struct r300_context *r300)
     OUT_BATCH_REGSEQ(R300_RB3D_CBLEND, 2);
     OUT_BATCH(0x0);
     OUT_BATCH(0x0);
-    OUT_BATCH_REGVAL(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
     OUT_BATCH_REGVAL(R300_ZB_CNTL, 0);
     END_BATCH();
+    if (r300->options.hw_tcl_enabled) {
+        BEGIN_BATCH(2);
+        OUT_BATCH_REGVAL(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
+        END_BATCH();
+    }
 }
 
 static void emit_cb_setup(struct r300_context *r300,
@@ -496,6 +524,27 @@ static void emit_cb_setup(struct r300_context *r300,
     END_BATCH();
 }
 
+unsigned r300_check_blit(gl_format dst_format)
+{
+    switch (dst_format) {
+        case MESA_FORMAT_RGB565:
+        case MESA_FORMAT_ARGB1555:
+        case MESA_FORMAT_RGBA8888:
+        case MESA_FORMAT_RGBA8888_REV:
+        case MESA_FORMAT_ARGB8888:
+        case MESA_FORMAT_ARGB8888_REV:
+        case MESA_FORMAT_XRGB8888:
+            break;
+        default:
+            return 0;
+    }
+
+    if (_mesa_get_format_bits(dst_format, GL_DEPTH_BITS) > 0)
+        return 0;
+
+    return 1;
+}
+
 /**
  * Copy a region of [@a width x @a height] pixels from source buffer
  * to destination buffer.
@@ -520,27 +569,36 @@ static void emit_cb_setup(struct r300_context *r300,
  * @param[in] height region height
  * @param[in] flip_y set if y coords of the source image need to be flipped
  */
-GLboolean r300_blit(struct r300_context *r300,
-                    struct radeon_bo *src_bo,
-                    intptr_t src_offset,
-                    gl_format src_mesaformat,
-                    unsigned src_pitch,
-                    unsigned src_width,
-                    unsigned src_height,
-                    unsigned src_x_offset,
-                    unsigned src_y_offset,
-                    struct radeon_bo *dst_bo,
-                    intptr_t dst_offset,
-                    gl_format dst_mesaformat,
-                    unsigned dst_pitch,
-                    unsigned dst_width,
-                    unsigned dst_height,
-                    unsigned dst_x_offset,
-                    unsigned dst_y_offset,
-                    unsigned reg_width,
-                    unsigned reg_height,
-                    unsigned flip_y)
+unsigned r300_blit(struct gl_context *ctx,
+                   struct radeon_bo *src_bo,
+                   intptr_t src_offset,
+                   gl_format src_mesaformat,
+                   unsigned src_pitch,
+                   unsigned src_width,
+                   unsigned src_height,
+                   unsigned src_x_offset,
+                   unsigned src_y_offset,
+                   struct radeon_bo *dst_bo,
+                   intptr_t dst_offset,
+                   gl_format dst_mesaformat,
+                   unsigned dst_pitch,
+                   unsigned dst_width,
+                   unsigned dst_height,
+                   unsigned dst_x_offset,
+                   unsigned dst_y_offset,
+                   unsigned reg_width,
+                   unsigned reg_height,
+                   unsigned flip_y)
 {
+    r300ContextPtr r300 = R300_CONTEXT(ctx);
+
+    if (!r300_check_blit(dst_mesaformat))
+        return 0;
+
+    /* Make sure that colorbuffer has even width - hw limitation */
+    if (dst_pitch % 2 > 0)
+        ++dst_pitch;
+
     /* Need to clamp the region size to make sure
      * we don't read outside of the source buffer
      * or write outside of the destination buffer.
@@ -555,6 +613,10 @@ GLboolean r300_blit(struct r300_context *r300,
         reg_height = dst_height - dst_y_offset;
 
     if (src_bo == dst_bo) {
+        return 0;
+    }
+
+    if (src_offset % 32 || dst_offset % 32) {
         return GL_FALSE;
     }
 
@@ -562,7 +624,7 @@ GLboolean r300_blit(struct r300_context *r300,
         fprintf(stderr, "src: size [%d x %d], pitch %d, "
                 "offset [%d x %d], format %s, bo %p\n",
                 src_width, src_height, src_pitch,
-                src_offset, src_y_offset,
+                src_x_offset, src_y_offset,
                 _mesa_get_format_name(src_mesaformat),
                 src_bo);
         fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n",
@@ -571,8 +633,11 @@ GLboolean r300_blit(struct r300_context *r300,
         fprintf(stderr, "region: %d x %d\n", reg_width, reg_height);
     }
 
+    /* Flush is needed to make sure that source buffer has correct data */
+    radeonFlush(r300->radeon.glCtx);
+
     if (!validate_buffers(r300, src_bo, dst_bo))
-        return GL_FALSE;
+        return 0;
 
     rcommonEnsureCmdBufSpace(&r300->radeon, 200, __FUNCTION__);
 
@@ -588,7 +653,9 @@ GLboolean r300_blit(struct r300_context *r300,
         r300_emit_rs_setup(r300);
     }
 
-    emit_pvs_setup(r300, r300->blit.vp_code.body.d, 2);
+    if (r300->options.hw_tcl_enabled)
+       emit_pvs_setup(r300, r300->blit.vp_code.body.d, 2);
+
     emit_vap_setup(r300);
 
     emit_cb_setup(r300, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height);
@@ -603,5 +670,5 @@ GLboolean r300_blit(struct r300_context *r300,
 
     radeonFlush(r300->radeon.glCtx);
 
-    return GL_TRUE;
-}
\ No newline at end of file
+    return 1;
+}