program build should failed if there is created kernel attached to program piglit error: "Trigger CL_INVALID_OPERATION if there are kernel objects attached to program" --- src/gallium/state_trackers/clover/api/kernel.cpp | 10 ++++++++-- src/gallium/state_trackers/clover/core/kernel.cpp | 1 + src/gallium/state_trackers/clover/core/program.cpp | 14 ++++++++++++++ src/gallium/state_trackers/clover/core/program.hpp | 4 ++++ 4 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp index 05cc392..69f7d6c 100644 --- a/src/gallium/state_trackers/clover/api/kernel.cpp +++ b/src/gallium/state_trackers/clover/api/kernel.cpp @@ -76,7 +76,10 @@ clCreateKernelsInProgram(cl_program d_prog, cl_uint count, CLOVER_API cl_int clRetainKernel(cl_kernel d_kern) try { - obj(d_kern).retain(); + auto &kern = obj(d_kern); + kern.retain(); + program &prog = kern.program; + prog.ref_kernel(kern.name()); return CL_SUCCESS; } catch (error &e) { @@ -85,7 +88,10 @@ clRetainKernel(cl_kernel d_kern) try { CLOVER_API cl_int clReleaseKernel(cl_kernel d_kern) try { - if (obj(d_kern).release()) + auto &kern = obj(d_kern); + program &prog = kern.program; + prog.unref_kernel(kern.name()); + if (kern.release()) delete pobj(d_kern); return CL_SUCCESS; diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp index 5e5fe51..c670253 100644 --- a/src/gallium/state_trackers/clover/core/kernel.cpp +++ b/src/gallium/state_trackers/clover/core/kernel.cpp @@ -51,6 +51,7 @@ kernel::kernel(clover::program &prog, const std::string &name, else throw error(CL_INVALID_KERNEL_DEFINITION); } + prog.ref_kernel(name); } template<typename V> diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp index e09c3aa..dbfa284 100644 --- a/src/gallium/state_trackers/clover/core/program.cpp +++ b/src/gallium/state_trackers/clover/core/program.cpp @@ -42,6 +42,9 @@ program::program(clover::context &ctx, void program::build(const ref_vector<device> &devs, const char *opts) { + if (_cl_kernel_ref_count.size()) + throw error(CL_INVALID_OPERATION); + if (has_source) { _devices = devs; @@ -110,3 +113,14 @@ program::symbols() const { return _binaries.begin()->second.syms; } + +void program::ref_kernel(const std::string &name) { + ++_cl_kernel_ref_count[name]; +} + +void program::unref_kernel(const std::string &name) { + auto it = _cl_kernel_ref_count.find(name); + if (it != _cl_kernel_ref_count.end()) + if (--(it->second) == 0) + _cl_kernel_ref_count.erase(it); +} diff --git a/src/gallium/state_trackers/clover/core/program.hpp b/src/gallium/state_trackers/clover/core/program.hpp index 1081454..f9c91ed 100644 --- a/src/gallium/state_trackers/clover/core/program.hpp +++ b/src/gallium/state_trackers/clover/core/program.hpp @@ -60,6 +60,9 @@ namespace clover { const compat::vector<module::symbol> &symbols() const; + void ref_kernel(const std::string &name); + void unref_kernel(const std::string &name); + const intrusive_ref<clover::context> context; private: @@ -67,6 +70,7 @@ namespace clover { std::map<const device *, module> _binaries; std::map<const device *, std::string> _logs; std::map<const device *, std::string> _opts; + std::map<std::string, size_t> _cl_kernel_ref_count; std::string _source; }; } -- 2.0.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev