<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:SimSun;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:SimSun;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
{font-family:SimSun;
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.hoenzb
{mso-style-name:hoenzb;}
span.EmailStyle18
{mso-style-type:personal-reply;
font-family:"Calibri","sans-serif";
color:#1F497D;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri","sans-serif";}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="ZH-CN" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="font-size:10.5pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:10.5pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> zhigang gong [mailto:zhigang.gong@gmail.com]
<br>
<b>Sent:</b> Wednesday, August 07, 2013 1:04 PM<br>
<b>To:</b> Song, Ruiling<br>
<b>Cc:</b> beignet@lists.freedesktop.org<br>
<b>Subject:</b> Re: [Beignet] [PATCH 1/2] enable scratch memory allocation and read/write<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal"><span lang="EN-US">My suggestion here is to seprate the scratch OBlock read/write out. And submit the<o:p></o:p></span></p>
<div>
<p class="MsoNormal"><span lang="EN-US">Dword Read/Write part firstly, as OBlock read/write is not used right now, Right?<o:p></o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span lang="EN-US" style="color:#1F497D">[Ruiling] In fact, I first use OBlock Read/Write for spill implementation. As I met some failure, so, I also implement scratch HBlock. I call it HBlock as it always read
multiples of HWord. There are two modes of scratch RW, but I only enable DWORD mode. That is the HBlock in the patch. If you have concern about the oword block rw, I can remove OBlock RW logic.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span lang="EN-US" style="font-size:10.5pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal"><span lang="EN-US">On Wed, Aug 7, 2013 at 12:53 PM, zhigang gong <<a href="mailto:zhigang.gong@gmail.com" target="_blank">zhigang.gong@gmail.com</a>> wrote:<o:p></o:p></span></p>
<div>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span lang="EN-US"><o:p> </o:p></span></p>
<div>
<div>
<p class="MsoNormal"><span lang="EN-US">On Wed, Aug 7, 2013 at 10:05 AM, Ruiling Song <<a href="mailto:ruiling.song@intel.com" target="_blank">ruiling.song@intel.com</a>> wrote:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">There are two modes of scratch RW, OBlock, HBlock.<br>
HBlock was documented as scratch block write/read in HW spec.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> I guess you mean Dword Block here when you are talking about Hblock, right?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:10.5pt;font-family:"Calibri","sans-serif";color:#1F497D">[Ruiling]Yes, you are right. It is dword mode scratch rw. As it read/write multiples of hword, so, I would like to call it hword RW.
<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> The only two channel mode supported for scratch read/write are OWord or Dword.<o:p></o:p></span></p>
</div>
<div>
<div>
<div>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal"><span lang="EN-US">While the OBlock was documented as OWord block read/write.<br>
I enabled both of them, but only used HBlock RW in later spill patch.<br>
<br>
Signed-off-by: Ruiling Song <<a href="mailto:ruiling.song@intel.com" target="_blank">ruiling.song@intel.com</a>><br>
---<br>
backend/src/backend/context.cpp | 18 ++++++++<br>
backend/src/backend/context.hpp | 3 ++<br>
backend/src/backend/gen/gen_mesa_disasm.c | 43 ++++++++++++++---<br>
backend/src/backend/gen_context.cpp | 71 +++++++++++++++++++++++++++++<br>
backend/src/backend/gen_context.hpp | 6 ++-<br>
backend/src/backend/gen_defs.hpp | 25 ++++++++++<br>
backend/src/backend/gen_encoder.cpp | 67 ++++++++++++++++++++++++++-<br>
backend/src/backend/gen_encoder.hpp | 8 ++++<br>
backend/src/backend/program.cpp | 8 ++++<br>
backend/src/backend/program.h | 4 ++<br>
backend/src/backend/program.hpp | 3 ++<br>
src/cl_command_queue_gen7.c | 9 ++++<br>
src/cl_driver.h | 4 ++<br>
src/cl_driver_defs.c | 1 +<br>
src/intel/intel_gpgpu.c | 53 ++++++++++++++++-----<br>
15 files changed, 303 insertions(+), 20 deletions(-)<br>
<br>
diff --git a/backend/src/backend/context.cpp b/backend/src/backend/context.cpp<br>
index 48160de..5484869 100644<br>
--- a/backend/src/backend/context.cpp<br>
+++ b/backend/src/backend/context.cpp<br>
@@ -268,6 +268,15 @@ namespace gbe<br>
}<br>
}<br>
<br>
+ static int<br>
+ alignScratchSize(int size){<br>
+ int i = 0;<br>
+<br>
+ for(; i < size; i+=1024)<br>
+ ;<br>
+<br>
+ return i;<br>
+ }<o:p></o:p></span></p>
</blockquote>
</div>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> How about just return size * 1024 here, and it'd better to be a macro or inline function? <o:p></o:p></span></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<div>
<p class="MsoNormal"><span lang="EN-US"> ///////////////////////////////////////////////////////////////////////////<br>
// Generic Context (shared by the simulator and the HW context)<br>
///////////////////////////////////////////////////////////////////////////<br>
@@ -284,6 +293,7 @@ namespace gbe<br>
this->simdWidth = nextHighestPowerOf2(OCL_SIMD_WIDTH);<br>
else<br>
this->simdWidth = fn.getSimdWidth();<br>
+ this->scratchOffset = 0;<br>
}<br>
<br>
Context::~Context(void) {<br>
@@ -306,6 +316,8 @@ namespace gbe<br>
this->kernel = NULL;<br>
}<br>
if(this->kernel != NULL)<br>
+ this->kernel->scratchSize = alignScratchSize(this->scratchOffset);<o:p></o:p></span></p>
</div>
<p class="MsoNormal"><span lang="EN-US">+ if(this->kernel != NULL; <o:p></o:p></span></p>
</blockquote>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal"><span lang="EN-US"> this->kernel->ctx = this;<o:p></o:p></span></p>
</blockquote>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> How about just write it this way<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> if (this->kernel != NULL) {<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> this->kernel->scratchSize = alignScratchSize(this->scratchOffset);<o:p></o:p></span></p>
</div>
<div>
<div>
<div>
<p class="MsoNormal"><span lang="EN-US"> this->kernel->ctx = this;<o:p></o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal"><span lang="EN-US"> } <o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
</div>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal"><span lang="EN-US"> return this->kernel;<br>
}<br>
@@ -337,6 +349,12 @@ namespace gbe<br>
return offset + GEN_REG_SIZE;<br>
}<br>
<br>
+ uint32_t Context::allocateScratchMem(uint32_t size) {<br>
+ uint32_t offset = scratchOffset;<br>
+ scratchOffset += size;<br>
+ return offset;<br>
+ }<br>
+<br>
void Context::buildStack(void) {<br>
const auto &stackUse = dag->getUse(ir::ocl::stackptr);<br>
if (stackUse.size() == 0) // no stack is used if stackptr is unused<br>
diff --git a/backend/src/backend/context.hpp b/backend/src/backend/context.hpp<br>
index c205388..50c0e70 100644<br>
--- a/backend/src/backend/context.hpp<br>
+++ b/backend/src/backend/context.hpp<br>
@@ -91,6 +91,8 @@ namespace gbe<br>
/* allocate a new entry for a specific image's information */<br>
/*! Get (search or allocate if fail to find one) image info curbeOffset.*/<br>
uint32_t getImageInfoCurbeOffset(ir::ImageInfoKey key, size_t size);<br>
+ /*! allocate size scratch memory and return start address */<br>
+ uint32_t allocateScratchMem(uint32_t size);<br>
protected:<br>
/*! Build the instruction stream. Return false if failed */<br>
virtual bool emitCode(void) = 0;<br>
@@ -126,6 +128,7 @@ namespace gbe<br>
set<ir::LabelIndex> usedLabels; //!< Set of all used labels<br>
JIPMap JIPs; //!< Where to jump all labels/branches<br>
uint32_t simdWidth; //!< Number of lanes per HW threads<br>
+ uint32_t scratchOffset; //!< scratch slot for next scratch memory request<br>
GBE_CLASS(Context); //!< Use custom allocators<br>
};<br>
<br>
diff --git a/backend/src/backend/gen/gen_mesa_disasm.c b/backend/src/backend/gen/gen_mesa_disasm.c<br>
index ca8ca37..dd4f485 100644<br>
--- a/backend/src/backend/gen/gen_mesa_disasm.c<br>
+++ b/backend/src/backend/gen/gen_mesa_disasm.c<br>
@@ -373,6 +373,28 @@ static const char *data_port_data_cache_category[] = {<br>
"scratch",<br>
};<br>
<br>
+static const char *data_port_scratch_block_size[] = {<br>
+ "1 HWord",<br>
+ "2 HWord",<br>
+ "Reserve",<br>
+ "4 HWord",<br>
+};<o:p></o:p></span></p>
</blockquote>
<div>
<p class="MsoNormal"><span lang="EN-US"> <o:p></o:p></span></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> Use "n HWord" is a little confused. They are just n simd8 registers and has Hword alignment<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> in scratch memory, and the register data type is specified at the channel data type.<o:p></o:p></span></p>
</div>
<div>
<div>
<div>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D">[Ruiling] OK, will change it as spec: 1 register/ 2 registers/ 4 registers.</span><span lang="EN-US"><o:p></o:p></span></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal"><span lang="EN-US">+<br>
+static const char *data_port_scratch_invalidate[] = {<br>
+ "no invalidate",<br>
+ "invalidate cache line",<br>
+};<br>
+<br>
+static const char *data_port_scratch_data_type[] = {<br>
+ "Oword",<br>
+ "Dword",<br>
+};<br>
+<br>
+static const char *data_port_scratch_msg_type[] = {<br>
+ "Scratch Read",<br>
+ "Scratch Write",<br>
+};<br>
+<br>
static const char *data_port_data_cache_msg_type[] = {<br>
[0] = "OWord Block Read",<br>
[1] = "Unaligned OWord Block Read",<br>
@@ -1155,12 +1177,21 @@ int gen_disasm (FILE *file, const void *opaque_insn)<br>
inst->bits3.sampler_gen7.simd_mode);<br>
break;<br>
case GEN_SFID_DATAPORT_DATA_CACHE:<br>
- format (file, " (bti: %d, rgba: %d, %s, %s, %s)",<br>
- inst->bits3.gen7_untyped_rw.bti,<br>
- inst->bits3.gen7_untyped_rw.rgba,<br>
- data_port_data_cache_simd_mode[inst->bits3.gen7_untyped_rw.simd_mode],<br>
- data_port_data_cache_category[inst->bits3.gen7_untyped_rw.category],<br>
- data_port_data_cache_msg_type[inst->bits3.gen7_untyped_rw.msg_type]);<br>
+ if(inst->bits3.gen7_untyped_rw.category == 0) {<br>
+ format (file, " (bti: %d, rgba: %d, %s, %s, %s)",<br>
+ inst->bits3.gen7_untyped_rw.bti,<br>
+ inst->bits3.gen7_untyped_rw.rgba,<br>
+ data_port_data_cache_simd_mode[inst->bits3.gen7_untyped_rw.simd_mode],<br>
+ data_port_data_cache_category[inst->bits3.gen7_untyped_rw.category],<br>
+ data_port_data_cache_msg_type[inst->bits3.gen7_untyped_rw.msg_type]);<br>
+ } else {<br>
+ format (file, " (addr: %d, blocks: %s, %s, mode: %s, %s)",<br>
+ inst->bits3.gen7_scratch_rw.offset,<br>
+ data_port_scratch_block_size[inst->bits3.gen7_scratch_rw.block_size],<br>
+ data_port_scratch_invalidate[inst->bits3.gen7_scratch_rw.invalidate_after_read],<br>
+ data_port_scratch_data_type[inst->bits3.gen7_scratch_rw.data_type],<br>
+ data_port_scratch_msg_type[inst->bits3.gen7_scratch_rw.msg_type]);<br>
+ }<br>
break;<br>
case GEN_SFID_MESSAGE_GATEWAY:<br>
format (file, " (subfunc: %s, notify: %d, ackreq: %d)",<br>
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp<br>
index 97a9527..e0e4a87 100644<br>
--- a/backend/src/backend/gen_context.cpp<br>
+++ b/backend/src/backend/gen_context.cpp<br>
@@ -562,6 +562,77 @@ namespace gbe<br>
p->pop();<br>
}<br>
<br>
+ void GenContext::scratchWriteOWord(const GenRegister header, uint32_t offset, uint32_t reg_num, uint32_t reg_type) {<br>
+ p->push();<br>
+ uint32_t simdWidth = p->curr.execWidth;<br>
+ const uint32_t nr = <a href="http://header.nr" target="_blank">header.nr</a>;<br>
+ p->curr.predicate = GEN_PREDICATE_NONE;<br>
+ p->curr.noMask = 1;<br>
+<br>
+ p->curr.execWidth = 8;<br>
+ p->MOV(header, GenRegister::ud8grf(0,0));<br>
+<br>
+ p->curr.execWidth = 1;<br>
+ p->MOV(GenRegister::ud1grf(nr, 2), GenRegister::immud(offset/16));<br>
+ p->pop();<br>
+<br>
+ int size = typeSize(reg_type)*simdWidth;<br>
+ p->push();<br>
+ p->SCRATCH_WRITE_OWORD(header, size, reg_num);<br>
+ p->pop();<br>
+ }<br>
+<br>
+ void GenContext::scratchReadOWord(const GenRegister dst, const GenRegister header, uint32_t offset, uint32_t reg_num, uint32_t reg_type) {<br>
+ p->push();<br>
+ uint32_t simdWidth = p->curr.execWidth;<br>
+ const uint32_t nr = <a href="http://header.nr" target="_blank">header.nr</a>;<br>
+ p->curr.predicate = GEN_PREDICATE_NONE;<br>
+ p->curr.noMask = 1;<br>
+<br>
+ p->curr.execWidth = 8;<br>
+ p->MOV(header, GenRegister::ud8grf(0,0));<br>
+<br>
+ p->curr.execWidth = 1;<br>
+ p->MOV(GenRegister::ud1grf(nr, 2), GenRegister::immud(offset/16));<br>
+ p->pop();<br>
+<br>
+ int size = typeSize(reg_type)*simdWidth;<br>
+ p->push();<br>
+ p->SCRATCH_READ_OWORD(dst, header, size, reg_num);<br>
+ p->pop();<br>
+ }<br>
+<br>
+ void GenContext::scratchWriteHWord(const GenRegister header, uint32_t offset, uint32_t reg_num, uint32_t reg_type) {<o:p></o:p></span></p>
</blockquote>
</div>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> I think you should use scratchWriteDWord here? right? <o:p></o:p></span></p>
</div>
<div>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal"><span lang="EN-US">+ p->push();<br>
+ uint32_t simdWidth = p->curr.execWidth;<br>
+ p->curr.predicate = GEN_PREDICATE_NONE;<br>
+ p->curr.noMask = 1;<br>
+<br>
+ p->curr.execWidth = 8;<br>
+ p->MOV(header, GenRegister::ud8grf(0,0));<br>
+ p->pop();<br>
+<br>
+ int size = typeSize(reg_type)*simdWidth;<br>
+ p->push();<br>
+ p->SCRATCH_WRITE_HWORD(header, offset/32, size, reg_num);<br>
+ p->pop();<br>
+ }<br>
+<br>
+ void GenContext::scratchReadHWord(const GenRegister dst, const GenRegister header, uint32_t offset, uint32_t reg_num, uint32_t reg_type) {<br>
+ p->push();<br>
+ uint32_t simdWidth = p->curr.execWidth;<br>
+ p->curr.predicate = GEN_PREDICATE_NONE;<br>
+ p->curr.noMask = 1;<br>
+ p->curr.execWidth = 8;<br>
+ p->MOV(header, GenRegister::ud8grf(0,0));<br>
+ p->pop();<br>
+<br>
+ int size = typeSize(reg_type)*simdWidth;<br>
+ p->push();<br>
+ p->SCRATCH_READ_HWORD(dst, header, offset/32, size, reg_num);<br>
+ p->pop();<br>
+ }<br>
+<o:p></o:p></span></p>
</blockquote>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal"><span lang="EN-US"> void GenContext::emitTypedWriteInstruction(const SelectionInstruction &insn) {<br>
const GenRegister header = GenRegister::retype(ra->genReg(insn.src(0)), GEN_TYPE_UD);<br>
const GenRegister ucoord = ra->genReg(insn.src(insn.extra.elem));<br>
diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp<br>
index dc5dc45..3b78342 100644<br>
--- a/backend/src/backend/gen_context.hpp<br>
+++ b/backend/src/backend/gen_context.hpp<br>
@@ -41,6 +41,7 @@ namespace gbe<br>
class Selection; // Performs instruction selection<br>
class SelectionInstruction; // Pre-RA Gen instruction<br>
class SelectionReg; // Pre-RA Gen register<br>
+ class GenRegister;<br>
<br>
/*! Context is the helper structure to build the Gen ISA or simulation code<br>
* from GenIR<br>
@@ -108,7 +109,10 @@ namespace gbe<br>
void emitSampleInstruction(const SelectionInstruction &insn);<br>
void emitTypedWriteInstruction(const SelectionInstruction &insn);<br>
void emitGetImageInfoInstruction(const SelectionInstruction &insn);<br>
-<br>
+ void scratchWriteOWord(const GenRegister header, uint32_t offset, uint32_t reg_num, uint32_t reg_type);<br>
+ void scratchReadOWord(const GenRegister dst, const GenRegister header, uint32_t offset, uint32_t reg_num, uint32_t reg_type);<br>
+ void scratchWriteHWord(const GenRegister header, uint32_t offset, uint32_t reg_num, uint32_t reg_type);<br>
+ void scratchReadHWord(const GenRegister dst, const GenRegister header, uint32_t offset, uint32_t reg_num, uint32_t reg_type);<br>
/*! Implements base class */<br>
virtual Kernel *allocateKernel(void);<br>
/*! Store the position of each label instruction in the Gen ISA stream */<br>
diff --git a/backend/src/backend/gen_defs.hpp b/backend/src/backend/gen_defs.hpp<br>
index 5b15e30..00e61c9 100644<br>
--- a/backend/src/backend/gen_defs.hpp<br>
+++ b/backend/src/backend/gen_defs.hpp<br>
@@ -319,6 +319,15 @@ enum GenMessageTarget {<br>
#define GEN_BYTE_SCATTER 12//1100: Byte Scattered Write<br>
#define GEN_UNTYPED_WRITE 13//1101: Untyped Surface Write<br>
<br>
+/* Data port data cache scratch messages*/<br>
+#define GEN_SCRATCH_READ 0<br>
+#define GEN_SCRATCH_WRITE 1<br>
+#define GEN_SCRATCH_DATA_OWORD 0<br>
+#define GEN_SCRATCH_DATA_DWORD 1<br>
+#define GEN_SCRATCH_BLOCK_SIZE_1 0<br>
+#define GEN_SCRATCH_BLOCK_SIZE_2 1<br>
+#define GEN_SCRATCH_BLOCK_SIZE_4 3<br>
+<br>
/* Data port render cache Message Type*/<br>
#define GEN_MBLOCK_READ 4 //0100: Media Block Read<br>
#define GEN_TYPED_READ 5 //0101: Typed Surface Read<br>
@@ -765,6 +774,22 @@ struct GenInstruction<br>
uint32_t end_of_thread:1;<br>
} gen7_byte_rw;<br>
<br>
+ /*! Data port Scratch Read/ write */<br>
+ struct {<br>
+ uint32_t offset:12;<br>
+ uint32_t block_size:2;<br>
+ uint32_t ignored0:1;<br>
+ uint32_t invalidate_after_read:1;<br>
+ uint32_t data_type:1;<br>
+ uint32_t msg_type:1;<br>
+ uint32_t category:1;<br>
+ uint32_t header_present:1;<br>
+ uint32_t response_length:5;<br>
+ uint32_t msg_length:4;<br>
+ uint32_t pad2:2;<br>
+ uint32_t end_of_thread:1;<br>
+ } gen7_scratch_rw;<br>
+<br>
/*! Data port OBlock read / write */<br>
struct {<br>
uint32_t bti:8;<br>
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp<br>
index 64b5bd1..afb193f 100644<br>
--- a/backend/src/backend/gen_encoder.cpp<br>
+++ b/backend/src/backend/gen_encoder.cpp<br>
@@ -147,7 +147,7 @@ namespace gbe<br>
else<br>
NOT_SUPPORTED;<br>
}<br>
-#if 0<br>
+#if 1<br>
static void setOBlockRW(GenEncoder *p,<br>
GenInstruction *insn,<br>
uint32_t bti,<br>
@@ -1136,6 +1136,71 @@ namespace gbe<br>
this->setSrc0(insn, msg);<br>
setTypedWriteMessage(this, insn, bti, msg_type, msg_length, header_present);<br>
}<o:p></o:p></span></p>
</blockquote>
</div>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> I don't think you can reuse the setOBlockRW for the scratch buffer.<o:p></o:p></span></p>
</div>
<div>
<div>
<div>
<p class="MsoNormal"><span lang="EN-US"> <o:p></o:p></span></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal"><span lang="EN-US">+ static void setScratchMessage(GenEncoder *p,<br>
+ GenInstruction *insn,<br>
+ uint32_t offset,<br>
+ uint32_t block_size,<br>
+ uint32_t data_type,<br>
+ uint32_t msg_type,<br>
+ uint32_t msg_length,<br>
+ uint32_t response_length)<br>
+ {<br>
+ const GenMessageTarget sfid = GEN_SFID_DATAPORT_DATA_CACHE;<br>
+ setMessageDescriptor(p, insn, sfid, msg_length, response_length, true);<br>
+ insn->bits3.gen7_scratch_rw.block_size = block_size;<br>
+ insn->bits3.gen7_scratch_rw.msg_type = msg_type;<br>
+ insn->bits3.gen7_scratch_rw.data_type = data_type;<br>
+ insn->bits3.gen7_scratch_rw.offset = offset;<br>
+ insn->bits3.gen7_scratch_rw.category = 1;<br>
+ }<br>
+<br>
+ void GenEncoder::SCRATCH_WRITE_HWORD(GenRegister msg, uint32_t offset, uint32_t size, uint32_t src_num)<br>
+ {<br>
+ assert(src_num == 1 || src_num ==2);<br>
+ uint32_t block_size = src_num == 1 ? GEN_SCRATCH_BLOCK_SIZE_1 : GEN_SCRATCH_BLOCK_SIZE_2;<br>
+ GenInstruction *insn = this->next(GEN_OPCODE_SEND);<br>
+ this->setHeader(insn);<br>
+ this->setDst(insn, GenRegister::retype(GenRegister::null(), GEN_TYPE_UD));<br>
+ this->setSrc0(insn, msg);<br>
+ this->setSrc1(insn, GenRegister::immud(0));<br>
+ // here src_num means register that will be write out: in terms of 32byte register number<br>
+ setScratchMessage(this, insn, offset, block_size, GEN_SCRATCH_DATA_DWORD, GEN_SCRATCH_WRITE, src_num+1, 0);<br>
+ }<br>
+<br>
+ void GenEncoder::SCRATCH_READ_HWORD(GenRegister dst, GenRegister src, uint32_t offset, uint32_t size, uint32_t dst_num)<br>
+ {<br>
+ assert(dst_num == 1 || dst_num ==2);<br>
+ uint32_t block_size = dst_num == 1 ? GEN_SCRATCH_BLOCK_SIZE_1 : GEN_SCRATCH_BLOCK_SIZE_2;<br>
+ GenInstruction *insn = this->next(GEN_OPCODE_SEND);<br>
+ this->setHeader(insn);<br>
+ this->setDst(insn, dst);<br>
+ this->setSrc0(insn, src);<br>
+ this->setSrc1(insn, GenRegister::immud(0));<br>
+ // here dst_num is the register that will be write-back: in terms of 32byte register<br>
+ setScratchMessage(this, insn, offset, block_size, GEN_SCRATCH_DATA_DWORD, GEN_SCRATCH_READ, 1, dst_num);<br>
+ }<br>
+<br>
+ void GenEncoder::SCRATCH_WRITE_OWORD(GenRegister msg, uint32_t size, uint32_t src_num)<br>
+ {<br>
+ GenInstruction *insn = this->next(GEN_OPCODE_SEND);<br>
+ this->setHeader(insn);<br>
+ this->setDst(insn, GenRegister::retype(GenRegister::null(), GEN_TYPE_UD));<br>
+ this->setSrc0(insn, msg);<br>
+ this->setSrc1(insn, GenRegister::immud(0));<br>
+ // here src_num means registers that will be write out: in terms of 32byte register number<br>
+ setOBlockRW(this, insn, 255, size/16, GEN_OBLOCK_WRITE, src_num+1, 0);<br>
+ }<o:p></o:p></span></p>
</blockquote>
</div>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> I'm confused here, you prepared a message header for Scratch OWord read/write, but then you send a </span><span lang="EN-US" style="font-size:10.0pt;font-family:"Arial","sans-serif"">OWord Block Read</span><span lang="EN-US"><o:p></o:p></span></p>
</div>
<p class="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:"Arial","sans-serif""> message. I don't think it's going to work as desired. You can check the "OWord Block Read/Write" in the spec, you can find</span><span lang="EN-US"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:"Arial","sans-serif""> a restriction there:</span><span lang="EN-US"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:"Arial","sans-serif""> the only surface type allowed is SURFTYPE_BUFFER.</span><span lang="EN-US"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:"Arial","sans-serif";color:black"> And here, the surface is a scratch buffer.</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Arial","sans-serif""><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:10.5pt;font-family:"Calibri","sans-serif";color:#1F497D">[Ruiling] scratch buffer is stateless buffer, i.e.
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Arial","sans-serif"">SURFTYPE_BUFFER. It is more preferred to call “OWord block read/write” instead of “scratch OWord block read/write”. This is not what written as oword mode under scratch memory
read/write. </span><span lang="EN-US" style="font-size:10.5pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p></o:p></span></p>
<div>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal"><span lang="EN-US">+<br>
+ void GenEncoder::SCRATCH_READ_OWORD(GenRegister dst, GenRegister src, uint32_t size, uint32_t dst_num)<br>
+ {<br>
+ GenInstruction *insn = this->next(GEN_OPCODE_SEND);<br>
+ this->setHeader(insn);<br>
+ this->setDst(insn, dst);<br>
+ this->setSrc0(insn, src);<br>
+ this->setSrc1(insn, GenRegister::immud(0));<br>
+ // here dst_num is the register that will be write-back: in terms of 32byte register<br>
+ setOBlockRW(this, insn, 255, size/16, GEN_OBLOCK_READ, 1, dst_num);<br>
+ }<br>
<br>
void GenEncoder::EOT(uint32_t msg) {<br>
GenInstruction *insn = this->next(GEN_OPCODE_SEND);<br>
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp<br>
index 083bd8c..66c4f25 100644<br>
--- a/backend/src/backend/gen_encoder.hpp<br>
+++ b/backend/src/backend/gen_encoder.hpp<br>
@@ -155,6 +155,14 @@ namespace gbe<br>
void BYTE_GATHER(GenRegister dst, GenRegister src, uint32_t bti, uint32_t elemSize);<br>
/*! Byte scatter (for unaligned bytes, shorts and ints) */<br>
void BYTE_SCATTER(GenRegister src, uint32_t bti, uint32_t elemSize);<br>
+ /*! for scratch memory oblock read */<br>
+ void SCRATCH_READ_OWORD(GenRegister msg, GenRegister dst, uint32_t size, uint32_t dst_num);<br>
+ /*! for scratch memory oblock write */<br>
+ void SCRATCH_WRITE_OWORD(GenRegister msg, uint32_t size, uint32_t src_num);<br>
+ /*! for scratch memory hblock read */<br>
+ void SCRATCH_READ_HWORD(GenRegister msg, GenRegister dst, uint32_t offset, uint32_t size, uint32_t dst_num);<br>
+ /*! for scratch memory hblock write */<br>
+ void SCRATCH_WRITE_HWORD(GenRegister msg, uint32_t offset, uint32_t size, uint32_t src_num);<br>
/*! Send instruction for the sampler */<br>
void SAMPLE(GenRegister dest,<br>
GenRegister msg,<br>
diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp<br>
index 26c22f3..35d3a7c 100644<br>
--- a/backend/src/backend/program.cpp<br>
+++ b/backend/src/backend/program.cpp<br>
@@ -374,6 +374,12 @@ namespace gbe {<br>
return kernel->getStackSize();<br>
}<br>
<br>
+ static int32_t kernelGetScratchSize(gbe_kernel genKernel) {<br>
+ if (genKernel == NULL) return 0;<br>
+ const gbe::Kernel *kernel = (const gbe::Kernel*) genKernel;<br>
+ return kernel->getScratchSize();<br>
+ }<br>
+<br>
static int32_t kernelUseSLM(gbe_kernel genKernel) {<br>
if (genKernel == NULL) return 0;<br>
const gbe::Kernel *kernel = (const gbe::Kernel*) genKernel;<br>
@@ -443,6 +449,7 @@ GBE_EXPORT_SYMBOL gbe_kernel_get_simd_width_cb *gbe_kernel_get_simd_width = NULL<br>
GBE_EXPORT_SYMBOL gbe_kernel_get_curbe_offset_cb *gbe_kernel_get_curbe_offset = NULL;<br>
GBE_EXPORT_SYMBOL gbe_kernel_get_curbe_size_cb *gbe_kernel_get_curbe_size = NULL;<br>
GBE_EXPORT_SYMBOL gbe_kernel_get_stack_size_cb *gbe_kernel_get_stack_size = NULL;<br>
+GBE_EXPORT_SYMBOL gbe_kernel_get_scratch_size_cb *gbe_kernel_get_scratch_size = NULL;<br>
GBE_EXPORT_SYMBOL gbe_kernel_set_const_buffer_size_cb *gbe_kernel_set_const_buffer_size = NULL;<br>
GBE_EXPORT_SYMBOL gbe_kernel_get_required_work_group_size_cb *gbe_kernel_get_required_work_group_size = NULL;<br>
GBE_EXPORT_SYMBOL gbe_kernel_use_slm_cb *gbe_kernel_use_slm = NULL;<br>
@@ -476,6 +483,7 @@ namespace gbe<br>
gbe_kernel_get_curbe_offset = gbe::kernelGetCurbeOffset;<br>
gbe_kernel_get_curbe_size = gbe::kernelGetCurbeSize;<br>
gbe_kernel_get_stack_size = gbe::kernelGetStackSize;<br>
+ gbe_kernel_get_scratch_size = gbe::kernelGetScratchSize;<br>
gbe_kernel_set_const_buffer_size = gbe::kernelSetConstBufSize;<br>
gbe_kernel_get_required_work_group_size = gbe::kernelGetRequiredWorkGroupSize;<br>
gbe_kernel_use_slm = gbe::kernelUseSLM;<br>
diff --git a/backend/src/backend/program.h b/backend/src/backend/program.h<br>
index f36bfbf..d20e7af 100644<br>
--- a/backend/src/backend/program.h<br>
+++ b/backend/src/backend/program.h<br>
@@ -198,6 +198,10 @@ extern gbe_kernel_get_curbe_size_cb *gbe_kernel_get_curbe_size;<br>
typedef int32_t (gbe_kernel_get_stack_size_cb)(gbe_kernel);<br>
extern gbe_kernel_get_stack_size_cb *gbe_kernel_get_stack_size;<br>
<br>
+/*! Get the scratch size (zero if no scratch is required) */<br>
+typedef int32_t (gbe_kernel_get_scratch_size_cb)(gbe_kernel);<br>
+extern gbe_kernel_get_scratch_size_cb *gbe_kernel_get_scratch_size;<br>
+<br>
/*! Get the curbe offset where to put the data. Returns -1 if not required */<br>
typedef int32_t (gbe_kernel_get_curbe_offset_cb)(gbe_kernel, enum gbe_curbe_type type, uint32_t sub_type);<br>
extern gbe_kernel_get_curbe_offset_cb *gbe_kernel_get_curbe_offset;<br>
diff --git a/backend/src/backend/program.hpp b/backend/src/backend/program.hpp<br>
index 2d67310..83aaab8 100644<br>
--- a/backend/src/backend/program.hpp<br>
+++ b/backend/src/backend/program.hpp<br>
@@ -96,6 +96,8 @@ namespace gbe {<br>
INLINE uint32_t getCurbeSize(void) const { return this->curbeSize; }<br>
/*! Return the size of the stack (zero if none) */<br>
INLINE uint32_t getStackSize(void) const { return this->stackSize; }<br>
+ /*! Return the size of the scratch memory needed (zero if none) */<br>
+ INLINE uint32_t getScratchSize(void) const { return this->scratchSize; }<br>
/*! Get the SIMD width for the kernel */<br>
INLINE uint32_t getSIMDWidth(void) const { return this->simdWidth; }<br>
/*! Says if SLM is needed for it */<br>
@@ -135,6 +137,7 @@ namespace gbe {<br>
uint32_t curbeSize; //!< Size of the data to push<br>
uint32_t simdWidth; //!< SIMD size for the kernel (lane number)<br>
uint32_t stackSize; //!< Stack size (may be 0 if unused)<br>
+ uint32_t scratchSize; //!< Scratch memory size (may be 0 if unused)<br>
bool useSLM; //!< SLM requires a special HW config<br>
Context *ctx; //!< Save context after compiler to alloc constant buffer curbe<br>
ir::SamplerSet *samplerSet;//!< Copy from the corresponding function.<br>
diff --git a/src/cl_command_queue_gen7.c b/src/cl_command_queue_gen7.c<br>
index 8933213..e58433f 100644<br>
--- a/src/cl_command_queue_gen7.c<br>
+++ b/src/cl_command_queue_gen7.c<br>
@@ -183,6 +183,14 @@ cl_bind_stack(cl_gpgpu gpgpu, cl_kernel ker)<br>
cl_gpgpu_set_stack(gpgpu, offset, stack_sz, cc_llc_l3);<br>
}<br>
<br>
+static void<br>
+cl_setup_scratch(cl_gpgpu gpgpu, cl_kernel ker)<br>
+{<br>
+ int32_t scratch_sz = gbe_kernel_get_scratch_size(ker->opaque);<br>
+<br>
+ cl_gpgpu_set_scratch(gpgpu, scratch_sz);<br>
+}<br>
+<br>
LOCAL cl_int<br>
cl_command_queue_ND_range_gen7(cl_command_queue queue,<br>
cl_kernel ker,<br>
@@ -231,6 +239,7 @@ cl_command_queue_ND_range_gen7(cl_command_queue queue,<br>
/* Bind all samplers */<br>
cl_gpgpu_bind_sampler(queue->gpgpu, ker->samplers, ker->sampler_sz);<br>
<br>
+ cl_setup_scratch(gpgpu, ker);<br>
/* Bind a stack if needed */<br>
cl_bind_stack(gpgpu, ker);<br>
cl_gpgpu_states_setup(gpgpu, &kernel);<br>
diff --git a/src/cl_driver.h b/src/cl_driver.h<br>
index 212beb3..673985d 100644<br>
--- a/src/cl_driver.h<br>
+++ b/src/cl_driver.h<br>
@@ -135,6 +135,10 @@ extern cl_gpgpu_bind_image_cb *cl_gpgpu_bind_image;<br>
typedef void (cl_gpgpu_set_stack_cb)(cl_gpgpu, uint32_t offset, uint32_t size, uint32_t cchint);<br>
extern cl_gpgpu_set_stack_cb *cl_gpgpu_set_stack;<br>
<br>
+/* Setup scratch */<br>
+typedef void (cl_gpgpu_set_scratch_cb)(cl_gpgpu, uint32_t per_thread_size);<br>
+extern cl_gpgpu_set_scratch_cb *cl_gpgpu_set_scratch;<br>
+<br>
/* Configure internal state */<br>
typedef void (cl_gpgpu_state_init_cb)(cl_gpgpu, uint32_t max_threads, uint32_t size_cs_entry);<br>
extern cl_gpgpu_state_init_cb *cl_gpgpu_state_init;<br>
diff --git a/src/cl_driver_defs.c b/src/cl_driver_defs.c<br>
index 4952288..9aa926e 100644<br>
--- a/src/cl_driver_defs.c<br>
+++ b/src/cl_driver_defs.c<br>
@@ -50,6 +50,7 @@ LOCAL cl_gpgpu_delete_cb *cl_gpgpu_delete = NULL;<br>
LOCAL cl_gpgpu_sync_cb *cl_gpgpu_sync = NULL;<br>
LOCAL cl_gpgpu_bind_buf_cb *cl_gpgpu_bind_buf = NULL;<br>
LOCAL cl_gpgpu_set_stack_cb *cl_gpgpu_set_stack = NULL;<br>
+LOCAL cl_gpgpu_set_scratch_cb *cl_gpgpu_set_scratch = NULL;<br>
LOCAL cl_gpgpu_bind_image_cb *cl_gpgpu_bind_image = NULL;<br>
LOCAL cl_gpgpu_state_init_cb *cl_gpgpu_state_init = NULL;<br>
LOCAL cl_gpgpu_set_perf_counters_cb *cl_gpgpu_set_perf_counters = NULL;<br>
diff --git a/src/intel/intel_gpgpu.c b/src/intel/intel_gpgpu.c<br>
index 2791fbe..b7434c4 100644<br>
--- a/src/intel/intel_gpgpu.c<br>
+++ b/src/intel/intel_gpgpu.c<br>
@@ -89,7 +89,9 @@ struct intel_gpgpu<br>
struct { drm_intel_bo *bo; } curbe_b;<br>
struct { drm_intel_bo *bo; } sampler_state_b;<br>
struct { drm_intel_bo *bo; } perf_b;<br>
+ struct { drm_intel_bo *bo; } scratch_b;<br>
<br>
+ uint32_t per_thread_scratch;<br>
struct {<br>
uint32_t num_cs_entries;<br>
uint32_t size_cs_entry; /* size of one entry in 512bit elements */<br>
@@ -127,6 +129,9 @@ intel_gpgpu_delete(intel_gpgpu_t *gpgpu)<br>
drm_intel_bo_unreference(gpgpu-><a href="http://perf_b.bo" target="_blank">perf_b.bo</a>);<br>
if (gpgpu-><a href="http://stack_b.bo" target="_blank">stack_b.bo</a>)<br>
drm_intel_bo_unreference(gpgpu-><a href="http://stack_b.bo" target="_blank">stack_b.bo</a>);<br>
+ if (gpgpu-><a href="http://scratch_b.bo" target="_blank">scratch_b.bo</a>)<br>
+ drm_intel_bo_unreference(gpgpu-><a href="http://scratch_b.bo" target="_blank">scratch_b.bo</a>);<br>
+<br>
intel_batchbuffer_delete(gpgpu->batch);<br>
cl_free(gpgpu);<br>
}<br>
@@ -199,18 +204,23 @@ intel_gpgpu_load_vfe_state(intel_gpgpu_t *gpgpu)<br>
BEGIN_BATCH(gpgpu->batch, 8);<br>
OUT_BATCH(gpgpu->batch, CMD_MEDIA_STATE_POINTERS | (8-2));<br>
<br>
- gen6_vfe_state_inline_t* vfe = (gen6_vfe_state_inline_t*)<br>
- intel_batchbuffer_alloc_space(gpgpu->batch,0);<br>
-<br>
- memset(vfe, 0, sizeof(struct gen6_vfe_state_inline));<br>
- vfe->vfe1.gpgpu_mode = 1;<br>
- vfe->vfe1.bypass_gateway_ctl = 1;<br>
- vfe->vfe1.reset_gateway_timer = 1;<br>
- vfe->vfe1.max_threads = gpgpu->max_threads - 1;<br>
- vfe->vfe1.urb_entries = 64;<br>
- vfe->vfe3.curbe_size = 480;<br>
- vfe->vfe4.scoreboard_mask = 0;<br>
- intel_batchbuffer_alloc_space(gpgpu->batch, sizeof(gen6_vfe_state_inline_t));<br>
+ if(gpgpu->per_thread_scratch > 0) {<br>
+ OUT_RELOC(gpgpu->batch, gpgpu-><a href="http://scratch_b.bo" target="_blank">scratch_b.bo</a>,<br>
+ I915_GEM_DOMAIN_RENDER,<br>
+ I915_GEM_DOMAIN_RENDER,<br>
+ gpgpu->per_thread_scratch/1024 - 1);<br>
+ }<br>
+ else {<br>
+ OUT_BATCH(gpgpu->batch, 0);<br>
+ }<br>
+ /* max_thread | urb entries | (reset_gateway|bypass_gate_way | gpgpu_mode) */<br>
+ OUT_BATCH(gpgpu->batch, 0 | ((gpgpu->max_threads - 1) << 16) | (64 << 8) | 0xc4);<br>
+ OUT_BATCH(gpgpu->batch, 0);<br>
+ /* curbe_size */<br>
+ OUT_BATCH(gpgpu->batch, 480);<br>
+ OUT_BATCH(gpgpu->batch, 0);<br>
+ OUT_BATCH(gpgpu->batch, 0);<br>
+ OUT_BATCH(gpgpu->batch, 0);<br>
ADVANCE_BATCH(gpgpu->batch);<br>
}<br>
<br>
@@ -434,6 +444,7 @@ intel_gpgpu_state_init(intel_gpgpu_t *gpgpu,<br>
if (gpgpu-><a href="http://stack_b.bo" target="_blank">stack_b.bo</a>)<br>
dri_bo_unreference(gpgpu-><a href="http://stack_b.bo" target="_blank">stack_b.bo</a>);<br>
gpgpu-><a href="http://stack_b.bo" target="_blank">stack_b.bo</a> = NULL;<br>
+<br>
}<o:p></o:p></span></p>
</blockquote>
</div>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> Don't need to add the above blank line.<o:p></o:p></span></p>
</div>
<div>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal"><span lang="EN-US"><br>
static void<br>
@@ -537,6 +548,23 @@ intel_gpgpu_bind_buf(intel_gpgpu_t *gpgpu, drm_intel_bo *buf, uint32_t offset, u<br>
}<br>
<br>
static void<br>
+intel_gpgpu_set_scratch(intel_gpgpu_t * gpgpu, uint32_t per_thread_size)<br>
+{<br>
+ drm_intel_bufmgr *bufmgr = gpgpu->drv->bufmgr;<br>
+ drm_intel_bo* old = gpgpu-><a href="http://scratch_b.bo" target="_blank">scratch_b.bo</a>;<br>
+ uint32_t total = per_thread_size * gpgpu->max_threads;<br>
+<br>
+ gpgpu->per_thread_scratch = per_thread_size;<br>
+<br>
+ if(old && old->size < total) {<br>
+ drm_intel_bo_unreference(old);<br>
+ old = NULL;<br>
+ }<br>
+<br>
+ if(!old)<br>
+ gpgpu-><a href="http://scratch_b.bo" target="_blank">scratch_b.bo</a> = drm_intel_bo_alloc(bufmgr, "SCRATCH_BO", total, 4096);<br>
+}<br>
+static void<br>
intel_gpgpu_set_stack(intel_gpgpu_t *gpgpu, uint32_t offset, uint32_t size, uint32_t cchint)<br>
{<br>
drm_intel_bufmgr *bufmgr = gpgpu->drv->bufmgr;<br>
@@ -823,5 +851,6 @@ intel_set_gpgpu_callbacks(void)<br>
cl_gpgpu_flush = (cl_gpgpu_flush_cb *) intel_gpgpu_flush;<br>
cl_gpgpu_walker = (cl_gpgpu_walker_cb *) intel_gpgpu_walker;<br>
cl_gpgpu_bind_sampler = (cl_gpgpu_bind_sampler_cb *) intel_gpgpu_bind_sampler;<br>
+ cl_gpgpu_set_scratch = (cl_gpgpu_set_scratch_cb *) intel_gpgpu_set_scratch;<br>
} <o:p></o:p></span></p>
</blockquote>
<div>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> I'm thinking of is there a way to test the scratch read/write directly? Maybe it's not so straightforward as it's only<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> used when spill/unspill occurs. And if a kernel triggers spill/unspill, it means the kernel is not very simple and can't<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US"> be a proper unit test case for scratch read/write. Any good idea?<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D">[Ruiling] this is also a problem I met. At last I only can manually call spillReg() to select one virtual register I want, so, I don’t have to face a complex kernel. But I don’t have good way of
verifying scratch RW.</span><span lang="EN-US" style="color:#888888"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-US" style="color:#888888"> - Zhigang<o:p></o:p></span></p>
</div>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal"><span lang="EN-US" style="color:#888888">--<br>
1.7.9.5<br>
<br>
_______________________________________________<br>
Beignet mailing list<br>
<a href="mailto:Beignet@lists.freedesktop.org" target="_blank">Beignet@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/beignet" target="_blank">http://lists.freedesktop.org/mailman/listinfo/beignet</a></span><span lang="EN-US"><o:p></o:p></span></p>
</blockquote>
</div>
</div>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
</div>
</div>
</div>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
</div>
</div>
</body>
</html>