Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**************************************************************************                                                                                  
  2.  *                                                                                                                                                          
  3.  * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.                                                                                                
  4.  * All Rights Reserved.                                                                                                                                      
  5.  *                                                                                                                                                          
  6.  * Permission is hereby granted, free of charge, to any person obtaining a                                                                                  
  7.  * copy of this software and associated documentation files (the                                                                                            
  8.  * "Software"), to deal in the Software without restriction, including                                                                                      
  9.  * without limitation the rights to use, copy, modify, merge, publish,                                                                                      
  10.  * distribute, sub license, and/or sell copies of the Software, and to                                                                                      
  11.  * permit persons to whom the Software is furnished to do so, subject to                                                                                    
  12.  * the following conditions:                                                                                                                                
  13.  *                                                                                                                                                          
  14.  * The above copyright notice and this permission notice (including the                                                                                      
  15.  * next paragraph) shall be included in all copies or substantial portions                                                                                  
  16.  * of the Software.                                                                                                                                          
  17.  *                                                                                                                                                          
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS                                                                                  
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                                                                                                
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.                                                                                  
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR                                                                                    
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,                                                                                  
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE                                                                                        
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                                                                                    
  25.  *                                                                                                                                                          
  26.  **************************************************************************/      
  27.  
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <assert.h>
  31.  
  32. #include "intel_batchbuffer.h"
  33.  
  34. #define MAX_BATCH_SIZE          0x400000
  35.  
  36. static void
  37. intel_batchbuffer_reset(struct intel_batchbuffer *batch, int buffer_size)
  38. {
  39.     struct intel_driver_data *intel = batch->intel;
  40.     int batch_size = buffer_size;
  41.    
  42.     printf("%s\n", __FUNCTION__);
  43.  
  44.     assert(batch->flag == I915_EXEC_RENDER ||
  45.            batch->flag == I915_EXEC_BLT ||
  46.            batch->flag == I915_EXEC_BSD ||
  47.            batch->flag == I915_EXEC_VEBOX);
  48.  
  49.     dri_bo_unreference(batch->buffer);
  50.     batch->buffer = dri_bo_alloc(intel->bufmgr,
  51.                                  "batch buffer",
  52.                                  batch_size,
  53.                                  0x1000);
  54.     assert(batch->buffer);
  55.     dri_bo_map(batch->buffer, 1);
  56.     assert(batch->buffer->virtual);
  57.     batch->map = batch->buffer->virtual;
  58.     batch->size = batch_size;
  59.     batch->ptr = batch->map;
  60.     batch->atomic = 0;
  61. }
  62.  
  63. static unsigned int
  64. intel_batchbuffer_space(struct intel_batchbuffer *batch)
  65. {
  66.     return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
  67. }
  68.  
  69.  
  70. struct intel_batchbuffer *
  71. intel_batchbuffer_new(struct intel_driver_data *intel, int flag, int buffer_size)
  72. {
  73.     struct intel_batchbuffer *batch = calloc(1, sizeof(*batch));
  74.     assert(flag == I915_EXEC_RENDER ||
  75.            flag == I915_EXEC_BSD ||
  76.            flag == I915_EXEC_BLT ||
  77.            flag == I915_EXEC_VEBOX);
  78.  
  79.     printf("%s\n", __FUNCTION__);
  80.    
  81.    if (!buffer_size || buffer_size < BATCH_SIZE) {
  82.         buffer_size = BATCH_SIZE;
  83.    }
  84.  
  85.    /* the buffer size can't exceed 4M */
  86.    if (buffer_size > MAX_BATCH_SIZE) {
  87.         buffer_size = MAX_BATCH_SIZE;
  88.    }
  89.  
  90.     batch->intel = intel;
  91.     batch->flag = flag;
  92.     batch->run = drm_intel_bo_mrb_exec;
  93.     intel_batchbuffer_reset(batch, buffer_size);
  94.  
  95.     return batch;
  96. }
  97.  
  98. void intel_batchbuffer_free(struct intel_batchbuffer *batch)
  99. {
  100.     if (batch->map) {
  101.         dri_bo_unmap(batch->buffer);
  102.         batch->map = NULL;
  103.     }
  104.  
  105.     dri_bo_unreference(batch->buffer);
  106.     free(batch);
  107. }
  108.  
  109. void
  110. intel_batchbuffer_flush(struct intel_batchbuffer *batch)
  111. {
  112.     unsigned int used = batch->ptr - batch->map;
  113.  
  114.     if (used == 0) {
  115.         return;
  116.     }
  117.  
  118.     if ((used & 4) == 0) {
  119.         *(unsigned int*)batch->ptr = 0;
  120.         batch->ptr += 4;
  121.     }
  122.  
  123.     *(unsigned int*)batch->ptr = MI_BATCH_BUFFER_END;
  124.     batch->ptr += 4;
  125.     dri_bo_unmap(batch->buffer);
  126.     used = batch->ptr - batch->map;
  127.     batch->run(batch->buffer, used, 0, 0, 0, batch->flag);
  128.     intel_batchbuffer_reset(batch, batch->size);
  129. }
  130.  
  131. void
  132. intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, unsigned int x)
  133. {
  134.     assert(intel_batchbuffer_space(batch) >= 4);
  135.     *(unsigned int *)batch->ptr = x;
  136.     batch->ptr += 4;
  137. }
  138.  
  139. void
  140. intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, dri_bo *bo,
  141.                                 uint32_t read_domains, uint32_t write_domains,
  142.                                 uint32_t delta)
  143. {
  144.     assert(batch->ptr - batch->map < batch->size);
  145.     dri_bo_emit_reloc(batch->buffer, read_domains, write_domains,
  146.                       delta, batch->ptr - batch->map, bo);
  147.     intel_batchbuffer_emit_dword(batch, bo->offset + delta);
  148. }
  149.  
  150. void
  151. intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
  152.                                    unsigned int size)
  153. {
  154.     assert(size < batch->size - 8);
  155.  
  156.     if (intel_batchbuffer_space(batch) < size) {
  157.         intel_batchbuffer_flush(batch);
  158.     }
  159. }
  160.  
  161. void
  162. intel_batchbuffer_data(struct intel_batchbuffer *batch,
  163.                           void *data,
  164.                           unsigned int size)
  165. {
  166.     assert((size & 3) == 0);
  167.     intel_batchbuffer_require_space(batch, size);
  168.  
  169.     assert(batch->ptr);
  170.     memcpy(batch->ptr, data, size);
  171.     batch->ptr += size;
  172. }
  173.  
  174. void
  175. intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch)
  176. {
  177.     struct intel_driver_data *intel = batch->intel;
  178.  
  179.     if (IS_GEN6(intel->device_id) ||
  180.         IS_GEN7(intel->device_id)) {
  181.         if (batch->flag == I915_EXEC_RENDER) {
  182.             BEGIN_BATCH(batch, 4);
  183.             OUT_BATCH(batch, CMD_PIPE_CONTROL | 0x2);
  184.  
  185.             if (IS_GEN6(intel->device_id))
  186.                 OUT_BATCH(batch,
  187.                           CMD_PIPE_CONTROL_WC_FLUSH |
  188.                           CMD_PIPE_CONTROL_TC_FLUSH |
  189.                           CMD_PIPE_CONTROL_NOWRITE);
  190.             else
  191.                 OUT_BATCH(batch,
  192.                           CMD_PIPE_CONTROL_WC_FLUSH |
  193.                           CMD_PIPE_CONTROL_TC_FLUSH |
  194.                           CMD_PIPE_CONTROL_DC_FLUSH |
  195.                           CMD_PIPE_CONTROL_NOWRITE);
  196.  
  197.             OUT_BATCH(batch, 0);
  198.             OUT_BATCH(batch, 0);
  199.             ADVANCE_BATCH(batch);
  200.         } else {
  201.             if (batch->flag == I915_EXEC_BLT) {
  202.                 BEGIN_BLT_BATCH(batch, 4);
  203.                 OUT_BLT_BATCH(batch, MI_FLUSH_DW);
  204.                 OUT_BLT_BATCH(batch, 0);
  205.                 OUT_BLT_BATCH(batch, 0);
  206.                 OUT_BLT_BATCH(batch, 0);
  207.                 ADVANCE_BLT_BATCH(batch);
  208.             }else if (batch->flag == I915_EXEC_VEBOX) {
  209.                 BEGIN_VEB_BATCH(batch, 4);
  210.                 OUT_VEB_BATCH(batch, MI_FLUSH_DW);
  211.                 OUT_VEB_BATCH(batch, 0);
  212.                 OUT_VEB_BATCH(batch, 0);
  213.                 OUT_VEB_BATCH(batch, 0);
  214.                 ADVANCE_VEB_BATCH(batch);
  215.             } else {
  216.                 assert(batch->flag == I915_EXEC_BSD);
  217.                 BEGIN_BCS_BATCH(batch, 4);
  218.                 OUT_BCS_BATCH(batch, MI_FLUSH_DW | MI_FLUSH_DW_VIDEO_PIPELINE_CACHE_INVALIDATE);
  219.                 OUT_BCS_BATCH(batch, 0);
  220.                 OUT_BCS_BATCH(batch, 0);
  221.                 OUT_BCS_BATCH(batch, 0);
  222.                 ADVANCE_BCS_BATCH(batch);
  223.             }
  224.         }
  225.     } else {
  226.         if (batch->flag == I915_EXEC_RENDER) {
  227.             BEGIN_BATCH(batch, 1);
  228.             OUT_BATCH(batch, MI_FLUSH | MI_FLUSH_STATE_INSTRUCTION_CACHE_INVALIDATE);
  229.             ADVANCE_BATCH(batch);              
  230.          } else {
  231.             assert(batch->flag == I915_EXEC_BSD);
  232.             BEGIN_BCS_BATCH(batch, 1);
  233.             OUT_BCS_BATCH(batch, MI_FLUSH | MI_FLUSH_STATE_INSTRUCTION_CACHE_INVALIDATE);
  234.             ADVANCE_BCS_BATCH(batch);
  235.         }
  236.     }
  237. }
  238.  
  239. void
  240. intel_batchbuffer_begin_batch(struct intel_batchbuffer *batch, int total)
  241. {
  242.     batch->emit_total = total * 4;
  243.     batch->emit_start = batch->ptr;
  244. }
  245.  
  246. void
  247. intel_batchbuffer_advance_batch(struct intel_batchbuffer *batch)
  248. {
  249.     assert(batch->emit_total == (batch->ptr - batch->emit_start));
  250. }
  251.  
  252. void
  253. intel_batchbuffer_check_batchbuffer_flag(struct intel_batchbuffer *batch, int flag)
  254. {
  255.     if (flag != I915_EXEC_RENDER &&
  256.         flag != I915_EXEC_BLT &&
  257.         flag != I915_EXEC_BSD &&
  258.         flag != I915_EXEC_VEBOX)
  259.         return;
  260.  
  261.     if (batch->flag == flag)
  262.         return;
  263.  
  264.     intel_batchbuffer_flush(batch);
  265.     batch->flag = flag;
  266. }
  267.  
  268. int
  269. intel_batchbuffer_check_free_space(struct intel_batchbuffer *batch, int size)
  270. {
  271.     return intel_batchbuffer_space(batch) >= size;
  272. }
  273.  
  274. static void
  275. intel_batchbuffer_start_atomic_helper(struct intel_batchbuffer *batch,
  276.                                       int flag,
  277.                                       unsigned int size)
  278. {
  279.     assert(!batch->atomic);
  280.     intel_batchbuffer_check_batchbuffer_flag(batch, flag);
  281.     intel_batchbuffer_require_space(batch, size);
  282.     batch->atomic = 1;
  283. }
  284.  
  285. void
  286. intel_batchbuffer_start_atomic(struct intel_batchbuffer *batch, unsigned int size)
  287. {
  288.     intel_batchbuffer_start_atomic_helper(batch, I915_EXEC_RENDER, size);
  289. }
  290.  
  291. void
  292. intel_batchbuffer_start_atomic_blt(struct intel_batchbuffer *batch, unsigned int size)
  293. {
  294.     intel_batchbuffer_start_atomic_helper(batch, I915_EXEC_BLT, size);
  295. }
  296.  
  297. void
  298. intel_batchbuffer_start_atomic_bcs(struct intel_batchbuffer *batch, unsigned int size)
  299. {
  300.     intel_batchbuffer_start_atomic_helper(batch, I915_EXEC_BSD, size);
  301. }
  302.  
  303. void
  304. intel_batchbuffer_start_atomic_veb(struct intel_batchbuffer *batch, unsigned int size)
  305. {
  306.     intel_batchbuffer_start_atomic_helper(batch, I915_EXEC_VEBOX, size);
  307. }
  308.  
  309.  
  310. void
  311. intel_batchbuffer_end_atomic(struct intel_batchbuffer *batch)
  312. {
  313.     assert(batch->atomic);
  314.     batch->atomic = 0;
  315. }
  316.  
  317. int
  318. intel_batchbuffer_used_size(struct intel_batchbuffer *batch)
  319. {
  320.     return batch->ptr - batch->map;
  321. }
  322.  
  323. void
  324. intel_batchbuffer_align(struct intel_batchbuffer *batch, unsigned int alignedment)
  325. {
  326.     int used = batch->ptr - batch->map;
  327.     int pad_size;
  328.  
  329.     assert((alignedment & 3) == 0);
  330.     pad_size = ALIGN(used, alignedment) - used;
  331.     assert((pad_size & 3) == 0);
  332.     assert(intel_batchbuffer_space(batch) >= pad_size);
  333.  
  334.     while (pad_size >= 4) {
  335.         intel_batchbuffer_emit_dword(batch, 0);
  336.         pad_size -= 4;
  337.     }
  338. }
  339.  
  340.