From b9607ac0dade0b45fe3ea74b88c828835a4cbb46 Mon Sep 17 00:00:00 2001 From: Benjamin Segovia Date: Wed, 28 Mar 2012 19:18:05 +0000 Subject: [PATCH] Started to implement the clean interface to support both HW and simulator --- src/CMakeLists.txt | 2 + src/cl_alloc.c | 11 ++++ src/cl_alloc.h | 3 ++ src/cl_buffer.c | 31 +++++++++++ src/cl_buffer.h | 69 ++++++++++++++++++++++++ src/cl_command_queue_gen7.c | 5 -- src/intel/intel_gpgpu.c | 73 ++----------------------- src/sim/sim_buffer.c | 126 ++++++++++++++++++++++++++++++++++++++++++++ src/sim/sim_buffer.h | 27 ++++++++++ 9 files changed, 273 insertions(+), 74 deletions(-) create mode 100644 src/cl_buffer.c create mode 100644 src/cl_buffer.h create mode 100644 src/sim/sim_buffer.c create mode 100644 src/sim/sim_buffer.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c1c40ef..efa31eb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,6 +18,8 @@ SET(OPENCL_SRC cl_context.c cl_command_queue.c cl_command_queue_gen7.c + cl_buffer.c + sim/sim_buffer.c intel/intel_gpgpu.c intel/intel_batchbuffer.c intel/intel_driver.c diff --git a/src/cl_alloc.c b/src/cl_alloc.c index 5967a26..4c99c49 100644 --- a/src/cl_alloc.c +++ b/src/cl_alloc.c @@ -22,6 +22,7 @@ #include #include +#include static volatile int32_t cl_alloc_n = 0; @@ -36,6 +37,16 @@ cl_malloc(size_t sz) } LOCAL void* +cl_aligned_malloc(size_t sz, size_t align) +{ + void * p = NULL; + atomic_inc(&cl_alloc_n); + p = memalign(align, sz); + assert(p); + return p; +} + +LOCAL void* cl_calloc(size_t n, size_t elem_size) { void *p = NULL; diff --git a/src/cl_alloc.h b/src/cl_alloc.h index b890bb7..9b463ed 100644 --- a/src/cl_alloc.h +++ b/src/cl_alloc.h @@ -26,6 +26,9 @@ /* Return a valid pointer for the requested memory block size */ extern void *cl_malloc(size_t sz); +/* Aligned malloc */ +extern void* cl_aligned_malloc(size_t sz, size_t align); + /* malloc + memzero */ extern void *cl_calloc(size_t n, size_t elem_size); diff --git a/src/cl_buffer.c b/src/cl_buffer.c new file mode 100644 index 0000000..53ceb15 --- /dev/null +++ b/src/cl_buffer.c @@ -0,0 +1,31 @@ +/* + * Copyright © 2012 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Benjamin Segovia + */ + +#include "cl_buffer.h" +#include + +cl_buffer_alloc_cb *cl_buffer_alloc = NULL; +cl_buffer_unreference_cb *cl_buffer_unreference = NULL; +cl_buffer_map_cb *cl_buffer_map = NULL; +cl_buffer_unmap_cb *cl_buffer_unmap = NULL; +cl_buffer_pin_cb *cl_buffer_pin = NULL; +cl_buffer_unpin_cb *cl_buffer_unpin = NULL; +cl_buffer_subdata_cb *cl_buffer_subdata = NULL; +cl_buffer_emit_reloc_cb *cl_buffer_emit_reloc = NULL; + diff --git a/src/cl_buffer.h b/src/cl_buffer.h new file mode 100644 index 0000000..391a2c7 --- /dev/null +++ b/src/cl_buffer.h @@ -0,0 +1,69 @@ +/* + * Copyright © 2012 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Benjamin Segovia + */ + +#ifndef __CL_BUFFER_H__ +#define __CL_BUFFER_H__ + +#include + +/* Hide behind some call backs the buffer allocation / deallocation ... This + * will allow us to make the use of a software performance simulator easier and + * to minimize the code specific for the HW and for the simulator + */ + +/* Encapsulates command buffer / data buffer / kernels */ +typedef struct cl_buffer cl_buffer; + +/* Encapsulates buffer manager */ +typedef struct cl_buffer_mgr cl_buffer_mgr; + +/* Allocate a buffer */ +typedef cl_buffer* (cl_buffer_alloc_cb)(cl_buffer_mgr*, const char*, unsigned long, unsigned long); +extern cl_buffer_alloc_cb *cl_buffer_alloc; + +/* Unref a buffer and destroy it if no more ref */ +typedef void (cl_buffer_unreference_cb)(cl_buffer*); +extern cl_buffer_unreference_cb *cl_buffer_unreference; + +/* Map a buffer */ +typedef void* (cl_buffer_map_cb)(cl_buffer*); +extern cl_buffer_map_cb *cl_buffer_map; + +/* Unmap a buffer */ +typedef void* (cl_buffer_unmap_cb)(cl_buffer*); +extern cl_buffer_unmap_cb *cl_buffer_unmap; + +/* Pin a buffer */ +typedef int (cl_buffer_pin_cb)(cl_buffer*); +extern cl_buffer_pin_cb *cl_buffer_pin; + +/* Unpin a buffer */ +typedef int (cl_buffer_unpin_cb)(cl_buffer*); +extern cl_buffer_unpin_cb *cl_buffer_unpin; + +/* Fill data in the buffer */ +typedef int (cl_buffer_subdata_cb)(cl_buffer*, unsigned long, unsigned long, const void*); +extern cl_buffer_subdata_cb *cl_buffer_subdata; + +/* Emit relocation */ +typedef int (cl_buffer_emit_reloc_cb) (cl_buffer *, uint32_t, cl_buffer*, uint32_t, uint32_t, uint32_t); +extern cl_buffer_emit_reloc_cb *cl_buffer_emit_reloc; + +#endif /* __CL_BUFFER_H__ */ + diff --git a/src/cl_command_queue_gen7.c b/src/cl_command_queue_gen7.c index 3245bac..ecf27dd 100644 --- a/src/cl_command_queue_gen7.c +++ b/src/cl_command_queue_gen7.c @@ -25,13 +25,8 @@ #include "cl_mem.h" #include "cl_utils.h" #include "cl_alloc.h" - -#ifdef _PLASMA -#include "plasma/plasma_export.h" -#else #include "intel_bufmgr.h" #include "intel/intel_gpgpu.h" -#endif #include #include diff --git a/src/intel/intel_gpgpu.c b/src/intel/intel_gpgpu.c index f52cbf7..7f01f61 100644 --- a/src/intel/intel_gpgpu.c +++ b/src/intel/intel_gpgpu.c @@ -157,7 +157,7 @@ gpgpu_set_base_address(intel_gpgpu_t *state) OUT_BATCH(state->batch, 0 | BASE_ADDRESS_MODIFY); OUT_BATCH(state->batch, 0 | BASE_ADDRESS_MODIFY); OUT_BATCH(state->batch, 0 | BASE_ADDRESS_MODIFY); -#endif +#endif /* USE_FULSIM */ ADVANCE_BATCH(state->batch); } @@ -477,21 +477,6 @@ gpgpu_state_init(intel_gpgpu_t *state, } static void -gpgpu_set_buf_reloc_gen6(intel_gpgpu_t *state, int32_t index, dri_bo* obj_bo) -{ - surface_heap_t *heap = state->surface_heap_b.bo->virtual; - heap->binding_table[index] = offsetof(surface_heap_t, surface) + - index * sizeof(gen6_surface_state_t); - dri_bo_emit_reloc(state->surface_heap_b.bo, - I915_GEM_DOMAIN_RENDER, - I915_GEM_DOMAIN_RENDER, - 0, - heap->binding_table[index] + - offsetof(gen6_surface_state_t, ss1), - obj_bo); -} - -static void gpgpu_set_buf_reloc_gen7(intel_gpgpu_t *state, int32_t index, dri_bo* obj_bo) { surface_heap_t *heap = state->surface_heap_b.bo->virtual; @@ -507,28 +492,6 @@ gpgpu_set_buf_reloc_gen7(intel_gpgpu_t *state, int32_t index, dri_bo* obj_bo) } static void -gpgpu_bind_buf_gen6(intel_gpgpu_t *state, - int32_t index, - dri_bo* obj_bo, - uint32_t size, - uint32_t cchint) -{ - surface_heap_t *heap = state->surface_heap_b.bo->virtual; - gen6_surface_state_t *ss = (gen6_surface_state_t *) heap->surface[index]; - const uint32_t size_ss = ((size+0xf) >> 4) - 1; /* ceil(size/16) - 1 */ - memset(ss, 0, sizeof(*ss)); - ss->ss0.surface_type = I965_SURFACE_BUFFER; - ss->ss0.surface_format = I965_SURFACEFORMAT_R32G32B32A32_FLOAT; - ss->ss1.base_addr = obj_bo->offset; - ss->ss2.width = size_ss & 0x7f; /* bits 6:0 of size_ss */ - ss->ss2.height = (size_ss >> 7) & 0x1fff; /* bits 19:7 of size_ss */ - ss->ss3.depth = size_ss >> 20; /* bits 26:20 of size_ss */ - ss->ss3.pitch = 0xf; /* sizeof(RGBA32) - 1 */; - ss->ss5.cache_control = cchint; - gpgpu_set_buf_reloc_gen6(state, index, obj_bo); -} - -static void gpgpu_bind_buf_gen7(intel_gpgpu_t *state, int32_t index, dri_bo* obj_bo, @@ -550,28 +513,6 @@ gpgpu_bind_buf_gen7(intel_gpgpu_t *state, } static void -gpgpu_bind_image2D_gen6(intel_gpgpu_t *state, - int32_t index, - dri_bo* obj_bo, - uint32_t format, - int32_t w, - int32_t h, - int32_t pitch) -{ - surface_heap_t *heap = state->surface_heap_b.bo->virtual; - gen6_surface_state_t *ss = (gen6_surface_state_t *) heap->surface[index]; - memset(ss, 0, sizeof(*ss)); - ss->ss0.surface_type = I965_SURFACE_2D; - ss->ss0.surface_format = format; - ss->ss1.base_addr = obj_bo->offset; - ss->ss2.width = w - 1; - ss->ss2.height = h - 1; - ss->ss3.pitch = pitch - 1; - ss->ss5.cache_control = cc_llc_l3; - gpgpu_set_buf_reloc_gen6(state, index, obj_bo); -} - -static void gpgpu_bind_image2D_gen7(intel_gpgpu_t *state, int32_t index, dri_bo* obj_bo, @@ -608,11 +549,9 @@ gpgpu_bind_buf(intel_gpgpu_t *state, uint32_t cchint) { uint32_t size = obj_bo->size; - + assert(index < MAX_SURFACES); - if(state->drv->gen_ver == 6) - gpgpu_bind_buf_gen6(state, index, obj_bo, size, cchint); - else if (state->drv->gen_ver == 7 || state->drv->gen_ver == 75) + if (state->drv->gen_ver == 7 || state->drv->gen_ver == 75) gpgpu_bind_buf_gen7(state, index, obj_bo, size, cchint); else NOT_IMPLEMENTED; @@ -629,11 +568,7 @@ gpgpu_bind_image2D(intel_gpgpu_t *state, gpgpu_tiling_t tiling) { assert(index < MAX_SURFACES); - if(state->drv->gen_ver == 6) { - // We do not tile with SNB - FATAL_IF (tiling != GPGPU_NO_TILE, "No tiling is implemented on SNB"); - gpgpu_bind_image2D_gen6(state, index, obj_bo, format, w, h, pitch); - } else if (state->drv->gen_ver == 7 || state->drv->gen_ver == 75) + if (state->drv->gen_ver == 7 || state->drv->gen_ver == 75) gpgpu_bind_image2D_gen7(state, index, obj_bo, format, w, h, pitch, tiling); else NOT_IMPLEMENTED; diff --git a/src/sim/sim_buffer.c b/src/sim/sim_buffer.c new file mode 100644 index 0000000..820c770 --- /dev/null +++ b/src/sim/sim_buffer.c @@ -0,0 +1,126 @@ +/* + * Copyright © 2012 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Benjamin Segovia + */ + +#include "cl_utils.h" +#include "cl_alloc.h" +#include "sim/sim_buffer.h" +#include "CL/cl.h" +#include +#include +#include + +#include "cl_buffer.h" + +/* Just to count allocations */ +typedef struct sim_bufmgr { volatile int buf_n; } sim_bufmgr_t; + +/* Just a named buffer to mirror real drm functions */ +typedef struct sim_buffer { + void *data; /* data in the buffer */ + size_t sz; /* size allocated */ + volatile int ref_n; /* number of references */ + char *name; /* name of the buffer */ + sim_bufmgr_t *bufmgr; /* owns the buffer */ +} sim_buffer_t; + +static void +sim_buffer_delete(sim_buffer_t *buf) +{ + if (buf == NULL) return; + cl_free(buf->data); + cl_free(buf->name); +} + +static sim_buffer_t* +sim_buffer_alloc(sim_bufmgr_t *bufmgr, const char *name, unsigned long sz, unsigned long align) +{ + sim_buffer_t *buf = NULL; + assert(bufmgr); + TRY_ALLOC_NO_ERR(buf, cl_calloc(1, sizeof(sim_buffer_t))); + if (sz) buf->data = cl_aligned_malloc(sz, align); + if (name) { + const size_t len = strlen(name); + TRY_ALLOC_NO_ERR(buf->name, cl_malloc(len+1)); + memcpy(buf->name, name, len); + buf->name[len] = 0; + } + buf->ref_n = 1; + buf->bufmgr = bufmgr; + atomic_inc(&buf->bufmgr->buf_n); + +exit: + return buf; +error: + sim_buffer_delete(buf); + buf = NULL; + goto exit; +} + +static void +sim_buffer_unreference(sim_buffer_t *buf) +{ + if (UNLIKELY(buf == NULL)) return; + if (atomic_dec(&buf->ref_n) > 1) return; + atomic_dec(&buf->bufmgr->buf_n); + sim_buffer_delete(buf); +} + +static void* +sim_buffer_map(sim_buffer_t *buf) +{ + assert(buf); + return buf->data; +} + +static int +sim_buffer_subdata(sim_buffer_t *buf, unsigned long offset, unsigned long size, const void *data) +{ + if (data == NULL) return 0; + if (buf == NULL) return 0; + memcpy((char*) buf->data + offset, data, size); + return 0; +} + +static int +sim_buffer_emit_reloc(sim_buffer_t *buf, + uint32_t offset, + sim_buffer_t *target_buf, + uint32_t target_offset, + uint32_t read_domains, + uint32_t write_domain) +{ + return 1; +} +static int sim_buffer_unmap(sim_buffer_t *buf) {return 0;} +static int sim_buffer_pin(sim_buffer_t *buf) {return 0;} +static int sim_buffer_unpin(sim_buffer_t *buf) {return 0;} + +LOCAL void +sim_setup_callbacks(void) +{ + cl_buffer_alloc = (cl_buffer_alloc_cb *) sim_buffer_alloc; + cl_buffer_unreference = (cl_buffer_unreference_cb *) sim_buffer_unreference; + cl_buffer_map = (cl_buffer_map_cb *) sim_buffer_map; + cl_buffer_unmap = (cl_buffer_unmap_cb *) sim_buffer_unmap; + cl_buffer_pin = (cl_buffer_pin_cb *) sim_buffer_pin; + cl_buffer_unpin = (cl_buffer_unpin_cb *) sim_buffer_unpin; + cl_buffer_subdata = (cl_buffer_subdata_cb *) sim_buffer_subdata; + cl_buffer_emit_reloc = (cl_buffer_emit_reloc_cb *) sim_buffer_emit_reloc; +} + diff --git a/src/sim/sim_buffer.h b/src/sim/sim_buffer.h new file mode 100644 index 0000000..230d89c --- /dev/null +++ b/src/sim/sim_buffer.h @@ -0,0 +1,27 @@ +/* + * Copyright © 2012 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Benjamin Segovia + */ + +#ifndef __SIM_BUFFER_H__ +#define __SIM_BUFFER_H__ + +/* Setup the call backs when using the simulator */ +extern void sim_setup_callbacks(void); + +#endif /* __SIM_BUFFER_H__ */ + -- 2.7.4